diff --git a/.ua/index.json b/.ua/index.json index ec2308d..0fddc07 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-26T08:09:26.855Z", + "generatedAt": "2026-10-26T08:10:50.397Z", "repoRoot": ".", "packages": [ { @@ -1460,6 +1460,12 @@ "t": "boolean", "d": "已完成步骤是否可点击回跳;缺省 false" }, + { + "n": "direction", + "t": "'horizontal' | 'vertical'", + "df": "'horizontal'", + "d": "排列方向:horizontal 横排连接线在节点之间;vertical 竖排、连接线落在圆点下方,已走完的一段用主色" + }, { "n": "onChange", "t": "(index: number) => void", @@ -1471,7 +1477,8 @@ "steps": [ "用 signal(0) 创建当前步索引,传入 active;索引之前的步骤显示 ✓ 已完成态", "流程推进时外部赋值即可:step(step() + 1),组件三态自动跟随", - "clickable: true 时已完成步骤可点击回跳并写回信号,配合 onChange 同步业务状态" + "clickable: true 时已完成步骤可点击回跳并写回信号,配合 onChange 同步业务状态", + "侧栏或移动端传 direction: 'vertical':圆点成一列、说明文字紧贴右侧,步与步之间由圆点下方的竖线相连(末步不画线,已完成的段用主色标进度)" ] }, { diff --git a/apps/demo/main.ts b/apps/demo/main.ts index 6119d08..b10c22e 100644 --- a/apps/demo/main.ts +++ b/apps/demo/main.ts @@ -582,13 +582,19 @@ const content = h( section( 'sec-stepper', '步骤条', - 'stepper:done/current/upcoming 三态随 active 信号流转,clickable 时点已完成步骤回跳。', + 'stepper:done/current/upcoming 三态随 active 信号流转,clickable 时点已完成步骤回跳;direction=vertical 走竖排。', stepper({ steps: [{ label: '确认订单', description: '收货信息与商品清单' }, { label: '支付', description: '选择支付方式' }, { label: '完成', description: '等待发货' }], active: stepIdx, clickable: true, onChange: (i) => toast.info(`回到第 ${i + 1} 步`), }), + divider({ dashed: true }), + stepper({ // 竖向:侧栏 / 移动端场景,连接线落在圆点下方 + steps: [{ label: '提交申请', description: '10-20 09:12 已提交' }, { label: '资料初审', description: '10-21 14:03 初审通过' }, { label: '终审', description: '等待风控终审' }], + active: signal(2), // 独立信号:演示停在第三步 + direction: 'vertical', + }), h( 'div', { class: 'row' }, diff --git a/llms-full.txt b/llms-full.txt index 8d25641..a3f5836 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-26T08:09:26.855Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-26T08:10:50.397Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -725,6 +725,7 @@ const tab = signal('a'); tabs({ tabs: [{ value: 'a', label: '概览', closable: - steps(必填):StepperItem[] —— 步骤列表,每项 { label, description? } - active(必填):Signal —— 当前步索引(0 基)信号,双向绑定:回跳写回、外部赋值同步 - clickable:boolean —— 已完成步骤是否可点击回跳;缺省 false +- direction(默认 'horizontal'):'horizontal' | 'vertical' —— 排列方向:horizontal 横排连接线在节点之间;vertical 竖排、连接线落在圆点下方,已走完的一段用主色 - onChange(回调):(index: number) => void —— 步骤切换回调(点击回跳触发) 示例: @@ -738,6 +739,7 @@ const step = signal(1); stepper({ steps: [{ label: '下单' }, { label: '支付' 1. 用 signal(0) 创建当前步索引,传入 active;索引之前的步骤显示 ✓ 已完成态 2. 流程推进时外部赋值即可:step(step() + 1),组件三态自动跟随 3. clickable: true 时已完成步骤可点击回跳并写回信号,配合 onChange 同步业务状态 +4. 侧栏或移动端传 direction: 'vertical':圆点成一列、说明文字紧贴右侧,步与步之间由圆点下方的竖线相连(末步不画线,已完成的段用主色标进度) 现场演示:apps/docs/demo.html#sec-stepper diff --git a/packages/skin/ui/src/stepper.ts b/packages/skin/ui/src/stepper.ts index d82049c..949a3bd 100644 --- a/packages/skin/ui/src/stepper.ts +++ b/packages/skin/ui/src/stepper.ts @@ -1,7 +1,7 @@ import { effect, h } from '@ui-arch/frame'; import type { StepperProps } from './types.js'; -/*** 步骤条:done/current/upcoming 三态横向流程指示,clickable 时已完成步骤可点回跳并写回 active 信号 ***/ +/*** 步骤条:done/current/upcoming 三态流程指示(横向 / 竖向),clickable 时已完成步骤可点回跳并写回 active 信号 ***/ export function stepper(props: StepperProps): HTMLElement { const active = props.active; const clickStep = (i: number): void => { if (!props.clickable || i >= active()) return; // 卫语句:不可点或未完成不回跳 @@ -20,7 +20,8 @@ export function stepper(props: StepperProps): HTMLElement { const li = h('li', { class: `ua-step ua-step-${state}`, 'aria-current': state === 'current' ? 'step' : null }, head, body); return li; }); - return h('ol', { class: 'ua-stepper' }, ...items); + const cls = props.direction === 'vertical' ? 'ua-stepper is-vertical' : 'ua-stepper'; // 方向只影响布局类,渲染逻辑共用 + return h('ol', { class: cls }, ...items); }; let el!: HTMLElement; // 当前渲染产物(effect 首跑赋值) effect(() => { const next = render(); if (el) el.replaceWith(next); el = next; }); // active 变化整条重渲染(条目少,开销可忽略) diff --git a/packages/skin/ui/src/types.ts b/packages/skin/ui/src/types.ts index 4d94d48..41aae99 100644 --- a/packages/skin/ui/src/types.ts +++ b/packages/skin/ui/src/types.ts @@ -224,6 +224,7 @@ export interface StepperProps { steps: StepperItem[]; // 步骤列表(按顺序渲染) active: Signal; // 当前步索引(0 基),双向绑定(回跳写回、外部赋值同步) clickable?: boolean; // 已完成步骤是否可点击回跳;缺省 false + direction?: 'horizontal' | 'vertical'; // 排列方向;缺省 horizontal(竖向适合侧栏 / 移动端,连接线走圆点下方) onChange?: (index: number) => void; // 步骤切换回调(点击回跳触发) } diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index d7de390..1497524 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -1331,6 +1331,12 @@ "t": "boolean", "d": "已完成步骤是否可点击回跳;缺省 false" }, + { + "n": "direction", + "t": "'horizontal' | 'vertical'", + "df": "'horizontal'", + "d": "排列方向:horizontal 横排连接线在节点之间;vertical 竖排、连接线落在圆点下方,已走完的一段用主色" + }, { "n": "onChange", "t": "(index: number) => void", @@ -1342,7 +1348,8 @@ "steps": [ "用 signal(0) 创建当前步索引,传入 active;索引之前的步骤显示 ✓ 已完成态", "流程推进时外部赋值即可:step(step() + 1),组件三态自动跟随", - "clickable: true 时已完成步骤可点击回跳并写回信号,配合 onChange 同步业务状态" + "clickable: true 时已完成步骤可点击回跳并写回信号,配合 onChange 同步业务状态", + "侧栏或移动端传 direction: 'vertical':圆点成一列、说明文字紧贴右侧,步与步之间由圆点下方的竖线相连(末步不画线,已完成的段用主色标进度)" ] }, { diff --git a/packages/skin/ui/ui.css b/packages/skin/ui/ui.css index e525bc6..d36dc18 100644 --- a/packages/skin/ui/ui.css +++ b/packages/skin/ui/ui.css @@ -915,6 +915,39 @@ body.ua-col-resizing { padding: 0; list-style: none; } +.ua-stepper.is-vertical { + flex-direction: column; + gap: 0; +} +.ua-stepper.is-vertical .ua-step { + flex: none; + position: relative; + padding: 0 0 var(--ua-space-3); +} +.ua-stepper.is-vertical .ua-step:last-child { + padding-bottom: 0; +} +.ua-stepper.is-vertical .ua-step + .ua-step { + padding-left: 0; /* 横排的左内距在竖排里会让圆点错位 */ +} +.ua-stepper.is-vertical .ua-step + .ua-step::before { + display: none; /* 横排的短横线在竖排里换成圆点下方的长线 */ +} +.ua-stepper.is-vertical .ua-step::after { + content: ''; + position: absolute; + left: 13px; /* 圆点水平中心 */ + top: 30px; + bottom: 2px; + width: 1px; + background: var(--ua-color-border); +} +.ua-stepper.is-vertical .ua-step:last-child::after { + display: none; /* 末步没有下一段可连 */ +} +.ua-stepper.is-vertical .ua-step-done::after { + background: color-mix(in srgb, var(--ua-color-accent) 55%, transparent); /* 已走完的一段用主色,进度一眼可读 */ +} .ua-step { display: flex; align-items: flex-start;