Files
RustUI/_plans/feedback-components-plan.md
T
2026-05-31 09:36:23 +08:00

1041 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Pika 反馈组件开发计划与规范
> 参照 ant Design 反馈组件,结合 Pika 设计规范(DESIGN_SPEC.md)制定。
> 核心目标:**让 AI 第一次生成的代码就能跑、就能看、就能用。**
> 设计原则:以 Apple Human Interface Guidelines 为准,融合 Ant Design 成熟实践。
---
## 一、组件体系
### 1.1 反馈组件分类
| 组件 | 英文名 | 用途 | 优先级 |
|------|--------|------|--------|
| Alert | 警告提示 | 显示需要关注的消息 | P0 |
| Message | 全局提示 | 操作反馈的非阻塞轻量提示 | P0 |
| Modal | 对话框 | 需要用户交互的浮层 | P0 |
| Notification | 通知提醒 | 复杂内容的全局通知 | P1 |
| Progress | 进度条 | 显示操作进度 | P1 |
| Spin | 加载中 | 页面或区块的加载状态 | P1 |
| Result | 结果 | 操作结果的反馈 | P1 |
| Drawer | 抽屉 | 从边缘滑出的面板 | P2 |
| Popconfirm | 气泡确认框 | 轻量级确认对话框 | P2 |
### 1.2 设计原则对照
| 规范项 | Pika 要求 | antd 参考 |
|--------|----------|----------|
| 尺寸体系 | `small \| middle \| large` | xs/sm/md/lg/xl (过多) |
| 样式绑定 | `data-*` 属性选择器 | className 拼接 |
| 事件命名 | `on + 动词 + 名词` | 部分不符合 |
| 数据 prop | 统一 `data` | options/dataSource/treeData 混乱 |
| 类型定义 | 联合类型字面量 | 部分使用 boolean |
---
## 二、Alert 组件
### 2.1 组件概述
显示需要用户关注的信息提示。
### 2.2 antd API 完整清单
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| action | 操作区域 | ReactNode | - |
| banner | 是否显示为顶部横幅 | boolean | false |
| closable | 是否可关闭,支持 `ClosableType` 配置 | boolean \| ClosableType | false |
| description | 描述内容 | ReactNode | - |
| icon | 自定义图标 | ReactNode | - |
| title | 标题 | ReactNode | - |
| showIcon | 是否显示图标 | boolean | false, banner 模式为 true |
| type | 类型 | `success \| info \| warning \| error` | `info`, banner 模式为 `warning` |
**ClosableType:**
| 属性 | 说明 | 类型 |
|------|------|------|
| afterClose | 关闭动画完成后的回调 | function |
| closeIcon | 自定义关闭图标 | ReactNode |
| onClose | 关闭时的回调 | (e: MouseEvent) => void |
### 2.3 Pika Props 定义
```tsx
export type AlertType = 'success' | 'info' | 'warning' | 'error'
export type AlertSize = 'small' | 'middle' | 'large'
export interface AlertProps {
type?: AlertType
size?: AlertSize
title?: ReactNode
description?: ReactNode
showIcon?: boolean
icon?: ReactNode
closable?: boolean
closeIcon?: ReactNode
action?: ReactNode
banner?: boolean
onClose?: (e: React.MouseEvent) => void
afterClose?: () => void
className?: string
style?: CSSProperties
}
```
### 2.4 Pika 样式规范
```tsx
// TSX — 使用 data-* 属性
<div
className={styles.root}
data-type={type}
data-size={size}
data-banner={banner || undefined}
data-closable={closable || undefined}
data-show-icon={showIcon || undefined}
>
<span className={styles.icon}>{icon || defaultIcon}</span>
<div className={styles.content}>
<span className={styles.title}>{title}</span>
<span className={styles.description}>{description}</span>
</div>
{closable && <button className={styles.close} data-close>×</button>}
</div>
```
```css
/* CSS — 使用属性选择器 */
.root[data-type="success"] { background: var(--nv-color-success-bg); color: var(--nv-color-success); }
.root[data-type="warning"] { background: var(--nv-color-warning-bg); color: var(--nv-color-warning); }
.root[data-type="error"] { background: var(--nv-color-error-bg); color: var(--nv-color-error); }
.root[data-type="info"] { background: var(--nv-color-info-bg); color: var(--nv-color-info); }
.root[data-banner] {
border-radius: 0;
margin: 0;
padding: var(--nv-spacing-small) var(--nv-spacing-middle);
}
```
---
## 三、Message 组件
### 3.1 组件概述
全局反馈操作结果的轻量提示,从顶部居中显示,自动关闭。
### 3.2 antd API 完整清单
**静态方法:**
```tsx
message.success(content, [duration], onClose)
message.error(content, [duration], onClose)
message.info(content, [duration], onClose)
message.warning(content, [duration], onClose)
message.loading(content, [duration], onClose)
```
**Config 参数:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| content | 消息内容 | ReactNode \| config | - |
| duration | 自动关闭延时(秒)0 为不自动关闭 | number | 1.5 / 3 |
| onClose | 关闭时的回调 | function | - |
**message.open(config) / message.useMessage():**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| className | 自定义类名 | string | - |
| classNames | 语义化 DOM 类名 | Record<SemanticDOM, string> | - |
| content | 消息内容 | ReactNode | - |
| duration | 自动关闭延时 | number | 3 |
| icon | 自定义图标 | ReactNode | - |
| pauseOnHover | 鼠标悬停时暂停计时 | boolean | true |
| key | 唯一标识 | string \| number | - |
| style | 自定义样式 | CSSProperties | - |
| styles | 语义化 DOM 样式 | Record<SemanticDOM, CSSProperties> | - |
| onClick | 点击回调 | function | - |
| onClose | 关闭回调 | function | - |
**message.config(options):**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| duration | 默认延时 | number | 3 |
| getContainer | 挂载节点 | () => HTMLElement | () => document.body |
| maxCount | 最大显示数 | number | - |
| prefixCls | 前缀类名 | string | `ant-message` |
| rtl | RTL 模式 | boolean | false |
| top | 距离顶部距离 | string \| number | 8 |
### 3.3 Pika Props 定义
```tsx
export type MessageType = 'success' | 'error' | 'warning' | 'info' | 'loading'
export type MessagePlacement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight'
export interface MessageConfig {
duration?: number
maxCount?: number
placement?: MessagePlacement
top?: number
bottom?: number
getContainer?: () => HTMLElement
}
export interface MessageOptions {
content: ReactNode
duration?: number
icon?: ReactNode
key?: string
onClose?: () => void
pauseOnHover?: boolean
className?: string
style?: CSSProperties
}
```
### 3.4 Pika API 设计
```tsx
// 静态方法
Message.show(options: MessageOptions): MessageInstance
Message.success(options: MessageOptions): MessageInstance
Message.error(options: MessageOptions): MessageInstance
Message.warning(options: MessageOptions): MessageInstance
Message.info(options: MessageOptions): MessageInstance
Message.loading(options: MessageOptions): MessageInstance
// 配置
Message.config(config: MessageConfig): void
Message.destroy(key?: string): void
Message.destroyAll(): void
// Hooks
const [MessageApi, contextHolder] = Message.useMessage()
```
---
## 四、Modal 组件
### 4.1 组件概述
需要用户交互的对话框,从页面中央弹出。
### 4.2 antd API 完整清单
**Modal 组件属性:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| afterClose | 完全关闭后的回调 | function | - |
| cancelButtonProps | 取消按钮 props | ButtonProps | - |
| cancelText | 取消按钮文字 | ReactNode | `Cancel` |
| centered | 是否居中显示 | boolean | false |
| closable | 是否显示关闭按钮 | boolean \| ClosableType | true |
| closeIcon | 自定义关闭图标 | ReactNode | <CloseOutlined /> |
| confirmLoading | 确认按钮 loading | boolean | false |
| destroyOnHidden | 关闭时是否销毁内容 | boolean | false |
| footer | 底部内容,设为 null 隐藏 | ReactNode \| ((originNode, extra) => ReactNode) | (OK/Cancel) |
| forceRender | 强制渲染 | boolean | false |
| focusable | 焦点管理配置 | `{ trap?: boolean, focusTriggerAfterClose?: boolean }` | - |
| getContainer | 挂载节点 | HTMLElement \| () => HTMLElement \| false | document.body |
| keyboard | 是否支持 ESC 关闭 | boolean | true |
| mask | 遮罩配置 | boolean \| `{ enabled?: boolean, blur?: boolean, closable?: boolean }` | true |
| modalRender | 自定义模态框渲染 | (node: ReactNode) => ReactNode | - |
| okButtonProps | 确认按钮 props | ButtonProps | - |
| okText | 确认按钮文字 | ReactNode | `OK` |
| okType | 确认按钮类型 | string | `primary` |
| open | 是否显示 | boolean | false |
| title | 标题 | ReactNode | - |
| width | 宽度 | string \| number \| Breakpoint | 520 |
| wrapClassName | 外层类名 | string | - |
| zIndex | z-index 值 | number | 1000 |
| onCancel | 取消回调 | function(e) | - |
| onOk | 确认回调 | function(e) | - |
| afterOpenChange | 打开/关闭动画结束回调 | (open: boolean) => void | - |
**Modal.method() 属性:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| icon | 自定义图标 | ReactNode | <ExclamationCircleFilled /> |
| maskClosable | 点击遮罩是否关闭 | boolean | false |
| okButtonProps | 确认按钮 props | ButtonProps | - |
| cancelButtonProps | 取消按钮 props | ButtonProps | - |
| width | 宽度 | string \| number | 416 |
### 4.3 Pika Props 定义
```tsx
export type ModalSize = 'small' | 'middle' | 'large'
export type ModalPlacement = 'top' | 'center' | 'bottom'
export interface ModalProps {
open?: boolean
title?: ReactNode
content?: ReactNode
footer?: ReactNode | null
width?: string | number
size?: ModalSize
placement?: ModalPlacement
closable?: boolean
closeIcon?: ReactNode
centered?: boolean
mask?: boolean
maskClosable?: boolean
keyboard?: boolean
loading?: boolean
confirmLoading?: boolean
okText?: ReactNode
cancelText?: ReactNode
okButtonProps?: ButtonProps
cancelButtonProps?: ButtonProps
okType?: ButtonVariant
getContainer?: HTMLElement | (() => HTMLElement) | false
zIndex?: number
onOk?: (e: React.MouseEvent) => void | Promise<void>
onCancel?: (e: React.MouseEvent) => void
afterOpenChange?: (open: boolean) => void
afterClose?: () => void
className?: string
style?: CSSProperties
}
```
### 4.4 Pika 样式规范
```tsx
// TSX
<div
className={styles.root}
data-open={open || undefined}
data-size={size}
data-placement={placement}
data-centered={centered || undefined}
>
<div className={styles.mask} data-mask />
<div className={styles.container}>
<div className={styles.header} data-header>
<span className={styles.title}>{title}</span>
{closable && <button data-close>×</button>}
</div>
<div className={styles.body}>{content}</div>
{footer !== undefined && (
<div className={styles.footer} data-footer>{footer}</div>
)}
</div>
</div>
```
---
## 五、Notification 组件
### 5.1 组件概述
全局通知消息,显示在屏幕四角,可包含复杂内容。
### 5.2 antd API 完整清单
**静态方法:**
```tsx
notification.success(config)
notification.error(config)
notification.info(config)
notification.warning(config)
notification.open(config)
notification.destroy(key?: string)
```
**Config 参数:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| actions | 操作按钮组 | ReactNode | - |
| className | 自定义类名 | string | - |
| closeIcon | 关闭图标 | ReactNode | true |
| description | 通知内容 | ReactNode | - |
| duration | 关闭延时,0/false 不自动关闭 | number \| false | 4.5 |
| icon | 自定义图标 | ReactNode | - |
| key | 唯一标识 | string | - |
| title | 标题 | ReactNode | - |
| placement | 位置 | `top \| topLeft \| topRight \| bottom \| bottomLeft \| bottomRight` | `topRight` |
| role | 语义角色 | `alert \| status` | `alert` |
| showProgress | 显示进度条 | boolean | - |
| pauseOnHover | 悬停暂停计时 | boolean | true |
| style | 自定义样式 | CSSProperties | - |
| onClick | 点击回调 | function | - |
| onClose | 关闭回调 | function | - |
**notification.useNotification() 配置:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| bottom | 距离底部距离 | number | 24 |
| closeIcon | 关闭图标 | ReactNode | - |
| getContainer | 挂载节点 | () => HTMLNode | () => document.body |
| maxCount | 最大显示数 | number | - |
| placement | 默认位置 | string | `topRight` |
| showProgress | 显示进度条 | boolean | - |
| pauseOnHover | 悬停暂停 | boolean | true |
| stack | 堆叠配置 | boolean \| `{ threshold: number }` | `{ threshold: 3 }` |
| top | 距离顶部距离 | number | 24 |
### 5.3 Pika Props 定义
```tsx
export type NotificationType = 'success' | 'info' | 'warning' | 'error'
export type NotificationPlacement =
| 'top'
| 'topLeft'
| 'topRight'
| 'bottom'
| 'bottomLeft'
| 'bottomRight'
export interface NotificationOptions {
title?: ReactNode
description?: ReactNode
icon?: ReactNode
actions?: ReactNode
duration?: number | false
showProgress?: boolean
pauseOnHover?: boolean
closable?: boolean
closeIcon?: ReactNode
onClose?: () => void
onClick?: () => void
className?: string
style?: CSSProperties
}
export interface NotificationConfig {
placement?: NotificationPlacement
top?: number
bottom?: number
maxCount?: number
stack?: boolean | { threshold: number }
getContainer?: () => HTMLElement
}
```
### 5.4 Pika API 设计
```tsx
// 静态方法
Notification.show(options: NotificationOptions): NotificationInstance
Notification.success(options: NotificationOptions): NotificationInstance
Notification.error(options: NotificationOptions): NotificationInstance
Notification.warning(options: NotificationOptions): NotificationInstance
Notification.info(options: NotificationOptions): NotificationInstance
Notification.destroy(key?: string): void
Notification.destroyAll(): void
// 配置
Notification.config(config: NotificationConfig): void
// Hooks
const [NotificationApi, contextHolder] = Notification.useNotification()
```
---
## 六、Progress 组件
### 6.1 组件概述
显示操作进度,支持线条、圆形、仪表盘三种类型。
### 6.2 antd API 完整清单
**通用属性:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| format | 格式化函数 | (percent, successPercent) => ReactNode | (percent) => percent + `%` |
| percent | 进度值 | number | 0 |
| railColor | 未填充部分颜色 | string | - |
| showInfo | 是否显示信息 | boolean | true |
| status | 状态 | `success \| exception \| normal \| active` | - |
| strokeColor | 进度条颜色 | string \| string[] \| { from: string; to: string; direction: string } | - |
| strokeLinecap | 线帽样式 | `round \| butt \| square` | `round` |
| success | 成功部分配置 | `{ percent: number, strokeColor: string }` | - |
| type | 类型 | `line \| circle \| dashboard` | `line` |
| size | 尺寸 | number \| [number, number] \| { width: number, height: number } \| "small" \| "medium" | "medium" |
**line 类型专属:**
| 属性 | 说明 | 类型 |
|------|------|------|
| steps | 总步数 | number |
| strokeColor | 进度条颜色,支持渐变 | string \| string[] |
**circle/dashboard 类型专属:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| strokeWidth | 圆形宽度(百分比) | number | 6 |
| strokeColor | 圆形颜色 | string \| { number%: string } | - |
**dashboard 类型专属:**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| gapDegree | 间隙角度(0-295) | number | 75 |
| gapPlacement | 间隙位置 | `top \| bottom \| start \| end` | `bottom` |
### 6.3 Pika Props 定义
```tsx
export type ProgressType = 'line' | 'circle' | 'dashboard'
export type ProgressStatus = 'success' | 'exception' | 'normal' | 'active'
export type ProgressSize = 'small' | 'middle' | 'large'
export type StrokeLinecap = 'round' | 'butt' | 'square'
export interface ProgressProps {
type?: ProgressType
status?: ProgressStatus
size?: ProgressSize
percent?: number
strokeColor?: string | string[] | { from: string; to: string; direction: 'left-right' | 'right-left' | 'top-bottom' | 'bottom-top' }
railColor?: string
strokeWidth?: number
strokeLinecap?: StrokeLinecap
gapDegree?: number
gapPlacement?: 'top' | 'bottom' | 'start' | 'end'
steps?: number
showInfo?: boolean
format?: (percent: number, successPercent?: number) => ReactNode
success?: { percent?: number; strokeColor?: string }
onChange?: (percent: number) => void
className?: string
style?: CSSProperties
}
```
---
## 七、Spin 组件
### 7.1 组件概述
页面或区块的加载状态指示器。
### 7.2 antd API 完整清单
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| delay | 延迟显示加载状态(毫秒) | number | - |
| description | 自定义描述文字 | ReactNode | - |
| fullscreen | 全屏模式 | boolean | false |
| indicator | 自定义加载指示器 | ReactNode | - |
| percent | 进度百分比,设为 `auto` 显示不定进度 | number \| 'auto' | - |
| size | 尺寸 | `small \| middle \| large` | `middle` |
| spinning | 是否显示 | boolean | true |
| tip | 自定义描述文字 (deprecated) | ReactNode | - |
| wrapperClassName | 包裹层类名 (deprecated) | string | - |
### 7.3 Pika Props 定义
```tsx
export type SpinSize = 'small' | 'middle' | 'large'
export interface SpinProps {
size?: SpinSize
spinning?: boolean
delay?: number
fullscreen?: boolean
indicator?: ReactNode
percent?: number | 'auto'
description?: ReactNode
tip?: ReactNode // deprecated, use description
onChange?: (spinning: boolean) => void
className?: string
style?: CSSProperties
}
```
### 7.4 Pika 样式规范
```tsx
// TSX
<div
className={styles.root}
data-size={size}
data-fullscreen={fullscreen || undefined}
data-spinning={spinning || undefined}
>
{fullscreen && <div className={styles.mask} data-mask />}
<div className={styles.container}>
<span className={styles.indicator}>{indicator || <DefaultIndicator />}</span>
{percent !== undefined && (
<span className={styles.progress}>{percent}%</span>
)}
{description && <span className={styles.description}>{description}</span>}
</div>
</div>
```
---
## 八、Result 组件
### 8.1 组件概述
展示操作结果,包含状态图标、标题、描述和操作按钮。
### 8.2 antd API 完整清单
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| extra | 操作区域 | ReactNode | - |
| icon | 自定义图标 | ReactNode | - |
| status | 状态 | `success \| error \| info \| warning \| 404 \| 403 \| 500` | `info` |
| subTitle | 副标题 | ReactNode | - |
| title | 标题 | ReactNode | - |
### 8.3 Pika Props 定义
```tsx
export type ResultStatus = 'success' | 'error' | 'info' | 'warning' | 404 | 403 | 500
export interface ResultProps {
status?: ResultStatus
title?: ReactNode
subTitle?: ReactNode
description?: ReactNode
icon?: ReactNode
extra?: ReactNode
className?: string
style?: CSSProperties
}
```
---
## 九、Drawer 组件
### 9.1 组件概述
从屏幕边缘滑出的面板,包含标题、内容和操作区。
### 9.2 antd API 完整清单
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| afterOpenChange | 动画结束回调 | function(open) | - |
| className | 面板类名 | string | - |
| closable | 关闭按钮配置 | boolean \| { closeIcon?: ReactNode; placement?: 'start' \| 'end' } | true |
| destroyOnHidden | 关闭时销毁内容 | boolean | false |
| extra | 额外操作区 | ReactNode | - |
| footer | 底部内容 | ReactNode | - |
| forceRender | 强制渲染 | boolean | false |
| focusable | 焦点管理 | `{ trap?: boolean, focusTriggerAfterClose?: boolean }` | - |
| getContainer | 挂载节点 | HTMLElement \| () => HTMLElement \| Selectors \| false | body |
| headerStyle | 头部样式 (deprecated) | CSSProperties | - |
| height | 高度 (deprecated) | string \| number | 378 |
| keyboard | ESC 关闭 | boolean | true |
| loading | 显示骨架屏 | boolean | false |
| mask | 遮罩配置 | boolean \| `{ enabled?: boolean, blur?: boolean }` | true |
| maskClosable | 点击遮罩关闭 | boolean | true |
| maxSize | 可调整的最大尺寸 | number | - |
| open | 是否显示 | boolean | false |
| placement | 位置 | `top \| right \| bottom \| left` | `right` |
| push | 嵌套推动行为 | boolean \| { distance: string \| number } | { distance: 180 } |
| resizable | 可调整尺寸 | boolean \| ResizableConfig | - |
| rootClassName | 根元素类名 | string | - |
| rootStyle | 根元素样式 | CSSProperties | - |
| size | 预设尺寸 | 'default' \| 'large' \| number \| string | 'default' |
| style | 面板样式 | CSSProperties | - |
| styles | 语义化样式 | Record<SemanticDOM, CSSProperties> | - |
| title | 标题 | ReactNode | - |
| width | 宽度 (deprecated) | string \| number | 378 |
| zIndex | z-index | number | 1000 |
| onClose | 关闭回调 | function(e) | - |
| drawerRender | 自定义渲染 | (node: ReactNode) => ReactNode | - |
### 9.3 Pika Props 定义
```tsx
export type DrawerPlacement = 'top' | 'right' | 'bottom' | 'left'
export type DrawerSize = 'default' | 'large' | number
export interface DrawerProps {
open?: boolean
title?: ReactNode
content?: ReactNode
footer?: ReactNode | null
placement?: DrawerPlacement
size?: DrawerSize
closable?: boolean
closeIcon?: ReactNode
closePlacement?: 'start' | 'end'
mask?: boolean
maskClosable?: boolean
keyboard?: boolean
loading?: boolean
extra?: ReactNode
resizable?: boolean
maxSize?: number
getContainer?: HTMLElement | (() => HTMLElement) | false
zIndex?: number
onClose?: (e: React.MouseEvent) => void
afterOpenChange?: (open: boolean) => void
className?: string
style?: CSSProperties
}
```
---
## 十、Popconfirm 组件
### 10.1 组件概述
轻量级气泡确认框,用于需要用户确认的操作。
### 10.2 antd API 完整清单
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| cancelButtonProps | 取消按钮 props | ButtonProps | - |
| cancelText | 取消按钮文字 | string | `Cancel` |
| disabled | 是否禁用 | boolean | false |
| icon | 自定义图标 | ReactNode | <ExclamationCircle /> |
| okButtonProps | 确认按钮 props | ButtonProps | - |
| okText | 确认按钮文字 | string | `OK` |
| okType | 确认按钮类型 | string | `primary` |
| showCancel | 显示取消按钮 | boolean | true |
| title | 标题 | ReactNode \| () => ReactNode | - |
| description | 描述 | ReactNode \| () => ReactNode | - |
| onCancel | 取消回调 | function(e) | - |
| onConfirm | 确认回调 | function(e) | - |
| onPopupClick | 弹出层点击回调 | function(e) | - |
**弹出属性 (共享 Tooltip/Popover/Popconfirm):**
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| align | 对齐配置 | object | - |
| arrow | 箭头配置 | boolean \| { pointAtCenter: boolean } | true |
| autoAdjustOverflow | 自动调整位置 | boolean | true |
| color | 背景色 | string | - |
| defaultOpen | 默认打开 | boolean | false |
| destroyOnHidden | 关闭时销毁 | boolean | false |
| fresh | 每次打开刷新内容 | boolean | false |
| getPopupContainer | 弹出层容器 | (triggerNode: HTMLElement) => HTMLElement | () => document.body |
| mouseEnterDelay | 鼠标进入延迟(秒) | number | 0.1 |
| mouseLeaveDelay | 鼠标离开延迟(秒) | number | 0.1 |
| placement | 位置 | `top \| left \| right \| bottom \| topLeft \| topRight \| bottomLeft \| bottomRight \| leftTop \| leftBottom \| rightTop \| rightBottom` | `top` |
| trigger | 触发方式 | `hover \| focus \| click \| contextMenu` \| Array | `hover` |
| open | 是否打开 | boolean | false |
| zIndex | z-index | number | - |
| onOpenChange | 打开状态变化回调 | (open: boolean) => void | - |
### 10.3 Pika Props 定义
```tsx
export type PopconfirmPlacement =
| 'top'
| 'topLeft'
| 'topRight'
| 'bottom'
| 'bottomLeft'
| 'bottomRight'
| 'left'
| 'leftTop'
| 'leftBottom'
| 'right'
| 'rightTop'
| 'rightBottom'
export interface PopconfirmProps {
title?: ReactNode
description?: ReactNode
icon?: ReactNode
okText?: ReactNode
cancelText?: ReactNode
okType?: ButtonVariant
okButtonProps?: ButtonProps
cancelButtonProps?: ButtonProps
showCancel?: boolean
disabled?: boolean
placement?: PopconfirmPlacement
trigger?: 'hover' | 'click' | 'focus' | 'contextMenu'
arrow?: boolean
autoAdjustOverflow?: boolean
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement
mouseEnterDelay?: number
mouseLeaveDelay?: number
open?: boolean
defaultOpen?: boolean
onConfirm?: (e: React.MouseEvent) => void
onCancel?: (e: React.MouseEvent) => void
onOpenChange?: (open: boolean) => void
className?: string
style?: CSSProperties
}
```
---
## 十一、通用 Token 设计
### 11.1 反馈组件 Token
```ts
export const feedbackTokens = {
alert: {
padding: { small: '8px 12px', middle: '12px 16px', large: '16px 24px' },
radius: 'var(--nv-radius-middle)',
iconSize: { small: 16, middle: 20, large: 24 },
},
message: {
width: 360,
padding: '12px 16px',
radius: 'var(--nv-radius-middle)',
zIndex: 2010,
},
notification: {
width: 384,
padding: '16px 24px',
radius: 'var(--nv-radius-middle)',
zIndex: 2050,
},
modal: {
width: { small: 400, middle: 520, large: 720 },
radius: 'var(--nv-radius-large)',
padding: '24px',
zIndex: 1000,
},
drawer: {
width: { default: 378, large: 736 },
height: 378,
radius: 0,
zIndex: 1000,
},
progress: {
lineHeight: 4,
circleStrokeWidth: 6,
dashboardGapDegree: 75,
},
spin: {
dotSize: { small: 14, middle: 20, large: 32 },
},
popconfirm: {
padding: '12px 16px',
radius: 'var(--nv-radius-middle)',
zIndex: 1060,
},
} as const
```
### 11.2 状态颜色映射
```ts
export const STATUS_COLORS = {
success: {
bg: 'var(--nv-color-success-bg)',
border: 'var(--nv-color-success-border)',
color: 'var(--nv-color-success)',
},
warning: {
bg: 'var(--nv-color-warning-bg)',
border: 'var(--nv-color-warning-border)',
color: 'var(--nv-color-warning)',
},
error: {
bg: 'var(--nv-color-error-bg)',
border: 'var(--nv-color-error-border)',
color: 'var(--nv-color-error)',
},
info: {
bg: 'var(--nv-color-info-bg)',
border: 'var(--nv-color-info-border)',
color: 'var(--nv-color-info)',
},
} as const
```
---
## 十二、文件结构
```
src/components/feedback/
├── alert/
│ ├── Alert.tsx
│ ├── Alert.module.css
│ ├── Alert.test.tsx
│ └── index.ts
├── message/
│ ├── Message.tsx
│ ├── Message.module.css
│ ├── Message.test.tsx
│ └── index.ts
├── modal/
│ ├── Modal.tsx
│ ├── Modal.module.css
│ ├── Modal.test.tsx
│ └── index.ts
├── notification/
│ ├── Notification.tsx
│ ├── Notification.module.css
│ ├── Notification.test.tsx
│ └── index.ts
├── progress/
│ ├── Progress.tsx
│ ├── Progress.module.css
│ ├── Progress.test.tsx
│ └── index.ts
├── spin/
│ ├── Spin.tsx
│ ├── Spin.module.css
│ ├── Spin.test.tsx
│ └── index.ts
├── result/
│ ├── Result.tsx
│ ├── Result.module.css
│ ├── Result.test.tsx
│ └── index.ts
├── drawer/
│ ├── Drawer.tsx
│ ├── Drawer.module.css
│ ├── Drawer.test.tsx
│ └── index.ts
├── popconfirm/
│ ├── Popconfirm.tsx
│ ├── Popconfirm.module.css
│ ├── Popconfirm.test.tsx
│ └── index.ts
└── tokens/
└── index.ts
```
---
## 十三、开发优先级
| 阶段 | 组件 | 原因 |
|------|------|------|
| Phase 1 | Alert, Spin, Progress | 基础反馈组件,使用频率高 |
| Phase 2 | Modal, Message | 需要用户交互的核心组件 |
| Phase 3 | Notification, Result | 复杂反馈场景 |
| Phase 4 | Drawer, Popconfirm | 边缘场景组件 |
---
## 十四、功能检查清单
### Alert
- [ ] 四种类型: success/info/warning/error
- [ ] 三种尺寸: small/middle/large
- [ ] 标题和描述
- [ ] 自定义图标
- [ ] 可关闭 (closable)
- [ ] 顶部横幅模式 (banner)
- [ ] 自定义操作 (action)
- [ ] 动画过渡
### Message
- [ ] 五种类型: success/error/warning/info/loading
- [ ] 自动关闭 (duration)
- [ ] 手动关闭
- [ ] 自定义图标
- [ ] 最大数量限制 (maxCount)
- [ ] 位置配置 (placement)
- [ ] 悬停暂停 (pauseOnHover)
- [ ] 全局配置 (config)
- [ ] Hooks API (useMessage)
### Modal
- [ ] 打开/关闭状态 (open)
- [ ] 标题和内容
- [ ] 自定义底部 (footer)
- [ ] 居中显示 (centered)
- [ ] 确认/取消按钮
- [ ] 按钮 loading 状态
- [ ] 遮罩配置 (mask)
- [ ] 键盘 ESC 关闭
- [ ] 宽度配置
- [ ] 静态方法 (Modal.confirm 等)
- [ ] Hooks API (useModal)
### Notification
- [ ] 五种类型
- [ ] 标题和描述
- [ ] 自动关闭
- [ ] 手动关闭
- [ ] 六种位置
- [ ] 堆叠显示 (stack)
- [ ] 最大数量
- [ ] 进度条显示
- [ ] 自定义操作按钮
- [ ] Hooks API
### Progress
- [ ] 三种类型: line/circle/dashboard
- [ ] 百分比显示
- [ ] 自定义颜色
- [ ] 渐变色
- [ ] 线帽样式
- [ ] 步骤显示
- [ ] 成功部分高亮
- [ ] 格式化函数
### Spin
- [ ] 三种尺寸
- [ ] 加载指示器
- [ ] 全屏模式
- [ ] 延迟显示
- [ ] 自定义描述
- [ ] 进度显示
### Result
- [ ] 七种状态
- [ ] 标题和描述
- [ ] 自定义图标
- [ ] 操作按钮区
### Drawer
- [ ] 四种位置
- [ ] 预设尺寸
- [ ] 可调整尺寸
- [ ] 遮罩配置
- [ ] 键盘关闭
- [ ] 嵌套推动
### Popconfirm
- [ ] 标题和描述
- [ ] 确认/取消按钮
- [ ] 自定义图标
- [ ] 多种触发方式
- [ ] 12 种弹出位置
- [ ] 自动调整位置
---
## 十五、AI 提示工程
```
开发 Pika 反馈组件时,遵循以下提示词:
1. 导入: import { 组件名 } from '@Pika/ui/feedback/组件名'
2. 尺寸: size 始终为 'small' | 'middle' | 'large'
3. 状态: status 始终为 'default' | 'success' | 'warning' | 'error' | 'info'
4. 样式: 使用 data-* 属性绑定,className 只用于自定义类
5. 事件: on + 动词 + 名词,如 onClose, onConfirm
6. 布尔: 使用 show/open/disabled 等肯定形式
7. 类型: 使用联合类型字面量,不用 boolean 隐藏选项
```