mcpField
C
canvas-styling-conventions

canvas-styling-conventions

github.com/drupal-canvasデザイン・UI3216 回インストール5 週間前に更新
リポジトリ

canvas-styling-conventions について

Drupal Canvas の React と Tailwind CSS 4 を使う開発者向けのスタイル規約スキルです。Canvas Headless と React の規則を区別し、テーマトークン、クラス結合、バリアントの使い方を示します。

主な機能

  1. 01Canvas Headless と React の判別
  2. 02Tailwind のテーマトークン利用
  3. 03cn() によるクラス結合
  4. 04CVA によるカラーのバリアント定義
  5. 05コンポーネントでの生のカラー値の回避

活用シーン

  1. 01Canvas コンポーネントのスタイル統一
  2. 02繰り返す色をテーマトークンに集約
  3. 03制限されたカラー設定の定義

インストール

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

$npx skills add https://github.com/drupal-canvas/skills --skill canvas-styling-conventions

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

詳細

プロジェクトの種類

このスキルを適用する前に、package.json を確認し、@drupal-canvas/headless または @drupal-canvas/headless- で始まる依存関係があるか確認してください。該当する依存関係がある場合、これは Canvas Headless コードベースです。まず canvas-headless を読んでください。以下の React 固有のガイダンスよりも、そちらが優先されます。このスキルの Tailwind 4 のテーマトークンに関するガイダンスは、ヘッドレスプロジェクトにもそのまま適用されます。一方、cn() と className のセクションは React 固有です。該当する依存関係がない場合、これは Canvas でレンダリングされる React コードベースです。コンポーネントは React(index.jsx/.tsx)で、このスキルの内容がすべてそのまま適用されます。プロジェクトの種類はこの2つのみです。

技術スタック

技術用途
Tailwind CSS 4.1+スタイリング
class-variance-authority(CVA)コンポーネントのバリアント
clsx + tailwind-merge(cn() 経由)クラス名のマージ

スタイリングにはこれらの依存関係のみを使用してください。サードパーティの CSS ライブラリを追加したり、新しいスタイリングユーティリティを作成したりしないでください。

Canvas Headless コードベースでは、drupal-canvas パッケージとその cn() はサポートされていません。CVA は、プロジェクトにインストールすれば、どのフレームワークでも使用できます。クラスのマージには、フレームワーク独自のクラス合成の慣用的な方法を使用してください。詳しくは canvas-headless を参照してください。

スタイリング規約

  • global.css で定義されている Tailwind のテーマカラー(primary-*、gray-*)を使用してください。
  • 色の値をハードコードせず、テーマトークンを使用してください。
  • 例にある既存のフォーカス、ホバー、アクティブ状態のパターンに従ってください。

cn() ユーティリティ

Tailwind クラスのマージには cn() を使用してください。条件付きクラスに clsx を使用し、tailwind-merge で競合するユーティリティを解決します。どちらかのソースからインポートできます。

import { cn } from '@/lib/utils';
// or
import { cn } from 'drupal-canvas';

使用例:

const Button = ({ variant, className, children }) => (
  <button
    className={cn(
      'rounded px-4 py-2',
      variant === 'primary' && 'bg-primary-600 text-white',
      variant === 'secondary' && 'bg-gray-200 text-gray-800',
      className,
    )}
  >
    {children}
  </button>
);

スタイルをカスタマイズできるよう className を受け付ける

このルールは React 固有です。Vue および Astro のコンポーネントでは、利用側がスタイルを上書きする必要がある場合、フレームワーク独自のクラスの受け渡し方法(Vue では属性のフォールスルー、Astro では class プロパティ)を使用してください。

すべての React コンポーネントは、スタイルを上書きできるよう className プロパティを受け付ける必要があります。利用側のクラスが優先されるよう、cn() の最後の引数として渡してください。

const Card = ({ colorScheme, className, children }) => (
  <div className={cn(cardVariants({ colorScheme }), className)}>{children}</div>
);

className は実装/合成用のプロパティであり、エディター用のプロパティではありません。component.yml に className を追加したり、必須として指定したり、Canvas のメタデータに表示したりしないでください。

Tailwind 4 のテーマ変数

Canvas プロジェクトでは、Tailwind CSS 4 の @theme ディレクティブを使って global.css にデザイントークンを定義します。@theme { } 内で定義された変数は、Tailwind のユーティリティクラスとして自動的に利用可能になります。

利用可能なデザイントークンは、必ず global.css で確認してください。 色、フォント、ブレークポイント、その他のデザイントークンの信頼できる情報源は、@theme ブロックです。

テーマ変数とユーティリティクラスの対応

@theme で CSS 変数を定義すると、Tailwind 4 は変数の名前空間プレフィックスに基づいて、対応するユーティリティクラスを自動生成します。

@theme 内の CSS 変数生成されるユーティリティクラス
--color-primary-600: #xxxbg-primary-600、text-primary-600、border-primary-600
--color-gray-100: #xxxbg-gray-100、text-gray-100、border-gray-100
--font-sans: ...font-sans
--breakpoint-md: 48remレスポンシブ用プレフィックス md:

パターンは次のとおりです。--{namespace}-{name} は {utility}-{name} になります。

例

global.css に次の定義があるとします。

@theme {
  --color-primary-600: #1899cb;
  --color-primary-700: #1487b4;
}

色を受け付けるユーティリティであれば、どれでもこれらの色を使用できます。

// Correct
<button className="bg-primary-600 hover:bg-primary-700 text-white">
  Click me
</button>

// Wrong
<button className="bg-[#1899cb] text-white hover:bg-[#1487b4]">Click me</button>

任意の値(例:bg-[#xxx])は、テーマ変数を追加するほどではないまれな単発のケースであれば使用できます。ただし、色が複数箇所で使われる場合や、ブランド/デザインシステムの値を表す場合は、代わりに @theme に追加してください。

セマンティックエイリアス

テーマ変数は、ほかの変数を参照してセマンティックエイリアスを作成できます。

@theme {
  --color-primary-700: #1487b4;
  --color-primary-dark: var(--color-primary-700);
}

bg-primary-700 と bg-primary-dark のどちらも使用できます。意図をより明確に表せる場合(例:ブランドカラーの暗いバリエーションを表す primary-dark)は、セマンティックエイリアスを使用してください。

テーマ変数の追加または更新

デザインで、テーマにまだ定義されていない色、フォント、その他の値が必要な場合は、コンポーネントに値をハードコードせず、global.css の @theme ブロックに追加してください。

新しいテーマ変数を追加する場合:

  • デザインに新しいブランドカラーまたは色合いが加わる
  • 既存の値にセマンティックエイリアスが必要になる(例:--color-accent)
  • デザインで特定のスペーシング、フォント、またはブレークポイントの値が繰り返し使われる

既存のテーマ変数を更新する場合:

  • ブランドカラーが変わる(16 進数値を更新する)
  • システム全体でデザイントークンを調整する必要がある

例 - 新しい色の追加:

@theme {
  /* Existing tokens */
  --color-primary-600: #1899cb;

  /* New token for a success state */
  --color-success: #22c55e;
  --color-success-dark: #16a34a;
}

追加後すぐに、bg-success、text-success-dark などを使用できます。

テーマを整理された状態に保ちましょう。 関連するトークンは、その用途を説明するコメントとともにグループ化してください。global.css の既存の命名規則に従ってください(例:primary-100 から primary-900 のような番号付きの色合い、primary-dark のようなセマンティックな名前)。

色の props には色コードではなくバリアントを使用する

ユーザーが色コードを渡せる props は作成しないでください(16 進数値、RGB、HSL、生の色文字列など)。代わりに、CVA を使って、global.css のデザイントークンに対応する、人が理解しやすい少数のバリアントを定義してください。

利用可能なデザイントークンは必ず global.css で確認してください。 そこに定義されているトークン(primary-*、gray-* など)が、色の値の唯一の信頼できる情報源です。

誤り - 生の色値を許可する場合:

# Wrong
props:
  properties:
    backgroundColor:
      title: Background Color
      type: string
      examples:
        - '#3b82f6'
// Wrong
const Card = ({ backgroundColor }) => (
  <div style={{ backgroundColor }}>{/* ... */}</div>
);

正しい例 - デザイントークンを使った CVA バリアント:

# Correct
props:
  properties:
    colorScheme:
      title: Color Scheme
      type: string
      enum:
        - default
        - primary
        - muted
        - dark
      meta:enum:
        default: Default (White)
        primary: Primary (Blue)
        muted: Muted (Light Gray)
        dark: Dark
      examples:
        - default
// Correct
import { cva } from 'class-variance-authority';

const cardVariants = cva('rounded-lg p-6', {
  variants: {
    colorScheme: {
      default: 'bg-white text-black',
      primary: 'bg-primary-600 text-white',
      muted: 'bg-gray-100 text-gray-700',
      dark: 'bg-gray-900 text-white',
    },
  },
  defaultVariants: {
    colorScheme: 'default',
  },
});

const Card = ({ colorScheme, children }) => (
  <div className={cardVariants({ colorScheme })}>{children}</div>
);

この方法により、次のことが実現できます。

  • デザインシステム全体で色を統一できる
  • ユーザーが任意の値ではなく、厳選された意味のある選択肢から選べる
  • global.css のトークンを変更するだけで、テーマを簡単に更新できる
  • テスト済みの色の組み合わせによって、アクセシビリティが向上する

コメント