- Move delete-btn to top-right of smart-field-wrapper via absolute positioning - Add template-editor-mode class to TemplateManage editor for CSS isolation - Show delete-btn only on hover/focus-within inside template-editor-mode - Add .field-value:focus highlight with background darken and blue glow - Sync defaultContent.ts smartField() HTML structure - Fix ReportEditor multi_select .map crash with Array.isArray guard
112 lines
3.4 KiB
Markdown
112 lines
3.4 KiB
Markdown
# 实现方案 — 字段聚焦高亮、删除按钮显隐控制与 .map Bug 修复(2026-04-17-11-14-28)
|
||
|
||
## 一、修改文件清单
|
||
|
||
1. `src/pages/TemplateManage.tsx` — 调整 `insertSmartField` HTML 结构;给编辑器增加 `template-editor-mode` class
|
||
2. `src/utils/defaultContent.ts` — 同步调整 `smartField()` HTML 结构
|
||
3. `src/index.css` — 聚焦高亮样式 + 删除按钮绝对定位 + 显隐控制
|
||
4. `src/pages/ReportEditor.tsx` — 修复 `multi_select` 的 `.map` 类型安全
|
||
|
||
## 二、详细改动
|
||
|
||
### 2.1 `src/pages/TemplateManage.tsx`
|
||
|
||
#### A. `insertSmartField` HTML 结构调整
|
||
将 `delete-btn` 放到 `.field-value` **之后**,并给 `.smart-field-wrapper` 增加 `position:relative`:
|
||
```html
|
||
<span class="smart-field-wrapper" contenteditable="false" style="white-space:nowrap;position:relative;">
|
||
<span class="field-value" data-bind="..." contenteditable="true" style="..."> </span>
|
||
<span class="delete-btn" contenteditable="false">×</span>
|
||
</span>
|
||
```
|
||
|
||
#### B. 编辑器容器增加专属 class
|
||
在渲染编辑器的 `<div ref={editorRef} ...>` 上增加 `template-editor-mode`:
|
||
```tsx
|
||
<div
|
||
ref={editorRef}
|
||
contentEditable
|
||
className="editor-content print-content template-editor-mode"
|
||
>
|
||
</div>
|
||
```
|
||
|
||
### 2.2 `src/utils/defaultContent.ts`
|
||
|
||
同步修改 `smartField(key)` 的 HTML 结构,与 `insertSmartField` 完全一致。
|
||
|
||
### 2.3 `src/index.css`
|
||
|
||
#### A. field-value 聚焦高亮
|
||
```css
|
||
.smart-field-wrapper .field-value:focus {
|
||
background-color: #e2e8f0;
|
||
border-color: #94a3b8;
|
||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.25);
|
||
transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
||
}
|
||
```
|
||
|
||
#### B. 删除按钮样式(默认隐藏)
|
||
```css
|
||
.smart-field-wrapper .delete-btn {
|
||
position: absolute;
|
||
top: -8px;
|
||
right: -8px;
|
||
width: 16px;
|
||
height: 16px;
|
||
background: #ef4444;
|
||
color: white;
|
||
border-radius: 50%;
|
||
font-size: 10px;
|
||
line-height: 16px;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
display: none;
|
||
z-index: 10;
|
||
}
|
||
.smart-field-wrapper .delete-btn:hover {
|
||
background: #dc2626;
|
||
}
|
||
```
|
||
|
||
#### C. 显隐控制(仅在 TemplateManage 显示)
|
||
```css
|
||
.template-editor-mode .smart-field-wrapper:hover .delete-btn,
|
||
.template-editor-mode .smart-field-wrapper:focus-within .delete-btn {
|
||
display: block;
|
||
}
|
||
```
|
||
|
||
#### D. 打印隐藏
|
||
保留已有的 `.print-content .smart-field-wrapper .delete-btn { display: none !important; }`。
|
||
|
||
### 2.4 `src/pages/ReportEditor.tsx`
|
||
|
||
修复 `multi_select` 渲染处的 `.map` 调用:
|
||
|
||
```tsx
|
||
if (field.type === 'multi_select') {
|
||
const isOpen = openDropdown === field.key;
|
||
const opts = field.options || multiSelectOptions[field.key] || [];
|
||
const rawValue = (reportData as any)[field.key];
|
||
const tags = Array.isArray(rawValue) ? rawValue : (rawValue ? [String(rawValue)] : []);
|
||
return (
|
||
...
|
||
{tags.map((tag: string) => (
|
||
<span key={tag} ...>
|
||
...
|
||
</span>
|
||
))}
|
||
...
|
||
);
|
||
}
|
||
```
|
||
|
||
## 三、风险与回滚
|
||
|
||
- **风险**:修改 `smartField` HTML 结构和 CSS 后,旧报告中已存在的智能字段没有删除按钮。这是预期行为(旧数据不回溯)。
|
||
- **风险**:`delete-btn` 的 `display: none` 默认隐藏 + `.template-editor-mode` 控制显示,ReportEditor 中由于容器没有 `template-editor-mode` class,删除按钮不会显示。
|
||
- **回滚**:如出现问题,可回退上述 4 个文件的修改。
|