2025-12-10 09:46:22 +08:00
|
|
|
|
# RightKey 组件详细文档
|
|
|
|
|
|
|
|
|
|
|
|
> 本文档详细描述 RightKey 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
|
|
|
|
|
## 1. 组件概述
|
|
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
### 1.1 基本信息
|
|
|
|
|
|
- **组件名称**: `BimRightKey`
|
|
|
|
|
|
- **文件路径**: `src/components/right-key/index.ts`
|
|
|
|
|
|
- **类型定义**: `src/components/right-key/types.ts`
|
|
|
|
|
|
- **样式文件**: `src/components/right-key/index.css`
|
|
|
|
|
|
- **实现接口**: `IBimComponent`
|
|
|
|
|
|
- **用途**: 提供一个全屏感知的定位容器,用于显示右键菜单等浮层内容。
|
|
|
|
|
|
- **特点**: 自动边界检测(防止溢出屏幕)、点击外部自动关闭、内容无关性(支持挂载任意内容)。
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 在 SDK 中的位置
|
|
|
|
|
|
- RightKey 是右键菜单系统的容器部分。
|
|
|
|
|
|
- 必须通过 `RightKeyManager` 使用,不允许直接使用。
|
|
|
|
|
|
- `RightKeyManager` 位于 `src/managers/right-key-manager.ts`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 组件类 API 文档
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 构造函数
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
constructor(options?: RightKeyOptions)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**<2A><>数**:
|
|
|
|
|
|
- `options`:
|
|
|
|
|
|
- `zIndex`: number (默认 10000)
|
|
|
|
|
|
- `className`: string
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 公共方法
|
|
|
|
|
|
|
|
|
|
|
|
#### `init(): void`
|
|
|
|
|
|
初始化组件(实现 `IBimComponent` 接口)
|
|
|
|
|
|
|
|
|
|
|
|
**功能**:
|
|
|
|
|
|
- 创建 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`
|
|
|
|
|
|
销毁组件
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
**功能**:
|
|
|
|
|
|
- 解绑全局事件
|
|
|
|
|
|
- 卸载内容
|
|
|
|
|
|
- 移除自身 DOM
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
---
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
## 3. Manager API 文档
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
### 3.1 RightKeyManager 类
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
**文件路径**: `src/managers/right-key-manager.ts`
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
#### `registerHandler(handler: (e) => MenuItemConfig[] | null): void`
|
|
|
|
|
|
注册上下文菜单处理器
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
**参数**:
|
|
|
|
|
|
- `handler`: 函数,接收 MouseEvent,返回菜单配置数组或 null。
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
**功能**:
|
|
|
|
|
|
- 将 handler 加入内部列表。
|
|
|
|
|
|
- 右键点击时,遍历列表。只要有一个 handler 返回了非空数组,就显示这些菜单项。
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
#### `showMenu(x, y, items, groupOrder?): void`
|
|
|
|
|
|
手动显示菜单
|
|
|
|
|
|
|
|
|
|
|
|
**功能**:
|
|
|
|
|
|
- 创建 `BimMenu` 实例
|
|
|
|
|
|
- 调用 `rightKeyPanel.mount(menu)`
|
|
|
|
|
|
- 调用 `rightKeyPanel.show(x, y)`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
|
|
|
|
|
## 4. UI 详细描述
|
|
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
### 4.1 DOM 结构
|
|
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
|
<!-- 容器 -->
|
|
|
|
|
|
<div class="bim-right-key" style="z-index: 9000; display: none; left: ...; top: ...">
|
|
|
|
|
|
<!-- 挂载的内容 (例如 BimMenu 的 ul) -->
|
|
|
|
|
|
<ul class="bim-menu">...</ul>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 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 边界检测算法
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
在 `show(x, y)` 时执行:
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
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`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-12-09 18:34:43 +08:00
|
|
|
|
|
|
|
|
|
|
## 6. 类型定义
|
|
|
|
|
|
|
2025-12-10 09:46:22 +08:00
|
|
|
|
### 6.1 IRightKeyContent
|
|
|
|
|
|
|
2025-12-09 18:34:43 +08:00
|
|
|
|
```typescript
|
2025-12-10 09:46:22 +08:00
|
|
|
|
interface IRightKeyContent {
|
2025-12-09 18:34:43 +08:00
|
|
|
|
getElement(): HTMLElement;
|
|
|
|
|
|
destroy(): void;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-12-10 09:46:22 +08:00
|
|
|
|
|
|
|
|
|
|
### 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 |
|