Surfaced while implementing objectui#6132 (PR #6345). Not fixed there: that card ruled a docs question, and this is a code-side contract question whose fix lands in packages/.
What was measured
objectui#6132's ruling redirects three menu reference pages at MenuItem.onClick, on the grounds that it is a real declared slot. It is — I verified it in three places before doing the redirect:
- source
packages/types/src/overlay.ts:346 — onClick?: () => void;
- built
packages/types/dist/overlay.d.ts:334 — the exact line objectui#6132 cited
- Zod mirror
packages/types/src/zod/overlay.zod.ts:136 — onClick: z.function().optional().describe('Click handler')
But no renderer reads it. The renderers read a different, undeclared key on the same item:
// packages/components/src/renderers/overlay/dropdown-menu.tsx:67
<DropdownMenuItem key={i} disabled={item.disabled} inset={item.inset} onSelect={item.onSelect}>
// packages/components/src/renderers/overlay/context-menu.tsx:65
<ContextMenuItem key={i} disabled={item.disabled} inset={item.inset} onSelect={item.onSelect}>
packages/components/src/renderers/overlay/menubar.tsx wires no item handler at all — neither spelling.
Neither onSelect nor inset is declared on MenuItem. The helper is typed renderMenuItems(items: any[]), which is why the mismatch type-checks.
Confirming the negative:
$ grep -rn "onClick" packages/components/src/renderers/overlay/*.tsx
(no matches)
Why it matters
Declared and enforced disagree in both directions on the same object:
- an author following the shipped type writes
onClick — it validates, it publishes, and it never fires;
- an author who gets a working menu wrote
onSelect — which no type declares, so nothing protects it from being renamed away.
This is the failure mode objectui#6132's own four-axis analysis called the most expensive one ("能通过校验、能发布、然后静默什么都不做"), except here it survives because the prop is declared, so it reads as correct.
Note this is a third MenuItem-shaped defect in the same family as objectui#6326 and objectui#6278 (both about an item's icon), and unlike those it is about the handler rather than the glyph.
The decision this needs
Which spelling is the contract?
I have no recommendation strong enough to skip triage — B matches observed runtime behaviour, A matches the published declaration, and the choice depends on whether any authored onSelect exists in the wild. Worth measuring before ruling.
⚠️ Whichever way this goes, PR #6345's three doc pages (overlay/context-menu.mdx, overlay/dropdown-menu.mdx, overlay/menubar.mdx) name onClick and would need the same correction under option B.
Refs: objectui#6132 · PR #6345 · objectui#6326 · objectui#6278 · objectui#4453.
Generated by Claude Code
Surfaced while implementing objectui#6132 (PR #6345). Not fixed there: that card ruled a docs question, and this is a code-side contract question whose fix lands in
packages/.What was measured
objectui#6132's ruling redirects three menu reference pages at
MenuItem.onClick, on the grounds that it is a real declared slot. It is — I verified it in three places before doing the redirect:packages/types/src/overlay.ts:346—onClick?: () => void;packages/types/dist/overlay.d.ts:334— the exact line objectui#6132 citedpackages/types/src/zod/overlay.zod.ts:136—onClick: z.function().optional().describe('Click handler')But no renderer reads it. The renderers read a different, undeclared key on the same item:
packages/components/src/renderers/overlay/menubar.tsxwires no item handler at all — neither spelling.Neither
onSelectnorinsetis declared onMenuItem. The helper is typedrenderMenuItems(items: any[]), which is why the mismatch type-checks.Confirming the negative:
Why it matters
Declared and enforced disagree in both directions on the same object:
onClick— it validates, it publishes, and it never fires;onSelect— which no type declares, so nothing protects it from being renamed away.This is the failure mode objectui#6132's own four-axis analysis called the most expensive one ("能通过校验、能发布、然后静默什么都不做"), except here it survives because the prop is declared, so it reads as correct.
Note this is a third
MenuItem-shaped defect in the same family as objectui#6326 and objectui#6278 (both about an item'sicon), and unlike those it is about the handler rather than the glyph.The decision this needs
Which spelling is the contract?
item.onClick, type the helper asMenuItem[]. Existing authoredonSelectkeys stop working.MenuItem.onClicktoonSelectin TS + Zod, and correct the three doc pages PR docs(components): follow the shipped types on the last five action props #6345 just pointed atonClick. This moves a published type.ActionConfig: it makes the docs retroactively true by widening the surface, and objectui#4453/Migrate the in-repo schema corpus (~424 files) to carry the canonical$schemamarker — the producer-side half of #5127's Option B #5329/Four fields docs pages import a cell renderer @object-ui/fields does not export — and two of them name a renderer that has no export at all #6107 have refused that three times.I have no recommendation strong enough to skip triage — B matches observed runtime behaviour, A matches the published declaration, and the choice depends on whether any authored
onSelectexists in the wild. Worth measuring before ruling.overlay/context-menu.mdx,overlay/dropdown-menu.mdx,overlay/menubar.mdx) nameonClickand would need the same correction under option B.Refs: objectui#6132 · PR #6345 · objectui#6326 · objectui#6278 · objectui#4453.
Generated by Claude Code