iter: e02 新增 stepper 步骤条组件(三态流转 + active 信号双向绑定 + clickable 回跳)

This commit is contained in:
HIsheR
2026-10-23 17:57:44 +08:00
parent 47bea0b69c
commit fc7a1e8299
13 changed files with 327 additions and 8 deletions
+1
View File
@@ -24,6 +24,7 @@ export { pagination } from './pagination.js';
export { spinner } from './spinner.js';
export { progress } from './progress.js';
export { tabs } from './tabs.js';
export { stepper } from './stepper.js';
export { modal } from './modal.js';
export { drawer } from './drawer.js';
export { form, formItem } from './form.js';
+28
View File
@@ -0,0 +1,28 @@
import { effect, h } from '@ui-arch/frame';
import type { StepperProps } from './types.js';
/*** 步骤条: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; // 卫语句:不可点或未完成不回跳
active(i); if (props.onChange) props.onChange(i); }; // 写回信号并回调
const render = (): HTMLElement => {
const cur = active();
const items = props.steps.map((s, i) => {
const state = i < cur ? 'done' : i === cur ? 'current' : 'upcoming'; // 三态:已完成 / 当前 / 未到
const mark = state === 'done' ? '✓' : String(i + 1); // 完成打勾,其余显示序号
const clickable = !!props.clickable && i < cur; // 仅已完成步骤可回跳
const head = clickable
? h('button', { class: 'ua-step-dot', type: 'button', onClick: () => clickStep(i) }, mark)
: h('span', { class: 'ua-step-dot' }, mark);
const body = h('div', { class: 'ua-step-text' }, h('span', { class: 'ua-step-label' }, s.label),
s.description ? h('span', { class: 'ua-step-desc' }, s.description) : null);
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);
};
let el!: HTMLElement; // 当前渲染产物(effect 首跑赋值)
effect(() => { const next = render(); if (el) el.replaceWith(next); el = next; }); // active 变化整条重渲染(条目少,开销可忽略)
return el;
}
+14
View File
@@ -175,6 +175,20 @@ export interface InputNumberProps {
onChange?: (value: number) => void; // 值变化回调(已夹取到合法区间)
}
/*** 步骤条条目 ***/
export interface StepperItem {
label: string; // 步骤标题
description?: string; // 步骤补充说明;缺省不渲染
}
/*** 步骤条入参 ***/
export interface StepperProps {
steps: StepperItem[]; // 步骤列表(按顺序渲染)
active: Signal<number>; // 当前步索引(0 基),双向绑定(回跳写回、外部赋值同步)
clickable?: boolean; // 已完成步骤是否可点击回跳;缺省 false
onChange?: (index: number) => void; // 步骤切换回调(点击回跳触发)
}
/*** 徽标入参 ***/
export interface BadgeProps {
label: string; // 徽标文案