디자인 투 코드 #2: 하나의 JSON, 열한 개 출력
Source: Dev.to
번역할 텍스트가 제공되지 않았습니다. 번역을 원하는 본문을 알려주시면 한국어로 번역해 드리겠습니다.
개요
전체 7onic 디자인 시스템은 1,847줄 길이의 단일 JSON 파일(figma‑tokens.json)에 기반합니다. 색상은 16진수 값(e.g., #6B21A8)으로, 간격은 일반 숫자(e.g., 16)로, 테두리 반경도 같은 형식으로, 애니메이션은 키프레임 객체로 저장합니다. 이 파일은 코드베이스에서 디자인 값이 존재할 수 있는 유일한 장소이며, 나머지는 모두 이 파일에서 생성됩니다.
단일 명령으로 해당 파일을 읽어 약 200 ms 안에 11개의 배포 파일을 생성합니다. 색상을 변경하고, 스크립트를 실행하고, 배포하면—이것이 전체 파이프라인입니다.
Generated Outputs
| Path | Description |
|---|---|
css/variables.css | 기본 CSS 변수 |
css/themes/light.css | 의미론적 라이트 테마 |
css/themes/dark.css | 의미론적 다크 테마 |
css/all.css | 번들된 CSS |
tailwind/v3-preset.js | Tailwind v3 프리셋 |
tailwind/v4-theme.css | Tailwind v4 테마 파일 |
tailwind/v4.css | Tailwind v4 CSS |
js/index.js | CommonJS 엔트리 |
js/index.mjs | ESM 엔트리 |
types/index.d.ts | TypeScript 선언 |
json/tokens.json | 처리된 토큰 출력 |
대부분의 파일은 생성이 간단하지만, 몇몇은 특별한 처리가 필요했습니다.
Tailwind 불투명도 수정자 다루기
문제점
다음과 같은 클래스를 사용했을 때:
작동하지 않았습니다. Tailwind의 불투명도 수정자는 실제 색상 채널에 접근해야 하기 때문입니다. 16진수 값이면 알파 컴포넌트를 삽입할 수 있지만, CSS 변수(var(--color-primary))는 Tailwind에게 단순 문자열에 불과해 불투명도를 계산할 수 없습니다.
해결책
각 색상 토큰에 대해 RGB 채널을 노출하는 두 번째 버전을 생성합니다:
/* figma‑tokens.json → generated CSS */
--color-primary: #6B21A8;
--color-primary-rgb: 107, 33, 168;
그 후 Tailwind v3에서는 다음과 같이 사용할 수 있습니다:
rgb(var(--color-primary-rgb) / )
이를 통해 bg-primary/50, border-border/40, text-foreground/80와 같은 클래스를 사용할 수 있습니다.
Result: 모든 색상이 이제 두 번 제공됩니다—한 번은 16진수 형태로, 또 한 번은 RGB 채널 형태로. 우아한가요? 논쟁의 여지가 있습니다. 효과적인가요? 확실히 그렇습니다. Tailwind v4에서는 이후 네이티브
color-mix()를 사용해 이를 간소화했습니다.
다크‑모드 전략
클래식 접근법 (Tailwind v3)
/* light values */
:root { /* … */ }
/* dark values */
.dark { /* … */ }
.dark 클래스를 “에 토글합니다.
시스템 선호 접근법 (Tailwind v4)
@media (prefers-color-scheme: dark) {
/* dark styles */
}
실제 충돌
사용자는 OS 선호도를 무시하고 싶을 수 있습니다. 예: “내 OS는 다크인데, 사이트는 라이트 모드로 보고 싶다.” prefers-color-scheme만 의존하면 이런 상황이 어색해집니다.
최종 결합 전략
- 기본적으로 OS 선호도를 따름
- 명시적인
data-theme="dark"를 존중 - 레거시
.dark클래스 토글을 지원
탈출구:
OS 설정에 관계없이 라이트 모드로 강제합니다.
@theme 함정
@theme inline을 사용하여 토큰 값을 직접 생성된 유틸리티에 삽입했습니다:
/* before */
background-color: var(--color-primary);
/* after (incorrect) */
background-color: #6B21A8;
하드코딩된 16진수 색상값은 CSS 변수는 변경될 수 있지만 정적 값은 변경될 수 없기 때문에 다크 모드 업데이트를 방해했습니다. 해결 방법은 inline 키워드를 제거하는 것이었습니다:
@theme
이제 유틸리티가 다시 CSS 변수를 참조하므로 다크 모드가 예상대로 작동합니다.
TypeScript 선언
파이프라인은 다음과 같은 선언도 내보냅니다:
export declare const colorPrimary: string;
export declare const spacingMd: string;
이 선언들은 선택 사항이지만 토큰을 차트, 런타임 테마 또는 기타 동적 시스템에 연결할 때 유용합니다.
실제 승리
| Before | After |
|---|---|
| 디자인 값이 Figma에 존재했습니다. | 값은 단일 JSON 파일에 저장됩니다. |
| 코드 값이 코드베이스에 존재했습니다. | 그 외 모든 것은 자동으로 파생됩니다. |
| 정렬을 위해서는 인간의 규율이 필요했습니다. | 드리프트가 구조적으로 불가능해집니다. |
11개의 출력, RGB 채널, 다크 모드 로직, 그리고 Tailwind의 특이점은 구현 세부 사항에 불과합니다. 핵심 성과는 디자인과 코드가 더 이상 현실을 놓고 논쟁하지 않는 시스템입니다.
리소스
- 7onic – 오픈‑소스 React 디자인 시스템 (MIT 라이선스). 문서 및 인터랙티브 플레이그라운드:
- 소스 코드: (별표 감사)
- 이 시리즈의 더 많은 글:
- X에서 업데이트 팔로우: @7onicHQ