Skip to content

Commit a406074

Browse files
authored
feat: tooltip (#6)
* feat: tooltip
1 parent 7b26439 commit a406074

File tree

9 files changed

+1929
-22
lines changed

9 files changed

+1929
-22
lines changed
Lines changed: 387 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,387 @@
1+
# Tooltip 组件开发计划
2+
3+
## 项目概述
4+
5+
基于现有的 CCUI 项目代码规范,参考 Element Plus Tooltip 组件的实现,完善 Tooltip 组件的功能实现、样式设计、测试用例和文档。
6+
7+
## 技术架构分析
8+
9+
### 现有项目结构
10+
11+
- 使用 Vue 3 + TypeScript + JSX
12+
- 组件采用 `defineComponent` + `setup` 函数式组件
13+
- 使用 `useNamespace` hook 生成 BEM 规范的 CSS 类名
14+
- 组件 props 通过 `ExtractPropTypes` 定义类型
15+
- 测试使用 Vitest + Vue Test Utils
16+
17+
### Tooltip 组件核心功能需求
18+
19+
基于 Element Plus Tooltip 组件分析,需要实现以下核心功能:
20+
21+
```mermaid
22+
graph TD
23+
A[Tooltip 组件] --> B[基础功能]
24+
A --> C[高级功能]
25+
A --> D[样式主题]
26+
A --> E[交互控制]
27+
28+
B --> B1[内容显示]
29+
B --> B2[位置定位]
30+
B --> B3[触发方式]
31+
32+
C --> C1[延迟显示/隐藏]
33+
C --> C2[禁用状态]
34+
C --> C3[HTML内容支持]
35+
C --> C4[自定义样式]
36+
37+
D --> D1[Dark主题]
38+
D --> D2[Light主题]
39+
D --> D3[自定义主题]
40+
41+
E --> E1[鼠标悬停]
42+
E --> E2[点击触发]
43+
E --> E3[焦点触发]
44+
E --> E4[手动控制]
45+
```
46+
47+
## 组件设计规范
48+
49+
### Props 设计
50+
51+
```typescript
52+
interface TooltipProps {
53+
// 基础属性
54+
content: string // 提示内容
55+
placement: TooltipPlacement // 位置:top/bottom/left/right + start/end
56+
effect: 'dark' | 'light' // 主题效果
57+
58+
// 显示控制
59+
visible?: boolean // 手动控制显示状态
60+
disabled: boolean // 是否禁用
61+
showArrow: boolean // 是否显示箭头
62+
63+
// 交互控制
64+
trigger: 'hover' | 'click' | 'focus' | 'manual' // 触发方式
65+
showAfter: number // 延迟显示时间(ms)
66+
hideAfter: number // 延迟隐藏时间(ms)
67+
68+
// 样式定制
69+
popperClass?: string // 自定义弹出层类名
70+
offset: number // 偏移距离
71+
72+
// 高级功能
73+
rawContent: boolean // 是否支持HTML内容
74+
enterable: boolean // 鼠标是否可进入tooltip
75+
}
76+
```
77+
78+
### 事件设计
79+
80+
```typescript
81+
interface TooltipEmits {
82+
'before-show': () => void // 显示前触发
83+
'show': () => void // 显示后触发
84+
'before-hide': () => void // 隐藏前触发
85+
'hide': () => void // 隐藏后触发
86+
'update:visible': (visible: boolean) => void // v-model支持
87+
}
88+
```
89+
90+
## 实现方案
91+
92+
### 1. 组件核心逻辑实现
93+
94+
#### 位置计算系统
95+
96+
```mermaid
97+
graph LR
98+
A[触发元素] --> B[计算位置]
99+
B --> C[应用偏移]
100+
C --> D[边界检测]
101+
D --> E[最终定位]
102+
103+
B --> B1[top/bottom/left/right]
104+
B --> B2[start/center/end对齐]
105+
```
106+
107+
#### 状态管理
108+
109+
- 使用 `ref` 管理显示状态
110+
- 使用 `computed` 计算样式类名
111+
- 使用 `watch` 监听 props 变化
112+
113+
#### 事件处理
114+
115+
- 鼠标事件:mouseenter/mouseleave
116+
- 点击事件:click
117+
- 焦点事件:focus/blur
118+
- 键盘事件:keydown/keyup
119+
120+
### 2. 样式系统设计
121+
122+
#### BEM 类名规范
123+
124+
```scss
125+
.ccui-tooltip {
126+
// 触发器容器
127+
&__trigger {
128+
display: inline-block;
129+
}
130+
131+
// 弹出层
132+
&__popper {
133+
position: absolute;
134+
z-index: 2000;
135+
136+
// 主题变体
137+
&--dark {
138+
background: #303133;
139+
color: #fff;
140+
}
141+
142+
&--light {
143+
background: #fff;
144+
color: #303133;
145+
border: 1px solid #e4e7ed;
146+
}
147+
}
148+
149+
// 箭头
150+
&__arrow {
151+
position: absolute;
152+
153+
// 位置变体
154+
&--top {
155+
/* 箭头在上方 */
156+
}
157+
&--bottom {
158+
/* 箭头在下方 */
159+
}
160+
&--left {
161+
/* 箭头在左侧 */
162+
}
163+
&--right {
164+
/* 箭头在右侧 */
165+
}
166+
}
167+
168+
// 内容区域
169+
&__content {
170+
padding: 10px;
171+
font-size: 12px;
172+
line-height: 1.2;
173+
}
174+
}
175+
```
176+
177+
#### 动画效果
178+
179+
```scss
180+
.ccui-tooltip-fade-enter-active,
181+
.ccui-tooltip-fade-leave-active {
182+
transition: opacity 0.15s;
183+
}
184+
185+
.ccui-tooltip-fade-enter-from,
186+
.ccui-tooltip-fade-leave-to {
187+
opacity: 0;
188+
}
189+
```
190+
191+
### 3. 测试策略
192+
193+
#### 单元测试覆盖
194+
195+
```mermaid
196+
graph TD
197+
A[测试用例] --> B[基础功能测试]
198+
A --> C[交互测试]
199+
A --> D[边界测试]
200+
A --> E[可访问性测试]
201+
202+
B --> B1[组件渲染]
203+
B --> B2[Props传递]
204+
B --> B3[插槽内容]
205+
206+
C --> C1[鼠标悬停]
207+
C --> C2[点击触发]
208+
C --> C3[键盘操作]
209+
210+
D --> D1[边界位置]
211+
D --> D2[极值参数]
212+
D --> D3[异常情况]
213+
214+
E --> E1[ARIA属性]
215+
E --> E2[键盘导航]
216+
E --> E3[屏幕阅读器]
217+
```
218+
219+
#### 测试用例设计
220+
221+
1. **基础渲染测试**
222+
- 组件正常挂载
223+
- 默认 props 生效
224+
- 插槽内容正确显示
225+
226+
2. **交互功能测试**
227+
- 鼠标悬停显示/隐藏
228+
- 点击触发显示/隐藏
229+
- 延迟显示/隐藏时间
230+
- 禁用状态测试
231+
232+
3. **位置定位测试**
233+
- 9种位置正确显示
234+
- 边界自动调整
235+
- 偏移量计算
236+
237+
4. **主题样式测试**
238+
- dark/light 主题切换
239+
- 自定义样式应用
240+
- 箭头显示/隐藏
241+
242+
### 4. 文档完善
243+
244+
#### API 文档结构
245+
246+
```markdown
247+
# Tooltip 文字提示
248+
249+
常用于展示鼠标 hover 时的提示信息。
250+
251+
## 何时使用
252+
253+
- 鼠标移入则显示提示,移出消失,气泡浮层不承载复杂文本和操作
254+
- 可用来代替系统默认的 title 提示,提供一个更好的用户体验
255+
256+
## 基本用法
257+
258+
:::demo 基础的、简洁的文字提示气泡框
259+
260+
## 不同位置
261+
262+
:::demo Tooltip 组件提供了12个不同的方向显示Tooltip
263+
264+
## 主题
265+
266+
:::demo Tooltip 组件内置了两个主题:dark和light
267+
268+
## 更多内容
269+
270+
:::demo 展示多行文本或者是设置文本内容的格式
271+
272+
## 高级扩展
273+
274+
:::demo 自定义过渡动画、延迟时间等高级功能
275+
```
276+
277+
#### 示例代码
278+
279+
每个功能点提供完整的 Vue 示例代码,包括:
280+
281+
- Template 使用方式
282+
- Script 配置选项
283+
- Style 样式定制
284+
285+
## 开发里程碑
286+
287+
### 阶段一:核心功能实现
288+
289+
1. **Props 类型定义** - 完善 `tooltip-types.ts`
290+
2. **基础组件结构** - 实现 `tooltip.tsx` 核心逻辑
291+
3. **位置计算系统** - 实现 12 种位置的定位算法
292+
4. **事件处理机制** - 实现各种触发方式
293+
294+
### 阶段二:样式和主题
295+
296+
1. **基础样式** - 完善 `tooltip.scss`
297+
2. **主题系统** - 实现 dark/light 主题
298+
3. **动画效果** - 添加过渡动画
299+
4. **响应式适配** - 确保各尺寸设备兼容
300+
301+
### 阶段三:测试和文档
302+
303+
1. **单元测试** - 完善 `tooltip.test.ts`
304+
2. **集成测试** - 测试与其他组件的交互
305+
3. **文档示例** - 完善 `index.md` 文档
306+
4. **可访问性** - 确保符合 WCAG 标准
307+
308+
### 阶段四:优化和发布
309+
310+
1. **性能优化** - 减少重复计算,优化渲染
311+
2. **边界处理** - 处理各种边界情况
312+
3. **代码审查** - 确保代码质量
313+
4. **版本发布** - 更新组件状态为 100%
314+
315+
## 质量保证
316+
317+
### 代码规范
318+
319+
- 遵循项目现有的 TypeScript 规范
320+
- 使用 ESLint 和 Prettier 格式化
321+
- 组件命名遵循 BEM 规范
322+
- 注释覆盖率达到 80% 以上
323+
324+
### 测试覆盖率
325+
326+
- 单元测试覆盖率 > 90%
327+
- 集成测试覆盖主要使用场景
328+
- 端到端测试验证用户交互流程
329+
330+
### 性能指标
331+
332+
- 组件初始化时间 < 10ms
333+
- 位置计算时间 < 5ms
334+
- 内存占用优化,避免内存泄漏
335+
336+
### 兼容性
337+
338+
- 支持 Vue 3.x
339+
- 支持现代浏览器 (Chrome 90+, Firefox 88+, Safari 14+)
340+
- 支持移动端触摸交互
341+
342+
## 风险评估
343+
344+
### 技术风险
345+
346+
- **位置计算复杂性**: 需要处理各种边界情况和滚动容器
347+
- **事件处理冲突**: 可能与其他组件的事件处理产生冲突
348+
- **性能问题**: 频繁的位置计算可能影响性能
349+
350+
### 解决方案
351+
352+
- 使用成熟的定位算法库或参考 Element Plus 实现
353+
- 建立完善的事件委托和清理机制
354+
- 实现防抖和节流优化性能
355+
356+
## 验收标准
357+
358+
### 功能完整性
359+
360+
- [ ] 支持 12 种位置定位
361+
- [ ] 支持 4 种触发方式
362+
- [ ] 支持 dark/light 主题
363+
- [ ] 支持延迟显示/隐藏
364+
- [ ] 支持禁用状态
365+
- [ ] 支持 HTML 内容
366+
- [ ] 支持自定义样式
367+
368+
### 代码质量
369+
370+
- [ ] TypeScript 类型完整
371+
- [ ] 单元测试覆盖率 > 90%
372+
- [ ] 代码审查通过
373+
- [ ] 性能测试通过
374+
375+
### 用户体验
376+
377+
- [ ] 交互流畅自然
378+
- [ ] 视觉效果美观
379+
- [ ] 可访问性良好
380+
- [ ] 文档清晰完整
381+
382+
### 项目集成
383+
384+
- [ ] 与现有组件库风格一致
385+
- [ ] 构建和打包正常
386+
- [ ] 在示例项目中正常运行
387+
- [ ] 组件状态更新为 100%

packages/ccui/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"coverage": "vitest run --coverage"
3030
},
3131
"dependencies": {
32+
"@floating-ui/dom": "^1.7.4",
33+
"@floating-ui/vue": "^1.1.9",
3234
"dayjs": "^1.11.19",
3335
"theme": "workspace:*",
3436
"vue": "^3.5.22"

0 commit comments

Comments
 (0)