iter: b03 新增 skeleton 骨架屏组件(三形状占位 + 扫光 + reduced-motion 兜底)
This commit is contained in:
+2
-2
@@ -22,8 +22,8 @@
|
||||
"title": "新增 skeleton 骨架屏组件",
|
||||
"motivation": "异步加载占位是数据表格与卡片的标配,配合 dataTable 空状态形成完整加载体验",
|
||||
"acceptance": "新增 skeleton.ts:skeleton({variant: 'text'|'rect'|'circle', rows?}),呼吸/扫光微动画 + prefers-reduced-motion 静态化,只消费 --ua-* 令牌;导出、manifest、文档、llms-full.txt 同步;demo 页加一节演示;npm run check 全绿",
|
||||
"status": "open",
|
||||
"notes": ""
|
||||
"status": "done",
|
||||
"notes": "skeleton({variant, rows}):text(多行,末行缩短)/ rect / circle 三形状,扫光动画(::after 位移 + 渐变),reduced-motion 下静态灰块(动画列表已补 .ua-skeleton 与 ::after);demo 新增 sec-skeleton 卡片组合演示"
|
||||
},
|
||||
{
|
||||
"id": "b04",
|
||||
|
||||
+29
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "ui-arch-registry-index/0.1",
|
||||
"generatedAt": "2026-10-23T07:49:42.422Z",
|
||||
"generatedAt": "2026-10-23T07:52:40.603Z",
|
||||
"repoRoot": ".",
|
||||
"packages": [
|
||||
{
|
||||
@@ -130,7 +130,7 @@
|
||||
{
|
||||
"name": "@ui-arch/ui",
|
||||
"type": "skin-dom",
|
||||
"description": "DOM 皮肤组件库:button / textField / textarea / checkbox / switch / select / radioGroup / card / badge / alert / toast / tooltip / spinner / progress / tabs / modal / form / formItem / dataTable,构建在 @ui-arch/frame 与 @ui-arch/table-core 之上,样式只消费 --ua-* 令牌。",
|
||||
"description": "DOM 皮肤组件库:button / textField / textarea / checkbox / switch / select / radioGroup / card / badge / alert / toast / tooltip / skeleton / spinner / progress / tabs / modal / form / formItem / dataTable,构建在 @ui-arch/frame 与 @ui-arch/table-core 之上,样式只消费 --ua-* 令牌。",
|
||||
"tags": [
|
||||
"components",
|
||||
"dom",
|
||||
@@ -154,6 +154,7 @@
|
||||
"alert(props):提示条,variant = info | success | warning | danger",
|
||||
"toast.info/success/warning/error(message, duration?):消息提示工厂,右上角堆叠,默认 3s 自动消失,出入场微动画;showToast(props) 为完整入参版本",
|
||||
"tooltip(props, trigger):悬浮提示,包裹触发器,hover / focus 延迟 150ms 出场,移出 / 失焦 / Esc 收起",
|
||||
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
|
||||
"spinner(props):加载指示器,size 控制直径",
|
||||
"progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色",
|
||||
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
|
||||
@@ -176,6 +177,7 @@
|
||||
"AlertProps",
|
||||
"ToastProps",
|
||||
"TooltipProps",
|
||||
"SkeletonProps",
|
||||
"SpinnerProps",
|
||||
"ProgressProps",
|
||||
"TabsProps",
|
||||
@@ -194,7 +196,7 @@
|
||||
"语义色 variant 四档:default|info / success / warning / danger,一律来自令牌,禁止硬编码颜色"
|
||||
],
|
||||
"docs": {
|
||||
"intro": "18 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。",
|
||||
"intro": "19 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。",
|
||||
"steps": [
|
||||
"安装依赖:pnpm add @ui-arch/ui @ui-arch/frame(workspace 内自动链接)",
|
||||
"引入样式:在应用入口 import '@ui-arch/ui/ui.css',暗色主题在根元素设 data-theme='dark'",
|
||||
@@ -489,6 +491,30 @@
|
||||
"传入 message 即可,入场自带下滑动画"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "skeleton",
|
||||
"title": "骨架屏 Skeleton",
|
||||
"demo": "sec-skeleton",
|
||||
"props": [
|
||||
{
|
||||
"n": "variant",
|
||||
"t": "'text' | 'rect' | 'circle'",
|
||||
"d": "占位形状;缺省 rect(整块矩形)"
|
||||
},
|
||||
{
|
||||
"n": "rows",
|
||||
"t": "number",
|
||||
"d": "text 形状的行数;缺省 3,末行自动缩短模拟段落"
|
||||
}
|
||||
],
|
||||
"example": "skeleton({ variant: 'text', rows: 3 }); skeleton({ variant: 'circle' }); skeleton({ variant: 'rect' })",
|
||||
"steps": [
|
||||
"数据加载期间用 skeleton 顶替真实内容,加载完成后整体替换",
|
||||
"文本段落用 variant: 'text' + rows 控制行数,头像用 'circle',卡片/图片区域用 'rect'",
|
||||
"占位块自带扫光动画,reduced-motion 用户自动静态化为纯灰块",
|
||||
"组合布局:skeleton 是普通 DOM,可放进 card / row 等任意容器"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "toast",
|
||||
"title": "消息提示 Toast",
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
{"time":"2026-10-23T15:47:00+08:00","id":"b01","result":"done","summary":"新增 tooltip 悬浮提示组件(包裹式 API / 150ms 延迟 / Esc 收起 / reduced-motion 兜底),同步 manifest + llms-full.txt + demo 区块,并修复 ua style 对 URL 中 // 的误判;npm run check 全绿"}
|
||||
{"time":"2026-10-23T15:50:03+08:00","id":"b02","result":"done","summary":"新增 toast 消息提示组件:四语义工厂 + showToast,右上角堆叠,默认 3s 自动消失,微动画 + reduced-motion 兜底;manifest/docs/llms 同步,check 全绿"}
|
||||
{"time":"2026-10-23T15:53:33+08:00","id":"b03","result":"done","summary":"新增 skeleton 骨架屏组件:text/rect/circle 三形状 + 扫光微动画 + reduced-motion 静态化;manifest/docs/llms/demo 同步,check 全绿"}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
progress,
|
||||
radioGroup,
|
||||
select,
|
||||
skeleton,
|
||||
spinner,
|
||||
switchButton,
|
||||
tabs,
|
||||
@@ -139,6 +140,16 @@ const app = h(
|
||||
button({ label: '信息(1.5s)', onClick: () => toast.info('已同步云端', 1500) }),
|
||||
),
|
||||
),
|
||||
section(
|
||||
'sec-skeleton',
|
||||
'骨架屏',
|
||||
'skeleton 占位:text 多行段落 / rect 块 / circle 圆,扫光微动画,reduced-motion 自动静态化。',
|
||||
card(
|
||||
{ title: '加载中的用户资料' },
|
||||
h('div', { class: 'row' }, skeleton({ variant: 'circle' }), skeleton({ variant: 'text', rows: 2 })),
|
||||
skeleton({ variant: 'rect' }),
|
||||
),
|
||||
),
|
||||
section(
|
||||
'sec-formlab',
|
||||
'表单校验',
|
||||
|
||||
+25
-2
@@ -1,6 +1,6 @@
|
||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||
|
||||
> 自动生成于 2026-10-23T07:49:42.422Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 自动生成于 2026-10-23T07:52:40.603Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||
|
||||
## 快速上手
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
## @ui-arch/ui(skin-dom)v0.1.0
|
||||
|
||||
18 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。
|
||||
19 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。
|
||||
|
||||
### button — 按钮 Button
|
||||
|
||||
@@ -260,6 +260,28 @@ alert({ message: '操作可能存在风险', variant: 'warning' })
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-feedback
|
||||
|
||||
### skeleton — 骨架屏 Skeleton
|
||||
|
||||
参数:
|
||||
|
||||
- variant:'text' | 'rect' | 'circle' —— 占位形状;缺省 rect(整块矩形)
|
||||
- rows:number —— text 形状的行数;缺省 3,末行自动缩短模拟段落
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
skeleton({ variant: 'text', rows: 3 }); skeleton({ variant: 'circle' }); skeleton({ variant: 'rect' })
|
||||
```
|
||||
|
||||
手把手:
|
||||
|
||||
1. 数据加载期间用 skeleton 顶替真实内容,加载完成后整体替换
|
||||
2. 文本段落用 variant: 'text' + rows 控制行数,头像用 'circle',卡片/图片区域用 'rect'
|
||||
3. 占位块自带扫光动画,reduced-motion 用户自动静态化为纯灰块
|
||||
4. 组合布局:skeleton 是普通 DOM,可放进 card / row 等任意容器
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-skeleton
|
||||
|
||||
### toast — 消息提示 Toast
|
||||
|
||||
参数:
|
||||
@@ -469,6 +491,7 @@ API 速览:
|
||||
- alert(props):提示条,variant = info | success | warning | danger
|
||||
- toast.info/success/warning/error(message, duration?):消息提示工厂,右上角堆叠,默认 3s 自动消失,出入场微动画;showToast(props) 为完整入参版本
|
||||
- tooltip(props, trigger):悬浮提示,包裹触发器,hover / focus 延迟 150ms 出场,移出 / 失焦 / Esc 收起
|
||||
- skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画
|
||||
- spinner(props):加载指示器,size 控制直径
|
||||
- progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色
|
||||
- tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
## @ui-arch/ui (v0.1.0)
|
||||
|
||||
- 类型: skin-dom · 目录: packages/skin/ui
|
||||
- 描述: DOM 皮肤组件库:button / textField / textarea / checkbox / switch / select / radioGroup / card / badge / alert / toast / tooltip / spinner / progress / tabs / modal / form / formItem / dataTable,构建在 @ui-arch/frame 与 @ui-arch/table-core 之上,样式只消费 --ua-* 令牌。
|
||||
- 描述: DOM 皮肤组件库:button / textField / textarea / checkbox / switch / select / radioGroup / card / badge / alert / toast / tooltip / skeleton / spinner / progress / tabs / modal / form / formItem / dataTable,构建在 @ui-arch/frame 与 @ui-arch/table-core 之上,样式只消费 --ua-* 令牌。
|
||||
- API:
|
||||
- button(props):按钮,variant = primary | ghost | danger
|
||||
- textField(props):文本输入,value 信号双向绑定
|
||||
@@ -59,6 +59,7 @@
|
||||
- alert(props):提示条,variant = info | success | warning | danger
|
||||
- toast.info/success/warning/error(message, duration?):消息提示工厂,右上角堆叠,默认 3s 自动消失,出入场微动画;showToast(props) 为完整入参版本
|
||||
- tooltip(props, trigger):悬浮提示,包裹触发器,hover / focus 延迟 150ms 出场,移出 / 失焦 / Esc 收起
|
||||
- skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画
|
||||
- spinner(props):加载指示器,size 控制直径
|
||||
- progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色
|
||||
- tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签
|
||||
|
||||
@@ -11,6 +11,7 @@ export { badge } from './badge.js';
|
||||
export { alert } from './alert.js';
|
||||
export { toast, showToast } from './toast.js';
|
||||
export { tooltip } from './tooltip.js';
|
||||
export { skeleton } from './skeleton.js';
|
||||
export { spinner } from './spinner.js';
|
||||
export { progress } from './progress.js';
|
||||
export { tabs } from './tabs.js';
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { h } from '@ui-arch/frame';
|
||||
import type { SkeletonProps } from './types.js';
|
||||
|
||||
/*** 骨架屏:variant 决定占位形状(text 多行 / rect 块 / circle 圆),纯展示无状态 ***/
|
||||
export function skeleton(props: SkeletonProps): HTMLElement {
|
||||
const variant = props.variant ?? 'rect'; // 缺省整块矩形
|
||||
if (variant !== 'text') return h('div', { class: `ua-skeleton ua-skeleton-${variant}` }); // 单形状直接返回
|
||||
const rows = props.rows ?? 3; // text 行数,末行缩短模拟段落收尾
|
||||
const lines: HTMLElement[] = [];
|
||||
for (let i = 0; i < rows; i++) lines.push(h('div', { class: `ua-skeleton ua-skeleton-text${i === rows - 1 ? ' ua-last' : ''}` }));
|
||||
return h('div', { class: 'ua-skeleton-group' }, ...lines);
|
||||
}
|
||||
@@ -92,6 +92,12 @@ export interface AlertProps {
|
||||
variant?: 'info' | 'success' | 'warning' | 'danger'; // 语义色;缺省 info
|
||||
}
|
||||
|
||||
/*** 骨架屏入参 ***/
|
||||
export interface SkeletonProps {
|
||||
variant?: 'text' | 'rect' | 'circle'; // 占位形状;缺省 rect
|
||||
rows?: number; // text 形状的行数;缺省 3
|
||||
}
|
||||
|
||||
/*** toast 消息提示入参 ***/
|
||||
export interface ToastProps {
|
||||
message: string; // 提示文案
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@ui-arch/ui",
|
||||
"type": "skin-dom",
|
||||
"description": "DOM 皮肤组件库:button / textField / textarea / checkbox / switch / select / radioGroup / card / badge / alert / toast / tooltip / spinner / progress / tabs / modal / form / formItem / dataTable,构建在 @ui-arch/frame 与 @ui-arch/table-core 之上,样式只消费 --ua-* 令牌。",
|
||||
"description": "DOM 皮肤组件库:button / textField / textarea / checkbox / switch / select / radioGroup / card / badge / alert / toast / tooltip / skeleton / spinner / progress / tabs / modal / form / formItem / dataTable,构建在 @ui-arch/frame 与 @ui-arch/table-core 之上,样式只消费 --ua-* 令牌。",
|
||||
"tags": [
|
||||
"components",
|
||||
"dom",
|
||||
@@ -25,6 +25,7 @@
|
||||
"alert(props):提示条,variant = info | success | warning | danger",
|
||||
"toast.info/success/warning/error(message, duration?):消息提示工厂,右上角堆叠,默认 3s 自动消失,出入场微动画;showToast(props) 为完整入参版本",
|
||||
"tooltip(props, trigger):悬浮提示,包裹触发器,hover / focus 延迟 150ms 出场,移出 / 失焦 / Esc 收起",
|
||||
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
|
||||
"spinner(props):加载指示器,size 控制直径",
|
||||
"progress(props):进度条,轨道 + 渐变流动填充,value 信号驱动 0-100,满格切 success 色",
|
||||
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
|
||||
@@ -47,6 +48,7 @@
|
||||
"AlertProps",
|
||||
"ToastProps",
|
||||
"TooltipProps",
|
||||
"SkeletonProps",
|
||||
"SpinnerProps",
|
||||
"ProgressProps",
|
||||
"TabsProps",
|
||||
@@ -65,7 +67,7 @@
|
||||
"语义色 variant 四档:default|info / success / warning / danger,一律来自令牌,禁止硬编码颜色"
|
||||
],
|
||||
"docs": {
|
||||
"intro": "18 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。",
|
||||
"intro": "19 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。",
|
||||
"steps": [
|
||||
"安装依赖:pnpm add @ui-arch/ui @ui-arch/frame(workspace 内自动链接)",
|
||||
"引入样式:在应用入口 import '@ui-arch/ui/ui.css',暗色主题在根元素设 data-theme='dark'",
|
||||
@@ -360,6 +362,30 @@
|
||||
"传入 message 即可,入场自带下滑动画"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "skeleton",
|
||||
"title": "骨架屏 Skeleton",
|
||||
"demo": "sec-skeleton",
|
||||
"props": [
|
||||
{
|
||||
"n": "variant",
|
||||
"t": "'text' | 'rect' | 'circle'",
|
||||
"d": "占位形状;缺省 rect(整块矩形)"
|
||||
},
|
||||
{
|
||||
"n": "rows",
|
||||
"t": "number",
|
||||
"d": "text 形状的行数;缺省 3,末行自动缩短模拟段落"
|
||||
}
|
||||
],
|
||||
"example": "skeleton({ variant: 'text', rows: 3 }); skeleton({ variant: 'circle' }); skeleton({ variant: 'rect' })",
|
||||
"steps": [
|
||||
"数据加载期间用 skeleton 顶替真实内容,加载完成后整体替换",
|
||||
"文本段落用 variant: 'text' + rows 控制行数,头像用 'circle',卡片/图片区域用 'rect'",
|
||||
"占位块自带扫光动画,reduced-motion 用户自动静态化为纯灰块",
|
||||
"组合布局:skeleton 是普通 DOM,可放进 card / row 等任意容器"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "toast",
|
||||
"title": "消息提示 Toast",
|
||||
|
||||
@@ -379,6 +379,49 @@
|
||||
background: color-mix(in srgb, var(--ua-color-danger) 12%, transparent);
|
||||
}
|
||||
|
||||
/* —— 骨架屏:占位灰块 + 扫光 —— */
|
||||
.ua-skeleton {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: var(--ua-radius-sm);
|
||||
background: color-mix(in srgb, var(--ua-color-border) 45%, transparent);
|
||||
}
|
||||
.ua-skeleton::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transform: translateX(-100%);
|
||||
background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--ua-color-bg) 65%, transparent), transparent);
|
||||
animation: ua-shimmer 1.4s ease-in-out infinite;
|
||||
}
|
||||
@keyframes ua-shimmer {
|
||||
to {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
.ua-skeleton-text {
|
||||
height: 12px;
|
||||
margin-bottom: var(--ua-space-2);
|
||||
}
|
||||
.ua-skeleton-text.ua-last {
|
||||
width: 60%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.ua-skeleton-rect {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
border-radius: var(--ua-radius-md);
|
||||
}
|
||||
.ua-skeleton-circle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ua-skeleton-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* —— toast 消息提示:右上角堆叠,转瞬即逝 —— */
|
||||
.ua-toast-host {
|
||||
position: fixed;
|
||||
@@ -707,6 +750,8 @@
|
||||
.ua-alert,
|
||||
.ua-tip,
|
||||
.ua-toast,
|
||||
.ua-skeleton,
|
||||
.ua-skeleton::after,
|
||||
.ua-form-error,
|
||||
.ua-modal,
|
||||
.ua-modal-overlay {
|
||||
|
||||
Reference in New Issue
Block a user