๐Fix : Address Copy Button - ์ค ์ฃผ์๊ฐ Placeholder#63
๐Fix : Address Copy Button - ์ค ์ฃผ์๊ฐ Placeholder#63
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
๐ ์ ์ฒด ์์ฝWalkthrough๋ณธ PR์ ์ธ ๊ฐ์ ํต์ฌ ์ปดํฌ๋ํธ๋ฅผ ์์ ํฉ๋๋ค. ์ธ์ฆ ํ์ด์ง์์ ์ต๊ทผ ๋ก๊ทธ์ธ ํ๋ซํผ ์ถ์ ์ํ๋ฅผ ์ถ๊ฐํ๊ณ ๋ก๊ทธ์ธ ๋ฒํผ๋ณ ํผ๋๋ฐฑ UI๋ฅผ ํตํฉํ์ผ๋ฉฐ, AddressCopy ์ปดํฌ๋ํธ์ props ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝ(label โ value + truncate)ํ๊ณ , Card ์ปดํฌ๋ํธ์ ๋๋น๋ฅผ ๊ณ ์ ๊ฐ์์ ๋ฐ์ํ์ผ๋ก ์กฐ์ ํ์ต๋๋ค. Changes
Estimated code review effort๐ฏ 3 (Moderate) | โฑ๏ธ ~20โ25 minutes ์ถ๊ฐ ์ฃผ์ ํ์ ์์ญ:
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touchesโ Failed checks (1 warning)
โ Passed checks (2 passed)
โจ Finishing touches
๐งช Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
๐ท๏ธ Labeler has automatically applied labels based on your PR title, branch name, or commit message. |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and canโt be posted inline due to platform limitations.
โ ๏ธ Outside diff range comments (1)
src/shared/components/button/AddressCopy.tsx (1)
51-59: Clickable div โ button ์ ํ์ผ๋ก ํค๋ณด๋ ์ ๊ทผ์ฑ/์ญํ ๋ณด์ฅํ์ฌ
div์onClick๋ง ์์ด ํค๋ณด๋ ์กฐ์(Enter/Space)๊ณผ ํฌ์ปค์ค, ์ญํ ์ด ๋ณด์ฅ๋์ง ์์ต๋๋ค. ๋ค์ดํฐ๋ธ<button>์ผ๋ก ๊ต์ฒดํ๊ณtype="button", ์ ์ ํaria-label/๋ผ์ด๋ธ ๋ฆฌ์ ์ ์ํ ํผ๋๋ฐฑ์ ์ ๊ณตํด์ฃผ์ธ์.Apply this diff:
-interface AddressCopyProps - extends React.HTMLAttributes<HTMLDivElement>, +interface AddressCopyProps + extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof addressCopyStyle> { value: string; truncate?: boolean; } const AddressCopy = ({ value, variant = 'gray', truncate = true, className, ...props }: AddressCopyProps) => { const [copied, setCopied] = useState(false); @@ - return ( - <div - onClick={handleCopy} + const ariaLabel = copied ? '์ฃผ์๊ฐ ๋ณต์ฌ๋์์ต๋๋ค' : '์ฃผ์ ๋ณต์ฌ'; + return ( + <button + type="button" + onClick={handleCopy} className={cn( addressCopyStyle({ variant }), 'w-full h-[4rem] px-[1.3rem] py-[1rem] gap-[0.4rem]', - 'cursor-pointer select-none', + 'cursor-pointer select-none', className, )} {...props} - > + aria-label={ariaLabel} + > @@ - </div> + <span className="sr-only" aria-live="polite" aria-atomic="true"> + {copied ? '๋ณต์ฌ๋จ' : ''} + </span> + </button> );
๐งน Nitpick comments (6)
src/shared/components/container/Card.tsx (2)
14-16: w-full ์ ํ ์ flex-shrink-0์์ ์ํธ์์ฉ ์ ๊ฒ ํ์๋ถ๋ชจ๊ฐ ์ข๊ฑฐ๋ gap/padding์ด ํฐ ํ๋ ์ค ์ปจํ ์ด๋์ผ ๋,
w-full+flex-shrink-0์กฐํฉ์ด ์ํ ์ค๋ฒํ๋ก๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. ๋ ์ด์์ ์ ๋ฌธ์ ๊ฐ ์์ผ๋ฉด OK์ง๋ง, ์ด์๊ฐ ๋ณด์ด๋ฉดflex-shrinkํ์ฉ(์:flex-shrink์ ๊ฑฐ) ๋๋ ๋ถ๋ชจ์min-w-0/overflow-hidden๋ณด์์ ๊ณ ๋ คํด์ฃผ์ธ์.
39-44: large์ ๊ธฐ์กด padding๊ณผ customPadding์ ๋ณํฉ ๊ฒฐ๊ณผ ์ฌํ์ธ
large๋pt/pb/px๋ฅผ ์ง์ ํ๊ณ ,customPadding์py/px๋ฅผ ์ถ๊ฐํฉ๋๋ค. twMerge ์์์py๊ฐpt/pb๋ฅผ ๋ฎ์ด ๋์ผํ ์ํ ํจ๋ฉ(1.4rem)์ผ๋ก ๋ฐ๋๋๋ค. ์๋๋ผ๋ฉด OK, ์๋๋ผ๋ฉดcustomPadding์ ๋ ๊ตฌ์ฒด์ ์ผ๋ก(์:pt๋๋pb๋ง) ์ง์ ํด ์ฃผ์ธ์.src/pages/auth/index.tsx (3)
11-15: ์๋ฆผ(alert) ๋์ ๋น์ฐจ๋จ ํผ๋๋ฐฑ์ผ๋ก ์ ํ ๊ถ์ฅ
alert๋ UI ํ๋ฆ์ ๋ง์ต๋๋ค. ์๋จ ๋ฒ๋ธ/ํ ์คํธ๋ก ๋์ฒดํ๊ฑฐ๋ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ง ๋์ํ๋๋ก ๊ฐ๋ํ๋ ํธ์ด ์ข์ต๋๋ค.Apply this diff (๊ฐ๋ฐ ํ๊ฒฝ์์๋ง alert ์ ์ง):
- const handleLoginClick = (platform: string) => { - alert(`${platform} ๋ก๊ทธ์ธ ์ค๋น์ค`); - console.log(`${platform} ๋ก๊ทธ์ธ ๋ฒํผ ํด๋ฆญ`); - setRecentPlatform(platform); - }; + const handleLoginClick = (platform: string) => { + if (process.env.NODE_ENV === 'development') { + // dev ์ ์ฉ ์๋ด + alert(`${platform} ๋ก๊ทธ์ธ ์ค๋น์ค`); + } + console.info(`[auth] ${platform} ๋ก๊ทธ์ธ ๋ฒํผ ํด๋ฆญ`); + setRecentPlatform(platform); + };
72-103: ๋ฒ๋ธ ํฌ์ง์ ๋์ ๐ โ a11y ๋ณด์์ ๋ณ๋ ์ปดํฌ๋ํธ์์ ๊ฒํ
pointer-events-none๋ก ํด๋ฆญ ๊ฐ์ญ์ ๋ง์ ์ ์ข์ต๋๋ค.RecentLoginBubble์role="status"์aria-live="polite"๋ฅผ ์ถ๊ฐํ๋ฉด ๋ณด์กฐ๊ธฐ๊ธฐ์ ๋ณต๊ท ์ ํธ๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฒ๋ฆฌ ์ ์๋๋ฆฝ๋๋ค.
9-15: Platform ์๋ณ์๋ฅผ ๋ฌธ์์ด ์ํ์์ ๋ถ๋ฆฌํ์ฌ ์ ํ ์์ ์ฑ ํฅ์๊ฒ์ฆ ๊ฒฐ๊ณผ, ์ ์๋ ๋ฆฌํฉํ ๋ง์ด ์ ํํ๊ณ ํ์ํฉ๋๋ค. ํ์ฌ ์ฝ๋๋ ํ๊ตญ์ด ๋ฌธ์์ด(
'์นด์นด์ค','๊ตฌ๊ธ')์ ์ํ๋ก ์ฌ์ฉํ๊ณ ์์ด, ๋ผ๋ฒจ ๋ณ๊ฒฝ ์ ์ด๋ฅผ ์ถ์ ํ๊ธฐ ์ด๋ ต์ต๋๋ค.ํต์ฌ ๋ฌธ์ :
- ๋ผ์ธ 9:
useState<string | null>(null)- ํ์ ์ด ๊ณผ๋ํ๊ฒ ๊ด๋ฒ์- ๋ผ์ธ 77, 79, 93, 95: ํ๊ตญ์ด ๋ฌธ์์ด์ด ํธ๋ค๋ฌ ํธ์ถ๊ณผ ์กฐ๊ฑด ๋น๊ต์ ์ง์ ์ฌ์ฉ๋จ
LoginButton.tsx๋ ์ด๋ฏธ ID ๊ธฐ๋ฐ ์ค๊ณ('kakao'|'google')๋ฅผ ๋ชจ๋ฒ์ ์ผ๋ก ๊ตฌํ ์ค์ ์๋ ํด๊ฒฐ์ฑ (diff ์ฐธ๊ณ ):
+ type PlatformId = 'kakao' | 'google'; + const [recentPlatform, setRecentPlatform] = useState<PlatformId | null>(null); + const labelMap: Record<PlatformId, string> = { kakao: '์นด์นด์ค', google: '๊ตฌ๊ธ' }; - const handleLoginClick = (platform: string) => { + const handleLoginClick = (platform: PlatformId) => { - onClick={() => handleLoginClick('์นด์นด์ค')} + onClick={() => handleLoginClick('kakao')} - {recentPlatform === '์นด์นด์ค' && ( + {recentPlatform === 'kakao' && (์ด ๋ณ๊ฒฝ์
LoginButton.tsx์ ์ค๊ณ ํจํด๊ณผ ์ผ๊ด๋๋ฉฐ, ๋ค๋ฅธ ํ์ผ์ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค. ๋ผ๋ฒจ ์ ์ง๋ณด์๊ฐ ํ ๊ณณ(labelMap)์์๋ง ์ด๋ฃจ์ด์ ธ ๋ฒ๊ทธ ๊ฐ๋ฅ์ฑ์ ์ค์ ๋๋ค.src/shared/components/button/AddressCopy.tsx (1)
39-48: ๋ณต์ฌ ์คํจ ์ฝ๋ฐฑ ์ฒ๋ฆฌ ์ถ๊ฐ ๊ถ์ฅ
Copy(..., onSuccess, undefined)๋ก ์คํจ ์ฒ๋ฆฌ ๋ถ์ฌ. ๋คํธ์ํฌ/๊ถํ ๋ฌธ์ ์ ์ฌ์ฉ์ ํผ๋๋ฐฑ์ด ์์ต๋๋ค. ์ต์ํ ์ฝ์/ํ ์คํธ๋ก ์๋ ค์ฃผ์ธ์.Apply this diff:
const handleCopy = () => { Copy( value, () => { setCopied(true); setTimeout(() => setCopied(false), 1500); }, - undefined, + (err) => { + console.warn('[AddressCopy] copy failed', err); + // TODO: ํ์ ์ ํ ์คํธ/์๋ฆผ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์๋ด + }, ); };
๐ Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
๐ Files selected for processing (3)
src/pages/auth/index.tsx(4 hunks)src/shared/components/button/AddressCopy.tsx(3 hunks)src/shared/components/container/Card.tsx(1 hunks)
๐งฐ Additional context used
๐งฌ Code graph analysis (2)
src/pages/auth/index.tsx (1)
src/pages/auth/components/LoginButton.tsx (1)
LoginButton(33-67)
src/shared/components/button/AddressCopy.tsx (1)
src/shared/lib/utils.ts (1)
cn(71-73)
โฐ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-and-deploy
๐ Additional comments (3)
src/shared/components/button/AddressCopy.tsx (3)
9-9: ์ปจํ ์ด๋ overflow-hidden ์ถ๊ฐ๋ ์ ์ ํฉ๋๋ค๋ฅ๊ทผ ๋ชจ์๋ฆฌ์์ ๋ด์ฉ ๋์นจ ์๋ฆผ ์ฒ๋ฆฌ์ ์ ํจํฉ๋๋ค. ์คํ์ผ ๋ณ๊ฒฝ์ ๋ฌธ์ ์์ด ๋ณด์ ๋๋ค.
55-55: w-full ์ ํ ์ํฅ ๋ฒ์ ์ ๊ฒ๊ณ ์ ํญ์์
w-full๋ก ๋ฐ๋๋ฉด์ ๋ถ๋ชจ ๋ ์ด์์์ ๋ฐ๋ผ ์ค๋ฐ๊ฟ/์ถ์ฝ ํญ์ด ๋ฌ๋ผ์ง๋๋ค. ์ฌ์ฉ์ฒ์์ ์๋๋๋ก ๋์ํ๋์ง ํ์ธ ๋ถํ๋๋ฆฝ๋๋ค.
23-28: API ๋ณ๊ฒฝ ํธํ์ฑ ๊ฒ์ฆ ๊ฒฐ๊ณผ: ๊ธฐ์กด ํธ์ถ๋ถ ์์ - ์ถ๊ฐ ๊ฒ์ฆ ํ์
AddressCopy์ปดํฌ๋ํธ๋ ์ ์๋ง ์๊ณ ํ์ฌ ์ฝ๋๋ฒ ์ด์ค์์ ์ฌ์ฉ์ฒ๊ฐ ์์ต๋๋ค (import/usage ๊ฒ์ ๊ฒฐ๊ณผ 0). ๋ฐ๋ผ์labelโvalueAPI ๋ณ๊ฒฝ์ผ๋ก ์ธํ ๊ธฐ์กด ํธ์ถ๋ถ์ ํธํ์ฑ ๋ฌธ์ ๋ ๋ฐ์ํ์ง ์์ต๋๋ค.๊ทธ๋ฌ๋ ๋น ๋ฌธ์์ด ์ฒ๋ฆฌ์ ๋ํ ๋ฐฉ์ด ๋ก์ง์ ์ฌ์ ํ ๊ถ์ฅ๋ฉ๋๋ค:
value๊ฐ ๋น ๋ฌธ์์ด์ผ ๋ ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ (disabled ์ํ ๋๋ ํด๋ฐฑ ํ ์คํธ)- ์์ ์ ์์ ์ ํจํ๋ ํ์ ์ฌํญ์ ์๋
ํ์ธ ํ์: ์ด ์ปดํฌ๋ํธ๊ฐ ์๋ก์ด ๊ฒ์ธ์ง, ๋๋ ์์ ํ ๊ต์ฒด๋ ๊ฒ์ธ์ง ๊ฐ๋ฐ์ ํ์ธ ๊ถ์ฅ.
skyblue1232
left a comment
There was a problem hiding this comment.
๋น ๋ฅธ ์์ ๊ฐ์ฌํฉ๋๋ค!!
๐ฅ ์์ ๋ด์ฉ
๐ค ์ถํ ์์ ์ฌํญ
๐ย ์ด์
PR Point (To Reviewer)
๋ฒํผ ๊ณ ์ ๋ผ๋ฒจ -> ์ค์ฃผ์๊ฐ์ผ๋ก ๋ณ๊ฒฝ
address copy ๊ฐ ๋ฒํผ ์ ์ฒด ๊ณ ์ ui ์ธ์ค ์๊ณ ์์ ํ์ผ๋, ์ค ์ฃผ์๊ฐ ๋ณด์ฌ์ ธ์ผ ํ๋ค๊ณ ํด์ ๋ฐ๊ฟ๋จ์ต๋๋ค.

๊ณ ์ ๋ฒํผ ๊ฐ์ด ์๋ label ๊ณผ ์ฃผ์๊ฐ value ๋ถ๋ฆฌ๋ฅผ value ํ๋๋ก ํตํฉํ์ต๋๋ค.
์ฌ์ฉ๋ฒ
์ ๋ฒ์ด๋ ํฌ๊ฒ ๋ค๋ฅด์ง ์์ต๋๋ค.
์ถ์ฝ & ์ฃผ์ ๋ณต์ฌ์ ์ก์
๊ธ์๋ ์ปดํฌ๋ํธ๋ฅผ ๋ฒ์ด๋๋ฉด ์ถ์ฝ๋๊ฒ ํด๋จ์ต๋๋ค.
์ฃผ์ ๋ณต์ฌํ๊ณ ํ์ ์ฐฝ์ด๋ ๋ฉํธ๋ฅผ ๋์ธ๊น ํ๋ค๊ฐ ์์ด์ฝ์ ์ฒดํฌ ํ์๊ฐ ์๋๊ฒ์ ํ์ธํ๊ณ 1.5์ด๊ฐ ์ฒดํฌ ํ์ ๋ณด์ฌ์ฃผ๋๊ฒ ์ข์ ๊ฑฐ ๊ฐ์์ ๋ฐ๊ฟ๋ดค์ต๋๋ค.
์์ธํ๊ฑด ์์๋ณด์๋ฉด ์ดํด๊ฐ ๋น ๋ฆ ๋๋ค!
๐ธย ํผ๊ทธ๋ง ์คํฌ๋ฆฐ์ท or ๊ธฐ๋ฅ GIF
KakaoTalk_20251027_011413350.mp4
Summary by CodeRabbit
๋ฆด๋ฆฌ์ฆ ๋ ธํธ
์๋ก์ด ๊ธฐ๋ฅ
์คํ์ผ