# RightKey 组件详细文档 > 本文档详细描述 RightKey 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。 --- ## 1. 组件概述 ### 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) ``` **��数**: - `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` 销毁组件 **功能**: - 解绑全局事件 - 卸载内容 - 移除自身 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 详细描述 ### 4.1 DOM 结构 ```html
``` ### 4.2 CSS 类名 #### `.bim-right-key` - `position: fixed`: 固定定位,相对于视口。 - `display: none`: 默认隐藏。 - `box-shadow`: 即使内容组件没有阴影,容器也可以提供(当前��要由内容组件自己提供)。 --- ## 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 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 |