Skip to content

finding(examples): sidebar-with-badges authors its two counts under content, which ui:badge never reads — the badges render empty #6806

Description

@claude

Found while implementing #6788 (the basic-context-menu trigger card authoring content).
Out of that card's fence, so filed rather than fixed. Same defect class, a third renderer.

Measured

examples/schema-catalog/src/schemas/components-basic-sidebar/sidebar-with-badges.json
authors both of its counts as

{ "type": "badge", "content": "12", "className": "ml-auto" }

packages/components/src/renderers/data-display/badge.tsx renders
schema.label || renderChildren(schema.body) -- it never reads content.

Rendered through the real SchemaRenderer on d06059f24:

components-basic-sidebar/sidebar-with-badges elements=22 leaked=2 text="InboxDraftsSentTrashMain content area"

The four item labels are there and the two counts are NOT: 12 and 3 reach the DOM only
as the leaked host attribute content (leaked=2) -- the #5574 class.

The contrast inside this one fixture is the tell: its sibling text nodes author content
too, and those render, because packages/components/src/renderers/basic/text.tsx reads
schema.content || schema.value. One key, two renderers, opposite outcomes -- which is
exactly the thing a reader copying the demo cannot see.

So the demo is named sidebar-with-badges and draws a sidebar with no badges.

Population

badge nodes authoring content in the catalog: 2, both in this fixture. Verified by
walking all 431 fixtures.

Fix shape (for triage, not a decision)

"label": "12" -- the key badge.tsx reads first and the one BadgeSchema declares for
its text. body is the other key it reads, but #6771 is retiring body as a children
dialect, so label is the spelling to converge on here. The renderer is the contract
(AGENTS.md #0.1); do not teach ui:badge to read content.

Why nothing caught it

BaseSchema is .passthrough() and carries [key: string]: any, so content is accepted
by zod and tsc alike. catalog-gallery-render.test.tsx renders this entry and passes: the
sidebar draws plenty of elements and text, so a non-vacuity control cannot see two missing
badges inside it. The corpus sweep added by #6788 covers card nodes only.

Related

#6788 (the card this was found under) - #6773 (same class, the aspect-ratio family) -
#5574 (the DOM-leak class the attribute belongs to)

Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions