iter(g36): 新增 result 结果页组件
This commit is contained in:
@@ -31,6 +31,7 @@ export { segmented } from './segmented.js';
|
||||
export { stepper } from './stepper.js';
|
||||
export { rate } from './rate.js';
|
||||
export { empty } from './empty.js';
|
||||
export { result } from './result.js';
|
||||
export { divider } from './divider.js';
|
||||
export { list } from './list.js';
|
||||
export { carousel } from './carousel.js';
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { h } from '@ui-arch/frame';
|
||||
import type { ResultProps } from './types.js';
|
||||
|
||||
// 语义状态对应的符号(纯装饰,读屏跳过)
|
||||
const GLYPH: Record<string, string> = { success: '✓', warning: '!', danger: '×', info: 'i' };
|
||||
|
||||
/*** 结果页:状态符号 + 标题 + 说明 + 操作区,用于提交完成 / 校验失败 / 无权限等终态页面 ***/
|
||||
export function result(props: ResultProps): HTMLElement {
|
||||
const status = props.status ?? 'info'; // 缺省中性信息
|
||||
return h(
|
||||
'div',
|
||||
{ class: `ua-result ua-result-${status}`, role: 'status' }, // role=status 由读屏播报终态
|
||||
h('div', { class: 'ua-result-icon', 'aria-hidden': 'true' }, GLYPH[status] ?? 'i'),
|
||||
h('div', { class: 'ua-result-title' }, props.title),
|
||||
props.description ? h('div', { class: 'ua-result-desc' }, props.description) : null,
|
||||
props.extra ? h('div', { class: 'ua-result-extra' }, props.extra) : null, // 操作区:常见为主次按钮
|
||||
) as HTMLElement;
|
||||
}
|
||||
@@ -420,6 +420,14 @@ export interface ListProps {
|
||||
onItemClick?: (item: ListItem, index: number) => void; // 条目点击回调;提供后条目可点击并带 hover 反馈
|
||||
}
|
||||
|
||||
/*** 结果页入参 ***/
|
||||
export interface ResultProps {
|
||||
status?: 'success' | 'warning' | 'danger' | 'info'; // 终态语义色;缺省 info
|
||||
title: string; // 主标题(必填)
|
||||
description?: string; // 补充说明;缺省不渲染
|
||||
extra?: unknown; // 操作区内容(常见为主次按钮);缺省不渲染
|
||||
}
|
||||
|
||||
/*** 通知入参 ***/
|
||||
export interface NotificationProps {
|
||||
title: string; // 通知标题(必填)
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
"carousel(props):轮播,items 横排位移,指示点/箭头/←→ 键切换,autoplay 毫秒自动前进且悬停暂停,index 信号可外部受控",
|
||||
"tree(props):树形,递归节点 + 箭头展开/收起 + 点选节点,键盘 Enter 选中、→ 展开、← 收起,禁用节点不响应",
|
||||
"upload(props):文件选择,点击或拖拽入列,清单可逐个移除,onChange 回传文件数组(不内置上传请求)",
|
||||
"notification(props):右下角通知卡片(标题 + 描述 + 操作区),返回 { el, close } 句柄,缺省常驻需手动关闭"
|
||||
"notification(props):右下角通知卡片(标题 + 描述 + 操作区),返回 { el, close } 句柄,缺省常驻需手动关闭",
|
||||
"result(props):结果页,status 四档语义色 + 标题 + 说明 + 操作区,用于提交完成/校验失败等终态"
|
||||
],
|
||||
"keyTypes": [
|
||||
"ButtonProps",
|
||||
@@ -1864,6 +1865,41 @@
|
||||
"action 放操作区(常见为按钮);variant 决定左侧条与圆点语义色",
|
||||
"与 toast 的分工:toast 右上角轻量瞬时,notification 右下角可长读、可操作"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "result",
|
||||
"title": "结果页 Result",
|
||||
"demo": "sec-result",
|
||||
"props": [
|
||||
{
|
||||
"n": "status",
|
||||
"t": "'success' | 'warning' | 'danger' | 'info'",
|
||||
"d": "终态语义色(图标底色);缺省 info"
|
||||
},
|
||||
{
|
||||
"n": "title",
|
||||
"t": "string",
|
||||
"r": 1,
|
||||
"d": "主标题"
|
||||
},
|
||||
{
|
||||
"n": "description",
|
||||
"t": "string",
|
||||
"d": "补充说明;缺省不渲染"
|
||||
},
|
||||
{
|
||||
"n": "extra",
|
||||
"t": "unknown",
|
||||
"d": "操作区内容(常见为主次按钮);缺省不渲染"
|
||||
}
|
||||
],
|
||||
"example": "result({ status: 'success', title: '提交成功', description: '工单 #2049 已受理', extra: button({ label: '查看工单', variant: 'primary', onClick: () => go() }) })",
|
||||
"steps": [
|
||||
"status 决定图标底色(success 绿 / warning 黄 / danger 红 / info 蓝),整体居中排布",
|
||||
"title 必填;description 用于说明原因或下一步,超过一行自动居中换行",
|
||||
"extra 放操作区,常见为主按钮 + 幽灵按钮;不传则不渲染",
|
||||
"组件自带 role=\"status\",插入页面后读屏会播报终态文案"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2363,3 +2363,44 @@ button.ua-step-dot:hover {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* —— 结果页 —— */
|
||||
.ua-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
gap: var(--ua-space-2);
|
||||
padding: var(--ua-space-4) var(--ua-space-3);
|
||||
min-height: 180px;
|
||||
justify-content: center;
|
||||
}
|
||||
.ua-result-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
font-size: var(--ua-font-size-lg);
|
||||
font-weight: 700;
|
||||
color: var(--ua-color-accent-contrast);
|
||||
background: var(--ua-color-accent);
|
||||
}
|
||||
.ua-result-success .ua-result-icon { background: var(--ua-color-success); }
|
||||
.ua-result-warning .ua-result-icon { background: var(--ua-color-warning); }
|
||||
.ua-result-danger .ua-result-icon { background: var(--ua-color-danger); }
|
||||
.ua-result-title {
|
||||
font-size: var(--ua-font-size-lg);
|
||||
font-weight: 600;
|
||||
color: var(--ua-color-text);
|
||||
}
|
||||
.ua-result-desc {
|
||||
max-width: 380px;
|
||||
font-size: var(--ua-font-size-sm);
|
||||
color: var(--ua-color-text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.ua-result-extra {
|
||||
margin-top: var(--ua-space-1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user