Skip to content

feat: Icon 컴포넌트 구현#6

Merged
ccconac merged 19 commits intodevfrom
feat/4-icon-component
Dec 28, 2025
Merged

feat: Icon 컴포넌트 구현#6
ccconac merged 19 commits intodevfrom
feat/4-icon-component

Conversation

@ccconac
Copy link
Copy Markdown
Member

@ccconac ccconac commented Dec 28, 2025

✅ 체크리스트

  • SVGR 변환을 위한 라이브러리 설치 및 CLI 추가
  • iconMap 자동 생성을 위한 스크립트 추가
  • Icon 컴포넌트 구현

📝 작업 상세 내용

1. SVGR 변환을 위한 라이브러리 설치 및 CLI 추가

아이콘을 추가한 뒤 아래 명령어를 터미널에 입력하면 자동으로 SVG 파일이 SVGR로 변환됩니다. 자세한 내용은 블로그에 작성해 두었습니다. [CLI] SVG 파일을 SVGR로 편리하게 변환하기

> npm run build:icons

2. iconMap 자동 생성을 위한 스크립트 추가

객체를 일일이 추가해야 하는 번거로움이 있어 node 스크립트를 추가적으로 작성했습니다. 아래 명령어를 입력하면 자동으로 iconMap이 생성됩니다.

> npm run gen:iconMap

만일 1번과 2번을 동시에 실행하고 싶다면 아래 명령어를 사용합니다.

> npm run build:icons:all

3. Icon 컴포넌트 구현

아래와 같이 Icon 컴포넌트를 사용할 수 있습니다.

import { Icon } from './components/Icon/Icon';

function App() {
  return (
    <div className="flex w-screen gap-3 justify-center pt-5">
      <Icon name="addLine" size="xs" />
      <Icon name="addLine" size="md" color="#aac65c" />
      <Icon name="addLine" size="xl" color="#5812c1" />
    </div>
  );
}

📚 참고 자료 (선택 사항)

[React] svg 파일 → 리액트 컴포넌트 변환하기 - React SVGR
Icon 컴포넌트 만들기(with SVGR, 동적 import)
svgr을 활용하여 svg 파일 유연하게 사용하기

📸 스크린샷 (선택 사항)

스크린샷 2025-12-28 오후 7 08 23

✅ 셀프 체크리스트

  • 브랜치 확인하기
  • 불필요한 코드가 들어가지 않았는지 재확인하기
  • issue 닫기
  • reiewers, assignees, Lables 등록 확인하기

이슈 번호: #4

Summary by CodeRabbit

  • 새 기능

    • 재사용 가능한 아이콘 컴포넌트 추가 — XS/SM/MD/LG/XL 크기 및 색상 지원
    • 이름 기반 아이콘 매핑 추가로 아이콘 사용이 더 쉬워짐
  • 작업(Chores)

    • 아이콘 생성 및 매핑 자동화 도구(아이콘 빌드/매핑 생성 스크립트)와 관련 개발 스크립트 추가로 워크플로우 개선

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

@ccconac ccconac self-assigned this Dec 28, 2025
@ccconac ccconac added 🔨 CHORE 환경 설정 관련 ✨ FEAT 기능 개발 💄 DESIGN UI 구현 labels Dec 28, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 28, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

SVGR 설정과 아이콘 생성/매핑 스크립트, 타입 및 런타임 Icon 컴포넌트를 추가하여 SVG → TSX 아이콘 생성과 아이콘 맵(sizeMap/iconMap) 자동화를 도입합니다.

Changes

Cohort / File(s) Summary
SVGR 설정
\.svgrrc.json
SVGR 구성 파일 추가: TypeScript/TSX 출력, Prettier 활성화, svgProps.fill="currentColor", icon: true, jsxRuntime: "automatic"
패키지 & 스크립트
package.json
build:icons, gen:iconMap, build:icons:all 스크립트 추가 및 @svgr/cli devDependency 추가
아이콘 맵 생성 스크립트
scripts/generate-iconMap.js
생성된 generated 디렉토리의 .tsx 아이콘 컴포넌트를 스캔해 src/components/Icon/iconMap.ts (자동 헤더, sizeMap, iconMap)을 생성하는 Node 스크립트 추가; 파일/오류 검사 및 로그 포함
런타임 Icon 컴포넌트
src/components/Icon/Icon.tsx
Icon 컴포넌트 추가: IconProps 사용, sizeMap로 픽셀 크기 계산, iconMap에서 컴포넌트 조회 후 렌더링(없으면 null)
타입 정의
src/components/Icon/Icon.types.ts
IconName, IconSize, IconProps 등 타입 추가 (iconMap/sizeMap의 키를 기반으로 한 타입)
자동 생성된 맵
src/components/Icon/iconMap.ts
자동 생성 파일로 sizeMap(xs..xl = 12/16/20/24/32) 및 iconMap(아이콘명→컴포넌트) 내보냄; 파일은 생성 경고 헤더 포함

Sequence Diagram(s)

sequenceDiagram
  participant Dev as 개발자
  participant SVGR as `@svgr/cli`
  participant FS as 파일시스템
  participant GenScript as scripts/generate-iconMap.js
  participant App as 애플리케이션

  Dev->>SVGR: SVG 파일 빌드 요청 (build:icons)
  SVGR->>FS: `src/components/Icon/generated/*` TSX 아이콘 생성
  Dev->>GenScript: gen:iconMap 실행
  GenScript->>FS: generated 디렉토리 스캔
  GenScript->>FS: `src/components/Icon/iconMap.ts` (헤더, sizeMap, iconMap) 생성/저장
  App->>FS: 런타임에서 `iconMap`/`sizeMap` 임포트
  App->>App: `Icon(name,size)` → `iconMap[name]` 조회 후 렌더링
  Note over GenScript,App: 빌드 타임(생성)과 런타임(사용) 흐름 분리
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • feat: Icon 컴포넌트 구현 #6 — 동일한 아이콘 관련 파일들(.svgrrc.json, package.json 스크립트, scripts/generate-iconMap.js, src/components/Icon/*)을 수정하여 아이콘 생성/매핑 도입과 직접적인 코드 레벨 연관이 있음.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 풀 리퀘스트 제목이 변경 사항의 주요 내용을 명확하게 반영하고 있습니다. Icon 컴포넌트 구현이 이 풀 리퀘스트의 핵심 목표이며, 제목에서 이를 명확히 표현하고 있습니다.

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fcde0fd and 8a1cfcd.

📒 Files selected for processing (4)
  • package.json
  • scripts/generate-iconMap.js
  • src/components/Icon/Icon.tsx
  • src/components/Icon/iconMap.ts

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

Copy link
Copy Markdown

@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 (4)
package.json (1)

17-17: 불필요한 --experimental-modules 플래그

package.json"type": "module"이 설정되어 있어 Node.js가 기본적으로 ES 모듈을 지원합니다. 해당 플래그는 제거해도 무방합니다.

🔎 수정 제안
-    "gen:iconMap": "node --experimental-modules ./scripts/generate-iconMap.js",
+    "gen:iconMap": "node ./scripts/generate-iconMap.js",
src/components/Icon/iconMap.ts (1)

4-4: import 경로에서 .tsx 확장자 제거 권장

TypeScript/번들러 설정에 따라 .tsx 확장자를 명시하면 문제가 발생할 수 있습니다. 이 파일은 자동 생성되므로 scripts/generate-iconMap.js에서 수정이 필요합니다.

-import * as Icon from './generated/index.tsx';
+import * as Icon from './generated/index';

위 변경은 generate-iconMap.js Line 24에서 적용해야 합니다.

scripts/generate-iconMap.js (1)

24-24: import 경로에서 .tsx 확장자 제거

일부 번들러나 TypeScript 설정에서 확장자를 명시하면 모듈 해석 문제가 발생할 수 있습니다.

🔎 수정 제안
-  const importLines = `import * as Icon from './generated/index.tsx'`;
+  const importLines = `import * as Icon from './generated/index'`;
src/components/Icon/Icon.tsx (1)

14-14: color 기본값이 currentColor 상속을 방해할 수 있음

SVGR 설정에서 fill: "currentColor"를 사용하여 CSS color 속성 상속을 활성화했습니다. 그러나 여기서 color ?? '#000'으로 항상 색상을 지정하면 부모 요소의 색상 상속이 무시됩니다.

색상이 명시적으로 전달된 경우에만 스타일을 적용하는 것이 좋습니다:

🔎 수정 제안
  return (
    <IconComponent
      width={pixelSize}
      height={pixelSize}
-     style={{ color: color ?? '#000' }}
+     style={color ? { color } : undefined}
      {...rest}
    />
  );

이렇게 하면 color prop이 없을 때 CSS color 속성이나 부모 요소의 색상을 자연스럽게 상속받습니다.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 362ab4c and 2d22c59.

⛔ Files ignored due to path filters (14)
  • package-lock.json is excluded by !**/package-lock.json
  • src/assets/icons/add-line.svg is excluded by !**/*.svg
  • src/assets/icons/bookmark.svg is excluded by !**/*.svg
  • src/assets/icons/circuit.svg is excluded by !**/*.svg
  • src/assets/icons/copy.svg is excluded by !**/*.svg
  • src/assets/icons/link.svg is excluded by !**/*.svg
  • src/assets/icons/logo.svg is excluded by !**/*.svg
  • src/components/Icon/generated/AddLine.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/Bookmark.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/Circuit.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/Copy.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/Link.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/Logo.tsx is excluded by !**/generated/**
  • src/components/Icon/generated/index.tsx is excluded by !**/generated/**
📒 Files selected for processing (6)
  • .svgrrc.json
  • package.json
  • scripts/generate-iconMap.js
  • src/components/Icon/Icon.tsx
  • src/components/Icon/Icon.types.ts
  • src/components/Icon/iconMap.ts
🧰 Additional context used
🧬 Code graph analysis (3)
src/components/Icon/Icon.types.ts (1)
src/components/Icon/iconMap.ts (2)
  • iconMap (14-21)
  • sizeMap (6-12)
src/components/Icon/Icon.tsx (2)
src/components/Icon/Icon.types.ts (1)
  • IconProps (12-12)
src/components/Icon/iconMap.ts (2)
  • sizeMap (6-12)
  • iconMap (14-21)
src/components/Icon/iconMap.ts (1)
src/components/Icon/Icon.tsx (1)
  • Icon (4-18)
🔇 Additional comments (2)
.svgrrc.json (1)

1-10: LGTM!

SVGR 설정이 잘 구성되어 있습니다. fill: "currentColor"로 CSS 색상 상속을 지원하고, jsxRuntime: "automatic"으로 React 19와 호환됩니다.

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

4-8: LGTM!

컴포넌트 구조가 깔끔합니다. size 기본값 설정과 IconComponent 존재 여부 확인이 잘 되어 있습니다.

Comment thread package.json Outdated
Comment thread scripts/generate-iconMap.js
Comment thread scripts/generate-iconMap.js Outdated
await fs.mkdir(path.dirname(OUTPUT_FILE), { recursive: true });
await fs.writeFile(OUTPUT_FILE, fileContent, 'utf8');

console.log(`iconMap이 정상적으로 생성되었습니다. total: ${tsxFiles.length}개`);
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

아이콘 개수 로그가 실제 생성 개수와 다를 수 있음

tsxFiles.lengthindex.tsx를 포함하지만 실제 iconMap에는 제외됩니다. 정확한 개수를 표시하려면 필터링 후 개수를 사용하세요.

🔎 수정 제안
+  const iconFiles = tsxFiles.filter((file) => file.replace(/\.tsx$/, '') !== 'index');
+
   const iconEntries = iconFiles
     .map((file) => {
       // ...
     })
     .join('\n');
   
   // ...
   
-  console.log(`iconMap이 정상적으로 생성되었습니다. total: ${tsxFiles.length}개`);
+  console.log(`iconMap이 정상적으로 생성되었습니다. total: ${iconFiles.length}개`);
🤖 Prompt for AI Agents
In scripts/generate-iconMap.js around line 59, the console.log uses
tsxFiles.length which counts files like index.tsx that are later excluded from
the generated iconMap; update the log to use the length of the filtered array
used to build iconMap (i.e., compute/filter the files exactly as you do when
creating the map and log that filteredArray.length) so the printed total matches
the actual icons generated.

Comment thread src/components/Icon/Icon.types.ts
@ccconac ccconac merged commit 1106a68 into dev Dec 28, 2025
1 check was pending
@ccconac ccconac linked an issue Dec 28, 2025 that may be closed by this pull request
1 task
@ccconac ccconac deleted the feat/4-icon-component branch December 28, 2025 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 CHORE 환경 설정 관련 💄 DESIGN UI 구현 ✨ FEAT 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Icon 컴포넌트 구현

1 participant