Skip to content

Comments

Feat(design-system): 카테고리 칩 컴포넌트#34

Merged
jllee000 merged 10 commits intodevelopfrom
feat/#29/chip-component
Aug 25, 2025
Merged

Feat(design-system): 카테고리 칩 컴포넌트#34
jllee000 merged 10 commits intodevelopfrom
feat/#29/chip-component

Conversation

@jllee000
Copy link
Collaborator

@jllee000 jllee000 commented Aug 25, 2025

📌 Related Issues

관련된 Issue를 태그해주세요. (e.g. - close #25)

✅ 체크 리스트

  • PR 제목의 형식을 잘 작성했나요? e.g. Feat(client): PR 템플릿 작성
  • 빌드가 성공했나요? (pnpm build)

📄 Tasks

  • 색상에 따른 칩 분기

⭐ PR Point (To Reviewer)

색상 코드값(#000000 같은) 기준으로 color 분기해서 작업할까 하다가, 어차피 색상 코드 받은 걸로 그거에 맞는 텍스트 색상도 세트로 바뀌는 거라서, 색상 코드값을 props로 받지 않고 하나의 색상 세트 네이밍으로 받아 관리했어요. ex. red면 이에 맞는 배경색과 텍스트 적용
++ 서버 리드와 이 색상값 전달 타입에 대해서 논의 후 결정했습니다!

📷 Screenshot

image

📷 CodeRabbit

  • 신기능
    • Chip 컴포넌트 추가 — 색상 변형과 선택적 카테고리 텍스트 지원, 디자인 시스템 인덱스에 노출.
  • 스토리북
    • Storybook 설정 및 미리보기 구성 추가, Chip 및 여러 컴포넌트용 스토리(Chip, Button, Header, Page, Configure 등) 추가.
  • 스타일
    • Storybook용 버튼/헤더/페이지 스타일 시트 추가로 일관된 UI 제공.
  • 테스트
    • Vitest·Playwright 연동 및 Storybook용 테스트 셋업 추가.
  • 기타
    • package 스크립트 및 개발 의존성에 Storybook·테스트 도구 추가.

@coderabbitai
Copy link

coderabbitai bot commented Aug 25, 2025

Warning

Rate limit exceeded

@jllee000 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 25 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 93c504c and e1bc684.

📒 Files selected for processing (3)
  • packages/design-system/src/components/chip/Chip.stories.tsx (1 hunks)
  • packages/design-system/src/components/chip/Chip.tsx (1 hunks)
  • packages/design-system/src/components/index.ts (1 hunks)

Walkthrough

design-system 패키지에 새로운 Chip 컴포넌트를 추가하고 components 인덱스에 재수출했습니다. 또한 Storybook 및 Vitest 관련 구성(.storybook, vitest.config 등)과 여러 데모/스토리 파일이 추가되었습니다.

Changes

Cohort / File(s) Change Summary
Chip 컴포넌트
packages/design-system/src/components/chip/Chip.tsx
신규 Chip 컴포넌트 추가: cva 기반 color variants, color 필수 prop, 선택적 category 텍스트, span 렌더링, default export.
Components 인덱스
packages/design-system/src/components/index.ts
export { default as Chip } from './chip/Chip'; 추가 — Chip 공개 재수출.
Storybook 설정
.storybook/main.ts, .storybook/preview.ts, .storybook/vitest.setup.ts, vitest.config.ts, vitest.shims.d.ts, package.json
Storybook/Vitest 통합 및 스크립트/의존성 추가, Storybook 플러그인/프레임워크 경로 절대해결 로직, vitest 프로젝트에 storybookTest 플러그인 연결.
Chip 스토리
packages/design-system/src/components/chip/Chip.stories.tsx
Chip용 Storybook 스토리(기본, AllColors) 추가 및 한글 문서화/argTypes 정의.
예제 컴포넌트 및 스토리들
stories/* (예: stories/Button.tsx, stories/Header.tsx, stories/Page.tsx, stories/*.stories.ts, stories/*.css, stories/Configure.mdx)
Storybook 데모 컴포넌트(Button, Header, Page), 관련 스토리 및 스타일, MDX 문서 추가.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Consumer as 소비자
    participant Index as components/index
    participant Chip as Chip 컴포넌트
    participant CVA as class-variance-authority

    Consumer->>Index: import { Chip } from 'design-system/components'
    Consumer->>Chip: <Chip color="red" category="프론트엔드" />
    Chip->>CVA: variants({ color })
    CVA-->>Chip: className
    Chip-->>Consumer: <span class="...">프론트엔드</span>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
카테고리 칩 컴포넌트 제작 — 색상별 칩 분기, 카테고리 정보 ( #29 )
Progress Bar 구현 및 분기/접근성 ( #25 ) 변경사항에 Progress 컴포넌트나 관련 스타일/스토리가 포함되어 있지 않음.

Out-of-scope changes

Code Change Explanation
Storybook/Vitest config 추가 (.storybook/main.ts, .storybook/preview.ts, vitest.config.ts) Storybook 및 테스트 인프라 추가는 #29(Chip)와 #25(Progress) 구현 요구와 직접 관련 없음.
여러 데모/스토리 컴포넌트 추가 (stories/Button.tsx, stories/Header.tsx, stories/Page.tsx, stories/*.stories.ts) Chip 기능 구현 이슈와 무관한 예제/데모 컴포넌트 및 스토리 추가임.
MDX 문서 및 스타일 시트 (stories/Configure.mdx, stories/*.css) 문서/스타일링 추가는 Chip/Progress 기능 요구와 직접 연관되지 않음.

Possibly related PRs

Suggested labels

🛠️ Feature, frontend, needs-review

Suggested reviewers

  • jjangminii
  • constantly-dev

Poem

폴짝, 새 칩 하나 나왔네 🐇
색을 갈아입고 카테고리 속삭여,
작은 스팬 위에 반짝이는 이름,
UI 들판에 점 하나 놓고선,
토끼가 깡총—축하 춤을 춘다 ✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#29/chip-component

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the feat 기능 개발하라 개발 달려라 달려 label Aug 25, 2025
@github-actions github-actions bot requested a review from jjangminii August 25, 2025 13:17
@github-actions
Copy link

github-actions bot commented Aug 25, 2025

✅ Storybook chromatic 배포 확인:
🐿️ storybook

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
packages/design-system/src/components/chip/Chip.tsx (3)

18-39: defaultVariants 사용성과 prop 요구사항 정렬

defaultVariants.color = 'red'가 설정되어 있는데, 기존에는 color가 필수라 디폴트가 의미가 없었습니다. 위 코멘트대로 color?:로 바꾸면 디폴트가 실제로 의미를 가집니다. 만약 color를 필수로 유지하려면 defaultVariants를 제거해 혼란을 줄이는 것을 권장합니다.

디자인 의도(디폴트 레드 허용 vs 항상 명시 필요)에 따라 최종 방향을 확인해 주세요.


40-44: 문자 콘텐츠 확장성(children 지원) 검토

향후 아이콘+텍스트 등 복합 콘텐츠(예: 카테고리 아이콘)를 담으려면 category 문자열 전용 대신 children을 기본으로 하고 category는 deprecated 또는 fallback으로 두는 전략이 유연합니다.

원한다면 children ?? category 패턴으로의 마이그레이션 diff 제공 가능합니다.


46-46: 타입도 공개 export하여 DX 향상

소비자가 색상 토큰/프롭 타입을 재사용할 수 있도록 타입 export를 권장합니다.

적용 diff:

 export default Chip;
+export type { ChipProps, ChipColor };
packages/design-system/src/components/index.ts (1)

4-4: 타입 재export로 소비자 편의 증대

ChipProps, ChipColor 타입도 함께 re-export하면 외부에서 타입을 쉽게 참조할 수 있습니다. (Chip.tsx에서 타입들을 export하도록 변경이 선행되어야 합니다.)

적용 diff:

 export { default as Chip } from './chip/Chip';
+export type { ChipProps, ChipColor } from './chip/Chip';
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3cbf52e and a6a2a34.

📒 Files selected for processing (2)
  • packages/design-system/src/components/chip/Chip.tsx (1 hunks)
  • packages/design-system/src/components/index.ts (1 hunks)
🔇 Additional comments (2)
packages/design-system/src/components/chip/Chip.tsx (1)

40-44: 접근성 가이드(빈 콘텐츠 처리)

category가 전달되지 않으면 빈 <span>이 렌더링됩니다. 이 경우는 aria-hidden="true"로 장식적 요소임을 명시하거나, 시각적으로만 표시한다면 aria-label을 제공하는 방안을 검토해 주세요.

필요 시 역할/레이블 설계를 함께 정의해 드립니다.

packages/design-system/src/components/index.ts (1)

4-4: Chip 공개 export 추가 확인

컴포넌트 인덱스에서 Chip 공개가 적절히 이루어졌습니다. 소비자 입장에서도 사용성이 좋아집니다.

@@ -0,0 +1,46 @@
import { cva } from 'class-variance-authority';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

유틸 및 타입 임포트 보강: cx(클래스 병합)와 HTMLAttributes 임포트

className 합성을 위해 cx를 같이 쓰고, React 타입은 네임스페이스 접근 대신 타입 임포트를 권장합니다.

적용 diff:

-import { cva } from 'class-variance-authority';
+import { cva, cx } from 'class-variance-authority';
+import type { HTMLAttributes } from 'react';
📝 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.

Suggested change
import { cva } from 'class-variance-authority';
import { cva, cx } from 'class-variance-authority';
import type { HTMLAttributes } from 'react';
🤖 Prompt for AI Agents
In packages/design-system/src/components/chip/Chip.tsx around line 1, the file
only imports cva but the review requests strengthening imports: add cx from
'class-variance-authority' to use for className merging and import the React
HTMLAttributes type as a type import (import type { HTMLAttributes } from
'react') instead of using the React namespace; update the component props to use
HTMLAttributes<HTMLDivElement> (or the appropriate element) and replace any
React.HTMLAttributes usages with the imported HTMLAttributes, and use cx(...)
when combining className strings to ensure correct class merging.

Comment on lines 14 to 17
interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
color: ChipColor;
category?: string;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

DOM 요소와 props 타입 불일치(Span 렌더링 + ButtonHTMLAttributes) — 타입 및 시맨틱 정정 제안

렌더링은 <span>인데 React.ButtonHTMLAttributes<HTMLButtonElement>를 확장하고 있어 시맨틱과 타입이 어긋납니다. 또한 React 네임스페이스 타입 사용 시 별도 타입 임포트가 없으면 TS 구성에 따라 오류가 날 수 있습니다. Span 용으로 맞추고 color를 optional로 두면 defaultVariants('red')도 자연스럽게 작동합니다.

적용 diff:

-interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
-  color: ChipColor;
+interface ChipProps extends HTMLAttributes<HTMLSpanElement> {
+  color?: ChipColor;
   category?: string;
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/design-system/src/components/chip/Chip.tsx around lines 14 to 17,
the component currently extends React.ButtonHTMLAttributes<HTMLButtonElement>
while rendering a <span>, causing a semantic and type mismatch and potential
React namespace issues; change the props to extend
React.HTMLAttributes<HTMLSpanElement> (or import HTMLAttributes and use
HTMLAttributes<HTMLSpanElement>) and make the color prop optional (color?:
ChipColor) so the component can rely on its defaultVariants('red') fallback;
keep category optional as-is and ensure any downstream usages/type imports are
updated accordingly.

Comment on lines +40 to +44
const Chip = ({ color, category }: ChipProps) => {
return (
<span className={ChipColorVariants({ color: color })}>{category}</span>
);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

className 합성 및 나머지 props 전달 누락 — 구성 가능성 향상

현재 className 오버라이드/확장과 이벤트/데이터 속성 전달이 불가능합니다. 디자인 시스템 컴포넌트로서 구성 가능성을 높이기 위해 전달/병합을 추가하세요.

적용 diff:

-const Chip = ({ color, category }: ChipProps) => {
-  return (
-    <span className={ChipColorVariants({ color: color })}>{category}</span>
-  );
-};
+const Chip = ({ color, category, className, ...rest }: ChipProps) => {
+  return (
+    <span
+      className={cx(ChipColorVariants({ color }), className)}
+      {...rest}
+    >
+      {category}
+    </span>
+  );
+};
📝 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.

Suggested change
const Chip = ({ color, category }: ChipProps) => {
return (
<span className={ChipColorVariants({ color: color })}>{category}</span>
);
};
const Chip = ({ color, category, className, ...rest }: ChipProps) => {
return (
<span
className={cx(ChipColorVariants({ color }), className)}
{...rest}
>
{category}
</span>
);
};
🤖 Prompt for AI Agents
In packages/design-system/src/components/chip/Chip.tsx around lines 40 to 44,
the component currently ignores incoming className and other DOM/event/data
props; update ChipProps to extend React.HTMLAttributes<HTMLSpanElement> (or
include a rest props bag), accept ...props in the component signature, and merge
incoming props.className with ChipColorVariants({ color }) using the project's
class-merge utility (clsx/twMerge/clsx) before passing to the span; finally
spread the remaining props onto the span so event handlers and data attributes
are forwarded.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (20)
vitest.shims.d.ts (1)

1-1: Vitest 전역 타입 선언 누락 확인 및 보강 제안

아래 tsconfig.json 파일들에서 compilerOptions.types"vitest"가 모두 누락된 것이 확인되었습니다:

  • apps/client/tsconfig.json: ✖ vitest types missing
  • apps/extension/tsconfig.json: ✖ vitest types missing
  • apps/landing/tsconfig.json: ✖ vitest types missing
  • packages/design-system/tsconfig.json: ✖ vitest types missing

따라서 전역으로 describe/it/expect 등을 안전하게 인식시키기 위해, 다음 중 한 가지 방법을 선택하여 적용해 주세요:

Shim 파일에 선언 추가
파일 vitest.shims.d.ts 상단을 아래와 같이 수정

+/// <reference types="vitest" />
 /// <reference types="@vitest/browser/providers/playwright" />

tsconfig.json 수정
각 프로젝트의 tsconfig*.json에서

{
  "compilerOptions": {
    "types": [
      /* 기존 항목들 */,
      "vitest"
    ]
  }
}

위 중 편한 방식을 선택해 적용해 주시면 전역 타입 인식 문제가 해소됩니다.

.storybook/preview.ts (2)

1-1: Preview 타입 import 경로를 '@storybook/react'로 교체 권장

Storybook 9.x에서는 Preview 타입을 @storybook/react에서 가져오는 것이 표준입니다. @storybook/react-vite에서 타입을 가져오면 IDE/빌드에서 타입 해석 오류가 발생할 수 있습니다.

-import type { Preview } from '@storybook/react-vite';
+import type { Preview } from '@storybook/react';

12-17: a11y 설정의 test: 'todo'는 표준 옵션이 아닙니다

@storybook/addon-a11ydisable, manual, config 등의 옵션을 지원합니다. 현재 test: 'todo'는 무시될 가능성이 높습니다. “UI에만 표시하고 CI 실패는 원치 않음”이라면 manual: true로 명시하거나 테스트 러너 측에서 임계치를 제어하는 편이 명확합니다.

   a11y: {
-      // 'todo' - show a11y violations in the test UI only
-      // 'error' - fail CI on a11y violations
-      // 'off' - skip a11y checks entirely
-      test: 'todo',
+      // 개발 중에만 a11y 패널에서 확인하고, 자동 스캔은 비활성화
+      manual: true,
   },

위 변경 후 pnpm storybook 실행 시 a11y 패널이 기대대로 동작하는지 확인해 주세요(자동 스캔 비활성화, 수동 검사만 노출).

package.json (1)

10-12: 도구 체인 버전 호환성 확인 결과

  • @storybook/react-vite@9.1.3의 peerDependencies(vite: ^5.0.0 ∥ ^6.0.0 ∥ ^7.0.0)가 프로젝트의 vite@7.1.2와 호환됩니다.
  • storybook@9.1.3는 peerDependencies로 prettier:^2 ∥ ^3만 요구하므로 별도 버전 충돌 우려가 없습니다.
  • vitest@3.2.4@vitest/browser@3.2.4는 상호 매칭되는 peerDependencies(jsdom, happy-dom, @vitest/ui@3.2.4, @types/node 등)를 가지며, 설치된 버전과 호환됩니다.

추가로, MDX에서 @storybook/blocks를 사용하실 경우

  • @storybook/addon-docs@9.1.3@storybook/blocks를 자동 설치하지 않으므로
  • 필요 시 npm install --save-dev @storybook/blocks@latest 또는 pnpm add -D @storybook/blocks@latest를 통해 직접 추가해주세요.
stories/Configure.mdx (3)

199-205: 문구 오탈자 수정 제안

“Follow guided walkthroughs on for key workflows.”에서 “on”이 중복된 것으로 보입니다.

-      <p>Follow guided walkthroughs on for key workflows.</p>
+      <p>Follow guided walkthroughs for key workflows.</p>

253-257: grid-gap 대신 gap 사용 권장

grid-gap은 구문 유지되지만 gap으로 대체되었습니다. 최신 속성 사용을 권장합니다.

   .sb-features-grid {
     display: grid;
     grid-template-columns: repeat(2, 1fr);
-    grid-gap: 32px 20px;
+    gap: 32px 20px;
   }

354-361: 중복된 margin-left 선언 정리

서로 다른 값으로 두 번 선언되어 있어 마지막 값만 적용됩니다. 불필요한 선언을 제거하세요.

   .sb-addon-img img {
     width: 1200px;
     transform: rotate(-12deg);
-    margin-left: 0;
     margin-top: 48px;
     margin-bottom: -40px;
     margin-left: -24px;
   }
packages/design-system/src/components/chip/Chip.stories.tsx (3)

4-12: 메타 타입 표기는 satisfies로 전환 권장

Storybook CSF8 권장 패턴에 맞춰 const meta = { ... } satisfies Meta<typeof Chip>로 작성하면 과잉 속성 탐지와 추론 품질이 좋아집니다.

-const meta: Meta<typeof Chip> = {
+const meta = {
   title: 'UI/Chip',
   component: Chip,
   tags: ['autodocs'],
   args: {
     category: 'Frontend',
     color: 'red',
   },
-};
+} satisfies Meta<typeof Chip>;

79-83: AllColors 스토리에서 color 컨트롤 비활성화

루프에서 color를 강제 설정하므로 Controls 패널에서 color를 노출하면 사용자가 바꿔도 즉시 덮어써져 혼란을 줄 수 있습니다. 컨트롤 제외를 권장합니다.

   parameters: {
     docs: {
       description: { story: '팔레트 뷰: 모든 색상 변형을 한 번에 미리보기' },
     },
+    controls: { exclude: ['color'] },
   },

17-32: 색상 옵션 하드코딩 중복 제거 및 재사용

Chip.stories.tsxargTypes.color.optionsAllColors 스토리 내 colors 배열이 동일한 색상 목록을 하드코딩하고 있으며, 이 목록은 Chip.tsxChipColor 타입 및 cva variants 정의와도 중복됩니다. 이로 인해 토큰 드리프트 위험이 있으므로, 한 곳에서만 관리하도록 리팩터링을 권장합니다.

주요 변경 제안:

  • packages/design-system/src/components/chip/Chip.tsx

    • 색상 목록을 상수로 추출하여 내보내기
    • ChipColor 타입을 해당 상수를 기반으로 재정의
    import { cva } from 'class-variance-authority';
    - type ChipColor = 'red' | 'purple' | … ;
    + export const CHIP_COLORS = [
    +   'red',
    +   'purple',
    +   'navyblue',
    +   'skyblue',
    +   'emerald',
    +   'navygreen',
    +   'khaki',
    +   'orange',
    +   'amber',
    +   'maroon',
    + ] as const;
    + export type ChipColor = typeof CHIP_COLORS[number];
    
    interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
      color: ChipColor;
      category?: string;
    }
    const ChipColorVariants = cva( /* … */ );
  • packages/design-system/src/components/chip/Chip.stories.tsx

    • argTypes.color.optionsAllColors 스토리의 colors 배열에서 하드코딩된 목록을 삭제하고, CHIP_COLORS를 import하여 재사용
       argTypes: {
         color: {
           control: { type: 'select' },
    -      options: [
    -        'red', 'purple', /* … */ 'maroon',
    -      ],
    +      options: CHIP_COLORS,
           description: '카테고리 색상',
         },
       },
    
    export const AllColors: Story = {
      args: { category: 'Category' },
      render: (args) => {
    -    const colors = [ 'red', 'purple', /* … */ 'maroon' ] as const;
    +    const colors = CHIP_COLORS;
         /* … */
      },
    };

이렇게 하면 색상 토큰이 한 곳에서 정의되어 컴포넌트–스토리 간에 항상 동기화되며, 향후 색상 추가·삭제 시 유지보수 부담을 줄일 수 있습니다. 필요하시면 패치 작성도 도와드리겠습니다.

stories/Page.tsx (1)

10-11: React.FC 사용 지양 및 상태 타입 명시화

React.FC는 암묵적 children, 제네릭 제약 등으로 비추천 경향입니다. 단순 함수 컴포넌트로 전환하고 useState<User | undefined>를 명시하면 의도가 더 선명합니다.

-export const Page: React.FC = () => {
-  const [user, setUser] = React.useState<User>();
+export function Page() {
+  const [user, setUser] = React.useState<User | undefined>(undefined);
stories/Button.tsx (1)

5-16: 표준 버튼 속성 수용을 위해 HTMLButtonAttributes 확장 권장

disabled, aria-*, onFocus 등 표준 속성을 자연스럽게 받도록 타입을 확장하면 재사용성이 좋아집니다. 현재도 ...props를 전달하지만 타입 선언이 좁아 에디터 지원이 제한됩니다.

-export interface ButtonProps {
+export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
   /** Is this the principal call to action on the page? */
   primary?: boolean;
   /** What background color to use */
   backgroundColor?: string;
   /** How large should the button be? */
   size?: 'small' | 'medium' | 'large';
   /** Button contents */
   label: string;
-  /** Optional click handler */
-  onClick?: () => void;
 }
stories/Button.stories.ts (3)

9-9: 스토리 타이틀 네이밍 컨벤션 정렬

디자인 시스템 내 문서화를 고려하면 "Example/Button" 대신 "Components/Button" 혹은 "Design System/Button"처럼 실서비스 컨벤션을 따르는 그룹핑이 탐색성에 유리합니다.
예:

-  title: 'Example/Button',
+  title: 'Components/Button',

18-23: 컨트롤/도큐멘트 품질 개선: size/primary 컨트롤 노출

현재 backgroundColor만 컨트롤로 노출됩니다. 소비자가 컴포넌트 API를 빠르게 이해할 수 있도록 sizeprimary도 컨트롤로 추가하는 것을 권장합니다.

   argTypes: {
-    backgroundColor: { control: 'color' },
+    backgroundColor: { control: 'color' },
+    size: {
+      control: { type: 'select' },
+      options: ['small', 'medium', 'large'],
+      description: 'Button size',
+    },
+    primary: {
+      control: 'boolean',
+      description: 'Use primary variant',
+    },
   },
   // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
   args: { onClick: fn() },

7-24: 스토리 구성 검토: Chip 컴포넌트 색상 분기 분리 및 Storybook 트리 정렬 요청

  • packages/design-system/src/components/chip/Chip.stories.tsx 파일이 존재하지만, meta.title이 Storybook 사이드바에서 Components/Chip로 노출되는지 확인이 필요합니다.
  • 현재 단일 스토리만 정의되어 있고, 색상 분기(예: success, warning, info 등)에 대한 개별 스토리가 없습니다.
    • 각 variant별로 별도 스토리(예:
    export const Success = { args: { variant: 'success' } };
    export const Warning = { args: { variant: 'warning' } };
    // …
    )를 추가하면 회귀 테스트 및 시각 검증에 유리합니다.
  • Vitest 연동(스토리 기반 테스트)이 이미 설정되어 있다면, 색상 토큰·클래스 바인딩에 대한 상호작용 테스트 케이스도 보강해 주세요.
vitest.config.ts (1)

16-36: Vitest 프로젝트 정의 방식 정교화: defineProject 사용 제안

현 구성도 동작 가능하나, Vitest가 권장하는 defineProject를 사용하면 타입 지원과 병렬 프로젝트 구성이 더 명확해집니다. 또한 플러그인을 루트 레벨에 배치하면 중복 구성을 줄일 수 있습니다.

-import { defineConfig } from 'vitest/config';
+import { defineConfig, defineProject } from 'vitest/config';

 export default defineConfig({
-  test: {
-    projects: [
-      {
-        extends: true,
-        plugins: [
-          // The plugin will run tests for the stories defined in your Storybook config
-          // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
-          storybookTest({ configDir: path.join(dirname, '.storybook') }),
-        ],
-        test: {
-          name: 'storybook',
-          browser: {
-            enabled: true,
-            headless: true,
-            provider: 'playwright',
-            instances: [{ browser: 'chromium' }],
-          },
-          setupFiles: ['.storybook/vitest.setup.ts'],
-        },
-      },
-    ],
-  },
+  plugins: [storybookTest({ configDir: path.join(dirname, '.storybook') })],
+  test: {
+    projects: [
+      defineProject({
+        name: 'storybook',
+        browser: {
+          enabled: true,
+          headless: true,
+          provider: 'playwright',
+          instances: [{ browser: 'chromium' }],
+        },
+        setupFiles: ['.storybook/vitest.setup.ts'],
+      }),
+    ],
+  },
 });
stories/Header.tsx (2)

21-36: 장식용 SVG 접근성 개선: 스크린 리더에서 숨기기

현재 SVG는 순수 장식 요소로 보입니다. 스크린 리더 노이즈를 줄이기 위해 aria-hiddenfocusable="false"를 추가하는 것을 권장합니다.

-        <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+        <svg
+          width="32"
+          height="32"
+          viewBox="0 0 32 32"
+          xmlns="http://www.w3.org/2000/svg"
+          aria-hidden="true"
+          focusable="false"
+        >

17-17: onClick 핸들러 기본값 제공으로 안정성 소폭 개선

ButtononClick?: () => void일 가능성이 높지만, 기본 no-op을 제공하면 스토리/데모에서 핸들러 미지정 시에도 의도를 명확히 할 수 있습니다.

-export const Header = ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps) => (
+export const Header = ({
+  user,
+  onLogin = () => {},
+  onLogout = () => {},
+  onCreateAccount = () => {},
+}: HeaderProps) => (
stories/Page.stories.ts (2)

22-33: 플레이 테스트 안정성 향상: 쿼리 재조회 및 findByRole 사용

클릭 직후 DOM 업데이트 타이밍에 따른 간헐적 실패를 줄이기 위해, 사라짐 검증은 queryByRole 재조회로, 등장 검증은 findByRole로 대기하는 패턴을 권장합니다.

 export const LoggedIn: Story = {
   play: async ({ canvasElement }) => {
     const canvas = within(canvasElement);
     const loginButton = canvas.getByRole('button', { name: /Log in/i });
     await expect(loginButton).toBeInTheDocument();
-    await userEvent.click(loginButton);
-    await expect(loginButton).not.toBeInTheDocument();
+    await userEvent.click(loginButton);
+    // 업데이트 이후 재조회로 부재 검증
+    await expect(canvas.queryByRole('button', { name: /Log in/i })).not.toBeInTheDocument();
 
-    const logoutButton = canvas.getByRole('button', { name: /Log out/i });
-    await expect(logoutButton).toBeInTheDocument();
+    // 등장 대기 후 검증
+    const logoutButton = await canvas.findByRole('button', { name: /Log out/i });
+    await expect(logoutButton).toBeInTheDocument();
   },
 };

8-14: 스토리 네임스페이스 정비

디자인 시스템 카탈로그와의 일관성을 위해 "Example/Page" 대신 "Components/Page" 또는 "Foundations/Page" 같은 그룹 사용을 제안드립니다.

-  title: 'Example/Page',
+  title: 'Components/Page',
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a6a2a34 and 93c504c.

⛔ Files ignored due to path filters (16)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • stories/assets/accessibility.png is excluded by !**/*.png
  • stories/assets/accessibility.svg is excluded by !**/*.svg
  • stories/assets/addon-library.png is excluded by !**/*.png
  • stories/assets/assets.png is excluded by !**/*.png
  • stories/assets/context.png is excluded by !**/*.png
  • stories/assets/discord.svg is excluded by !**/*.svg
  • stories/assets/docs.png is excluded by !**/*.png
  • stories/assets/figma-plugin.png is excluded by !**/*.png
  • stories/assets/github.svg is excluded by !**/*.svg
  • stories/assets/share.png is excluded by !**/*.png
  • stories/assets/styling.png is excluded by !**/*.png
  • stories/assets/testing.png is excluded by !**/*.png
  • stories/assets/theming.png is excluded by !**/*.png
  • stories/assets/tutorials.svg is excluded by !**/*.svg
  • stories/assets/youtube.svg is excluded by !**/*.svg
📒 Files selected for processing (18)
  • .storybook/main.ts (1 hunks)
  • .storybook/preview.ts (1 hunks)
  • .storybook/vitest.setup.ts (1 hunks)
  • package.json (1 hunks)
  • packages/design-system/src/components/chip/Chip.stories.tsx (1 hunks)
  • packages/design-system/src/components/chip/Chip.tsx (1 hunks)
  • stories/Button.stories.ts (1 hunks)
  • stories/Button.tsx (1 hunks)
  • stories/Configure.mdx (1 hunks)
  • stories/Header.stories.ts (1 hunks)
  • stories/Header.tsx (1 hunks)
  • stories/Page.stories.ts (1 hunks)
  • stories/Page.tsx (1 hunks)
  • stories/button.css (1 hunks)
  • stories/header.css (1 hunks)
  • stories/page.css (1 hunks)
  • vitest.config.ts (1 hunks)
  • vitest.shims.d.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • stories/button.css
  • stories/header.css
  • stories/page.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/design-system/src/components/chip/Chip.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-23T18:42:42.797Z
Learnt from: jjangminii
PR: Pinback-Team/pinback-client#22
File: packages/design-system/package.json:32-35
Timestamp: 2025-08-23T18:42:42.797Z
Learning: Storybook packages have different release cycles and stable versions. As of 2025, storybook/test and storybook/blocks have their latest stable versions in the 8.x line (8.6.14), while other packages like storybook/react-vite are stable in 9.x line (9.1.3). Mixed major versions across Storybook packages can be intentional and correct when using the latest stable version of each package.

Applied to files:

  • package.json
🧬 Code graph analysis (5)
stories/Header.stories.ts (1)
stories/Header.tsx (1)
  • Header (17-56)
stories/Page.tsx (1)
stories/Header.tsx (1)
  • Header (17-56)
stories/Button.stories.ts (1)
stories/Button.tsx (1)
  • Button (19-37)
stories/Header.tsx (1)
stories/Button.tsx (1)
  • Button (19-37)
stories/Page.stories.ts (2)
stories/Page.tsx (1)
  • Page (10-73)
stories/Header.stories.ts (2)
  • LoggedOut (34-34)
  • LoggedIn (26-32)
🔇 Additional comments (9)
stories/Configure.mdx (1)

1-1: MDX 블록 import 경로 최신화: @storybook/blocks 사용 권장

Storybook 8/9에서는 @storybook/addon-docs/blocks 대신 @storybook/blocks 사용이 권장됩니다. 구 경로는 제거/호환 중단 가능성이 있습니다.

-import { Meta } from "@storybook/addon-docs/blocks";
+import { Meta } from "@storybook/blocks";
⛔ Skipped due to learnings
Learnt from: jjangminii
PR: Pinback-Team/pinback-client#22
File: packages/design-system/package.json:32-35
Timestamp: 2025-08-23T18:42:42.797Z
Learning: Storybook packages have different release cycles and stable versions. As of 2025, storybook/test and storybook/blocks have their latest stable versions in the 8.x line (8.6.14), while other packages like storybook/react-vite are stable in 9.x line (9.1.3). Mixed major versions across Storybook packages can be intentional and correct when using the latest stable version of each package.
.storybook/vitest.setup.ts (1)

1-7: ✅ Vitest + Portable Stories 설정 반영 확인됨

  • vitest.config.ts에서 setupFiles: ['.storybook/vitest.setup.ts'].storybook/vitest.setup.ts가 정상 포함됨 (32번 줄)
  • storybookTest({ configDir: path.join(dirname, '.storybook') }) 호출로 Storybook 테스트 플러그인 및 configDir 옵션이 올바르게 설정됨 (22번 줄)

추가 검토 및 조치 불필요합니다.

stories/Page.tsx (1)

15-21: 헤더 상호작용 핸들러는 데모 목적에 적합(LGTM)

스토리 데모 용도로 로그인/로그아웃 상태 전환 로직이 간결하고 충분합니다.

stories/Header.stories.ts (1)

7-21: 메타 구성, 타입 세이프티, 테스트 훅 사용이 적절합니다

satisfies Meta<typeof Header>fn() 활용으로 스토리/테스트 작성 준비가 잘 되어 있습니다. 추가 조치는 없어 보입니다.

stories/Button.tsx (1)

28-36: type="button" 지정과 클래스 구성 적절(LGTM)

폼 내 기본 submit 방지 목적의 type="button" 지정과 모드 클래스 구성 방식이 명확합니다.

stories/Button.stories.ts (1)

1-1: 타입 임포트 경로 유지 권장

현재 프로젝트는 Vite 빌더용 Storybook 패키지(@storybook/react-vite@^9.1.3)를 사용하고 있으며, 공식 문서에서도 “Replace your-framework with the framework you are using, e.g. react-vite” 예시처럼 Vite 빌더를 쓸 경우 import type { Meta, StoryObj } from '@storybook/react-vite';를 권장합니다 (storybook.js.org).
@storybook/react 패키지가 devDependencies에 존재하지 않아 해당 경로로 타입을 임포트할 경우 모듈을 찾을 수 없어 빌드 에러가 발생합니다.

따라서 기존 @storybook/react-vite 경로를 그대로 유지하시는 것이 맞습니다.

Likely an incorrect or invalid review comment.

vitest.config.ts (2)

8-12: ESM/CJS 환경 가드 처리 좋습니다

__dirname 유무에 따른 분기와 fileURLToPath 사용으로 런타임 환경 차이를 안전하게 흡수하고 있습니다. 유지보수 관점에서도 가독성이 좋습니다.


26-31: Playwright 인스턴스 설정 호환성 확인 완료

현재 package.json의 devDependencies에 Vitest ^3.2.4와 Playwright ^1.55.0가 명시되어 있으며, Vitest 3 이상에서 browser.instances 옵션을 공식 지원합니다.
또한 .storybook/vitest.setup.ts.storybook 디렉터리도 정상 존재하므로, 제안된 폴백(name: 'chromium')을 적용하지 않고도 instances: [{ browser: 'chromium' }] 구성을 그대로 사용하셔도 문제 없습니다.

stories/Header.tsx (1)

17-56: 구성/타이핑 전반적으로 안정적입니다

Props를 명시적으로 모델링하고 상태를 외부에서 주입받는 구조가 스토리/테스트 친화적입니다. 버튼 라벨도 명확하여 접근성 측면에서도 기본 요건을 충족합니다.

@@ -0,0 +1,28 @@
import type { StorybookConfig } from '@storybook/react-vite';

import { join, dirname } from "path"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

ESM 환경에서 require 미정의 오류 가능 — createRequire 사용 필요

현재 파일은 ESM(Top-level import) 문법을 사용하고 있어 require가 정의되지 않았을 수 있습니다. createRequire(import.meta.url)require.resolve를 안전하게 사용하도록 보완해 주세요. 또한 getAbsolutePath의 반환 타입을 string으로 명시하면 타입 안정성이 좋아집니다.

 import { join, dirname } from "path"
+import { createRequire } from "module"
 
 /**
 * This function is used to resolve the absolute path of a package.
 * It is needed in projects that use Yarn PnP or are set up within a monorepo.
 */
-function getAbsolutePath(value: string): any {
-  return dirname(require.resolve(join(value, 'package.json')))
-}
+const require = createRequire(import.meta.url)
+function getAbsolutePath(value: string): string {
+  return dirname(require.resolve(join(value, "package.json")))
+}

Also applies to: 9-11

🤖 Prompt for AI Agents
In .storybook/main.ts around lines 3 and 9-11, the file uses ESM imports so
using require.resolve may fail; replace direct require usage by importing
createRequire from "module" and create a require via
createRequire(import.meta.url) to call require.resolve safely in ESM, and
annotate the getAbsolutePath function to return string (not implicit any) to
improve type safety; update any callers accordingly to accept a string return
and remove reliance on global require.

Comment on lines 13 to 16
"stories": [
"../stories/**/*.mdx",
"../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"
],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

디자인 시스템 스토리 경로 누락 — 패키지 내부 스토리도 로드되도록 확장 권장

현재 stories 글롭이 루트 stories/만 가리켜 packages/design-system 하위의 *.stories.*가 로드되지 않을 수 있습니다. 카테고리 칩(Chip) 스토리를 Storybook에서 확인하려면 경로를 확장해 주세요.

   "stories": [
     "../stories/**/*.mdx",
-    "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"
+    "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
+    "../packages/**/*.mdx",
+    "../packages/**/*.stories.@(js|jsx|mjs|ts|tsx)"
   ],

변경 후 pnpm storybook을 실행하여 Chip 스토리가 탐색기에 노출되는지 확인해 주세요.


🏁 Script executed:

#!/usr/bin/env bash

# Display the first 50 lines of the Storybook config to confirm current glob patterns
echo "== .storybook/main.ts (lines 1–50) =="
sed -n '1,50p' .storybook/main.ts || echo "Unable to read .storybook/main.ts"

# List any MDX or .stories.* files under packages/design-system to confirm their existence
echo
echo "== Story files in packages/design-system/ =="
find packages/design-system -type f \( -iname "*.mdx" -o -iname "*.stories.*" \) || echo "No story files found under packages/design-system/"

Length of output: 1362


스토리 glob 패턴 확장 필요 — 패키지 내부 스토리 로드

현재 .storybook/main.tsstories 설정에 루트 stories/만 포함되어 있어 packages/design-system 하위의 스토리가 로드되지 않습니다. Chip 컴포넌트 등의 패키지 내 스토리를 불러오기 위해 glob 패턴을 확장해주세요.

• 파일: .storybook/main.ts
• 위치: stories 배열

  "stories": [
    "../stories/**/*.mdx",
-   "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"
+   "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
+   "../packages/**/*.mdx",
+   "../packages/**/*.stories.@(js|jsx|mjs|ts|tsx)"
  ],

변경 후 pnpm storybook 실행 시 탐색기에서 packages/design-system/src/components/chip/Chip.stories.tsx가 노출되는지 확인 부탁드립니다.

📝 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.

Suggested change
"stories": [
"../stories/**/*.mdx",
"../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"
],
"stories": [
"../stories/**/*.mdx",
"../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
"../packages/**/*.mdx",
"../packages/**/*.stories.@(js|jsx|mjs|ts|tsx)"
],
🤖 Prompt for AI Agents
In .storybook/main.ts around lines 13 to 16, the stories glob only includes
"../stories/**" so it misses component stories inside packages (e.g.,
packages/design-system); update the stories array to include package-level globs
that match nested package story files (for example add
"../packages/**/src/**/*.stories.@(js|jsx|mjs|ts|tsx)" or
"../packages/**/stories/**/*.@(mdx|@(js|jsx|mjs|ts|tsx))") so pnpm storybook
will discover packages/design-system/src/components/chip/Chip.stories.tsx;
ensure patterns are relative to the .storybook folder and include the same
extensions as existing entries.

Comment on lines 51 to 53
href="https://storybook.js.org/docs/configure/styling-and-css/?renderer=react&ref=configure"
target="_blank"
>Learn more<RightArrow /></a>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

외부 링크에 rel="noopener noreferrer" 추가

target="_blank" 사용 시 탭 간 window.opener를 통한 보안/성능 이슈를 방지하기 위해 rel="noopener noreferrer"를 추가하세요.

패턴 예시(다른 앵커에도 동일 적용):

-      <a
-        href="https://storybook.js.org/docs/configure/styling-and-css/?renderer=react&ref=configure"
-        target="_blank"
-      >Learn more<RightArrow /></a>
+      <a
+        href="https://storybook.js.org/docs/configure/styling-and-css/?renderer=react&ref=configure"
+        target="_blank"
+        rel="noopener noreferrer"
+      >Learn more<RightArrow /></a>

Also applies to: 63-65, 75-78, 97-100, 106-109, 116-119, 126-129, 135-138, 144-147, 156-159, 171-174, 181-184, 192-195, 202-205

🤖 Prompt for AI Agents
In stories/Configure.mdx around lines 51-53 (and similarly at 63-65, 75-78,
97-100, 106-109, 116-119, 126-129, 135-138, 144-147, 156-159, 171-174, 181-184,
192-195, 202-205), anchors that use target="_blank" are missing rel="noopener
noreferrer"; update each external <a> tag that opens a new tab to include
rel="noopener noreferrer" alongside target="_blank" to prevent window.opener
security/performance issues.

@jllee000 jllee000 changed the title Feat(design-system): 카테고리 색상 분기 Feat(design-system): 카테고리 칩 컴포넌트 Aug 25, 2025
Copy link
Member

@constantly-dev constantly-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!! 간단한 코멘트 남겼으니 확인해주세요~

| 'amber'
| 'maroon';

interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버튼 속성을 확장하고 있는데 아래 span을 사용하고 있네요. 특별하게 button을 쓸 이유가 있다면 아래 span태그도 바꿔야 할 것 같아요! 통일하기!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 헉.! 네 이부분 놓쳤네요! 수정해두겠습니다 :)

| 'amber'
| 'maroon';

interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고

Suggested change
interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
interface ChipProps extends ButtonHTMLAttributes<HTMLButtonElement> {

로만 써도 될 것 같아요 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가적으로 찾아보니, 최신 버전부터는 표준이 바뀌었군요 ㅎㅎ! 감사합니다!


interface ChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
color: ChipColor;
category?: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카테고리 명이 없어도 되는 경우가 있나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인해보니 말씀대로 카테고리 명은 필수인 것 같아서! 수정해두었습니다 :)

import Chip from './Chip';

const meta: Meta<typeof Chip> = {
title: 'UI/Chip',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title: 'Components/Chip', 로 통일하기!

Comment on lines 34 to 36
parameters: {
docs: {
description: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parameters: {
docs: {
description: {
parameters: {
layout: 'centered',
docs: {
description: {

로 중앙 정렬 하는 것은 어떤가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중앙 정렬 UI 가 따로 가능하군요? 와우 하나 새로 알아갑니다!


return (
<div style={{ display: 'grid', gap: '8px' }}>
{colors.map((c) => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소하지만 c보다는 color로 네이밍하는 것이 좋을 것 같아요 👍

@constantly-dev
Copy link
Member

색상 코드값(#000000 같은) 기준으로 color 분기해서 작업할까 하다가, 어차피 색상 코드 받은 걸로 그거에 맞는 텍스트 색상도 세트로 바뀌는 거라서, 색상 코드값을 props로 받지 않고 하나의 색상 세트 네이밍으로 받아 관리했어요. ex. red면 이에 맞는 배경색과 텍스트 적용 ++ 서버 리드와 이 색상값 전달 타입에 대해서 논의 후 결정했습니다!

너무 좋습니다~~~ 👍

@jllee000 jllee000 merged commit 8b443b0 into develop Aug 25, 2025
6 checks passed
Copy link
Collaborator

@jjangminii jjangminii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

타입을 명확히 정의해 유지보수성이 높아진 점이 특히 좋습니다. 불필요한 렌더링을 막아 안정성을 끌어올린 부분도 인상적이에요.
색상 케이스가 많아 손이 많이 갔을 텐데 꼼꼼히 반영해 주셔서 고생하셨습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 기능 개발하라 개발 달려라 달려

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 카테고리 칩 컴포넌트 제작

3 participants