docs: update menu and right-key component documentation
This commit is contained in:
@@ -1,58 +1,211 @@
|
||||
# RightKey 组件文档
|
||||
# RightKey 组件详细文档
|
||||
|
||||
> 本文档详细描述 RightKey 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。
|
||||
|
||||
---
|
||||
|
||||
## 1. 组件概述
|
||||
|
||||
`BimRightKey` 是一个通用的右键浮层容器组件。
|
||||
- **位置**: `src/components/right-key/index.ts`
|
||||
- **功能**: 负责在指定坐标 (x, y) 显示内容,处理边界检测防止溢出屏幕,以及点击外部自动关闭。
|
||||
- **特点**: 它不关心内容是什么,通过 `mount()` 方法挂载任意实现 `IRightKeyContent` 接口的内容组件。
|
||||
### 1.1 基本信息
|
||||
- **组件名称**: `BimRightKey`
|
||||
- **文件路径**: `src/components/right-key/index.ts`
|
||||
- **类型定义**: `src/components/right-key/types.ts`
|
||||
- **样式文件**: `src/components/right-key/index.css`
|
||||
- **实现接口**: `IBimComponent`
|
||||
- **用途**: 提供一个全屏感知的定位容器,用于显示右键菜单等浮层内容。
|
||||
- **特点**: 自动边界检测(防止溢出屏幕)、点击外部自动关闭、内容无关性(支持挂载任意内容)。
|
||||
|
||||
## 2. 组件类 API
|
||||
### 1.2 在 SDK 中的位置
|
||||
- RightKey 是右键菜单系统的容器部分。
|
||||
- 必须通过 `RightKeyManager` 使用,不允许直接使用。
|
||||
- `RightKeyManager` 位于 `src/managers/right-key-manager.ts`。
|
||||
|
||||
### `BimRightKey`
|
||||
---
|
||||
|
||||
#### 方法
|
||||
## 2. 组件类 API 文档
|
||||
|
||||
| 方法名 | 参数 | 返回值 | 描述 |
|
||||
|:----|:---|:---|:---|
|
||||
| `init` | `()` | `void` | 初始化,绑定全局点击事件 |
|
||||
| `mount` | `(content: IRightKeyContent)` | `void` | 挂载内容组件 |
|
||||
| `show` | `(x: number, y: number)` | `void` | <20><><EFBFBD>指定位置显示,会自动调整位置防止溢出 |
|
||||
| `hide` | `()` | `void` | 隐藏容器 |
|
||||
| `destroy` | `()` | `void` | 销毁容器,解绑事件 |
|
||||
| `setOnClose` | `(callback: () => void)` | `void` | 设置关闭时的回调 |
|
||||
### 2.1 构造函数
|
||||
|
||||
## 3. Manager API
|
||||
```typescript
|
||||
constructor(options?: RightKeyOptions)
|
||||
```
|
||||
|
||||
### `RightKeyManager`
|
||||
**<EFBFBD><EFBFBD>数**:
|
||||
- `options`:
|
||||
- `zIndex`: number (默认 10000)
|
||||
- `className`: string
|
||||
|
||||
- **位置**: `src/managers/right-key-manager.ts`
|
||||
- **功能**: 监听容器的 `contextmenu` 事件,决定显示什么内容。
|
||||
### 2.2 公共方法
|
||||
|
||||
#### 方法
|
||||
#### `init(): void`
|
||||
初始化组件(实现 `IBimComponent` 接口)
|
||||
|
||||
| 方法名 | 参数 | 返回值 | 描述 |
|
||||
|:----|:---|:---|:---|
|
||||
| `registerHandler` | `(handler: (e) => BimMenuItem[])` | `void` | 注册上下文处理器 |
|
||||
| `showMenu` | `(x, y, items, groupOrder?)` | `void` | 手动显示菜单 |
|
||||
| `hide` | `()` | `void` | 隐藏 |
|
||||
**功能**:
|
||||
- 创建 DOM 结构
|
||||
- 将容器挂载到 `document.body`(或其他指定容器,当前实现是 body)
|
||||
- 绑定全局 `mousedown` 事件用于检测“点击外部”
|
||||
|
||||
#### `mount(content: IRightKeyContent): void`
|
||||
挂载内容组件
|
||||
|
||||
**参数**:
|
||||
- `content`: 实现了 `IRightKeyContent` 接口的对象(如 `BimMenu`)
|
||||
|
||||
**功能**:
|
||||
- 清空当前容器内容
|
||||
- 调用 `content.getElement()` 并将结果 append 到容器中
|
||||
- 保存 content 引用
|
||||
|
||||
#### `unmountContent(): void`
|
||||
卸载内容
|
||||
|
||||
**功能**:
|
||||
- 调用 `content.destroy()`
|
||||
- 清空容器 DOM
|
||||
|
||||
#### `show(x: number, y: number): void`
|
||||
显示容器
|
||||
|
||||
**参数**:
|
||||
- `x`, `y`: 屏幕坐标(通常是鼠标事件的 `clientX/Y`)
|
||||
|
||||
**功能**:
|
||||
- 计算容器尺寸
|
||||
- 执行边界检测算法,调整坐标防止溢出
|
||||
- 设置 `top/left` 样式
|
||||
- 设置 `display: block`
|
||||
|
||||
#### `hide(): void`
|
||||
隐藏容器
|
||||
|
||||
**功能**:
|
||||
- 设置 `display: none`
|
||||
- 触发 `onClose` 回调(如果设置了)
|
||||
|
||||
#### `setOnClose(callback: () => void): void`
|
||||
设置关闭回调
|
||||
|
||||
**功能**:
|
||||
- 注册一个回调函数,在容器被隐藏(如点击外部)时触发。通常用于通知 Manager 清理状态。
|
||||
|
||||
#### `destroy(): void`
|
||||
销毁组件
|
||||
|
||||
**功能**:
|
||||
- 解绑全局事件
|
||||
- 卸载内容
|
||||
- 移除自身 DOM
|
||||
|
||||
---
|
||||
|
||||
## 3. Manager API 文档
|
||||
|
||||
### 3.1 RightKeyManager 类
|
||||
|
||||
**文件路径**: `src/managers/right-key-manager.ts`
|
||||
|
||||
#### `registerHandler(handler: (e) => MenuItemConfig[] | null): void`
|
||||
注册上下文菜单处理器
|
||||
|
||||
**参数**:
|
||||
- `handler`: 函数,接收 MouseEvent,返回菜单配置数组或 null。
|
||||
|
||||
**功能**:
|
||||
- 将 handler 加入内部列表。
|
||||
- 右键点击时,遍历列表。只要有一个 handler 返回了非空数组,就显示这些菜单项。
|
||||
|
||||
#### `showMenu(x, y, items, groupOrder?): void`
|
||||
手动显示菜单
|
||||
|
||||
**功能**:
|
||||
- 创建 `BimMenu` 实例
|
||||
- 调用 `rightKeyPanel.mount(menu)`
|
||||
- 调用 `rightKeyPanel.show(x, y)`
|
||||
|
||||
---
|
||||
|
||||
## 4. UI 详细描述
|
||||
|
||||
- **容器**: `<div class="bim-right-key"></div>`
|
||||
- **定位**: `position: fixed`
|
||||
- **层级**: `z-index: 10000` (默认)
|
||||
### 4.1 DOM 结构
|
||||
|
||||
## 5. 实现细节
|
||||
```html
|
||||
<!-- 容器 -->
|
||||
<div class="bim-right-key" style="z-index: 9000; display: none; left: ...; top: ...">
|
||||
<!-- 挂载的内容 (例如 BimMenu 的 ul) -->
|
||||
<ul class="bim-menu">...</ul>
|
||||
</div>
|
||||
```
|
||||
|
||||
- **边界检测**: 在 `show(x, y)` 时,会计算容器宽高和视口宽高。如果 `x + width > viewportWidth`,则 `x = x - width`(向左展开)。同理处理垂直方向。
|
||||
- **点击外部关闭**: 监听 `document` 的 `mousedown` 事件,如果点击目标不在容器内,则调用 `hide()`。
|
||||
### 4.2 CSS 类名
|
||||
|
||||
#### `.bim-right-key`
|
||||
- `position: fixed`: 固定定位,相对于视口。
|
||||
- `display: none`: 默认隐藏。
|
||||
- `box-shadow`: 即使内容组件没有阴影,容器也可以提供(当前<E5BD93><E5898D>要由内容组件自己提供)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 逻辑流程详细描述
|
||||
|
||||
### 5.1 全局点击检测 (`handleGlobalClick`)
|
||||
|
||||
组件初始化时,会在 `document` 上绑定 `mousedown` (捕获阶段或冒泡阶段,通常冒泡即可)。
|
||||
|
||||
1. 当 `mousedown` 发生时,检查 `event.target`。
|
||||
2. 如果 `target` 位于 `.bim-right-key` 容器内部,**不做处理**(认为是有效的内部交互)。
|
||||
3. 如果 `target` 在容器外部,调用 `hide()` 关闭菜单。
|
||||
|
||||
**注意**: 子菜单(SubMenu)通常挂载在 `body` 上,物理上位于 `.bim-right-key` 外部。为了防止点击子菜单时误关主菜单,子菜单容器必须阻止 `mousedown` 冒泡(见 Menu 组件文档)。
|
||||
|
||||
### 5.2 边界检测算法
|
||||
|
||||
在 `show(x, y)` 时执行:
|
||||
|
||||
1. 获取容器尺寸: `rect = element.getBoundingClientRect()`
|
||||
2. 获取视口尺寸: `winW = window.innerWidth`, `winH = window.innerHeight`
|
||||
3. **水平调整**:
|
||||
- 如果 `x + rect.width > winW`: `x = x - rect.width`(向左展开)
|
||||
- 否则: `x` 保持不变(向右展开)
|
||||
4. **垂直调整**:
|
||||
- 如果 `y + rect.height > winH`: `y = y - rect.height`(向上展开)
|
||||
- 否则: `y` 保持不变(向下展开)
|
||||
5. 应用调整后的 `x, y` 到 `style.left` 和 `style.top`。
|
||||
|
||||
---
|
||||
|
||||
## 6. 类型定义
|
||||
|
||||
### 6.1 IRightKeyContent
|
||||
|
||||
```typescript
|
||||
export interface IRightKeyContent {
|
||||
interface IRightKeyContent {
|
||||
getElement(): HTMLElement;
|
||||
destroy(): void;
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 RightKeyOptions
|
||||
|
||||
```typescript
|
||||
interface RightKeyOptions {
|
||||
className?: string;
|
||||
zIndex?: number;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 文件清单
|
||||
|
||||
- `src/components/right-key/index.ts`: 组件核心逻辑
|
||||
- `src/components/right-key/index.css`: 样式
|
||||
- `src/components/right-key/types.ts`: 类型定义
|
||||
- `src/managers/right-key-manager.ts`: 管理器
|
||||
|
||||
---
|
||||
|
||||
## 8. 更新记录
|
||||
|
||||
| 日期 | 修改内容 | 修改人 |
|
||||
|------|---------|--------|
|
||||
| 2024-XX-XX | 更新 Manager API 以支持 MenuItemConfig | AI Assistant |
|
||||
Reference in New Issue
Block a user