gpui-kit Tag 组件完全指南:从基础标签到自定义 HSLA 颜色与状态映射
【免费下载链接】gpui-kitRust GUI components for building fantastic cross-platform desktop application by using GPUI.项目地址: https://gitcode.com/GitHub_Trending/gp/gpui-kit
Tag 是 gpui-kit(基于 GPUI 的 Rust 跨平台桌面 GUI 组件库)中一个轻量但灵活的标签组件,用于展示分类、状态、优先级和其他元数据。它体积紧凑、开箱即用,适合在列表、卡片和详情页中高频复用。读完本文,你将掌握 Tag 的全部创建方式(语义变体、预设颜色、自定义颜色)、尺寸与圆角控制,以及如何在状态/分类/优先级等真实业务场景中落地使用。
导入 Tag
Tag 组件定义在componentcrate 中,并通过gpui_kit统一对外导出。推荐从根路径导入:
use gpui_kit::component::tag::Tag;如果同时需要使用预设颜色枚举,可以一并导入:
use gpui_kit::component::{ColorName, tag::Tag};从源码结构看,Tag 位于 crates/component/src/tag.rs,在 crates/component/src/lib.rs 中以pub mod tag;声明,因此两种导入路径均可用。
基础标签:一行代码创建
Tag 的创建方法是静态构造器,直接调用即可得到一个可渲染的组件,配合.child(...)放入标签文本:
Tag::primary().child("Primary") Tag::secondary().child("Secondary") Tag::danger().child("Danger") Tag::success().child("Success") Tag::warning().child("Warning") Tag::info().child("Info")每个构造器对应一种TagVariant枚举变体(见 crates/component/src/tag.rs):
| 构造器 | 对应变体 | 典型用途 |
|---|---|---|
Tag::new() | 默认Secondary | 无特定语义的普通标签 |
Tag::primary() | Primary | 主色强调、主打标签 |
Tag::secondary() | Secondary(默认变体) | 常规分类、次要信息 |
Tag::danger() | Danger | 危险、错误、失败 |
Tag::success() | Success | 成功、完成、通过 |
Tag::warning() | Warning | 警告、待处理、进行中 |
Tag::info() | Info | 中性信息提示 |
注意Tag::new()的默认变体是Secondary(TagVariant上标有#[default]),所以不带任何变体创建的标签会呈现次级样式。
语义变体:与主题色自动联动
语义变体用于表达"含义优先"的视觉语言。与硬编码颜色不同,这些变体的背景色、边框色、前景色全部从当前主题中实时读取,因此切换主题(深色/浅色、自定义主题)时标签会自动跟随:
Tag::primary().child("Featured") Tag::secondary().child("Category") Tag::danger().child("Critical") Tag::success().child("Completed") Tag::warning().child("Pending") Tag::info().child("Information")以 crates/component/src/tag.rs 的实现为证,每种变体的取色逻辑如下:
- 背景色
bg:Primary取cx.theme().primary,其余分别取secondary、danger、success、warning、info; - 边框色
border:除Secondary使用cx.theme().border(中性边框)外,其余语义变体均使用与背景一致的主题色; - 前景色
fg:默认填充态使用对应的*_foreground(如primary_foreground、danger_foreground),保证文字与背景的对比度。
这套映射意味着:你只需声明语义,无需关心具体色值,主题切换、明暗适配都由组件与主题系统(theme::ActiveTheme)协作完成。
Outline 描边风格
当需要弱化填充、突出信息层级时,调用.outline()即可切换为描边风格:
Tag::primary().outline().child("Primary Outline") Tag::secondary().outline().child("Secondary Outline") Tag::danger().outline().child("Error Outline") Tag::success().outline().child("Success Outline")从 crates/component/src/tag.rs 的渲染逻辑可以看到 outline 的两处关键行为:
- 背景变为透明:
bg使用transparent_white(),而非变体色块; - 前景色切换:
fg方法中outline == true时,各语义变体的文字颜色从*_foreground切换为语义色本身(例如Primary的 outline 前景色变为cx.theme().primary),形成"彩色文字 + 同色描边 + 透明底"的轮廓效果。
这与真实仓库中的用法一致,例如 crates/story/src/stories/table_story.rs 用 outline 标签呈现表格中的支付状态:
"Paid" => Tag::success().outline().child(status.to_string()), "Pending" => Tag::warning().outline().child(status.to_string()), "Unpaid" => Tag::danger().outline().child(status.to_string()), _ => Tag::new().child(status.to_string()),尺寸控制
预设尺寸
Tag 实现了Sizabletrait,提供预设尺寸与自定义尺寸两种方式:
Tag::primary().small().child("Small Tag") Tag::primary().child("Medium Tag") // 默认 MediumSizabletrait 定义在 crates/component/src/sizing.rs,提供以下快捷方法:
xsmall()→Size::XSmallsmall()→Size::Smalllarge()→Size::Large- 不调用时默认
Size::Medium
自定义尺寸
use gpui_kit::Size; Tag::primary().with_size(Size::XSmall).child("XSmall") Tag::primary().with_size(Size::Large).child("Large")with_size()接受impl Into<Size>,Size枚举定义于 crates/component/src/sizing.rs,取值包括XSmall、Small、Medium(默认)、Large以及Size(Pixels)(可传px(30.)自定义像素尺寸)。
从 crates/component/src/tag.rs 可以看到尺寸对渲染的实际影响:
- 字体统一为
text_xs(); XSmall/Small时内边距为px_1p5().py_0p5()(更紧凑);- 其余尺寸使用
px_2p5().py_1(); - 尺寸同时影响默认圆角(见下文"圆角控制")。
在 crates/story/src/stories/collapsible_story.rs 中就有.small()紧凑标签的实战示例:Tag::success().small().child("Shipped")。
预设颜色标签
当语义色不够用、需要"按名称选色"时,使用Tag::color(ColorName):
use gpui_kit::component::ColorName; Tag::color(ColorName::Blue).child("Blue Tag") Tag::color(ColorName::Green).child("Green Tag") Tag::color(ColorName::Purple).child("Purple Tag") Tag::color(ColorName::Pink).child("Pink Tag")ColorName定义于 crates/component/src/theme/color.rs,共 21 个可解析名称:White、Black、Neutral、Gray、Red、Orange、Amber、Yellow、Lime、Green、Emerald、Teal、Cyan、Sky、Blue、Indigo、Violet、Purple、Fuchsia、Pink、Rose;ColorName::all()返回其中的 19 个彩色名称(不含White/Black),方便做枚举遍历。
Tag::color()的取色是主题自适应的(见 crates/component/src/tag.rs 与 crates/component/src/tag.rs):
- 浅色主题:背景取色阶
scale(50)、边框取scale(200)、文字取scale(600); - 深色主题:背景取
scale(950)并叠加 50% 透明度、边框取scale(800)叠加 50% 透明度、文字取scale(300)。
这种"同色系不同色阶"的映射让彩色标签在明暗两种主题下都保持可读的对比度,无需手动挑选深浅色。这也是 crates/story/src/stories/tag_story.rs 中遍历ColorName::all()批量渲染彩色标签的实现基础。
自定义 HSLA 颜色
当预设名称无法满足品牌色或一次性配色需求时,使用Tag::custom(color, foreground, border)传入三组 HSLA 颜色:背景色、前景(文字)色、边框色:
use gpui_kit::{hsla, Hsla}; let color = hsla(220.0 / 360.0, 0.8, 0.5, 1.0); let foreground = hsla(0.0, 0.0, 1.0, 1.0); let border = hsla(220.0 / 360.0, 0.8, 0.4, 1.0); Tag::custom(color, foreground, border).child("Custom Color")hsla构造函数接收归一化的 HSLA 参数(色相 H 用 0.0–1.0 表示,因此示例中220.0 / 360.0即色相 220°)。在 crates/component/src/tag.rs 中,custom()将三个颜色打包为TagVariant::Custom { color, foreground, border },渲染时三个通道直接透传(bg用color、border用border、fg用foreground),完全绕开主题映射——这意味着自定义颜色在明暗主题下都会保持你给定的值,适合需要精确品牌色的场景。
在 crates/story/src/stories/tag_story.rs 中也可以看到实际用例,例如用indigo_500()、indigo_50()等辅助函数构造自定义标签。
圆角控制
Tag 提供三种圆角策略:
use gpui_kit::px; Tag::primary().rounded_full().child("Rounded Full") Tag::primary().rounded(px(4.0)).child("Custom Radius") Tag::primary().rounded(px(0.0)).child("Square Tag")- 默认圆角:不调用任何圆角方法时,
XSmall/Small尺寸使用theme().radius / 2.,其余尺寸使用theme().radius(见 crates/component/src/tag.rs),与全局主题的圆角体系保持一致; .rounded(radius):接受任意impl Into<AbsoluteLength>,例如px(4.0)、rems(0.5),完全自定义圆角半径;.rounded_full():实际实现为rounded = rems(1.)(见 crates/component/src/tag.rs),得到一个胶囊形(药丸形)标签。
在 crates/story/src/stories/tag_story.rs 的 "Square" 展示区中,全部变体均通过.rounded(px(0.))渲染为直角方形标签。
常见场景
状态标签
状态信息是 Tag 最典型的应用场景,语义色与业务状态一一对应:
Tag::success().child("Completed") Tag::warning().child("In Progress") Tag::danger().child("Failed") Tag::info().child("Pending Review")仓库中 crates/story/src/stories/table_story.rs 正是这种"状态 → 语义变体"映射的模板,配合.outline()可以进一步降低视觉噪音;crates/story/src/stories/accordion_story.rs 则用Tag::success().outline().child("New")标记新内容。
分类标签
分类信息追求"稳定、可区分",适合把颜色绑定到固定分类上:
Tag::secondary().child("Technology") Tag::color(ColorName::Blue).child("Design") Tag::color(ColorName::Green).child("Development") Tag::color(ColorName::Purple).child("Marketing")设计建议是:为每个分类固定一个ColorName,形成稳定的"分类 → 颜色"映射表,避免同一分类在不同页面出现不同颜色。
优先级标签
优先级用危险程度递增的语义色表达,符合用户的直觉认知:
Tag::danger().child("High Priority") Tag::warning().child("Medium Priority") Tag::secondary().child("Low Priority")API 参考
创建方法
| 方法 | 说明 |
|---|---|
new() | 创建默认变体(Secondary)的标签 |
primary() | 主色标签 |
secondary() | 次级标签 |
danger() | 危险状态标签 |
success() | 成功状态标签 |
warning() | 警告状态标签 |
info() | 信息标签 |
color(ColorName) | 使用预设颜色创建标签(21 个ColorName可选) |
custom(color, fg, border) | 使用自定义 HSLA 颜色创建标签(背景、前景、边框三通道) |
with_variant(TagVariant) | 显式设置任意变体(crates/component/src/tag.rs) |
样式方法
| 方法 | 说明 |
|---|---|
outline() | 使用描边风格(透明背景 + 语义色文字与边框) |
rounded(radius) | 自定义圆角(接受px、rems等AbsoluteLength) |
rounded_full() | 完整圆角,胶囊样式(实现为rems(1.)) |
尺寸方法
| 方法 | 说明 |
|---|---|
small() | 小尺寸标签(Size::Small) |
xsmall() | 更小尺寸标签(Size::XSmall) |
large() | 大尺寸标签(Size::Large) |
with_size(size) | 设置自定义尺寸(接受Size或像素值) |
尺寸方法由Sizabletrait(crates/component/src/sizing.rs)提供,Tag 的默认尺寸为Size::Medium。
渲染与交互实现细节
Tag 通过RenderOncetrait 实现一次性渲染(crates/component/src/tag.rs),核心渲染管线如下:
- 背景色:outline 时为
transparent_white(),否则取变体的bg(cx); - 文字色:取变体的
fg(outline, cx)(outline 会切换前景取色分支); - 边框色:取变体的
border(cx); - 圆角:显式设置的优先,否则按尺寸取主题圆角;
- 基础样式:
flex+items_center+border_1+text_xs+line_height(relative(1.25)),按尺寸施加内边距; - 悬停反馈:自动附加
.hover(|this| this.opacity(0.9)),鼠标悬停时轻微降透明度,提供轻量交互反馈。
同时 Tag 实现了Styled(可继续用链式样式方法细化外观)与ParentElement(可放入任意子元素,而不只是文本,例如文字加图标)。需要说明的是,Tag 默认是纯展示组件,本身不绑定点击等交互行为;如需可点击标签,应在外部包装InteractiveElement并自行注册事件处理。
设计建议
- 状态类信息优先使用语义颜色:success、warning、danger、info 已与主题联动,能随主题自动适配明暗,避免手写颜色;
- 分类标签结合
ColorName做稳定映射:为每个分类固定颜色名称,保证跨页面、跨主题的一致性; - 空间有限时优先使用
small():紧凑场景(如表格单元格、卡片角标)下小尺寸能显著降低视觉负担,XSmall可作为更极限的兜底; - 纯展示标签不应默认承担交互职责:Tag 本身不处理点击;需要交互语义(如可移除、可筛选)时请在外层包装按钮或可交互元素,保持组件单一职责。
总结
Tag 是 gpui-kit 中"小而精"的典型组件:六个语义构造器覆盖绝大多数状态展示,ColorName提供 21 种预设颜色,custom()支持任意 HSLA 三通道配色,outline()、圆角与尺寸控制让它在列表、表格、卡片、详情页之间自由切换形态。结合主题系统自动取色与明暗适配机制,开发者可以用最少的代码获得始终一致、可随主题演进的标签体系。想查看完整可运行示例,可阅读 crates/story/src/stories/tag_story.rs,其中覆盖了默认、Outline、Rounded、Square 与全色板等全部形态。
【免费下载链接】gpui-kitRust GUI components for building fantastic cross-platform desktop application by using GPUI.项目地址: https://gitcode.com/GitHub_Trending/gp/gpui-kit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考