generated from gc/template-java-maven
- 디자인 시스템 가이드 문서 11개 생성 (docs/design/) - CSS 변수 토큰 시스템 (@theme + :root/.dark 전환) - cn() 유틸리티 (clsx + tailwind-merge) - Button/Badge 공통 컴포넌트 (variant/size, 다크모드 대응) - 하드코딩 Tailwind 색상 → CSS 변수 토큰 리팩토링 (30개 파일) - 차트 팔레트 다크모드 색상 업데이트 (CHART_COLORS_HEX) - 버튼 다크모드 채도/대비 강화 (primary-600 기반) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.7 KiB
4.7 KiB
Do & Don't
디자인 시스템 적용 시 자주 발생하는 실수와 올바른 방법.
CSS 변수 토큰
색상
DO — CSS 변수 토큰 사용
<div className="bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] border border-[var(--color-border)]" />
DON'T — HEX 하드코딩
// 다크 모드 전환 불가, 토큰 변경 시 전부 수정 필요
<div className="bg-white text-gray-900 border border-gray-200" />
DON'T — Tailwind 기본 팔레트로 브랜드 컬러 표현
// 브랜드 컬러(#6D94C5)와 blue-500(#3B82F6)은 다른 색상
<div className="bg-blue-500 text-blue-900" />
시멘틱 컬러
DO — 의미에 맞는 시멘틱 컬러 사용
// 성공 상태
<Badge className="bg-[var(--color-success)]/10 text-[var(--color-success)]">완료</Badge>
// 오류 메시지
<p className="text-[var(--color-danger)] text-sm">{errorMessage}</p>
// 경고 알림
<div className="border-l-4 border-[var(--color-warning)] bg-[var(--color-warning)]/10 p-4" />
DON'T — 브랜드 컬러를 시멘틱 용도로 사용
// Primary 컬러는 성공/오류를 표현하지 않음
<p className="text-[var(--color-primary)]">저장에 실패했습니다</p>
DON'T — 시멘틱 컬러를 장식 목적으로 사용
// danger 컬러는 위험/오류 상황 전용
<Badge className="bg-[var(--color-danger)]">인기</Badge>
Spacing 스케일
DO — 4px 단위 스케일 사용
<div className="p-4 gap-2 mt-6" /> // 16px / 8px / 24px
<div className="px-3 py-1.5" /> // 12px / 6px (sm 버튼)
DON'T — 임의의 px 값
<div className="p-[13px] gap-[7px] mt-[22px]" />
DON'T — 인라인 스타일로 여백 지정
<div style={{ padding: '13px', marginTop: '22px' }} />
cn() 유틸리티
DO — 조건부 클래스에 cn() 사용
<button
className={cn(
'px-4 py-2 rounded-lg font-medium transition-colors',
isActive ? 'bg-[var(--color-primary)] text-white' : 'text-[var(--color-text-secondary)]',
disabled && 'opacity-50 cursor-not-allowed',
className,
)}
/>
DON'T — 템플릿 리터럴로 조건부 클래스 조합
// Tailwind 클래스 충돌 가능, purge 미적용 위험
<button className={`px-4 py-2 ${isActive ? 'bg-blue-500' : ''} ${disabled ? 'opacity-50' : ''}`} />
DON'T — 동적 클래스 문자열 조합
// Tailwind는 전체 클래스 문자열을 스캔 — 동적 조합 시 purge에서 제거될 수 있음
const color = 'primary';
<div className={`text-[var(--color-${color})]`} /> // 위험
DO — 객체 맵 사용
const colorMap = {
primary: 'text-[var(--color-primary)]',
danger: 'text-[var(--color-danger)]',
} as const;
<div className={cn(colorMap[color])} />
컴포넌트 Props
DO — className prop 허용 + cn() 병합
const Card = ({ className, children }: CardProps) => (
<div className={cn('rounded-xl border border-[var(--color-border)] p-6', className)}>
{children}
</div>
);
DON'T — className prop 미제공 (재사용성 저하)
const Card = ({ children }: { children: React.ReactNode }) => (
<div className="rounded-xl border border-[var(--color-border)] p-6">
{children}
</div>
);
다크 모드
DO — CSS 변수 토큰 사용으로 자동 전환
// --color-bg-surface는 Light: #FFF, Dark: #1E2023으로 자동 전환
<div className="bg-[var(--color-bg-surface)]" />
DON'T — dark: 클래스로 각각 지정 (토큰이 있는 색상에)
// 중복 관리 부담, 토큰과 불일치 가능
<div className="bg-white dark:bg-gray-900" />
단, CSS 변수 토큰이 없는 케이스(투명도, 그라디언트 등)에는 dark: 사용 허용.
타이포그래피
DO — 타입 스케일 클래스 사용
<h1 className="text-4xl font-bold leading-tight text-[var(--color-text-primary)]">페이지 제목</h1>
<p className="text-base leading-relaxed text-[var(--color-text-secondary)]">설명 텍스트</p>
DON'T — 임의 폰트 크기
<h1 className="text-[22px] font-bold">페이지 제목</h1>
아이콘
DO — Lucide React + 색상 토큰
import { ChevronRight } from 'lucide-react';
<ChevronRight className="size-5 text-[var(--color-text-secondary)]" aria-hidden="true" />
DON'T — 다른 라이브러리 혼용
// Font Awesome, Material Icons 등 혼용 금지
import { FaChevronRight } from 'react-icons/fa';
DON'T — 아이콘에 color prop으로 HEX 지정
<ChevronRight color="#6D94C5" /> // CSS 변수 토큰을 사용할 수 없음