OpenMetadata UI 设计体系解析:Tag 标签组件的规范、令牌与核心组件实现
【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata
导读
Tag 是 OpenMetadata 前端设计体系(位于 openmetadata-ui/src/main/resources/ui/specs/components/tags.md)中负责呈现"可交互元数据标签"的基础组件,覆盖分类标签(classification tags)、术语表术语(glossary terms)与数据层级(tiers)等典型场景。本文以该规范文档为主体,结合仓库中的真实样式源码tags.less、语义令牌定义tokens.css以及 Badge 等兄弟组件规范,系统讲解 Tag 的适用边界、结构解剖、令牌映射、Props/API、交互状态与可复用的 LESS/TSX 实现,帮助你在 OpenMetadata UI 中正确使用并扩展 Tag 组件。
组件定位:什么时候用 Tag,什么时候不该用
规范将 Tag 归类为Base / metadata级别的基础组件,状态为Stable,其组件实现分散在两条技术线上:
- 现代实现:
@openmetadata/ui-core-components包中的Tag、TagGroup、TagList(新增工作); - 遗留实现:Ant Design
Tag与自研tier-tag。
Use when(适用场景):表示可交互的元数据标签——分类标签、术语表术语、数据层级(tier)——这些标签可以被选择(select)、计数(count)或移除(remove)。
Don't use when(不适用场景),规范给出了两条清晰的边界:
- 当 chip 是只读的状态或计数时,应改用 Badge,而非 Tag;
- 当 chip 承担按钮职责时,应改用 Button,而非 Tag。
这与 Badge 规范形成互补:Badge 的定位是"非交互的状态、计数或内联类别标签"(如实体 tier、管道状态、标题旁的项目计数),其明确写着"当 chip 可点击、可移除或可选中时,请使用 Tags"。因此判断口诀可以概括为:可交互 → Tag,纯展示 → Badge,要触发动作 → Button。
Anatomy:Tag 的结构解剖
规范的解剖图(ASCII)展示了 Tag 从左到右的可选部件组合:
┌──────────────────────────────────────┐ │ [☑] ●/avatar Label [count] [×] │ └──────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ └─ close X (removable) │ │ │ └─ count chip (bg-tertiary) │ │ └─ label: font-weight medium │ └─ optional avatar or status dot └─ optional selection checkbox各部件职责如下:
| 部件 | 说明 |
|---|---|
| pill container(胶囊容器) | 承载全部内容的表面,由背景色 +::after伪元素描边构成 |
| checkbox(选择框) | 可选,仅在可选中模式下出现(selectionMode为single/multiple) |
| avatar / dot(头像/状态点) | 可选,置于标签文本前,用于带图标的实体标签或状态指示 |
| label(标签文本) | 核心内容,font-weight: medium(中字重) |
| count chip(计数块) | 可选,使用--om-color-bg-tertiary背景的独立计数块 |
| close X(关闭按钮) | 可选,出现即代表标签可移除,点击触发onClose |
Tokens:Tag 使用的设计令牌
规范强调了一个值得注意的事实:tags.less中真正的--om-*令牌只有圆角(作用在tier-tag上),现代 core-components 的 Tag 将剩余语义映射到全局语义令牌;而遗留的tier-tag仍在使用@purple-*LESS 变量。
在仓库的 tags.less 中可以验证这一描述——遗留样式源码仅有 20 行:
@import (reference) '../variables.less'; .tier-tag { color: @purple-5; background-color: @purple-1; border-color: @purple-5; border-radius: var(--om-radius-md); }规范给出的令牌映射表如下:
| Part(部件) | Token |
|---|---|
| Corner radius(圆角) | --om-radius-md |
| Surface(表面背景) | --om-color-bg-primary |
| Label text(标签文本色) | --om-color-text-secondary |
| Count chip surface(计数块背景) | --om-color-bg-tertiary |
| Hairline outline(细描边) | --om-color-border |
| Focus ring(焦点环) | --om-color-focus-ring |
Tier tint(遗留@purple-1/@purple-5) | --om-color-purple-50/--om-color-purple-700 |
这些令牌的具体取值可以在 tokens.css 中找到定义(均通过var(--xxx, <fallback>)方式级联上游设计令牌,示例取值来自该文件):
--om-radius-md: var(--radius-md, 6px);--om-color-bg-tertiary: var(--color-bg-tertiary, #f5f5f5);--om-color-interactive-selected: var(--color-bg-brand-primary, #eff8ff);--om-color-focus-ring: var(--color-focus-ring, #2e90fa);--om-color-purple-50: var(--color-purple-50, #f4f3ff),--om-color-purple-700: var(--color-purple-700, #5925dc)。
从 Radius 基础规范 看,--om-radius-md为 6px(用于按钮),--om-radius-sm为 4px(用于输入框、小型控件、tags),这与 Tag 结构中使用--om-radius-sm修饰计数块的示例一致;而 Badge 这类"胶囊"则使用--om-radius-full(9999px)。圆角统一走令牌而非裸写border-radius像素值,是 Radius 规范 中明确的硬性约束,yarn token-audit会把裸的border-radius值标记为警告。
Props / API:core-components 的 Tag 与 TagGroup
规范的 API 表格定义了现代实现TagGroup/Tag的完整属性契约:
| Prop | 取值/说明 |
|---|---|
TagGroup.label | string,aria-label,必填(无障碍标签) |
TagGroup.selectionMode | none、single、multiple |
TagGroup.size | sm、md、lg |
Tag.id | string,需要选择/关闭功能时必填 |
Tag.count | number,渲染计数块 |
Tag.avatarSrc/Tag.dot | 前置头像或状态点 |
Tag.isDisabled | boolean |
Tag.onClose | (id: string) => void,传入后渲染关闭 X |
几点实现层面的解读:
TagGroup.label是必填项:TagGroup 在语义上是一个可聚焦的"标签组",必须提供aria-label供读屏软件识别,这也是 UI 无障碍规范的一部分;Tag.id与选择/关闭强绑定:由于selectionMode支持单选/多选,onClose回调签名是(id: string) => void,因此每个 Tag 必须有稳定的id才能被组内区分;count与avatarSrc/dot是二选一的附加部件:计数块与头像/状态点互不冲突,均作为 label 之外的增强信息呈现。
States:Tag 的六种交互状态
| State | Treatment(处理方式) |
|---|---|
| Default(默认) | --om-color-bg-primary背景 +::after上的--om-color-border描边 |
| Hover(悬停) | 关闭 X 表面出现色调;可选中的行高亮 |
| Selected(选中) | 复选框勾选;--om-color-interactive-selected表面色 |
| Focus(聚焦) | --om-color-focus-ring焦点环,2px 宽度、2px 偏移 |
| Disabled(禁用) | 变暗(dimmed),cursor: not-allowed |
规范附带了一条重要的实现约束(以引用块强调):
描边放在
::after上、焦点用outline—— 永远不要用tw:ring-*。
这条约束的目的是保证焦点环不改变布局(outline不占文档流)、描边可通过伪元素灵活控制圆角裁切,同时避免 Tailwind 的 ring 实现与设计令牌体系冲突。这属于"层级 3(组件样式)只允许引用层级 2 令牌"原则的具体体现——组件内部组合令牌、但不再引入新的原始像素值或框架专有写法。
Code example:可复用的实现示例
样式层(LESS,Layer 3 组件样式只引用 Layer 2 令牌)
/* Layer 3 — component styles reference Layer 2 tokens only */ .custom-tag { border-radius: var(--om-radius-md); font-weight: var(--om-font-weight-medium); background: var(--om-color-bg-primary); color: var(--om-color-text-secondary); outline: 1px solid var(--om-color-border); outline-offset: -1px; .tag-count { background: var(--om-color-bg-tertiary); border-radius: var(--om-radius-sm); } &.tier-tag { background: var(--om-color-purple-50); color: var(--om-color-purple-700); } }要点说明:
- 根容器使用
border-radius: var(--om-radius-md)(6px),与tier-tag在 tags.less 中的圆角取值保持一致; - 计数块
.tag-count使用--om-radius-sm(4px),呼应 Radius 规范 中"tags 用小圆角"的指引; - 描边通过
outline实现并配合outline-offset: -1px,与规范"描边在::after/outline上、不用 ring"的约束一致; &.tier-tag分支把遗留@purple-*的视觉语义(浅紫底@purple-1、深紫字@purple-5)迁移到--om-color-purple-50/--om-color-purple-700令牌,实现"遗留样式 → 令牌化"的渐进改造路径。
组件层(TSX,core-components)
import { Tag, TagGroup, TagList } from '@openmetadata/ui-core-components'; <TagGroup label={t('label.tag-plural')} selectionMode="multiple"> <TagList> <Tag count={3} id="pii" onClose={onRemove}>{t('label.pii')}</Tag> </TagList> </TagGroup>;要点说明:
TagGroup承担标签组的容器与选择语义,label传入国际化后的aria-label(示例使用t('label.tag-plural')国际化函数);TagList作为子元素集合包裹实际Tag;- 示例中的
pii标签携带count={3}(展示 3 个相关项)与onClose={onRemove}(渲染可移除的关闭 X),并处于multiple多选模式——完整覆盖了"可选中、可计数、可移除"三大核心交互能力。
与设计体系其他部分的关系
Tag 不是孤立组件,规范末尾给出了明确的交叉引用关系:
- 同级组件:Badge(只读状态/计数,与 Tag 互斥使用)、Card(卡片容器,可在内部承载 Tag 列表)、Button(触发动作,不可冒充 Tag);
- Foundation 基础层:Color(语义色板,Tag 的选中/焦点/表面色均取自语义色)、Radius(圆角刻度,
md用于主体、sm用于计数块)、Typography(font-weight-medium的文本层级)。
从整个设计体系的视角看,Tag 属于典型的"语义令牌消费者"组件:它本身只在 tags.less 中保留了极少量的--om-*令牌(圆角),其余全部通过 core-components 映射到--om-color-*语义令牌。这种"组件样式 → 语义令牌 → 基础令牌 → 上游设计变量"的分层结构(在 tokens.css 中以var(--xxx, <fallback>)逐级级联),正是 OpenMetadata UI 设计体系保证跨主题、跨版本一致性的关键机制——当你需要自定义业务标签样式时,遵循"只引用--om-*令牌、不写裸像素值、描边用 outline/::after"三条规则,即可与现有体系无缝对齐。
【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考