iter(e04): 新增 empty 空状态组件

This commit is contained in:
HIsheR
2026-10-23 18:11:47 +08:00
parent 62d4ce648d
commit fd4ee018e6
12 changed files with 172 additions and 9 deletions
+14
View File
@@ -0,0 +1,14 @@
import { h } from '@ui-arch/frame';
import type { EmptyProps } from './types.js';
/*** 空状态:居中占位提示,title/description 可选,action 放操作区(常见为按钮) ***/
export function empty(props: EmptyProps): HTMLDivElement {
return h(
'div',
{ class: 'ua-empty', role: 'status' }, // role=status 由读屏播报
h('div', { class: 'ua-empty-icon', 'aria-hidden': 'true' }, '⌀'), // 装饰符号,读屏跳过
props.title ? h('div', { class: 'ua-empty-title' }, props.title) : null,
props.description ? h('div', { class: 'ua-empty-desc' }, props.description) : null,
props.action ? h('div', { class: 'ua-empty-action' }, props.action) : null,
) as HTMLDivElement;
}
+1
View File
@@ -26,6 +26,7 @@ export { progress } from './progress.js';
export { tabs } from './tabs.js';
export { stepper } from './stepper.js';
export { rate } from './rate.js';
export { empty } from './empty.js';
export { modal } from './modal.js';
export { drawer } from './drawer.js';
export { form, formItem } from './form.js';
+7
View File
@@ -197,6 +197,13 @@ export interface RateProps {
onChange?: (value: number) => void; // 评分变化回调
}
/*** 空状态入参 ***/
export interface EmptyProps {
title?: string; // 主标题;缺省不渲染
description?: string; // 补充说明;缺省不渲染
action?: unknown; // 操作区内容(常见为按钮);缺省不渲染
}
/*** 徽标入参 ***/
export interface BadgeProps {
label: string; // 徽标文案
+29
View File
@@ -40,6 +40,7 @@
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
"stepper(props):步骤条,done/current/upcoming 三态,active 信号双向绑定,clickable 时已完成步骤可回跳",
"rate(props):评分星标,value 信号双向绑定,hover 预览移出还原,键盘方向键调节,max 可配",
"empty(props):空状态占位,title/description 可选,action 放操作区",
"modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区",
"drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭",
"form(props, items):表单容器,布局 + 聚合校验,全部通过才触发 onSubmit",
@@ -1052,6 +1053,34 @@
"max 可调整星标总数;disabled 支持布尔或信号禁用"
]
},
{
"id": "empty",
"title": "空状态 Empty",
"demo": "sec-empty",
"props": [
{
"n": "title",
"t": "string",
"d": "主标题;缺省不渲染"
},
{
"n": "description",
"t": "string",
"d": "补充说明;缺省不渲染"
},
{
"n": "action",
"t": "unknown",
"d": "操作区内容(常见为按钮);缺省不渲染"
}
],
"example": "empty({ title: '暂无数据', description: '调整筛选条件后再试', action: button({ label: '重置筛选', variant: 'ghost' }) })",
"steps": [
"在列表 / 表格 / 筛选结果为空时渲染 empty 占位",
"title 一句话说明状态,description 补充原因或建议",
"action 传入 DOM(如 ghost 按钮)引导用户下一步操作"
]
},
{
"id": "pagination",
"title": "分页器 Pagination",
+29
View File
@@ -814,6 +814,35 @@ button.ua-step-dot:hover {
border-radius: 4px;
}
/* —— 空状态 —— */
.ua-empty {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--ua-space-2);
padding: var(--ua-space-4);
min-height: 120px; /* 撑出足够留白感 */
justify-content: center;
text-align: center;
}
.ua-empty-icon {
font-size: 34px;
line-height: 1;
color: var(--ua-color-border); /* 装饰符号弱化为边框色 */
}
.ua-empty-title {
font-size: var(--ua-font-size-md);
font-weight: 600;
color: var(--ua-color-text);
}
.ua-empty-desc {
font-size: var(--ua-font-size-sm);
color: var(--ua-color-text-muted);
}
.ua-empty-action {
margin-top: var(--ua-space-1);
}
/* —— 徽标 —— */
.ua-badge {
display: inline-block;