Feedbacks(Toast)
- 组件说明:反馈提示组件,用于向用户展示操作结果或系统状态。Figma 中 Message(简单消息)和 Alert(带标题)均为 Toast 变体。
- 当前状态:当前覆盖 Message / Alert × Action Button × Info、Success、Warning、Error、AI Feedback 五种样式。
- 实现约定:自研 toast manager,无第三方依赖。
Toaster订阅 store 并通过 portal 渲染到body;Figma 设计 token 直接以 Tailwind token class 应用。Toaster默认启用closeButton。 - Figma 规范:Feedbacks / Alerts
基础用法
最简形态:Message(简单消息),对应 Figma Description=False。
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => toast('A short and clear sentence is perfect.')}> Default </Button> <Button variant="secondary" onClick={() => toast.info('A short and clear sentence is perfect.')}> Info </Button> <Button variant="secondary" onClick={() => toast.success('A short and clear sentence is perfect.')}> Success </Button> <Button variant="secondary" onClick={() => toast.warning('A short and clear sentence is perfect.')}> Warning </Button> <Button variant="secondary" onClick={() => toast.error('A short and clear sentence is perfect.')}> Error </Button> <Button variant="secondary" onClick={() => toast.aiFeedback('A short and clear sentence is perfect.')}> AI Feedback </Button> </div>, )
AI Feedback
AI 生成内容反馈专属样式:白底 + AI 渐变描边 + 多色渐变图标,对应 Figma Style=AI Feedback。
Message
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => toast.aiFeedback('A short and clear sentence is perfect.')}> AI Message </Button> <Button variant="secondary" onClick={() => toast.aiFeedback('A short and clear sentence is perfect.', { action: { label: 'Button', onClick: () => {} }, }) } > AI Message + Action </Button> </div>, )
Alert
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => toast.aiFeedback('Title', { description: 'A short and clear sentence is perfect.' }) } > AI Alert </Button> <Button variant="secondary" onClick={() => toast.aiFeedback('Title', { description: 'A short and clear sentence is perfect.', action: { label: 'Confirm', onClick: () => {} }, }) } > AI Alert + Action </Button> <Button variant="secondary" onClick={() => toast.aiFeedback('Title', { description: 'A short and clear sentence is perfect.', action: { label: 'Confirm', onClick: () => {} }, cancel: { label: 'Cancel', onClick: () => {} }, }) } > AI Alert + Action + Cancel </Button> </div>, )
主矩阵
当前 spec 验收范围是 Style × Description × Action Button。文档站优先展示最核心的可见矩阵。
Message / Alert
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => toast.info('Message')}>Info Message</Button> <Button variant="secondary" onClick={() => toast.info('Alert Title', { description: 'A short and clear sentence is perfect.' })} > Info Alert </Button> <Button variant="secondary" onClick={() => toast.success('Message')}>Success Message</Button> <Button variant="secondary" onClick={() => toast.success('Alert Title', { description: 'A short and clear sentence is perfect.' })} > Success Alert </Button> </div>, )
带标题(Alert 形态)
传入 description 进入 Alert 布局,对应 Figma Description=True。
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => toast.info('Title', { description: 'A short and clear sentence is perfect.' })}> Info </Button> <Button variant="secondary" onClick={() => toast.success('Title', { description: 'A short and clear sentence is perfect.' })}> Success </Button> <Button variant="secondary" onClick={() => toast.warning('Title', { description: 'A short and clear sentence is perfect.' })}> Warning </Button> <Button variant="secondary" onClick={() => toast.error('Title', { description: 'A short and clear sentence is perfect.' })}> Error </Button> </div>, )
带操作按钮
对应 Figma Action Button=True。
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => toast.info('A short and clear sentence is perfect.', { action: { label: 'Button', onClick: () => {} }, })}> Message + Action </Button> <Button variant="secondary" onClick={() => toast.error('Title', { description: 'A short and clear sentence is perfect.', action: { label: 'Button', onClick: () => {} }, cancel: { label: 'Button', onClick: () => {} }, })}> Alert + Actions </Button> </div>, )
补充能力
编程式控制
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => { const id = toast.loading('Loading...') setTimeout(() => toast.success('Done!', { id }), 2000) }}> Promise 模拟 </Button> <Button variant="secondary" onClick={() => toast.dismiss()}> 全部关闭 </Button> </div>, )
Feedbacks 命名空间
Feedbacks 命名空间与 toast / Toaster 直接导入保持一致,适合 patterns 语义下统一引用。
结果
Loading...
实时编辑器
render( <div style={{ display: 'flex', gap: 12, padding: '40px 0', flexWrap: 'wrap' }}> <Button variant="secondary" onClick={() => Feedbacks.toast.info('Namespaced message')}> Feedbacks.toast.info </Button> </div>, )
尺寸规范
Figma 变体对照
| Figma 形态 | Figma 属性 | toast API |
|---|---|---|
| Message | Description=False, Action=False | toast.info('msg') |
| Message + Action | Description=False, Action=True | toast.info('msg', { action }) |
| Alert | Description=True, Action=False | toast.info('title', { description }) |
| Alert + Actions | Description=True, Action=True | toast.info('title', { description, action, cancel }) |
颜色 Token
| Variant | 遮罩/图标颜色 |
|---|---|
| info | Template Community/Icon/Sky#528fcc |
| success | Template Community/Icon/Moss#4cbf69 |
| warning | Template Community/Icon/Mustard#bfa043 |
| error | Template Community/Icon/Coral#cc5266 |
容器
| 属性 | Token | 值 |
|---|---|---|
| 左内边距 | Spacing_16 | 16px |
| 右内边距 | Spacing_12 | 12px |
| 上下内边距 | Spacing_8 | 8px |
| 圆角 | Radius_5 | 5px |
| 阴影 | Effects/Shadow/Default | 0 0 32px rgba(0,0,0,0.1) |
| 遮罩透明度 | — | 18% (before: 伪元素) |
Props
Toaster
Toast 宿主容器,全局在应用根组件放置一个即可。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
position | ToastPosition | 'top-center' | Toast 位置(top/bottom × left/center/right) |
closeButton | boolean | true | 关闭按钮容器级默认值,可被单条 toast 覆盖 |
duration | number | 4000 | 默认自动消失时长(ms),可被单条 toast 覆盖 |
visibleToasts | number | 3 | 堆叠时同时完全可见的 toast 数量 |
className | string | — | 自定义容器类名 |
style | CSSProperties | — | 自定义容器内联样式 |
toast 函数
| 方法 | 说明 |
|---|---|
toast('msg') | 默认 Toast |
toast.info('msg') | Info 变体 |
toast.success('msg') | Success 变体 |
toast.warning('msg') | Warning 变体 |
toast.error('msg') | Error 变体 |
toast.aiFeedback('msg') | AI Feedback 变体 |
toast.loading('msg') | Loading 变体(默认不自动消失) |
toast('title', { description }) | 带标题(Alert 形态) |
toast('msg', { action: { label, onClick } }) | 带操作按钮 |
toast('msg', { closeButton: true }) | 强制显示关闭按钮(覆盖容器与形态规则) |
toast('msg', { closeButton: false }) | 强制隐藏关闭按钮 |
toast('msg', { id }) | 复用已存在的 id 原地更新(如 loading → success) |
toast.dismiss(id?) | 关闭指定/全部 Toast |
Feedbacks
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Toaster | ComponentType<ToasterProps> | - | Toast 容器组件 |
toast | typeof toast | - | 命名空间下的触发函数 |
使用约束
<Toaster />必须放在应用根组件中,全局只需一个。- Toast 位置、持续时间等配置通过
<Toaster>props 或toast()第二参数控制。 - variant 图标(info/success/warning/error/aiFeedback)由设计系统通过图标契约提供;
default无图标,loading显示 spinner。