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

1333 lines
40 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 导航组件规划
> 基于 Pika 设计规范的导航组件设计
> 设计原则:以 Apple HIG 为准,AI-First,三级别尺寸体系
---
## 一、组件体系概览
Pika 导航组件采用三大类设计:
| 类别 | 组件 | 说明 | 优先级 |
|------|------|------|-------|
| **导航菜单** | Menu | 导航菜单 | P0 |
| **标签页** | Tabs | 标签页切换 | P1 |
| **面包屑** | Breadcrumb | 路径导航 | P1 |
| **步骤条** | Steps | 分步流程 | P2 |
| **下拉菜单** | Dropdown | 下拉操作 | P2 |
| **分页** | Pagination | 分页导航 | P2 |
---
## 二、核心设计原则
### 2.1 AI-First 设计原则(与根规范一致)
| 原则 | 说明 |
|-----|------|
| **零歧义** | Props 名称自解释,无简称、无隐式行为 |
| **零默认假设** | 所有视觉行为显式声明 |
| **一致性** | 相同概念用相同 prop 名 |
| **扁平化** | 最多一层嵌套 |
| **确定性** | 相同输入始终产生相同输出 |
### 2.2 统一尺寸体系(三级别)
所有导航组件使用统一的三级别尺寸体系:
| 级别 | 尺寸 | 用途 |
|-----|------|------|
| **small** | 小尺寸 | 紧凑列表、表格内 |
| **middle** | 中尺寸 | 默认使用 |
| **large** | 大尺寸 | 突出显示、重点导航 |
### 2.3 Design Token
```css
/* 导航组件尺寸 */
--nv-nav-item-height-small: 32px;
--nv-nav-item-height-middle: 40px;
--nv-nav-item-height-large: 48px;
--nv-nav-item-padding-small: 8px 12px;
--nv-nav-item-padding-middle: 12px 16px;
--nv-nav-item-padding-large: 16px 24px;
```
---
## 三、组件详细设计
### 3.1 Menu 导航菜单
#### 功能说明
Menu 是应用的主要导航组件,支持水平模式和垂直模式。
#### Props 定义(AI-First
```tsx
export interface MenuProps {
/** 菜单模式 */
mode?: 'horizontal' | 'vertical' | 'inline'
/** 主题色 */
theme?: 'light' | 'dark'
/** 选中菜单项 */
selectedKey?: string
/** 展开的子菜单 */
openKeys?: string[]
/** 默认展开的子菜单 */
defaultOpenKeys?: string[]
/** 触发方式 */
triggerSubMenuAction?: 'hover' | 'click'
/** 动画时长 */
duration?: number
/** 菜单元数据 */
items?: MenuItem[]
/** 选中回调 */
onSelect?: (key: string) => void
/** 展开回调 */
onOpenChange?: (keys: string[]) => void
/** 子元素 */
children?: React.ReactNode
className?: string
style?: React.CSSProperties
}
export interface MenuItem {
/** 唯一标识 */
key: string
/** 显示文本 */
label: React.ReactNode
/** 图标 */
icon?: React.ReactNode
/** 是否禁用 */
disabled?: boolean
/** 子菜单 */
children?: MenuItem[]
}
export interface SubMenuProps {
/** 唯一标识 */
key: string
/** 显示文本 */
label: React.ReactNode
/** 图标 */
icon?: React.ReactNode
/** 子菜单项 */
items?: MenuItem[]
/** 子元素 */
children?: React.ReactNode
}
```
#### 使用示例
```tsx
// 水平菜单
<Menu
mode="horizontal"
theme="light"
items={[
{ key: 'home', label: '首页' },
{ key: 'about', label: '关于' },
{ key: 'contact', label: '联系', disabled: true },
]}
/>
// 垂直菜单
<Menu
mode="vertical"
selectedKey="home"
onSelect={(key) => console.log(key)}
items={[
{
key: 'group1',
label: '分组 1',
children: [
{ key: 'item1', label: '菜单项 1' },
{ key: 'item2', label: '菜单项 2' },
]
},
]}
/>
// 带图标
<Menu
items={[
{ key: 'home', label: '首页', icon: <HomeIcon /> },
{ key: 'user', label: '用户', icon: <UserIcon /> },
]}
/>
```
#### Design Token
```css
--nv-menu-item-height: 40px;
--nv-menu-item-padding: 12px 16px;
--nv-menu-item-color: rgba(0, 0, 0, 0.85);
--nv-menu-item-hover-bg: rgba(0, 0, 0, 0.04);
--nv-menu-item-active-bg: rgba(108, 92, 231, 0.08);
--nv-menu-item-selected-color: var(--nv-color-primary);
--nv-menu-item-selected-bg: rgba(108, 92, 231, 0.08);
--nv-menu-item-disabled-color: rgba(0, 0, 0, 0.25);
--nv-menu-item-icon-size: 16px;
--nv-menu-item-gap: 8px;
--nv-menu-item-radius: var(--nv-radius-middle);
```
---
### 3.2 Tabs 标签页
#### 功能说明
Tabs 用于在多个内容区块之间快速切换。
#### Props 定义(AI-First
```tsx
export interface TabsProps {
/** 当前激活的标签 */
activeKey?: string
/** 默认激活的标签 */
defaultActiveKey?: string
/** 标签位置 */
tabPosition?: 'top' | 'right' | 'bottom' | 'left'
/** 标签大小 */
size?: 'small' | 'middle' | 'large'
/** 标签类型 */
type?: 'line' | 'card' | 'editable-card'
/** 是否可关闭(仅 editable-card */
hideAdd?: boolean
/** 标签数据 */
items?: TabItem[]
/** 切换回调 */
onChange?: (key: string) => void
/** 编辑回调(仅 editable-card */
onEdit?: (key: string, action: 'add' | 'remove') => void
/** 子元素 */
children?: React.ReactNode
className?: string
style?: React.CSSProperties
}
export interface TabItem {
/** 唯一标识 */
key: string
/** 显示文本 */
label: React.ReactNode
/** 内容 */
children?: React.ReactNode
/** 是否禁用 */
disabled?: boolean
/** 关闭图标 */
closable?: boolean
}
```
#### 使用示例
```tsx
// 基础标签页
<Tabs
items={[
{ key: 'tab1', label: '标签 1', children: '内容 1' },
{ key: 'tab2', label: '标签 2', children: '内容 2' },
{ key: 'tab3', label: '标签 3', disabled: true },
]}
/>
// 可编辑标签页
<Tabs
type="editable-card"
items={tabs}
onEdit={(key, action) => {
if (action === 'add') addTab()
if (action === 'remove') removeTab(key)
}}
/>
// 大尺寸
<Tabs size="large" items={items} />
```
#### Design Token
```css
--nv-tabs-item-height-small: 28px;
--nv-tabs-item-height-middle: 36px;
--nv-tabs-item-height-large: 44px;
--nv-tabs-item-padding-small: 4px 8px;
--nv-tabs-item-padding-middle: 8px 16px;
--nv-tabs-item-padding-large: 12px 24px;
--nv-tabs-item-font-size: var(--nv-font-size-middle);
--nv-tabs-item-color: rgba(0, 0, 0, 0.65);
--nv-tabs-item-active-color: var(--nv-color-primary);
--nv-tabs-item-hover-color: rgba(0, 0, 0, 0.85);
--nv-tabs-item-disabled-color: rgba(0, 0, 0, 0.25);
--nv-tabs-ink-bar-height: 2px;
--nv-tabs-ink-bar-color: var(--nv-color-primary);
```
---
### 3.3 Breadcrumb 面包屑
#### 功能说明
Breadcrumb 显示当前页面在网站层级结构中的位置。
#### Props 定义(AI-First
```tsx
export interface BreadcrumbProps {
/** 分隔符 */
separator?: React.ReactNode
/** 面包屑数据 */
items?: BreadcrumbItem[]
/** 路由信息 */
routes?: Route[]
/** 路由参数 */
params?: Record<string, string>
/** 自定义渲染 */
itemRender?: (
route: Route,
params: Record<string, string>,
routes: Route[],
paths: string[]
) => React.ReactNode
/** 子元素 */
children?: React.ReactNode
className?: string
style?: React.CSSProperties
}
export interface BreadcrumbItem {
/** 显示文本 */
title: React.ReactNode
/** 链接地址 */
href?: string
/** 点击回调 */
onClick?: () => void
/** 下拉菜单 */
menu?: {
items: BreadcrumbItem[]
}
}
export interface Route {
path: string
breadcrumbName: string
children?: Route[]
}
```
#### 使用示例
```tsx
// 基础面包屑
<Breadcrumb
items={[
{ title: '首页', href: '/' },
{ title: '列表', href: '/list' },
{ title: '详情' },
]}
/>
// 带下拉菜单
<Breadcrumb
items={[
{ title: '首页' },
{
title: '列表',
menu: {
items: [
{ title: '列表 1', href: '/list/1' },
{ title: '列表 2', href: '/list/2' },
]
}
},
{ title: '详情' },
]}
/>
// 自定义分隔符
<Breadcrumb separator=">">
<Breadcrumb.Item></Breadcrumb.Item>
<Breadcrumb.Item></Breadcrumb.Item>
<Breadcrumb.Item></Breadcrumb.Item>
</Breadcrumb>
```
#### Design Token
```css
--nv-breadcrumb-font-size: var(--nv-font-size-small);
--nv-breadcrumb-color: rgba(0, 0, 0, 0.45);
--nv-breadcrumb-link-color: rgba(0, 0, 0, 0.45);
--nv-breadcrumb-link-hover-color: var(--nv-color-primary);
--nv-breadcrumb-separator-color: rgba(0, 0, 0, 0.45);
--nv-breadcrumb-separator-margin: 8px;
```
---
### 3.4 Steps 步骤条
#### 功能说明
Steps 用于展示任务进度,分步骤进行。
#### Props 定义(AI-First
```tsx
export interface StepsProps {
/** 当前步骤 */
current?: number
/** 步骤状态 */
status?: 'wait' | 'process' | 'finish' | 'error'
/** 方向 */
direction?: 'horizontal' | 'vertical'
/** 步骤大小 */
size?: 'small' | 'middle' | 'large'
/** 标签位置 */
labelPlacement?: 'horizontal' | 'vertical'
/** 是否显示进度条 */
progressDot?: boolean
/** 步骤数据 */
items?: StepItem[]
/** 子元素 */
children?: React.ReactNode
className?: string
style?: React.CSSProperties
}
export interface StepItem {
/** 唯一标识 */
key?: string
/** 显示文本 */
title?: React.ReactNode
/** 副标题 */
subTitle?: React.ReactNode
/** 描述文本 */
description?: React.ReactNode
/** 图标 */
icon?: React.ReactNode
/** 步骤状态 */
status?: 'wait' | 'process' | 'finish' | 'error'
/** 是否禁用 */
disabled?: boolean
}
```
#### 使用示例
```tsx
// 基础步骤条
<Steps
current={1}
items={[
{ title: '步骤 1', description: '描述 1' },
{ title: '步骤 2', description: '描述 2' },
{ title: '步骤 3', description: '描述 3' },
]}
/>
// 垂直步骤条
<Steps direction="vertical" current={1}>
<Steps.Item title="已完成" description="这是描述" />
<Steps.Item title="进行中" description="这是描述" />
<Steps.Item title="待处理" description="这是描述" />
</Steps>
// 错误状态
<Steps
current={2}
status="error"
items={[
{ title: '已完成' },
{ title: '进行中' },
{ title: '出错啦', description: '请检查网络' },
]}
/>
```
#### Design Token
```css
--nv-steps-icon-size-small: 16px;
--nv-steps-icon-size-middle: 24px;
--nv-steps-icon-size-large: 32px;
--nv-steps-title-font-size: var(--nv-font-size-middle);
--nv-steps-description-font-size: var(--nv-font-size-small);
--nv-steps-text-color: rgba(0, 0, 0, 0.65);
--nv-steps-text-title-color: rgba(0, 0, 0, 0.85);
--nv-steps-finish-color: var(--nv-color-primary);
--nv-steps-process-color: var(--nv-color-primary);
--nv-steps-error-color: var(--nv-color-error);
--nv-steps-wait-color: rgba(0, 0, 0, 0.25);
```
---
### 3.5 Dropdown 下拉菜单
#### 功能说明
Dropdown 是下拉菜单组件,用于展示操作列表。
#### Props 定义(AI-First
```tsx
export interface DropdownProps {
/** 触发方式 */
trigger?: 'hover' | 'click' | 'focus'
/** 菜单位置 */
placement?: 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight'
/** 菜单数据 */
menu?: {
items: DropdownItem[]
onClick?: (key: string) => void
}
/** 下拉触发元素 */
overlay?: React.ReactNode
/** 触发元素 */
children?: React.ReactNode
className?: string
style?: React.CSSProperties
onVisibleChange?: (visible: boolean) => void
}
export interface DropdownItem {
/** 唯一标识 */
key: string
/** 显示文本 */
label: React.ReactNode
/** 图标 */
icon?: React.ReactNode
/** 是否禁用 */
disabled?: boolean
/** 分隔线 */
type?: 'divider'
}
export interface DropdownButtonProps extends DropdownProps {
/** 按钮类型 */
type?: 'primary' | 'default'
/** 按钮大小 */
size?: 'small' | 'middle' | 'large'
/** 按钮图标 */
icon?: React.ReactNode
}
```
#### 使用示例
```tsx
// 基础下拉菜单
<Dropdown
menu={{
items: [
{ key: 'edit', label: '编辑', icon: <EditIcon /> },
{ key: 'delete', label: '删除', disabled: true },
{ type: 'divider' },
{ key: 'export', label: '导出' },
]
}}
>
<Button></Button>
</Dropdown>
// 下拉按钮
<DropdownButton
type="primary"
menu={{
items: [
{ key: 'option1', label: '选项 1' },
{ key: 'option2', label: '选项 2' },
]
}}
>
</DropdownButton>
// 点击触发
<Dropdown trigger="click" placement="bottomLeft">
<Button></Button>
</Dropdown>
```
#### Design Token
```css
--nv-dropdown-item-height: 36px;
--nv-dropdown-item-padding: 8px 12px;
--nv-dropdown-item-font-size: var(--nv-font-size-middle);
--nv-dropdown-item-color: rgba(0, 0, 0, 0.85);
--nv-dropdown-item-hover-bg: rgba(0, 0, 0, 0.04);
--nv-dropdown-item-selected-bg: rgba(108, 92, 231, 0.08);
--nv-dropdown-item-selected-color: var(--nv-color-primary);
--nv-dropdown-item-disabled-color: rgba(0, 0, 0, 0.25);
--nv-dropdown-item-icon-gap: 8px;
--nv-dropdown-padding: 8px;
--nv-dropdown-radius: var(--nv-radius-middle);
```
---
### 3.6 Pagination 分页
#### 功能说明
Pagination 用于在大量数据之间进行导航。
#### Props 定义(AI-First
```tsx
export interface PaginationProps {
/** 当前页码 */
current?: number
/** 默认页码 */
defaultCurrent?: number
/** 总页数 */
total?: number
/** 每页条数 */
pageSize?: number
/** 默认每页条数 */
defaultPageSize?: number
/** 是否禁用 */
disabled?: boolean
/** 是否显示快速跳转 */
showQuickJumper?: boolean
/** 是否显示选择每页条数 */
showSizeChanger?: boolean
/** 每页条数选项 */
pageSizeOptions?: number[]
/** 分页器大小 */
size?: 'small' | 'middle' | 'large'
/** 简洁模式 */
simple?: boolean
/** 自定义渲染 */
itemRender?: (
page: number,
type: 'page' | 'prev' | 'next' | 'jump-prev' | 'jump-next',
element: React.ReactNode
) => React.ReactNode
/** 页码变化回调 */
onChange?: (page: number, pageSize: number) => void
/** 每页条数变化回调 */
onShowSizeChange?: (current: number, size: number) => void
className?: string
style?: React.CSSProperties
}
```
#### 使用示例
```tsx
// 基础分页
<Pagination
total={100}
current={1}
pageSize={10}
onChange={(page) => console.log(page)}
/>
// 显示每页条数选择
<Pagination
total={100}
showSizeChanger
pageSizeOptions={[10, 20, 50, 100]}
/>
// 简洁模式
<Pagination simple total={100} />
// 小尺寸
<Pagination size="small" total={100} />
```
#### Design Token
```css
--nv-pagination-item-size-small: 24px;
--nv-pagination-item-size-middle: 32px;
--nv-pagination-item-size-large: 40px;
--nv-pagination-font-size: var(--nv-font-size-middle);
--nv-pagination-item-bg: #fff;
--nv-pagination-item-color: rgba(0, 0, 0, 0.85);
--nv-pagination-item-active-bg: var(--nv-color-primary);
--nv-pagination-item-active-color: #fff;
--nv-pagination-item-disabled-color: rgba(0, 0, 0, 0.25);
--nv-pagination-item-hover-bg: rgba(0, 0, 0, 0.04);
```
---
## 四、AI-First 设计规范
### 4.1 Props 命名规范
| 规则 | 说明 |
|-----|------|
| **事件回调** | `on + 动词 + 名词``onChange``onSelect``onOpenChange``onEdit` |
| **布尔属性** | 动词/形容词 + 肯定形式:`disabled``showQuickJumper``showSizeChanger` |
| **尺寸** | 统一使用 `small``middle``large` |
| **状态** | 统一使用 `wait``process``finish``error` |
### 4.2 样式绑定规范
使用 `data-*` 属性进行样式绑定:
```tsx
// Menu
<div
data-mode="vertical"
data-theme="dark"
data-selected-key="home"
/>
// Tabs
<div
data-position="top"
data-size="middle"
data-type="card"
data-active-key="tab1"
/>
// Steps
<div
data-direction="horizontal"
data-size="middle"
data-status="process"
/>
```
### 4.3 组件导入规范
每个组件独立导入,路径即名字:
```tsx
import { Menu } from '@Pika/ui/menu'
import { Tabs } from '@Pika/ui/tabs'
import { Breadcrumb } from '@Pika/ui/breadcrumb'
import { Steps } from '@Pika/ui/steps'
import { Dropdown } from '@Pika/ui/dropdown'
import { Pagination } from '@Pika/ui/pagination'
```
---
## 五、文件结构
```
src/components/
├── menu/
│ ├── index.ts
│ ├── Menu.tsx
│ ├── MenuItem.tsx
│ ├── SubMenu.tsx
│ ├── Menu.module.css
│ └── Menu.test.tsx
├── tabs/
│ ├── index.ts
│ ├── Tabs.tsx
│ ├── TabPane.tsx
│ ├── Tabs.module.css
│ └── Tabs.test.tsx
├── breadcrumb/
│ ├── index.ts
│ ├── Breadcrumb.tsx
│ ├── BreadcrumbItem.tsx
│ ├── Breadcrumb.module.css
│ └── Breadcrumb.test.tsx
├── steps/
│ ├── index.ts
│ ├── Steps.tsx
│ ├── Step.tsx
│ ├── Steps.module.css
│ └── Steps.test.tsx
├── dropdown/
│ ├── index.ts
│ ├── Dropdown.tsx
│ ├── DropdownButton.tsx
│ ├── Dropdown.module.css
│ └── Dropdown.test.tsx
└── pagination/
├── index.ts
├── Pagination.tsx
├── Pagination.module.css
└── Pagination.test.tsx
```
---
## 六、优先级规划
### Phase 1: 核心导航 (P0)
| 组件 | 说明 | 预估工时 |
|-----|------|---------|
| Menu | 导航菜单 | 4h |
### Phase 2: 标签和路径 (P1)
| 组件 | 说明 | 预估工时 |
|-----|------|---------|
| Tabs | 标签页 | 3h |
| Breadcrumb | 面包屑 | 2h |
### Phase 3: 辅助导航 (P2)
| 组件 | 说明 | 预估工时 |
|-----|------|---------|
| Steps | 步骤条 | 2h |
| Dropdown | 下拉菜单 | 2h |
| DropdownButton | 下拉按钮 | 1h |
| Pagination | 分页 | 2h |
---
## 七、与 Pika 设计规范对照
| Pika 规范 | 实现方式 |
|----------|---------|
| **AI-First** | 所有 Props 使用联合类型字面量,无魔法字符串 |
| **三级别尺寸** | `small``middle``large` 统一应用于所有组件 |
| **统一事件命名** | `on + 动词 + 名词` 规则:`onChange``onSelect``onOpenChange` |
| **布尔属性** | 动词/形容词 + 肯定形式:`disabled``showQuickJumper` |
| **data-* 样式绑定** | 使用 `data-*` 属性而非 className 拼接 |
| **自包含组件** | 每个组件独立导入,路径即名字 |
| **Apple HIG** | 圆角、间距、动效遵循 Apple 规范 |
---
## 八、完整使用示例
### 8.1 后台管理系统导航
```tsx
import { Layout, Menu, Breadcrumb, Dropdown, Tabs } from '@Pika/ui'
const App = () => {
const menuItems = [
{ key: 'home', label: '首页', icon: <HomeIcon /> },
{
key: 'user',
label: '用户管理',
icon: <UserIcon />,
children: [
{ key: 'user-list', label: '用户列表' },
{ key: 'user-role', label: '角色管理' },
]
},
{ key: 'settings', label: '设置', icon: <SettingsIcon />, disabled: true },
]
const breadcrumbItems = [
{ title: '首页', href: '/' },
{ title: '用户管理' },
{ title: '用户列表' },
]
return (
<Layout>
<Layout.Header>
<Menu mode="horizontal" items={menuItems} />
<Dropdown
menu={{
items: [
{ key: 'profile', label: '个人中心' },
{ key: 'settings', label: '设置' },
{ type: 'divider' },
{ key: 'logout', label: '退出登录' },
]
}}
>
<Avatar />
</Dropdown>
</Layout.Header>
<Layout.Content>
<Breadcrumb items={breadcrumbItems} />
<Tabs
items={[
{ key: 'tab1', label: '基本信息', children: <Profile /> },
{ key: 'tab2', label: '账号安全', children: <Security /> },
{ key: 'tab3', label: '操作日志', children: <Logs /> },
]}
/>
</Layout.Content>
</Layout>
)
}
```
---
## 九、antd 完整 API 清单(构建参考)
### 9.1 Menu 完整 API
#### Menu Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| forceSubMenuRender | 渲染前强制渲染子菜单 | boolean | false |
| inlineCollapsed | 内联菜单折叠状态 | boolean | - |
| collapsedWidth | 折叠宽度 | number | 48 |
| defaultCollapsed | 默认折叠状态 | boolean | false |
| siderMenu | 侧边菜单 | ReactNode | - |
| menuHeader | 菜单头部 | ReactNode | - |
| breakpoint | 触发响应式布局的断点 | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' | - |
| getPopupContainer | 菜单渲染父节点 | (menuNode: HTMLElement) => HTMLElement | () => document.body |
| ghost | 幽灵模式,使主体背景透明 | boolean | false |
| items | 菜单数据 | MenuItem[] | - |
| defaultItems | 默认菜单数据 | MenuItem[] | - |
| multiple | 支持多选 | boolean | false |
| selectable | 是否允许选中 | boolean | true |
| defaultOpenAll | 默认展开所有菜单 | boolean | false |
| openKeys | 当前展开的 SubMenu 菜单项 key 数组 | string[] | - |
| defaultOpenKeys | 初始展开的 SubMenu 菜单项 key 数组 | string[] | - |
| activeKey | 当前选中的菜单项 key | string | - |
| defaultActiveFirst | 是否默认选中第一个菜单项 | boolean | false |
| selectedKeys | 当前选中的菜单项 key 数组 | string[] | - |
| defaultSelectedKeys | 初始选中的菜单项 key 数组 | string[] | - |
| inlineIndent | 内联菜单缩进宽度 | number | 24 |
| focusable | 是否可聚焦 | boolean | false |
| onSelect | 被选中时调用的回调函数 | function({ key: string, keyPath: string[], item: ReactInstance, domEvent: DOMEvent }) | - |
| onDeselect | 取消选中时调用的回调函数(仅在 multiple 模式下有效) | function({ key: string, keyPath: string[], item: ReactInstance, domEvent: DOMEvent }) | - |
| onClick | 点击菜单项的回调函数 | function({ key: string, keyPath: string[], item: ReactInstance, domEvent: DOMEvent }) | - |
| onOpenChange | SubMenu 展开/关闭的回调函数 | function(openKeys: string[]) | - |
| onTitleClick | 点击标题的回调函数 | function({ key: string, domEvent: DOMEvent }) | - |
| style | 根样式 | CSSProperties | - |
| className | 根样式类名 | string | - |
| theme | 主题颜色 | 'light' \| 'dark' | 'light' |
| mode | 菜单类型 | 'horizontal' \| 'vertical' \| 'inline' | 'vertical' |
| triggerSubMenuAction | SubMenu 展开/关闭的触发行为 | 'hover' \| 'click' | 'hover' |
| subMenuOpenDelay | SubMenu 展开延迟(毫秒) | number | 0 |
| subMenuCloseDelay | SubMenu 关闭延迟(毫秒) | number | 0 |
| fixSiderbar | 固定侧边栏 | boolean | false |
| fixMenuItemBgColor | 固定菜单项背景色 | string | - |
| iconMarginPadding | 图标和文字之间的间距 | number | 8 |
| layout | 整体布局 | 'side' \| 'mix' | 'side' |
| splitMenus | 分割菜单(仅在 mix 模式下有效) | boolean | false |
| menuExtraRender | 菜单底部额外渲染 | (props: MenuProps) => ReactNode | - |
| menuFooterRender | 菜单底部渲染 | (props: MenuProps) => ReactNode | - |
| menuContentRender | 自定义菜单内容渲染 | (props: MenuProps, defaultDom: ReactNode) => ReactNode | - |
| itemActiveClass | 菜单项 active 状态的类名 | string | - |
#### MenuItem Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| key | 唯一标志 | string \| number | - |
| label | 菜单项标题 | ReactNode | - |
| icon | 菜单图标 | ReactNode | - |
| disabled | 是否禁用 | boolean | false |
| danger | 危险状态 | boolean | false |
| title | 设置收缩时展示的悬浮标题 | string | - |
#### SubMenu Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| key | 唯一标志 | string \| number | - |
| label | 菜单项标题 | ReactNode | - |
| icon | 菜单图标 | ReactNode | - |
| children | 子菜单项 | MenuItem[] \| ReactNode | - |
| disabled | 是否禁用 | boolean | false |
| popupClassName | 子菜单样式类名 | string | - |
| popupOffset | 子菜单偏移量 | [number, number] | - |
| onTitleClick | 点击标题的回调函数 | function({ key: string, domEvent: DOMEvent }) | - |
| expandIcon | 自定义展开图标 | ReactNode \| ((props: TitleProps) => ReactNode) | - |
#### Menu.Divider Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| className | 样式类名 | string | - |
| style | 样式 | CSSProperties | - |
---
### 9.2 Tabs 完整 API
#### Tabs Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| activeKey | 当前激活 tab 面板的 key | string | - |
| defaultActiveKey | 初始化选中面板的 key | string | '0' |
| items | tab 面板内容 | TabItem[] | - |
| moreIcon | 自定义折叠图标 | ReactNode | - |
| popupClassName | 下拉菜单样式类名 | string | - |
| tabBarGutter | tabs 之间的间隙 | number | - |
| size | 大小,提供 `large` \| `middle` \| `small` 三种尺寸 | 'large' \| 'middle' \| 'small' | 'middle' |
| tabPosition | 页签位置,提供 `top` \| `right` \| `bottom` \| `left` 四种位置 | 'top' \| 'right' \| 'bottom' \| 'left' | 'top' |
| tabBarStyle | tab bar 样式对象 | CSSProperties | - |
| tabBarExtraContent | tab bar 上额外的元素 | ReactNode | - |
| renderTabBar | 替换原生 tab bar | (props: TabsProps, DefaultTabBar: React.ComponentClass) => ReactElement | - |
| onChange | 面板切换回调 | function(activeKey) {} | - |
| onTabClick | tab 被点击的回调 | function(key: string, event: Event) | - |
| onTabScroll | tab 滚动回调 | function({ direction: 'left' \| 'right' \| 'top' \| 'bottom' }) | - |
| destroyInactiveTabPane | 被隐藏时销毁 tab 面板内容 | boolean | false |
| className | 样式类名 | string | - |
| style | 根元素样式 | CSSProperties | - |
| indicator | 自定义 indicator | object \| (props: TabsProps) => ReactNode | - |
| indicatorSize | indicator 尺寸 | number \| ((origin: { current: number, width: number }) => number) | - |
| moreTransition | 更多菜单过渡动画 | string | - |
#### TabItem Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| key | 对应 activeKey | string | - |
| label | 选项卡头显示文字 | ReactNode | - |
| children | tab 面板内容 | ReactNode | - |
| disabled | 是否禁用 | boolean | false |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
| closable | 是否可关闭(仅在 type="editable-card" 时有效) | boolean | true |
| closeIcon | 自定义关闭图标 | ReactNode | - |
| icon | 图标 | ReactNode | - |
| popupClassName | 下拉菜单样式类名 | string | - |
#### Tabs.CardProps
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| type | 页签的基本样式 | 'line' \| 'card' \| 'editable-card' | 'line' |
| onEdit | 新增和删除页签的回调(仅在 type="editable-card" 时有效) | function(action: 'add' \| 'remove', key: string) | - |
| addIcon | 自定义新增按钮图标 | ReactNode | - |
| showAdd | 是否显示新增按钮(仅在 type="editable-card" 时有效) | boolean | false |
---
### 9.3 Breadcrumb 完整 API
#### Breadcrumb Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| separator | 分隔符自定义 | ReactNode | '/' |
| children | 面包屑内容 | ReactNode | - |
| items | 面包屑每一项的数据 | BreadcrumbItem[] | - |
| routes | router 的路由信息 | Route[] | - |
| params | 路由的参数 | object | - |
| prefix | 在每个 breadcrumb 前添加自定义前缀 | ReactNode | - |
| loadTime | 懒加载数据的时间间隔 | number | - |
| itemRender | 自定义渲染函数 | (route, params, routes, paths) => ReactNode | - |
| className | 容器类名 | string | - |
| style | 容器样式 | CSSProperties | - |
#### BreadcrumbItem Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| className | 样式类名 | string | - |
| style | 样式 | CSSProperties | - |
| href | 链接地址 | string | - |
| onClick | 点击事件 | (e: MouseEvent) => void | - |
| title | 标题 | ReactNode | - |
| separator | 分隔符 | ReactNode | - |
| menu | 下拉菜单配置 | { items: BreadcrumbItem[] } | - |
| dropdownProps | 下拉菜单属性 | DropdownProps | - |
| children | 子菜单项 | BreadcrumbItem[] | - |
#### Route Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| path | 路径 | string | - |
| breadcrumbName | 面包屑名称 | string | - |
| children | 子路由 | Route[] | - |
| params | 路由参数 | object | - |
| breadcrumbNameClassName | 面包屑名称类名 | string | - |
| breadcrumbNameStyle | 面包屑名称样式 | CSSProperties | - |
---
### 9.4 Steps 完整 API
#### Steps Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| current | 指定当前步骤,从 0 开始 | number | 0 |
| status | 指定当前步骤的状态 | 'wait' \| 'process' \| 'finish' \| 'error' | 'process' |
| size | 尺寸,提供 `large` \| `small` 两档 | 'large' \| 'small' | 'large' |
| direction | 指定步骤条方向 | 'horizontal' \| 'vertical' | 'horizontal' |
| labelPlacement | 指定标签放置位置 | 'horizontal' \| 'vertical' | 'horizontal' |
| controls | 自定义操作区域 | ReactNode | - |
| className | 步骤条类名 | string | - |
| style | 步骤条样式 | CSSProperties | - |
| currentStatus | 当前步骤的状态 | 'wait' \| 'process' \| 'finish' \| 'error' | 'process' |
| initial | 起始序号,从 0 开始 | number | 0 |
| icons | 各种状态图标设置 | { finish?: ReactNode, error?: ReactNode } | - |
| responsive | 响应式布局,当屏幕宽度小于 532px 时自动变为垂直模式 | boolean | true |
| percent | 当前 `process` 步骤显示百分比数字(只有 `type="navigation"` 时生效) | number | - |
| onChange | 步骤切换回调 | (current: number) => void | - |
| type | 步骤条类型 | 'default' \| 'navigation' \| 'simple' | 'default' |
| items | 步骤配置 | StepItem[] | - |
#### StepItem Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| title | 标题 | ReactNode | - |
| subTitle | 子标题 | ReactNode | - |
| description | 步骤的描述性文字 | ReactNode | - |
| icon | 步骤图标的 React 元素 | ReactNode | - |
| status | 指定状态 | 'wait' \| 'process' \| 'finish' \| 'error' | 'wait' |
| disabled | 禁用点击 | boolean | false |
| className | 步骤类名 | string | - |
| style | 步骤样式 | CSSProperties | - |
| onChange | 点击步骤回调 | () => void | - |
---
### 9.5 Dropdown 完整 API
#### Dropdown Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| menu | 菜单配置项 | MenuProps | - |
| overlay | 折叠的菜单 | ReactNode | - |
| trigger | 触发行为 | Array<'click' \| 'hover' \| 'contextMenu'> | ['hover'] |
| disabled | 菜单是否禁用 | boolean | - |
| onOpenChange | 菜单打开/关闭回调 | (open: boolean) => void | - |
| open | 菜单是否打开,受控 | boolean | - |
| defaultOpen | 菜单默认是否打开 | boolean | - |
| placement | 菜单弹出位置 | 'top' \| 'left' \| 'right' \| 'bottom' \| 'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' \| 'leftTop' \| 'leftBottom' \| 'rightTop' \| 'rightBottom' | 'bottomLeft' |
| overlayClassName | 下拉根元素的类名 | string | - |
| overlayStyle | 下拉根元素样式 | CSSProperties | - |
| overlayInnerStyle | 下拉内容样式 | CSSProperties | - |
| arrow | 是否显示箭头 | boolean \| { pointAtCenter: boolean } | false |
| autoAdjustOverflow | 下拉框根据弹出层自动调整位置 | boolean | true |
| getPopupContainer | 菜单渲染父节点 | (triggerNode: HTMLElement) => HTMLElement | () => document.body |
| transitionName | 过渡动画类名 | string | - |
| forceRender | 强制渲染下拉菜单内容 | boolean | false |
| destroyTooltipOnHide | 关闭后是否销毁 Tooltip | boolean | false |
#### DropdownMenuProps
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| items | 菜单项配置 | MenuItem[] | - |
| onClick | 点击菜单项回调 | (key: string) => void | - |
| selectable | 是否允许选中(通过 activeKey | boolean | false |
| activeKey | 当前选中的菜单项 key | string | - |
| defaultActiveFirst | 是否默认选中第一个菜单项 | boolean | false |
| theme | 主题 | 'light' \| 'dark' | 'light' |
#### DropdownMenuItem Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| key | 唯一标志 | string | - |
| label | 菜单项标题 | ReactNode | - |
| icon | 菜单图标 | ReactNode | - |
| disabled | 是否禁用 | boolean | false |
| danger | 危险状态 | boolean | false |
| title | 标题(不支持自定义渲染) | string | - |
| type | 类型,`divider` 表示分割线 | 'divider' | - |
| onMouseEnter | 鼠标进入回调 | (e: MouseEvent) => void | - |
| onMouseLeave | 鼠标离开回调 | (e: MouseEvent) => void | - |
| onClick | 点击回调 | (e: MouseEvent) => void | - |
#### DropdownButton Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| type | 按钮类型 | 'default' \| 'primary' \| 'dashed' \| 'link' \| 'text' | 'default' |
| size | 按钮大小 | 'small' \| 'middle' \| 'large' | 'middle' |
| icon | 按钮图标 | ReactNode | - |
| danger | 危险按钮 | boolean | false |
| disabled | 禁用状态 | boolean | false |
| loading | 加载状态 | boolean | false |
| onClick | 点击回调 | (e: MouseEvent) => void | - |
| overlay | 折叠的菜单 | ReactNode | - |
| menu | 菜单配置项 | MenuProps | - |
| trigger | 触发行为 | Array<'click' \| 'hover' \| 'contextMenu'> | ['hover'] |
| buttonsRender | 自定义按钮渲染 | (buttons: [ReactNode, ReactNode]) => ReactNode[] | - |
| open | 菜单是否打开,受控 | boolean | - |
| defaultOpen | 菜单默认是否打开 | boolean | - |
| onOpenChange | 菜单打开/关闭回调 | (open: boolean) => void | - |
| placement | 菜单弹出位置 | 'top' \| 'left' \| 'right' \| 'bottom' \| 'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight' | 'bottomLeft' |
| className | 类名 | string | - |
| style | 样式 | CSSProperties | - |
| overlayClassName | 下拉根元素的类名 | string | - |
| overlayStyle | 下拉根元素样式 | CSSProperties | - |
| icon | 按钮图标 | ReactNode | - |
---
### 9.6 Pagination 完整 API
#### Pagination Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| total | 总数 | number | - |
| defaultCurrent | 默认当前页 | number | 1 |
| current | 当前页 | number | - |
| defaultPageSize | 默认每页条数 | number | 10 |
| pageSize | 每页条数 | number | - |
| pageSizeOptions | 指定每页可以显示多少条 | string[] \| number[] | ['10', '20', '50', '100'] |
| showSizeChanger | 是否显示每页条数选择器 | boolean | true |
| showQuickJumper | 是否显示快速跳转 | boolean | false |
| pageSizePrecise | 精确的每页条数(受控模式) | boolean | false |
| showTotal | 用于显示数据总量 | total => ReactNode \| (total, range) => ReactNode | - |
| showPrevNextJumpers | 是否显示上一页、下一页跳转 | boolean | true |
| showFirstLastPager | 是否显示第一页和最后一页 | boolean | true |
| showJumper | 是否显示输入框跳转 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| simple | 是否使用简洁模式 | boolean | - |
| locale | 默认语言配置 | object | - |
| className | 类名 | string | - |
| style | 样式 | CSSProperties | - |
| prefixCls | 类名前缀 | string | - |
| selectPrefixCls | 下拉菜单类名前缀 | string | - |
| totalBoundaryShowSizeChanger | 当 total 大于多少时显示 pageSize 选择器 | number | 50 |
| size | 分页器大小 | 'small' \| 'default' | 'default' |
| responsive | 当屏幕宽度小于 538px 时自动变为 mini 尺寸 | boolean | - |
| onChange | 页码或 pageSize 变化的回调 | (page: number, pageSize: number) => void | - |
| onShowSizeChange | pageSize 变化的回调 | (current: number, size: number) => void | - |
| itemRender | 自定义渲染页码 | (page: number, type: 'page' \| 'prev' \| 'next' \| 'jump-prev' \| 'jump-next', originElement: ReactNode) => ReactNode | - |
| role | ARIA role | string | - |
| showLessItems | 是否显示较少页面导航 | boolean | false |
#### Pagination Mini Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| size | 分页器大小 | 'small' | - |
#### TotalProps
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| total | 总数 | number | - |
| range | 当前范围 | [number, number] | - |
---
## 十、功能检查清单
构建组件时,请确保实现以下所有功能:
### 10.1 Menu 必须实现的功能
- [ ] horizontal / vertical / inline 三种模式
- [ ] light / dark 两种主题
- [ ] 支持无限层级 SubMenu
- [ ] 支持 Menu.Item / Menu.SubMenu / Menu.Divider
- [ ] 支持 inlineCollapsed 折叠
- [ ] 支持 selectedKeys 受控
- [ ] 支持 openKeys 受控
- [ ] 支持 triggerSubMenuAction 触发方式
- [ ] 支持 icon 图标
- [ ] 支持 disabled 禁用
- [ ] 支持 danger 危险状态
- [ ] 支持 keyboard 键盘导航
- [ ] 支持自定义展开图标
### 10.2 Tabs 必须实现的功能
- [ ] top / right / bottom / left 四种位置
- [ ] line / card / editable-card 三种类型
- [ ] 支持 Tab.Item 子组件
- [ ] 支持 activeKey 受控
- [ ] 支持 onChange 切换回调
- [ ] 支持 closable 可关闭
- [ ] 支持 forceRender 强制渲染
- [ ] 支持 disabled 禁用
- [ ] 支持 showAdd 新增按钮
- [ ] 支持 icon 图标
- [ ] 支持 destroyedInactiveTabPane 销毁非活动面板
### 10.3 Breadcrumb 必须实现的功能
- [ ] 支持 Breadcrumb.Item 子组件
- [ ] 支持 items 数据配置
- [ ] 支持 separator 自定义分隔符
- [ ] 支持 routes 路由配置
- [ ] 支持 params 路由参数
- [ ] 支持 itemRender 自定义渲染
- [ ] 支持 href 链接
- [ ] 支持 onClick 点击事件
- [ ] 支持 menu 下拉菜单
- [ ] 支持 prefix 前缀
### 10.4 Steps 必须实现的功能
- [ ] horizontal / vertical 两种方向
- [ ] 支持 current 当前步骤
- [ ] 支持 status 状态
- [ ] 支持 Step.Item 子组件
- [ ] 支持 labelPlacement 标签位置
- [ ] 支持 title / subTitle / description
- [ ] 支持 icon 图标
- [ ] 支持 disabled 禁用
- [ ] 支持 icons 自定义图标
- [ ] 支持 responsive 响应式
- [ ] 支持 onChange 切换回调
- [ ] 支持 initial 起始序号
### 10.5 Dropdown 必须实现的功能
- [ ] 支持 hover / click / contextMenu 触发方式
- [ ] 支持 menu 数据配置
- [ ] 支持 overlay 插槽
- [ ] 支持 placement 位置
- [ ] 支持 arrow 箭头
- [ ] 支持 disabled 禁用
- [ ] 支持 onOpenChange 开关回调
- [ ] 支持 open 受控
- [ ] 支持 DropdownButton 下拉按钮
- [ ] 支持 danger 危险状态
- [ ] 支持 icon 图标
- [ ] 支持 divider 分割线
### 10.6 Pagination 必须实现的功能
- [ ] 支持 total 总数
- [ ] 支持 current / defaultCurrent 当前页
- [ ] 支持 pageSize / defaultPageSize 每页条数
- [ ] 支持 pageSizeOptions 每页条数选项
- [ ] 支持 showSizeChanger 显示条数选择器
- [ ] 支持 showQuickJumper 快速跳转
- [ ] 支持 showTotal 显示总数
- [ ] 支持 simple 简洁模式
- [ ] 支持 size 大小
- [ ] 支持 disabled 禁用
- [ ] 支持 onChange 页码变化回调
- [ ] 支持 onShowSizeChange 条数变化回调
- [ ] 支持 itemRender 自定义渲染
- [ ] 支持 showLessItems 显示较少页码
---
## 十一、AI 提示工程
```
1. 导入路径 = @Pika/ui/组件名 (menu/tabs/breadcrumb/steps/dropdown/pagination)
2. 尺寸 prop 始终叫 size,值从 small/middle/large 选
3. 布尔 prop 用动词开头 (disabled, showQuickJumper, showSizeChanger)
4. 回调命名 = on + 动词 + 名词 (onChange, onSelect, onOpenChange, onEdit)
5. 所有 prop 类型用联合类型字面量定义
6. 使用 data-* 属性进行样式绑定
7. Menu items / Tabs items / Dropdown items 使用统一的 Item 类型
8. 构建组件时参考第九章的 antd 完整 API,确保不遗漏任何功能
9. 使用第十章的功能检查清单进行自检
```
---
> **Pika 导航组件:简洁、统一、AI-First、功能完整**