diff --git a/.ua/backlog.json b/.ua/backlog.json index 131299d..df7bf01 100644 --- a/.ua/backlog.json +++ b/.ua/backlog.json @@ -308,6 +308,14 @@ "acceptance": "packages/skin/ui 新增 empty.ts:empty({title?, description?, action?}),居中排版,action 为可选 DOM 操作区(常见放按钮);只消费 --ua-* 令牌;导出、manifest、文档、llms-full.txt、README 清单同步;demo 加一节演示;npm run check 全绿", "status": "done", "notes": "empty(props):纯静态组件(无信号),role=status 由读屏播报;装饰符号 ⌀ 弱化为边框色且 aria-hidden;min-height 120px 撑留白(令牌只到 space-4);demo 新增 sec-empty(信号切换有数据/无结果对比,内容用响应式函数渲染);README 同步 32 组件" + }, + { + "id": "e05", + "title": "新增 divider 分隔线组件", + "motivation": "表单分组、卡片内区块、工具栏之间需要统一分隔语义,目前只有 menu 内部私有分隔线,独立场景无组件可用", + "acceptance": "packages/skin/ui 新增 divider.ts:divider({label?, vertical?, dashed?}),水平/垂直两种方向,可带居中文案标签;只消费 --ua-* 令牌;导出、manifest、文档、llms-full.txt、README 清单同步;demo 加一节演示;npm run check 全绿", + "status": "done", + "notes": "divider(props):水平线用 ::before/::after 双线夹 label 居中文案;vertical 单线(伪元素清空,dashed 走 border-left);dashed 水平线 border-top 替代背景色;role=separator + aria-label;demo 新增 sec-divider(文案线/虚线/工具栏竖线三种用法);README 同步 33 组件" } ] -} \ No newline at end of file +} diff --git a/.ua/index.json b/.ua/index.json index 111f47f..271609f 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-23T10:11:22.346Z", + "generatedAt": "2026-10-23T10:14:36.972Z", "repoRoot": ".", "packages": [ { @@ -170,6 +170,7 @@ "stepper(props):步骤条,done/current/upcoming 三态,active 信号双向绑定,clickable 时已完成步骤可回跳", "rate(props):评分星标,value 信号双向绑定,hover 预览移出还原,键盘方向键调节,max 可配", "empty(props):空状态占位,title/description 可选,action 放操作区", + "divider(props):分隔线,水平/垂直两种方向,可带居中文案标签,dashed 切虚线", "modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区", "drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭", "form(props, items):表单容器,布局 + 聚合校验,全部通过才触发 onSubmit", @@ -1210,6 +1211,34 @@ "action 传入 DOM(如 ghost 按钮)引导用户下一步操作" ] }, + { + "id": "divider", + "title": "分隔线 Divider", + "demo": "sec-divider", + "props": [ + { + "n": "label", + "t": "string", + "d": "居中文案标签;缺省纯线条" + }, + { + "n": "vertical", + "t": "boolean", + "d": "是否垂直分隔线(用于行内工具栏);缺省水平" + }, + { + "n": "dashed", + "t": "boolean", + "d": "是否虚线;缺省实线" + } + ], + "example": "divider({ label: '更多信息' }) / divider({ vertical: true })", + "steps": [ + "在区块之间插入 divider 划分内容层次", + "传 label 在水平线上显示居中文案,如「更多信息」", + "工具栏内用 vertical: true 的行内竖线,dashed: true 切虚线弱化分隔感" + ] + }, { "id": "pagination", "title": "分页器 Pagination", diff --git a/.ua/iterations.log b/.ua/iterations.log index 21dc477..6c77e95 100644 --- a/.ua/iterations.log +++ b/.ua/iterations.log @@ -38,3 +38,4 @@ {"ts":"2026-10-23T17:57:31+08:00","id":"e02","result":"done","commit":"fc7a1e8","summary":"新增 stepper 步骤条:三态流转 + active 信号双向绑定 + clickable 回跳,门禁全绿"} {"ts":"2026-10-23T18:03:34+08:00","id":"e03","result":"done","commit":"ee20322","summary":"新增 rate 评分组件:星标点选 + hover 预览 + 键盘方向键调节,信号双向绑定,门禁全绿"} {"ts":"2026-10-23T18:11:46+08:00","id":"e04","result":"done","commit":"fd4ee01","summary":"新增 empty 空状态组件:title/description/action 居中占位,静态零依赖,门禁全绿"} +{"ts":"2026-10-23T18:14:46+08:00","id":"e05","result":"done","commit":"pending","summary":"新增 divider 分隔线组件:水平/垂直 + 居中文案 + 虚线,门禁全绿"} diff --git a/README.md b/README.md index d9f934e..b0c286e 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ npm run demo # 打开演示:apps/demo/dist/demo.html npm run docs # 生成人类文档站 apps/docs/index.html + Agent 全量文档 llms-full.txt ``` -## 组件(共 32 个) +## 组件(共 33 个) -accordion · alert · avatar · badge · breadcrumb · button · card · checkbox · dataTable · drawer · empty · form · inputNumber · menu · modal · pagination · popover · progress · radioGroup · rate · select · skeleton · slider · spinner · stepper · switchButton · tabs · tag · textField · textarea · toast · tooltip +accordion · alert · avatar · badge · breadcrumb · button · card · checkbox · dataTable · divider · drawer · empty · form · inputNumber · menu · modal · pagination · popover · progress · radioGroup · rate · select · skeleton · slider · spinner · stepper · switchButton · tabs · tag · textField · textarea · toast · tooltip -分组:表单(button / textField / inputNumber / textarea / checkbox / switchButton / select / radioGroup / slider / rate / form / formItem)、反馈(alert / toast / spinner / progress / skeleton / badge / empty)、浮层(tooltip / popover / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper)、数据(dataTable / tag / avatar / card)。 +分组:表单(button / textField / inputNumber / textarea / checkbox / switchButton / select / radioGroup / slider / rate / form / formItem)、反馈(alert / toast / spinner / progress / skeleton / badge / empty)、浮层(tooltip / popover / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper)、数据(dataTable / tag / avatar / card)、其他(divider)。 ## 目录 @@ -25,7 +25,7 @@ accordion · alert · avatar · badge · breadcrumb · button · card · checkbo |---|---| | `packages/core/frame` | @ui-arch/frame:signal / computed / effect + hyperscript(无虚拟 DOM) | | `packages/core/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) | -| `packages/skin/ui` | @ui-arch/ui:32 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) | +| `packages/skin/ui` | @ui-arch/ui:33 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) | | `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) | | `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server | | `apps/demo` | 交互演示(esbuild 打包成单文件) | diff --git a/apps/demo/main.ts b/apps/demo/main.ts index c4b7787..623a8bb 100644 --- a/apps/demo/main.ts +++ b/apps/demo/main.ts @@ -9,6 +9,7 @@ import { card, checkbox, dataTable, + divider, drawer, empty, form, @@ -397,6 +398,23 @@ const content = h( ? empty({ title: '暂无匹配结果', description: '试试放宽筛选条件,或清空关键词重新搜索。', action: button({ label: '重置筛选', variant: 'ghost', onClick: () => noResult(false) }) }) : card({ title: '搜索结果' }, h('p', null, '这里展示命中的数据列表。'))), ), + section( + 'sec-divider', + '分隔线', + 'divider:水平线可带居中文案,dashed 切虚线;vertical 行内竖线用于工具栏。', + divider({ label: '更多信息' }), + h('p', null, '分割线上下的内容各自成组。'), + divider({ dashed: true }), + h( + 'div', + { class: 'row' }, + button({ label: '保存', variant: 'ghost' }), + divider({ vertical: true }), + button({ label: '另存为', variant: 'ghost' }), + divider({ vertical: true, dashed: true }), + button({ label: '导出', variant: 'ghost' }), + ), + ), section( 'sec-menu', '下拉菜单', diff --git a/llms-full.txt b/llms-full.txt index 8e0dd29..976212c 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-23T10:11:22.346Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-23T10:14:36.972Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -696,6 +696,28 @@ empty({ title: '暂无数据', description: '调整筛选条件后再试', actio 现场演示:apps/docs/demo.html#sec-empty +### divider — 分隔线 Divider + +参数: + +- label:string —— 居中文案标签;缺省纯线条 +- vertical:boolean —— 是否垂直分隔线(用于行内工具栏);缺省水平 +- dashed:boolean —— 是否虚线;缺省实线 + +示例: + +``` +divider({ label: '更多信息' }) / divider({ vertical: true }) +``` + +手把手: + +1. 在区块之间插入 divider 划分内容层次 +2. 传 label 在水平线上显示居中文案,如「更多信息」 +3. 工具栏内用 vertical: true 的行内竖线,dashed: true 切虚线弱化分隔感 + +现场演示:apps/docs/demo.html#sec-divider + ### pagination — 分页器 Pagination 参数: @@ -874,6 +896,7 @@ API 速览: - stepper(props):步骤条,done/current/upcoming 三态,active 信号双向绑定,clickable 时已完成步骤可回跳 - rate(props):评分星标,value 信号双向绑定,hover 预览移出还原,键盘方向键调节,max 可配 - empty(props):空状态占位,title/description 可选,action 放操作区 +- divider(props):分隔线,水平/垂直两种方向,可带居中文案标签,dashed 切虚线 - modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区 - drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭 - form(props, items):表单容器,布局 + 聚合校验,全部通过才触发 onSubmit diff --git a/llms.txt b/llms.txt index c62d8c2..8def2f9 100644 --- a/llms.txt +++ b/llms.txt @@ -75,6 +75,7 @@ - stepper(props):步骤条,done/current/upcoming 三态,active 信号双向绑定,clickable 时已完成步骤可回跳 - rate(props):评分星标,value 信号双向绑定,hover 预览移出还原,键盘方向键调节,max 可配 - empty(props):空状态占位,title/description 可选,action 放操作区 + - divider(props):分隔线,水平/垂直两种方向,可带居中文案标签,dashed 切虚线 - modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区 - drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭 - form(props, items):表单容器,布局 + 聚合校验,全部通过才触发 onSubmit diff --git a/packages/skin/ui/src/divider.ts b/packages/skin/ui/src/divider.ts new file mode 100644 index 0000000..a5aef21 --- /dev/null +++ b/packages/skin/ui/src/divider.ts @@ -0,0 +1,11 @@ +import { h } from '@ui-arch/frame'; +import type { DividerProps } from './types.js'; + +/*** 分隔线:水平/垂直两种方向,可带居中文案标签,dashed 切虚线 ***/ +export function divider(props: DividerProps): HTMLDivElement { + const cls = ['ua-divider', props.vertical ? 'ua-divider-vertical' : '', props.dashed ? 'ua-divider-dashed' : ''].filter(Boolean).join(' '); + const line = props.label && !props.vertical + ? h('div', { class: cls, role: 'separator', 'aria-label': props.label }, h('span', { class: 'ua-divider-label' }, props.label)) + : h('div', { class: cls, role: 'separator', 'aria-label': props.label }); // 垂直或无标签:纯线条 + return line as HTMLDivElement; +} diff --git a/packages/skin/ui/src/index.ts b/packages/skin/ui/src/index.ts index c1304b7..dd8d25b 100644 --- a/packages/skin/ui/src/index.ts +++ b/packages/skin/ui/src/index.ts @@ -27,6 +27,7 @@ export { tabs } from './tabs.js'; export { stepper } from './stepper.js'; export { rate } from './rate.js'; export { empty } from './empty.js'; +export { divider } from './divider.js'; export { modal } from './modal.js'; export { drawer } from './drawer.js'; export { form, formItem } from './form.js'; diff --git a/packages/skin/ui/src/types.ts b/packages/skin/ui/src/types.ts index a326de2..c94821b 100644 --- a/packages/skin/ui/src/types.ts +++ b/packages/skin/ui/src/types.ts @@ -204,6 +204,13 @@ export interface EmptyProps { action?: unknown; // 操作区内容(常见为按钮);缺省不渲染 } +/*** 分隔线入参 ***/ +export interface DividerProps { + label?: string; // 居中文案标签;缺省纯线条 + vertical?: boolean; // 是否垂直分隔线(用于行内工具栏);缺省水平 + dashed?: boolean; // 是否虚线;缺省实线 +} + /*** 徽标入参 ***/ export interface BadgeProps { label: string; // 徽标文案 diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index e3c76cc..dd222e6 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -41,6 +41,7 @@ "stepper(props):步骤条,done/current/upcoming 三态,active 信号双向绑定,clickable 时已完成步骤可回跳", "rate(props):评分星标,value 信号双向绑定,hover 预览移出还原,键盘方向键调节,max 可配", "empty(props):空状态占位,title/description 可选,action 放操作区", + "divider(props):分隔线,水平/垂直两种方向,可带居中文案标签,dashed 切虚线", "modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区", "drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭", "form(props, items):表单容器,布局 + 聚合校验,全部通过才触发 onSubmit", @@ -1081,6 +1082,34 @@ "action 传入 DOM(如 ghost 按钮)引导用户下一步操作" ] }, + { + "id": "divider", + "title": "分隔线 Divider", + "demo": "sec-divider", + "props": [ + { + "n": "label", + "t": "string", + "d": "居中文案标签;缺省纯线条" + }, + { + "n": "vertical", + "t": "boolean", + "d": "是否垂直分隔线(用于行内工具栏);缺省水平" + }, + { + "n": "dashed", + "t": "boolean", + "d": "是否虚线;缺省实线" + } + ], + "example": "divider({ label: '更多信息' }) / divider({ vertical: true })", + "steps": [ + "在区块之间插入 divider 划分内容层次", + "传 label 在水平线上显示居中文案,如「更多信息」", + "工具栏内用 vertical: true 的行内竖线,dashed: true 切虚线弱化分隔感" + ] + }, { "id": "pagination", "title": "分页器 Pagination", diff --git a/packages/skin/ui/ui.css b/packages/skin/ui/ui.css index 1458428..bd3bf4d 100644 --- a/packages/skin/ui/ui.css +++ b/packages/skin/ui/ui.css @@ -843,6 +843,46 @@ button.ua-step-dot:hover { margin-top: var(--ua-space-1); } +/* —— 分隔线 —— */ +.ua-divider { + display: flex; + align-items: center; + gap: var(--ua-space-3); + margin: var(--ua-space-3) 0; +} +.ua-divider::before, +.ua-divider::after { + content: ''; + flex: 1; + height: 1px; + background: var(--ua-color-border); +} +.ua-divider-dashed::before, +.ua-divider-dashed::after { + background: none; + border-top: 1px dashed var(--ua-color-border); +} +.ua-divider-label { + font-size: var(--ua-font-size-sm); + color: var(--ua-color-text-muted); + white-space: nowrap; +} +.ua-divider-vertical { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 20px; + margin: 0 var(--ua-space-2); +} +.ua-divider-vertical::before, +.ua-divider-vertical::after { + content: none; /* 垂直线:单线无伪元素 */ +} +.ua-divider-vertical.ua-divider-dashed { + background: none; + border-left: 1px dashed var(--ua-color-border); /* 垂直虚线走边框 */ +} + /* —— 徽标 —— */ .ua-badge { display: inline-block;