定义

本页确立规范中使用的精确定义。术语有意与框架无关,但我们将在示例中使用 React。

1. 工件分类法

1.1 原语

原语(或无样式组件)是提供行为和可访问性而不包含任何样式的 最低级构建块

原语完全无样式(即未样式化),封装语义、焦点管理、键盘交互、分层/portal、ARIA 连接、测量及类似关注点。它们提供行为基础,但需要样式才能成为完整的 UI。

示例:

期望:

  • 完全无样式(headless)。
  • 单一职责;可组合为带样式的组件。
  • 为其角色提供详尽的 a11y 行为。
  • 版本管理偏向稳定;破坏性更改少且有文档说明。

术语 primitive 和 component 在网络上通常交替使用,但它们并不相同。

1.2 组件

组件是为原语添加视觉设计或组合多个元素以创建完整、可用界面元素的带样式、可复用的 UI 单元。

组件仍属于相对低层级,但包含样式,使其可立即在应用中使用。它们通常将未样式的原语用默认视觉设计包装,同时保持可定制性。

示例:

期望:

  • 清晰的 props API;在适用场景下支持受控和非受控用法。
  • 包含默认样式但便于覆盖(classes、tokens、slots)。
  • 完全支持键盘操作并对屏幕阅读器友好(继承自原语)。
  • 可组合(children/slots、render props 或组合子组件)。
  • 可能由原语构建,或通过样式直接实现行为。

1.3 模式

模式是为解决特定 UI/UX 问题而对原语或组件进行的特定组合。

示例:

  • 带内联错误的表单验证
  • 确认破坏性操作
  • 智能提示搜索(Typeahead)
  • 乐观 UI

期望。

  • 描述行为、可访问性、键盘映射和失败模式。
  • 可能包含多个框架的参考实现。

1.4 区块

区块是带有内容脚手架的、面向生产就绪的有偏好组合组件,解决具体的界面用例(通常与产品相关)。区块以可采用速度换取通用性。

示例:

  • 定价表
  • 认证页面
  • 引导步骤器
  • AI 聊天面板
  • 计费设置表单

期望。

  • 强默认值,便于复制粘贴,易于品牌化/主题化。
  • 除布局与协调之外逻辑最小;领域逻辑通过处理器进行存根。
  • 通过 props 接收数据;不会在没有文档化适配器的情况下将数据隐藏在拉取中。

1.5 页面

页面是由多个区块组合而成、面向单一路由的完整视图,用于服务特定的用户目标。页面将区块组合成表示应用中某一目的地的连贯布局。

示例:

  • 登陆页(Hero 区块 + 功能区块 + 定价区块 + 页脚区块)
  • 产品详情页(图像画廊区块 + 产品信息区块 + 评论区块)
  • 仪表盘页面(统计区块 + 图表区块 + 活动提要区块)

期望:

  • 将多个区块组合成单一路由的统一布局。
  • 注重布局和区块协调而非组件级细节。
  • 可能包含用于区块间数据协调的页面特定逻辑。
  • 针对单一 URL/路由自包含;不用于跨路由复用。

1.6 模板

多页面集合或完整站点脚手架,捆绑页面、路由配置、共享布局、全局提供者和项目结构。模板是整个应用或主要应用部分的完整起点。

示例:

  • TailwindCSS Templates
  • shadcnblocks Templates(完整应用外壳)
  • “SaaS 启动器”(认证页面 + 仪表盘页面 + 设置页面 + 营销页面)
  • “电子商务模板”(店面 + 产品页面 + 结账流程 + 管理页面)

期望:

  • 包含具有路由/导航结构的多个页面。
  • 提供全局配置(主题提供者、认证上下文、布局外壳)。
  • 有偏好的项目结构和明确约定。
  • 设计为综合起点;分叉并自定义而不是作为依赖导入。
  • 可能包含构建配置、部署设置和开发工具链。

1.7 实用工具(非视觉)

为开发者易用性或组合导出的辅助工具;不渲染为 UI。

示例:

  • React hooks(useControllableState、useId)
  • 类工具
  • 快捷键辅助
  • 焦点范围

期望。

  • 无副作用(除非有明确文档说明)。
  • 可孤立测试;支持 tree-shaking。

2. API 与组合词汇

2.1 Props API

组件的公共配置面。Props 是稳定的、类型化的,并带有默认值和可访问性影响的文档。

2.2 Children / Slots

供调用者提供结构或内容的占位符。

  • Children(隐式插槽)。位于开/闭标签之间的 JSX。
  • 命名插槽。诸如 icon、footer 的 props,或 <Component.Slot> 子组件。
  • 插槽转发。将 DOM 属性/className/refs 传递到底层元素。

2.3 Render Prop(函数作为子项)

用于委托渲染的函数子项,父组件提供状态/数据。

<ParentComponent data={data}>
  {(item) => (
    <ChildComponent key={item.id} {...item} />
  )}
</ParentComponent>

当父组件必须拥有数据/行为但使用者必须完全控制标记时使用。

2.4 受控 与 非受控

受控非受控 是用于描述组件状态的术语。

受控 组件的值由 props 驱动,并通常触发 onChange 事件(真相来源为父组件)。非受控 组件保持内部状态;可能暴露 defaultValue 和命令式重置。

许多输入应同时支持两者。详见 controlled and uncontrolled state

2.5 Provider / Context

顶层组件,为子树提供共享状态/配置(例如主题、区域设置、活动标签 id)。Provider 的放置位置需有明确文档说明。

2.6 Portal

在 DOM 层级之外渲染 UI 以管理分层/堆叠上下文(例如模态框、弹出框、提示),同时保留可访问性(焦点陷阱、aria-modal、静默背景)。

3. 样式与主题词汇

3.1 无样式(Headless)

实现行为和可访问性但不规定外观。需要使用者提供样式。

3.2 带样式(Styled)

附带默认视觉设计(CSS 类、内联样式或 tokens),但仍便于覆盖(className 合并、CSS 变量、主题化)。

3.3 变体

通过 props 暴露的离散、文档化的样式或行为变体(例如 size="sm|md|lg"tone="neutral|destructive")。变体不是独立组件。

3.4 设计令牌

命名的、与平台无关的值(例如 --color-bg--radius-md--space-2),用于参数化视觉设计并支持主题化。

4. 可访问性词汇

4.1 角色 / 状态 / 属性

用于传达语义的 WAI-ARIA 属性(role="menu")、状态(aria-checked)和关系(aria-controlsaria-labelledby)。

4.2 键盘映射

组件小部件的文档化键盘交互集合(例如 TabArrow keysHome/EndEscape)。每个交互组件都要声明并实现键盘映射。

4.3 焦点管理

有关初始焦点、漫游焦点、焦点陷阱以及清理时焦点返回的规则。

5. 分发词汇

5.1 包(注册表分发)

组件/库发布到包注册表(例如 npm)并通过打包器导入。偏向版本化更新和依赖管理。

5.2 复制粘贴(源代码分发)

源代码直接集成到使用者的仓库中(通常通过 CLI)。偏向所有权、自定义和没有额外运行时。

5.3 注册表(目录)

工件(原语、组件、区块、模板)的策展索引,附带元数据、预览和安装/复制说明。注册表不一定是包管理器。

6. 分类启发式

使用此决策流程来命名和定位工件:

  1. 它是否封装了单一行为或可访问性关注点,且没有样式? → 原语
  2. 它是否为带样式的、可复用的 UI 元素,为原语添加视觉设计或组合多个元素? → 组件
  3. 它是否通过有偏好的组合和文案解决具体的产品用例? → 区块
  4. 它是否为页面/流程提供脚手架,包括路由/提供者和可替换区域? → 模板
  5. 它是否为经常出现的解决方案的文档,与实现无关? → 模式
  6. 它是否为易用性/组合提供非视觉逻辑? → 实用工具

7. 非目标与澄清

  • Web Components 与 “组件”。在本规范中,“组件”指可复用的 UI 单元(示例以 React 为例)。除非明确说明,否则不意味着 HTML 自定义元素标准。等效原则适用于各框架。
  • 小部件。由于含糊,避免使用“widget”一词;使用 component(通用)或 pattern(仅文档)代替。
  • 主题 与 样式。主题是样式的参数化(通过 tokens)。样式是具体呈现。组件应支持主题;区块/模板可附带有偏好的样式以及主题化钩子。