Files
workspace/table-two-state-keyboard-2025.changeset.md
T
2026-10-16 17:30:17 +08:00

43 lines
4.7 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.
---
'@g3soft/ui': minor
---
G3Table 行内编辑改为**两态模型**(选中态 / 编辑态),键盘交互按 ERP 表格规格重做。
**两种状态**
| 状态 | 长什么样 | 怎么进入 |
| --- | --- | --- |
| 选中态 | 单元格有选中框,**格子里没有 input** | 单击、方向键 / `Tab` 移动 |
| 编辑态 | 格子里有 `input` / `textarea` | 双击、`Enter`、`F2`、直接打字、`editRow()` |
**行为变更(会影响既有交互)**
- **单击只选中,不再直接进入编辑**(改为双击)。这是本次最显眼的变化 —— 依赖"点一格就能打字"的页面需要改用双击,或保留单击后按 `Enter` / 直接打字。
- 新增**选中态键位**:`Enter` 进编辑并全选、`F2` 进编辑且光标在末尾、可打印字符进编辑并**覆盖原值**、方向键只移动选中框。
- **左右键改为"input 先消费、到边界才放行"**:光标在文本中间时归输入框移光标(有选区时同样归输入框),光标已贴在该方向边界或值为空时才交给表格切格。此前左右键一律归输入框,导致编辑态里无法用 `→` 逐格往右走。横向到行边界即停,不跨行(跨行用 `Tab` / `Enter`)。
- `↑` `↓`(单行)由"不拦、放行给底座"改为由组件显式提交并移动;`Shift+↑↓` 与 `textarea` 的上下仍归输入框。
- `F2`(编辑态)光标移到末尾。
**新增事件**
- `edit-start`(编辑器已挂载、已聚焦、光标已就位)、`edit-end`(值已提交并离开该格)、`edit-cancel`(`Esc`,值已还原)、`value-change`(值实际变化)。
- `value-change` 与既有的 `change` **同时抛出、语义相同**:改名会让已上线的 `@change` 绑定静默失效(Vue 对未声明的监听不报错),因此保留旧名。
- `Esc` 取消编辑现在对**所有**编辑器有效。`select` / `date` 是"立即写回并已抛过 `change`"的,取消会把该格改回进入时的值**并再抛一次 `change`**,父级据此回退(此前 `Esc` 只对文本框有效,在下拉 / 日历格里按 `Esc` 值已经改了却退不回去)。只回滚当前这一格,不牵连同一行里先前改过的其它格。
**缺陷修复**
- **输入法(IME)**:组合态(`event.isComposing` 或 `keyCode === 229`)下不再拦截任何键。修前在候选框上按 `Enter` 确认候选词会被当成"确认并下移"——候选词上不了屏、光标还跳到下一行;候选框里 `↑↓` 选字也会被当成切行。
- **`Esc` 在下拉 / 日历格里退不出编辑**:`select` / `date` 的值是立即写回行数据的,而 `Esc` 的取消分支只挂在文本框编辑器上,于是这两类格子按 `Esc` 既不还原也不退出编辑。现在统一接上,并做成**两段式**(第一记 `Esc` 关下拉 / 关日历,第二记才取消整格编辑)。
- **`Esc` 的"还原"对 `select` / `date` 会还原成刚改的值**:去重用的快照(`initialValues`)与"进入编辑时的值"此前共用一份 Map,而 `shouldNotify` 每次真正变化都会把它推进到新值——对文本框无碍(提交前不通知),对立即写回的 `select` / `date` 则等于把"原值"换成了新值,回滚于是无效。现在两格概念分开存:去重一份(可推进)、进入值一份(只写一次)。
- **跨行移动不提交、不抛 `change`**:编辑器只挂在当前编辑行,跨行移动时旧编辑器被**卸载**,而 DOM 元素被移除时浏览器**不派发 blur**,`onBlur` 那条提交路径整个不执行,值只剩兜底写入(写 raw、不响应式、不抛事件)。表现为"同一行内跳格会保存、跨行跳格静默丢失通知"。现在 `Tab` / 方向键 / `Enter` 移动前都显式提交一次。
- **`Esc` 之后方向键 / 打字失灵**:原先把焦点还给 `td[data-cs-s]`,但库渲染表体 `td` 时**没有** `tabindex`(唯一带 `tabindex="-1"` 的是它内层的 `.table-cell-wrapper`),对 `td` 调 `focus()` 是静默无效的,焦点实际留在 `body`。改为把焦点交给内层容器 `.stk-table`(库给了它 `tabindex="0"`,底座的键盘导航也挂在那里)。
- `edit-start` / `edit-end` 对同一次编辑会话各只抛一次(重渲染、显式提交后又补 `blur` 等重复路径不会重复抛)。
**其它**
- 内部:`startEdit` 成为进入编辑态的**唯一入口**(规格 §六),插入符落点由触发源通过 `caret` 显式传达;`activateEditing` / `moveToCellBelow` 相应改名与泛化(`moveToAdjacent` 支持四向)。
- 文档(`docs/content/ui/data/table.md`)与 `editable` 示例已同步到两态模型。
- 单测从 162 增至 192:新增左右键边界判据、IME 组合态、四向移动、草稿显式提交等用例。