REAL SHOWCASE SOURCEoverlay-feedback
1 个文件 · 158 行 · TypeScript
// ===== showcase/src/examples/components/overlay_feedback.ts ===== import { NotificationManager, RenderBorder, RenderButton, RenderDrawer, RenderLoadingHost, RenderModal, RenderPageHeader, RenderStackPanel, RenderText, RenderTextBox, RenderWrapPanel,} from 'ds-ui'import type { ShowcaseExample } from '../../showcase_example' export function createOverlayFeedbackExample(): ShowcaseExample { const notifications = new NotificationManager() const status = new RenderText('选择一种反馈方式,观察阻断范围与交互语义。', { role: 'secondary' }) const modal = new RenderModal({ title: '确认提交', content: '提交后将进入审核流程,是否继续?', buttons: [ { key: 'cancel', label: '取消' }, { key: 'submit', label: '提交', primary: true }, ], onClose: key => { status.text = key === 'submit' ? '已确认提交。' : '已取消提交。' }, }) const detailsModal = new RenderModal({ title: '错误详情', content: '请求未完成,请检查网络连接后重试。\n\n错误编号:DEMO-1001', buttons: [{ key: 'close', label: '关闭', primary: true }], }) const showErrorDetails = (errorCode: string): void => { detailsModal.content = `请求未完成,请检查网络连接后重试。\n\n错误编号:${errorCode}` detailsModal.show() } const drawerContent = new RenderStackPanel({ orientation: 'vertical', spacing: 12, crossAxisAlignment: 'stretch' }) drawerContent.addChild(new RenderText('患者详情', { role: 'title', weight: 'semibold' })) drawerContent.addChild(new RenderTextBox({ value: '李安然', label: '姓名', readonly: true })) drawerContent.addChild(new RenderTextBox({ value: '呼吸内科', label: '科室', readonly: true })) drawerContent.addChild(new RenderText('Drawer 可以承载真实组件树,并保留底层页面上下文。', { role: 'secondary' })) const drawer = new RenderDrawer({ title: '患者详情', side: 'right', width: 420, child: drawerContent }) const loadingPanel = new RenderStackPanel({ orientation: 'vertical', spacing: 8 }) loadingPanel.addChild(new RenderText('局部查询结果', { role: 'title', weight: 'semibold' })) loadingPanel.addChild(new RenderText('生命体征、检验结果和处置建议仍保留原有布局。', { role: 'secondary' })) const loadingContent = new RenderBorder({ background: 'muted', padding: 18, child: loadingPanel }) const loadingHost = new RenderLoadingHost({ child: loadingContent, text: '正在刷新患者数据…' }) let loading = false let loadingButton!: RenderButton loadingButton = new RenderButton({ label: '开启局部 Loading', onClick: () => { loading = !loading loadingHost.setLoading(loading, loading ? '正在刷新患者数据…' : undefined) loadingButton.label = loading ? '关闭局部 Loading' : '开启局部 Loading' loadingButton.markNeedsLayout() status.text = loading ? '当前只阻断查询结果区域。' : '局部查询已恢复交互。' }, }) const actions = new RenderWrapPanel({ spacing: 10, runSpacing: 10 }) actions.addChild(new RenderButton({ label: '打开 Modal', variant: 'primary', onClick: () => modal.show() })) actions.addChild(new RenderButton({ label: '打开 Drawer', onClick: () => drawer.show() })) actions.addChild(new RenderButton({ label: '仅标题通知', onClick: () => notifications.notify({ type: 'info', title: '操作已完成', duration: 0 }), })) actions.addChild(new RenderButton({ label: '成功通知', onClick: () => notifications.show('success', '保存成功', '病历内容已经保存。') })) actions.addChild(new RenderButton({ label: '警告通知', onClick: () => notifications.show('warning', '网络较慢', '后台正在自动重试。', 5000) })) actions.addChild(new RenderButton({ label: '可重试错误', onClick: () => notifications.notify({ type: 'error', title: '保存失败', message: '网络连接异常,请重试。', action: { label: '重试', onInvoke: () => { status.text = '已触发重试。' }, }, }), })) actions.addChild(new RenderButton({ label: '错误详情', onClick: () => notifications.notify({ type: 'error', title: '处理失败', message: '错误编号:DEMO-1001', action: { label: '查看详情', onInvoke: () => showErrorDetails('DEMO-1001') }, }), })) actions.addChild(new RenderButton({ label: '三条可查看错误', onClick: () => { for (const [index, errorCode] of ['DEMO-2001', 'DEMO-2002', 'DEMO-2003'].entries()) { notifications.notify({ type: 'error', title: `处理失败 ${index + 1}`, message: `错误编号:${errorCode}`, action: { label: '查看详情', onInvoke: () => showErrorDetails(errorCode) }, }) } }, })) actions.addChild(new RenderButton({ label: '长文本通知', onClick: () => notifications.notify({ type: 'warning', title: '部分数据未保存', message: '由于服务端校验未通过,当前修改暂未保存,请检查输入后重试。', }), })) actions.addChild(new RenderButton({ label: '三条堆叠', onClick: () => { notifications.notify({ type: 'info', title: '任务已开始', message: '正在准备数据。', duration: 0 }) notifications.notify({ type: 'warning', title: '检查到变更', message: '请留意未保存内容。', duration: 0 }) notifications.notify({ type: 'success', title: '检查完成', message: '共处理 3 项数据。', duration: 0 }) }, })) actions.addChild(new RenderButton({ label: '异步操作', onClick: () => notifications.notify({ type: 'info', title: '可执行操作', message: '点击提交后观察 pending 状态。', action: { label: '提交', onInvoke: () => new Promise<void>(resolve => { globalThis.setTimeout(() => { status.text = '异步操作已完成。' resolve() }, 1200) }), }, }), })) actions.addChild(loadingButton) const panel = new RenderStackPanel({ orientation: 'vertical', spacing: 18, crossAxisAlignment: 'stretch' }) panel.addChild(new RenderPageHeader({ title: 'Overlay 与反馈语义', description: '同一页面中对比确认、侧栏、非阻断通知和局部加载。' })) panel.addChild(actions) loadingHost.height = 150 panel.addChild(loadingHost) panel.addChild(status) panel.padding = 24 return { content: panel, afterMount: () => drawer.show(), }}