canvas-navigation-components について
Drupal Canvas と React プロジェクト向けに、ナビゲーションコンポーネントの分割、データソース選択、アクセシブルなマークアップを案内するスキルです。メニュー、パンくずリスト、静的ナビゲーションの実装方法を扱います。
主な機能
- 01ナビゲーションを領域ごとに分割
- 02メニュー、パンくず、静的データを選択
- 03SWR による Drupal メニュー取得
- 04メニューのプロパティとスロット設定
- 05ナビゲーションのアクセシビリティ指針
活用シーン
- 01再利用可能なメイン・フッターナビの構築
- 02Drupal メニューからリンクを取得
- 03現在のページに応じたパンくずの表示
- 04複数列を含むメガメニューの構成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ drupal-canvas/ skills --skill canvas-navigation-componentsインストール後、Claude Code で/canvas-navigation-componentsを入力して読み込まれたか確認します。
同梱ファイルreferences/data-sources.md
詳細
Canvas ナビゲーションコンポーネント
プロジェクトの種類
このスキルを適用する前に、package.json で @drupal-canvas/headless または @drupal-canvas/headless- で始まる依存関係があるか確認してください。該当するものがある場合は、Canvas Headless のコードベースです。まず canvas-headless を読んでください。以下の分解、命名、アクセシビリティに関するガイダンスは、そのまま適用されます。React コンポーネントでは、Drupal、Workbench、React のヘッドレスプロジェクトで、以下のポータブルなフックと SWR のパターンを使用します。ヘッドレスサーバーコードでは SDK の getClient() を使用し、React を使用しないネイティブコンポーネントでは、フレームワーク標準のデータ読み込みとページコンテキストを使用します。該当する依存関係がない場合は、Canvas レンダリングの React コードベースです。コンポーネントは React(index.jsx/.tsx)であり、このスキルのすべてが記載どおりに適用されます。プロジェクトの種類はこの 2 つのみです。
Canvas に適したナビゲーションを構築します。再利用しやすい名前、明確なプロパティ(variant、menuName)とスロット(ロゴ、ユーティリティ、メガメニュー領域)、正しいデータソース(Drupal メニュー、パンくずリストのコンテキスト、静的データ)、そしてアクセシブルなマークアップを使用します。
このスキルは、以下のスキルに追加で適用されます。
canvas-design-decomposition— コードを書く前に、領域、ツリー、プロパティ/スロットの概要、再利用を優先した命名を検討します。canvas-data-fetching— SWR、useJsonApiClient、メニューのリソースパターン、Workbench のルールを扱います。
続いて、スロットと繰り返し可能なグループについて、canvas-component-metadata、canvas-component-definition(references/naming.md を含む)、canvas-styling-conventions、canvas-component-composability を適用してください。
ワークフロー(順序が重要です)
1. 分解する(必須)
React または component.yml を書き始める前に、canvas-design-decomposition に従い、少なくともフェーズ E(プロパティ/スロット)まで進めてください。
ナビゲーション固有の検討事項:
- クローム(バー、ドロワーのシェル)をリンクリストや任意のカラム(フッター、メガメニュー)から分けます。1 つの巨大なコンポーネントにするのではなく、コンポジションを優先してください。
- リンクグループやカードの繰り返しには、
canvas-component-composability/references/repeatable-content.mdに従って、親+子のパターンを使用します。 - ページ固有の名前ではなく、汎用的な
machineName(main-navigation、footer-navigation)を使用します。配置場所はコンポーネント名ではなく、ページで表現します。 - レイアウトモード(水平、ドロワー、コンパクトなフッター)には**
variant**を検討します。 - ナビゲーションがDrupal メニューからデータを取得する場合は、概要に**
menuNameを追加します(ステップ 2 を参照)。作成者がブロックを組み合わせる場合は、ロゴ、ユーティリティリンク、CTA にスロット**を使用します。
2. データソースを選ぶ
判断表については、references/data-sources.md を参照してください。概要:
| ソース | 使用する場面 |
|---|---|
| Drupal メニュー | 編集者が「構造 → メニュー」でリンクを管理する場合。menu_items と getResource を使用します |
| パンくずリスト | usePageContext() を介して現在のページコンテキストから階層を取得する場合 |
| 静的データ | 例外的な場合に限り使用し、その理由を記載します。適切なデフォルト値またはスロットも用意してください |
3. フェッチを実装する(Drupal メニュー)
canvas-data-fetching のナビゲーション/メニューコンポーネントセクションを使用します。
drupal-canvas/reactのuseJsonApiClient()でclientを読み取ります。useSWR(client && menuName ? ['menu_items', menuName] : null, ([type, id]) => client.getResource(type, id))- データが有効な場合は
Array.from(sortMenu(data))を使用し、それ以外の場合はFALLBACK_LINKSを使用します。利用可能なデータをisLoadingで隠したり、 ドラフトセッションのエラーをフォールバックコンテンツが正常に表示されたかのように 見せかけたりしないでください。 - Workbench やメニューがないサイトでも表示できるよう、必ず
FALLBACK_LINKSを定義します。 - 編集者が Drupal メニューを選択できるようにする場合は、
component.ymlにmenuNameを公開します(マシン名。例:main、footer)。プロパティを指定せず、 JSX でデフォルトのみをハードコーディングするのは、例としては問題ありません。 メニューの切り替えが必要な本番環境のナビゲーションでは、データフェッチのルールに 従ってmenuNameを登録する必要があります。 - 静的プレビューのみを表示するためにフェッチを無効にする場合は、
menuNameを明示的に null に設定します。省略すると、コンポーネントのデフォルトメニューが選択されることがあります。
Workbench のモックに JSON:API のメニューペイロードを捏造してはいけません。実際の 読み込み/エラー/空の状態を優先してください。メニューが空の場合はフォールバックリンクで対応します。
Drupal のメニュー(推奨): 本番環境のナビゲーションは、コード内のハードコードされた
配列だけでなく、Drupal メニュー(CMS)に配置する必要があります。FALLBACK_LINKS
は Workbench/メニューが空の場合に使用するものであり、実際のサイトで CMS メニューの
長期的な代替として使うものではありません。
Acquia Source では、その環境を自動化する際は Source MCP を使用してメニューを作成または
更新することを優先してください。acquia-source-navigation-menus
を参照してください。それ以外の場合は、Drupal の構造 → メニューを使用します。
menu_name をこのコンポーネントの menuName プロパティに合わせてください。
Acquia Source 以外の対象環境では、Drupal 管理画面(またはデプロイプロセス)を使用し、
Source MCP のメニュースキルは適用しないでください。管理画面/MCP にアクセスできない場合は、
作成する必要があるメニューを正確にユーザーに伝えてください(menuName/main、
footer などのマシン名に合わせます)。canvas-data-fetching
と同様に、構造 → メニューへのリンクも記載してください。
4. パンくずリスト
パンくずリストは menu_items ではなく、ページコンテキストから取得します。
drupal-canvas/react の usePageContext() は条件なしで読み込み、その後、ページが null の場合や
breadcrumbs コレクションが空の場合に対応します。フィールドを新たに作る前に、既存の
パターンを確認してください。Workbench ではデフォルトでパンくずリストは空です。ルーティングされた
アプリケーションで実際のページ階層を確認してください。アプリケーションでルーティングを明示的に
適合させる場合を除き、Drupal が生成した URL を保持してください。
5. アクセシビリティ(最低限)
- 主なリンクリストは
<nav>で囲み、固有のaria-labelを指定するか、 可視の見出しテキストを指すaria-labelledbyを指定します。 - モバイル用トグルには
aria-expandedを指定します。ID を設定する場合はaria-controlsも 指定し、ボタンにはtype="button"を指定します。 - すべてのリンクに
aria-current="page"を設定してはいけません。デザイン上必要な場合に限り、 実際の現在の項目に設定します。 - ネストされたリスト(メガメニュー、フッターの列)では、適切な場合にリストのセマンティクスを 保持し、タブ順序が予測可能になるようにします。
6. メタデータとスタイル設定
- Props/slots の YAML:
canvas-component-metadata。 - フォルダーとモック:
canvas-component-definition。 - Tailwind トークン:
canvas-styling-conventions。
参考例
メニュー、SWR、sortMenu を組み合わせた標準例は、
canvas-data-fetching にあります。
エディターで設定するための menuName メタデータも含まれています。
メガメニューとネストされたメニュー
- モデルの構成:親ナビゲーションシェルと、列または注目コンテンツ用のスロット、リンクグループ用の子コンポーネントで構成します。
- ネストされたメニューの形状: 生の JSON:API のネスト構造を前提にしないでください。子要素をマッピングする前に、コンポーネントが使用するものと同じ
JsonApiClient呼び出しで、デシリアライズ後の出力を確認してください(canvas-data-fetchingを参照)。
参考資料
重複の防止
- メニューのコードサンプル全体と
menuNameの YAML は、canvas-data-fetchingの Navigation / Menu Components にあります。 - 分解フェーズ A~G はここでは繰り返しません。代わりに
canvas-design-decompositionを使用してください。