"use client"; import type { CSSProperties, ReactNode } from "react"; import type { CssSection, CssToken } from "./read-css-tokens"; import styles from "./dev-test.module.scss"; /** * 미리보기 — 토큰 이름으로 무엇을 보여줄지 고른다. * * ⚠️ 값은 그 토큰의 CSS 변수가 아니라 **그 섹션의 선언 원문**을 넣는다. `var(--fox-그토큰)`을 * 쓰면 PC 섹션을 좁은 창에서 볼 때 모바일 값이 그려지고 Light 섹션이 다크 테마에서 다크 색으로 * 그려진다 — 이 화면은 각 모드가 정의한 값을 보여야 하므로 현재 테마·뷰포트에 흔들리면 안 된다. * 원문이 참조(`var(--fox-primitive-…)`)인 경우는 그대로 넣어도 안전하다. 참조 대상인 * primitive·theme는 모드와 무관한 단일 값이기 때문이다. * 인라인 `style`을 쓰는 예외인 이유도 같다: 렌더할 토큰을 미리 알 수 없다. */ const PREVIEWS: { match: RegExp; render: (value: string) => ReactNode }[] = [ { match: /(^|-)padding(-|$)/, render: (value) => (
첫 번째 문단
두 번째 문단
첫 번째 문단
두 번째 문단
다람쥐 헌 쳇바퀴에 타고파 · Handgloves 0123
), }, { match: /^font-family-/, render: (value) => (다람쥐 헌 쳇바퀴에 타고파 · Handgloves 0123
), }, { match: /^font-weight-/, render: (value) => (다람쥐 헌 쳇바퀴에 타고파 · Handgloves 0123
), }, ]; function previewFor(token: CssToken): ReactNode { if (isColor(token)) { // 색은 값 칸의 칩이 이미 보여준다. return null; } const hit = PREVIEWS.find((entry) => entry.match.test(token.name)); return hit ? hit.render(token.declaration) : null; } /** 색 토큰 판별 — 이 세 접두사만 색이다(font-·number-는 아니다). */ function isColor(token: CssToken): boolean { return /^(color|primitive|theme)-/.test(token.name); } /** * 칩 배경으로 선언 원문을 그대로 넣는다. 참조(`var(--fox-primitive-neutral-0)`)든 * 리터럴이든 CSS가 알아서 해석하고, 참조 대상인 primitive·theme는 모드와 무관한 * 값이라 Light 섹션은 라이트 색이, Dark 섹션은 다크 색이 정확히 그려진다. */ function chipStyle(token: CssToken): CSSProperties { return { background: token.declaration }; } export function TokenView({ section }: { section: CssSection }) { const hasPreview = section.tokens.some((token) => previewFor(token) !== null); return ({section.source} — 값은 컴파일된 스타일시트에서 직접 읽습니다. 참조면 가리키는 토큰을, 아니면 값을 표시합니다.
| 토큰 | 값 / 참조 | {hasPreview ?미리보기 | : null}
|---|---|---|
| {token.name} | {isColor(token) ? ( ) : null} {token.alias !== null ? ( → {token.alias} ) : ( token.declaration )} | {hasPreview ?{previewFor(token)} | : null}