EmptyState 空状态
没有数据时的占位区域:说明为什么为空,以及可以做什么。
空状态与结果页共用同一套结构:图标、标题、说明、操作四段与整页结果完全一致,404、403、500 等结果页也使用本组件。status 只接受这三个状态码,只落为 root 的 data-status,皮肤据此把图标区并入最接近的一族语气色,不改变语义、不带插画资源;成功、警示、出错、提示等通用结果使用全库统一的 tone 轴。
用法
图标、标题、说明、操作四个槽都可选,只有 root 是必需的
还没有任何工单
新建一条工单,或者换个筛选条件再看看。
组件结构
加粗的是必需部件。
data-scope="empty-state":root · media · indicator · title · description · action
示例
尺寸
size 只改变留白与字号,语义不变;不传即 md
sm
塞进侧栏或卡片里的那一档。
md
缺省档,列表与表格用它。
lg
整页只有这一块时用它。
播报方式
默认 polite 使 root 成为活区,筛选完成后就地播报;off 使它只是一个普通容器
没有匹配「曦寒」的结果
换个词,或者去掉几个筛选条件。
用作结果页
同一套部件也承载 404、403 等结果:status 为图标区上语气色,操作槽中放置回退出口
404 页面不存在
地址可能敲错了,或者这条记录已经被删掉。
403 没有权限
这块内容需要更高的角色,找管理员要一下。
500 服务出错
请求没能处理完,稍后再试一次。
图标自带语气
图标槽中放置一个带 tone 的图标,着色落在图标自身上,不经过根上的 tone
全部导入成功
128 条记录已入库,没有需要人工处理的行。
部分行被跳过
有 6 行缺少必填字段,这次没有导入它们。
导入没有完成
文件读到一半中断,这次改动已经整体回滚。
颜色
tone 为图标区上语气色,与全库同一根轴;绘制什么图标仍由作者放置
全部导入成功
128 条记录已入库。
部分行被跳过
有 6 行缺少必填字段。
导入没有完成
这次改动已经整体回滚。
任务已排队
前面还有 3 个任务在跑。
设计指引
何时使用
- 列表、表格、搜索结果为空。
- 首次使用、还没有任何数据。
何时不用
特性
- 图标、标题、描述、操作四段都可选。
live决定内容出现时读屏如何播报,搜索结果变空时尤其重要。status只接受 404 / 403 / 500 三个状态码,各并入最接近的一族语气色;tone直接指定语气,两者都写时以tone为准。- 开幕只在出现时播放:页面加载完成之前挂上或服务端渲染后水合的空状态直接呈现;筛选、删除或新数据带来的出现,以及 root 从
hidden恢复显示,图标、标题、说明、操作依次开幕。
组合
最佳实践
- 区分三种空:从未有数据、筛选后为空、搜索无结果,三者的文案完全不同。
- 提供一条出路:新建、清除筛选、更换关键词。
- 用作结果页时每一页都提供回退出口:回首页、重试、联系支持,403 与 500 尤其需要。
- 失败页提供可追溯的标识(请求号、时间),便于用户报障。
反模式
- 只显示一个空盒子加“暂无数据”,用户不知道下一步做什么。
- 首次使用的空状态与筛选无结果的外观相同。
- 只写“出错了”,不说明错误内容,也不提供下一步。
API 参考
产物
| 层 | 值 |
|---|---|
| 自定义元素 | <xh-empty-state> |
| Vue 组件 | XhEmptyStateAction XhEmptyStateDescription XhEmptyStateIndicator XhEmptyStateMedia XhEmptyStateRoot XhEmptyStateTitle |
| 状态机 | emptyStateMachine |
| 皮肤 | @xihan-ui/styles/empty-state.css |
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
live | EmptyStateLive | 默认 polite。 | |
size | Size | 尺寸档位,只影响留白与字号,不改变语义。 | |
status | EmptyStateStatus | 结果页的状态码,只写为 root 的 data-status;皮肤据此把图标区并入最接近的一族语气色,图标内容由作者放入图标槽。 | |
tone | Tone | 语气:brand / neutral / success / warning / danger / info,决定图标区使用哪族颜色;与 status 都提供时以它为准。未提供时保持中性。 |
状态
以下名称仅用于内部状态机。
状态:idle
事件:APPEARANCE.RELEASE
connect API
getXxxProps() 返回对应部件的宿主属性。
| 成员 | 类型 | 说明 |
|---|---|---|
live | EmptyStateLive | 生效的播报方式,默认值补齐后的结果。 |
getRootProps | () => T['element'] | |
getMediaProps | () => T['element'] | 插画槽:按自身的尺寸档测量,与字形槽二选一。 |
getIndicatorProps | () => T['element'] | |
getTitleProps | () => T['element'] | |
getDescriptionProps | () => T['element'] | |
getActionProps | () => T['element'] |
无障碍
键盘
规格出处:W3C APG
无键盘交互(不接收焦点,或焦点行为完全由原生元素提供)。
ARIA
以下属性由 connect 生成。
| 部件 | 属性 | 值 |
|---|---|---|
root | role | undefined | 'status' |
media | aria-hidden | 'true' |
indicator | aria-hidden | 'true' |
样式参考
皮肤
@xihan-ui/styles/empty-state.css 使用 [data-scope="empty-state"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。
数据属性
由 connect 生成;条件不成立时不输出无值属性。
| 部件 | 属性 | 值 |
|---|---|---|
root | data-size | props.size |
root | data-status | props.status |
root | data-tone | props.tone |
media | data-instant | ''(条件成立时才出现) |
indicator | data-instant | ''(条件成立时才出现) |
title | data-instant | ''(条件成立时才出现) |
description | data-instant | ''(条件成立时才出现) |
action | data-instant | ''(条件成立时才出现) |
CSS 变量
本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。
| 变量 | 部件 | CSS 属性 | 状态 | 默认来源 | 说明 |
|---|---|---|---|---|---|
--xh-empty-state-action-gap | action | gap | default | --xh-space-2 | empty-state 的 action 部件 gap 覆盖槽。 |
--xh-empty-state-description-fg | description | color | default | --xh-fg-muted | empty-state 的 description 部件 color 覆盖槽。 |
--xh-empty-state-description-font-size | description | font-size | default | --xh-text-secondary-size | empty-state 的 description 部件 font-size 覆盖槽。 |
--xh-empty-state-description-leading | description | line-height | default | --xh-leading-normal | empty-state 的 description 部件 line-height 覆盖槽。 |
--xh-empty-state-description-max-w | description | max-inline-size | default | --xh-measure-prose | empty-state 的 description 部件 max-inline-size 覆盖槽。 |
--xh-empty-state-fg | root | color | default | --xh-fg-default | empty-state 的 root 部件 color 覆盖槽。 |
--xh-empty-state-gap | root | gap | default | --xh-_empty-state-gap | empty-state 的 root 部件 gap 覆盖槽。 |
--xh-empty-state-icon-size | indicator | --xh-icon-sizeblock-sizeinline-size | default | --xh-_empty-state-icon-size | empty-state 的 indicator 部件 --xh-icon-size、block-size、inline-size 覆盖槽。 |
--xh-empty-state-indicator-fg | indicator | color | default | --xh-_empty-state-accent | empty-state 的 indicator 部件 color 覆盖槽。 |
--xh-empty-state-indicator-font-size | indicator | font-size | default | --xh-_empty-state-icon-size | empty-state 的 indicator 部件 font-size 覆盖槽。 |
--xh-empty-state-media-fg | media | color | default | --xh-_empty-state-accent | empty-state 的 media 部件 color 覆盖槽。 |
--xh-empty-state-media-size | media | block-size | default | --xh-_empty-state-icon-size | empty-state 的 media 部件 block-size 覆盖槽。 |
--xh-empty-state-px | root | padding-inline | default | --xh-space-6 | empty-state 的 root 部件 padding-inline 覆盖槽。 |
--xh-empty-state-py | root | padding-block | default | --xh-_empty-state-py | empty-state 的 root 部件 padding-block 覆盖槽。 |
--xh-empty-state-title-fg | title | color | default | --xh-fg-default | empty-state 的 title 部件 color 覆盖槽。 |
--xh-empty-state-title-font-size | title | font-size | default | --xh-_empty-state-title-size | empty-state 的 title 部件 font-size 覆盖槽。 |
--xh-empty-state-title-font-weight | title | font-weight | default | --xh-font-weight-semibold | empty-state 的 title 部件 font-weight 覆盖槽。 |
--xh-empty-state-title-leading | title | line-height | default | --xh-leading-tight | empty-state 的 title 部件 line-height 覆盖槽。 |
动效
动效角色:出现(见动效规范)。
共享关键帧 xh-rise-in 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立。时长与缓动读动效令牌,改令牌即改全局节奏。
系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。
RTL
皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。
