コンテンツにスキップ

ダークモードのマージ

インクリメンタルオーバーライド

Section titled “インクリメンタルオーバーライド”

ダークファイル("$dark": true)はライトと異なるキーだけを宣言し、オーバーライドしないキーはライトの値を引き継ぎます:

color-dark.json
{
"$namespace": "color",
"$dark": true,
"$description": "ライトと異なるキーのみを宣言し、未オーバーライドのキーは color.json を引き継ぐ",
"primary": { "default": { "value": "#3D649E" } }
}

color.primary.hover、.active など列挙されていないキーは、ダークでもライトの値を引き継ぎます。削減の原則はキー単位の比較です:ライトの値と完全に同じキーは一律で削除されます(例えば onPrimary は両テーマとも #FFFFFF、disabled.* は両テーマとも同じ ref の組なので、いずれもダークファイルには現れません)。

ダークファイルはライトファイルと同じ $namespace を宣言しなければなりません(color-dark.json は "$namespace": "color" を明示)。そうして初めてオーバーライドキーが同じパスに落ちます。

ダークファイル内の ref は resolveDarkRef で解決し、ルールはライトと異なります:

  1. 対象がダーク名前空間内にあり、かつ ref → ダーク内でチェーンを再帰的にたどる(ダークがダークを参照して初めて同一テーマの値になる)
  2. 対象がダーク名前空間内にあり、かつリテラル値 → ダーク値を返す
  3. 対象がダーク名前空間内にない → ライト名前空間へフォールバックして値を取る
// ダークがダークを参照:ダークの primary.active を取る
"selectedDark": { "ref": "color.primary.active" }

ダーク ref にも循環検出があり(检测到暗色令牌引用环)、対象はライトセット / ダークセットのいずれかに存在しなければならず、そうでなければ 暗色令牌 X 引用不存在 を投げます。

web 血脈のダークは color-mix() を多用しますが、ネイティブ端にはこのランタイム能力がありません。そのためビルド期にリテラルの色値へ事前計算し、計算の根拠を description に書きます:

"selected": {
"value": "#B1C1D8",
"description": "color-mix(primary 40%, #fff) から事前計算。ダークパネルのコントラスト比 5.2:1"
},
"primary": {
"bg": {
"value": "rgba(61, 100, 158, 0.25)",
"description": "color-mix(primary 25%, transparent) から事前計算"
}
}

resolveTokens は TokenSet.dark を生成します:フラットな Map<path, TokenValue> で、オーバーライドされたキーのみを含みます。各端の target がそれぞれの出し方を決めます:

プラットフォーム ダークの仕組み
Android 独立した object LhDarkTokens
iOS 独立した public enum LhDarkTokens
HarmonyOS 独立した export class LhDarkTokens
C 同名マクロの再定義——ダークのヘッダーファイルをライトの後で include し、同名の #define をそのまま上書きする

2 種類の異常が orphanDarkPaths に記録されます(codegen は中断しません。pnpm verify:tokens が報告します):

  • ダークキーに型がない(自身の type もなく、ライトセットに同名キーもなく継承できない)→ そのキーをスキップし、オーバーライド表に書き込まない
  • ダークキーがライトセットに存在しない(孤児)→ オーバーライド表には書き込むが、報告する

現在ダークがオーバーライドするのは color.* 名前空間のみです(正確なキー数はバージョンによって変わります。トークンリファレンス ページのダーク列を参照)。色以外の名前空間(間隔、角丸、フォントサイズなど)はダークでもライトの値を引き継ぎます——dist/docs/tokens.md で色以外の行のダーク列が — なのはこのためです。

トークンリファレンス ページでは、各トークンのライト値とダーク値を同時に確認できます。

Copyright © 2024-2026 FengMo WenXue