OwnUI v1.0.0
开始使用
Getting started

快速开始

把三个文件拷进你的项目,按顺序引入即可。不需要构建工具,也不需要任何 npm 依赖。

HTML · 引入顺序不可颠倒
<!-- 1. 设计 Token:颜色 / 字阶 / 间距 / 圆角 / 阴影 / 动效 -->
<link rel="stylesheet" href="library/tokens.css">
<!-- 2. 基础层:重置、排版、布局、工具类 -->
<link rel="stylesheet" href="library/base.css">
<!-- 3. 组件层:全部组件样式 -->
<link rel="stylesheet" href="library/components.css">
<!-- 4. 行为层:弹层、提示、标签页等交互(可选,纯原生) -->
<script src="library/components.js"></script>
两种用法
声明式:写 data 属性即可
<button class="ui-btn ui-btn--primary"
        data-ui="modal" data-target="#demoModal">打开弹窗</button>

<div class="ui-modal" id="demoModal">…</div>
命令式:调 API
UI.toast({ message: '已保存', type: 'success' });
UI.modal.open('#demoModal');
const ok = await UI.confirm({
  title: '确认删除该记录?',
  description: '删除后不可恢复。'
});
与框架集成:所有行为都通过 ui:* 自定义事件对外广播(如 ui:submit、ui:change、ui:sort), 在任意框架里用原生事件监听即可接管,无需为组件库再包一层。
Principles

八条设计原则

组件库不只是样式集合,它约束的是「什么不能妥协」。以下八条是所有组件的验收标准。

状态完备

任何会等待的操作都要有 空 / 加载 / 成功 / 失败 四态,缺一不可上线。

结构稳定

同一流程的四态共用一副骨架,只换内容不换结构,避免页面跳动。

单一主操作

每屏至多一个实心主按钮,第二重要操作降级为描边,第三为幽灵或文字。

Token 唯一来源

组件里不出现字面量色值与魔法数字,换肤只改 L1/L2 变量。

可读性底线

正文对比度 ≥ 4.5:1,大字与非文本元素 ≥ 3:1;状态不靠颜色单独传达。

命中区底线

可点元素实际命中区 ≥ 44×44,视觉尺寸可以更小,但触控区域不变。

即时反馈

操作后 100ms 内必须有可见变化;超过 1 秒要给进度;超过 10 秒要能取消。

错误可行动

错误提示 = 现象 + 原因 + 下一步动作 + 可复制的错误码,禁止只说「操作失败」。

Foundations

设计 Token

三层结构:L1 原始层(色阶与标量)→ L2 语义层(绑定用途,组件只引用这层)→ L3 组件层(绑定槽位)。 换主题只改 L1/L2,组件代码零改动。完整清单见 library/tokens.css 与 library/tokens.json。

中性灰阶(唯一基础色阶,无色相)

n-0
#FFFFFF
n-25
#FCFCFD
n-50
#F7F7F8
n-100
#F1F1F3
n-150
#E7E7EA
n-200
#D9D9DE
n-300
#C1C1C8
n-400
#9C9CA5
n-500
#71717A
n-600
#52525B
n-700
#3F3F46
n-800
#27272A
n-900
#18181B
n-950
#0E0E11

语义色(组件只引用这一层,完整清单见 library/tokens.css)

--ui-primary
主色 · 可配置
primary-hover
400 ~ 700 档
primary-active
再深 / 再浅一档
--ui-primary-weak
主色浅底
--ui-bg
页面画布
--ui-surface
卡片 / 面板
--ui-text
一级文字
--ui-text-2
二级文字
--ui-border
默认描边
control-track
开关轨道 / 灰面
--ui-disabled-bg
禁用底
surface-invert
反色区块
nav-bg-hover
导航 hover 底
nav-bg-active
导航选中底
把 --ui-bg · nav-bg-hover · nav-bg-active 三块放一起看:这三级灰面是刻意拉开的。侧栏选中态一开始复用的是 --ui-primary-weak,而中性主题下它由 --ui-p-50 派生、恰好等于页面底 --ui-bg——两者都是 #F7F7F8,选中项和背景完全融成一片,等于没有选中态。所以「贴在页面底上的选中底」必须单独定义,不能借用主色浅底。

状态色(底 / 主 / 字 三件套,文字用深一档保证对比度)

info 底
字 #0369A1
success 底
字 #15803D
warning 底
字 #B45309
danger 底
字 #B91C1C

字阶(10 阶)

组件库等级
40/48 · bold
页面主标题
32/40 · bold
区块标题
24/32 · bold
卡片标题
20/28 · semibold
条目标题
16/24 · semibold
正文文本,用于说明段落与描述
15/24 · regular
次级正文,用于辅助信息
13/20 · regular
说明与脚注,最小可读字号
12/18 · regular
Overline label
11/16 · semibold · 字距 .1em

间距(4pt 基准)

space-1 · 4
space-2 · 8
space-3 · 12
space-4 · 16
space-5 · 20
space-6 · 24
space-8 · 32
space-10 · 40
space-12 · 48
space-16 · 64

圆角与阴影

4 · xs
8 · sm
12 · md
16 · lg
24 · xl
32 · 2xl
999
shadow-xs
shadow-sm
shadow-md
shadow-lg
shadow-xl

动效、层级与断点

动效
Token值用途
--ui-dur-1100ms按压、即时反馈
--ui-dur-2180ms状态切换、展开收起
--ui-dur-3280ms弹层进出、页面转场
--ui-dur-loop1200ms不确定进度循环
层级
Token值内容
--ui-z-sticky20吸顶栏、侧栏
--ui-z-dropdown60下拉菜单
--ui-z-overlay80遮罩、加载蒙层
--ui-z-modal90模态框、抽屉
--ui-z-toast110轻提示
--ui-z-tooltip120气泡提示、二次确认
断点:480 / 640 / 768 / 1024 / 1280。栅格列数与边距随断点变化,--ui-page-gutter 与 --ui-container 是唯二的布局变量。
Theming

主色配置

默认主题是中性无色:主色等于墨黑,整站呈现灰阶语汇。换品牌色有两条路——右上角开关直接挑一套预设, 或者覆盖 --ui-p-50…900 做自己的色阶。组件样式一行都不用改: 组件引用的是 L2 语义层,L2 引用的是 L1 色阶。

CSS · 用内置预设,或自建一套色阶
/* 方式一:用内置预设。tokens.css 自带 blue / indigo / emerald / orange / violet,
   不写这个属性就是默认的中性墨黑。两种主题、hover/active 方向都已配好。 */
<html data-ui-accent="blue">

/* 方式二:自建色阶。加在 tokens.css 之后即可,档位契约如下。

   选择器特意写成 :root:where([…]) 而不是 :root[…] —— :where() 的权重恒为 0,
   整条选择器只剩 :root 的 0,1,0,刚好低于 tokens.css 里两个深色块(0,2,0)。
   深色块要把下面这三个浅色槽位改指到 --ui-primary-dark-*,权重必须压得住它们。
   若写成 :root[data-ui-accent="brand"](0,2,0),本文件在后就会反过来压住深色块,
   症状是深色模式下 hover 还是那个深蓝、主按钮仍然是白字。 */
:root:where([data-ui-accent="brand"]) {
  --ui-p-50:  #EFF6FF;   /* weak 淡底 */
  --ui-p-100: #DBEAFE;   /* weak hover */
  --ui-p-200: #BFDBFE;   /* weak 边框 */
  --ui-p-300: #93C5FD;
  --ui-p-400: #60A5FA;   /* 深色模式主色 */
  --ui-p-500: #3B82F6;
  --ui-p-600: #2563EB;   /* 主色本身,压白字必须 ≥4.5:1 */
  --ui-p-700: #1D4ED8;   /* hover */
  --ui-p-800: #1E40AF;   /* active */
  --ui-p-900: #172554;   /* 深色模式下的淡底 */

  /* 品牌色状态往"变深"走;墨黑是唯一例外,它往浅处走,否则加深肉眼不可见 */
  --ui-primary-hover:  var(--ui-p-700);
  --ui-primary-active: var(--ui-p-800);
  --ui-primary-text:   var(--ui-n-0);    /* 600 档偏亮时改成 var(--ui-n-950) */

  /* 深色模式不反白,改走上半档浅色以保住色相——墨黑没有色相可保,才整体反白 */
  --ui-primary-dark:            var(--ui-p-400);
  --ui-primary-dark-hover:      var(--ui-p-300);
  --ui-primary-dark-active:     var(--ui-p-200);
  --ui-primary-dark-weak:       var(--ui-p-900);
  --ui-primary-dark-weak-hover: var(--ui-p-800);
  --ui-primary-dark-border:     var(--ui-p-700);
  --ui-primary-dark-text:       var(--ui-n-950);
}
预设主色 / 自定义色值
标签 进行中
上面这排色点、右上角开关、以及窄屏抽屉底部的色点,是同一组选项、同一段状态——点任意一处,三处一起高亮。 联动之所以能成立,是因为它们改的都是 <html> 上的 --ui-p-*: --ui-primary / hover / active / weak / border 全部派生自它,于是按钮、开关、进度、标签自动跟随。 注意作用域:这些声明必须落在 <html> 上,写到某个后代元素上是不生效的—— var() 在声明它的元素上就完成了替换,父级那份早已变成具体色值继承下来。 作用域之外还有一个权重坑:两个深色块(:root[data-ui-theme="dark"] 与 @media 里那条 auto)都是 0,2,0, 它们负责把 hover / active / text 这三个浅色槽位改指到深色槽位。 自己的色阶块若也写成 0,2,0 又放在其后,就会把这份覆盖权抢走,深色模式的 hover 会退回浅色档。 写成 :root:where([…]) 让它只剩 0,1,0 即可 —— 上面代码块与导出的文件都是这么写的。 自定义色值会算出完整的 10 档色阶写到 <html> 的行内样式上; 若所选色值压白字不足 4.5:1,它先改用墨色文字把色相原样留住,只有连墨字也过不了的中间调窄带, 才沿加深方向调整,并明确告诉你改成了什么——不静默改值。 深色模式下预设主色不反白:它走 400 档浅色配深字以保住色相,只有墨黑因为无色相可保才整体反白。
导出这一版主题:调色台与导出面板都搬到首页了——它们是一件事的两半, 放在首屏才拿得到。本节只讲换肤机制。
调色板是自绘的,不是 <input type="color">——后者的系统对话框 拿不到实时预览,样式也不受控。面板里拖动 SV 方块与色相条会边拖边改全站(rAF 节流), 松手才落盘并提示;下面两行对比度读数会实时告诉你引擎最终会用白字还是墨字。 一处刻意的行为:当前色暗到或灰到看不出色相时,一碰色相条会先把它抬进可辨区间 (明度 <35% 抬到 85%,饱和度 <35% 抬到 70%)。否则默认的墨黑明度只有 11%, 拖色相条会毫无反应、看着像坏了。深蓝、翠绿这类正常色不受影响。
Components · Basic

基础组件

按钮、图标按钮、徽章标签、头像。它们是所有界面的最小计量单位,也是状态最密集的一批组件。

按钮 .ui-btn

四档变体 + 三档尺寸,四个变体对应四种操作优先级:实心(每屏至多一个)、默认(白底描边)、幽灵(工具栏与行内)、链接。 任意按钮加 .is-loading 进入加载态,加载时保留原宽度,避免布局跳动。

variants
sizes & composition
default
hover · 底色深一档(墨黑例外:浅一档)
active · 再深一档 + 缩放
focus-visible
disabled
loading
selected
HTML
<button class="ui-btn ui-btn--primary" type="button">主操作</button>
<button class="ui-btn ui-btn--default ui-btn--lg" type="button">次操作 / 大</button>

<!-- 加载态:JS 切换 class,宽度不变 -->
<button class="ui-btn ui-btn--primary is-loading" type="button">提交中</button>

<!-- 可切换按钮用 aria-pressed 表达选中态 -->
<button class="ui-btn ui-btn--default" aria-pressed="true">已选中</button>
契约
项取值说明
variantsprimary · default · ghost · link · danger · danger-outline每屏至多一个 primary
sizessm 32 / md 40 / lg 48(高度)min-width 44 保证命中区
stateshover · active · focus-visible · disabled · loading · selected禁用仍保留命中区与提示
stateDirection品牌色 hover = --ui-p-700,active = --ui-p-800比主色 600 档深一步。中性墨黑是唯一例外(600/500/400 往浅走):近黑再加深只有 10/255 的差,肉眼不可辨
a11y原生 button/a;加载态用 aria-busy 更佳焦点环 2px 主色,offset 2px
图标按钮 .ui-icon-btn

视觉 44×44(含 --sm 的 36×36 视觉,命中区用伪元素撑到 44)。必须提供 aria-label 或 data-tooltip。

icon button
HTML
<button class="ui-icon-btn" type="button" aria-label="设置" data-tooltip="设置">…</button>
徽章、标签与状态点 .ui-badge / .ui-tag / .ui-chip / .ui-status

四者分工:badge 表状态与计数,tag 表归类与筛选,chip 是可移除的已选项,status 是带圆点的状态行。状态一律另附文字或形状,不靠颜色单独传达。

badge 默认 主要 信息 成功 警告 失败 描边胶囊
tag / chip / status 全部 已选中 已选条件 运行中 排队中 异常 已归档
头像 .ui-avatar

支持图片、文字兜底、方形、三档尺寸、在线状态点与头像组堆叠。图片建议 1:1 且不小于 80px。

avatar 张 李 王 产品 陈
A B C +5
HTML
<span class="ui-avatar"><img src="avatar.png" alt="张三"></span>
<span class="ui-avatar">张<span class="ui-avatar__status ui-avatar__status--online"></span></span>
Components · Form

表单组件

表单的一致性最容易腐烂:标签位置、错误位置、必填标记、间距。这里的规则是标签在上、错误在下、间距统一 8px,校验即时触发。

输入框与文本域 .ui-input / .ui-textarea

三档尺寸,聚焦时主色描边 + 3px 浅色外扩环。校验失败用 .is-invalid,并同时提供文字说明,不只靠红色。

input
用于在列表中区分不同项目
仅支持字母、数字与短横线
textarea
支持 Markdown 语法,最多 500 字
输入组与搜索框 .ui-input-group / .ui-search

前后缀、单位、按钮与输入框拼接成一体,聚焦时整组共享焦点环。

input group
https://
元
复选框、单选框与开关 .ui-check / .ui-switch

全部基于原生 input,因此键盘、读屏、表单序列化天然可用;视觉层用兄弟节点绘制,支持选中、半选、禁用与聚焦态。

checkbox / radio
switch
HTML
<label class="ui-check">
  <input type="checkbox" checked>
  <span class="ui-check__box"></span>
  <span class="ui-check__label">选项文字</span>
</label>

<div class="ui-switch">
  <input type="checkbox" id="sw">
  <span class="ui-switch__track"></span>
  <label class="ui-switch__label" for="sw">开关文字</label>
</div>
上传与文件列表 .ui-dropzone / .ui-file

支持点击选择与拖拽投放,拖入时高亮为 .is-dragover;选中的文件通过 ui:file 事件抛出,文件列表由库自动渲染。

点击选择,或把文件拖到这里
支持 PNG、JPG、PDF,单个文件不超过 10 MB
spec-v2.pdf 2.4 MB
HTML + JS
<div class="ui-dropzone" data-ui="dropzone" tabindex="0" role="button">
  <input type="file" multiple hidden>
  <div class="ui-dropzone__title">点击选择,或把文件拖到这里</div>
  <div class="ui-dropzone__hint">支持 PNG、JPG、PDF,单个不超过 10 MB</div>
</div>
<div class="ui-file-list" data-ui-file-list></div>

<script>
  document.querySelector('.ui-dropzone').addEventListener('ui:file', function (e) {
    console.log(e.detail.files);   // FileList 数组,交给你的上传逻辑
  });
</script>
表单布局与即时校验 .ui-form / .ui-form-row / data-ui="validate"

校验规则写在 data-validate 上:required | email | phone | min:6 | max:20 | code。 失焦即校验、输入中实时修正;校验失败会同步 aria-invalid 与 aria-describedby,读屏可感知。 试一下:输入非法手机号后移开焦点。

校验规则
规则含义触发时机
required不能为空失焦 / 提交
email邮箱格式失焦 / 提交
phone11 位手机号失焦 / 提交
min:6 / max:20长度区间失焦 / 提交
code字母数字与短横线失焦 / 提交
Components · Feedback

反馈组件

反馈的层级由「打扰程度」决定:提示条留在页面里,Toast 自动消失,模态框打断操作,抽屉保留上下文。 但凡涉及删除、覆盖等破坏性动作,一律要二次确认,且确认按钮用危险色。

提示条 .ui-alert / .ui-banner

四色语义 + 中性、描边两种低调变体。文案公式:发生了什么 + 为什么 + 下一步做什么。

数据已同步至最新版本
同步发生于 3 分钟前,如需强制刷新请点击列表右上角的刷新按钮。
9 条记录已保存
本月剩余额度不足 10%
额度用尽后接口将返回 429,建议提前升级套餐或调整调用频率。
接口调用失败:签名校验未通过
签名密钥可能已经轮换。请在控制台重新复制密钥后重试,错误码 SIGN_INVALID。
轻提示 UI.toast()

默认 3 秒自动消失,鼠标悬停暂停计时;区域内 aria-live="polite",读屏会朗读。四色语义 + 可选描述行与关闭按钮。

试一下
JS
UI.toast('已复制到剪贴板');
UI.toast({ message: '保存成功', description: '更新了 3 个字段', type: 'success' });
UI.toast({ message: '这条不会自动消失', duration: 0, position: 'bottom' });
// type: info | success | warning | danger
抽屉 .ui-drawer

从右、左、底三个方向滑入,同样具备焦点陷阱与 ESC 关闭。移动端的目录、筛选面板、详情预览常用它。

drawer
气泡提示与二次确认 data-tooltip / .ui-popconfirm

气泡提示作用于 hover 与 focus 两个时机(键盘用户也能看到),自动避让视口边界。 破坏性操作必须走二次确认,确认按钮用危险色,描述里写清后果。

hover / focus 我
HTML
<!-- 气泡提示:鼠标与键盘都能触发 -->
<button class="ui-btn ui-btn--default" data-tooltip="提示文字" data-tooltip-placement="top">…</button>

<!-- 二次确认 -->
<span class="ui-popconfirm-host" data-ui="popconfirm"
      data-popconfirm-title="确认删除该密钥?"
      data-popconfirm-desc="删除后调用会立即失败,且无法恢复。"
      data-popconfirm-ok="删除">
  <button class="ui-btn ui-btn--danger-outline" data-ui="popconfirm-trigger">删除密钥</button>
</span>

<!-- 或命令式:await UI.confirm({ title, description, confirmText }) -->
进度 .ui-progress / .ui-ring

线性、环形、不确定三种形态。确定进度必须带上具体数值或 n/m,不要让用户只看转圈。

24%
68%
完成
重试中
72%
35%
HTML
<div class="ui-progress"><div class="ui-progress__bar" style="width: 68%"></div></div>
<div class="ui-progress is-indeterminate"><div class="ui-progress__bar"></div></div>

<div class="ui-ring" style="--ui-ring-value: 72"><span class="ui-ring__value">72%</span></div>
加载态与骨架屏 .ui-spinner / .ui-skeleton / .ui-loading-veil

骨架屏优于转圈:骨架告诉用户「这里将出现什么」,转圈只告诉他「在等」。 局部刷新用 .ui-loading-veil 蒙层,整页首次加载用骨架屏。

spinner
正在加载第 3 页,共 12 页
skeleton
局部刷新:内容保留,蒙层提示

适用于表格翻页、卡片重新拉取等场景,避免整块内容消失造成位置跳动。

正在更新…
空状态与结果页 .ui-empty / .ui-result

空状态要回答两件事:这里为什么是空的、我该做什么,所以必须有行动按钮,且主行动用主色。 结果页用于任务结束后的收尾:成功给下一步,失败给原因与重试。

还没有创建任何项目

创建项目后可以分配成员、配置密钥并查看调用统计。

提交成功

申请编号 AP-20260924-013,审核结果将在 1 个工作日内发送到你的邮箱。

上传失败

文件超过大小限制。[请更换文件或压缩后重试]。[原文件不受影响,可放心重试]。

错误码 FILE_SIZE_LIMIT
Components · Navigation

导航组件

层级上限三层:主 Tab → 列表 → 详情。每个页面都要有明确的返回路径,不允许死路页面。

侧栏导航 .ui-sidenav

支持分组标题、当前项高亮与右侧徽标。当前项同时改变底色、字重并加一条左侧色轨——不只靠颜色传达状态,色觉障碍下也能定位。

标签页 .ui-tabs

切换时同步 aria-selected 与面板 hidden,支持左右方向键与 Home/End 键切换(无障碍要求)。另有胶囊变体。

共 128 条记录,按创建时间倒序排列。方向键可切换标签,无需鼠标。

列表视图面板

HTML
<div class="ui-tabs" data-ui="tabs">
  <div class="ui-tabs__list" role="tablist">
    <button class="ui-tab" role="tab" id="t1" aria-controls="p1" aria-selected="true">全部</button>
    <button class="ui-tab" role="tab" id="t2" aria-controls="p2" aria-selected="false">处理中</button>
  </div>
  <div class="ui-tabpanel" role="tabpanel" id="p1" aria-labelledby="t1" tabindex="0">…</div>
  <div class="ui-tabpanel" role="tabpanel" id="p2" aria-labelledby="t2" tabindex="0" hidden>…</div>
</div>
分段控件 .ui-segmented

用于 2–5 个互斥选项的轻量切换(时间范围、视图粒度、币种)。等宽变体加 --block。

步骤条 .ui-steps

横向用于短流程(≤5 步),纵向用于带说明的长流程。移动端加 --responsive 自动转纵向并保持骨架一致。

horizontal
提交申请
填写基础信息
资质审核
预计 1 个工作日
3
配置密钥
当前步骤
4
联调上线
沙箱 → 生产
需求沟通
资源匹配 · 方案报价
2
演示体验
样例试跑 · 路径确认
3
商务签约
合同签署 · 结算方式
Components · Data display

数据展示

数字用等宽字形(tabular-nums)避免跳动;表格单元格默认不换行,容器负责横向滚动。

卡片 .ui-card

可组合头部、主体、底部;交互卡加 --interactive(悬停上浮 2px + 阴影),选中加 --selected(主色描边 + 1px 外环)。

基础卡片

头部 + 主体 + 底部三区可自由取舍

新增

主体区域承载主要内容。卡片之间用 24px 间距,内部用 12px 节奏。

可点击卡片

整卡即命中区,悬停有位移反馈,键盘可聚焦

已选中卡片
选中

主色描边 + 1px 外环,同时叠加状态文字,不靠颜色单独传达。

统计卡 .ui-stat

指标名在上、数值在中、趋势在下。数值用 32px 粗体等宽数字,趋势用箭头 + 文字双重表达,不靠颜色单独传达。
.ui-stat__trend--up 表示向好(绿)、--down 表示转差(红)——是"好坏"而非"涨跌"。 做金融/行情类产品时按本地惯例把两者反过来(涨用红、跌用绿)即可,只改这两个类的颜色,不动结构。

今日调用次数
18,204
较昨日 +12.4%
成功率
99.6%
较昨日 -0.3%
平均耗时
128ms
近 7 天无明显波动
剩余额度
1.2万次
本月 30 日重置
HTML
<div class="ui-stat">
  <div class="ui-stat__label">今日调用次数</div>
  <div class="ui-stat__value">18,204</div>
  <div class="ui-stat__trend ui-stat__trend--up">较昨日 +12.4%</div>
</div>
特性卡 .ui-feature

「图标 + 标题 + 说明」的标准组合,用于能力介绍、接入方式、服务保障等并列信息。图标底色跟随主色,换肤自动生效。

接口对接

完整商品、订单与状态接口,附 SDK 与沙箱环境。

成品页面

免开发接入,可直接嵌入现有业务入口。

服务保障

7×24 响应,专属服务群直连对接人。

极速开通

专人对接,最快 1 天内完成上线。

表格 .ui-table

表头吸顶、行悬停高亮、可选斑马纹与紧凑模式;数字列右对齐并用等宽字形。 表头按钮加 data-sort="列号" 即可排序(点表头试试,会派发 ui:sort)。

订单列表,支持按列排序
客户 状态 创建时间 操作
#A-20260924-018 星野科技 ¥ 12,800.00 已完成 09-24 14:22
#A-20260924-017 云图网络 ¥ 3,600.00 处理中 09-24 11:08
#A-20260923-142 恒睿实业 ¥ 48,600.00 已完成 09-23 17:41
#A-20260923-121 锐驰传媒 ¥ 900.00 已取消 09-23 09:15
#A-20260922-097 百川物流 ¥ 24,500.00 已完成 09-22 16:03
HTML
<div class="ui-table-wrap" data-ui="table-sort">
  <table class="ui-table ui-table--striped">
    <thead>
      <tr>
        <th><button class="ui-table__sort" data-sort="0" aria-sort="none">订单号</button></th>
        <th class="ui-table__cell-num">金额</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>#A-018</td><td class="ui-table__cell-num" data-value="12800">¥ 12,800</td></tr>
    </tbody>
  </table>
</div>

<script>
  document.querySelector('[data-ui="table-sort"]').addEventListener('ui:sort', function (e) {
    // 需要服务端排序时在这里发请求;纯前端排序库已内置
    console.log(e.detail.index, e.detail.direction);
  });
</script>
描述列表与列表 .ui-desc / .ui-list

详情页用描述列表(键值对齐),横向列表用于条目管理,交互项悬停变色、命中区 ≥44。

接口详情
接口路径
POST /v1/order/create
鉴权方式
HMAC-SHA256 签名
限流
1000 次 / 分钟
状态
已上线
最近更新
2026-09-20 10:24
  • 李 李工 管理员 最近登录 2 小时前
  • 王 王工 最近登录 3 天前
  • 陈 陈工 尚未登录 待激活
时间线 .ui-timeline

已完成节点用主色实心点 + 主色连线,进行中为空心主色环,未开始为中性描边;状态同时由文字表达。

创建应用 09-22 09:14

由 张明 创建,默认开启沙箱环境

生成生产密钥 09-23 11:02

密钥仅在创建时展示一次,已确认保存

接口联调中 进行中

已完成 8/12 个接口的联通性验证

正式上线 未开始

需完成全部接口验收后触发

折叠面板 .ui-collapse

加 data-accordion 变为手风琴(同时只开一项)。头部高度 52px,键盘可操作。

先确认时间戳与服务器时间差不超过 5 分钟,再核对签名串是否对参数名做了字典序排序。错误码 SIGN_INVALID 会返回期望签名前 8 位,便于比对。
HTML
<div class="ui-collapse" data-ui="collapse">   <!-- 加 data-accordion 变手风琴 -->
  <div class="ui-collapse__item">
    <button class="ui-collapse__header" aria-expanded="true" aria-controls="p1">问题</button>
    <div class="ui-collapse__panel" id="p1">答案</div>
  </div>
</div>
代码块 .ui-codeblock

深色 / 浅色两版,配合 data-ui="copy" 提供一键复制。长代码自动横向滚动。

curl -X POST https://api.example.com/v1/order/create \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"skuId":"1001","quantity":1}'
const res = await fetch('/v1/order/create', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}` },
  body: JSON.stringify({ skuId: '1001' })
});
Components · Layout

布局与区块

区间距用 stack/grid,页面级用 container + section。--ui-container 是唯一的内容宽度来源。

容器与栅格 .ui-container / .ui-grid / .ui-stack

栅格提供 2/3/4 列与自适应两档,列数随 1024、768 断点自动降级;--sidebar 是「侧栏 + 主内容」的两栏模板。

grid
1
2
3
4
侧栏 260px
主内容自适应 · 1024 断点下自动堆叠
HTML
<div class="ui-container">…</div>              <!-- max-width 1200 + 24 边距 -->
<div class="ui-container ui-container--wide">…</div>

<div class="ui-grid ui-grid--3">…</div>          <!-- 3 列,1024 降 2 列,768 降 1 列 -->
<div class="ui-grid ui-grid--auto">…</div>       <!-- 自动填充,最小 240px -->
<div class="ui-grid ui-grid--sidebar">…</div>    <!-- 260px + 自适应 -->

<div class="ui-stack ui-stack--4">…</div>       <!-- 纵向 16px 节奏 -->
<div class="ui-row ui-row--between">…</div>      <!-- 横向两端对齐 -->
Hero 与区块标题 .ui-hero / .ui-section-header

Hero 支持左右分栏(--split),标题最大 20 字一行;区块标题右侧可挂操作区。

Open platform

把权益接入,做到一行代码

统一接口、统一对账、统一售后。自营供应链直供,覆盖点餐、影票、卡券与实物四类福利场景。

接口可用性
99.98%
平均响应
128ms
覆盖场景
4类
合作方
50+
常用工具

按使用频次排序,最近使用的排在最前。

指标条、工具条与 CTA .ui-metrics / .ui-toolbar / .ui-cta

指标条用于四指标并列;工具条承载筛选与批量操作;CTA 是反色区块,内部按钮自动适配反色语境,无需额外类名。

今日订单
1,284
+8.2%
成功率
99.6%
持平
平均耗时
128ms
较上周 -12 ms
告警
2
待处理

准备好开始了吗?

提交接入申请后,我们会安排专人对接,最快 1 天内完成上线。

Patterns

组合示例

组件库的价值在于组合。以下三个区块全部由上面的组件拼成,没有一行业务专属样式。

数据看板区块

区间标题 + 四指标 + 筛选工具条 + 表格 + 分页。骨架从上到下依次是「标题区 → 指标区 → 操作区 → 数据区 → 分页区」。

经营看板

数据每 5 分钟更新一次,最后更新 22:30。

GMV
¥ 328万
+14.2%
订单量
42,180
+6.8%
客单价
¥ 77.8
-1.2%
退款率
0.42%
持平
渠道订单GMV转化率状态
小程序18,240¥ 142.6 万3.8%正常
H5 活动页12,880¥ 98.2 万2.9%正常
公众号7,420¥ 54.1 万2.1%低于预期
线下扫码3,640¥ 33.5 万4.6%正常
共 42,180 条记录
方案对比区

三档方案并列,中间档用 --selected 突出但仍只保留一个实心主按钮——推荐档用实心,其余用描边。

按调用量选择方案

所有方案均含沙箱环境、签名鉴权与 7×24 技术支持。

基础版
¥ 2,980/ 月
  • 月调用 10 万次
  • 4 类权益场景
  • 工单支持
推荐 · 专业版
¥ 9,800/ 月
  • 月调用 50 万次
  • 全部权益场景 + OEM 白标
  • 专属服务群 + 定时对账
旗舰版
按需报价
  • 不限调用量
  • 私有化部署可选
  • 驻场技术对接
流程协作区

步骤条负责「全局进度」,时间线负责「单点动态」,CTA 负责「下一步入口」。三者纵向排列即可构成完整的流程页。

接入进度

当前处于第 2 步,预计还需 1 个工作日。

进行中
提交申请
09-22 完成
2
资质审核
预计 1 个工作日
3
配置密钥
待开始
4
联调上线
待开始
对接人
李
李工 · 解决方案顾问
响应时段 09:00 – 21:00
最近动态
材料提交成功 09-22 09:14

营业执照、法人身份证明已上传

审核中 进行中

通常 1 个工作日内完成,结果通过短信与邮件通知

审核通过后即可生成密钥

密钥仅在创建时展示一次,建议先配置好密钥管理方案。

Quality

无障碍与质量清单

每个组件合并前都要过这份清单;未达标的项不允许进入发布物。

✓
四态齐全

空 / 加载 / 成功 / 失败,且骨架一致

✓
单一主操作

每屏至多一个实心按钮

✓
七态齐全

hover / active / focus / disabled / loading / selected,且状态方向可辨

✓
无硬编码

颜色 / 字号 / 间距全部来自 tokens.css;灰面与反白块也走语义层,深色模式不会漏出亮块

✓
对比度达标

正文 ≥ 4.5:1,#71717A 在白底约 4.8:1

✓
命中区 ≥ 44×44

小尺寸按钮用伪元素撑开触控区

✓
焦点永远可见

2px 主色 outline,全局禁止 outline:none

✓
状态不只靠颜色

同时叠加文字、图标或形状

✓
键盘可达

Tabs 方向键、菜单 Esc、弹层焦点陷阱

✓
动效可降级

prefers-reduced-motion 下瞬间切换

✓
响应式无破版

480 / 768 / 1024 / 1440 均验证

✓
读屏有语义

角色、label、aria-* 与动态播报齐全

交付物清单

文件作用是否可选
library/tokens.css三层设计 Token,唯一的取色来源必需
library/base.css重置、排版、布局、工具类必需
library/components.css全部 40+ 组件样式必需
library/components.js弹层、提示、标签页等行为层,零依赖用到交互组件时必需
library/tokens.jsonToken 导出,供设计工具与跨端对齐可选
docs/index.html本页:组件文档与在线实例可选(不发布可删)