按钮与状态 触发动作、告诉用户「在跑」
FlowButton flowbtn
悬停时圆形色块自中心扩散铺满,左箭头滑入、右箭头滑出,文字右移让位,胶囊收成圆角矩形。把鼠标移上去看。
<!-- 加 data-flow,页面加载后自动升级 -->
<button data-flow>刷新数据</button>
// 或者用 JS 新建 / 升级已有按钮
const b = UIKit.flowButton("刷新数据", { onClick: run });
UIKit.upgradeFlow(document.querySelector("#btnSave"));
UIKit.flowText(b, "已刷新"); // 改文字不能用 textContent=
LoadingState loadst
3×3 像素网格 + 流光标签 + 等宽实时计时。适合 10 秒以上的长任务:转圈只说明「在跑」,这个还回答「跑了多久」。
Drive
Dots
Orbit
<span id="status"></span>
const h = UIKit.busy("#status", "刷新实际数据", "Drive"); // 开始,计时自动走
// ...await fetch(...)
h.stop("已刷新(3 组)"); // 结束:停表 + 写终态文字
// 等价写法:UIKit.idle("#status", "已刷新(3 组)")
// 三种波形:Drive 方块波前 / Dots 圆点波前 / Orbit 绕周长的彗星
// 长任务(分钟级)用 Orbit,高频短任务用 Dots
筛选与选择 都是持有值的控件,看板工具栏三件套
SlideTabs slidetabs
滑块在标签之间移动:悬停先滑过去「预演」,点击才真正切换,移出容器自动归位。做切片器 / 分段控件 / 视图切换。方向键也能切。
全部
含禁用项 · 铺不下时可横滑
<div id="slicer"></div>
const tabs = UIKit.slideTabs("#slicer", {
items: ["全部", "洗地机", "吸尘器"],
value: "全部",
onChange: (value, index) => render(value)
});
tabs.value(); // 当前值
tabs.setValue("吸尘器"); // 程序化赋值,不触发 onChange
tabs.setItems(list, "全部"); // 换一批选项
<!-- 或纯标签声明,自动升级;加 class="fill" 铺满一行等分 -->
<div data-tabs="日,周,月,季,年" data-value="月"></div>
el.addEventListener("uik:change", e => e.detail.value);
SelectBox selectbox
下拉框(持有值的那种):选中项打勾并高亮,选项 ≥12 个自动出搜索框,首字母连打可跳转。第二个是由原生 <select> 升级来的——没 JS 时它就是个能用的下拉框,升级后仍能正常提交表单。
en · cn
<!-- 推荐:原生 select 加 data-select,渐进增强 -->
<select data-select name="lang">
<option value="zh-CN" data-icon="🇨🇳" selected>简体中文</option>
<option value="en" data-icon="🇺🇸">English</option>
</select>
// 选中值会写回原生 select 并派发原生 change,表单照常提交
// 或纯 JS
const sb = UIKit.selectBox("#lang", {
items: [
{ value: "en", label: "English", icon: "🇺🇸" },
{ value: "zh-CN", label: "简体中文", icon: "🇨🇳" }
],
value: "en",
search: "auto", // true / false / "auto"(≥12 项时出搜索框)
onChange: (v, item) => setLang(v)
});
sb.value(); // 当前值
sb.setValue("zh-CN"); // 程序化赋值,不触发 onChange
sb.setItems(list, "en"); // 换一批选项
DateFilter datefilter
日期筛选:日期区间(双月并排)与单日两种模式,左侧快捷区间(本月、近 30 天、本季度…)。方向键可逐日移动,PageUp/Down 翻月。
未选
<button id="range">时间范围</button>
const df = UIKit.dateFilter("#range", {
mode: "range", // 或 "single"
value: ["2026-01-01", "2026-03-31"],
min: "2020-01-01", max: "2026-12-31",
onChange: (v) => reload(v[0], v[1]) // v 是 ["YYYY-MM-DD","YYYY-MM-DD"],清空时为 null
});
df.value(); // 当前值
df.setValue(["2026-04-01","2026-06-30"]); // 不触发 onChange
<!-- 或纯标签声明,用 uik:change 取值 -->
<button data-date-filter="range" data-value="2026-01-01,2026-03-31">时间范围</button>
// 自定义快捷区间 / 禁用某些日子
presets: [{ label: "本财年", get: () => [new Date(2026,3,1), new Date(2027,2,31)] }],
disabledDate: (d) => d.getDay() === 0 // 周日不可选
流程图 自成一套板岩配色,不吃 --uik-accent
FlowDiagram flowdia
系统图 / 流程图:泳道 + 按语义分色的节点 + 正交连线。把鼠标移到节点上看聚焦。位置由你给的 (lane, col) 决定,它不做自动布局。
五套皮:slate 提炼自
archify(MIT),
flat / terminal / blueprint / notion 提炼自
fireworks-tech-graph(MIT)的风格指南 1/2/3/4。换皮只改令牌,走线与交互不动。
slate · archify
<div id="arch"></div>
UIKit.flowDiagram("#arch", {
lanes: [
{ id: "edge", title: "接入层" },
{ id: "svc", title: "服务层" },
{ id: "data", title: "数据层" }
],
nodes: [
{ id: "web", label: "Web 控制台", sub: "React", type: "frontend", lane: "edge", col: 0 },
{ id: "api", label: "API 网关", sub: "Kong", type: "backend", lane: "edge", col: 2, tag: "LB" },
{ id: "calc", label: "测算服务", sub: "Python", type: "backend", lane: "svc", col: 1 },
{ id: "pg", label: "PostgreSQL", sub: "主库", type: "database", lane: "data", col: 1 },
{ id: "mq", label: "任务队列", sub: "Redis", type: "queue", lane: "svc", col: 3 }
],
edges: [
{ from: "web", to: "api", label: "HTTPS" },
{ from: "api", to: "calc", label: "gRPC", type: "emphasis" },
{ from: "calc", to: "pg", label: "SQL", type: "dashed" },
{ from: "calc", to: "mq" },
{ from: "mq", to: "calc", label: "回调" } // 回头线自动绕道
],
onSelect: (n) => console.log(n.id)
});
// 节点 type 共 7 种,决定配色与图例:
// frontend 青 / backend 绿 / database 紫 / cloud 黄 / security 粉 / queue 橙 / external 灰
// 同一泳道内叠多行用 row: 1;拿静态图去贴文档用 handle.svg()
// 换皮:slate(默认)/ flat / terminal / blueprint / notion
UIKit.flowDiagram("#arch", { preset: "blueprint", ...spec });
UIKit.flowDiagramOf("#arch").setPreset("notion"); // 也可以随时换