Skip to content

feat(css): expose primitive and semantic color tokens as CSS variables#5

Open
nacal wants to merge 1 commit into
mainfrom
feat/expose-color-tokens-as-css-vars
Open

feat(css): expose primitive and semantic color tokens as CSS variables#5
nacal wants to merge 1 commit into
mainfrom
feat/expose-color-tokens-as-css-vars

Conversation

@nacal
Copy link
Copy Markdown
Member

@nacal nacal commented May 18, 2026

Summary

  • 新規 src/_tokens.scss を追加し、@pepabo-inhouse/adapter 経由でプリミティブ・セマンティックカラーを :root { --wip-color-* } として公開
  • src/_all.scss の先頭で @use './tokens'; を読み込み、既存のフレーバービルドに乗せる
  • src/docs/Color.mdx に「CSS 変数として参照する」セクションを追加

これにより、wip-ui を消費する側のアプリケーションでも var(--wip-color-semantic-neutral-100) のようにデザイントークンを直接参照できるようになり、#f4f4f5 などのハードコードが不要になります。

仕組み

  • _tokens.scssadapter.get-primitive-color() / adapter.get-semantic-color() を呼び、scripts/build-flavor-css.mjsflavorImporter がフレーバーごとに値を解決します。
  • 既存の prefixPlugin:
    • フレーバー個別ファイル (dist/css/{flavor}.css): :root のままドキュメントレベルに残す
    • 結合ファイル (dist/styles.css): :root[data-flavor="xxx"] に書き換え、last-flavor-wins を回避
  • 1 フレーバーあたり 102 個の変数を出力(primitive: 2 mono + 5×10 spectrum = 52 / semantic: 5×10 = 50)。
  • pepper はベースラインとして無接頭辞でも出力するため、<FlavorProvider> を使わない consumer でも var(--wip-color-*) は pepper 値で解決されます。

動作確認

$ npm run build:flavors
Building flavor CSS for 7 flavors...
  ✓ pepper.css   …   ✓ lolipop.css
  ✓ styles.css (pepper baseline + 7 flavors scoped)

dist/styles.css--wip-color-semantic-neutral-100 をフレーバーごとに抽出:

flavor value
pepper #edeef0
minne #f5f5f5
apollo #d9dce9
nachiguro #f2f6f7
flippers #ededed
kung-pu #edeef0
lolipop #dddfea
  • npm run lint (typecheck + biome): 通過
  • dist/styles.css 内に :root { ... } は 1 つだけ(pepper baseline)、残りは [data-flavor="..."] でスコープ済みであることを確認

議論ポイント

  1. プリミティブを公開するかセマンティック限定か — 本 PR では両方公開しています。セマンティックを推奨としつつ、Escape Hatch としてプリミティブも提供する立場。
  2. 命名規則--wip-color-primitive-gray-100 / --wip-color-semantic-neutral-100 の階層型を採用。理由は JS API (colors.primitive.gray, colors.semantic.neutral) や inhouse のトークン分類と一致するため。フラット (--wip-color-gray-100) のほうがよければご指摘ください。
  3. body reset / spacing / text colors は本 PR のスコープ外で、PR2 として別途切り出す予定です。

Test plan

  • npm run build:flavors でビルドエラーなし、警告なし
  • dist/css/{flavor}.css 各ファイル内の :root { --wip-color-* } の値がフレーバーごとに異なる
  • dist/styles.css 内で [data-flavor="xxx"] { --wip-color-* } にスコープされている
  • Storybook (npm run storybook) で Foundations/Colors のドキュメントが正しく表示される
  • 別プロジェクト (frontend-training-2026 など) から var(--wip-color-semantic-neutral-100) を参照して値が解決される

🤖 Generated with Claude Code

Adds src/_tokens.scss which emits a :root block of --wip-color-primitive-*
and --wip-color-semantic-* custom properties via the flavor-aware adapter.
Consumers can now reference design-system colors directly from their own
CSS (e.g. var(--wip-color-semantic-neutral-100)) instead of hardcoding hex
values. The existing scopeRoot pipeline in scripts/build-flavor-css.mjs
rescopes the :root block per flavor in the combined dist/styles.css.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant