Repository navigation
[feat]: icon 컴포넌트 추가 - #6
Conversation
워크스루SVGO 및 SVGR을 활용한 자동 아이콘 생성 파이프라인을 도입합니다. 45개 이상의 새로운 아이콘 컴포넌트를 추가하고, 사후 처리 및 인덱스 생성 스크립트를 구현하며, 경로 별칭을 설정하고 관련 구성 파일을 업데이트합니다. 변경 사항
추정 코드 리뷰 노력🎯 3 (중간) | ⏱️ ~25분 특별 주의 사항:
관련 이슈
관련 PR
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (43)
assets/svgs/Funding.svgis excluded by!**/*.svgassets/svgs/Location.svgis excluded by!**/*.svgassets/svgs/Logo.svgis excluded by!**/*.svgassets/svgs/My.svgis excluded by!**/*.svgassets/svgs/alram.svgis excluded by!**/*.svgassets/svgs/arrow-down.svgis excluded by!**/*.svgassets/svgs/arrow-left.svgis excluded by!**/*.svgassets/svgs/arrow-right.svgis excluded by!**/*.svgassets/svgs/arrow-top.svgis excluded by!**/*.svgassets/svgs/certification.svgis excluded by!**/*.svgassets/svgs/check-box-disabled.svgis excluded by!**/*.svgassets/svgs/check-box-enabled.svgis excluded by!**/*.svgassets/svgs/circle-symbol.svgis excluded by!**/*.svgassets/svgs/close.svgis excluded by!**/*.svgassets/svgs/community.svgis excluded by!**/*.svgassets/svgs/copy.svgis excluded by!**/*.svgassets/svgs/delete.svgis excluded by!**/*.svgassets/svgs/disaster-info.svgis excluded by!**/*.svgassets/svgs/edit.svgis excluded by!**/*.svgassets/svgs/ellipsis.svgis excluded by!**/*.svgassets/svgs/eye.svgis excluded by!**/*.svgassets/svgs/family.svgis excluded by!**/*.svgassets/svgs/filter.svgis excluded by!**/*.svgassets/svgs/good.svgis excluded by!**/*.svgassets/svgs/hambuger-bar.svgis excluded by!**/*.svgassets/svgs/heart.svgis excluded by!**/*.svgassets/svgs/home.svgis excluded by!**/*.svgassets/svgs/logo-symbol.svgis excluded by!**/*.svgassets/svgs/minus.svgis excluded by!**/*.svgassets/svgs/noti.svgis excluded by!**/*.svgassets/svgs/phone.svgis excluded by!**/*.svgassets/svgs/photo.svgis excluded by!**/*.svgassets/svgs/plus.svgis excluded by!**/*.svgassets/svgs/reset.svgis excluded by!**/*.svgassets/svgs/save.svgis excluded by!**/*.svgassets/svgs/search.svgis excluded by!**/*.svgassets/svgs/send.svgis excluded by!**/*.svgassets/svgs/share.svgis excluded by!**/*.svgassets/svgs/start.svgis excluded by!**/*.svgassets/svgs/tile-symbol.svgis excluded by!**/*.svgassets/svgs/warning.svgis excluded by!**/*.svgassets/svgs/weather.svgis excluded by!**/*.svgpnpm-lock.yamlis 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 intentionalThe 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!아이콘 컴포넌트가 일관된 패턴을 따르고 있습니다.
sizeprop,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→Plussuccessfully completedThe component rename from
PlusIcontoPlusis fully implemented. FloatingButton correctly imports and uses the newPluscomponent witharia-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 문서화도 잘 되어 있습니다.
| // logo 파일인지 확인 (정확히 "Logo"만 매칭) | ||
| const isLogo = componentName === "Logo"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find all logo-related files
find src/icons -type f -name "*Logo*" 2>/dev/nullRepository: 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.cjsRepository: 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 5Repository: 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 cjsRepository: 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.
| const width = originalSvgInfo?.width || originalWidth || "81"; | ||
| const height = originalSvgInfo?.height || originalHeight || "20"; | ||
| const aspectRatio = parseFloat(width) / parseFloat(height); |
There was a problem hiding this comment.
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.
| 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.
| // 파일명이 다르면 변경 | ||
| if (file !== newFileName) { | ||
| await rename(filePath, newFilePath); | ||
| console.log(`📝 ${file} -> ${newFileName}`); | ||
| } |
There was a problem hiding this comment.
파일 덮어쓰기 위험
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.
| 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"; |
There was a problem hiding this comment.
오타: 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).
| 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"; |
There was a problem hiding this comment.
파일명 및 컴포넌트명 오타 수정 필요
파일명과 컴포넌트명에 오타가 있습니다. "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.
| 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.
| export { Filter } from "./Filter"; | ||
| export { Funding } from "./Funding"; | ||
| export { Good } from "./Good"; | ||
| export { HambugerBar } from "./HambugerBar"; |
There was a problem hiding this comment.
오타: 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.
| <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" | ||
| /> |
There was a problem hiding this comment.
🛠️ 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.
| <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.
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (2)
assets/svgs/alarm.svgis excluded by!**/*.svgassets/svgs/hamburger-bar.svgis 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.
변경 사항
변경 유형
관련 이슈
체크리스트
컴포넌트 관련 (컴포넌트 추가/수정 시)
src/components/디렉토리에 올바르게 위치해 있습니다src/index.ts에서 export 되었습니다스토리북 관련
*.stories.ts)이 생성/업데이트되었습니다autodocs태그가 포함되어 있습니다품질 관리
pnpm run lint통과pnpm run check(타입 체크) 통과pnpm test --run통과pnpm run build)접근성
문서화
테스트
스크린샷 / 데모
추가 정보
Summary by CodeRabbit
릴리스 노트
새로운 기능
Chores
✏️ Tip: You can customize this high-level summary in your review settings.