Conversation
Summary of ChangesHello @dasosann, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 PR은 프로젝트의 디자인 토큰 관리 시스템을 개선하는 데 중점을 둡니다. 기존의 정적 JSON 파일 사용 방식에서 벗어나, 스크립트를 통해 CSS 변수와 유틸리티 클래스를 동적으로 생성하는 방식으로 전환하여 디자인 일관성과 개발 효율성을 높였습니다. 새로운 토큰 시스템의 적용을 시각적으로 검증할 수 있는 테스트 페이지도 함께 제공됩니다. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
/describe --pr_description.generate_title=true --pr_description.use_description_markers=false |
|
PR Description updated to latest commit (354fd18)
|
There was a problem hiding this comment.
File Walkthrough
Enhancement
| |||
Configuration changes
| |||
| Miscellaneous |
| if (colors.Pink) { | ||
| Object.entries(colors.Pink).forEach(([key, value]) => { | ||
| if (key.startsWith("color-pink-")) { | ||
| cssVariables.push(` --${sanitizeKey(key)}: ${value.$value};`); | ||
| } | ||
| }); | ||
| } | ||
| if (colors.Flame) { | ||
| Object.entries(colors.Flame).forEach(([key, value]) => { | ||
| if (key.startsWith("color-flame-")) { | ||
| cssVariables.push(` --${sanitizeKey(key)}: ${value.$value};`); | ||
| } | ||
| }); | ||
| } | ||
| if (colors.Orange) { | ||
| Object.entries(colors.Orange).forEach(([key, value]) => { | ||
| if (key.startsWith("color-orange-")) { | ||
| cssVariables.push(` --${sanitizeKey(key)}: ${value.$value};`); | ||
| } | ||
| }); | ||
| } |
There was a problem hiding this comment.
Pink, Flame, Orange 색상 토큰을 처리하는 로직이 중복되고 있습니다. 이는 새로운 색상 카테고리가 추가될 때마다 코드를 복사-붙여넣기 해야 하므로 유지보수성을 저해합니다. 이 부분을 배열과 반복문으로 리팩토링하여 코드 중복을 제거하고 확장성을 높이는 것을 권장합니다.
const colorCategories = ["Pink", "Flame", "Orange"];
colorCategories.forEach((category) => {
if (colors[category]) {
const prefix = `color-${category.toLowerCase()}-`;
Object.entries(colors[category]).forEach(([key, value]) => {
if (key.startsWith(prefix)) {
cssVariables.push(` --${sanitizeKey(key)}: ${value.$value};`);
}
});
}
});References
- 중복 코드를 발견하면 재사용 가능한 유틸리티나 로직으로 추출할 것을 제안해야 합니다. 현재 색상 카테고리(Pink, Flame, Orange)를 처리하는 로직이 거의 동일하게 반복되고 있어 이 규칙에 위배됩니다. (link)
| if (ref.startsWith("Colors.Pink.")) { | ||
| const key = ref.replace("Colors.Pink.", ""); | ||
| return `var(--${key})`; | ||
| } | ||
| if (ref.startsWith("Colors.Flame.")) { | ||
| const key = ref.replace("Colors.Flame.", ""); | ||
| return `var(--${key})`; | ||
| } | ||
| if (ref.startsWith("Colors.Orange.")) { | ||
| const key = ref.replace("Colors.Orange.", ""); | ||
| return `var(--${key})`; | ||
| } |
There was a problem hiding this comment.
resolveValue 함수 내에서 Colors.Pink, Colors.Flame, Colors.Orange 에 대한 참조를 처리하는 로직이 중복되어 있습니다. 이 또한 코드의 유지보수성을 낮추는 요인이 됩니다. 여러 if 문을 하나로 통합하여 더 간결하고 일반적인 방식으로 처리하도록 리팩토링하는 것이 좋습니다.
if (ref.startsWith("Colors.Pink.") || ref.startsWith("Colors.Flame.") || ref.startsWith("Colors.Orange.")) {
const key = ref.substring(ref.lastIndexOf('.') + 1);
return `var(--${sanitizeKey(key)})`;
}References
- 중복 코드를 발견하면 재사용 가능한 유틸리티나 로직으로 추출할 것을 제안해야 합니다.
resolveValue함수 내에서 여러 색상 카테고리에 대한 참조를 처리하는if블록들이 반복되고 있어 이 규칙에 위배됩니다. (link)
| <button className="btn-primary text-16-600 px-8 py-3 transition-opacity hover:opacity-90"> | ||
| Primary Button | ||
| </button> | ||
| <button className="btn-slate text-brand-black border-light text-16-600 rounded-2xl border px-8 py-3"> | ||
| Secondary Button | ||
| </button> | ||
| <button className="btn-disabled text-16-400 cursor-not-allowed px-8 py-3"> | ||
| Disabled Button | ||
| </button> |
There was a problem hiding this comment.
버튼 컴포넌트의 클래스명과 접근성에 몇 가지 개선점이 필요해 보입니다.
- 잘못된 클래스명:
btn-primary,btn-slate등의 클래스명이 사용되었지만,tokens.css에는bg-button-primary와 같이 배경색을 지정하는 유틸리티 클래스가 정의되어 있습니다. 이로 인해 버튼의 배경 스타일이 적용되지 않고 있습니다. - 스타일 누락: Primary 버튼의 경우, 배경 그래디언트가 적용되면 가독성을 위해
text-white클래스를 추가해야 합니다. 또한 다른 버튼들과의 일관성을 위해rounded-2xl을 추가하는 것이 좋습니다. - Disabled 버튼 접근성:
disabled속성 없이cursor-not-allowed클래스만 사용하면, 시각적으로는 비활성화된 것처럼 보이지만 스크린 리더 사용자에게는 여전히 클릭 가능한 버튼으로 인식됩니다. 웹 접근성을 준수하기 위해disabled속성을 명시적으로 추가해야 합니다.
| <button className="btn-primary text-16-600 px-8 py-3 transition-opacity hover:opacity-90"> | |
| Primary Button | |
| </button> | |
| <button className="btn-slate text-brand-black border-light text-16-600 rounded-2xl border px-8 py-3"> | |
| Secondary Button | |
| </button> | |
| <button className="btn-disabled text-16-400 cursor-not-allowed px-8 py-3"> | |
| Disabled Button | |
| </button> | |
| <button className="bg-button-primary text-white text-16-600 rounded-2xl px-8 py-3 transition-opacity hover:opacity-90"> | |
| Primary Button | |
| </button> | |
| <button className="bg-button-slate text-brand-black border-light text-16-600 rounded-2xl border px-8 py-3"> | |
| Secondary Button | |
| </button> | |
| <button className="bg-button-disabled text-disabled text-16-400 cursor-not-allowed rounded-2xl px-8 py-3" disabled> | |
| Disabled Button | |
| </button> |
References
- 아이콘 전용 버튼의
aria-label등 접근성(A11y) 관련 사항을 확인해야 합니다. 현재 비활성화 버튼이disabled속성 없이 스타일로만 처리되어 있어 스크린 리더 사용자가 이를 인지할 수 없으므로 접근성 표준에 위배됩니다. (link)
| const tokensPath = path.join(__dirname, "../app/token.json"); | ||
| const tokens = JSON.parse(fs.readFileSync(tokensPath, "utf-8")); |
There was a problem hiding this comment.
토큰 생성 스크립트는 현재 파일 시스템 작업이나 JSON 파싱에서 발생할 수 있는 오류를 처리하지 않습니다. 예를 들어 token.json 파일이 없거나 내용이 잘못된 경우 스크립트가 비정상적으로 종료됩니다. try...catch 블록을 사용하여 오류를 적절히 처리하고 사용자에게 명확한 에러 메시지를 보여주는 것이 스크립트의 안정성을 높이는 데 도움이 됩니다.
| const tokensPath = path.join(__dirname, "../app/token.json"); | |
| const tokens = JSON.parse(fs.readFileSync(tokensPath, "utf-8")); | |
| const tokensPath = path.join(__dirname, "../app/token.json"); | |
| let tokens; | |
| try { | |
| tokens = JSON.parse(fs.readFileSync(tokensPath, "utf-8")); | |
| } catch (error) { | |
| console.error(`❌ Error reading or parsing ${tokensPath}:`, error.message); | |
| process.exit(1); | |
| } |
| tailwindUtilities.push(`${className} { | ||
| font-size: ${size}px; | ||
| font-weight: ${weight}; | ||
| line-height: 1.5; | ||
| }`); |
User description
요약
🤖 Generated by PR Agent at 354fd18
token.json에서 CSS 변수로 변환하는generate-tokens.js스크립트 추가tokens.css를globals.css에 임포트하여 전역 스타일 적용구현 사항
generate-tokens.js
토큰 JSON을 CSS 변수로 변환하는 생성 스크립트scripts/generate-tokens.js
token.json에서 색상, 타이포그래피, 반경, 테두리, 불투명도 토큰 파싱tokens.css자동 생성text-{size}-{weight}형식 생성tokens.css
자동 생성된 CSS 변수 및 유틸리티 클래스app/tokens.css
text-{size}-{weight}제공globals.css
토큰 CSS 파일 임포트 추가app/globals.css
tokens.css임포트 추가로 생성된 토큰 전역 적용page.tsx
디자인 토큰 테스트 및 시각화 페이지app/page.tsx
settings.json
CSS 린트 설정 업데이트.vscode/settings.json
unknownAtRules무시 설정 추가@layer등 커스텀 CSS 규칙 경고 제거token.json
레거시 토큰 파일 제거app/src/token.json
Need Review
Reference
📜 리뷰 규칙
Reviewer는 아래 P5 Rule을 참고하여 리뷰를 진행합니다.
P5 Rule을 통해 Reviewer는 Reviewee에게 리뷰의 의도를 보다 정확히 전달할 수 있습니다.
PR Type
Enhancement
Description
디자인 토큰 자동 생성 스크립트로 토큰 관리 자동화
token.json을 CSS 변수로 변환하는generate-tokens.js스크립트 추가생성된
tokens.css를 전역 스타일에 통합하여 디자인 시스템 구축Diagram Walkthrough
File Walkthrough
generate-tokens.js
토큰 JSON을 CSS 변수로 변환하는 생성 스크립트scripts/generate-tokens.js
token.json에서 색상, 타이포그래피, 반경, 테두리, 불투명도 토큰 파싱tokens.css자동 생성text-{size}-{weight}형식의 타이포그래피 유틸리티 클래스 생성tokens.css
자동 생성된 CSS 변수 및 유틸리티 클래스app/tokens.css
text-{size}-{weight}타이포그래피 유틸리티 클래스 제공page.tsx
디자인 토큰 테스트 페이지로 변경app/page.tsx
globals.css
토큰 CSS 파일 임포트 추가app/globals.css
tokens.css파일 임포트 추가settings.json
CSS 린트 설정 추가.vscode/settings.json
css.lint.unknownAtRules설정@layer등 커스텀 CSS 규칙 경고 무시token.json
토큰 파일 위치 변경app/src/token.json
app/token.json)로 이동