Files
RustUI/_plans/navigation-components-plan.md
T

1333 lines
40 KiB
Markdown
Raw Normal View History

2026-05-31 09:36:23 +08:00
# 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、功能完整**