iter: d20 progress 支持不确定态
This commit is contained in:
@@ -208,6 +208,14 @@
|
|||||||
"acceptance": "DataTableProps 新增 selected?: Signal<RowKey[]>,与内核选择双向同步(内容比较避免来回派发,外部数组拷贝保护内核);demo 首表传 picked 信号,展示已选计数与「清空选择」按钮;manifest/文档/llms-full.txt 同步;npm run check 全绿",
|
"acceptance": "DataTableProps 新增 selected?: Signal<RowKey[]>,与内核选择双向同步(内容比较避免来回派发,外部数组拷贝保护内核);demo 首表传 picked 信号,展示已选计数与「清空选择」按钮;manifest/文档/llms-full.txt 同步;npm run check 全绿",
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"notes": "复用 page 桥接的同一套思路:两个 effect 各管一向,sameKeys 内容比较收敛;内部写回拷贝 [...internal],防外部改动内核数组;demo 需 import type { RowKey } 才能对齐 Signal 的逆变"
|
"notes": "复用 page 桥接的同一套思路:两个 effect 各管一向,sameKeys 内容比较收敛;内部写回拷贝 [...internal],防外部改动内核数组;demo 需 import type { RowKey } 才能对齐 Signal 的逆变"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d20",
|
||||||
|
"title": "progress 支持不确定态(未知时长加载)",
|
||||||
|
"motivation": "请求时长未知时只能硬编造一个假百分比,或用 spinner 但失去条状形态;不确定态是进度条的标准形态",
|
||||||
|
"acceptance": "ProgressProps.value 改为可选;缺省时渲染不确定态(35% 填充块 1.2s 往复)、不显示百分比、role=progressbar + aria-label=进行中;定量态补 aria-valuemin/max/now;reduced-motion 静态化;demo 加不确定态示例;manifest/文档/llms-full.txt 同步;npm run check 全绿",
|
||||||
|
"status": "done",
|
||||||
|
"notes": "以「不传 value」作为不确定态的开关,不新增布尔参数(少一个可矛盾的状态);定量态的 aria-valuenow 用函数属性随信号更新;reduced-motion 下靠既有 .ua-progress-fill 规则把动画归零,退化为静态 35% 条"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "ui-arch-registry-index/0.1",
|
"$schema": "ui-arch-registry-index/0.1",
|
||||||
"generatedAt": "2026-10-23T09:01:45.831Z",
|
"generatedAt": "2026-10-23T09:02:18.149Z",
|
||||||
"repoRoot": ".",
|
"repoRoot": ".",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
@@ -163,7 +163,7 @@
|
|||||||
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
|
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
|
||||||
"pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达",
|
"pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达",
|
||||||
"spinner(props):加载指示器,size 控制直径",
|
"spinner(props):加载指示器,size 控制直径",
|
||||||
"progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色",
|
"progress(props):进度条,value 信号驱动 0-100(满格切 success 色);不传 value 退化为不确定态无限往复",
|
||||||
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
|
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
|
||||||
"modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区",
|
"modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区",
|
||||||
"drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭",
|
"drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭",
|
||||||
@@ -950,8 +950,7 @@
|
|||||||
{
|
{
|
||||||
"n": "value",
|
"n": "value",
|
||||||
"t": "Signal<number>",
|
"t": "Signal<number>",
|
||||||
"r": 1,
|
"d": "当前进度 0-100 信号,变化自动平滑过渡(越界钳制)"
|
||||||
"d": "进度 0-100 信号,变化自动平滑过渡"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "showText",
|
"n": "showText",
|
||||||
@@ -962,10 +961,12 @@
|
|||||||
],
|
],
|
||||||
"example": "const pct = signal(0); progress({ value: pct }); setInterval(() => pct((pct() + 5) % 105), 400)",
|
"example": "const pct = signal(0); progress({ value: pct }); setInterval(() => pct((pct() + 5) % 105), 400)",
|
||||||
"steps": [
|
"steps": [
|
||||||
|
"时长未知的加载直接 progress() 不传 value:填充块匀速往复,不显示百分比,读屏读作进行中",
|
||||||
"创建数值信号 pct = signal(0),范围 0-100(越界自动钳制)",
|
"创建数值信号 pct = signal(0),范围 0-100(越界自动钳制)",
|
||||||
"传入 value,填充宽度与百分比文字随信号平滑过渡",
|
"传入 value,填充宽度与百分比文字随信号平滑过渡",
|
||||||
"进行中填充带流动条纹,到 100% 自动变 success 色并停止条纹",
|
"进行中填充带流动条纹,到 100% 自动变 success 色并停止条纹",
|
||||||
"不需要百分比文字时传 showText: false"
|
"不需要百分比文字时传 showText: false",
|
||||||
|
"定量进度用 value 信号:满格自动切 success 色并停止条纹,role=progressbar + aria-valuenow 同步"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,3 +24,4 @@
|
|||||||
{"time": "2026-10-23T16:59:46+08:00", "id": "d17", "result": "done", "summary": "表单错误态打通包裹式控件:focusout/change 取代 blur + aria-invalid + .ua-invalid 后代选择器覆盖 select/radio/slider;demo 加必填 select;check 全绿"}
|
{"time": "2026-10-23T16:59:46+08:00", "id": "d17", "result": "done", "summary": "表单错误态打通包裹式控件:focusout/change 取代 blur + aria-invalid + .ua-invalid 后代选择器覆盖 select/radio/slider;demo 加必填 select;check 全绿"}
|
||||||
{"time": "2026-10-23T17:00:55+08:00", "id": "d18", "result": "done", "summary": "ua verify 新增皮肤硬编码颜色门禁(#hex 禁止,rgba 仅限阴影/遮罩),清掉 ui.css 5 处 #fff 改令牌;负向测试确认能拦;check 全绿"}
|
{"time": "2026-10-23T17:00:55+08:00", "id": "d18", "result": "done", "summary": "ua verify 新增皮肤硬编码颜色门禁(#hex 禁止,rgba 仅限阴影/遮罩),清掉 ui.css 5 处 #fff 改令牌;负向测试确认能拦;check 全绿"}
|
||||||
{"time": "2026-10-23T17:01:46+08:00", "id": "d19", "result": "done", "summary": "dataTable 新增 selected 受控信号:与内核选择双向同步(内容比较 + 拷贝保护),demo 展示已选计数与清空;check 全绿"}
|
{"time": "2026-10-23T17:01:46+08:00", "id": "d19", "result": "done", "summary": "dataTable 新增 selected 受控信号:与内核选择双向同步(内容比较 + 拷贝保护),demo 展示已选计数与清空;check 全绿"}
|
||||||
|
{"time": "2026-10-23T17:02:24+08:00", "id": "d20", "result": "done", "summary": "progress 支持不确定态:value 可选,缺省时 35% 填充块往复 + aria-label 进行中;定量态补 aria-valuenow;demo/manifest/llms 同步,check 全绿"}
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ const content = h(
|
|||||||
alert({ message: '警告提示:操作可能存在风险。', variant: 'warning' }),
|
alert({ message: '警告提示:操作可能存在风险。', variant: 'warning' }),
|
||||||
h('div', { class: 'row' }, spinner(), spinner({ size: 26 })),
|
h('div', { class: 'row' }, spinner(), spinner({ size: 26 })),
|
||||||
progress({ value: percent }),
|
progress({ value: percent }),
|
||||||
|
h('div', { class: 'row' }, h('span', { class: 'out' }, '不确定态:'), progress()),
|
||||||
),
|
),
|
||||||
section(
|
section(
|
||||||
'sec-tooltip',
|
'sec-tooltip',
|
||||||
|
|||||||
+9
-7
@@ -1,6 +1,6 @@
|
|||||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||||
|
|
||||||
> 自动生成于 2026-10-23T09:01:45.831Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
> 自动生成于 2026-10-23T09:02:18.149Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
@@ -530,7 +530,7 @@ spinner(); spinner({ size: 26 })
|
|||||||
|
|
||||||
参数:
|
参数:
|
||||||
|
|
||||||
- value(必填):Signal<number> —— 进度 0-100 信号,变化自动平滑过渡
|
- value:Signal<number> —— 当前进度 0-100 信号,变化自动平滑过渡(越界钳制)
|
||||||
- showText(默认 true):boolean —— 是否显示百分比文字;缺省 true
|
- showText(默认 true):boolean —— 是否显示百分比文字;缺省 true
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
@@ -541,10 +541,12 @@ const pct = signal(0); progress({ value: pct }); setInterval(() => pct((pct() +
|
|||||||
|
|
||||||
手把手:
|
手把手:
|
||||||
|
|
||||||
1. 创建数值信号 pct = signal(0),范围 0-100(越界自动钳制)
|
1. 时长未知的加载直接 progress() 不传 value:填充块匀速往复,不显示百分比,读屏读作进行中
|
||||||
2. 传入 value,填充宽度与百分比文字随信号平滑过渡
|
2. 创建数值信号 pct = signal(0),范围 0-100(越界自动钳制)
|
||||||
3. 进行中填充带流动条纹,到 100% 自动变 success 色并停止条纹
|
3. 传入 value,填充宽度与百分比文字随信号平滑过渡
|
||||||
4. 不需要百分比文字时传 showText: false
|
4. 进行中填充带流动条纹,到 100% 自动变 success 色并停止条纹
|
||||||
|
5. 不需要百分比文字时传 showText: false
|
||||||
|
6. 定量进度用 value 信号:满格自动切 success 色并停止条纹,role=progressbar + aria-valuenow 同步
|
||||||
|
|
||||||
现场演示:apps/docs/demo.html#sec-feedback
|
现场演示:apps/docs/demo.html#sec-feedback
|
||||||
|
|
||||||
@@ -742,7 +744,7 @@ API 速览:
|
|||||||
- skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画
|
- skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画
|
||||||
- pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达
|
- pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达
|
||||||
- spinner(props):加载指示器,size 控制直径
|
- spinner(props):加载指示器,size 控制直径
|
||||||
- progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色
|
- progress(props):进度条,value 信号驱动 0-100(满格切 success 色);不传 value 退化为不确定态无限往复
|
||||||
- tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签
|
- tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签
|
||||||
- modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区
|
- modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区
|
||||||
- drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭
|
- drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
- skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画
|
- skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画
|
||||||
- pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达
|
- pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达
|
||||||
- spinner(props):加载指示器,size 控制直径
|
- spinner(props):加载指示器,size 控制直径
|
||||||
- progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色
|
- progress(props):进度条,value 信号驱动 0-100(满格切 success 色);不传 value 退化为不确定态无限往复
|
||||||
- tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签
|
- tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签
|
||||||
- modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区
|
- modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区
|
||||||
- drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭
|
- drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭
|
||||||
|
|||||||
@@ -1,18 +1,37 @@
|
|||||||
import { effect, h } from '@ui-arch/frame';
|
import { effect, h } from '@ui-arch/frame';
|
||||||
import type { ProgressProps } from './types.js';
|
import type { ProgressProps } from './types.js';
|
||||||
|
|
||||||
/*** 进度条:轨道 + 渐变流动填充,value 信号驱动 0-100;满格切换 success 色并停止条纹 ***/
|
/*** 进度条:value 信号驱动 0-100 定量态,缺省 value 则退化为不确定态(无限往复);满格切 success 色并停条纹 ***/
|
||||||
export function progress(props: ProgressProps): HTMLElement {
|
export function progress(props: ProgressProps = {}): HTMLElement {
|
||||||
|
// —— 状态集中声明 ——
|
||||||
|
const value = props.value; // 可选:不传即不确定态
|
||||||
const fill = h('div', { class: 'ua-progress-fill' });
|
const fill = h('div', { class: 'ua-progress-fill' });
|
||||||
const track = h('div', { class: 'ua-progress-track' }, fill);
|
const track = h('div', { class: 'ua-progress-track' }, fill);
|
||||||
const text = h('span', { class: 'ua-progress-text' });
|
const text = h('span', { class: 'ua-progress-text' });
|
||||||
|
const withText = props.showText !== false && !!value; // 不确定态没有百分比可显示
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
fill.classList.add('ua-indeterminate'); // 宽度与往复动画交给 CSS
|
||||||
|
return h('div', { class: 'ua-progress', role: 'progressbar', 'aria-label': '进行中' }, track);
|
||||||
|
}
|
||||||
effect(() => {
|
effect(() => {
|
||||||
const v = clamp(props.value()); // 依赖收集:信号变化自动写回
|
const v = clamp(value()); // 依赖收集:信号变化自动写回
|
||||||
fill.style.width = `${v}%`;
|
fill.style.width = `${v}%`;
|
||||||
fill.classList.toggle('ua-done', v >= 100); // 满格切语义色
|
fill.classList.toggle('ua-done', v >= 100); // 满格切语义色
|
||||||
text.textContent = `${Math.round(v)}%`;
|
text.textContent = `${Math.round(v)}%`;
|
||||||
});
|
});
|
||||||
return h('div', { class: 'ua-progress' }, track, props.showText === false ? null : text);
|
return h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
class: 'ua-progress',
|
||||||
|
role: 'progressbar',
|
||||||
|
'aria-valuemin': '0',
|
||||||
|
'aria-valuemax': '100',
|
||||||
|
'aria-valuenow': () => String(Math.round(clamp(value()))),
|
||||||
|
},
|
||||||
|
track,
|
||||||
|
withText ? text : null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** 进度钳制到 0-100 ***/
|
/*** 进度钳制到 0-100 ***/
|
||||||
|
|||||||
@@ -213,8 +213,8 @@ export interface SpinnerProps {
|
|||||||
|
|
||||||
/*** 进度条入参 ***/
|
/*** 进度条入参 ***/
|
||||||
export interface ProgressProps {
|
export interface ProgressProps {
|
||||||
value: Signal<number>; // 当前进度 0-100 的信号
|
value?: Signal<number>; // 当前进度 0-100 的信号;不传即不确定态(未知时长的加载)
|
||||||
showText?: boolean; // 是否右侧显示百分比;缺省 true
|
showText?: boolean; // 是否右侧显示百分比;缺省 true(不确定态忽略)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** 标签页入参 ***/
|
/*** 标签页入参 ***/
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
|
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
|
||||||
"pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达",
|
"pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达",
|
||||||
"spinner(props):加载指示器,size 控制直径",
|
"spinner(props):加载指示器,size 控制直径",
|
||||||
"progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色",
|
"progress(props):进度条,value 信号驱动 0-100(满格切 success 色);不传 value 退化为不确定态无限往复",
|
||||||
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
|
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
|
||||||
"modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区",
|
"modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区",
|
||||||
"drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭",
|
"drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭",
|
||||||
@@ -821,8 +821,7 @@
|
|||||||
{
|
{
|
||||||
"n": "value",
|
"n": "value",
|
||||||
"t": "Signal<number>",
|
"t": "Signal<number>",
|
||||||
"r": 1,
|
"d": "当前进度 0-100 信号,变化自动平滑过渡(越界钳制)"
|
||||||
"d": "进度 0-100 信号,变化自动平滑过渡"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"n": "showText",
|
"n": "showText",
|
||||||
@@ -833,10 +832,12 @@
|
|||||||
],
|
],
|
||||||
"example": "const pct = signal(0); progress({ value: pct }); setInterval(() => pct((pct() + 5) % 105), 400)",
|
"example": "const pct = signal(0); progress({ value: pct }); setInterval(() => pct((pct() + 5) % 105), 400)",
|
||||||
"steps": [
|
"steps": [
|
||||||
|
"时长未知的加载直接 progress() 不传 value:填充块匀速往复,不显示百分比,读屏读作进行中",
|
||||||
"创建数值信号 pct = signal(0),范围 0-100(越界自动钳制)",
|
"创建数值信号 pct = signal(0),范围 0-100(越界自动钳制)",
|
||||||
"传入 value,填充宽度与百分比文字随信号平滑过渡",
|
"传入 value,填充宽度与百分比文字随信号平滑过渡",
|
||||||
"进行中填充带流动条纹,到 100% 自动变 success 色并停止条纹",
|
"进行中填充带流动条纹,到 100% 自动变 success 色并停止条纹",
|
||||||
"不需要百分比文字时传 showText: false"
|
"不需要百分比文字时传 showText: false",
|
||||||
|
"定量进度用 value 信号:满格自动切 success 色并停止条纹,role=progressbar + aria-valuenow 同步"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -893,6 +893,23 @@
|
|||||||
animation: none;
|
animation: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
/* 不确定态:固定比例填充块匀速往复,宽度与位移都由动画控制 */
|
||||||
|
.ua-progress-fill.ua-indeterminate {
|
||||||
|
width: 35%;
|
||||||
|
transition: none;
|
||||||
|
animation: ua-indeterminate 1.2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
.ua-progress-fill.ua-indeterminate::after {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
@keyframes ua-indeterminate {
|
||||||
|
from {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(285%);
|
||||||
|
}
|
||||||
|
}
|
||||||
@keyframes ua-stripe {
|
@keyframes ua-stripe {
|
||||||
to {
|
to {
|
||||||
background-position: 17px 0;
|
background-position: 17px 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user