Skip to content

[feat]: icon 컴포넌트 추가 - #6

Merged
choihooo merged 8 commits into
developfrom
feature/icon-component-generation
Dec 1, 2025
Merged

choihooo merged 8 commits into
developfrom
feature/icon-component-generation

Conversation

@choihooo

@choihooo choihooo commented Dec 1, 2025 •

Copy link
Copy Markdown
Member

변경 사항

  • icon 원본 파일들을 추가했습니다.
  • icon 원본 파일을 컴포넌트로 변환하는 스크립트를 추가했습니다.
  • icon 컴포넌트들을 추가했습니다.

변경 유형

  • 🐛 버그 수정
  • ✨ 새로운 기능 (Breaking Change 없음)
  • 💥 Breaking Change (기존 API 변경)
  • 📝 문서화 업데이트
  • 🎨 스타일 변경 (코드 포맷팅, 세미콜론 누락 등)
  • ♻️ 리팩토링 (기능 변경 없음, 코드 개선)
  • ⚡️ 성능 개선
  • ✅ 테스트 추가/수정

관련 이슈

체크리스트

컴포넌트 관련 (컴포넌트 추가/수정 시)

  • 컴포넌트가 src/components/ 디렉토리에 올바르게 위치해 있습니다
  • 컴포넌트가 src/index.ts에서 export 되었습니다
  • TypeScript 타입이 올바르게 정의되었습니다
  • vanilla-extract를 사용한 스타일링이 올바르게 구현되었습니다

스토리북 관련

  • 스토리 파일(*.stories.ts)이 생성/업데이트되었습니다
  • 다양한 상태와 변형(variants)에 대한 스토리가 포함되어 있습니다
  • autodocs 태그가 포함되어 있습니다
  • Controls가 올바르게 설정되어 있습니다

품질 관리

  • pnpm run lint 통과
  • pnpm run check (타입 체크) 통과
  • pnpm test --run 통과
  • 빌드가 성공적으로 완료됩니다 (pnpm run build)

접근성

  • 접근성 관련 속성(aria-label, role 등)이 올바르게 설정되었습니다
  • 키보드 네비게이션이 올바르게 동작합니다
  • 스토리북의 a11y 애드온으로 검증했습니다

문서화

  • 컴포넌트 props에 대한 JSDoc 주석이 작성되었습니다
  • 복잡한 로직에 대한 주석이 작성되었습니다
  • README나 관련 문서가 업데이트되었습니다 (필요한 경우)

테스트

  • 새로운 테스트가 추가되었습니다 (필요한 경우)
  • 기존 테스트가 모두 통과합니다

스크린샷 / 데모

추가 정보

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 40개 이상의 새로운 아이콘 컴포넌트 추가 (화살표, 체크박스, 공유, 검색 등)
    • 확장된 아이콘 라이브러리로 UI 디자인 옵션 향상
  • Chores

    • 모듈 경로 별칭 설정으로 코드 import 경로 간편화
    • 빌드 시스템 최적화 및 아이콘 자동 처리 스크립트 추가

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 1, 2025 •

Copy link
Copy Markdown

워크스루

SVGO 및 SVGR을 활용한 자동 아이콘 생성 파이프라인을 도입합니다. 45개 이상의 새로운 아이콘 컴포넌트를 추가하고, 사후 처리 및 인덱스 생성 스크립트를 구현하며, 경로 별칭을 설정하고 관련 구성 파일을 업데이트합니다.

변경 사항

코호트 / 파일 변경 요약
SVG 및 아이콘 생성 구성
package.json, svgr.config.cjs
SVGO 최적화 및 SVGR 생성 npm 스크립트 추가. SVGR 구성에서 TypeScript, 아이콘 모드, 자동 JSX 런타임 활성화 및 색상 치환 규칙 추가.
아이콘 생성 및 처리 스크립트
scripts/post-process-icons.cjs, scripts/update-icons-index.cjs
SVGR 생성 아이콘을 후처리하여 viewBox, 크기, 접근성 속성을 표준화하고 원본 SVG 메타데이터를 유지하는 스크립트 추가. 생성된 아이콘에서 동적으로 인덱스 파일을 생성하는 스크립트 추가.
아이콘 컴포넌트
src/icons/Alarm.tsx, src/icons/ArrowDown.tsx, src/icons/ArrowLeft.tsx, src/icons/ArrowRight.tsx, src/icons/ArrowTop.tsx, src/icons/Certification.tsx, src/icons/CheckBoxDisabled.tsx, src/icons/CheckBoxEnabled.tsx, src/icons/CircleSymbol.tsx, src/icons/Close.tsx, src/icons/Community.tsx, src/icons/Copy.tsx, src/icons/Delete.tsx, src/icons/DisasterInfo.tsx, src/icons/Edit.tsx, src/icons/Ellipsis.tsx, src/icons/Eye.tsx, src/icons/Family.tsx, src/icons/Filter.tsx, src/icons/Funding.tsx, src/icons/Good.tsx, src/icons/HamburgerBar.tsx, src/icons/Heart.tsx, src/icons/Home.tsx, src/icons/Location.tsx, src/icons/Logo.tsx, src/icons/LogoSymbol.tsx, src/icons/Minus.tsx, src/icons/My.tsx, src/icons/Noti.tsx, src/icons/Phone.tsx, src/icons/Photo.tsx, src/icons/Plus.tsx, src/icons/Reset.tsx, src/icons/Save.tsx, src/icons/Search.tsx, src/icons/Send.tsx, src/icons/Share.tsx, src/icons/Start.tsx, src/icons/TileSymbol.tsx, src/icons/Warning.tsx, src/icons/Weather.tsx
일관된 크기 조정(기본값 24), 접근성 속성(aria-label, aria-hidden), SVG props 확산을 지원하는 45개 새로운 아이콘 컴포넌트 추가. 각 컴포넌트는 PascalCase 인터페이스, 함수형 컴포넌트, displayName 할당을 포함합니다.
아이콘 인덱스 및 스토리
src/icons/index.ts, src/stories/icons/Icons.stories.tsx
생성된 모든 아이콘에서 동적으로 생성된 아이콘 인덱스. 크기, 색상, 접근성 변형을 포함한 포괄적인 아이콘 스토리북 추가.
경로 별칭 구성
vite.config.ts, vitest.config.ts
"@" 경로 별칭을 src 디렉토리로 매핑 추가. vitest 플러그인 순서 변경 및 src/icons/**을 커버리지 제외에 추가.
import 경로 마이그레이션
src/components/Button/Button.css.ts, src/components/FloatingButton/FloatingButton.css.ts, src/components/FloatingButton/FloatingButton.tsx, src/components/Switch/Switch.css.ts, src/stories/tokens/*.tsx, .storybook/tsconfig.json
상대 경로 imports를 "@" 경로 별칭으로 업데이트. FloatingButton의 PlusIcon을 Plus로 이름 변경.

추정 코드 리뷰 노력

🎯 3 (중간) | ⏱️ ~25분

특별 주의 사항:

  • 아이콘 컴포넌트 일관성: 45개 이상의 아이콘 컴포넌트가 동일한 패턴을 따르므로, 몇 개를 샘플링하고 나머지는 일관성 검증하면 됩니다. Props 인터페이스, 기본값, 접근성 처리가 모두 동일한지 확인하세요.
  • 후처리 스크립트 로직: scripts/post-process-icons.cjs는 viewBox 추출, 크기 조정, 로고 특수 처리를 포함하는 복잡한 로직을 가지고 있습니다. SVG 파싱 오류 처리 및 원본 SVG 메타데이터 재사용 메커니즘을 꼼꼼히 검토하세요.
  • SVGR 구성: svgr.config.cjs의 색상 치환 규칙이 모든 아이콘에서 의도대로 작동하는지 확인하세요.
  • 경로 별칭 마이그레이션: 모든 import 경로가 일관되게 업데이트되었는지, 누락된 파일이 없는지 확인하세요.

관련 이슈

관련 PR

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목 '[feat]: icon 컴포넌트 추가'는 주요 변경사항인 icon 컴포넌트 추가를 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명은 변경 사항, 변경 유형, 관련 이슈, 체크리스트를 모두 포함하고 있으며 템플릿 구조를 잘 따르고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/icon-component-generation

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (9)
src/components/FloatingButton/FloatingButton.tsx (1)

63-63: 더 설명적인 aria-label 사용을 고려해보세요.

현재 aria-label="+"는 기능적이지만, 스크린 리더 사용자를 위해 "추가" 또는 컨텍스트에 맞는 더 명확한 레이블(예: "새 항목 추가")을 사용하는 것이 접근성 측면에서 더 좋습니다.

-				<Plus aria-label="+" />
+				<Plus aria-label="추가" />
src/icons/ArrowRight.tsx (1)

3-40: 아이콘 공통 패턴/a11y 처리 양호, 향후 공통 타입·role 정리 제안

  • size 기본값, aria-label/aria-hidden 처리, currentColor 사용 등 전반적인 패턴은 문제 없이 잘 구성되어 있습니다.
  • 이 패턴이 모든 아이콘에서 반복되므로, 나중에 IconProps 같은 공통 인터페이스를 src/icons/IconProps.ts 등으로 분리해 두면 타입/문서 변경 시 유지보수가 조금 더 수월할 것 같습니다.
  • aria-label을 사용하는 경우 <svg>에 role="img"를 함께 지정해 두면 스크린 리더 입장에서 의미가 더 명확해져 접근성 측면에서 약간의 플러스가 될 수 있습니다.
svgr.config.cjs (1)

1-14: SVGR 설정은 적절하며, 색상 치환 범위 확장 여지가 있습니다

  • icon, typescript, jsxRuntime: "automatic" 선택은 현재 구조(TSX 아이콘, 최신 JSX 런타임)에 잘 맞습니다.
  • 추후 SVG 원본에서 더 다양한 고정 색상(예: 다른 그레이/블랙 톤이나 브랜드 컬러 등)을 모두 currentColor로 통일하고 싶다면, replaceAttrValues에 색상을 추가하거나 SVGO 설정 쪽에서 함께 정리하는 것도 고려해볼 만합니다.
src/icons/Copy.tsx (1)

32-35: stroke 속성에 strokeWidth 명시 고려

첫 번째 path에서 stroke를 사용하지만 strokeWidth가 명시되지 않았습니다. 브라우저 기본값(1)이 적용되지만, 명시적으로 설정하면 의도를 더 명확히 할 수 있습니다.

 <path
   stroke="currentColor"
+  strokeWidth={1}
   d="M9 4.5h9a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H9a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5Z"
 />
src/stories/icons/Icons.stories.tsx (2)

11-22: 아이콘 필터링 로직 개선 권장

현재 필터링 로직은 function 또는 object 타입인지만 확인합니다. 이 방식은 React 컴포넌트가 아닌 다른 내보내기(예: 상수, 유틸리티 객체)도 포함할 수 있습니다. displayName 속성 확인을 추가하면 더 안정적입니다.

 const allIcons = Object.entries(Icons)
   .filter(([, component]) => {
-    // React 컴포넌트인지 확인 (함수 또는 객체)
     return (
-      typeof component === "function" ||
-      (typeof component === "object" && component !== null)
+      (typeof component === "function" ||
+        (typeof component === "object" && component !== null)) &&
+      (component as { displayName?: string }).displayName !== undefined
     );
   })

405-527: CloseIconCustomization 스토리의 SVG 중복

동일한 SVG 구조가 색상만 다르게 4번 반복됩니다. 데모 목적이므로 현재 상태도 괜찮지만, 유지보수를 위해 색상 배열을 순회하는 방식으로 리팩토링할 수 있습니다.

src/icons/index.ts (1)

1-42: 아이콘 Props 타입 내보내기 누락

현재 컴포넌트만 내보내고 Props 인터페이스(예: HomeProps, CloseProps)는 내보내지 않습니다. 소비자가 타입을 확장하거나 재사용해야 할 경우 Props 타입도 함께 내보내는 것이 좋습니다.

-export { Alram } from "./Alram";
+export { Alram, type AlramProps } from "./Alram";
-export { ArrowDown } from "./ArrowDown";
+export { ArrowDown, type ArrowDownProps } from "./ArrowDown";
 // ... 나머지 아이콘들도 동일하게 적용

또는 scripts/update-icons-index.cjs 스크립트를 수정하여 자동으로 Props 타입도 내보내도록 할 수 있습니다.

scripts/post-process-icons.cjs (2)

88-90: 디렉토리 읽기 오류가 무시됨

assets/svgs 디렉토리가 없거나 읽기 권한이 없을 때 오류가 무시되어 디버깅이 어려울 수 있습니다. 경고 로그를 추가하는 것을 고려해 보세요.

-  const svgFiles = await readdir(SVGS_DIR).catch(() => []);
+  const svgFiles = await readdir(SVGS_DIR).catch((err) => {
+    console.warn(`⚠️  assets/svgs 디렉토리를 읽을 수 없습니다: ${err.message}`);
+    return [];
+  });

298-300: 처리 결과 카운트가 부정확할 수 있음

iconFiles.length는 스킵된 파일도 포함하므로 실제 처리된 파일 수와 다를 수 있습니다. 정확한 카운트를 위해 별도 변수를 사용하는 것이 좋습니다.

+    let processedCount = 0;
     for (const file of iconFiles) {
       // ... 
       if (!isSvgrGenerated && content.includes("export const") && content.includes("Props")) {
         console.log(`⏭️  ${file}는 이미 처리된 파일입니다. 스킵합니다.`);
         continue;
       }
       // ...
       console.log(`✅ ${componentName} 후처리 완료`);
+      processedCount++;
     }
 
     console.log(
-      `\n🎉 총 ${iconFiles.length}개의 아이콘 후처리가 완료되었습니다!`
+      `\n🎉 총 ${processedCount}개의 아이콘 후처리가 완료되었습니다!`
     );
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d88091 and 4aa1fa1.

⛔ Files ignored due to path filters (43)
  • assets/svgs/Funding.svg is excluded by !**/*.svg
  • assets/svgs/Location.svg is excluded by !**/*.svg
  • assets/svgs/Logo.svg is excluded by !**/*.svg
  • assets/svgs/My.svg is excluded by !**/*.svg
  • assets/svgs/alram.svg is excluded by !**/*.svg
  • assets/svgs/arrow-down.svg is excluded by !**/*.svg
  • assets/svgs/arrow-left.svg is excluded by !**/*.svg
  • assets/svgs/arrow-right.svg is excluded by !**/*.svg
  • assets/svgs/arrow-top.svg is excluded by !**/*.svg
  • assets/svgs/certification.svg is excluded by !**/*.svg
  • assets/svgs/check-box-disabled.svg is excluded by !**/*.svg
  • assets/svgs/check-box-enabled.svg is excluded by !**/*.svg
  • assets/svgs/circle-symbol.svg is excluded by !**/*.svg
  • assets/svgs/close.svg is excluded by !**/*.svg
  • assets/svgs/community.svg is excluded by !**/*.svg
  • assets/svgs/copy.svg is excluded by !**/*.svg
  • assets/svgs/delete.svg is excluded by !**/*.svg
  • assets/svgs/disaster-info.svg is excluded by !**/*.svg
  • assets/svgs/edit.svg is excluded by !**/*.svg
  • assets/svgs/ellipsis.svg is excluded by !**/*.svg
  • assets/svgs/eye.svg is excluded by !**/*.svg
  • assets/svgs/family.svg is excluded by !**/*.svg
  • assets/svgs/filter.svg is excluded by !**/*.svg
  • assets/svgs/good.svg is excluded by !**/*.svg
  • assets/svgs/hambuger-bar.svg is excluded by !**/*.svg
  • assets/svgs/heart.svg is excluded by !**/*.svg
  • assets/svgs/home.svg is excluded by !**/*.svg
  • assets/svgs/logo-symbol.svg is excluded by !**/*.svg
  • assets/svgs/minus.svg is excluded by !**/*.svg
  • assets/svgs/noti.svg is excluded by !**/*.svg
  • assets/svgs/phone.svg is excluded by !**/*.svg
  • assets/svgs/photo.svg is excluded by !**/*.svg
  • assets/svgs/plus.svg is excluded by !**/*.svg
  • assets/svgs/reset.svg is excluded by !**/*.svg
  • assets/svgs/save.svg is excluded by !**/*.svg
  • assets/svgs/search.svg is excluded by !**/*.svg
  • assets/svgs/send.svg is excluded by !**/*.svg
  • assets/svgs/share.svg is excluded by !**/*.svg
  • assets/svgs/start.svg is excluded by !**/*.svg
  • assets/svgs/tile-symbol.svg is excluded by !**/*.svg
  • assets/svgs/warning.svg is excluded by !**/*.svg
  • assets/svgs/weather.svg is excluded by !**/*.svg
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (49)
  • package.json (3 hunks)
  • scripts/post-process-icons.cjs (1 hunks)
  • scripts/update-icons-index.cjs (1 hunks)
  • src/components/FloatingButton/FloatingButton.tsx (2 hunks)
  • src/icons/Alram.tsx (1 hunks)
  • src/icons/ArrowDown.tsx (1 hunks)
  • src/icons/ArrowLeft.tsx (1 hunks)
  • src/icons/ArrowRight.tsx (1 hunks)
  • src/icons/ArrowTop.tsx (1 hunks)
  • src/icons/Certification.tsx (1 hunks)
  • src/icons/CheckBoxDisabled.tsx (1 hunks)
  • src/icons/CheckBoxEnabled.tsx (1 hunks)
  • src/icons/CircleSymbol.tsx (1 hunks)
  • src/icons/Close.tsx (1 hunks)
  • src/icons/Community.tsx (1 hunks)
  • src/icons/Copy.tsx (1 hunks)
  • src/icons/Delete.tsx (1 hunks)
  • src/icons/DisasterInfo.tsx (1 hunks)
  • src/icons/Edit.tsx (1 hunks)
  • src/icons/Ellipsis.tsx (1 hunks)
  • src/icons/Eye.tsx (1 hunks)
  • src/icons/Family.tsx (1 hunks)
  • src/icons/Filter.tsx (1 hunks)
  • src/icons/Funding.tsx (1 hunks)
  • src/icons/Good.tsx (1 hunks)
  • src/icons/HambugerBar.tsx (1 hunks)
  • src/icons/Heart.tsx (1 hunks)
  • src/icons/Home.tsx (1 hunks)
  • src/icons/Location.tsx (1 hunks)
  • src/icons/Logo.tsx (1 hunks)
  • src/icons/LogoSymbol.tsx (1 hunks)
  • src/icons/Minus.tsx (1 hunks)
  • src/icons/My.tsx (1 hunks)
  • src/icons/Noti.tsx (1 hunks)
  • src/icons/Phone.tsx (1 hunks)
  • src/icons/Photo.tsx (1 hunks)
  • src/icons/Plus.tsx (3 hunks)
  • src/icons/Reset.tsx (1 hunks)
  • src/icons/Save.tsx (1 hunks)
  • src/icons/Search.tsx (1 hunks)
  • src/icons/Send.tsx (1 hunks)
  • src/icons/Share.tsx (1 hunks)
  • src/icons/Start.tsx (1 hunks)
  • src/icons/TileSymbol.tsx (1 hunks)
  • src/icons/Warning.tsx (1 hunks)
  • src/icons/Weather.tsx (1 hunks)
  • src/icons/index.ts (1 hunks)
  • src/stories/icons/Icons.stories.tsx (1 hunks)
  • svgr.config.cjs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (46)
scripts/update-icons-index.cjs (1)
scripts/post-process-icons.cjs (8)
  • require (3-3)
  • require (4-4)
  • ICONS_DIR (6-6)
  • files (242-242)
  • iconFiles (244-253)
  • name (12-12)
  • content (116-116)
  • content (266-266)
src/icons/Save.tsx (1)
src/icons/index.ts (1)
  • Save (35-35)
src/icons/Start.tsx (1)
src/icons/index.ts (1)
  • Start (39-39)
src/icons/Minus.tsx (3)
src/icons/index.ts (1)
  • Minus (28-28)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/LogoSymbol.tsx (3)
src/icons/index.ts (1)
  • LogoSymbol (27-27)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Close.tsx (3)
src/icons/index.ts (1)
  • Close (10-10)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/ArrowDown.tsx (3)
src/icons/index.ts (1)
  • ArrowDown (2-2)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/CheckBoxDisabled.tsx (2)
src/icons/index.ts (1)
  • CheckBoxDisabled (7-7)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
src/icons/Noti.tsx (1)
src/icons/index.ts (1)
  • Noti (30-30)
src/icons/ArrowTop.tsx (3)
src/icons/index.ts (1)
  • ArrowTop (5-5)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Photo.tsx (1)
src/icons/index.ts (1)
  • Photo (32-32)
src/icons/Reset.tsx (1)
src/icons/index.ts (1)
  • Reset (34-34)
src/icons/My.tsx (3)
src/icons/index.ts (1)
  • My (29-29)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Search.tsx (1)
src/icons/index.ts (1)
  • Search (36-36)
src/icons/Warning.tsx (1)
src/icons/index.ts (1)
  • Warning (41-41)
src/icons/Delete.tsx (1)
src/icons/index.ts (1)
  • Delete (13-13)
src/icons/Ellipsis.tsx (2)
src/icons/index.ts (1)
  • Ellipsis (16-16)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
src/icons/ArrowRight.tsx (1)
src/icons/index.ts (1)
  • ArrowRight (4-4)
src/icons/Certification.tsx (3)
src/icons/index.ts (1)
  • Certification (6-6)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/TileSymbol.tsx (3)
src/icons/index.ts (1)
  • TileSymbol (40-40)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Heart.tsx (3)
src/icons/index.ts (1)
  • Heart (23-23)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/ArrowLeft.tsx (3)
src/icons/index.ts (1)
  • ArrowLeft (3-3)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/HambugerBar.tsx (3)
src/icons/index.ts (1)
  • HambugerBar (22-22)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Share.tsx (1)
src/icons/index.ts (1)
  • Share (38-38)
src/icons/Good.tsx (3)
src/icons/index.ts (1)
  • Good (21-21)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Filter.tsx (3)
src/icons/index.ts (1)
  • Filter (19-19)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Family.tsx (3)
src/icons/index.ts (1)
  • Family (18-18)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Logo.tsx (3)
src/icons/index.ts (1)
  • Logo (26-26)
scripts/post-process-icons.cjs (4)
  • aspectRatio (149-149)
  • width (147-147)
  • height (148-148)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/CircleSymbol.tsx (3)
src/icons/index.ts (1)
  • CircleSymbol (9-9)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Edit.tsx (3)
src/icons/index.ts (1)
  • Edit (15-15)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Funding.tsx (3)
src/icons/index.ts (1)
  • Funding (20-20)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Eye.tsx (1)
src/icons/index.ts (1)
  • Eye (17-17)
src/icons/DisasterInfo.tsx (3)
src/icons/index.ts (1)
  • DisasterInfo (14-14)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Community.tsx (1)
src/icons/index.ts (1)
  • Community (11-11)
src/icons/Location.tsx (1)
src/icons/index.ts (1)
  • Location (25-25)
src/icons/Phone.tsx (3)
src/icons/index.ts (1)
  • Phone (31-31)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Send.tsx (3)
src/icons/index.ts (1)
  • Send (37-37)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/icons/Home.tsx (1)
src/icons/index.ts (1)
  • Home (24-24)
src/icons/Alram.tsx (3)
src/icons/index.ts (1)
  • Alram (1-1)
scripts/post-process-icons.cjs (1)
  • svg (34-34)
scripts/update-icons-index.cjs (1)
  • path (9-9)
src/components/FloatingButton/FloatingButton.tsx (2)
src/icons/Plus.tsx (1)
  • Plus (16-46)
src/icons/index.ts (1)
  • Plus (33-33)
src/icons/Copy.tsx (1)
src/icons/index.ts (1)
  • Copy (12-12)
src/icons/Weather.tsx (1)
src/icons/index.ts (1)
  • Weather (42-42)
scripts/post-process-icons.cjs (1)
scripts/update-icons-index.cjs (5)
  • require (8-8)
  • ICONS_DIR (11-11)
  • content (39-39)
  • files (16-16)
  • iconFiles (18-21)
src/icons/CheckBoxEnabled.tsx (1)
src/icons/index.ts (1)
  • CheckBoxEnabled (8-8)
src/stories/icons/Icons.stories.tsx (6)
src/icons/Close.tsx (1)
  • Close (16-40)
src/icons/index.ts (5)
  • Close (10-10)
  • Search (36-36)
  • Home (24-24)
  • Edit (15-15)
  • Delete (13-13)
src/icons/Search.tsx (1)
  • Search (16-40)
src/icons/Home.tsx (1)
  • Home (16-38)
src/icons/Edit.tsx (1)
  • Edit (16-38)
src/icons/Delete.tsx (1)
  • Delete (16-40)
src/icons/Plus.tsx (1)
src/icons/index.ts (1)
  • Plus (33-33)
🔇 Additional comments (42)
src/icons/Warning.tsx (1)

1-42: 구현이 우수합니다!

아이콘 컴포넌트가 접근성과 타입 안전성을 모두 고려하여 잘 구현되었습니다:

  • aria-label 제공 시 의미 있는 아이콘, 미제공 시 장식용으로 처리
  • currentColor 사용으로 테마 적용 가능
  • TypeScript 타입 정의 완벽
  • Props spreading으로 확장성 확보
src/icons/Noti.tsx (1)

1-40: LGTM!

Warning 아이콘과 동일한 패턴을 따르며, 모든 모범 사례가 적용되었습니다.

src/icons/Filter.tsx (1)

1-42: LGTM!

일관된 아이콘 패턴을 따르며 올바르게 구현되었습니다.

src/icons/ArrowDown.tsx (1)

1-42: LGTM!

일관된 아이콘 구현 패턴을 따르며 모든 접근성 요구사항을 충족합니다.

src/icons/Weather.tsx (1)

1-46: LGTM!

일관된 패턴을 따르며 올바르게 구현되었습니다. 여러 path 요소를 사용한 복잡한 아이콘도 적절하게 처리되었습니다.

src/icons/Phone.tsx (1)

1-40: LGTM!

일관된 아이콘 패턴을 따르며 모든 모범 사례가 적용되었습니다.

src/icons/Send.tsx (1)

1-42: LGTM!

일관된 아이콘 구현 패턴을 따르며 TypeScript 타입 안전성과 접근성을 모두 고려한 우수한 구현입니다.

src/icons/Certification.tsx (1)

1-42: 잘 구현된 아이콘 컴포넌트입니다.

일관된 API 패턴(size, aria-label), 적절한 접근성 처리(aria-hidden 토글), TypeScript 타입 지원이 모두 잘 구현되어 있습니다.

src/icons/Logo.tsx (2)

21-23: aspectRatio 값 검증이 잘 되어 있습니다.

viewBox "0 0 81 20"에서 계산된 aspectRatio 4.05 (81/20)가 정확합니다. 로고의 가로세로 비율을 올바르게 유지합니다.


36-43: 브랜드 색상 사용이 적절합니다.

다른 아이콘들과 달리 currentColor 대신 고정된 브랜드 색상(#FF6929)을 사용하는 것은 로고의 일관된 브랜드 아이덴티티 유지를 위해 적절한 선택입니다.

src/components/FloatingButton/FloatingButton.tsx (1)

3-3: 아이콘 import 업데이트가 올바릅니다.

새로운 아이콘 시스템으로의 전환이 정확하게 이루어졌습니다.

scripts/update-icons-index.cjs (1)

14-50: 잘 구현된 인덱스 생성 스크립트입니다.

스크립트 로직이 명확하고 에러 처리도 적절합니다. 파일 필터링, 정렬, export 문 생성이 올바르게 구현되어 있습니다.

src/icons/ArrowLeft.tsx (1)

1-42: 일관된 패턴의 아이콘 컴포넌트입니다.

Props 인터페이스, 접근성 처리, displayName 설정이 모두 올바르게 구현되었습니다. currentColor 사용으로 테마 색상 적용이 가능합니다.

src/icons/Save.tsx (1)

1-42: 올바르게 구현된 아이콘 컴포넌트입니다.

다른 아이콘들과 동일한 패턴을 따르며, 접근성 및 타입 정의가 적절합니다.

package.json (2)

35-36: 아이콘 생성 워크플로우가 잘 구성되었습니다.

SVGR과 SVGO를 활용한 자동화된 아이콘 생성 파이프라인이 적절하게 설정되었습니다. 스크립트 체이닝 순서가 논리적입니다.


78-78: Dependency versions are current and secure.

@svgr/cli@8.1.0 is the latest available version with no reported vulnerabilities. svgo@3.0.2 is stable; a newer major version (4.0.0) exists but upgrading is optional. No critical security advisories apply to these versions.

src/icons/Eye.tsx (1)

1-40: 일관된 아이콘 컴포넌트 구현입니다.

타입 정의, 접근성 처리, 스타일링이 다른 아이콘들과 동일한 패턴을 따릅니다.

src/icons/Location.tsx (1)

1-40: 적절하게 구현된 아이콘 컴포넌트입니다.

일관된 패턴과 올바른 접근성 구현을 확인했습니다.

src/icons/Start.tsx (1)

1-40: 올바르게 구현된 아이콘 컴포넌트입니다.

다른 아이콘들과 일관된 패턴을 따르며, 모든 필수 요소가 적절하게 구현되었습니다.

src/icons/LogoSymbol.tsx (2)

3-14: LGTM!

Props 인터페이스, 접근성 처리, displayName 설정이 모두 올바르게 구현되어 있습니다.

Also applies to: 16-31, 38-40


32-35: Hardcoded brand colors appear intentional

The hardcoded fill colors (#FF6929, #FF8754) in LogoSymbol.tsx, Logo.tsx, TileSymbol.tsx, and CircleSymbol.tsx are distinct from utility icons, which consistently use fill="currentColor". This pattern suggests the hardcoded colors are intentional for maintaining brand identity. No changes needed unless color customization is a new requirement for these brand components.

src/icons/Photo.tsx (1)

3-42: LGTM!

컴포넌트 구조, 타입 정의, 접근성 구현이 모두 올바릅니다. currentColor 사용으로 색상 커스터마이징이 가능합니다.

src/icons/CircleSymbol.tsx (2)

32-37: 하드코딩된 색상 값 확인 필요

LogoSymbol과 마찬가지로 #FF8754 색상이 하드코딩되어 있습니다. 브랜드 심볼의 정체성을 위해 고정 색상이 필요한 경우가 아니라면, 다른 아이콘들과의 일관성을 위해 currentColor를 사용하는 것을 권장합니다.


3-14: LGTM!

Props 인터페이스와 접근성 구현이 올바릅니다.

Also applies to: 16-31, 38-42

src/icons/Community.tsx (1)

3-40: LGTM!

타입 정의, 접근성 처리, currentColor 사용 등 모든 구현이 올바릅니다.

src/icons/Share.tsx (1)

3-45: LGTM!

여러 개의 SVG 요소를 포함하고 있으며 모두 currentColor를 사용하여 일관된 색상 제어가 가능합니다. 구현이 올바릅니다.

src/icons/Delete.tsx (1)

3-42: LGTM!

컴포넌트 구조와 접근성 구현이 올바릅니다.

src/icons/Edit.tsx (1)

3-40: LGTM!

타입 정의와 접근성 처리가 올바르게 구현되어 있습니다.

src/icons/Good.tsx (1)

3-40: LGTM!

Props 인터페이스, 접근성 구현, currentColor 사용 등 모든 부분이 올바릅니다.

src/icons/Family.tsx (1)

3-40: Family 아이콘 컴포넌트 구현 이상 없어 보입니다

ArrowRight와 동일한 패턴으로 size, aria-label/aria-hidden, currentColor 처리까지 일관되게 적용되어 있어서 바로 사용해도 무방해 보입니다.

src/icons/Funding.tsx (1)

3-40: Funding 아이콘도 공통 패턴을 잘 따르고 있습니다

FundingProps 정의, size 기본값, aria-label/aria-hidden 처리, currentColor 사용까지 다른 아이콘과 일관되며 특별한 문제는 없어 보입니다.

src/icons/Reset.tsx (1)

3-40: Reset 아이콘 컴포넌트도 일관된 API로 잘 추가되었습니다

기존 아이콘들과 동일한 프로퍼티·접근성 패턴을 사용하고 있어, 디자인 시스템 내에서 일관성 있게 활용 가능해 보입니다.

src/icons/ArrowTop.tsx (1)

3-40: ArrowTop 아이콘 구현도 문제 없어 보입니다

다른 Arrow 계열 아이콘과 동일한 프로퍼티·접근성 패턴을 따르고 있고, SVG path만 상단 화살표 형태로 변경되어 있어 일관성과 사용성 측면에서 무리가 없습니다.

src/icons/Heart.tsx (1)

3-40: Heart 아이콘 컴포넌트도 디자인 시스템 패턴에 잘 맞습니다

HeartProps와 컴포넌트 구현이 다른 아이콘들과 동일한 형태라, 상태 아이콘(좋아요/즐겨찾기 등)으로 사용할 때에도 일관된 API로 다룰 수 있어 보입니다.

src/icons/DisasterInfo.tsx (1)

3-40: DisasterInfo 아이콘도 정보성 아이콘 용도로 무리 없이 사용 가능합니다

공통 아이콘 프로퍼티 구조와 aria-label/aria-hidden 처리 방식이 그대로 적용되어 있어, 재난/안내 정보 관련 UI에 붙여도 일관성 있게 동작할 것 같습니다.

src/icons/Ellipsis.tsx (1)

1-39: LGTM!

아이콘 컴포넌트가 일관된 패턴을 따르고 있습니다. size prop, aria-label 기반 접근성 처리, displayName 설정이 올바르게 구현되었습니다.

src/icons/Home.tsx (1)

1-40: LGTM!

아이콘 컴포넌트가 프로젝트의 아이콘 패턴을 올바르게 따르고 있습니다.

src/icons/My.tsx (1)

1-42: LGTM!

아이콘 컴포넌트가 일관된 패턴을 따르고 있으며, fillRule과 clipRule 속성이 올바르게 적용되었습니다.

src/icons/Plus.tsx (1)

3-48: Breaking change: PlusIcon → Plus successfully completed

The component rename from PlusIcon to Plus is fully implemented. FloatingButton correctly imports and uses the new Plus component with aria-label="+". All code references have been updated.

Minor note: The test comment in FloatingButton.test.tsx still references "PlusIcon" (// PlusIcon이 aria-label="+"로 렌더링됨) but the test itself is correct and functional—consider updating the comment for consistency.

scripts/post-process-icons.cjs (3)

11-24: LGTM!

파일명을 PascalCase로 변환하는 로직이 적절합니다. 하이픈, 언더스코어, 공백을 올바르게 처리합니다.


67-77: 비정사각형 아이콘의 viewBox 강제 변환 주의

기존 viewBox가 있어도 강제로 "0 0 24 24"로 변경하면, 원본이 정사각형이 아닌 아이콘(예: 16x20)의 경우 왜곡될 수 있습니다. 의도된 동작이라면 무시해도 됩니다.


218-231: 접근성 구현이 적절합니다

aria-label이 제공되지 않으면 aria-hidden={true}로 설정하여 장식용 아이콘으로 처리하는 패턴이 올바르게 구현되어 있습니다. TypeScript 타입 정의와 JSDoc 문서화도 잘 되어 있습니다.

Comment on lines +118 to +119
// logo 파일인지 확인 (정확히 "Logo"만 매칭)
const isLogo = componentName === "Logo";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all logo-related files
find src/icons -type f -name "*Logo*" 2>/dev/null

Repository: Team-NumberOne/daepyro-design-system

Length of output: 123


🏁 Script executed:

#!/bin/bash
# Check context in post-process-icons.cjs
sed -n '100,140p' scripts/post-process-icons.cjs

Repository: Team-NumberOne/daepyro-design-system

Length of output: 1102


🏁 Script executed:

#!/bin/bash
# Search for LogoSymbol or logo variant references
rg "Logo" scripts/post-process-icons.cjs -B 5 -A 5

Repository: Team-NumberOne/daepyro-design-system

Length of output: 1390


🏁 Script executed:

#!/bin/bash
# Search entire codebase for LogoSymbol
rg "LogoSymbol" --type ts --type tsx --type js --type jsx --type cjs

Repository: Team-NumberOne/daepyro-design-system

Length of output: 107


Update logo variant matching to include "LogoSymbol"

Both Logo.tsx and LogoSymbol.tsx exist in src/icons/. Currently, only componentName === "Logo" is treated with special logo handling (preserving original dimensions and viewBox). Update the condition to also match LogoSymbol:

const isLogo = componentName === "Logo" || componentName === "LogoSymbol";

This ensures LogoSymbol receives the same original size preservation treatment as Logo.

🤖 Prompt for AI Agents
In scripts/post-process-icons.cjs around lines 118 to 119, the code only treats
the "Logo" component specially; update the logo-detection condition to also
recognize "LogoSymbol" so both variants preserve original dimensions and
viewBox. Replace the strict equality check with a compound condition that
returns true for either "Logo" or "LogoSymbol" (e.g., using a logical OR or an
array includes) so LogoSymbol receives the same processing path as Logo.

Comment on lines +147 to +149
const width = originalSvgInfo?.width || originalWidth || "81";
const height = originalSvgInfo?.height || originalHeight || "20";
const aspectRatio = parseFloat(width) / parseFloat(height);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

parseFloat NaN 가능성 검증 필요

width 또는 height가 순수 숫자가 아닌 경우(예: "auto", "%") parseFloat가 NaN을 반환하여 생성된 코드에 NaN이 포함될 수 있습니다.

     const width = originalSvgInfo?.width || originalWidth || "81";
     const height = originalSvgInfo?.height || originalHeight || "20";
-    const aspectRatio = parseFloat(width) / parseFloat(height);
+    const parsedWidth = parseFloat(width);
+    const parsedHeight = parseFloat(height);
+    const aspectRatio = (Number.isNaN(parsedWidth) || Number.isNaN(parsedHeight) || parsedHeight === 0)
+      ? 81 / 20  // 기본 비율
+      : parsedWidth / parsedHeight;
📝 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 width = originalSvgInfo?.width || originalWidth || "81";
const height = originalSvgInfo?.height || originalHeight || "20";
const aspectRatio = parseFloat(width) / parseFloat(height);
const width = originalSvgInfo?.width || originalWidth || "81";
const height = originalSvgInfo?.height || originalHeight || "20";
const parsedWidth = parseFloat(width);
const parsedHeight = parseFloat(height);
const aspectRatio = (Number.isNaN(parsedWidth) || Number.isNaN(parsedHeight) || parsedHeight === 0)
? 81 / 20 // 기본 비율
: parsedWidth / parsedHeight;
🤖 Prompt for AI Agents
In scripts/post-process-icons.cjs around lines 147 to 149, parseFloat(width) or
parseFloat(height) can return NaN for non-numeric values like "auto" or "%",
which will propagate into aspectRatio; ensure you validate the parsed values and
fall back to safe numeric defaults before dividing. Specifically, parseFloat
both width and height into local variables, check Number.isFinite(...) and that
height !== 0, and if either is invalid use originalWidth/originalHeight or the
string literal defaults ("81" and "20") converted to numbers; then compute
aspectRatio from these validated numeric values so NaN or division-by-zero
cannot occur.

Comment on lines +287 to +291
// 파일명이 다르면 변경
if (file !== newFileName) {
await rename(filePath, newFilePath);
console.log(`📝 ${file} -> ${newFileName}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

파일 덮어쓰기 위험

rename() 전에 대상 파일 존재 여부를 확인하지 않습니다. 예를 들어 arrow-down.tsx와 ArrowDown.tsx가 모두 존재하면 예기치 않게 덮어쓸 수 있습니다.

+      const { access } = require("node:fs/promises");
       // 파일명이 다르면 변경
       if (file !== newFileName) {
+        try {
+          await access(newFilePath);
+          console.warn(`⚠️  ${newFileName}가 이미 존재합니다. ${file} 스킵.`);
+          continue;
+        } catch {
+          // 파일이 없으면 정상 진행
+        }
         await rename(filePath, newFilePath);
         console.log(`📝 ${file} -> ${newFileName}`);
       }

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

🤖 Prompt for AI Agents
In scripts/post-process-icons.cjs around lines 287-291, the code renames files
without checking whether the target path already exists which can overwrite an
existing file (e.g., arrow-down.tsx vs ArrowDown.tsx); before calling
rename(filePath, newFilePath) check whether newFilePath exists (fs.access or
fs.stat) and if it does either (a) skip the rename and log a warning/error, or
(b) compute a non-colliding unique filename (append a numeric suffix) and use
that as newFileName, then perform the rename and handle/report any errors;
ensure the existence check and rename are properly awaited and wrapped in
try/catch.

Comment thread src/icons/Alram.tsx Outdated
Comment on lines +1 to +46
import type { SVGProps } from "react";

export interface AlramProps extends SVGProps<SVGSVGElement> {
/**
* 아이콘 크기
* @default 24
*/
size?: number;
/**
* 아이콘의 접근성 레이블
* 제공하지 않으면 장식용으로 처리됩니다 (aria-hidden="true")
*/
"aria-label"?: string;
}

export const Alram = ({
size = 24,
"aria-label": ariaLabel,
...props
}: AlramProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
aria-label={ariaLabel}
aria-hidden={!ariaLabel}
{...props}
>
<path
fill="currentColor"
fillRule="evenodd"
d="M4.902 8.844C5.267 5.242 8.335 2.5 12 2.5s6.734 2.742 7.098 6.344l.499 4.924a.3.3 0 0 0 .051.137l.981 1.399c.948 1.35-.03 3.196-1.695 3.196H5.066c-1.664 0-2.643-1.846-1.695-3.196l.981-1.4a.3.3 0 0 0 .051-.136z"
clipRule="evenodd"
/>
<path
fill="currentColor"
d="M16 19.5c0 .263-.104.523-.305.765-.2.243-.495.463-.867.65a5.4 5.4 0 0 1-1.297.433c-.486.1-1.006.152-1.531.152a7.6 7.6 0 0 1-1.53-.152 5.4 5.4 0 0 1-1.298-.434c-.372-.186-.667-.406-.868-.649-.2-.242-.304-.502-.304-.765z"
/>
</svg>
);
};

Alram.displayName = "Alram";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

오타: Alram → Alarm

"Alram"은 "Alarm"의 오타입니다. 이 컴포넌트가 공개 API의 일부이므로, 나중에 수정하면 breaking change가 됩니다. 지금 수정하는 것을 권장합니다.

영향 범위:

  • 파일명: Alram.tsx → Alarm.tsx
  • 인터페이스: AlramProps → AlarmProps
  • 컴포넌트: Alram → Alarm
  • displayName: "Alram" → "Alarm"
  • index.ts 내보내기
🤖 Prompt for AI Agents
In src/icons/Alram.tsx lines 1-46 the component and types are misspelled as
"Alram" instead of "Alarm"; rename the file to src/icons/Alarm.tsx, rename the
exported component from Alram to Alarm, rename AlramProps to AlarmProps, update
the default export/displayName to "Alarm", and update any index.ts or other
re-exports/imports to export/import Alarm (adjust paths/usages across the repo
to avoid broken imports).

Comment thread src/icons/HambugerBar.tsx Outdated
Comment on lines +1 to +42
import type { SVGProps } from "react";

export interface HambugerBarProps extends SVGProps<SVGSVGElement> {
/**
* 아이콘 크기
* @default 24
*/
size?: number;
/**
* 아이콘의 접근성 레이블
* 제공하지 않으면 장식용으로 처리됩니다 (aria-hidden="true")
*/
"aria-label"?: string;
}

export const HambugerBar = ({
size = 24,
"aria-label": ariaLabel,
...props
}: HambugerBarProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
aria-label={ariaLabel}
aria-hidden={!ariaLabel}
{...props}
>
<path
fill="currentColor"
fillRule="evenodd"
d="M20 7.75H4v-2.5h16zm0 5.5H4v-2.5h16zm0 5.5H4v-2.5h16z"
clipRule="evenodd"
/>
</svg>
);
};

HambugerBar.displayName = "HambugerBar";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

파일명 및 컴포넌트명 오타 수정 필요

파일명과 컴포넌트명에 오타가 있습니다. "Hambuger"가 아닌 "Hamburger"가 올바른 철자입니다.

수정이 필요한 항목:

  • 파일명: HambugerBar.tsx → HamburgerBar.tsx
  • 인터페이스명: HambugerBarProps → HamburgerBarProps
  • 컴포넌트명: HambugerBar → HamburgerBar
  • displayName: "HambugerBar" → "HamburgerBar"
  • src/icons/index.ts의 export도 함께 수정 필요

수정을 위한 diff:

-export interface HambugerBarProps extends SVGProps<SVGSVGElement> {
+export interface HamburgerBarProps extends SVGProps<SVGSVGElement> {
 	/**
 	 * 아이콘 크기
 	 * @default 24
 	 */
 	size?: number;
 	/**
 	 * 아이콘의 접근성 레이블
 	 * 제공하지 않으면 장식용으로 처리됩니다 (aria-hidden="true")
 	 */
 	"aria-label"?: string;
 }

-export const HambugerBar = ({
+export const HamburgerBar = ({
 	size = 24,
 	"aria-label": ariaLabel,
 	...props
-}: HambugerBarProps) => {
+}: HamburgerBarProps) => {
 	return (
 		<svg
 			xmlns="http://www.w3.org/2000/svg"
 			width={size}
 			height={size}
 			viewBox="0 0 24 24"
 			fill="none"
 			aria-label={ariaLabel}
 			aria-hidden={!ariaLabel}
 			{...props}
 		>
 			<path
 				fill="currentColor"
 				fillRule="evenodd"
 				d="M20 7.75H4v-2.5h16zm0 5.5H4v-2.5h16zm0 5.5H4v-2.5h16z"
 				clipRule="evenodd"
 			/>
 		</svg>
 	);
 };

-HambugerBar.displayName = "HambugerBar";
+HamburgerBar.displayName = "HamburgerBar";

또한 src/icons/index.ts에서도 수정 필요:

-export { HambugerBar } from "./HambugerBar";
+export { HamburgerBar } from "./HamburgerBar";
📝 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 type { SVGProps } from "react";
export interface HambugerBarProps extends SVGProps<SVGSVGElement> {
/**
* 아이콘 크기
* @default 24
*/
size?: number;
/**
* 아이콘의 접근성 레이블
* 제공하지 않으면 장식용으로 처리됩니다 (aria-hidden="true")
*/
"aria-label"?: string;
}
export const HambugerBar = ({
size = 24,
"aria-label": ariaLabel,
...props
}: HambugerBarProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
aria-label={ariaLabel}
aria-hidden={!ariaLabel}
{...props}
>
<path
fill="currentColor"
fillRule="evenodd"
d="M20 7.75H4v-2.5h16zm0 5.5H4v-2.5h16zm0 5.5H4v-2.5h16z"
clipRule="evenodd"
/>
</svg>
);
};
HambugerBar.displayName = "HambugerBar";
import type { SVGProps } from "react";
export interface HamburgerBarProps extends SVGProps<SVGSVGElement> {
/**
* 아이콘 크기
* @default 24
*/
size?: number;
/**
* 아이콘의 접근성 레이블
* 제공하지 않으면 장식용으로 처리됩니다 (aria-hidden="true")
*/
"aria-label"?: string;
}
export const HamburgerBar = ({
size = 24,
"aria-label": ariaLabel,
...props
}: HamburgerBarProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
aria-label={ariaLabel}
aria-hidden={!ariaLabel}
{...props}
>
<path
fill="currentColor"
fillRule="evenodd"
d="M20 7.75H4v-2.5h16zm0 5.5H4v-2.5h16zm0 5.5H4v-2.5h16z"
clipRule="evenodd"
/>
</svg>
);
};
HamburgerBar.displayName = "HamburgerBar";
🤖 Prompt for AI Agents
In src/icons/HambugerBar.tsx lines 1-42 the component and types are misspelled
as "Hambuger" instead of "Hamburger"; rename the file to
src/icons/HamburgerBar.tsx, update the interface HambugerBarProps →
HamburgerBarProps, the component HambugerBar → HamburgerBar, and the displayName
string to "HamburgerBar"; also update any callers and the export in
src/icons/index.ts to export the renamed HamburgerBar from the new file path to
keep imports working.

Comment thread src/icons/index.ts Resolved
Comment thread src/icons/index.ts Outdated
export { Filter } from "./Filter";
export { Funding } from "./Funding";
export { Good } from "./Good";
export { HambugerBar } from "./HambugerBar";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

오타: HambugerBar → HamburgerBar

"Hambuger"는 "Hamburger"의 오타입니다. 해당 아이콘 파일(HambugerBar.tsx)과 소스 SVG 파일명을 함께 수정해야 합니다.

🤖 Prompt for AI Agents
In src/icons/index.ts around line 22, the exported identifier has a typo: export
{ HambugerBar } from "./HambugerBar"; — rename the component/file to
HamburgerBar (fix the filename HambugerBar.tsx → HamburgerBar.tsx and the
internal component name/export), update the source SVG filename if it contains
the same typo, and update this export to export { HamburgerBar } from
"./HamburgerBar"; also search and update all imports/usages across the repo to
the corrected name to avoid broken imports.

Comment thread src/icons/TileSymbol.tsx
Comment on lines +32 to +39
<path
fill="#FF6929"
d="m12.744 9.442-2.372-.437a.312.312 0 0 0-.372.301v5.389c0 .191.18.336.374.3l2.372-.451a.31.31 0 0 0 .254-.3v-4.5a.31.31 0 0 0-.256-.301z"
/>
<path
fill="#FF6929"
d="m19.715 8.898-4.613-4.613a4.387 4.387 0 0 0-6.204 0L4.285 8.898a4.387 4.387 0 0 0 0 6.204l4.613 4.613a4.386 4.386 0 0 0 6.204 0l4.613-4.613a4.386 4.386 0 0 0 0-6.204m-4.07 6.984a.3.3 0 0 1-.298.298H8.653a.3.3 0 0 1-.299-.298V8.118c0-.165.134-.298.299-.298h6.694c.166 0 .299.134.299.298z"
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

하드코딩된 색상을 currentColor로 변경하세요.

이 아이콘만 #FF6929 색상이 하드코딩되어 있어 다른 아이콘들과 일관성이 없습니다. CSS를 통한 색상 제어가 불가능하여 재사용성이 떨어집니다.

다음 diff를 적용하여 다른 아이콘들과 동일하게 currentColor를 사용하도록 변경하세요:

 			<path
-				fill="#FF6929"
+				fill="currentColor"
 				d="m12.744 9.442-2.372-.437a.312.312 0 0 0-.372.301v5.389c0 .191.18.336.374.3l2.372-.451a.31.31 0 0 0 .254-.3v-4.5a.31.31 0 0 0-.256-.301z"
 			/>
 			<path
-				fill="#FF6929"
+				fill="currentColor"
 				d="m19.715 8.898-4.613-4.613a4.387 4.387 0 0 0-6.204 0L4.285 8.898a4.387 4.387 0 0 0 0 6.204l4.613 4.613a4.386 4.386 0 0 0 6.204 0l4.613-4.613a4.386 4.386 0 0 0 0-6.204m-4.07 6.984a.3.3 0 0 1-.298.298H8.653a.3.3 0 0 1-.299-.298V8.118c0-.165.134-.298.299-.298h6.694c.166 0 .299.134.299.298z"
 			/>

특정 색상이 필요한 경우, 부모 컴포넌트에서 className이나 style prop을 통해 색상을 지정하는 것이 권장됩니다.

📝 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
<path
fill="#FF6929"
d="m12.744 9.442-2.372-.437a.312.312 0 0 0-.372.301v5.389c0 .191.18.336.374.3l2.372-.451a.31.31 0 0 0 .254-.3v-4.5a.31.31 0 0 0-.256-.301z"
/>
<path
fill="#FF6929"
d="m19.715 8.898-4.613-4.613a4.387 4.387 0 0 0-6.204 0L4.285 8.898a4.387 4.387 0 0 0 0 6.204l4.613 4.613a4.386 4.386 0 0 0 6.204 0l4.613-4.613a4.386 4.386 0 0 0 0-6.204m-4.07 6.984a.3.3 0 0 1-.298.298H8.653a.3.3 0 0 1-.299-.298V8.118c0-.165.134-.298.299-.298h6.694c.166 0 .299.134.299.298z"
/>
<path
fill="currentColor"
d="m12.744 9.442-2.372-.437a.312.312 0 0 0-.372.301v5.389c0 .191.18.336.374.3l2.372-.451a.31.31 0 0 0 .254-.3v-4.5a.31.31 0 0 0-.256-.301z"
/>
<path
fill="currentColor"
d="m19.715 8.898-4.613-4.613a4.387 4.387 0 0 0-6.204 0L4.285 8.898a4.387 4.387 0 0 0 0 6.204l4.613 4.613a4.386 4.386 0 0 0 6.204 0l4.613-4.613a4.386 4.386 0 0 0 0-6.204m-4.07 6.984a.3.3 0 0 1-.298.298H8.653a.3.3 0 0 1-.299-.298V8.118c0-.165.134-.298.299-.298h6.694c.166 0 .299.134.299.298z"
/>
🤖 Prompt for AI Agents
In src/icons/TileSymbol.tsx around lines 32 to 39, the two <path> elements
hardcode fill="#FF6929" which prevents CSS color inheritance; change both fill
attributes to "currentColor" so the icon inherits color from parent (allowing
styling via className or style), and ensure any components needing the original
orange set the color on the parent element instead.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/icons/HamburgerBar.tsx (1)

28-29: aria-hidden 패턴 개선 제안 (선택사항)

현재 aria-hidden={!ariaLabel} 패턴은 명시적이지만, aria-hidden의 기본값이 false이므로 기술적으로는 중복입니다. 다음과 같이 간소화할 수 있습니다:

 			aria-label={ariaLabel}
-			aria-hidden={!ariaLabel}
+			{...(!ariaLabel && { "aria-hidden": true })}

또는 aria-label이 있을 때만 aria-hidden을 생략:

 			aria-label={ariaLabel}
-			aria-hidden={!ariaLabel}
+			{...(!ariaLabel && { "aria-hidden": "true" })}

다만 현재 패턴도 명확하고 일관성이 있으므로, 특히 생성된 코드라면 현재 방식을 유지하는 것도 합리적입니다.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 083f7f0 and dd7916c.

⛔ Files ignored due to path filters (2)
  • assets/svgs/alarm.svg is excluded by !**/*.svg
  • assets/svgs/hamburger-bar.svg is excluded by !**/*.svg
📒 Files selected for processing (5)
  • src/icons/Alarm.tsx (1 hunks)
  • src/icons/HamburgerBar.tsx (1 hunks)
  • src/icons/index.ts (1 hunks)
  • vite.config.ts (2 hunks)
  • vitest.config.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • vitest.config.ts
  • vite.config.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/icons/HamburgerBar.tsx (1)
src/icons/index.ts (1)
  • HamburgerBar (22-22)
🔇 Additional comments (3)
src/icons/HamburgerBar.tsx (1)

1-42: 아이콘 컴포넌트 구현이 우수합니다!

TypeScript 타입 정의, 접근성 처리, 그리고 테마 지원(currentColor)이 잘 구현되어 있습니다. 컴포넌트 구조가 명확하고 재사용 가능합니다.

src/icons/Alarm.tsx (1)

1-46: 일관된 아이콘 패턴 구현 확인

Alarm 컴포넌트가 HamburgerBar와 동일한 패턴을 따르고 있어 아이콘 라이브러리 전체의 일관성이 유지됩니다. TypeScript 타입, 접근성 처리, 그리고 props 구조가 모두 올바르게 구현되어 있습니다.

src/icons/index.ts (1)

1-42: Previous review feedback has been properly addressed ✅

The typos mentioned in the prior review (Alram → Alarm, HambugerBar → HamburgerBar) have been corrected. All 42 exports are properly alphabetically sorted, and every exported icon file exists in the codebase with consistent file structure. File count verification confirms all exports have corresponding implementation files.

@choihooo
choihooo merged commit 1ecf1c9 into develop Dec 1, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant