-
Notifications
You must be signed in to change notification settings - Fork 4
Feat/component/tech stack/DEVING-41 #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/component/tech stack/DEVING-41 #22
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Walkthrough이번 변경 사항에서는 새로운 UI 기능 구현을 위한 여러 React 컴포넌트와 유틸리티 함수들이 도입되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant TS as TechStackPage
participant IR as IconRegistry
participant GP as getPath
participant BI as BaseIcon
TS->>IR: 요청 - 아이콘 컴포넌트 생성
IR->>GP: SVG 문자열에서 경로 추출
GP-->>IR: 추출된 SVG 경로 데이터
IR->>BI: BaseIcon 생성 (속성 전달)
BI-->>IR: 렌더링된 아이콘 반환
IR-->>TS: 구성된 아이콘 컴포넌트 반환
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov ReportAll modified and coverable lines are covered by tests ✅ |
CI Status Report검사 결과
✅ 모든 검사가 통과되었습니다. |
CI Status Report검사 결과
✅ 모든 검사가 통과되었습니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (7)
src/components/ui/Icon/getPath.ts (1)
1-4: SVG 경로 추출 로직 개선이 필요합니다.현재 구현은 기본적인 SVG 경로 추출만 지원합니다. 다음과 같은 개선사항을 고려해주세요:
- 여러 path 요소가 있는 경우 처리
- 잘못된 SVG 문자열에 대한 오류 처리
- 다양한 SVG 포맷 지원
export default function getPath(svgString: string): string { + if (!svgString) return ''; + try { + const paths = svgString.match(/d="([^"]+)"/g); + if (!paths) return ''; + return paths.map(p => p.match(/d="([^"]+)"/)[1]).join(' '); + } catch (error) { + console.error('SVG 경로 추출 중 오류 발생:', error); + return ''; + } - const pathMatch = svgString.match(/d="([^"]+)"/); - return pathMatch ? pathMatch[1] : ''; }src/components/ui/Icon/BaseIcon.tsx (1)
26-39: SVG 최적화 속성을 추가해주세요.SVG 렌더링 성능 향상을 위한 추가 속성이 필요합니다.
return ( <svg role="img" + aria-label={ariaLabel} width={size} height={size} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill={color} className={cn(radiusMap[radius], className)} preserveAspectRatio="xMidYMid meet" + focusable="false" > + {title && <title>{title}</title>} <path d={path} /> </svg> );src/components/ui/Icon/iconRegistry.ts (2)
8-16: 컴포넌트 생성 성능 최적화가 필요합니다.
createIconComponent함수의 결과를 메모이제이션하여 불필요한 재생성을 방지할 수 있습니다.+const iconComponentCache = new Map<string, (props: IconProps) => JSX.Element>(); + function createIconComponent(config: IconConfig) { + const cacheKey = `${config.category}-${config.name}`; + if (iconComponentCache.has(cacheKey)) { + return iconComponentCache.get(cacheKey)!; + } + return function Icon(props: IconProps) { return createElement(BaseIcon, { ...props, color: props.color ?? config.color, path: config.path, }); }; }
19-31: 타입 안전성 개선이 필요합니다.카테고리와 컴포넌트 이름에 대한 타입 안전성을 강화할 수 있습니다.
+type IconCategory = 'frontend' | 'backend' | 'design'; +type IconName = IconConfig['name']; + export const Icons = ICON_LIST.reduce< - Record<string, Record<string, (props: IconProps) => JSX.Element>> + Record<IconCategory, Record<`${IconName}Icon`, (props: IconProps) => JSX.Element>> >((acc, config) => { const category = config.category; const componentName = `${config.name}Icon`;src/app/preview/tech-stack/page.tsx (1)
6-104: 섹션 컴포넌트를 분리해주세요.기술 스택 섹션들이 반복되는 구조를 가지고 있습니다. 재사용 가능한 컴포넌트로 분리하면 코드 유지보수가 용이해질 것 같습니다.
+interface TechSectionProps { + title: string; + categories: { + title: string; + icons: Array<{ Icon: typeof frontend[keyof typeof frontend]; className?: string }>; + }[]; +} + +const TechSection = ({ title, categories }: TechSectionProps) => ( + <section> + <h2 className="mb-6 text-2xl font-bold">{title}</h2> + {categories.map((category, index) => ( + <div key={index} className="mb-8"> + <h3 className="mb-4 text-lg font-semibold">{category.title}</h3> + <div className="flex flex-wrap gap-4"> + {category.icons.map(({ Icon, className }, iconIndex) => ( + <TechIcon key={iconIndex} icon={Icon} className={className} /> + ))} + </div> + </div> + ))} + </section> +);src/components/ui/Icon/IconData.ts (2)
3-8: 인터페이스 정의가 잘 구조화되어 있습니다.타입스크립트 모범 사례를 잘 따르고 있으며, 카테고리 타입이 유니온 타입으로 적절하게 제한되어 있습니다.
카테고리를 별도의 enum으로 추출하는 것을 고려해보세요.
카테고리 값의 재사용성과 유지보수성을 높이기 위해 다음과 같이 enum으로 분리하는 것을 제안합니다:
+export enum IconCategory { + Frontend = 'frontend', + Backend = 'backend', + Design = 'design' +} export interface IconConfig { name: string; color: string; path: string; - category: 'frontend' | 'backend' | 'design'; + category: IconCategory; }
10-268: 아이콘 목록이 잘 구성되어 있습니다.각 아이콘 항목이 일관된 구조를 따르고 있으며, SVG 경로와 색상 코드가 올바르게 포맷되어 있습니다.
코드 가독성 향상을 위한 제안사항:
- JSDoc 주석 추가
- 카테고리별 아이콘 그룹화
+/** + * 기술 스택 아이콘 목록 + * @type {IconConfig[]} + */ export const ICON_LIST: IconConfig[] = [ + // Frontend { name: 'Javascript', // ... }, + // Backend { name: 'Spring', // ... }, + // Design { name: 'Figma', // ... }, ];색상 코드 유효성 검사 추가를 고려해보세요.
색상 코드의 유효성을 보장하기 위해 유틸리티 함수를 추가하는 것을 제안합니다:
const isValidHexColor = (color: string): boolean => { return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/app/preview/tech-stack/page.tsx(1 hunks)src/components/ui/Icon/BaseIcon.tsx(1 hunks)src/components/ui/Icon/IconData.ts(1 hunks)src/components/ui/Icon/getPath.ts(1 hunks)src/components/ui/Icon/iconRegistry.ts(1 hunks)
| export interface BaseIconProps { | ||
| color?: string; | ||
| size?: number; | ||
| radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'; | ||
| className?: string; | ||
| path: string; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
접근성 관련 속성을 추가해주세요.
아이콘의 접근성을 향상시키기 위해 aria-label과 title 속성을 추가하는 것이 좋습니다.
export interface BaseIconProps {
color?: string;
size?: number;
radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
className?: string;
path: string;
+ title?: string;
+ ariaLabel?: string;
}📝 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.
| export interface BaseIconProps { | |
| color?: string; | |
| size?: number; | |
| radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'; | |
| className?: string; | |
| path: string; | |
| } | |
| export interface BaseIconProps { | |
| color?: string; | |
| size?: number; | |
| radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'; | |
| className?: string; | |
| path: string; | |
| title?: string; | |
| ariaLabel?: string; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아이콘의 접근성을 향상시키면 어떤 이점을 얻을 수 있어?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
@clyde-yoonjae 아이콘 접근성 향상은 다음과 같은 중요한 이점이 있습니다:
- 스크린 리더 지원: 시각 장애가 있는 사용자들이 스크린 리더를 통해 아이콘의 의미를 이해할 수 있습니다.
- 사용자 경험 개선: 모든 사용자가 마우스 호버 시 툴팁을 통해 아이콘의 목적을 명확히 알 수 있습니다.
- SEO 최적화: 검색 엔진이 콘텐츠의 의미를 더 잘 이해할 수 있어 검색 순위가 개선될 수 있습니다.
- 법적 준수: 많은 국가의 웹 접근성 법규를 준수하는 데 도움이 됩니다.
🌐 Web query:
What are the benefits of making icons accessible with aria-label and title attributes?
💡 Result:
Using aria-label and title attributes enhances accessibility for icons by bridging gaps between visual and non-visual user experiences. Below are their key benefits:
Benefits of aria-label
-
Provides Screen Reader Context:
When icons lack visible text (e.g., a button with only an SVG),aria-labelsupplies an accessible name for assistive technologies[1][3][7]. For example:<button aria-label="Close"><svg>...</svg></button>
Screen readers announce "Close" instead of "Button" or generic descriptions[1][9].
-
Overrides Ambiguous Default Names:
If an icon’s default name (e.g.,alttext) is unclear or missing,aria-labelensures clarity[1][5][7]. -
Prioritizes Accessibility Over Redundant Text:
Unlike visible labels oraltattributes,aria-labeltakes precedence in defining the accessible name[1][5]. -
Works Across Interactive Elements:
Supported on buttons, links, form controls, and landmarks[1][5], making it ideal for icon-based actions like "Search" or "Menu"[3][7].
Benefits of title Attribute
-
Adds Tooltips for Mouse Users:
Displays a hoverable description (e.g., explaining an icon’s purpose)[2][5]. -
Supplements Visible Labels:
Useful for non-critical advisory text (e.g., clarifying a link’s destination)[2][5].
Key Considerations
-
aria-labelvs.title:- Use
aria-labelwhen no visible label exists[1][5]. - Use
titlefor supplementary tooltips[2][5].
- Use
-
Avoid Redundancy:
- Do not combine
aria-labelwith visible labels oralttext unless necessary[7][9].
- Do not combine
-
Limitations of
title:- Not exposed to keyboard-only users or consistently read by screen readers[2][5].
Example Implementation
<!-- Using both attributes: -->
<button
aria-label="Email"
title="Send email"
>
<svg>...</svg>
</button>- Screen readers announce "Email"[3][9], while mouse users see "Send email"[2][5].
In summary, aria-label ensures accessibility for assistive technologies by labeling untexted icons, while title enhances usability via tooltips—though its impact is limited compared to ARIA solutions[1][2][5].
Citations:
- 1: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label
- 2: https://www.deque.com/blog/text-links-practices-screen-readers/
- 3: https://humanwhocodes.com/blog/2013/04/01/making-accessible-icon-buttons/
- 4: Accessibility: instead of label on button with icon try title on icon vmware-archive/clarity#5806
- 5: https://www.aditus.io/aria/aria-label/
- 6: https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/
- 7: https://www.a11y-collective.com/blog/aria-labels/
- 8: Set default `aria-label` or add `<title>` to SVG for accessibility lucide-icons/lucide#2121
- 9: https://sarasoueidan.com/blog/accessible-icon-buttons/
- 10: https://a11y.email/basics-aria-label-or-alt/
@clyde-yoonjae 아이콘 접근성 향상의 구체적인 이점을 설명드리겠습니다:
-
스크린 리더 사용성
aria-label을 통해 시각 장애인들이 아이콘의 정확한 목적을 이해할 수 있습니다- 스크린 리더가 "버튼" 대신 "닫기 버튼"과 같이 명확한 의미를 전달합니다
-
시각적 사용자 경험
title속성으로 마우스 호버 시 툴팁이 표시되어 아이콘의 기능을 직관적으로 이해할 수 있습니다- 새로운 사용자나 아이콘의 의미가 모호할 수 있는 상황에서 특히 유용합니다
-
웹 표준 준수
- WCAG(웹 콘텐츠 접근성 지침) 준수를 통해 더 많은 사용자가 서비스를 이용할 수 있습니다
- 향후 접근성 관련 법적 요구사항에 선제적으로 대응할 수 있습니다
-
검색엔진 최적화(SEO)
- 검색 엔진이 아이콘의 의미를 정확히 파악할 수 있어 콘텐츠 색인이 개선됩니다
- 전반적인 웹사이트의 접근성 점수가 향상됩니다
✏️ Learnings added
Learnt from: clyde-yoonjae
PR: MoimService/Moim-FE#22
File: src/components/ui/Icon/BaseIcon.tsx:3-9
Timestamp: 2025-02-21T05:01:45.380Z
Learning: Icon components should include accessibility attributes (aria-label, title) to support screen readers, improve user experience, enhance SEO, and comply with accessibility regulations. The aria-label is used for screen readers, while title provides tooltips for sighted users.
Learnt from: clyde-yoonjae
PR: MoimService/Moim-FE#22
File: src/components/ui/Icon/BaseIcon.tsx:3-9
Timestamp: 2025-02-21T05:01:45.380Z
Learning: Icon accessibility should be implemented with both aria-label and title attributes for comprehensive coverage:
- aria-label: Provides essential context for screen readers, taking precedence over other accessible names
- title: Offers supplementary tooltips for sighted users on hover
These attributes serve different purposes and user groups, with aria-label being crucial for assistive technologies while title enhances visual user experience. Implementation should avoid redundancy between visible labels and aria-labels.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ariaLable과 title에 대해 설명해줘. 그리고 title은 어디에쓰여
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@clyde-yoonjae ariaLabel과 title의 주요 차이점과 용도를 설명드리겠습니다:
ariaLabel
- 스크린 리더와 같은 보조 기술을 위한 속성입니다
- 시각적으로 보이지 않지만, 스크린 리더가 읽어주는 텍스트를 지정합니다
- 예:
ariaLabel="메뉴 닫기"→ 스크린 리더가 "메뉴 닫기" 버튼이라고 읽어줍니다
title
- 마우스를 올렸을 때 나타나는 툴팁 텍스트를 지정합니다
- 주로 다음과 같은 상황에서 사용됩니다:
- 아이콘의 기능 설명 (예:
title="새 창에서 열기") - 추가 정보 제공 (예:
title="파일 크기: 2MB") - 긴 텍스트의 전체 내용 표시 (예: 말줄임표로 잘린 텍스트)
- 아이콘의 기능 설명 (예:
✏️ Learnings added
Learnt from: clyde-yoonjae
PR: MoimService/Moim-FE#22
File: src/components/ui/Icon/BaseIcon.tsx:3-9
Timestamp: 2025-02-21T05:43:52.418Z
Learning: In React components, title attribute is commonly used for providing tooltip text that appears on hover, particularly useful for:
1. Explaining icon functionality
2. Showing additional information
3. Displaying full text of truncated content
The title attribute serves visual users, unlike ariaLabel which is for screen readers.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수정했어 확인해줘
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
@clyde-yoonjae 변경사항을 확인하기 위해 파일 내용을 확인하고 있습니다. 잠시만 기다려주세요.
(_/)
(„• ֊ •„)
╭━━━━━━━━━╮
╰━━━━━━━━━╯
🏁 Script executed:
#!/bin/bash
cat src/components/ui/Icon/BaseIcon.tsx
Length of output: 918
@clyde-yoonjae 변경사항이 정확하게 구현되었네요! 👍
ariaLabel과titleprops가 올바르게 추가되었습니다- SVG에서
aria-label과title태그가 적절하게 사용되었습니다 role="img"도 추가되어 있어 접근성이 더욱 향상되었습니다
완벽하게 구현해주셨습니다!
(\ /)
(„• ᴗ •„)
| |
| |
| <div className="flex flex-wrap gap-4"> | ||
| <frontend.JavascriptIcon size={24} radius="lg" /> | ||
| <frontend.TypescriptIcon size={24} radius="lg" /> | ||
| <frontend.ReactIcon size={24} radius="lg" /> | ||
| <frontend.VueIcon size={24} radius="lg" /> | ||
| </div> | ||
| <div className="flex flex-wrap gap-4"> | ||
| <frontend.JavascriptIcon size={12} radius="lg" /> | ||
| <frontend.TypescriptIcon size={12} radius="lg" /> | ||
| <frontend.ReactIcon size={12} radius="lg" /> | ||
| <frontend.VueIcon size={12} radius="lg" /> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
아이콘 크기 중복 코드를 제거해주세요.
동일한 아이콘이 다른 크기로 반복되어 있습니다. 컴포넌트로 분리하여 재사용성을 높일 수 있습니다.
+const TechIcon = ({ icon: Icon, size = 24 }) => (
+ <Icon size={size} radius="lg" />
+);
+
<div className="flex flex-wrap gap-4">
- <frontend.JavascriptIcon size={24} radius="lg" />
- <frontend.TypescriptIcon size={24} radius="lg" />
- <frontend.ReactIcon size={24} radius="lg" />
- <frontend.VueIcon size={24} radius="lg" />
+ <TechIcon icon={frontend.JavascriptIcon} />
+ <TechIcon icon={frontend.TypescriptIcon} />
+ <TechIcon icon={frontend.ReactIcon} />
+ <TechIcon icon={frontend.VueIcon} />
</div>📝 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.
| <div className="flex flex-wrap gap-4"> | |
| <frontend.JavascriptIcon size={24} radius="lg" /> | |
| <frontend.TypescriptIcon size={24} radius="lg" /> | |
| <frontend.ReactIcon size={24} radius="lg" /> | |
| <frontend.VueIcon size={24} radius="lg" /> | |
| </div> | |
| <div className="flex flex-wrap gap-4"> | |
| <frontend.JavascriptIcon size={12} radius="lg" /> | |
| <frontend.TypescriptIcon size={12} radius="lg" /> | |
| <frontend.ReactIcon size={12} radius="lg" /> | |
| <frontend.VueIcon size={12} radius="lg" /> | |
| </div> | |
| const TechIcon = ({ icon: Icon, size = 24 }) => ( | |
| <Icon size={size} radius="lg" /> | |
| ); | |
| <div className="flex flex-wrap gap-4"> | |
| <TechIcon icon={frontend.JavascriptIcon} /> | |
| <TechIcon icon={frontend.TypescriptIcon} /> | |
| <TechIcon icon={frontend.ReactIcon} /> | |
| <TechIcon icon={frontend.VueIcon} /> | |
| </div> | |
| <div className="flex flex-wrap gap-4"> | |
| <frontend.JavascriptIcon size={12} radius="lg" /> | |
| <frontend.TypescriptIcon size={12} radius="lg" /> | |
| <frontend.ReactIcon size={12} radius="lg" /> | |
| <frontend.VueIcon size={12} radius="lg" /> | |
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
예시 페이지기때문에 무시해줘
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@clyde-yoonjae 알겠습니다. 예시 페이지에 대한 리뷰 의견을 철회하겠습니다.
✏️ Learnings added
Learnt from: clyde-yoonjae
PR: MoimService/Moim-FE#22
File: src/app/preview/tech-stack/page.tsx:14-25
Timestamp: 2025-02-21T05:01:06.124Z
Learning: Code in preview/example pages (e.g., paths containing "preview") can have relaxed code quality standards as they serve demonstration purposes rather than production code.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Lee-Dong-Seok
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니다!!👍👍👍👍
CI Status Report검사 결과
✅ 모든 검사가 통과되었습니다. |
dbswl701
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
svg 이렇게까지 관리할 수 있을지 몰랐네용 배워갑니다!
Lee-Dong-Seok
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍👍👍👍👍👍👍
lee1nna
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다 !! 👍
📝 주요 작업 내용
아이콘 컴포넌트 생성
📺 스크린샷
/preview/tech-stack
🔗 참고 사항
처음엔, assets하위에 하나하나 전부 넣었으나, 디자인이 언제 변경될지 모르고, 크기나 색상등 자유로운 변경을 위해 어떻게 관리할까 고민한 결과입니다. 저도 처음본 패턴이기에 공유하기위하여 작성합니다.
설명에 앞서 ui폴더 하위에 Icon을 생성하여
로 분류하였습니다.
1. BaseIcon.tsx
BaseIcon 컴포넌트는 모든 SVG 아이콘의 기본 템플릿 역할을 하는 핵심 컴포넌트입니다. IconRegistry.ts에서 각각의 아이콘을 생성할 때 이 BaseIcon을 기반으로 만듭니다.
2. getPath.ts
https://simpleicons.org/
해당 링크(무료 svg를 제공해주는 사이트)에서 svg를 가져와, path를 분리해주는 유틸 함수입니다. Icon에만 존속되기 때문에 따로 분류는 하지않았습니다.
3. iconData.ts
모든 기술스택들의 리스트 배열입니다.
4. IconRegistry.ts
리스트와 BaseIcon.tsx을 토대로 새로운 컴포넌트를 만들어내는 함수입니다.
Omit은 특정 타입에서 원하는 키를 제거하는 타입입니다. 따라 기존 BaseIconProps에서 path타입을 제거한 새로운 IconProps 타입을 먼저 생성합니다.
그리고 위의 함수를 통해 아이콘 컴포넌트 생성함수를 작성합니다.
return문에 쓰인 createElement 메소드 : https://ko.react.dev/reference/react/createElement
그리고 하위 카테고리별 컴포넌트 생성
Record<K, T>
Record타입은 키가 K타입이고, 값이 T타입인 객체 타입을 정의하는 방법입니다.
따라
는
다음과 같이 해석됩니다.
다음으론
Reduce 메서드 분석입니다.
먼저 reduce메서드는 배열의 여러개의 값을 하나의 값으로 축소해주는 배열메서드 입니다.
첫번째 인수 자리에 콜백함수가 들어오고 두번째 인수자리에는 초기값이 들어옵니다. 즉, 자신을 호출한 배열의 모든 요소를 순회하며 인수로 전달받은 콜백함수를 반복호출합니다.(이때 원본 배열은 변경되지 않습니다.)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce - mdn글입니다
첫번째 파라미터인 acc는 이전 반복에서 return한 값이 다음 반복의 acc가 됩니다. 초기값은 빈 객체인 {} 형태입니다.
두 번 파라미터인 config는 현재요소로 ICON_LIST 배열의 현재 처리중인 아이템입니다.
이렇게 acc는 계속 누적되면서 최종 결과물을 만들고, config는 ICON_LIST의 각 아이템을 순차적으로 처리하는 역할을 합니다.
그리고
이 부분은 카테고리 체크 및 초기화의 역할로 해당 카테고리가 없을 때 빈 객체를 생성합니다.
다음과 같이 수행됩니다.
그리고 생성된 카테고리 객체에 새로운 아이콘 컴포넌트를 추가하게 됩니다.
전체 과정 예시입니다.
++) 추가로 학습한 부분
SVG의 <title> 태그는 HTML의 title 속성과는 다르게 동작합니다.
HTML의 title 속성
SVG의 title 태그
HTML의 <title> 태그
💬 리뷰 요구사항
ex) 중점적으로 리뷰해줬으면 하는 부분
📃 관련 이슈
DEVING-41
Summary by CodeRabbit