多くのアプリ、一つのシステム
よくある失敗: あるキットがアプリA用に作られ、アプリBのボタンは高さが4px高く、角丸が2px大きいため、Bは「今回だけ」とボタンをフォークする。5つのアプリができる頃には、6種類のボタン、8種類のセレクト、3種類のモーダルができあがり、すべて同じ仕事をしている。
共有コンポーネントをトークンサイズにします: 動作、マークアップ、状態を持ち、各テーマが計測値を提供します。その後、アプリごとに統合していきます。
トークンサイズのコンポーネント
アプリ間で異なるすべての計測値をテーマトークンから読み取ります:
@theme {
--spacing-btn-sm: 1.75rem; --spacing-btn-px-sm: 0.625rem;
--spacing-btn-md: 2.25rem; --spacing-btn-px-md: 0.875rem;
--spacing-field: 2.125rem; /* 入力 / セレクトの高さ */
--text-label: 0.8125rem;
}
md: "h-btn-md px-btn-px-md text-sm",
icon: "size-btn-md",
そして:
- スイートはテーマ内でトークンを一度オーバーライドするだけで、その中のすべてのアプリが独自の計測値を持つコントロールを取得します。
- 半径、塗りつぶし、シャドウはすでにトークンです (
rounded-field,bg-accent,--shadow-card)。 - 塗りつぶしは、カラーに装飾クラスを加えて表現します(例:
bg-accent accent-fill)。装飾(光沢)のみを定義するテーマは、透明なボタンをレンダリングしません。
references/button.tsx を参照してください。
統合パス、アプリごとに
-
ローカルコピーを棚卸しする。 各アプリを
export function (Btn|Button|IconBtn|Select|Field|Input|Modal|Dialog|Sheet|Badge|Empty|Pager|Toast|Stat|Status|Spinner)でgrepします。呼び出し箇所を数えます。 -
置き換えて削除する テーマ設定後に共有コンポーネントが一致する場合。バリアント名を明示的にマッピングし、そのマッピングを書き留めます:
ローカル名 共有バリアント primary,navyaccentsecondaryoutlinequiet,softsubtledanger(ベタ塗り)danger-solid -
アプリ固有の部分はアプリ固有のままにする:
- ドメインウィジェット、チャート、アプリアイコン;
- 形状がブランドであるコントロール(iOSの角形、Carbonのフラットコントロール、48pxのピル型CTA);
- 共有コンポーネントにない動作を持つコントロール(トライステートチェックボックス、削除可能なチップ、「すべて」リセットアイテム、マルチセレクトフィルター)。
何かを1つ追加するだけの薄いラッパーは問題ありません。コメントにその理由を記述してください。
-
ネイティブの
<select>とメニューベースのセレクトを1つのSelectに置き換える。- Radix Select は
""を「値なし」として予約しています:"all"のようなセンチネル値を使用し、それをマッピングし直します。 aria-labelledbyとaria-describedbyを転送します。selectOption()を呼び出すウォークスルースクリプトは、コンボボックスをクリックしてからオプションをクリックする必要があります。
- Radix Select は
-
各アプリを独自のスクリーンショットと照合する (
visual-regression-passを参照)。実際の差分は通常意図されたものです: サイズ、光沢、押下スケール。
tailwind-merge の落とし穴 (cn())
tailwind-merge は Tailwind の組み込みスケールしか認識しません。カスタムトークンは次の3つの方法で静かに壊れます:
- 未知のスペーシングトークン。
cn("h-btn-md", "h-10")は両方を保持します。h-btn-mdが高さであることを認識せず、スタイルシートの順序が勝者を決定するためです。呼び出し元のh-10がトークンに負けて、40pxのボタンが36pxでレンダリングされました。トークンを登録してください:extendTailwindMerge({ extend: { theme: { spacing: ["btn-sm","btn-md","field", …] } } })。 - 未知のテキストサイズ。
cn("text-meta", "text-ink")はtext-metaを色として扱い、ドロップします。サイズを登録してください:theme: { text: ["meta","micro","label"] }。 - カスタムシャドウと色。
text-14がtext-t3の隣にある、または任意のshadow-[var(--x)]が名前付きシャドウの隣にある: 同じ問題です。コードベースがどこでも閉じたカスタムスケールを使用している場合は、そこでプレーンなclsxを使用してください。
references/cn.ts を参照してください。
フォーカスとバリデーション
aria-invalid:ring-*スタイルはfocus-visible:ring-*より優先され、フォーカスされた無効フィールドのフォーカスリングを隠します。aria-invalid:not-focus-visible:ring-…と記述してください。- フォーム内の裸の
<button>はフォームを送信します。共有Buttonがデフォルトでtype="button"にしない場合、変換されたすべての非送信呼び出しサイトでそれを設定する必要があります。