[UI/#4] TextField, CategoryCircle, DiaryCard 컴포넌트 구현#6
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughReact Native용 공용 UI 컴포넌트로 Changes공용 UI 컴포넌트
Estimated code review effort: 3 (Moderate) | ~20 minutes Related issues: Suggested labels: ui, feature Suggested reviewers: UI 컴포넌트 리뷰 경험이 있는 팀원 Poem 원형 체크와 입력창이 생기고 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
components/ui/TextField.tsx (1)
24-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value상태 관리 및 렌더링 로직 확인 완료.
isFocused/isTextarea파생 값과 조건부 클래스,disabled/rightText처리 로직에 특별한 문제는 발견되지 않았습니다. 컴포넌트 시그니처도 가이드라인에 부합합니다(화살표 함수/export default미사용,View/Text/TextInput사용).다만 현재
TextField는 내부TextInput으로ref를 전달하지 않아, 부모 컴포넌트에서 포커스를 프로그래밍적으로 제어할 수 없습니다. React 19에서는forwardRef없이도 함수 컴포넌트가ref를 일반 prop으로 받을 수 있으므로, 향후 필요 시 이를 활용해ref를TextInput에 전달하는 것을 고려해볼 수 있습니다. 현재 PR 범위(이슈#4)에는 프로그래밍적 포커스 제어가 명시되어 있지 않아 필수는 아닙니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/ui/TextField.tsx` around lines 24 - 75, TextField currently drops any ref from parent components, so the internal TextInput cannot be focused programmatically. Update TextField to accept a ref in its props/signature and pass it through to the TextInput, keeping the existing isFocused, isTextarea, disabled, and rightText behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@components/ui/TextField.tsx`:
- Around line 24-75: TextField currently drops any ref from parent components,
so the internal TextInput cannot be focused programmatically. Update TextField
to accept a ref in its props/signature and pass it through to the TextInput,
keeping the existing isFocused, isTextarea, disabled, and rightText behavior
unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: eed39544-fd1d-47d0-b383-339f971a71bc
📒 Files selected for processing (1)
components/ui/TextField.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (2)
components/ui/CategoryCircle.tsx (2)
41-70: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value리스트 재렌더링 최적화 여지
CategoryCircle은 카테고리 목록에서 반복 렌더링될 가능성이 높은 순수 프레젠테이션 컴포넌트입니다. 부모 리렌더링 시 불필요한 재렌더링을 줄이기 위해React.memo로 감싸는 것을 고려해볼 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/ui/CategoryCircle.tsx` around lines 41 - 70, `CategoryCircle` is a frequently repeated presentational component and may re-render unnecessarily when its parent updates. Wrap the `CategoryCircle` component in `React.memo` so it only re-renders when `CategoryCircleProps` (`color`, `state`, `onPress`) actually change, and keep the existing `CategoryCircle` export/name intact so it can be located easily.
50-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win접근성 속성 누락
Pressable에accessibilityRole,accessibilityState={{ selected: isSelected, disabled: isDisabled }},accessibilityLabel등이 없어 스크린 리더 사용자가 카테고리 선택 상태를 인지하기 어렵습니다.state가 변경되는 만큼 접근성 상태를 함께 노출하는 것이 좋습니다.♿️ 제안
<Pressable disabled={isDisabled} onPress={onPress} + accessibilityRole="button" + accessibilityState={{ selected: isSelected, disabled: isDisabled }} className={`h-9 w-9 items-center justify-center rounded-full ${🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/ui/CategoryCircle.tsx` around lines 50 - 58, The Pressable in CategoryCircle is missing accessibility metadata, so update its props to expose the selection and disabled state to screen readers. Add an appropriate accessibilityRole, accessibilityState using isSelected and isDisabled, and a meaningful accessibilityLabel based on the category/selection state so users can understand and interact with the category button.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@components/ui/CategoryCircle.tsx`:
- Around line 41-70: `CategoryCircle` is a frequently repeated presentational
component and may re-render unnecessarily when its parent updates. Wrap the
`CategoryCircle` component in `React.memo` so it only re-renders when
`CategoryCircleProps` (`color`, `state`, `onPress`) actually change, and keep
the existing `CategoryCircle` export/name intact so it can be located easily.
- Around line 50-58: The Pressable in CategoryCircle is missing accessibility
metadata, so update its props to expose the selection and disabled state to
screen readers. Add an appropriate accessibilityRole, accessibilityState using
isSelected and isDisabled, and a meaningful accessibilityLabel based on the
category/selection state so users can understand and interact with the category
button.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 3dadcf54-72d1-4424-872e-3705b2945ab8
📒 Files selected for processing (1)
components/ui/CategoryCircle.tsx
Hyochan02
left a comment
There was a problem hiding this comment.
처음 다뤄보는 라이브러리로 작업하느라 힘들었을텐데 고생하셨습니다 :)
코멘트 확인 후 수정한 부분은 resolve 눌러서 코멘트 닫아주시면 됩니다 :)
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/components/common/CategoryCircle.tsx (1)
53-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win터치 영역/접근성 속성 보완 고려
h-9 w-9(36x36px)는 일반적으로 권장되는 최소 터치 타겟(44x44px)보다 작습니다.hitSlop을 추가하거나 크기를 늘리는 것을 고려해보세요. 또한 스크린 리더 사용자를 위해accessibilityRole="button"과accessibilityState={{ selected: isSelected, disabled: isDisabled }}를 추가하면 상태 전달이 명확해집니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/CategoryCircle.tsx` around lines 53 - 62, The Pressable in CategoryCircle is too small for a comfortable touch target and is missing accessibility state/role metadata. Update the CategoryCircle component’s Pressable to either expand the tappable area with hitSlop or increase the visual size beyond h-9 w-9, and add accessibilityRole="button" plus accessibilityState using isSelected and isDisabled so screen readers can announce the control state clearly.src/components/common/TextField.tsx (1)
52-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value하드코딩된 색상값을 디자인 토큰으로 통일 고려
다른 스타일은 모두 tailwind 클래스(
cn)로 관리되는데,placeholderTextColor만 하드코딩된 hex 값(#949997)을 사용하고 있습니다. 색상 값이 바뀔 경우 이 부분만 누락되어 불일치가 발생할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/TextField.tsx` at line 52, The TextField component is still using a hardcoded placeholder color instead of the shared design system token. Update the placeholderTextColor usage in TextField so it pulls from the same token/theme source used by the cn-based Tailwind styling, keeping the placeholder color consistent with the rest of the component styles.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/components/common/CategoryCircle.tsx`:
- Around line 53-62: The Pressable in CategoryCircle is too small for a
comfortable touch target and is missing accessibility state/role metadata.
Update the CategoryCircle component’s Pressable to either expand the tappable
area with hitSlop or increase the visual size beyond h-9 w-9, and add
accessibilityRole="button" plus accessibilityState using isSelected and
isDisabled so screen readers can announce the control state clearly.
In `@src/components/common/TextField.tsx`:
- Line 52: The TextField component is still using a hardcoded placeholder color
instead of the shared design system token. Update the placeholderTextColor usage
in TextField so it pulls from the same token/theme source used by the cn-based
Tailwind styling, keeping the placeholder color consistent with the rest of the
component styles.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 53622efe-b551-4a7b-bd3a-e67fea3c4b7e
📒 Files selected for processing (2)
src/components/common/CategoryCircle.tsxsrc/components/common/TextField.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/common/DiaryCard.tsx (1)
141-160: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value이미지에 접근성 속성 누락.
일기 사진에
accessibilityLabel또는 장식용 이미지임을 나타내는accessible={false}가 없어 스크린 리더 사용자 경험이 떨어질 수 있습니다.♿ 제안
<Image key={`${imageVariant}-${index}`} source={source} resizeMode="cover" + accessibilityLabel={`${props.title} 이미지 ${index + 1}`}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/DiaryCard.tsx` around lines 141 - 160, The Image elements rendered in DiaryCard are missing accessibility handling, so update the image mapping in DiaryCard to either provide an accessibilityLabel for each diary photo or mark decorative images with accessible={false}. Use the existing Image render inside the images.map block and make the choice consistent with how these photos should be announced to screen readers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/common/DiaryCard.tsx`:
- Around line 65-68: The DiaryCard component has multiple prettier/prettier
formatting violations across the affected sections, including line wrapping and
Tailwind class ordering. Run the formatter on DiaryCard.tsx and clean up the
flagged JSX/TypeScript blocks around DiaryCardImageVariant and the other listed
snippets so the file matches the project’s Prettier/ESLint rules. Use the
DiaryCard component and DiaryCardImageVariant type as anchors while fixing all
reported formatting spots.
---
Nitpick comments:
In `@src/components/common/DiaryCard.tsx`:
- Around line 141-160: The Image elements rendered in DiaryCard are missing
accessibility handling, so update the image mapping in DiaryCard to either
provide an accessibilityLabel for each diary photo or mark decorative images
with accessible={false}. Use the existing Image render inside the images.map
block and make the choice consistent with how these photos should be announced
to screen readers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a5c72644-86b9-42cc-a503-02be3133c821
📒 Files selected for processing (1)
src/components/common/DiaryCard.tsx
Hyochan02
left a comment
There was a problem hiding this comment.
일기 카드 컴포넌트까지 고생하셨습니다!!
추가 코멘트 확인 후 수정 부탁드립니다 :)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/common/CategoryCircle.tsx`:
- Around line 64-70: In CategoryCircle, the selected-but-not-disabled branch is
passing a Tailwind class string to CheckIcon instead of a real color value.
Update the color prop in the isSelected/isDisabled render path so CheckIcon
receives the intended actual white color value when isSelected is true and
isDisabled is false, while keeping the disabled gray value unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 002bf37c-f26f-47a0-8543-de6a6409d24e
⛔ Files ignored due to path filters (1)
assets/icons/check.svgis excluded by!**/*.svg,!**/assets/**
📒 Files selected for processing (3)
src/components/common/CategoryCircle.tsxsrc/components/common/DiaryCard.tsxsrc/types/diaries/diaryCard.types.ts
| {isSelected || isDisabled ? ( | ||
| <CheckIcon | ||
| width={24} | ||
| height={24} | ||
| color={isDisabled ? "#AEB2B0" : "bg-gray-0"} | ||
| /> | ||
| ) : null} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
선택(비활성 아님) 상태의 체크 아이콘 색상 값이 잘못됨.
Line 68에서 isDisabled가 false인 경우(isSelected만 true인 경우) color에 "bg-gray-0"이 전달됩니다. 이는 NativeWind/Tailwind 클래스명이며, CheckIcon(SVG 컴포넌트)의 color/fill prop은 실제 색상 값(hex 등)을 기대하므로 유효한 색상으로 처리되지 않습니다. PR 설명에 따르면 선택 시 흰색 체크가 표시되어야 하므로, 실제로는 체크 아이콘이 의도한 흰색으로 렌더링되지 않을 가능성이 높습니다.
🐛 제안하는 수정
{isSelected || isDisabled ? (
<CheckIcon
width={24}
height={24}
- color={isDisabled ? "`#AEB2B0`" : "bg-gray-0"}
+ color={isDisabled ? "`#AEB2B0`" : "`#FFFFFF`"}
/>
) : null}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {isSelected || isDisabled ? ( | |
| <CheckIcon | |
| width={24} | |
| height={24} | |
| color={isDisabled ? "#AEB2B0" : "bg-gray-0"} | |
| /> | |
| ) : null} | |
| {isSelected || isDisabled ? ( | |
| <CheckIcon | |
| width={24} | |
| height={24} | |
| color={isDisabled ? "`#AEB2B0`" : "`#FFFFFF`"} | |
| /> | |
| ) : null} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/common/CategoryCircle.tsx` around lines 64 - 70, In
CategoryCircle, the selected-but-not-disabled branch is passing a Tailwind class
string to CheckIcon instead of a real color value. Update the color prop in the
isSelected/isDisabled render path so CheckIcon receives the intended actual
white color value when isSelected is true and isDisabled is false, while keeping
the disabled gray value unchanged.
📌 관련 이슈번호
(Closes 키워드가 있어야 PR이 머지되었을 때 이슈가 자동으로 닫힌다)
📌 PR 유형
어떤 변경 사항이 있나요?
📌 PR 요약
📌 작업 세부 내용
TextField 컴포넌트 구현
typeprops로 구분sizeprops로 구분00:00등) 표시 지원className방식 스타일 적용CategoryCircle 컴포넌트 구현
stateprops로 구분DiaryCard 컴포넌트 구현
variantprops로 구분📸 스크린샷 (선택)
🔗 참고 자료