902 lines
20 KiB
Markdown
902 lines
20 KiB
Markdown
|
|
# Pika 其他组件开发计划与规范
|
|||
|
|
|
|||
|
|
> 基于 Pika 设计规范,参照 Ant Design 剩余组件体系,构建专为 AI 代码生成优化的其他组件库。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、组件总览
|
|||
|
|
|
|||
|
|
Pika 其他组件分为以下几类:
|
|||
|
|
|
|||
|
|
| 类别 | 组件 | antd 对标 | 优先级 |
|
|||
|
|
|------|------|-----------|--------|
|
|||
|
|
| **通用组件** | Affix, Anchor, App, ConfigProvider, BackTop, Watermark | Ant Design 通用组件 | P0-P1 |
|
|||
|
|
| **容器组件** | Drawer | Ant Design 抽屉 | P1 |
|
|||
|
|
| **数据展示** | List | Ant Design 列表 | P1 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、核心设计原则(与根规范一致)
|
|||
|
|
|
|||
|
|
### 2.1 AI 优先设计原则
|
|||
|
|
|
|||
|
|
| 原则 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| **零歧义** | Props 名称自解释,无简称、无隐式行为 |
|
|||
|
|
| **零默认假设** | 所有视觉行为显式声明 |
|
|||
|
|
| **一致性** | 相同概念用相同 prop 名 |
|
|||
|
|
| **扁平化** | 最多一层嵌套 |
|
|||
|
|
| **确定性** | 相同输入始终产生相同输出 |
|
|||
|
|
|
|||
|
|
### 2.2 统一尺寸体系
|
|||
|
|
|
|||
|
|
所有组件使用统一的三级尺寸体系:
|
|||
|
|
|
|||
|
|
| 级别 | 说明 | 常用值 |
|
|||
|
|
|------|------|-------|
|
|||
|
|
| **small** | 小尺寸 | 紧凑列表、表格内 |
|
|||
|
|
| **middle** | 中尺寸(默认) | 默认使用 |
|
|||
|
|
| **large** | 大尺寸 | 突出显示、重点元素 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、通用组件
|
|||
|
|
|
|||
|
|
### 3.1 Affix 固钉
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
将页面元素固定在可视区域内,常用于导航栏、侧边栏、回到顶部按钮等。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface AffixProps {
|
|||
|
|
/** 距离窗口顶部达到指定偏移量后触发 */
|
|||
|
|
offsetTop?: number;
|
|||
|
|
/** 距离窗口底部达到指定偏移量后触发 */
|
|||
|
|
offsetBottom?: number;
|
|||
|
|
/** 指定 Affix 挂载的 HTML 节点 */
|
|||
|
|
target?: () => HTMLElement | null;
|
|||
|
|
/** 监听滚动事件的容器 */
|
|||
|
|
getContainer?: () => HTMLElement | Window;
|
|||
|
|
/** 固定状态改变时触发的回调 */
|
|||
|
|
onChange?: (isAffixed: boolean) => void;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
/** 样式类名 */
|
|||
|
|
className?: string;
|
|||
|
|
/** 自定义样式 */
|
|||
|
|
style?: React.CSSProperties;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { Affix, Button } from '@Pika/ui/affix';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
<Affix offsetTop={10}>
|
|||
|
|
<Button variant="solid">固钉在顶部</Button>
|
|||
|
|
</Affix>;
|
|||
|
|
|
|||
|
|
// 固钉在底部
|
|||
|
|
<Affix offsetBottom={10}>
|
|||
|
|
<Button variant="solid">固钉在底部</Button>
|
|||
|
|
</Affix>;
|
|||
|
|
|
|||
|
|
// 自定义容器
|
|||
|
|
<Affix target={() => document.getElementById('scroll-container')} offsetTop={10}>
|
|||
|
|
<Button variant="solid">在容器内固钉</Button>
|
|||
|
|
</Affix>;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
--nv-affix-z-index: 10;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.2 Anchor 锚点
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
用于跳转到页面指定位置,或显示当前滚动位置。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface AnchorProps {
|
|||
|
|
/** 锚点方向 */
|
|||
|
|
direction?: 'vertical' | 'horizontal';
|
|||
|
|
/** 当前激活的锚点链接 */
|
|||
|
|
activeLink?: string;
|
|||
|
|
/** 锚点滚动偏移量 */
|
|||
|
|
targetOffset?: number;
|
|||
|
|
/** 点击锚点链接的回调 */
|
|||
|
|
onClick?: (
|
|||
|
|
e: React.MouseEvent<HTMLElement>,
|
|||
|
|
link: { href: string; title: ReactNode }
|
|||
|
|
) => void;
|
|||
|
|
/** 锚点链接改变时的回调 */
|
|||
|
|
onChange?: (currentActiveLink: string) => void;
|
|||
|
|
/** 获取锚点容器 */
|
|||
|
|
getContainer?: () => HTMLElement | Window;
|
|||
|
|
/** 是否改变 hash */
|
|||
|
|
hash?: boolean;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
/** 样式类名 */
|
|||
|
|
className?: string;
|
|||
|
|
/** 自定义样式 */
|
|||
|
|
style?: React.CSSProperties;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface AnchorLinkProps {
|
|||
|
|
/** 锚点链接 */
|
|||
|
|
href: string;
|
|||
|
|
/** 锚点文本 */
|
|||
|
|
title: ReactNode;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { Anchor } from '@Pika/ui/anchor';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
<Anchor>
|
|||
|
|
<Anchor.Link href="#section-1" title="第一章" />
|
|||
|
|
<Anchor.Link href="#section-2" title="第二章">
|
|||
|
|
<Anchor.Link href="#section-2-1" title="2.1 小节" />
|
|||
|
|
<Anchor.Link href="#section-2-2" title="2.2 小节" />
|
|||
|
|
</Anchor.Link>
|
|||
|
|
<Anchor.Link href="#section-3" title="第三章" />
|
|||
|
|
</Anchor>;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
--nv-anchor-link-height: 32px;
|
|||
|
|
--nv-anchor-link-color: var(--nv-text-color-secondary);
|
|||
|
|
--nv-anchor-link-active-color: var(--nv-color-primary);
|
|||
|
|
--nv-anchor-link-active-width: 2px;
|
|||
|
|
--nv-anchor-wrapper-padding: 4px 0;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.3 App 包裹组件
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
提供全局上下文,用于 Message、Modal、Notification 等组件的静态方法调用。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface AppProps {
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface AppContextProps {
|
|||
|
|
message: MessageStatic;
|
|||
|
|
modal: ModalStatic;
|
|||
|
|
notification: NotificationStatic;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export declare function useApp(): AppContextProps;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { App, Button } from '@Pika/ui/app';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
function AppDemo() {
|
|||
|
|
const { message, modal, notification } = App.useApp();
|
|||
|
|
|
|||
|
|
const showMessage = () => {
|
|||
|
|
message.success('操作成功');
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const showModal = () => {
|
|||
|
|
modal.info({ title: '提示', content: '这是一条提示信息' });
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<App>
|
|||
|
|
<Button onClick={showMessage}>显示消息</Button>
|
|||
|
|
<Button onClick={showModal}>显示对话框</Button>
|
|||
|
|
</App>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P0
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.4 ConfigProvider 全局配置
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
为组件提供统一的全局配置,包括主题、语言、国际化等。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface ConfigProviderProps {
|
|||
|
|
/** 主题配置 */
|
|||
|
|
theme?: {
|
|||
|
|
token?: Record<string, any>;
|
|||
|
|
components?: Record<string, any>;
|
|||
|
|
algorithm?: 'default' | 'dark' | 'compact' | Array<'default' | 'dark' | 'compact'>;
|
|||
|
|
};
|
|||
|
|
/** 语言包 */
|
|||
|
|
locale?: Record<string, any>;
|
|||
|
|
/** 全局 zIndex */
|
|||
|
|
zIndex?: number;
|
|||
|
|
/** 设置主题色 */
|
|||
|
|
colorPrimary?: string;
|
|||
|
|
/** 设置图标前缀 */
|
|||
|
|
iconPrefixCls?: string;
|
|||
|
|
/** 设置组件类名前缀 */
|
|||
|
|
prefixCls?: string;
|
|||
|
|
/** 设置弹框的默认渲染容器 */
|
|||
|
|
getPopupContainer?: (node: HTMLElement) => HTMLElement;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { ConfigProvider, Button } from '@Pika/ui/config-provider';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
<ConfigProvider
|
|||
|
|
theme={{
|
|||
|
|
token: {
|
|||
|
|
colorPrimary: '#1890ff',
|
|||
|
|
borderRadius: 8,
|
|||
|
|
},
|
|||
|
|
}}
|
|||
|
|
>
|
|||
|
|
<App />
|
|||
|
|
</ConfigProvider>;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
与根设计规范中的 Token 一致。
|
|||
|
|
|
|||
|
|
#### 开发优先级:P0
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.5 BackTop 回到顶部
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
提供快速回到页面顶部的功能。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface BackTopProps {
|
|||
|
|
/** 距离顶部多少像素时显示 */
|
|||
|
|
visibilityHeight?: number;
|
|||
|
|
/** 点击回调 */
|
|||
|
|
onClick?: () => void;
|
|||
|
|
/** 监听滚动的容器 */
|
|||
|
|
target?: () => HTMLElement | Window;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
/** 样式类名 */
|
|||
|
|
className?: string;
|
|||
|
|
/** 自定义样式 */
|
|||
|
|
style?: React.CSSProperties;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { BackTop } from '@Pika/ui/back-top';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
<BackTop />;
|
|||
|
|
|
|||
|
|
// 自定义图标
|
|||
|
|
<BackTop>
|
|||
|
|
<div style={{
|
|||
|
|
height: 40,
|
|||
|
|
width: 40,
|
|||
|
|
lineHeight: '40px',
|
|||
|
|
borderRadius: 4,
|
|||
|
|
backgroundColor: '#1088e9',
|
|||
|
|
color: '#fff',
|
|||
|
|
textAlign: 'center',
|
|||
|
|
fontSize: 20,
|
|||
|
|
}}>
|
|||
|
|
UP
|
|||
|
|
</div>
|
|||
|
|
</BackTop>;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
--nv-back-top-size: 40px;
|
|||
|
|
--nv-back-top-z-index: 10;
|
|||
|
|
--nv-back-top-color: var(--nv-color-primary);
|
|||
|
|
--nv-back-top-hover-color: var(--nv-color-primary-hover);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.6 Watermark 水印
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
为页面或元素添加水印,防止截图泄露或证明来源。(注意:在 FEEDBACK_COMPONENTS.md 中已有定义,这里补充完整)
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface WatermarkProps {
|
|||
|
|
/** 水印文字 */
|
|||
|
|
content?: string | string[];
|
|||
|
|
/** 自定义图片水印 */
|
|||
|
|
image?: string;
|
|||
|
|
/** 水印宽度(文字模式时为单个文字宽度) */
|
|||
|
|
width?: number;
|
|||
|
|
/** 水印高度(文字模式时为单个文字高度) */
|
|||
|
|
height?: number;
|
|||
|
|
/** 旋转角度 */
|
|||
|
|
rotate?: number;
|
|||
|
|
/** 水印之间的水平间距 */
|
|||
|
|
gap?: [number, number];
|
|||
|
|
/** 水印在 canvas 上绘制时的偏移量 */
|
|||
|
|
offset?: [number, number];
|
|||
|
|
/** 文字样式 */
|
|||
|
|
font?: {
|
|||
|
|
color?: string;
|
|||
|
|
fontSize?: number;
|
|||
|
|
fontFamily?: string;
|
|||
|
|
fontWeight?: 'normal' | 'light' | 'weight' | number;
|
|||
|
|
};
|
|||
|
|
/** 水印层级 */
|
|||
|
|
zIndex?: number;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { Watermark, Card } from '@Pika/ui/watermark';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
<Watermark content="Pika UI">
|
|||
|
|
<Card style={{ width: 600, height: 400 }}>
|
|||
|
|
<p>这是一些内容,会有水印覆盖</p>
|
|||
|
|
</Card>
|
|||
|
|
</Watermark>;
|
|||
|
|
|
|||
|
|
// 多行水印
|
|||
|
|
<Watermark content={['Pika UI', '内部文档']}>
|
|||
|
|
<div>内容</div>
|
|||
|
|
</Watermark>;
|
|||
|
|
|
|||
|
|
// 自定义样式
|
|||
|
|
<Watermark
|
|||
|
|
content="Pika UI"
|
|||
|
|
rotate={-25}
|
|||
|
|
font={{
|
|||
|
|
color: 'rgba(0, 0, 0, 0.08)',
|
|||
|
|
fontSize: 16,
|
|||
|
|
}}
|
|||
|
|
>
|
|||
|
|
<div>内容</div>
|
|||
|
|
</Watermark>;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
--nv-watermark-font-size: 14px;
|
|||
|
|
--nv-watermark-font-color: rgba(0, 0, 0, 0.08);
|
|||
|
|
--nv-watermark-rotate: -22deg;
|
|||
|
|
--nv-watermark-gap: [100, 100];
|
|||
|
|
--nv-watermark-z-index: 9;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P3
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、容器组件
|
|||
|
|
|
|||
|
|
### 4.1 Drawer 抽屉
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
抽屉组件,用于从屏幕边缘滑出内容面板,常用于详情页、表单页、筛选页等。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export type DrawerPlacement = 'top' | 'right' | 'bottom' | 'left';
|
|||
|
|
export type DrawerSize = 'small' | 'middle' | 'large' | number | string;
|
|||
|
|
|
|||
|
|
export interface DrawerProps {
|
|||
|
|
/** 抽屉是否可见 */
|
|||
|
|
open: boolean;
|
|||
|
|
/** 抽屉标题 */
|
|||
|
|
title?: ReactNode;
|
|||
|
|
/** 抽屉宽度(placement 为 left/right 时生效) */
|
|||
|
|
width?: number | string;
|
|||
|
|
/** 抽屉高度(placement 为 top/bottom 时生效) */
|
|||
|
|
height?: number | string;
|
|||
|
|
/** 抽屉尺寸预设 */
|
|||
|
|
size?: DrawerSize;
|
|||
|
|
/** 抽屉放置位置 */
|
|||
|
|
placement?: DrawerPlacement;
|
|||
|
|
/** 是否显示遮罩 */
|
|||
|
|
mask?: boolean;
|
|||
|
|
/** 点击遮罩是否关闭 */
|
|||
|
|
maskClosable?: boolean;
|
|||
|
|
/** 是否显示右上角关闭按钮 */
|
|||
|
|
closable?: boolean;
|
|||
|
|
/** 自定义关闭图标 */
|
|||
|
|
closeIcon?: ReactNode;
|
|||
|
|
/** 点击关闭图标的回调 */
|
|||
|
|
onClose?: () => void;
|
|||
|
|
/** 抽屉打开后的回调 */
|
|||
|
|
afterOpenChange?: (open: boolean) => void;
|
|||
|
|
/** 抽屉的容器 */
|
|||
|
|
getContainer?: HTMLElement | (() => HTMLElement) | null;
|
|||
|
|
/** 预渲染,防止抖动 */
|
|||
|
|
forceRender?: boolean;
|
|||
|
|
/** 关闭时销毁 Drawer 里的子元素 */
|
|||
|
|
destroyOnClose?: boolean;
|
|||
|
|
/** 抽屉的样式 */
|
|||
|
|
style?: React.CSSProperties;
|
|||
|
|
/** 抽屉标题的样式 */
|
|||
|
|
headerStyle?: React.CSSProperties;
|
|||
|
|
/** 抽屉内容的样式 */
|
|||
|
|
bodyStyle?: React.CSSProperties;
|
|||
|
|
/** 自定义遮罩样式 */
|
|||
|
|
maskStyle?: React.CSSProperties;
|
|||
|
|
/** 抽屉的类名 */
|
|||
|
|
className?: string;
|
|||
|
|
/** 抽屉根元素的类名 */
|
|||
|
|
rootClassName?: string;
|
|||
|
|
/** 是否支持键盘 esc 关闭 */
|
|||
|
|
keyboard?: boolean;
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
/** 抽屉页脚 */
|
|||
|
|
footer?: ReactNode;
|
|||
|
|
/** 页脚的样式 */
|
|||
|
|
footerStyle?: React.CSSProperties;
|
|||
|
|
/** 是否显示页脚 */
|
|||
|
|
footer?: ReactNode | null;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { Drawer, Button, Form, Input } from '@Pika/ui/drawer';
|
|||
|
|
|
|||
|
|
function DrawerDemo() {
|
|||
|
|
const [open, setOpen] = useState(false);
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<>
|
|||
|
|
<Button onClick={() => setOpen(true)}>打开抽屉</Button>
|
|||
|
|
<Drawer
|
|||
|
|
title="基本抽屉"
|
|||
|
|
width={480}
|
|||
|
|
open={open}
|
|||
|
|
onClose={() => setOpen(false)}
|
|||
|
|
>
|
|||
|
|
<p>这是抽屉的内容</p>
|
|||
|
|
<p>可以放置任何内容</p>
|
|||
|
|
</Drawer>
|
|||
|
|
</>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 表单抽屉
|
|||
|
|
function FormDrawer() {
|
|||
|
|
const [open, setOpen] = useState(false);
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<>
|
|||
|
|
<Button onClick={() => setOpen(true)}>新建</Button>
|
|||
|
|
<Drawer
|
|||
|
|
title="新建"
|
|||
|
|
width={480}
|
|||
|
|
open={open}
|
|||
|
|
onClose={() => setOpen(false)}
|
|||
|
|
footer={
|
|||
|
|
<div style={{ textAlign: 'right' }}>
|
|||
|
|
<Button onClick={() => setOpen(false)} style={{ marginRight: 8 }}>
|
|||
|
|
取消
|
|||
|
|
</Button>
|
|||
|
|
<Button variant="solid" onClick={() => setOpen(false)}>
|
|||
|
|
确定
|
|||
|
|
</Button>
|
|||
|
|
</div>
|
|||
|
|
}
|
|||
|
|
>
|
|||
|
|
<Form layout="vertical">
|
|||
|
|
<Form.Item label="名称" name="name">
|
|||
|
|
<Input placeholder="请输入名称" />
|
|||
|
|
</Form.Item>
|
|||
|
|
<Form.Item label="描述" name="description">
|
|||
|
|
<TextArea placeholder="请输入描述" rows={4} />
|
|||
|
|
</Form.Item>
|
|||
|
|
</Form>
|
|||
|
|
</Drawer>
|
|||
|
|
</>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
--nv-drawer-z-index: 1000;
|
|||
|
|
--nv-drawer-header-height: 56px;
|
|||
|
|
--nv-drawer-header-padding: 16px 24px;
|
|||
|
|
--nv-drawer-body-padding: 24px;
|
|||
|
|
--nv-drawer-footer-padding: 16px 24px;
|
|||
|
|
--nv-drawer-mask-bg: rgba(0, 0, 0, 0.45);
|
|||
|
|
--nv-drawer-bg: #fff;
|
|||
|
|
--nv-drawer-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|||
|
|
--nv-drawer-width-small: 378px;
|
|||
|
|
--nv-drawer-width-middle: 480px;
|
|||
|
|
--nv-drawer-width-large: 736px;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、数据展示组件
|
|||
|
|
|
|||
|
|
### 5.1 List 列表
|
|||
|
|
|
|||
|
|
#### 组件定位
|
|||
|
|
通用列表组件,用于展示一系列同类数据。
|
|||
|
|
|
|||
|
|
#### Props 定义
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
export interface ListProps<T> {
|
|||
|
|
/** 列表数据 */
|
|||
|
|
data?: T[];
|
|||
|
|
/** 列表尺寸 */
|
|||
|
|
size?: 'small' | 'middle' | 'large';
|
|||
|
|
/** 列表边框 */
|
|||
|
|
bordered?: boolean;
|
|||
|
|
/** 是否显示分割线 */
|
|||
|
|
split?: boolean;
|
|||
|
|
/** 列表项头部 */
|
|||
|
|
header?: ReactNode;
|
|||
|
|
/** 列表项底部 */
|
|||
|
|
footer?: ReactNode;
|
|||
|
|
/** 列表加载状态 */
|
|||
|
|
loading?: boolean;
|
|||
|
|
/** 空列表时显示的内容 */
|
|||
|
|
empty?: ReactNode;
|
|||
|
|
/** 渲染列表项 */
|
|||
|
|
renderItem?: (item: T, index: number) => ReactNode;
|
|||
|
|
/** 列表项布局 */
|
|||
|
|
itemLayout?: 'horizontal' | 'vertical';
|
|||
|
|
/** 列表行高 */
|
|||
|
|
rowKey?: string | ((item: T) => string);
|
|||
|
|
/** 是否显示网格 */
|
|||
|
|
grid?: {
|
|||
|
|
gutter?: number;
|
|||
|
|
column?: number;
|
|||
|
|
xs?: number;
|
|||
|
|
sm?: number;
|
|||
|
|
md?: number;
|
|||
|
|
lg?: number;
|
|||
|
|
xl?: number;
|
|||
|
|
xxl?: number;
|
|||
|
|
};
|
|||
|
|
/** 子元素 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
/** 样式类名 */
|
|||
|
|
className?: string;
|
|||
|
|
/** 自定义样式 */
|
|||
|
|
style?: React.CSSProperties;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface ListItemProps {
|
|||
|
|
/** 列表项内容 */
|
|||
|
|
children?: ReactNode;
|
|||
|
|
/** 列表项的额外内容 */
|
|||
|
|
extra?: ReactNode;
|
|||
|
|
/** 列表项的类名 */
|
|||
|
|
className?: string;
|
|||
|
|
/** 列表项的样式 */
|
|||
|
|
style?: React.CSSProperties;
|
|||
|
|
/** 列表项的 actions */
|
|||
|
|
actions?: ReactNode[];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface ListItemMetaProps {
|
|||
|
|
/** 头像 */
|
|||
|
|
avatar?: ReactNode;
|
|||
|
|
/** 标题 */
|
|||
|
|
title?: ReactNode;
|
|||
|
|
/** 描述 */
|
|||
|
|
description?: ReactNode;
|
|||
|
|
/** 类名 */
|
|||
|
|
className?: string;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用示例
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { List, Avatar, Button } from '@Pika/ui/list';
|
|||
|
|
|
|||
|
|
// 基本使用
|
|||
|
|
const data = [
|
|||
|
|
{ name: '张三', age: 25, avatar: 'https://example.com/avatar1.jpg' },
|
|||
|
|
{ name: '李四', age: 30, avatar: 'https://example.com/avatar2.jpg' },
|
|||
|
|
{ name: '王五', age: 28, avatar: 'https://example.com/avatar3.jpg' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
<List
|
|||
|
|
data={data}
|
|||
|
|
renderItem={(item) => (
|
|||
|
|
<List.Item>
|
|||
|
|
<List.Item.Meta
|
|||
|
|
avatar={<Avatar src={item.avatar} />}
|
|||
|
|
title={<a href="#">{item.name}</a>}
|
|||
|
|
description={`年龄: ${item.age}岁`}
|
|||
|
|
/>
|
|||
|
|
</List.Item>
|
|||
|
|
)}
|
|||
|
|
/>;
|
|||
|
|
|
|||
|
|
// 网格列表
|
|||
|
|
<List
|
|||
|
|
grid={{ gutter: 16, column: 4 }}
|
|||
|
|
data={data}
|
|||
|
|
renderItem={(item) => (
|
|||
|
|
<List.Item>
|
|||
|
|
<Card title={item.name}>
|
|||
|
|
<p>{item.age}岁</p>
|
|||
|
|
</Card>
|
|||
|
|
</List.Item>
|
|||
|
|
)}
|
|||
|
|
/>;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Design Token
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
--nv-list-item-height-small: 32px;
|
|||
|
|
--nv-list-item-height-middle: 40px;
|
|||
|
|
--nv-list-item-height-large: 48px;
|
|||
|
|
--nv-list-item-padding-small: 8px 12px;
|
|||
|
|
--nv-list-item-padding-middle: 12px 16px;
|
|||
|
|
--nv-list-item-padding-large: 16px 24px;
|
|||
|
|
--nv-list-border-color: var(--nv-color-border);
|
|||
|
|
--nv-list-split-color: var(--nv-color-border);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 开发优先级:P1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、开发计划与优先级
|
|||
|
|
|
|||
|
|
### 6.1 优先级规划
|
|||
|
|
|
|||
|
|
#### Phase 1: 核心通用组件(P0)
|
|||
|
|
|
|||
|
|
| 组件 | 说明 | 预估工时 |
|
|||
|
|
|------|------|---------|
|
|||
|
|
| App | 包裹组件,提供全局上下文 | 0.5 天 |
|
|||
|
|
| ConfigProvider | 全局配置组件 | 1 天 |
|
|||
|
|
|
|||
|
|
#### Phase 2: 重要通用组件(P1)
|
|||
|
|
|
|||
|
|
| 组件 | 说明 | 预估工时 |
|
|||
|
|
|------|------|---------|
|
|||
|
|
| Affix | 固钉组件 | 0.5 天 |
|
|||
|
|
| Anchor | 锚点组件 | 0.5 天 |
|
|||
|
|
| BackTop | 回到顶部 | 0.5 天 |
|
|||
|
|
| Drawer | 抽屉组件 | 1.5 天 |
|
|||
|
|
| List | 列表组件 | 1.5 天 |
|
|||
|
|
|
|||
|
|
#### Phase 3: 高级组件(P3)
|
|||
|
|
|
|||
|
|
| 组件 | 说明 | 预估工时 |
|
|||
|
|
|------|------|---------|
|
|||
|
|
| Watermark | 水印组件 | 0.5 天 |
|
|||
|
|
|
|||
|
|
### 6.2 开发里程碑
|
|||
|
|
|
|||
|
|
| 阶段 | 任务 | 时间 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| Phase 1 | App 和 ConfigProvider | 1 周 |
|
|||
|
|
| Phase 2 | Affix、Anchor、BackTop、Drawer、List | 2 周 |
|
|||
|
|
| Phase 3 | Watermark | 0.5 周 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、通用设计规范
|
|||
|
|
|
|||
|
|
### 7.1 Props 命名规范
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
// ✅ Pika 方式
|
|||
|
|
interface ComponentProps {
|
|||
|
|
// 尺寸统一
|
|||
|
|
size?: 'small' | 'middle' | 'large';
|
|||
|
|
|
|||
|
|
// 状态统一
|
|||
|
|
status?: 'default' | 'success' | 'warning' | 'error' | 'info';
|
|||
|
|
|
|||
|
|
// 数据统一
|
|||
|
|
data?: T[];
|
|||
|
|
|
|||
|
|
// 布尔属性:动词/形容词 + 肯定形式
|
|||
|
|
showIcon?: boolean;
|
|||
|
|
showClose?: boolean;
|
|||
|
|
closable?: boolean;
|
|||
|
|
disabled?: boolean;
|
|||
|
|
loading?: boolean;
|
|||
|
|
|
|||
|
|
// 事件:on + 动词 + 名词
|
|||
|
|
onChange?: (value: any) => void;
|
|||
|
|
onClick?: (event: MouseEvent) => void;
|
|||
|
|
onClose?: () => void;
|
|||
|
|
onOpenChange?: (open: boolean) => void;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 样式绑定规范
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
// ✅ Pika 方式:使用 data-* 属性
|
|||
|
|
<div
|
|||
|
|
data-size={size}
|
|||
|
|
data-status={status}
|
|||
|
|
data-variant={variant}
|
|||
|
|
data-loading={loading}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
// CSS 中使用属性选择器
|
|||
|
|
.component[data-size="small"] {
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.3 类型定义规范
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
// ✅ 使用联合类型字面量
|
|||
|
|
type Size = 'small' | 'middle' | 'large';
|
|||
|
|
type Status = 'default' | 'success' | 'warning' | 'error' | 'info';
|
|||
|
|
|
|||
|
|
// ❌ 避免使用 string 或 any
|
|||
|
|
type Size = string; // 范围不明确
|
|||
|
|
type Status = any; // 没有类型提示
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、无障碍设计
|
|||
|
|
|
|||
|
|
### 8.1 ARIA 属性
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
// Drawer
|
|||
|
|
<div
|
|||
|
|
role="dialog"
|
|||
|
|
aria-modal="true"
|
|||
|
|
aria-labelledby="drawer-title"
|
|||
|
|
aria-describedby="drawer-content"
|
|||
|
|
>
|
|||
|
|
<h2 id="drawer-title">标题</h2>
|
|||
|
|
<div id="drawer-content">内容</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
// List
|
|||
|
|
<ul role="list">
|
|||
|
|
<li role="listitem">列表项 1</li>
|
|||
|
|
<li role="listitem">列表项 2</li>
|
|||
|
|
</ul>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 8.2 键盘操作
|
|||
|
|
|
|||
|
|
- Drawer 支持 Esc 关闭
|
|||
|
|
- 所有可点击元素支持 Enter/Space 触发
|
|||
|
|
- Tab 顺序合理
|
|||
|
|
|
|||
|
|
### 8.3 颜色对比度
|
|||
|
|
|
|||
|
|
- 文本与背景对比度 ≥ 4.5:1
|
|||
|
|
- 大文本对比度 ≥ 3:1
|
|||
|
|
- 图标与背景对比度 ≥ 3:1
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、与 Pika 根规范的对照
|
|||
|
|
|
|||
|
|
| Pika 根规范 | 实现方式 |
|
|||
|
|
|------------|---------|
|
|||
|
|
| **AI 优先** | 所有 Props 使用联合类型字面量,无魔法字符串 |
|
|||
|
|
| **三级别尺寸** | `small`/`middle`/`large` 统一应用于所有组件 |
|
|||
|
|
| **统一事件命名** | `on + 动词 + 名词` 规则 |
|
|||
|
|
| **布尔属性** | 动词/形容词 + 肯定形式 |
|
|||
|
|
| **data-* 样式绑定** | 使用 `data-*` 属性而非 class 拼接 |
|
|||
|
|
| **自包含组件** | 每个组件独立导入,路径即名字 |
|
|||
|
|
| **Apple HIG** | 圆角、间距、动效遵循 Apple 规范 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十、完整组件清单
|
|||
|
|
|
|||
|
|
### 10.1 已规划完成的组件
|
|||
|
|
|
|||
|
|
- ✅ **通用组件**: Button, FloatButton, Icon, Typography
|
|||
|
|
- ✅ **数据展示**: Avatar, Badge, Calendar, Card, Carousel, Collapse, Descriptions, Empty, Image, Popover, QRCode, Segmented, Statistic, Table, Tag, Timeline, Tooltip, Tour, Tree
|
|||
|
|
- ✅ **数据录入**: AutoComplete, Cascader, Checkbox, Radio, Switch, DatePicker, Form, Input, InputNumber, Mention, RangePicker, Rate, Select, Slider, Textarea, TimePicker, Transfer, TreeSelect, Upload
|
|||
|
|
- ✅ **布局组件**: Divider, Flex, Grid, Layout, Masonry, Space, Splitter, Stack
|
|||
|
|
- ✅ **导航组件**: Breadcrumb, Dropdown, Menu, Pagination, Steps, Tabs
|
|||
|
|
- ✅ **反馈组件**: Alert, Message, Notification, Modal, Popconfirm, Spin, Progress, Result, Skeleton, Watermark
|
|||
|
|
|
|||
|
|
### 10.2 本规范补充的组件
|
|||
|
|
|
|||
|
|
- 📋 **通用组件**: Affix, Anchor, App, ConfigProvider, BackTop
|
|||
|
|
- 📋 **容器组件**: Drawer
|
|||
|
|
- 📋 **数据展示**: List
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十一、AI 生成提示
|
|||
|
|
|
|||
|
|
当 AI 生成 Pika 组件相关代码时,请遵循以下提示:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
1. 导入路径 = @Pika/ui/组件名
|
|||
|
|
2. 尺寸 prop 始终叫 size,值从 small/middle/large 选
|
|||
|
|
3. 数据 prop 始终叫 data
|
|||
|
|
4. 布尔 prop 用动词/形容词开头
|
|||
|
|
5. 所有 prop 类型用联合类型字面量定义
|
|||
|
|
6. 使用 data-* 属性进行样式绑定
|
|||
|
|
7. 事件回调 = on + 动词 + 名词
|
|||
|
|
8. 参考 Ant Design API 但按照 Pika 规范调整命名
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
> **Pika 其他组件计划完成!所有必要组件的规范已制定完毕。**
|
|||
|
|
|