Conversation
|
📚 Storybook is ready for review! |
Walkthroughapps/web에 Radix UI Tabs 의존성을 추가하고, Tabs 컴포넌트와 타입 정의를 신설했으며, 해당 컴포넌트의 Storybook 스토리를 추가했습니다. 컴포넌트는 Radix Tabs 프리미티브를 조합해 리스트/트리거 렌더링과 값 제어를 지원합니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as 사용자
participant Tabs as Tabs 컴포넌트
participant Radix as Radix Tabs(Root/List/Trigger)
participant DOM as DOM
User->>Tabs: 탭 클릭(새 value)
Tabs->>Radix: value 전달(제어형)
Radix->>DOM: data-state="active"/"inactive" 반영
note over DOM: 스타일 상태 전환(활성/비활성)
DOM-->>User: 활성 탭 표시
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 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 |
|
📚 Storybook is ready for review! |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
apps/web/src/shared/components/Tabs/Tabs.stories.tsx (1)
5-40: 인라인 스타일 대신 CSS-in-JS 사용을 권장합니다.tabItems의 label에서 인라인 스타일을 사용하고 있습니다. 프로젝트에서 PandaCSS를 사용하고 있으므로, 일관성을 위해 css 헬퍼 함수를 사용하는 것이 좋겠습니다.
+import { css } from "../../../../styled-system/css"; const tabItems = [ { value: "일일 업무", label: ( - <div style={{ display: "flex", flexDirection: "row", alignItems: "center", gap: "6px" }}> + <div className={css({ display: "flex", flexDirection: "row", alignItems: "center", gap: "6px" })}> {/* SVG 내용 */} <div>일일 업무</div> </div> ), }, { value: "회의 일정", label: ( - <div style={{ display: "flex", flexDirection: "row", alignItems: "center", gap: "6px" }}> + <div className={css({ display: "flex", flexDirection: "row", alignItems: "center", gap: "6px" })}> {/* SVG 내용 */} <div>회의 일정</div> </div> ), }, ];apps/web/src/shared/components/Tabs/Tabs.tsx (2)
8-8: 사용되지 않는 listRef 제거를 고려해보세요.listRef가 선언되고 할당되지만 실제로는 사용되지 않고 있습니다. UseTabsIndicatorProps 타입도 정의되어 있지만 현재 구현에서는 활용되지 않습니다. 향후 indicator 기능 구현을 위한 준비 작업이라면 주석으로 의도를 명시하는 것이 좋겠습니다.
export const Tabs = (props: TabsProps) => { const { width = "100%", tabItems, value, ...rest } = props; - const listRef = useRef<HTMLDivElement>(null); + // TODO: indicator 기능 구현 시 활용 예정 + // const listRef = useRef<HTMLDivElement>(null);
21-32: 접근성을 위한 aria-label 추가를 권장합니다.TabsBase.List에 적절한 aria-label을 추가하면 스크린 리더 사용자에게 더 나은 경험을 제공할 수 있습니다.
<TabsBase.List ref={listRef} data-orientation="horizontal" + aria-label="탭 목록" className={css({ position: "relative", display: "flex", height: "35px", padding: "0 20px", backgroundColor: "#fff", boxSizing: "border-box", })} >
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
apps/web/package.json(1 hunks)apps/web/src/shared/components/Tabs/Tabs.stories.tsx(1 hunks)apps/web/src/shared/components/Tabs/Tabs.tsx(1 hunks)apps/web/src/shared/components/Tabs/Tabs.type.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/src/shared/components/Tabs/Tabs.stories.tsx (2)
apps/web/src/shared/components/Tabs/Tabs.tsx (1)
Tabs(6-63)apps/web/src/shared/components/Tabs/Tabs.type.ts (1)
TabsProps(13-16)
🔇 Additional comments (3)
apps/web/package.json (1)
19-19: 추가된 Radix UI Tabs 의존성이 최신 버전이며 안전합니다.추가된 @radix-ui/react-tabs 버전 1.1.13은 최신 버전이며, 보안 스캔 결과 위험 요소가 탐지되지 않아 안전한 것으로 확인되었습니다. 이 의존성은 새로 추가된 Tabs 컴포넌트 구현에 필요한 라이브러리입니다.
apps/web/src/shared/components/Tabs/Tabs.stories.tsx (1)
81-81: key 속성을 이용한 강제 리마운트 로직이 우아합니다.defaultValue 변경 시 key를 사용하여 컴포넌트를 강제 리마운트하는 접근 방식이 Storybook 환경에서 초기 상태를 올바르게 반영하기 위한 좋은 해결책입니다.
apps/web/src/shared/components/Tabs/Tabs.tsx (1)
33-59: LGTM! 잘 구조화된 Tabs 구현입니다.tabItems를 순회하여 동적으로 Trigger를 생성하는 로직과 data-state에 따른 스타일링이 깔끔하게 구현되어 있습니다. Radix UI의 접근성 기능을 활용하면서도 커스텀 스타일링을 잘 적용했습니다.
| interface TabItem { | ||
| value: string; | ||
| label: ReactNode; | ||
| } |
There was a problem hiding this comment.
TabItem 인터페이스 export가 누락되었습니다.
TabItem 인터페이스가 다른 인터페이스들과 달리 export되지 않았습니다. Tabs 컴포넌트와 Storybook에서 이 타입을 사용하므로 export가 필요합니다.
-interface TabItem {
+export interface TabItem {
value: string;
label: ReactNode;
}📝 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.
| interface TabItem { | |
| value: string; | |
| label: ReactNode; | |
| } | |
| export interface TabItem { | |
| value: string; | |
| label: ReactNode; | |
| } |
🤖 Prompt for AI Agents
In apps/web/src/shared/components/Tabs/Tabs.type.ts around lines 4 to 7, the
TabItem interface is declared but not exported; add the export keyword to the
interface declaration (e.g., export interface TabItem { ... }) so Tabs component
and Storybook can import the type, and update any imports if necessary to
reflect the exported name.
📝 PR 유형
📝 PR 설명
Tabs 컴포넌트 마이그레이션 작업입니다.
관련된 이슈 넘버
close #59
✅ 작업 목록
MR하기 전에 확인해주세요
📚 논의사항
📚 ETC
Summary by CodeRabbit
New Features
Documentation
Chores