mcpField
T
tailwind-design-system

tailwind-design-system

github.com/giuseppe-trisciuoglioデザイン・UI3654.5k 回インストール7 週間前に更新
リポジトリ

tailwind-design-system について

Tailwind CSSとshadcn/uiでデザインシステムを構築するチーム向けのシステム設計ガイドです。トークンベースのテーマ設定やコンポーネントのラッパーを扱い、UIのルールを一元化します。

主な機能

  1. 01デザイントークンの一元管理
  2. 02CSS変数によるテーマ設定
  3. 03ライト、ダーク、複数テーマ対応
  4. 04shadcn/uiコンポーネントのラッパー
  5. 05トークン検証ワークフロー

活用シーン

  1. 01Tailwind CSSデザインシステムの新規構築
  2. 02スタイルをCSS変数トークンへ移行
  3. 03ダークまたはブランドテーマの追加
  4. 04UIコンポーネントへの共通ルール適用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill tailwind-design-system

インストール後、Claude Code で/tailwind-design-systemを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
component-wrapping.md
globals.css.example
theming.md

詳細

Tailwind CSS と shadcn/ui のデザインシステム

概要

Tailwind CSS(v4.1 以降)と shadcn/ui を使用して、集中管理型のデザインシステムを作成・管理するためのエキスパートガイドです。このスキルでは、デザイントークンの定義、CSS 変数を使用したテーマの設定、shadcn/ui のプリミティブに基づく一貫性のある UI コンポーネントライブラリの構築について、体系的なワークフローを提供します。

他のスキルとの関係:

  • tailwind-css-patterns は、ユーティリティファーストのスタイリング、レスポンシブデザイン、Tailwind CSS の一般的な使い方を扱います
  • shadcn-ui は、個々のコンポーネントのインストール、設定、実装を扱います
  • このスキル は、システムレベルのオーケストレーション、つまりデザイントークン、テーマ設定の基盤、コンポーネントのラッピングパターン、アプリケーション全体の一貫性の確保に重点を置きます

使用するタイミング

  • Tailwind CSS と shadcn/ui を使用して、新しいデザインシステムをゼロから構築する場合
  • デザイントークン(色、タイポグラフィ、余白、角丸、シャドウ)を CSS 変数として定義する場合
  • 集中管理型のテーマシステム(ライト/ダークモード)を使用して globals.css を設定する場合
  • shadcn/ui コンポーネントを、制約を適用したデザインシステムのプリミティブでラップする場合
  • 一貫性のある UI を実現するため、トークン駆動型のコンポーネントライブラリを構築する場合
  • JavaScript ベースの Tailwind 設定から CSS ファーストの設定(v4.1 以降)に移行する場合
  • 知覚的な均一性を実現するため、oklch 形式でカラーパレットを確立する場合
  • ライト/ダークモード以外の複数テーマ対応(例:ブランドテーマ)を作成する場合

手順

手順 1:デザインシステムの設定を初期化する

次のコマンドを実行して、プロジェクトをセットアップします。

# Check if Tailwind is installed
npx tailwindcss --version

# For Tailwind v4 (recommended)
npx @tailwindcss/vite@latest init   # or: npm install -D tailwindcss @tailwindcss/vite

# Initialize shadcn/ui CLI
npx shadcn@latest init

# Install core shadcn/ui components
npx shadcn@latest add button card input -y

検証チェックポイント:セットアップ後、次のコマンドで確認します。

ls src/components/ui/        # Should list installed components
cat src/app/globals.css       # Should contain @tailwind directives
手順 2:デザイントークンを定義する

デザイントークンを含む src/app/globals.css を作成します。

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    /* Brand Colors */
    --primary: oklch(0.55 0.18 250);
    --primary-foreground: oklch(0.985 0 0);

    /* Semantic Colors */
    --background: oklch(0.99 0 0);
    --foreground: oklch(0.15 0 0);
    --secondary: oklch(0.96 0.01 250);
    --secondary-foreground: oklch(0.20 0 0);

    /* Validation: all colors must have foreground pair */
    --destructive: oklch(0.55 0.22 25);
    --destructive-foreground: oklch(0.985 0 0);
  }

  .dark {
    --primary: oklch(0.65 0.20 250);
    --background: oklch(0.14 0 0);
    --foreground: oklch(0.97 0 0);
    --secondary: oklch(0.25 0.02 250);
  }
}

検証チェックポイント:トークンが有効な CSS であることを確認します。

grep -E "^[[:space:]]*--[a-z-]+:" src/app/globals.css | wc -l
# Should return count of defined tokens (e.g., 10+)
手順 3:テーマ設定の基盤を構成する

CSS 変数を Tailwind ユーティリティに連携します(Tailwind v4.1 以降)。

@theme inline {
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-background: var(--background);
  --color-foreground: var(--foreground);
}

components/providers/theme-provider.tsx にダークモードのクラス切り替えを追加します。

import { useEffect } from "react";
export function ThemeProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
    document.documentElement.classList.toggle("dark", isDark);
  }, []);
  return <>{children}</>;
}

検証チェックポイント:ダークモードをテストします。

document.documentElement.classList.contains("dark") // in browser console
手順 4:shadcn/ui コンポーネントをラップする

src/components/ds/Button.tsx を作成します。

import { Button as ShadcnButton } from "@/components/ui/button";

type DSVariant = "primary" | "secondary" | "destructive" | "ghost";
const variantMap: Record<DSVariant, "default" | "secondary" | "destructive" | "ghost"> = {
  primary: "default", secondary: "secondary",
  destructive: "destructive", ghost: "ghost",
};

export function Button({ variant = "primary", ...props }: { variant?: DSVariant } & React.ComponentProps<typeof ShadcnButton>) {
  return <ShadcnButton variant={variantMap[variant]} {...props} />;
}

検証チェックポイント:ビルドが成功することを確認します。

npx tsc --noEmit src/components/ds/Button.tsx
手順 5:検証してドキュメント化する

トークン検証スクリプトを実行します。

REQUIRED=("primary" "primary-foreground" "background" "foreground" "secondary" "secondary-foreground")
for token in "${REQUIRED[@]}"; do
  grep -q "$token:" src/app/globals.css || echo "MISSING: --$token"
done

検証チェックポイント:すべての shadcn コンポーネントが DS トークンを使用していることを確認します。

grep -r "bg-primary\|text-primary\|bg-background" src/components/ds/

例

カスタムトークンの追加

globals.css の基本トークンを拡張します。

:root {
  --warning: oklch(0.84 0.16 84);
  --warning-foreground: oklch(0.28 0.07 46);
}

.dark {
  --warning: oklch(0.41 0.11 46);
  --warning-foreground: oklch(0.99 0.02 95);
}

@theme inline {
  --color-warning: var(--warning);
  --color-warning-foreground: var(--warning-foreground);
}

使用例:<div className="bg-warning text-warning-foreground">Warning</div>

shadcn/ui コンポーネントをデザインシステムのプリミティブとしてラップする

Button、Text、Stack のプリミティブと、完全な TypeScript 型を含む詳しい例については、references/component-wrapping.md を参照してください。

トークンの使用を徹底する、制約付きのデザインシステムコンポーネントを作成します。 インラインの例:

import { Button as ShadcnButton } from "@/components/ui/button";

export function Button({ variant = "primary", size = "md", ...props }) {
  const variantMap = { primary: "default", secondary: "secondary" };
  const sizeMap = { sm: "sm", md: "default", lg: "lg" };
  return (
    <ShadcnButton
      variant={variantMap[variant]}
      size={sizeMap[size]}
      {...props}
    />
  );
}
複数テーマへの対応

ライト/ダークモード以外にも複数のブランドテーマが必要なアプリケーションの場合:

[data-theme="ocean"] {
  --primary: oklch(0.55 0.18 230);
  --primary-foreground: oklch(0.985 0 0);
}

[data-theme="forest"] {
  --primary: oklch(0.50 0.15 145);
  --primary-foreground: oklch(0.985 0 0);
}
const [theme, setTheme] = useState("light");
useEffect(() => {
  document.documentElement.setAttribute("data-theme", theme);
}, [theme]);
デザイントークンの検証

必要なトークンがすべて定義されていることを確認します。

#!/bin/bash
REQUIRED=("--background" "--foreground" "--primary" "--primary-foreground")
for token in "${REQUIRED[@]}"; do
  grep -q "$token:" src/styles/globals.css || echo "Missing: $token"
done

制約と注意事項

  • oklch カラーフォーマット:知覚的な均一性を保つため、oklch を使用してください。すべてのブラウザーが oklch にネイティブ対応しているわけではないため、古いブラウザーを対象とする場合は互換性を確認してください
  • トークンの命名:シームレスに統合できるよう、shadcn/ui の規約(--primary、--primary-foreground)に従ってください
  • @theme inline と @theme:CSS 変数を Tailwind ユーティリティに橋渡しする場合は @theme inline を使用し、トークンを直接定義する場合は @theme を使用してください
  • コンポーネントのラップ:ラッパーコンポーネントは薄く保ってください。デザインシステムのルールを適用する制約のみを追加し、shadcn/ui のロジックを重複させないでください
  • ダークモード::root 内のすべてのトークンに対し、必ずダークモードの値を定義してください。ダークモード用のトークンが欠けていると、視覚的なリグレッションが発生します
  • CSS 変数のスコープ::root で定義されたトークンはグローバルです。競合せずに複数のテーマを使うには、[data-theme] セレクターを使用してください
  • パフォーマンス:CSS カスタムプロパティの過剰なチェーンは避けてください。var() の参照ごとにわずかですが、ゼロではないオーバーヘッドが発生します
  • Tailwind v4 と v3:@theme ディレクティブと @theme inline は v4.1 以降の機能です。v3 のプロジェクトでは、theme.extend とともに tailwind.config.js を使用してください

ベストプラクティス

  1. 信頼できる唯一の情報源:すべてのデザイントークンは globals.css に配置してください。コンポーネント内で色の値をハードコードしないでください
  2. 意味に基づく命名:外観に基づく名前(--blue-500、--red-600)ではなく、用途に基づく名前(--primary、--destructive)を使用してください
  3. 前景色とのペアリング:コントラスト要件を満たすため、すべての背景トークンに対応する -foreground トークンを用意してください
  4. トークンのスケール:柔軟性を確保できるよう、カスタムパレットには完全なスケール(50~950)を定義してください
  5. コンポーネントのバレルエクスポート:インポートを簡潔にするため、すべての DS コンポーネントを単一の index.ts からエクスポートしてください
  6. アクセシビリティ:すべてのトークンペア(背景色/前景色)が WCAG AA のコントラスト比(テキストは 4.5:1、大きなテキストは 3:1)を満たすようにしてください
  7. トークンのドキュメント化:チーム向けに、すべてのトークンの視覚的なリファレンスを管理してください
  8. 一貫したスペーシング:任意の値ではなく、DS コンポーネントを通じて Tailwind のスペーシングスケール(gap-2、gap-4、gap-6)を使用してください

参考資料

コメント