fix(components): action:group / action:menu stop reading a member's properties.params (objectui#11638) - #11655
Conversation
…roperties.params The spec refuses a `properties` bag on an `action:group` / `action:menu` member: its static parameter values are not part of the inline action vocabulary, and an action that needs them is its own `action:button` node. Fork 5's census found no writer. `readMemberStaticParamValues` is retired with its two calls; each container now forwards an array `params` as `actionParams` alone and an object `params` through `readActionEntryParamValues` (the `api` window of objectstack#5777 kept). `withEvaluatedProperties` stays: `action:bar` still evaluates an inline member's `properties` for `action:button` / `action:icon`. Docblocks that taught `properties.params` as a member's home now cite the spec's member prescription, including the `action:bar` overflow note and the `useConfigBagEvaluator` docblock, which this change made false. Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL Co-authored-by: Claude <noreply@anthropic.com>
…ms; changeset The objectui#10290 pins split by the reader a member reaches. The NODE path (an `action:bar` member mounted inline on `action:button` / `action:icon`) keeps its "resolved" pins. The MEMBER path (`action:group` inline and dropdown, `action:menu`, and an `action:bar` member in the overflow menu) has the "resolved" pin inverted: `properties.params` does not reach the runner. Beside it, objectui#11638 pins that an array `params` reaches the runner as `actionParams` alone, and that an `api` member's object `params` is its payload even beside a `properties.params`. Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL Co-authored-by: Claude <noreply@anthropic.com>
…perties-params Claude-Session: https://claude.ai/code/session_015W8GBu6sBiqus2L2xjMsAL Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
ACCEPT: PR objectui#11655, head
|
Fixes #11638
Clause-②: no
What changes
action:groupandaction:menustop reading a member'sproperties.params.readMemberStaticParamValues(instatic-params.ts) is retired, together with its two calls in thehandleExecuteofaction-group.tsxandaction-menu.tsx. Each container now forwards:paramsasactionParamsalone, with no staticparamsbeside it;paramsthroughreadActionEntryParamValues, which is unchanged: atype: 'api'member's objectparamsis its request payload (theInlineActionSchema.params声明为参数定义数组,但type:'api'的活消费者(与 showcase 页)用的是静态载荷 map —— 一个键两种形状 objectstack#5777 window), and on any other type an objectparamsis dropped with its existing development warning (objectui#10462).The
useConfigBagEvaluator()call each of the two containers made existed only for that read, so it is removed with it.withEvaluatedPropertiesstays, becauseaction:barstill evaluates an inline member'spropertiesfor theaction:button/action:iconnode it mounts the member on.readStaticParamValues(the node path) andreadActionEntryParamValuesare not touched.No export, prop, type member or i18n key changes.
@object-ui/componentspublishes.(plus./style.css), and its entry does not re-exportstatic-params.Why
Triage's re-scoped grade on this card (comment
5991243780): retirereadMemberStaticParamValues'sproperties.paramsread, add no new reading of a member'sparamsobject, and keep two pins: a member's arrayparamsstill reaches the runner asactionParams, and anaction:button'sparamsobject is unchanged. The governing texts behind it:paramsnever carries two shapes, and ⛔ no new value-bag key is declared";propertiesentry ofactionContainerMemberGuidanceinpackages/spec/src/ui/component.zod.ts, objectstackmain): "A member carries nopropertiesbag: its static parameter values (properties.params) are not part of the inline action vocabulary. For atype: 'api'member's request body writebodyExtra; to run an action with static parameter values, author it as its ownaction:buttonnode, whoseparamsobject carries them."Behaviour, before and after (measured by the pins below)
action:group/action:menu/action:baroverflowproperties.paramsonlyparamsparamsundefined)paramsplusproperties.paramsactionParamsplus the evaluated staticparamsactionParamsalone;paramsis only what the user answerstype: 'api', objectparamsplusproperties.paramsproperties.paramsreplaced the payloadparamsis the payloadapi, objectparamsaction:button/action:iconnode withproperties.paramsaction:barmember drawn inline (mounted onaction:button/action:icon)Docblocks
Rewritten to cite the spec's member prescription: the
static-params.tsmodule header, thewithEvaluatedPropertiesdocblock (nowaction:baronly), the parenthetical in thereadActionEntryParamValuesdocblock, and thehandleExecutecomments in both containers.Two comments outside the claim's declared file surface said something this change makes false, so they are corrected in the same change (comment-only, no code):
action-bar.tsx'srenderMembercomment said theaction:menuevaluates an overflow member'sproperties. It now says the menu reads no member'sproperties, so an overflow member'sproperties.paramsdoes not reach the runner;useConfigBagEvaluatordocblock inpackages/react/src/hooks/useConfigBagEvaluator.tsnamedaction:group/action:menuas users of the hook. It now namesaction:barand says the other two read no memberproperties.Writers
Re-measured in this tree at
75c81aa. No file outside tests authorspropertieson anaction:group/action:menumember:examples/**,**/*.stories.*,content/docs/**andapps/**(tests excluded): two files nameaction:grouporaction:menu,content/docs/guide/slotted-pages.mdandcontent/docs/layout/page-header.mdx, and neither authors a memberpropertiesbag. Control on the same pathspec: 19 files nameaction:button.properties.paramsmention outside the action renderers (content/docs/guide/record-edit-modes.md,packages/app-shell/README.md,AppContent.tsx,recordFormNavigation.ts) teaches it on anaction:buttonnode, which the prescription keeps. None is changed.action:bar/action:menumember lists (ObjectView.tsx,InterfaceListPage.tsx,EnvironmentListToolbar.tsx,DetailView.tsx,RecordDetailPanel.tsx,RecordDetailView.tsx,useNavRunAction.ts) put nopropertieson a member.The only authored member
properties.paramswas in this package's own objectui#10290 test, re-judged below. No live reproduction is owed, because the key had no writer; the unit pins below carry the proof.Tests
packages/components/src/renderers/action/__tests__/action-container-member-params-10290.test.tsx, driven through the realSchemaRenderer, the real containers and the realActionRunneron a record page:action:button'sproperties.paramsresolves${record.id}); "the handler receivesproperties.paramswith${record.id}resolved" on the threeaction:barinline paths (inline,component: action:icon,component: action:group), which are the node path; and "a node-levelparamsOBJECT is still not a values channel, and says so once" on all eight paths. The parentdescribeis renamed from "a container member's" to "anaction:barmember's", because the old title is no longer true.properties.paramswith${record.id}resolved" on the five member paths (action:barwithcomponent: action:menu,action:barspilled pastmaxVisible,action:groupinline,action:groupdropdown,action:menu) is now "a member'sproperties.paramsis not forwarded as static values".paramsreaches the runner asactionParamsalone, beside aproperties.params" and "anapimember's objectparamsis its payload, and aproperties.paramsbeside it no longer replaces it".action-entry-object-params-10462.test.tsx(array leg asactionParams,apiobject as payload, non-apiobject dropped), and theaction:buttonproperties.paramspins inaction-params-properties-10289.test.tsx,action-params-templates-7867.test.tsx,action-forward-precedence.test.tsxandaction-bodyShape-forward.test.tsx.Reverse validation. With the fix committed (
7d6838d), the three source files were restored to the basef1a177cbygit checkoutand the test file was run. On disk,readMemberStaticParamValueswas counted 0, then 2, 2 and 1 after the restore, and the blob hashes matched the base. Result:Tests 15 failed | 12 passed (27). All 15 failures were assertion failures (for example, "expected { objectName: 'account', … } to be undefined"), and the 12 node-path and control pins stayed green. Restore: the blob hashes equalHEADandgit diff HEADis empty.Gates at
75c81aa(after mergingorigin/mainat4367146), each exit code read from its own file:pnpm exec vitest run packages/components/: exit 0,Test Files 360 passed | 1 skipped (361),Tests 3674 passed | 24 skipped (3698)pnpm exec vitest run packages/react/: exit 0,Test Files 108 passed (108),Tests 1400 passed (1400)pnpm --filter @object-ui/components type-checkandpnpm --filter @object-ui/react type-check: exit 0, afterpnpm --filter '@object-ui/components^...' build(exit 0).tsconfig.test.jsonlists the edited test file.pnpm --filter @object-ui/components lint/pnpm --filter @object-ui/react lint: exit 0, 0 errors.pnpm check:action-forward-parity(exit 0, "5 surfaces checked against 42 runtime-read keys from 4 consumers"),check:unreferenced-sources,check:handler-key-reads,check:new-line-citations("0 new citation(s)"),check:control-bytes,check:test-path-roots,check:vi-mock-override-shape,check:changeset-claims,check:pending-changeset-literals,check:icon-record-names,check:phantom-deps: each exit 0.node scripts/check-changeset-presence.mjs,check-changeset-no-major.mjs,check-changeset-fixed.mjs,check-changeset-overwrite.mjs: each exit 0.CI runs the full farm. This change was not measured locally beyond the list above.
Changeset
.changeset/11638-member-properties-params-retired.md,@object-ui/components: minor. It is a behaviour change, so it is gradedminorper this repository's version policy, and the changeset states the change with a FROM/TO.Acceptance notes
action:barinline and overflow now differ for a member that carriesproperties.params. An inlineaction:barmember is mounted onaction:button/action:icon, whose node reader still reads the bar-evaluatedproperties.params. The same member in the overflow menu reachesaction:menu, which reads no memberproperties. So for such a member, themaxVisiblesplit decides whether static values arrive. No producer was found:action:baris not one of the spec's fouraction:*component rows, and its hosts compose members from registered actions, whose spec schema is strict and declares noproperties. The ruling names only the member read, so the bar's inline evaluation (withEvaluatedPropertiesinrenderMember) is left in place. Whether it should also be retired is the seat's call. Pinned both ways in the test file above.action-bar.tsx,packages/react/src/hooks/useConfigBagEvaluator.ts). Both are comments this change made false; no code outside the claimed files changed.Generated by Claude Code