Skip to content

docs(context-menu): author the trigger card's text under the key ui:card reads - #6807

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6788-context-menu-demo-content
Aug 30, 2026
Merged

os-sam merged 1 commit into
mainfrom
claude/issue-6788-context-menu-demo-content

Conversation

@claude

@claude claude Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #6788

What was wrong

examples/schema-catalog/src/schemas/components-overlay-context-menu/basic-context-menu.json
authored its trigger as { "type": "card", "content": "Right-click here", "className": "p-8 text-center border-dashed" }.

Both halves of the card's claim re-verified on this branch's base d06059f24 before choosing the fix:

  • packages/components/src/renderers/layout/card.tsx reads title, description, header,
    children || body, footer (plus clickable/hoverable). It never reads content.
  • the ui:card registration declares inputs title, description, className. No content.

So the tile drew an empty dashed box and the instruction reached the DOM only as the leaked host
attribute content="Right-click here" -- the #5574 class, for which ui:card is already ledgered
in packages/app-shell/src/__tests__/widget-dom-leak-sweep.test.tsx.

The fix: children, one line

card.tsx accepts two spellings for that slot, and they are not equal choices. BaseSchema marks
body "Legacy, use children", #6771 is retiring body as a children dialect, and #6773 authored
children in the four sibling aspect-ratio card demos (dfb889f8d). So the corpus converges on
one spelling instead of acquiring a second.

The renderer was not taught to read content. That would widen a published surface to a second
dialect for one slot -- the shape #6771 is removing elsewhere. The renderer is the contract
(AGENTS.md #0.1).

The pin is the wider half

examples/schema-catalog/test/card-demo-content-6788.test.tsx. This defect was found by hand
while correcting its four siblings, so a pin scoped to this entry would leave the next one to the
next pair of eyes. The key assertions therefore run over every card node in the catalog --
93 nodes, 53 entries, 19 categories, at any depth -- not over this entry.

Two key assertions, because they fail for different reasons (the #6157 class-3 shape, where a key is
refused by neither zod nor tsc):

  1. DECLARED -- read off the shipped CardSchema's own zod shape, not a hand-copied list, so it
    follows the platform. .success could not be the probe: BaseSchema is .passthrough() and
    carries [key: string]: any, so content parses green and type-checks.
  2. READ -- the keys card.tsx reads, copied as literals on purpose. Strictly stronger than (1):
    variant is declared on CardSchema and read by nothing, so a demo authoring it would pass (1)
    and still draw nothing. There is a counter-probe for exactly that.

Plus the acceptance criterion itself, category-scoped: the tile's text is non-empty when rendered
through the real SchemaRenderer, it contains the author's own string, and no element carries it as
a content attribute. Not widened to all 53 card-bearing entries: some sit inside nodes that want a
datasource, and catalog-gallery-render.test.tsx already owns the corpus-wide render sweep with its
documented exclusions.

Every assertion is paired with a counter-probe rendering or judging the exact pre-fix shape.

Verification

All of the below on the final commit 7b02e14de, each under the shared verify lock:

pnpm exec vitest run examples/schema-catalog/          17 files, 1875 tests passed
pnpm -F @object-ui/example-schema-catalog type-check   tsc --noEmit && tsc -p tsconfig.test.json -> exit 0
pnpm -F @object-ui/example-schema-catalog lint         0 errors (1 pre-existing warning in the generated index)
pnpm -F @object-ui/example-schema-catalog regenerate:check   src/index.ts is up to date (431 entries)
node scripts/check-type-check-coverage.mjs             45/46 via type-check; 41/41 packages compile their tests
node scripts/check-lint-coverage.mjs                   46/46 packages linted, 0 errors
pnpm check:control-bytes                               OK (scanned 5646 tracked text files)
node scripts/check-changeset-fixed.mjs                 All workspace packages are in the fixed group
node scripts/check-changeset-no-major.mjs              No changeset declares a `major` bump
node scripts/check-changeset-presence.mjs              no changeset is owed (an empty-frontmatter one is added anyway)

The new test file is genuinely inside the type-check program, not merely beside it:
tsc -p tsconfig.test.json --listFiles reports it once.

Reverse verification. With the fix committed, the pre-fix content spelling was restored on
disk (mutation proved present: injected spelling count 1, removed spelling count 0, blob
1a466c50a -> 78ba83bd7) and the pin was re-run: 3 failed, 6 passed -- both key assertions
naming components-overlay-context-menu/basic-context-menu.trigger / content, and the render
assertion reading expected '' not to be ''. The counter-probes stayed green, which is the designed
direction: they render their own shapes. The restore leg was then proved byte-identical
(git diff HEAD empty, blob back to 1a466c50a), and the union above was run after it.

The population question

Asked, and measured by walking all 431 catalog fixtures: card nodes authoring content in
examples/schema-catalog/ = 1, this one. The other four the filing counted are the
aspect-ratio demos already corrected by #6773 (dfb889f8d). After this change the count is 0,
which is what the corpus assertion now holds.

Two same-class defects in other node families were measured while sweeping and are filed rather
than fixed here -- out of this card's fence:

The value keys on this fixture's menu items are not touched here: they are undeclared on
MenuItem and read by no renderer, but that population (21 items across three fixture families) is
already owned by open issue #6521.

Release declaration

.changeset/6788-context-menu-demo-content.md, empty frontmatter: no published package source
changed, so this declares no release -- the same shape #6773 used.

Generated by Claude Code


Generated by Claude Code

…ard reads

`components-overlay-context-menu/basic-context-menu.json` authored its trigger
as `{ "type": "card", "content": "Right-click here" }`.
`packages/components/src/renderers/layout/card.tsx` reads `title`,
`description`, `header`, `children || body` and `footer`, and `content` is not
among the `ui:card` registration's declared `inputs` either — both re-verified
on d06059f. So the tile drew an empty dashed box and the instruction reached
the DOM only as the leaked host attribute `content="Right-click here"` (the
objectui#5574 class, for which `ui:card` is already ledgered in
`widget-dom-leak-sweep.test.tsx`).

`children`, not `body`: the renderer accepts both, but `BaseSchema` marks
`body` legacy and objectui#6771 is retiring it as a `children` dialect, and
objectui#6773 authored `children` in the four sibling `aspect-ratio` card
demos. The renderer was NOT taught to read `content` — that would add a second
dialect for one slot to a published surface (AGENTS.md #0.1).

Adds `examples/schema-catalog/test/card-demo-content-6788.test.tsx`. Its key
assertions run over EVERY `card` node in the catalog (93 nodes, 53 entries, 19
categories on d06059f), not over this one entry, because this defect was
found by hand while correcting its four siblings. Two assertions, because they
fail for different reasons: keys must be DECLARED by the shipped `CardSchema`
(read off its zod shape, so it follows the platform) and must be keys
`card.tsx` READS (literals — `variant` is declared and read by nothing). The
render half is category-scoped and asserts the acceptance criterion directly:
the tile's text is non-empty through the real `SchemaRenderer`. Every
assertion is paired with a counter-probe on the exact pre-fix shape.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
@os-sales
os-sales marked this pull request as ready for review August 29, 2026 22:15
Merged via the queue into main with commit aa20c41 Aug 30, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(examples): the basic-context-menu demo authors its trigger card under content, which ui:card never reads — the tile is an empty dashed box

1 participant