定义
本页确立规范中使用的精确定义。术语有意与框架无关,但我们将在示例中使用 React。
1. 工件分类法
1.1 原语
原语(或无样式组件)是提供行为和可访问性而不包含任何样式的 最低级构建块。
原语完全无样式(即未样式化),封装语义、焦点管理、键盘交互、分层/portal、ARIA 连接、测量及类似关注点。它们提供行为基础,但需要样式才能成为完整的 UI。
示例:
- Radix UI Primitives (Dialog, Popover, Tooltip 等)
- React Aria Components
- Base UI
- Headless UI
期望:
- 完全无样式(headless)。
- 单一职责;可组合为带样式的组件。
- 为其角色提供详尽的 a11y 行为。
- 版本管理偏向稳定;破坏性更改少且有文档说明。
术语 primitive 和 component 在网络上通常交替使用,但它们并不相同。
1.2 组件
组件是为原语添加视觉设计或组合多个元素以创建完整、可用界面元素的带样式、可复用的 UI 单元。
组件仍属于相对低层级,但包含样式,使其可立即在应用中使用。它们通常将未样式的原语用默认视觉设计包装,同时保持可定制性。
示例:
- shadcn/ui components(Radix 原语的样式包装)
- Material UI components
- Ant Design components
期望:
- 清晰的 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-controls、aria-labelledby)。
4.2 键盘映射
组件小部件的文档化键盘交互集合(例如 Tab、Arrow keys、Home/End、Escape)。每个交互组件都要声明并实现键盘映射。
4.3 焦点管理
有关初始焦点、漫游焦点、焦点陷阱以及清理时焦点返回的规则。
5. 分发词汇
5.1 包(注册表分发)
组件/库发布到包注册表(例如 npm)并通过打包器导入。偏向版本化更新和依赖管理。
5.2 复制粘贴(源代码分发)
源代码直接集成到使用者的仓库中(通常通过 CLI)。偏向所有权、自定义和没有额外运行时。
5.3 注册表(目录)
工件(原语、组件、区块、模板)的策展索引,附带元数据、预览和安装/复制说明。注册表不一定是包管理器。
6. 分类启发式
使用此决策流程来命名和定位工件:
- 它是否封装了单一行为或可访问性关注点,且没有样式? → 原语
- 它是否为带样式的、可复用的 UI 元素,为原语添加视觉设计或组合多个元素? → 组件
- 它是否通过有偏好的组合和文案解决具体的产品用例? → 区块
- 它是否为页面/流程提供脚手架,包括路由/提供者和可替换区域? → 模板
- 它是否为经常出现的解决方案的文档,与实现无关? → 模式
- 它是否为易用性/组合提供非视觉逻辑? → 实用工具
7. 非目标与澄清
- Web Components 与 “组件”。在本规范中,“组件”指可复用的 UI 单元(示例以 React 为例)。除非明确说明,否则不意味着 HTML 自定义元素标准。等效原则适用于各框架。
- 小部件。由于含糊,避免使用“widget”一词;使用 component(通用)或 pattern(仅文档)代替。
- 主题 与 样式。主题是样式的参数化(通过 tokens)。样式是具体呈现。组件应支持主题;区块/模板可附带有偏好的样式以及主题化钩子。