Repository navigation
fix(plugin-form): an ObjectForm block's showReset draws the Reset button instead of clearing the form after a save - #27599
Conversation
…g the form after a save WIP: renderer, variants and tests; changeset follows. Claude-Session: https://claude.ai/code/session_01Utp6CXYxRw2JZU7Ybu98id Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CXYxRw2JZU7Ybu98id Co-authored-by: Claude <noreply@anthropic.com>
…e-reset pin Claude-Session: https://claude.ai/code/session_01Utp6CXYxRw2JZU7Ybu98id Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CXYxRw2JZU7Ybu98id Co-authored-by: Claude <noreply@anthropic.com>
|
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC Contract reviewServed-tier: Face: the ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC 席位核对ACCEPT · head
Generated by Claude Code |
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
Requested by Bill · project thread
Fixes #27247
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
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-formblock declaresshowResetas "Show the reset button" (the spec text is unchanged). The renderer OR-ed it into the form's clear-after-save flag, sotruedrew no button and emptied the form after every save, andfalsedid nothing. The triage ruling: the renderer honoursshowResetas declared, andresetOnSubmitstays its own key.@object-ui/components(formrenderer).showResetdraws a Reset button in the action bar, between Cancel and Save, labelledresetLabelor the session language'scommon.reset(already in all ten packs; added to the no-provider fallback). Theformelement handles its ownresetevent: it restores react-hook-form's opening values (the defaults thedefaultValuesreset keeps current), clears the submit error and the rejected-field markers, and callspreventDefaultso the browser does not also restore the DOM inputs. So anytype="reset"button that names the form'sidreaches the same restore.@object-ui/plugin-form.ObjectForm: the flat path no longer readsshowResetintoresetOnSubmit. The flat and sectioned simple paths handshowReset(off inviewmode) to the bar.TabbedFormforwards it to its bar.DrawerFormandModalFormdraw the button in their own footers astype="reset" form={formId}, gated like Save (no button inviewmode or on a record closed for edit). A footer with only Reset still shows.@object-ui/types.FormSchema(the renderer-internalformnode, which@objectstack/specdoes not declare) gainsshowReset?: booleanandresetLabel?: string, with JSDoc and zod rows. The seat approved this file-surface addition before any push.Not covered (no clean slot).
WizardFormandMasterDetailFormhave 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 noshowReset, and nothing there changes.Declarations, measured.
Clause-②: yes (widening): the two keys reach the published entry of@object-ui/types(dist/form.d.tsdeclaresshowReset?: booleanandresetLabel?: stringon the exportedFormSchema;dist/zod/form.zod.d.tshas both rows).Metadata-protocol: none: what a metadata author writes is unchanged. Theobject-formblock'sshowResetand its text are as before, and the new keys sit on theformnode, which is not in the spec's block vocabulary or the public-tiersdui.manifest.json(check-sdui-manifestexit 0, manifest unchanged). Changeset levelpatchfor the three packages.Tests
ui/packages/plugin-form/src/ObjectForm.showReset-27247.test.tsx(8): the flat form's button restoresinitialValuesand does not callcreate; a save withshowReset: truekeeps the typed value (the pin against the old clear); unset draws no button;viewmode draws none; the sectioned form restores the opening values; the tabbed form draws one button; the modal footer's button names the form'sidand a click restores the opening values; the drawer footer draws it with the form'sid.ui/packages/components/src/renderers/form/__tests__/form-reset-button-27247.test.tsx(3): no button unlessshowReset;resetLabelnames it and a click restoresdefaultValueswithoutonSubmit; a reset button outside the form reaches it through the formid.Ablations (each committed first, mutated through scripts/ablation-replace.mjs, restored to HEAD with git diff HEAD empty)
schema.showReset ||back at the head of the flat path'sresetOnSubmit:a save does not clear the form because of showResetgoes red, 1 failed and 7 passed.onReset={handleReset}from theformelement: 5 red (restores the opening values; outside reset button; flat form; sectioned form; modal footer), 6 passed.Local verification (pre-merge head 42f8831, merged head 61baeb3)
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-checkfor@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.Acceptance notes
content/docs/ui/components/plugins.mdxlistsshowResetwith no description. That page is generated fromsdui.manifest.json, from theobject-formregistration inputs inplugin-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 andcontent/docs/**have no sentence that describes the old effect.skills/objectstack-ui/references/react-blocks.mdsays "Show the reset button." forshowReset. That is now true, so no skills line is wrong.ObjectFormbuilds itsformnode withoutresetOnSubmit. SosubmitBehavior: { kind: 'continue' }(andresetOnSuccesson 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 keptAlpha.origin/maincarries no trailer pair (git's default merge message; the pre-push hook accepted it).Verification
Open an
object-formblock withshowReset: truein 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