Communitygithub.com

マルチアプリ・デザインシステム

複数のアプリやプロトタイプを、見た目を平坦化せずに1つの共有コンポーネントライブラリに統合します。重複したローカルコンポーネントの発見、トークン駆動の共有コンポーネント化、バリアント名のマッピング、アプリ固有の部分の判断、カスタムトークンを静かに壊すtailwind-mergeの落とし穴をカバーします。

マルチアプリ・デザインシステム とは?

このスキルは、複数のアプリやスイート製品がそれぞれ独自に成長させたボタン、セレクト、フィールド、モーダル、ページャー、トーストなどの重複コンポーネントを、1つの共有コンポーネントライブラリに統合するための体系的なアプローチを提供します。各アプリの外観や計測値を維持するために、コンポーネントをトークン駆動型にし、テーマごとに寸法を定義できるようにします。具体的には、CSSカスタムプロパティ(`--spacing-btn-md`など)を用いて高さやパディングをトークン化し、各アプリやスイートが独自のテーマで値を上書きできるようにします。また、統合プロセスでは、アプリごとにローカルコンポーネントを棚卸しし、共有コンポーネントに置き換えるバリアントマッピングを明確に定義します。さらに、`cn()`関数内でカスタムトークンがtailwind-mergeによって誤って解釈されないように、`extendTailwindMerge`を使ってトークンを正しく登録する方法も説明します。このスキルは、Claude CodeやCursor、CodexなどのAIエージェントと連携して、既存のコードベースを分析し、統合作業を効率的に進める際に有用です。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Adamparishspok/skills/tree/HEAD/skills/multi-app-design-system

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

多くのアプリ、一つのシステム

よくある失敗: あるキットがアプリ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 を参照してください。

統合パス、アプリごとに

  1. ローカルコピーを棚卸しする。 各アプリを export function (Btn|Button|IconBtn|Select|Field|Input|Modal|Dialog|Sheet|Badge|Empty|Pager|Toast|Stat|Status|Spinner) でgrepします。呼び出し箇所を数えます。

  2. 置き換えて削除する テーマ設定後に共有コンポーネントが一致する場合。バリアント名を明示的にマッピングし、そのマッピングを書き留めます:

    ローカル名共有バリアント
    primary, navyaccent
    secondaryoutline
    quiet, softsubtle
    danger (ベタ塗り)danger-solid
  3. アプリ固有の部分はアプリ固有のままにする:

    • ドメインウィジェット、チャート、アプリアイコン;
    • 形状がブランドであるコントロール(iOSの角形、Carbonのフラットコントロール、48pxのピル型CTA);
    • 共有コンポーネントにない動作を持つコントロール(トライステートチェックボックス、削除可能なチップ、「すべて」リセットアイテム、マルチセレクトフィルター)。

    何かを1つ追加するだけの薄いラッパーは問題ありません。コメントにその理由を記述してください。

  4. ネイティブの <select> とメニューベースのセレクトを1つのSelectに置き換える。

    • Radix Select は "" を「値なし」として予約しています: "all" のようなセンチネル値を使用し、それをマッピングし直します。
    • aria-labelledby と aria-describedby を転送します。
    • selectOption() を呼び出すウォークスルースクリプトは、コンボボックスをクリックしてからオプションをクリックする必要があります。
  5. 各アプリを独自のスクリーンショットと照合する (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" にしない場合、変換されたすべての非送信呼び出しサイトでそれを設定する必要があります。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Adamparishspok/skills

Make a website, web app or online store ready for AI agents. Scan it with Cloudflare's Agent Readiness checks, decide which checks apply to this kind of site, ship the discovery files and headers in priority order, and add the AI-first basics the scanner does not score (server-rendered content, JSON-LD, llms.txt). Covers robots.txt AI rules, Content Signals, sitemap, Markdown for Agents (Accept text/markdown), Link headers, API catalog, OAuth discovery, auth.md, MCP server card, A2A agent card, agent skills index, WebMCP, and commerce protocols (ACP, UCP, AP2, MPP, x402). Use when making a site AI-ready, agent-ready or AI-first, or fixing an isitagentready.com or Cloudflare Agent Readiness report. Triggers on: AI ready, agent ready, AI-first, agent readiness, isitagentready, AI Crawl Control, Markdown for Agents, text/markdown, llms.txt, GPTBot, ClaudeBot, AI crawlers, Content-Signal, ai-train, api-catalog, .well-known, oauth-protected-resource, auth.md, MCP server card, agent card, agent skills, WebMCP, a...

Adamparishspok/skills

Install a complete, lean favicon set on any website or web app — the five files modern browsers, iOS and Android actually use, one block of head markup added once in the root layout, and a check that every file resolves. Covers finding the public folder per framework, generating the set from one SVG (or from a RealFaviconGenerator package), dark-mode SVG icons, maskable manifest icons, cache busting and verification. Use when adding, replacing or auditing a favicon, app icon, apple-touch-icon or web manifest. Triggers on: favicon, favicon.ico, favicon.svg, apple-touch-icon, site.webmanifest, manifest.json, app icon, PWA icon, maskable icon, tab icon, RealFaviconGenerator.

Adamparishspok/skills

Give an interface one shared tempo and a small vocabulary of hover and state micro-interactions: duration tiers (tap/pop/hover/card/layout) for CSS and Motion, swap hand-offs, rows whose highlight grows in, trailing arrows, chevron nudges, card lifts without translate, scroll-edge fades, and icon/label swaps for copy and toggle buttons. Use when animations feel inconsistent, durations are scattered magic numbers, hovers only change colour, or a product feels flat or unfinished. Triggers on: animation duration, transition timing, hover state, micro-interaction, polish, copy button feedback, menu icon to close, back arrow, card hover, scroll fade, motion tokens, Framer Motion durations.

Adamparishspok/skills

Build or migrate a UI's neutral palette (grounds, surfaces, lines, ink/text) as an OKLCH formula driven by a few inputs instead of dozens of hand-picked hex values, with light and dark themes, per-step ladder overrides, a fit script that reproduces existing colours, and a browser contrast audit. Use when creating a theme, adding dark mode, retinting a product, auditing text contrast, or consolidating several apps' palettes. Triggers on: palette, neutrals, grey ramp, dark mode, theme tokens, oklch, retint, hue, contrast audit, design tokens, Tailwind @theme colours.

関連スキル