790 lines
17 KiB
Markdown
790 lines
17 KiB
Markdown
|
|
# 按钮扩展组件设计文档
|
|||
|
|
|
|||
|
|
> **版本:** v1.2.0
|
|||
|
|
> **更新时间:** 2025-11-17
|
|||
|
|
> **作者:** Nex Design Team
|
|||
|
|
> **状态:** ✅ 已完成
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📖 目录
|
|||
|
|
|
|||
|
|
1. [概述](#概述)
|
|||
|
|
2. [设计方案](#设计方案)
|
|||
|
|
3. [组件API](#组件api)
|
|||
|
|
4. [使用指南](#使用指南)
|
|||
|
|
5. [最佳实践](#最佳实践)
|
|||
|
|
6. [更新日志](#更新日志)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
### 设计目标
|
|||
|
|
|
|||
|
|
为终端列表页面的按钮提供清晰的操作介绍和帮助信息,解决以下问题:
|
|||
|
|
- 用户不了解按钮功能
|
|||
|
|
- 复杂操作缺少引导
|
|||
|
|
- 需要快速的上下文帮助
|
|||
|
|
|
|||
|
|
### 设计原则
|
|||
|
|
|
|||
|
|
1. **简洁至上** - 去除不必要的动画,使用扁平化设计
|
|||
|
|
2. **功能独立** - 帮助功能不影响主操作流程
|
|||
|
|
3. **易于理解** - 直观的图标和交互模式
|
|||
|
|
4. **现代美学** - 符合Material Design和Fluent Design趋势
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 设计方案
|
|||
|
|
|
|||
|
|
我们提供了5种不同的设计方案,可根据实际场景选择使用:
|
|||
|
|
|
|||
|
|
### 方案1:增强型工具提示 (Enhanced Tooltip)
|
|||
|
|
|
|||
|
|
**特点:**
|
|||
|
|
- 渐变色彩背景,视觉效果出众
|
|||
|
|
- 支持标题、描述、快捷键、注意事项
|
|||
|
|
- 带有脉冲动画的提示图标
|
|||
|
|
- 响应式设计,移动端友好
|
|||
|
|
|
|||
|
|
**适用场景:**
|
|||
|
|
- ✅ 简单操作,需要快速了解功能
|
|||
|
|
- ✅ 不希望占用额外页面空间
|
|||
|
|
- ✅ 信息量较少的提示
|
|||
|
|
|
|||
|
|
**效果预览:**
|
|||
|
|
```
|
|||
|
|
[按钮] (i) ← 脉冲动画图标
|
|||
|
|
↓ 悬停
|
|||
|
|
┌────────────────────────┐
|
|||
|
|
│ 新增主机 │
|
|||
|
|
│ 向系统中添加新的主机... │
|
|||
|
|
│ 快捷键: Ctrl+N │
|
|||
|
|
│ 注意: 请确保IP不冲突 │
|
|||
|
|
└────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案2:智能帮助面板 (Smart Help Panel) ⭐ 推荐
|
|||
|
|
|
|||
|
|
**特点:**
|
|||
|
|
- 侧边抽屉式设计,信息完整
|
|||
|
|
- 实时显示当前悬停按钮的详细信息
|
|||
|
|
- 包含使用场景、操作步骤、注意事项等
|
|||
|
|
- 支持查看所有可用操作的快速索引
|
|||
|
|
- 点击"?"图标直接打开帮助面板
|
|||
|
|
|
|||
|
|
**适用场景:**
|
|||
|
|
- ✅ 复杂业务操作,需要详细说明
|
|||
|
|
- ✅ 新用户培训和引导
|
|||
|
|
- ✅ 功能较多,需要分步骤引导
|
|||
|
|
|
|||
|
|
**交互流程:**
|
|||
|
|
```
|
|||
|
|
1. 悬停按钮 → 出现"?"图标
|
|||
|
|
2. 点击"?" → 打开右侧帮助面板
|
|||
|
|
3. 显示详细内容:
|
|||
|
|
- 功能说明
|
|||
|
|
- 使用场景
|
|||
|
|
- 操作步骤
|
|||
|
|
- 注意事项
|
|||
|
|
- 快捷键
|
|||
|
|
- 权限要求
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**特殊优化:**
|
|||
|
|
- 面板打开时,鼠标离开按钮不会清空内容
|
|||
|
|
- 点击"所有可用操作"卡片可切换内容
|
|||
|
|
- 自动展开"当前操作"区域
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案3:悬浮展开卡片 (Hover Expand Card)
|
|||
|
|
|
|||
|
|
**特点:**
|
|||
|
|
- 精美的悬浮卡片设计
|
|||
|
|
- 滑入动画,视觉流畅
|
|||
|
|
- 分层信息展示
|
|||
|
|
- 使用React Portal渲染,永不被遮挡
|
|||
|
|
|
|||
|
|
**适用场景:**
|
|||
|
|
- ✅ 需要展示较多信息
|
|||
|
|
- ✅ 不想打断操作流程
|
|||
|
|
- ✅ 希望信息就近显示
|
|||
|
|
|
|||
|
|
**技术实现:**
|
|||
|
|
```jsx
|
|||
|
|
// 使用Portal避免z-index遮挡问题
|
|||
|
|
import { createPortal } from 'react-dom'
|
|||
|
|
|
|||
|
|
{createPortal(renderCard(), document.body)}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案4:智能引导 (Smart Guide)
|
|||
|
|
|
|||
|
|
**特点:**
|
|||
|
|
- 简洁扁平设计,独立帮助图标
|
|||
|
|
- 点击查看弹窗式详细引导
|
|||
|
|
- 包含步骤式操作说明
|
|||
|
|
|
|||
|
|
**适用场景:**
|
|||
|
|
- ✅ 需要详细引导,但不希望干扰主流程
|
|||
|
|
- ✅ 功能上线初期的用户引导
|
|||
|
|
- ✅ 复杂操作的分步说明
|
|||
|
|
|
|||
|
|
**设计对比:**
|
|||
|
|
```
|
|||
|
|
旧版(已废弃):脉冲动画徽章,过于复杂
|
|||
|
|
新版:简洁帮助图标,点击查看详情
|
|||
|
|
|
|||
|
|
┌────────────┐ ┌─┐
|
|||
|
|
│ 新增主机 │ │?│ ← 简洁优雅
|
|||
|
|
└────────────┘ └─┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案5:底部固定提示栏 (Bottom Hint Bar)
|
|||
|
|
|
|||
|
|
**特点:**
|
|||
|
|
- 固定底部位置,不遮挡操作区域
|
|||
|
|
- 实时更新,流畅切换
|
|||
|
|
- 三种主题可选(渐变、浅色、深色)
|
|||
|
|
|
|||
|
|
**适用场景:**
|
|||
|
|
- ✅ 需要始终可见的提示信息
|
|||
|
|
- ✅ 不希望被tooltip遮挡操作区域
|
|||
|
|
- ✅ 简单的实时信息展示
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 组件API
|
|||
|
|
|
|||
|
|
### ButtonWithTip
|
|||
|
|
|
|||
|
|
增强型工具提示按钮组件。
|
|||
|
|
|
|||
|
|
**Props:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ButtonWithTipProps {
|
|||
|
|
label: string // 按钮文本
|
|||
|
|
icon?: ReactNode // 按钮图标
|
|||
|
|
type?: 'primary' | 'default' // 按钮类型
|
|||
|
|
danger?: boolean // 是否为危险按钮
|
|||
|
|
disabled?: boolean // 是否禁用
|
|||
|
|
onClick?: () => void // 点击回调
|
|||
|
|
size?: 'small' | 'middle' | 'large'
|
|||
|
|
showTipIcon?: boolean // 是否显示提示图标
|
|||
|
|
tip?: {
|
|||
|
|
title?: string // 提示标题
|
|||
|
|
description?: string // 详细描述
|
|||
|
|
shortcut?: string // 快捷键
|
|||
|
|
notes?: string[] // 注意事项
|
|||
|
|
placement?: 'top' | 'bottom' | 'left' | 'right'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用示例:**
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
import ButtonWithTip from '@/components/ButtonWithTip/ButtonWithTip'
|
|||
|
|
|
|||
|
|
<ButtonWithTip
|
|||
|
|
label="新增主机"
|
|||
|
|
icon={<PlusOutlined />}
|
|||
|
|
type="primary"
|
|||
|
|
tip={{
|
|||
|
|
title: '新增主机',
|
|||
|
|
description: '向系统中添加新的主机终端设备',
|
|||
|
|
shortcut: 'Ctrl+N',
|
|||
|
|
notes: ['请确保IP地址不与现有主机冲突', 'MAC地址必须唯一']
|
|||
|
|
}}
|
|||
|
|
onClick={handleAdd}
|
|||
|
|
/>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### ActionHelpPanel
|
|||
|
|
|
|||
|
|
智能帮助面板组件(方案2)。
|
|||
|
|
|
|||
|
|
**Props:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ActionHelpPanelProps {
|
|||
|
|
visible: boolean // 是否显示面板
|
|||
|
|
onClose: () => void // 关闭回调
|
|||
|
|
currentAction?: { // 当前操作信息
|
|||
|
|
title: string
|
|||
|
|
icon: ReactNode
|
|||
|
|
description: string
|
|||
|
|
scenarios?: string[] // 使用场景
|
|||
|
|
steps?: string[] // 操作步骤
|
|||
|
|
warnings?: string[] // 注意事项
|
|||
|
|
shortcut?: string // 快捷键
|
|||
|
|
permission?: string // 权限要求
|
|||
|
|
badge?: {
|
|||
|
|
text: string
|
|||
|
|
color: string
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
allActions?: Array<Action> // 所有可用操作
|
|||
|
|
placement?: 'left' | 'right' // 面板位置
|
|||
|
|
onActionSelect?: (action: Action) => void // 选择操作回调
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用示例:**
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
import ActionHelpPanel from '@/components/ActionHelpPanel/ActionHelpPanel'
|
|||
|
|
|
|||
|
|
const [showPanel, setShowPanel] = useState(false)
|
|||
|
|
const [currentAction, setCurrentAction] = useState(null)
|
|||
|
|
|
|||
|
|
// 在按钮外层添加hover和点击事件
|
|||
|
|
<div
|
|||
|
|
onMouseEnter={() => setCurrentAction(actionsConfig.add)}
|
|||
|
|
onMouseLeave={() => !showPanel && setCurrentAction(null)}
|
|||
|
|
>
|
|||
|
|
<Button>新增主机</Button>
|
|||
|
|
<button onClick={() => setShowPanel(true)}>?</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<ActionHelpPanel
|
|||
|
|
visible={showPanel}
|
|||
|
|
onClose={() => setShowPanel(false)}
|
|||
|
|
currentAction={currentAction}
|
|||
|
|
allActions={Object.values(actionsConfig)}
|
|||
|
|
onActionSelect={(action) => setCurrentAction(action)}
|
|||
|
|
/>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### ButtonWithHoverCard
|
|||
|
|
|
|||
|
|
悬浮展开卡片按钮组件(方案3)。
|
|||
|
|
|
|||
|
|
**Props:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ButtonWithHoverCardProps {
|
|||
|
|
label: string
|
|||
|
|
icon?: ReactNode
|
|||
|
|
type?: 'primary' | 'default'
|
|||
|
|
danger?: boolean
|
|||
|
|
disabled?: boolean
|
|||
|
|
onClick?: () => void
|
|||
|
|
size?: 'small' | 'middle' | 'large'
|
|||
|
|
cardInfo?: {
|
|||
|
|
title: string
|
|||
|
|
icon: ReactNode
|
|||
|
|
description: string
|
|||
|
|
scenarios?: string[]
|
|||
|
|
quickTips?: string[]
|
|||
|
|
warnings?: string[]
|
|||
|
|
shortcut?: string
|
|||
|
|
badge?: { text: string; color: string }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**技术要点:**
|
|||
|
|
- 使用 `createPortal` 渲染卡片到 `document.body`
|
|||
|
|
- 使用 `useRef` 获取按钮位置
|
|||
|
|
- 避免z-index遮挡问题
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### ButtonWithGuide
|
|||
|
|
|
|||
|
|
智能引导按钮组件(方案4)。
|
|||
|
|
|
|||
|
|
**Props:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ButtonWithGuideProps {
|
|||
|
|
label: string
|
|||
|
|
icon?: ReactNode
|
|||
|
|
type?: 'primary' | 'default'
|
|||
|
|
danger?: boolean
|
|||
|
|
disabled?: boolean
|
|||
|
|
onClick?: () => void
|
|||
|
|
size?: 'small' | 'middle' | 'large'
|
|||
|
|
guide?: {
|
|||
|
|
title: string
|
|||
|
|
icon: ReactNode
|
|||
|
|
description: string
|
|||
|
|
steps?: string[]
|
|||
|
|
scenarios?: string[]
|
|||
|
|
warnings?: string[]
|
|||
|
|
shortcut?: string
|
|||
|
|
permission?: string
|
|||
|
|
badge?: { text: string; color: string }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**特点:**
|
|||
|
|
- 简洁的帮助图标(不影响按钮文字)
|
|||
|
|
- 点击打开弹窗式详细引导
|
|||
|
|
- 包含步骤式说明(使用Ant Design Steps组件)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### BottomHintBar
|
|||
|
|
|
|||
|
|
底部固定提示栏组件(方案5)。
|
|||
|
|
|
|||
|
|
**Props:**
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface BottomHintBarProps {
|
|||
|
|
visible: boolean
|
|||
|
|
hintInfo?: {
|
|||
|
|
title: string
|
|||
|
|
icon: ReactNode
|
|||
|
|
description: string
|
|||
|
|
quickTip?: string
|
|||
|
|
warning?: string
|
|||
|
|
shortcut?: string
|
|||
|
|
badge?: { text: string; color: string }
|
|||
|
|
}
|
|||
|
|
onClose?: () => void
|
|||
|
|
theme?: 'light' | 'dark' | 'gradient'
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用示例:**
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
import BottomHintBar from '@/components/BottomHintBar/BottomHintBar'
|
|||
|
|
|
|||
|
|
const [showHint, setShowHint] = useState(false)
|
|||
|
|
const [hintInfo, setHintInfo] = useState(null)
|
|||
|
|
|
|||
|
|
<div
|
|||
|
|
onMouseEnter={() => {
|
|||
|
|
setHintInfo(actionConfig)
|
|||
|
|
setShowHint(true)
|
|||
|
|
}}
|
|||
|
|
onMouseLeave={() => setShowHint(false)}
|
|||
|
|
>
|
|||
|
|
<Button>操作按钮</Button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<BottomHintBar
|
|||
|
|
visible={showHint}
|
|||
|
|
hintInfo={hintInfo}
|
|||
|
|
theme="gradient"
|
|||
|
|
/>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 使用指南
|
|||
|
|
|
|||
|
|
### 快速开始
|
|||
|
|
|
|||
|
|
1. **选择合适的方案**
|
|||
|
|
|
|||
|
|
根据使用场景选择组件:
|
|||
|
|
|
|||
|
|
| 场景 | 推荐方案 |
|
|||
|
|
|------|---------|
|
|||
|
|
| 简单列表页面,快速提示 | 方案1 增强型工具提示 |
|
|||
|
|
| 复杂后台系统,详细引导 | 方案2 智能帮助面板 ⭐ |
|
|||
|
|
| 数据密集页面,信息丰富 | 方案3 悬浮展开卡片 |
|
|||
|
|
| 新功能上线,用户引导 | 方案4 智能引导 |
|
|||
|
|
| 操作频繁,始终可见 | 方案5 底部固定提示栏 |
|
|||
|
|
|
|||
|
|
2. **导入组件**
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
// 方案1
|
|||
|
|
import ButtonWithTip from '@/components/ButtonWithTip/ButtonWithTip'
|
|||
|
|
|
|||
|
|
// 方案2
|
|||
|
|
import ActionHelpPanel from '@/components/ActionHelpPanel/ActionHelpPanel'
|
|||
|
|
|
|||
|
|
// 方案3
|
|||
|
|
import ButtonWithHoverCard from '@/components/ButtonWithHoverCard/ButtonWithHoverCard'
|
|||
|
|
|
|||
|
|
// 方案4
|
|||
|
|
import ButtonWithGuide from '@/components/ButtonWithGuide/ButtonWithGuide'
|
|||
|
|
|
|||
|
|
// 方案5
|
|||
|
|
import BottomHintBar from '@/components/BottomHintBar/BottomHintBar'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **配置操作信息**
|
|||
|
|
|
|||
|
|
建议将操作配置统一管理:
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
const actionsConfig = {
|
|||
|
|
add: {
|
|||
|
|
title: '新增主机',
|
|||
|
|
icon: <PlusOutlined />,
|
|||
|
|
description: '向系统中添加新的主机终端设备',
|
|||
|
|
scenarios: [
|
|||
|
|
'当有新设备需要接入系统管理时',
|
|||
|
|
'需要扩展终端设备数量时'
|
|||
|
|
],
|
|||
|
|
steps: [
|
|||
|
|
'点击"新增主机"按钮',
|
|||
|
|
'填写主机基本信息',
|
|||
|
|
'选择主机所属分组',
|
|||
|
|
'保存并等待主机上线'
|
|||
|
|
],
|
|||
|
|
warnings: [
|
|||
|
|
'请确保IP地址不与现有主机冲突',
|
|||
|
|
'MAC地址必须唯一且格式正确'
|
|||
|
|
],
|
|||
|
|
shortcut: 'Ctrl+N',
|
|||
|
|
permission: '管理员权限',
|
|||
|
|
badge: { text: '常用', color: 'blue' }
|
|||
|
|
},
|
|||
|
|
// ... 其他操作
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案2完整实现示例
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
import { useState } from 'react'
|
|||
|
|
import { Button } from 'antd'
|
|||
|
|
import { PlusOutlined } from '@ant-design/icons'
|
|||
|
|
import ActionHelpPanel from '@/components/ActionHelpPanel/ActionHelpPanel'
|
|||
|
|
|
|||
|
|
function MyPage() {
|
|||
|
|
const [showHelpPanel, setShowHelpPanel] = useState(false)
|
|||
|
|
const [currentAction, setCurrentAction] = useState(null)
|
|||
|
|
|
|||
|
|
// 处理悬停
|
|||
|
|
const handleHover = (actionKey) => {
|
|||
|
|
if (!showHelpPanel) {
|
|||
|
|
setCurrentAction(actionsConfig[actionKey])
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理离开
|
|||
|
|
const handleLeave = () => {
|
|||
|
|
if (!showHelpPanel) {
|
|||
|
|
setCurrentAction(null)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理点击
|
|||
|
|
const handleHelpClick = (e, actionKey) => {
|
|||
|
|
e.stopPropagation()
|
|||
|
|
setCurrentAction(actionsConfig[actionKey])
|
|||
|
|
setShowHelpPanel(true)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div>
|
|||
|
|
{/* 按钮区域 */}
|
|||
|
|
<div
|
|||
|
|
className="button-wrapper"
|
|||
|
|
onMouseEnter={() => handleHover('add')}
|
|||
|
|
onMouseLeave={handleLeave}
|
|||
|
|
>
|
|||
|
|
<Button type="primary" icon={<PlusOutlined />}>
|
|||
|
|
新增主机
|
|||
|
|
</Button>
|
|||
|
|
<button
|
|||
|
|
className="help-icon"
|
|||
|
|
onClick={(e) => handleHelpClick(e, 'add')}
|
|||
|
|
>
|
|||
|
|
?
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 帮助面板 */}
|
|||
|
|
<ActionHelpPanel
|
|||
|
|
visible={showHelpPanel}
|
|||
|
|
onClose={() => setShowHelpPanel(false)}
|
|||
|
|
currentAction={currentAction}
|
|||
|
|
allActions={Object.values(actionsConfig)}
|
|||
|
|
onActionSelect={(action) => setCurrentAction(action)}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 最佳实践
|
|||
|
|
|
|||
|
|
### 1. 内容编写规范
|
|||
|
|
|
|||
|
|
**功能描述:**
|
|||
|
|
- 用简洁的语言描述功能(1-2句话)
|
|||
|
|
- 突出重点和目的
|
|||
|
|
- 避免技术术语
|
|||
|
|
|
|||
|
|
**使用场景:**
|
|||
|
|
- 列举2-4个实际使用场景
|
|||
|
|
- 使用"当...时"的句式
|
|||
|
|
- 帮助用户理解何时使用
|
|||
|
|
|
|||
|
|
**操作步骤:**
|
|||
|
|
- 按实际操作顺序编写
|
|||
|
|
- 每步一句话,清晰明确
|
|||
|
|
- 使用动词开头
|
|||
|
|
|
|||
|
|
**注意事项:**
|
|||
|
|
- 危险操作必须有明确警告
|
|||
|
|
- 使用醒目的颜色标记
|
|||
|
|
- 提供实际的使用建议
|
|||
|
|
|
|||
|
|
### 2. 性能优化
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
// ✅ 使用useMemo缓存配置
|
|||
|
|
const actionsConfig = useMemo(() => ({
|
|||
|
|
add: { ... },
|
|||
|
|
delete: { ... }
|
|||
|
|
}), [])
|
|||
|
|
|
|||
|
|
// ✅ 防止不必要的重渲染
|
|||
|
|
const handleHover = useCallback((key) => {
|
|||
|
|
if (!showPanel) {
|
|||
|
|
setCurrentAction(actionsConfig[key])
|
|||
|
|
}
|
|||
|
|
}, [showPanel, actionsConfig])
|
|||
|
|
|
|||
|
|
// ✅ 面板打开时避免hover更新
|
|||
|
|
if (!showPanel) {
|
|||
|
|
setCurrentAction(null)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 可访问性
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
// 添加title属性
|
|||
|
|
<button className="help-icon" title="查看帮助">
|
|||
|
|
?
|
|||
|
|
</button>
|
|||
|
|
|
|||
|
|
// 添加aria标签
|
|||
|
|
<Button aria-label="新增主机">
|
|||
|
|
新增主机
|
|||
|
|
</Button>
|
|||
|
|
|
|||
|
|
// 快捷键支持
|
|||
|
|
useEffect(() => {
|
|||
|
|
const handleKeyPress = (e) => {
|
|||
|
|
if (e.ctrlKey && e.key === 'n') {
|
|||
|
|
handleAdd()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
window.addEventListener('keydown', handleKeyPress)
|
|||
|
|
return () => window.removeEventListener('keydown', handleKeyPress)
|
|||
|
|
}, [])
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 响应式适配
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
/* 移动端隐藏某些提示 */
|
|||
|
|
@media (max-width: 768px) {
|
|||
|
|
.help-icon {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hover-info-card {
|
|||
|
|
width: 100%;
|
|||
|
|
left: 0 !important;
|
|||
|
|
transform: translateY(-50%);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 更新日志
|
|||
|
|
|
|||
|
|
### v1.2.0 (2025-11-17)
|
|||
|
|
|
|||
|
|
**新增:**
|
|||
|
|
- ✨ 新增 `ButtonWithGuide` 组件,替代复杂的徽章设计
|
|||
|
|
- ✨ 方案2添加 `onActionSelect` 回调,支持点击卡片切换内容
|
|||
|
|
|
|||
|
|
**修复:**
|
|||
|
|
- 🐛 修复方案2点击"?"后内容消失的问题
|
|||
|
|
- 🐛 修复方案2"所有可用操作"卡片无法点击的问题
|
|||
|
|
- 🐛 修复方案3悬浮卡片被Card遮挡(使用Portal)
|
|||
|
|
- 🐛 修复菜单图标,从 `GlobalOutlined` 改为 `BlockOutlined`
|
|||
|
|
|
|||
|
|
**优化:**
|
|||
|
|
- 💄 简化方案4设计,去掉复杂的脉冲动画
|
|||
|
|
- 💄 方案2面板打开时不响应鼠标hover事件
|
|||
|
|
- 💄 提升整体视觉一致性
|
|||
|
|
|
|||
|
|
### v1.1.0 (2025-11-17)
|
|||
|
|
|
|||
|
|
**新增:**
|
|||
|
|
- ✨ 新增 `ActionHelpPanel` 智能帮助面板组件
|
|||
|
|
- ✨ 新增 `BottomHintBar` 底部提示栏组件
|
|||
|
|
- ✨ 方案2添加点击"?"图标直接打开面板功能
|
|||
|
|
|
|||
|
|
**修复:**
|
|||
|
|
- 🐛 修复 `ButtonWithTip` 的 Tooltip overlayClassName 警告
|
|||
|
|
- 🐛 修复 `AppSider` 的 findDOMNode 警告(使用 items 配置)
|
|||
|
|
- 🐛 修复方案5底部提示栏鼠标移动时闪烁的问题
|
|||
|
|
|
|||
|
|
**优化:**
|
|||
|
|
- 💄 为方案2按钮添加悬停时的"?"图标提示
|
|||
|
|
- 💄 提升方案3悬浮卡片的 z-index 和阴影效果
|
|||
|
|
|
|||
|
|
### v1.0.0 (2025-11-17)
|
|||
|
|
|
|||
|
|
**初始版本:**
|
|||
|
|
- 🎉 发布5种按钮扩展设计方案
|
|||
|
|
- 📦 提供完整的组件API和使用文档
|
|||
|
|
- 📝 提供详细的设计指南和最佳实践
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 技术架构
|
|||
|
|
|
|||
|
|
### 依赖项
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"react": "^18.2.0",
|
|||
|
|
"react-dom": "^18.2.0",
|
|||
|
|
"antd": "^5.x",
|
|||
|
|
"@ant-design/icons": "^5.x"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/components/
|
|||
|
|
├── ButtonWithTip/
|
|||
|
|
│ ├── ButtonWithTip.jsx
|
|||
|
|
│ └── ButtonWithTip.css
|
|||
|
|
├── ActionHelpPanel/
|
|||
|
|
│ ├── ActionHelpPanel.jsx
|
|||
|
|
│ └── ActionHelpPanel.css
|
|||
|
|
├── ButtonWithHoverCard/
|
|||
|
|
│ ├── ButtonWithHoverCard.jsx
|
|||
|
|
│ └── ButtonWithHoverCard.css
|
|||
|
|
├── ButtonWithGuide/
|
|||
|
|
│ ├── ButtonWithGuide.jsx
|
|||
|
|
│ └── ButtonWithGuide.css
|
|||
|
|
└── BottomHintBar/
|
|||
|
|
├── BottomHintBar.jsx
|
|||
|
|
└── BottomHintBar.css
|
|||
|
|
|
|||
|
|
src/pages/
|
|||
|
|
└── AllButtonDesigns.jsx # 演示页面
|
|||
|
|
|
|||
|
|
docs/
|
|||
|
|
└── components/
|
|||
|
|
└── ButtonExtensions.md # 本文档
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 在线演示
|
|||
|
|
|
|||
|
|
访问地址:**http://localhost:5173/design/button-designs**
|
|||
|
|
|
|||
|
|
菜单路径:**组件设计 → 扩展按钮**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### Q1: 如何选择合适的方案?
|
|||
|
|
|
|||
|
|
**A:** 根据以下因素选择:
|
|||
|
|
- **信息量**:少 → 方案1,多 → 方案2/3
|
|||
|
|
- **复杂度**:简单 → 方案1/5,复杂 → 方案2/4
|
|||
|
|
- **使用频率**:频繁 → 方案5,偶尔 → 方案1/3
|
|||
|
|
- **用户类型**:新手 → 方案2/4,熟练 → 方案1/5
|
|||
|
|
|
|||
|
|
### Q2: 可以混合使用多种方案吗?
|
|||
|
|
|
|||
|
|
**A:** 可以。建议:
|
|||
|
|
- 同一页面使用统一的方案
|
|||
|
|
- 不同页面可以使用不同方案
|
|||
|
|
- 核心操作使用方案2,次要操作使用方案1
|
|||
|
|
|
|||
|
|
### Q3: 如何自定义样式?
|
|||
|
|
|
|||
|
|
**A:** 所有组件都支持自定义样式:
|
|||
|
|
|
|||
|
|
```jsx
|
|||
|
|
// 通过className
|
|||
|
|
<ButtonWithTip className="my-custom-button" />
|
|||
|
|
|
|||
|
|
// 通过style
|
|||
|
|
<ButtonWithTip style={{ marginRight: 16 }} />
|
|||
|
|
|
|||
|
|
// 修改CSS变量
|
|||
|
|
:root {
|
|||
|
|
--tip-primary-gradient: linear-gradient(...);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Q4: 移动端如何适配?
|
|||
|
|
|
|||
|
|
**A:** 所有组件都内置了响应式支持:
|
|||
|
|
- 方案1:移动端隐藏提示图标
|
|||
|
|
- 方案2:面板宽度自适应
|
|||
|
|
- 方案3:卡片居中显示
|
|||
|
|
- 方案5:提示栏自适应布局
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 贡献指南
|
|||
|
|
|
|||
|
|
欢迎提出改进建议!
|
|||
|
|
|
|||
|
|
**提交Issues:**
|
|||
|
|
- 使用清晰的标题
|
|||
|
|
- 提供复现步骤
|
|||
|
|
- 附上截图或录屏
|
|||
|
|
|
|||
|
|
**提交Pull Requests:**
|
|||
|
|
- 遵循现有代码风格
|
|||
|
|
- 添加必要的注释
|
|||
|
|
- 更新相关文档
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 许可证
|
|||
|
|
|
|||
|
|
MIT License
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 联系方式
|
|||
|
|
|
|||
|
|
- 项目地址:`/Users/jiliu/工作/projects/Nex Design`
|
|||
|
|
- 文档路径:`src/components/docs/ButtonExtensions.md`
|
|||
|
|
- 在线演示:`http://localhost:5173/design/button-designs`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**最后更新:** 2025-11-17
|
|||
|
|
**文档版本:** v1.2.0
|