1041 lines
30 KiB
Markdown
1041 lines
30 KiB
Markdown
# 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 隐藏选项
|
||
```
|