feat(app-shell): render ActionParamDialog params through the shared form field-widget renderer (#2700, ADR-0059)#2704
Merged
Conversation
…orm field-widget renderer (#2700, ADR-0059) Retire the bespoke per-type branch chain in ActionParamDialog. Every declared action param now renders through the same fieldWidgetMap the object form uses, so a param of ANY form-supported field type (file, image, richtext, color, address, code, date, ...) gets its real widget — lazily, behind Suspense — instead of collapsing to a text input. Subsumes the single `file` branch ask in #2698 (upload via the ambient UploadProvider, multiple/accept/maxSize honored). - fields: export resolveFormWidgetType() + getLazyFieldWidget() (per-type cached React.lazy over the form's own widget loaders). - core: ActionParamDef gains accept/maxSize; multiple is general widget config (was lookup-only). - app-shell: pure paramToField() adapter (param -> field shape, with explicit param-only fallbacks: legacy aliases, lookup-without-referenceTo -> text); resolveActionParams() inherits multiple/accept/maxSize from the referenced field for every type; required validation, visible CEL gating, helpText, error styling, and value shapes for previously-supported types unchanged. - tests: dialog behavior net across text/textarea/number/boolean/select/date/ file/color/unknown + required blocking + defaultValue round-trip; drift test pinning param support ⊇ FORM_FIELD_TYPES (mirrors the FieldEditWidget parity guard). - docs: ADR-0059, enhanced-actions "Action Params" section, app-shell/fields READMEs, objectui skill protocol rule; changeset (minor). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rg7oavKSUdb2KzYEEYrCHX
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
July 19, 2026 18:04
This was referenced Jul 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2700. Subsumes the single
filebranch ask in #2698.What
ActionParamDialogno longer hand-rolls a per-type ternary chain (select/lookup/textarea/number/ boolean, everything else → textInput). Every declared action param now renders through the samefieldWidgetMapthe object form uses, so a param of ANY form-supported field type —file,image,richtext,markdown,color,address,code,date, … — gets its real widget, lazily loaded behind<Suspense>, and the param surface can never silently drift behind the form surface again.@object-ui/fields— new exportsresolveFormWidgetType(type)(widget-key resolution incl. spec aliases liketoggle/json/secret; unknown →text, mirroring the form) andgetLazyFieldWidget(type)(per-type-cachedReact.lazyover the form's own widget loaders — zero eager bundle weight).@object-ui/core—ActionParamDefgainsaccept/maxSize;multiplepromoted to general widget config (was lookup-only).@object-ui/app-shell— pureparamToField()adapter (param →FieldWidgetProps.fieldshape), with explicit param-only fallbacks: legacy alias spellings (checkbox/reference/datetime-local/autonumber) andlookup-without-referenceTo→ text input with the "paste an ID" hints.resolveActionParams()now inheritsmultiple/accept/maxSizefrom the referenced field for every type.requiredvalidation (isMissingValue),visibleCEL gating, helpText/error chrome, i18n option-label localization, boolean inline-checkbox row UX, and value shapes for previously-supported types (select→ string,number→ number,date→YYYY-MM-DD, …) are unchanged.UploadProvider; lookup/user pickers use the surroundingSchemaRendererContext, exactly as the previousLookupFieldreuse did.Tests
paramToField.test.ts): every type inFORM_FIELD_TYPESresolves to its own widget — param support ⊇ form support, mirroring theFieldEditWidgetparity test.ActionParamDialog.test.tsx): text/textarea/number/boolean/select/date/file/color/unknown-type rendering, value round-trip throughresolve,required-empty blocking with error text,defaultValueseeding.resolveActionParams.test.ts): widget-config inheritance (inline, field-backed, override, missing-field fallback).app-shell+fields+coresuites: 284 files / 3111 tests green. Console + affected packagestype-checkgreen. Changed files lint clean (@object-ui/corepackage lint fails at baseline on files untouched here — verified via stash).Docs / skills
docs/adr/0059-action-params-shared-field-widgets.md) — decision, param-only fallbacks, drift guard, value-shape contract.content/docs/core/enhanced-actions.mdx— new "Action Params (input collection)" section.packages/app-shell/README.md+packages/fields/README.md— component / export docs.skills/objectui/rules/protocol.md— new rule: action params use specFieldTypes + the shared widget renderer; no bespoke dialog branches.@object-ui/fields/@object-ui/core/@object-ui/app-shellminor.Companion PR
@objectstack/specwidening (ActionParamSchema+multiple/accept/maxSize): objectstack-ai/framework — same branch name, see the companion PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01Rg7oavKSUdb2KzYEEYrCHX
Generated by Claude Code