Files
bim_engine/docs-old/components/弹窗组件-Dialog.md

908 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dialog 组件详细文档
> 本文档详细描述 Dialog 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。
---
## 1. 组件概述
### 1.1 基本信息
- **组件名称**: `BimDialog`
- **文件路径**: `src/components/dialog/index.ts`
- **类型定义**: `src/components/dialog/index.type.ts`
- **样式文件**: `src/components/dialog/index.css`
- **实现接口**: `IBimComponent`
- **用途**: 提供可拖拽、可缩放的通用弹窗组件,支持自定义内容和样式
### 1.2 在 SDK 中的位置
- Dialog 组件是独立的 UI 组件
- 必须通过 `DialogManager` 使用,不允许直接使用
- `DialogManager` 位于 `src/managers/dialog-manager.ts`
---
## 2. 组件类 API 文档
### 2.1 构造函数
```typescript
constructor(options: DialogOptions)
```
**参数**:
- `options`: `DialogOptions` - 弹窗配置选项(详见类型定义)
**默认配置**:
```typescript
{
title: 'Dialog',
width: 300,
height: 'auto',
position: 'center',
draggable: true,
resizable: false,
minWidth: 200,
minHeight: 100
}
```
**行为**:
- 合并用户配置和默认配置
- 创建 DOM 结构
- 自动调用 `init()` 方法
### 2.2 公共方法
#### `init(): void`
初始化组件功能(实现 `IBimComponent` 接口)
**功能**:
- 将弹窗元素添加到容器
- 初始化位置
- 如果 `draggable` 为 true初始化拖拽功能
- 如果 `resizable` 为 true初始化缩放功能
- 订阅主题和语言变更
- 调用 `onOpen` 回调
**调用时机**: 构造函数中自动调用,也可手动调用
#### `setTheme(theme: ThemeConfig): void`
设置主题(实现 `IBimComponent` 接口)
**参数**:
- `theme`: `ThemeConfig` - 全局主题配置
**功能**:
- 将主题颜色映射到 CSS 变量
- 如果用户未自定义颜色,使用主题颜色
- 如果用户已自定义颜色,保持用户自定义
**CSS 变量映射**:
- `--bim-dialog-bg``theme.panelBackground` (如果未自定义 `backgroundColor`)
- `--bim-dialog-header-bg``theme.componentHover` (如果未自定义 `headerBackgroundColor`)
- `--bim-dialog-title-color``theme.textPrimary` (如果未自定义 `titleColor`)
- `--bim-dialog-text-color``theme.textPrimary` (如果未自定义 `textColor`)
- `--bim-dialog-border-color``theme.border` (如果未自定义 `borderColor`)
#### `setLocales(): void`
设置语言(实现 `IBimComponent` 接口)
**功能**:
- 更新标题文本(如果标题是翻译键)
- 使用 `t()` 函数获取翻译后的文本
**行为**:
- 查找 `.bim-dialog-title` 元素
- 如果 `options.title` 存在,使用 `t(options.title)` 更新文本
#### `setContent(content: HTMLElement | string): void`
动态设置弹窗内容
**参数**:
- `content`: `HTMLElement | string` - 内容元素或 HTML 字符串
**功能**:
- 清空当前内容
- 设置新内容(支持 HTML 字符串或 DOM 元素)
#### `fitHeight(recenter: boolean = false): void`
根据内容自动调整弹窗高度
**使用场景**
- 弹窗内容存在“展开/收起”等高度变化的交互(例如测量面板展开后需要增高弹窗,避免遮挡底部操作按钮)
**参数**
- `recenter`: 是否根据 `options.position` 重新计算定位(默认 `false`
**行为**
- 先将高度设置为 `auto`,获取自然高度
- 再将高度夹紧到 `[minHeight, containerHeight]` 范围内
- 默认不重置用户拖拽后的 `left/top`,仅做边界夹紧;若 `recenter=true` 则按 `position` 重新定位
#### `close(): void`
关闭弹窗并销毁
**功能**:
- 清理 `requestAnimationFrame`(如果存在)
- 取消主题和语言订阅
- 从 DOM 中移除元素
- 标记为已销毁
- 调用 `onClose` 回调
#### `destroy(): void`
销毁组件(实现 `IBimComponent` 接口)
**功能**:
- 调用 `close()` 方法
### 2.3 私有方法(供理解实现细节)
#### `createDom(): HTMLElement`
创建弹窗的 DOM 结构
**返回**: 创建的弹窗根元素
**DOM 结构**:
```html
<div class="bim-dialog" [id="..."]>
<div class="bim-dialog-header" [class="draggable"]>
<span class="bim-dialog-title">标题文本</span>
<span class="bim-dialog-close">&times;</span>
</div>
<div class="bim-dialog-content">
<!-- 用户内容 -->
</div>
[<div class="bim-dialog-resize-handle"></div>] <!-- 如果 resizable -->
</div>
```
**关键实现**:
1. 创建根元素,应用 CSS 变量和尺寸
2. 创建标题栏,包含标题和关闭按钮
3. 创建内容区域,支持 HTML 字符串或 DOM 元素
4. 如果 `resizable` 为 true创建缩放手柄
5. **事件拦截**: 绑定所有鼠标/触摸事件,使用 `stopPropagation()` 阻止冒泡,防止传递给 3D 引擎
**事件拦截列表**:
```typescript
['click', 'dblclick', 'contextmenu', 'wheel',
'mousedown', 'mouseup', 'mousemove',
'touchstart', 'touchend', 'touchmove',
'pointerdown', 'pointerup', 'pointermove',
'pointerenter', 'pointerleave', 'pointerover', 'pointerout']
```
#### `initPosition(): void`
初始化弹窗位置
**功能**:
- 根据 `position` 选项计算弹窗位置
- 支持预设位置(如 'center', 'top-left' 等)或坐标对象 `{ x, y }`
- 确保弹窗不超出容器边界
**位置计算逻辑**:
- `center`: `left = (containerWidth - dialogWidth) / 2`, `top = (containerHeight - dialogHeight) / 2`
- `top-left`: `left = 0`, `top = 0`
- `top-center`: `left = (containerWidth - dialogWidth) / 2`, `top = 0`
- `top-right`: `left = containerWidth - dialogWidth`, `top = 0`
- `left-center`: `left = 0`, `top = (containerHeight - dialogHeight) / 2`
- `right-center`: `left = containerWidth - dialogWidth`, `top = (containerHeight - dialogHeight) / 2`
- `bottom-left`: `left = 0`, `top = containerHeight - dialogHeight`
- `bottom-center`: `left = (containerWidth - dialogWidth) / 2`, `top = containerHeight - dialogHeight`
- `bottom-right`: `left = containerWidth - dialogWidth`, `top = containerHeight - dialogHeight`
- `{ x, y }`: 直接使用坐标值
**边界限制**:
```typescript
left = Math.max(0, Math.min(left, containerWidth - dialogWidth));
top = Math.max(0, Math.min(top, containerHeight - dialogHeight));
```
#### `initDrag(): void`
初始化拖拽功能
**功能**:
- 在标题栏上绑定 `mousedown` 事件
- 实现拖拽移动功能
- 使用 `requestAnimationFrame` 优化性能
- 使用 `capture: true` 确保事件在捕获阶段处理
**拖拽流程**:
1. `mousedown`: 记录起始位置和弹窗当前位置,缓存容器和弹窗尺寸
2. `mousemove`: 计算偏移量,更新弹窗位置,限制在容器边界内
3. `mouseup`: 清理事件监听和动画帧
**性能优化**:
- 使用 `requestAnimationFrame` 节流更新
- 缓存容器和弹窗尺寸,减少 reflow
- 使用 `capture: true` 确保事件处理
#### `initResize(): void`
初始化缩放功能
**功能**:
- 在缩放手柄上绑定 `mousedown` 事件
- 实现右下角拖拽缩放功能
- 使用 `requestAnimationFrame` 优化性能
- 限制最小尺寸
**缩放流程**:
1. `mousedown`: 记录起始位置和弹窗当前尺寸
2. `mousemove`: 计算偏移量,更新弹窗尺寸,限制最小尺寸
3. `mouseup`: 清理事件监听和动画帧
**尺寸限制**:
```typescript
newWidth = Math.max(minWidth || 100, startWidth + deltaX);
newHeight = Math.max(minHeight || 50, startHeight + deltaY);
```
---
## 3. 分化组件说明
### 3.1 BimInfoDialog
**文件路径**: `src/components/dialog/bimInfoDialog/index.ts`
**继承关系**: `BimInfoDialog extends BimDialog`
**特殊功能**:
- 预定义了信息展示的内容结构
- 包含标题、信息列表和操作按钮
- 使用固定的配置(宽度 320px可缩放可拖拽
**实现方式**:
- 在构造函数中创建内容 DOM
- 调用父类构造函数,传入预定义的配置
- 不需要重写其他方法,直接继承父类功能
**内容结构**:
```html
<div class="bim-info-dialog-content">
<h3>Model Information</h3>
<ul>
<li><strong>Name:</strong> Sample Project</li>
<li><strong>Version:</strong> 1.0.0</li>
<li><strong>Date:</strong> 当前日期</li>
<li><strong>Status:</strong> <span style="color: green;">Active</span></li>
</ul>
<button>Update Status</button>
</div>
```
**与父类的差异**:
- 固定了内容结构
- 固定了部分配置选项
- 其他功能完全继承自 `BimDialog`
---
## 4. Manager API 文档
### 4.1 DialogManager 类
**文件路径**: `src/managers/dialog-manager.ts`
**继承关系**: `DialogManager extends BimComponent`
### 4.2 构造函数
```typescript
constructor(engine: BimEngine, container: HTMLElement)
```
**参数**:
- `engine`: `BimEngine` - 引擎实例
- `container`: `HTMLElement` - 弹窗挂载的目标容器
**行为**:
- 保存容器引用
- 监听 `ui:open-dialog` 事件
- 如果事件 payload.id 是 'info',自动打开信息弹窗
### 4.3 公共方法
#### `create(options: Omit<DialogOptions, 'container'>): BimDialog`
创建一个通用弹窗
**参数**:
- `options`: `Omit<DialogOptions, 'container'>` - 弹窗配置(不需要传 container
**返回**: `BimDialog` 实例
**功能**:
- 自动使用 Manager 绑定的容器
- 创建 `BimDialog` 实例
- 应用当前主题
- 将弹窗添加到活跃列表
-`onClose` 回调中自动从列表移除
**使用示例**:
```typescript
const dialog = engine.dialog.create({
title: '测试弹窗',
content: '这是内容',
width: 400,
height: 300
});
```
#### `showInfoDialog(): void`
显示二次封装的模型信息弹窗
**功能**:
- 创建 `BimInfoDialog` 实例
- 直接显示信息弹窗
**注意**: 此方法创建的弹窗不会自动加入管理列表(遗留逻辑)
#### `updateTheme(theme: ThemeConfig): void`
响应全局主题变更
**参数**:
- `theme`: `ThemeConfig` - 全局主题配置
**功能**:
- 遍历所有活跃弹窗
- 调用每个弹窗的 `setTheme()` 方法
#### `destroy(): void`
销毁管理器
**功能**:
- 销毁所有活跃弹窗
- 清空活跃列表
---
## 5. UI 详细描述
### 5.1 DOM 结构
**完整 HTML 结构**:
```html
<div class="bim-dialog" id="[可选ID]" style="[CSS变量和尺寸]">
<!-- 标题栏 -->
<div class="bim-dialog-header [draggable]">
<span class="bim-dialog-title">标题文本</span>
<span class="bim-dialog-close">&times;</span>
</div>
<!-- 内容区域 -->
<div class="bim-dialog-content">
<!-- 用户内容HTML字符串或DOM元素 -->
</div>
<!-- 缩放手柄(如果 resizable -->
<div class="bim-dialog-resize-handle"></div>
</div>
```
### 5.2 CSS 类名和样式
#### `.bim-dialog` (根元素)
- `position: absolute` - 绝对定位
- `background-color: var(--bim-dialog-bg)` - 背景色CSS 变量)
- `border: 1px solid var(--bim-dialog-border-color)` - 边框
- `border-radius: 6px` - 圆角
- `box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3)` - 阴影
- `display: flex` + `flex-direction: column` - 垂直布局
- `z-index: 10001` - 层级(确保在 3D 引擎之上)
- `min-width: 200px` - 最小宽度
- `min-height: 100px` - 最小高度
- `pointer-events: auto` - 确保可接收事件
#### `.bim-dialog-header` (标题栏)
- `height: 32px` - 固定高度
- `background-color: var(--bim-dialog-header-bg)` - 背景色
- `display: flex` + `align-items: center` + `justify-content: space-between` - 水平布局
- `padding: 0 10px` - 内边距
- `cursor: default` - 默认光标
- `user-select: none` - 禁止选中
- `border-bottom: 1px solid var(--bim-dialog-border-color)` - 底边框
#### `.bim-dialog-header.draggable` (可拖拽标题栏)
- `cursor: move` - 移动光标
#### `.bim-dialog-title` (标题文本)
- `font-size: 14px` - 字体大小
- `font-weight: 500` - 字体粗细
- `white-space: nowrap` - 不换行
- `overflow: hidden` - 隐藏溢出
- `text-overflow: ellipsis` - 文本省略
- `color: var(--bim-dialog-title-color)` - 文字颜色
#### `.bim-dialog-close` (关闭按钮)
- `cursor: pointer` - 指针光标
- `font-size: 18px` - 字体大小
- `color: #999` - 默认颜色
- `line-height: 1` - 行高
- `margin-left: 8px` - 左边距
#### `.bim-dialog-close:hover` (关闭按钮悬停)
- `color: #fff` - 悬停颜色
#### `.bim-dialog-content` (内容区域)
- `flex: 1` - 占据剩余空间
- `padding: 10px` - 内边距
- `overflow: auto` - 内容溢出时滚动
- `font-size: 14px` - 字体大小
- `color: var(--bim-dialog-text-color)` - 文字颜色
#### `.bim-dialog-resize-handle` (缩放手柄)
- `position: absolute` - 绝对定位
- `width: 10px` + `height: 10px` - 尺寸
- `bottom: 0` + `right: 0` - 右下角位置
- `cursor: se-resize` - 缩放光标
- `z-index: 10` - 层级
#### `.bim-dialog-resize-handle::after` (缩放装饰)
- 使用伪元素创建右下角斜线装饰
- `border-right` + `border-bottom` - 创建斜线效果
### 5.3 CSS 变量
**定义位置**: `:root` 或元素内联样式
**变量列表**:
- `--bim-dialog-bg`: 窗体背景颜色(默认 `rgba(17, 17, 17, 0.95)`
- `--bim-dialog-header-bg`: 标题栏背景颜色(默认 `#2a2a2a`
- `--bim-dialog-title-color`: 标题文字颜色(默认 `#fff`
- `--bim-dialog-text-color`: 内容文字颜色(默认 `#ccc`
- `--bim-dialog-border-color`: 边框颜色(默认 `#444`
### 5.4 交互行为
#### 拖拽
- **触发区域**: 标题栏(`.bim-dialog-header`
- **触发条件**: `draggable: true`
- **行为**:
- 鼠标按下标题栏时开始拖拽
- 鼠标移动时弹窗跟随移动
- 鼠标释放时结束拖拽
- 弹窗位置限制在容器边界内
#### 缩放
- **触发区域**: 缩放手柄(`.bim-dialog-resize-handle`
- **触发条件**: `resizable: true`
- **行为**:
- 鼠标按下缩放手柄时开始缩放
- 鼠标移动时弹窗尺寸跟随变化
- 鼠标释放时结束缩放
- 尺寸限制在最小尺寸以上
#### 关闭
- **触发方式**:
- 点击关闭按钮(`.bim-dialog-close`
- 调用 `close()` 方法
- **行为**: 弹窗从 DOM 移除,调用 `onClose` 回调
### 5.5 响应式行为
- 弹窗位置会根据容器尺寸自动调整,确保不超出边界
- 内容区域支持滚动(`overflow: auto`
- 标题文本过长时显示省略号(`text-overflow: ellipsis`
---
## 6. 逻辑流程详细描述
### 6.1 初始化流程
1. **构造函数调用**:
- 合并配置选项(用户配置 + 默认配置)
- 调用 `createDom()` 创建 DOM 结构
- 保存 header 和 contentArea 引用
- 自动调用 `init()`
2. **init() 方法执行**:
- 检查是否已初始化,如果是则返回
- 将弹窗元素添加到容器
- 调用 `initPosition()` 计算并设置位置
- 如果 `draggable` 为 true调用 `initDrag()`
- 如果 `resizable` 为 true调用 `initResize()`
- 标记为已初始化
- 调用 `onOpen` 回调(如果存在)
- 订阅主题变更:`themeManager.subscribe()`
- 订阅语言变更:`localeManager.subscribe()`
### 6.2 生命周期
#### 创建阶段
- 构造函数 → `createDom()``init()`
#### 运行阶段
- 响应主题变更:`setTheme()` 被调用
- 响应语言变更:`setLocales()` 被调用
- 用户交互:拖拽、缩放、关闭
#### 销毁阶段
- `close()``destroy()` 被调用
- 清理 `requestAnimationFrame`
- 取消主题和语言订阅
- 从 DOM 移除元素
- 调用 `onClose` 回调
### 6.3 事件处理流程
#### 拖拽事件流程
1. 用户在标题栏按下鼠标 → `mousedown` 事件
2. 记录起始位置和弹窗当前位置
3. 缓存容器和弹窗尺寸
4. 在 document 上绑定 `mousemove``mouseup`(捕获阶段)
5. 鼠标移动时 → `mousemove` 事件
- 计算偏移量
- 使用 `requestAnimationFrame` 更新位置
- 限制在容器边界内
6. 鼠标释放时 → `mouseup` 事件
- 清理事件监听
- 清理动画帧
#### 缩放事件流程
1. 用户在缩放手柄按下鼠标 → `mousedown` 事件
2. 记录起始位置和弹窗当前尺寸
3. 在 document 上绑定 `mousemove``mouseup`(捕获阶段)
4. 鼠标移动时 → `mousemove` 事件
- 计算偏移量
- 使用 `requestAnimationFrame` 更新尺寸
- 限制在最小尺寸以上
5. 鼠标释放时 → `mouseup` 事件
- 清理事件监听
- 清理动画帧
#### 事件拦截流程
- 弹窗根元素上绑定所有鼠标/触摸事件
- 使用 `stopPropagation()` 阻止事件冒泡
- 防止事件传递给 3D 引擎
- 使用 `passive: false` 允许阻止默认行为
### 6.4 状态管理
#### 内部状态
- `_isInitialized`: 是否已初始化
- `_isDestroyed`: 是否已销毁
- `rafId`: `requestAnimationFrame` 的 ID用于节流
#### 订阅管理
- `unsubscribeTheme`: 主题订阅取消函数
- `unsubscribeLocale`: 语言订阅取消函数
### 6.5 与其他组件的交互
- **与 DialogManager**: 通过 Manager 创建和管理
- **与 ThemeManager**: 订阅主题变更
- **与 LocaleManager**: 订阅语言变更
- **与 3D 引擎**: 通过事件拦截防止交互冲突
---
## 7. 国际化支持
### 7.1 使用的翻译键
- `options.title`: 弹窗标题(如果提供,会通过 `t()` 函数翻译)
### 7.2 语言变更处理
- 组件订阅 `localeManager.subscribe()`
- 语言变更时,`setLocales()` 方法被调用
- 更新标题文本:`titleEl.textContent = t(this.options.title)`
### 7.3 实现细节
```typescript
public setLocales(): void {
if (this.options.title) {
const titleEl = this.header.querySelector('.bim-dialog-title');
if (titleEl) {
titleEl.textContent = t(this.options.title);
}
}
}
```
---
## 8. 主题支持
### 8.1 使用的主题变量
- `theme.panelBackground``--bim-dialog-bg`
- `theme.componentHover``--bim-dialog-header-bg`
- `theme.textPrimary``--bim-dialog-title-color``--bim-dialog-text-color`
- `theme.border``--bim-dialog-border-color`
### 8.2 主题变更处理
- 组件订阅 `themeManager.subscribe()`
- 主题变更时,`setTheme()` 方法被调用
- 如果用户未自定义颜色,使用主题颜色
- 如果用户已自定义颜色,保持用户自定义
### 8.3 实现细节
```typescript
public setTheme(theme: ThemeConfig) {
const style = this.element.style;
if (!this.options.backgroundColor)
style.setProperty('--bim-dialog-bg', theme.panelBackground);
if (!this.options.headerBackgroundColor)
style.setProperty('--bim-dialog-header-bg', theme.componentHover);
// ... 其他颜色映射
}
```
---
## 9. 使用示例
### 9.1 基本使用(通过 Manager
```typescript
import { BimEngine } from 'iflow-engine';
const engine = new BimEngine('container');
// 创建简单弹窗
const dialog = engine.dialog.create({
title: 'dialog.testTitle', // 使用翻译键
content: '这是内容',
width: 400,
height: 300
});
// 创建可缩放弹窗
const resizableDialog = engine.dialog.create({
title: '可缩放弹窗',
content: '<div>内容</div>',
width: 500,
height: 400,
resizable: true,
draggable: true
});
// 创建自定义位置弹窗
const positionedDialog = engine.dialog.create({
title: '自定义位置',
content: '内容',
position: { x: 100, y: 100 },
width: 300,
height: 200
});
```
### 9.2 高级使用
```typescript
// 创建带自定义样式的弹窗
const styledDialog = engine.dialog.create({
title: '自定义样式',
content: '<div>内容</div>',
backgroundColor: 'rgba(100, 0, 0, 0.95)',
headerBackgroundColor: '#cc0000',
titleColor: '#ffffff',
textColor: '#ffcccc',
borderColor: '#ff6666',
width: 300,
height: 200
});
// 创建带回调的弹窗
const callbackDialog = engine.dialog.create({
title: '带回调',
content: '内容',
onOpen: () => {
console.log('弹窗已打开');
},
onClose: () => {
console.log('弹窗已关闭');
}
});
// 动态更新内容
const dynamicDialog = engine.dialog.create({
title: '动态内容',
content: '初始内容'
});
// 稍后更新内容
dynamicDialog.setContent('<div>新内容</div>');
```
### 9.3 使用信息弹窗
```typescript
// 通过 Manager 显示信息弹窗
engine.dialog.showInfoDialog();
// 通过事件总线打开(如果配置了监听)
engine.emit('ui:open-dialog', { id: 'info' });
```
---
## 10. 实现细节(供 AI 重现)
### 10.1 关键算法
#### 位置计算算法
```typescript
// 计算居中位置
function calculateCenterPosition(containerWidth, containerHeight, dialogWidth, dialogHeight) {
return {
left: (containerWidth - dialogWidth) / 2,
top: (containerHeight - dialogHeight) / 2
};
}
// 边界限制算法
function clampPosition(left, top, containerWidth, containerHeight, dialogWidth, dialogHeight) {
return {
left: Math.max(0, Math.min(left, containerWidth - dialogWidth)),
top: Math.max(0, Math.min(top, containerHeight - dialogHeight))
};
}
```
#### 拖拽算法
```typescript
// 拖拽位置更新
function updateDragPosition(startX, startY, currentX, currentY, startLeft, startTop) {
const deltaX = currentX - startX;
const deltaY = currentY - startY;
return {
left: startLeft + deltaX,
top: startTop + deltaY
};
}
```
#### 缩放算法
```typescript
// 缩放尺寸更新
function updateResizeSize(startX, startY, currentX, currentY, startWidth, startHeight, minWidth, minHeight) {
const deltaX = currentX - startX;
const deltaY = currentY - startY;
return {
width: Math.max(minWidth, startWidth + deltaX),
height: Math.max(minHeight, startHeight + deltaY)
};
}
```
### 10.2 性能优化点
1. **requestAnimationFrame 节流**:
- 拖拽和缩放使用 `requestAnimationFrame` 节流更新
- 避免频繁的 DOM 操作
2. **尺寸缓存**:
- 拖拽开始时缓存容器和弹窗尺寸
- 减少 `getBoundingClientRect()` 调用
3. **事件捕获**:
- 使用 `capture: true` 确保事件在捕获阶段处理
- 即使内部元素阻止冒泡,也能捕获事件
4. **CSS 变量**:
- 使用 CSS 变量应用主题
- 主题变更时无需重新渲染 DOM
### 10.3 注意事项和边界情况
1. **容器尺寸为 0**:
- 位置计算时可能出现除零或负数
- 使用 `Math.max()` 确保位置不为负
2. **弹窗尺寸大于容器**:
- 位置计算时确保弹窗不超出容器
- 使用边界限制算法
3. **快速连续操作**:
- 使用 `rafId` 防止多个动画帧同时执行
- 确保动画帧正确清理
4. **事件清理**:
- 组件销毁时必须清理所有事件监听
- 必须取消主题和语言订阅
5. **事件拦截**:
- 必须拦截所有鼠标/触摸事件
- 防止事件传递给 3D 引擎
6. **翻译键处理**:
- 标题可能是翻译键或普通文本
- 只有翻译键才需要通过 `t()` 函数处理
---
## 11. 类型定义
### 11.1 DialogOptions
```typescript
interface DialogOptions extends DialogColors {
container: HTMLElement; // 弹窗挂载的父容器(必需)
title?: string; // 弹窗标题(可选,支持翻译键)
content?: HTMLElement | string; // 弹窗内容(可选)
width?: number | string; // 宽度(可选,默认 300
height?: number | string; // 高度(可选,默认 'auto'
position?: DialogPosition; // 位置(可选,默认 'center'
draggable?: boolean; // 是否可拖拽(可选,默认 true
resizable?: boolean; // 是否可缩放(可选,默认 false
minWidth?: number; // 最小宽度(可选,默认 200
minHeight?: number; // 最小高度(可选,默认 100
onClose?: () => void; // 关闭回调(可选)
onOpen?: () => void; // 打开回调(可选)
id?: string; // 弹窗 ID可选
}
```
### 11.2 DialogPosition
```typescript
type DialogPosition =
| 'center'
| 'top-left' | 'top-center' | 'top-right'
| 'left-center' | 'right-center'
| 'bottom-left' | 'bottom-center' | 'bottom-right'
| { x: number; y: number };
```
### 11.3 DialogColors
```typescript
interface DialogColors {
backgroundColor?: string; // 窗体背景颜色
headerBackgroundColor?: string; // 标题栏背景颜色
titleColor?: string; // 标题文字颜色
textColor?: string; // 内容文字颜色
borderColor?: string; // 边框颜色
}
```
---
## 12. 文件清单
### 12.1 相关文件
- `src/components/dialog/index.ts` - 主组件类
- `src/components/dialog/index.type.ts` - 类型定义
- `src/components/dialog/index.css` - 样式文件
- `src/components/dialog/bimInfoDialog/index.ts` - 信息弹窗(分化组件)
- `src/components/dialog/bimInfoDialog/index.css` - 信息弹窗样式
- `src/managers/dialog-manager.ts` - 管理器类
### 12.2 依赖文件
- `src/types/component.ts` - IBimComponent 接口
- `src/themes/types.ts` - ThemeConfig 类型
- `src/services/theme.ts` - ThemeManager
- `src/services/locale.ts` - LocaleManager
---
## 13. 更新记录
| 日期 | 修改内容 | 修改人 |
|------|---------|--------|
| 2024-XX-XX | 初始创建 | AI Assistant |
---
**重要提醒**: 本文档必须与组件代码保持同步。任何组件修改都必须更新本文档!