디자인 투 코드 #2: 하나의 JSON, 열한 개 출력

발행: (2026년 4월 17일 AM 10:55 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

번역할 텍스트가 제공되지 않았습니다. 번역을 원하는 본문을 알려주시면 한국어로 번역해 드리겠습니다.

개요

전체 7onic 디자인 시스템은 1,847줄 길이의 단일 JSON 파일(figma‑tokens.json)에 기반합니다. 색상은 16진수 값(e.g., #6B21A8)으로, 간격은 일반 숫자(e.g., 16)로, 테두리 반경도 같은 형식으로, 애니메이션은 키프레임 객체로 저장합니다. 이 파일은 코드베이스에서 디자인 값이 존재할 수 있는 유일한 장소이며, 나머지는 모두 이 파일에서 생성됩니다.

단일 명령으로 해당 파일을 읽어 약 200 ms 안에 11개의 배포 파일을 생성합니다. 색상을 변경하고, 스크립트를 실행하고, 배포하면—이것이 전체 파이프라인입니다.

Generated Outputs

PathDescription
css/variables.css기본 CSS 변수
css/themes/light.css의미론적 라이트 테마
css/themes/dark.css의미론적 다크 테마
css/all.css번들된 CSS
tailwind/v3-preset.jsTailwind v3 프리셋
tailwind/v4-theme.cssTailwind v4 테마 파일
tailwind/v4.cssTailwind v4 CSS
js/index.jsCommonJS 엔트리
js/index.mjsESM 엔트리
types/index.d.tsTypeScript 선언
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만 의존하면 이런 상황이 어색해집니다.

최종 결합 전략

  1. 기본적으로 OS 선호도를 따름
  2. 명시적인 data-theme="dark"를 존중
  3. 레거시 .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;

이 선언들은 선택 사항이지만 토큰을 차트, 런타임 테마 또는 기타 동적 시스템에 연결할 때 유용합니다.

실제 승리

BeforeAfter
디자인 값이 Figma에 존재했습니다.값은 단일 JSON 파일에 저장됩니다.
코드 값이 코드베이스에 존재했습니다.그 외 모든 것은 자동으로 파생됩니다.
정렬을 위해서는 인간의 규율이 필요했습니다.드리프트가 구조적으로 불가능해집니다.

11개의 출력, RGB 채널, 다크 모드 로직, 그리고 Tailwind의 특이점은 구현 세부 사항에 불과합니다. 핵심 성과는 디자인과 코드가 더 이상 현실을 놓고 논쟁하지 않는 시스템입니다.

리소스

  • 7onic – 오픈‑소스 React 디자인 시스템 (MIT 라이선스). 문서 및 인터랙티브 플레이그라운드:
  • 소스 코드: (별표 감사)
  • 이 시리즈의 더 많은 글:
  • X에서 업데이트 팔로우: @7onicHQ
0 조회
Back to Blog

관련 글

더 보기 »

cubic-bezier로 CSS 전환을 레벨업하기

플랫해 보이는 CSS 전환은 왜 그런가요? 기본 ease 타이밍 함수는 작동하지만 일반적입니다. 실제 움직임은 개성이 있습니다—튕기고, 과도하게 움직이며…

React 초보자를 위한 기초

!React Basics for Beginners 표지 이미지 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-upl...