mcpField
C
canvas-navigation-components

canvas-navigation-components

github.com/drupal-canvas设计与 UI3158 次安装5 周前更新
代码仓库

关于 canvas-navigation-components

面向 Drupal Canvas 与 React 项目的导航组件实现技能,指导组件拆分、数据来源选择和无障碍标记。涵盖 Drupal 菜单、页面面包屑及静态导航的处理方式。

主要功能

  1. 01按区域拆分导航组件
  2. 02选择菜单、面包屑或静态数据
  3. 03使用 SWR 获取 Drupal 菜单
  4. 04配置菜单属性与组件插槽
  5. 05遵循导航无障碍要求

适用场景

  1. 01构建可复用的主导航或页脚导航
  2. 02从 Drupal 菜单加载链接
  3. 03根据当前页面显示面包屑
  4. 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 headless 项目中使用以下可移植的钩子和 SWR 模式。Headless 服务端代码使用 SDK 的 getClient();原生非 React 组件使用框架原生的数据加载和页面上下文。如果不存在此类依赖项,则这是一个 Canvas 渲染的 React 代码库:组件 使用 React(index.jsx/.tsx),本技能中的所有内容均按原样适用。 项目类型只有这两种。

构建适合 Canvas 的导航:使用可复用的名称、清晰的属性 (variant、menuName)和插槽(徽标、实用功能、超级菜单区域), 选择正确的数据源(Drupal 菜单、面包屑上下文或静态数据),并使用 无障碍标记。

本技能需与以下技能配合使用:

  1. canvas-design-decomposition — 在编写代码之前确定区域、树结构、属性/插槽草图,并优先采用可复用命名。
  2. canvas-data-fetching — SWR、 useJsonApiClient、菜单资源模式和 Workbench 规则。

然后应用 canvas-component-metadata、 canvas-component-definition (包括 references/naming.md)、 canvas-styling-conventions 和 canvas-component-composability, 以处理插槽和可重复组。

工作流(顺序很重要)

1. 拆解(必须)

按照 canvas-design-decomposition 至少完成阶段 E(属性/插槽),然后再编写 React 代码或 component.yml。

导航专用提示:

  • 将框架(导航栏、抽屉外壳)与链接列表和可选的 列(页脚、超级菜单)分开。优先采用组合,而不是创建一个包罗万象的组件。
  • 重复的链接组或卡片 → 按 canvas-component-composability/references/repeatable-content.md 采用父组件 + 子组件模式。
  • 使用通用的 machineName(main-navigation、footer-navigation),不要使用 特定页面的名称。将组件在页面中的位置表达在页面上,而不是组件名称中。
  • 在草图中为布局模式(水平、抽屉、紧凑页脚)设计 variant。
  • 如果导航读取Drupal 菜单,请在草图中添加 menuName(见步骤 2)。如果由作者组合这些区块,请使用插槽放置徽标、实用链接或 CTA。
2. 选择数据源

请参阅 references/data-sources.md 中的决策 表。摘要:

来源适用情况
Drupal 菜单编辑者在 Structure → Menus 中管理链接;使用 menu_items + getResource
面包屑通过 usePageContext() 获取当前页面上下文中的导航路径
静态数据少见;请说明原因;仍须提供合理的默认值或插槽
3. 实现获取逻辑(Drupal 菜单)

请参阅 canvas-data-fetching 中的 Navigation / Menu Components 部分:

  • 使用 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 而隐藏可用数据,也不要把草稿会话失败伪装成成功的回退内容。
  • 始终定义 FALLBACK_LINKS,以便 Workbench 和没有该菜单的网站仍能正常渲染。
  • 当编辑者需要选择 Drupal 菜单时,在 component.yml 中公开 menuName(机器名称,例如 main、footer)。示例中仅在 JSX 里硬编码默认值且不提供 prop 是可以的;生产环境中需要切换菜单的导航必须按照数据获取规则注册 menuName。
  • 对于仅静态预览,显式将 menuName 设为 null,以禁用获取逻辑;省略该属性可能会选用组件的默认菜单。

不要在 Workbench mock 中伪造 JSON:API 菜单载荷。优先采用真实的加载/错误/空数据行为;回退链接用于处理菜单为空的情况。

Drupal 中的菜单(首选): 生产环境中的导航应放在 Drupal 菜单(CMS)中,而不应只是在代码中硬编码数组。对于真实网站,FALLBACK_LINKS 用于 Workbench/菜单为空的情况,不能长期替代 CMS 菜单。

在 Acquia Source 上,自动化该环境时,优先使用 Source MCP,通过 acquia-source-navigation-menus 创建或更新菜单;否则请在 Drupal 中使用 Structure → Menus。让 menu_name 与此组件的 menuName prop 保持一致。

对于非 Acquia Source 目标,请使用 Drupal 管理界面(或你的部署流程)——不要应用 Source MCP 菜单技能。如果没有管理界面/MCP 访问权限,请准确告知用户需要创建哪些菜单(与 menuName/机器名称相符,例如 main、footer),并像 canvas-data-fetching 中那样链接到 Structure → Menus。

4. 面包屑

面包屑来自页面上下文,而非 menu_items。始终读取 drupal-canvas/react 中的 usePageContext(),然后处理页面为 null 或 breadcrumbs 集合为空的情况。请先阅读现有模式,再决定是否需要添加字段。Workbench 默认提供空的面包屑;请在路由应用中验证真实的页面路径。除非应用明确适配路由,否则保留 Drupal 生成的 URL。

5. 无障碍(最低要求)
  • 将主要链接列表包在 <nav> 中,并使用不同的 aria-label(或使用 aria-labelledby 指向可见标题文本)。
  • 移动端切换按钮:在接入 ID 时使用 aria-expanded、aria-controls;按钮使用 type="button"。
  • 不要将每个链接都标记为 aria-current="page"——只有在设计需要时,才标记真正的当前项。
  • 对于嵌套列表(大型菜单、页脚列),请在适当情况下保留列表语义;确保 Tab 顺序符合预期。
6. 元数据和样式

参考示例

规范的菜单 + SWR + sortMenu 示例位于 canvas-data-fetching, 其中包含用于编辑器配置的 menuName 元数据。

大型菜单和嵌套菜单

  • 模型组合:父级导航外壳 + 用于列或特色 内容块的插槽;子组件用于链接组。
  • **嵌套菜单结构:**不要假设原始 JSON:API 中存在嵌套结构。在映射 子级之前,使用组件将调用的同一个 JsonApiClient 调用探查反序列化后的 输出(参见 canvas-data-fetching)。

延伸阅读

避免重复

评论

支持 Markdown