Repository navigation
Commit 9c51314
fix(plugin-form): an ObjectForm block's showReset draws the Reset button instead of clearing the form after a save (#27599)
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgP6XkfpjCfyzzG2KwQPUZfy)_
Fixes #27247
Clause-②: yes (widening)
Metadata-protocol: none
## 维护者速读
- **改了什么**:ObjectForm 区块的 `showReset: true`
现在会在表单按钮栏画出「重置」按钮,点了把表单恢复到打开时的值、不保存;保存后不再因为 `showReset` 清空表单。
- **为什么改**:规范把 `showReset` 写作「显示重置按钮」,渲染器却把它当成「保存后清空」:设 `true`
没按钮、每次保存清空表单,设 `false` 没作用。
- **风险与回滚**:依赖旧的「保存后清空」副作用的表单会不再清空(应改用 `submitBehavior: { kind:
'continue' }`);回滚即 revert 本 PR,无数据或协议迁移。
- **先看**:`ui/packages/components/src/renderers/form/form.tsx`(按钮与 reset
事件处理)、`ui/packages/plugin-form/src/ObjectForm.tsx`(去掉 OR 进
`resetOnSubmit`
的那行)、`ui/packages/plugin-form/src/ModalForm.tsx`(表单外的页脚按钮经表单 id 触发重置)。
- **两分钟验证**:`pnpm --dir ui exec vitest run
packages/plugin-form/src/ObjectForm.showReset-27247.test.tsx`,预期 8 条全过。
- **需要你做的**:无,席位落地。
## What changes
The `object-form` block declares `showReset` as "Show the reset button"
(the spec text is unchanged). The renderer OR-ed it into the form's
clear-after-save flag, so `true` drew no button and emptied the form
after every save, and `false` did nothing. The triage ruling: the
renderer honours `showReset` as declared, and `resetOnSubmit` stays its
own key.
- **`@object-ui/components` (`form` renderer).** `showReset` draws a
Reset button in the action bar, between Cancel and Save, labelled
`resetLabel` or the session language's `common.reset` (already in all
ten packs; added to the no-provider fallback). The `form` element
handles its own `reset` event: it restores react-hook-form's opening
values (the defaults the `defaultValues` reset keeps current), clears
the submit error and the rejected-field markers, and calls
`preventDefault` so the browser does not also restore the DOM inputs. So
any `type="reset"` button that names the form's `id` reaches the same
restore.
- **`@object-ui/plugin-form`.**
- `ObjectForm`: the flat path no longer reads `showReset` into
`resetOnSubmit`. The flat and sectioned simple paths hand `showReset`
(off in `view` mode) to the bar.
- `TabbedForm` forwards it to its bar.
- `DrawerForm` and `ModalForm` draw the button in their own footers as
`type="reset" form={formId}`, gated like Save (no button in `view` mode
or on a record closed for edit). A footer with only Reset still shows.
- **`@object-ui/types`.** `FormSchema` (the renderer-internal `form`
node, which `@objectstack/spec` does not declare) gains `showReset?:
boolean` and `resetLabel?: string`, with JSDoc and zod rows. The seat
approved this file-surface addition before any push.
**Not covered (no clean slot).** `WizardForm` and `MasterDetailForm`
have their own action bars. A wizard has one inner form per step plus
merged step data, and a master-detail form has a header form plus line
items, so neither has one form whose opening values a Reset restores.
Both still read no `showReset`, and nothing there changes.
**Declarations, measured.** `Clause-②: yes (widening)`: the two keys
reach the published entry of `@object-ui/types` (`dist/form.d.ts`
declares `showReset?: boolean` and `resetLabel?: string` on the exported
`FormSchema`; `dist/zod/form.zod.d.ts` has both rows).
`Metadata-protocol: none`: what a metadata author writes is unchanged.
The `object-form` block's `showReset` and its text are as before, and
the new keys sit on the `form` node, which is not in the spec's block
vocabulary or the public-tier `sdui.manifest.json`
(`check-sdui-manifest` exit 0, manifest unchanged). Changeset level
`patch` for the three packages.
## Tests
- `ui/packages/plugin-form/src/ObjectForm.showReset-27247.test.tsx` (8):
the flat form's button restores `initialValues` and does not call
`create`; a save with `showReset: true` keeps the typed value (the pin
against the old clear); unset draws no button; `view` mode draws none;
the sectioned form restores the opening values; the tabbed form draws
one button; the modal footer's button names the form's `id` and a click
restores the opening values; the drawer footer draws it with the form's
`id`.
-
`ui/packages/components/src/renderers/form/__tests__/form-reset-button-27247.test.tsx`
(3): no button unless `showReset`; `resetLabel` names it and a click
restores `defaultValues` without `onSubmit`; a reset button outside the
form reaches it through the form `id`.
<details><summary>Ablations (each committed first, mutated through
scripts/ablation-replace.mjs, restored to HEAD with git diff HEAD
empty)</summary>
- Put `schema.showReset ||` back at the head of the flat path's
`resetOnSubmit`: `a save does not clear the form because of showReset`
goes red, 1 failed and 7 passed.
- Delete `onReset={handleReset}` from the `form` element: 5 red
(restores the opening values; outside reset button; flat form; sectioned
form; modal footer), 6 passed.
</details>
<details><summary>Local verification (pre-merge head 42f8831, merged
head 61baeb3)</summary>
- `pnpm --dir ui exec vitest run --maxWorkers=2 packages/plugin-form/
packages/components/src/renderers/form/ packages/types/`: pre-merge 674
files passed, 13326 tests passed, 18 skipped; post-merge 676 files
passed, 13337 tests passed, 18 skipped.
- `type-check` for `@object-ui/types`, `@object-ui/components`,
`@object-ui/plugin-form`: exit 0 on both heads.
- `dispatch-gates --commands` (34 families) run on the merged head and
reconciled with `--ran`: 34 derived, 34 run, every one exit 0, 0
NOT-MEASURED, 0 UNRUN.
</details>
## Acceptance notes
- `content/docs/ui/components/plugins.mdx` lists `showReset` with no
description. That page is generated from `sdui.manifest.json`, from the
`object-form` registration inputs in `plugin-form/src/index.tsx`. Adding
a description there means regenerating the manifest and the page, which
is outside this card's file surface, so it is left as is. The ui README
and `content/docs/**` have no sentence that describes the old effect.
- `skills/objectstack-ui/references/react-blocks.md` says "Show the
reset button." for `showReset`. That is now true, so no skills line is
wrong.
- Found while measuring, for the seat to file: on the sectioned simple
path, `ObjectForm` builds its `form` node without `resetOnSubmit`. So
`submitBehavior: { kind: 'continue' }` (and `resetOnSuccess` on a create
form) does not clear a sectioned form after a save, while the flat form
does. A probe test reproduced this: the flat form cleared, the sectioned
form kept `Alpha`.
- The merge commit from `origin/main` carries no trailer pair (git's
default merge message; the pre-push hook accepted it).
## Verification
Open an `object-form` block with `showReset: true` in create mode, type
in a field, and press Reset. The field goes back to its opening value
and nothing is saved. Save, and the form keeps the saved values.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CXYxRw2JZU7Ybu98id)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e270dab commit 9c51314
10 files changed
Lines changed: 353 additions & 4 deletions
File tree
- .changeset
- ui/packages
- components/src/renderers/form
- __tests__
- plugin-form/src
- types/src
- zod
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
439 | 439 | | |
440 | 440 | | |
441 | 441 | | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
442 | 445 | | |
443 | 446 | | |
444 | 447 | | |
| |||
1617 | 1620 | | |
1618 | 1621 | | |
1619 | 1622 | | |
| 1623 | + | |
1620 | 1624 | | |
| 1625 | + | |
1621 | 1626 | | |
1622 | 1627 | | |
1623 | 1628 | | |
| |||
3189 | 3194 | | |
3190 | 3195 | | |
3191 | 3196 | | |
| 3197 | + | |
| 3198 | + | |
| 3199 | + | |
| 3200 | + | |
| 3201 | + | |
| 3202 | + | |
| 3203 | + | |
| 3204 | + | |
| 3205 | + | |
| 3206 | + | |
| 3207 | + | |
| 3208 | + | |
| 3209 | + | |
| 3210 | + | |
3192 | 3211 | | |
3193 | 3212 | | |
3194 | 3213 | | |
| |||
3941 | 3960 | | |
3942 | 3961 | | |
3943 | 3962 | | |
| 3963 | + | |
3944 | 3964 | | |
3945 | 3965 | | |
| 3966 | + | |
3946 | 3967 | | |
3947 | 3968 | | |
3948 | 3969 | | |
| |||
3993 | 4014 | | |
3994 | 4015 | | |
3995 | 4016 | | |
| 4017 | + | |
3996 | 4018 | | |
3997 | 4019 | | |
3998 | 4020 | | |
| |||
4176 | 4198 | | |
4177 | 4199 | | |
4178 | 4200 | | |
| 4201 | + | |
| 4202 | + | |
| 4203 | + | |
| 4204 | + | |
| 4205 | + | |
| 4206 | + | |
| 4207 | + | |
| 4208 | + | |
| 4209 | + | |
| 4210 | + | |
4179 | 4211 | | |
4180 | 4212 | | |
4181 | 4213 | | |
| |||
4209 | 4241 | | |
4210 | 4242 | | |
4211 | 4243 | | |
| 4244 | + | |
| 4245 | + | |
4212 | 4246 | | |
4213 | 4247 | | |
4214 | 4248 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
98 | 98 | | |
99 | 99 | | |
100 | 100 | | |
| 101 | + | |
| 102 | + | |
101 | 103 | | |
102 | 104 | | |
103 | 105 | | |
| |||
185 | 187 | | |
186 | 188 | | |
187 | 189 | | |
| 190 | + | |
| 191 | + | |
188 | 192 | | |
189 | 193 | | |
190 | 194 | | |
| |||
739 | 743 | | |
740 | 744 | | |
741 | 745 | | |
| 746 | + | |
742 | 747 | | |
743 | 748 | | |
744 | 749 | | |
| |||
1014 | 1019 | | |
1015 | 1020 | | |
1016 | 1021 | | |
1017 | | - | |
| 1022 | + | |
1018 | 1023 | | |
1019 | 1024 | | |
1020 | 1025 | | |
| |||
1030 | 1035 | | |
1031 | 1036 | | |
1032 | 1037 | | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
1033 | 1052 | | |
1034 | 1053 | | |
1035 | 1054 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
| 109 | + | |
| 110 | + | |
109 | 111 | | |
110 | 112 | | |
111 | 113 | | |
| |||
222 | 224 | | |
223 | 225 | | |
224 | 226 | | |
| 227 | + | |
| 228 | + | |
225 | 229 | | |
226 | 230 | | |
227 | 231 | | |
| |||
867 | 871 | | |
868 | 872 | | |
869 | 873 | | |
| 874 | + | |
870 | 875 | | |
871 | 876 | | |
872 | 877 | | |
| |||
1219 | 1224 | | |
1220 | 1225 | | |
1221 | 1226 | | |
1222 | | - | |
| 1227 | + | |
1223 | 1228 | | |
1224 | 1229 | | |
1225 | 1230 | | |
| |||
1282 | 1287 | | |
1283 | 1288 | | |
1284 | 1289 | | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
1285 | 1304 | | |
1286 | 1305 | | |
1287 | 1306 | | |
| |||
0 commit comments