Skip to content

fix(examples): catalog entries author the keys their renderers read (#4624) - #4630

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-4624-catalog-authoring-truth
Aug 14, 2026
Merged

fix(examples): catalog entries author the keys their renderers read (#4624)#4630
os-zhuang merged 1 commit into
mainfrom
claude/issue-4624-catalog-authoring-truth

Conversation

@yinlianghui

@yinlianghui yinlianghui commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Fixes #4624
Fixes #4626
Fixes #4625

Three catalog-authoring defects on one surface, plus the #4616 render pin's exclusion tables shrinking to match reality. Authoring-side only: no renderer or package source is touched.

One of the three filings turned out to be partly mis-diagnosed. That is reported below rather than papered over, and the pin's header is corrected to match what was measured.

Piece 1 — #4624, components-disclosure-toggle-group/with-labels

Named root type "single", which nothing registers. Now "toggle-group" + "selectionType": "single", the spelling both siblings already use. The items keep their icon keys: ToggleGroupItem.icon is a declared field (packages/types/src/disclosure.ts:131), so this is not the entry inventing a key — though no renderer reads it, filed as #4632.

This was the last unintentional OBJUI-001 tile in the corpus.

Piece 2 — #4626, the two "blank tile" entries

components-overlay-tooltip/basic-tooltip — filing confirmed. It authored its trigger under children. Renderer prop reads, packages/components/src/renderers/overlay/tooltip.tsx:

  • line 28 renderChildren(schema.trigger) inside TooltipTrigger asChild
  • line 31 (schema.content || renderChildren(schema.body)) inside TooltipContent

children is read nowhere, so the tile drew nothing at all. Measured as authored: 2 elements (both harness wrappers), empty text. Now authors trigger; measured after: 3 elements, text "Hover me".

components-overlay-hover-card/basic-hover-card — filing falsified on both of its claims. The issue states the text renderer reads content and that value is therefore never read. It reads both:

  • packages/components/src/renderers/basic/text.tsx:35 and :40 both evaluate schema.content || schema.value

So the authored value WAS read, and the tile was not blank: measured as authored, it drew the text node "Hover over me". The pin's own non-vacuity control accepts text as well as elements (deliberately — components-basic-text/* are bare text nodes), so removing this entry's exclusion turns nothing red. That was verified by removing the exclusion BEFORE touching the entry: the run went red on 9 cases and this was not one of them.

What the entry did have is a different defect, one the filing did not name: a bare text node is not an element, so HoverCardTrigger asChild had nothing to clone and the card could never open. Measured contrast, same harness — a text trigger carrying a className renders a span that Radix wires (data-state="closed"), while the bare one renders no element at all. The trigger is now a link-variant button, which is the shape the renderer's own defaultProps declare for this slot (hover-card.tsx:50). The content slot keeps value, which is the key TextSchema declares (packages/types/src/layout.ts:56).

Note the deliberate non-change: the ruled correction value to content is a no-op at render time AND would author a key TextSchema does not declare. content appears only in the registry meta. That three-way disagreement is the real class question and is filed as #4631.

Piece 3 — #4625, the six components-form-calendar entries

Verify-first, as ruled. ui:calendar IS addressable as a schema type. Measured, not inferred:

  • Registry.get(type) with no namespace argument looks the string up verbatim (packages/core/src/registry/Registry.ts:350-358), and register() stores the namespaced form under exactly ui:calendar (line 163). SchemaRenderer passes the authored type straight in: ComponentRegistry.get(evaluatedSchema.type) at packages/react/src/SchemaRenderer.tsx:506.
  • Probe-rendered through this pin's own harness, before any entry was edited: { "type": "ui:calendar", "mode": "single" } produced 115 elements and painted the date-picker grid ("August 2026 SuMoTuWeThFrSa..."). The bare calendar keyword in the same probe produced 5 elements and "Error: DataSource required for object/api providers".

So all six now author ui:calendar and reach the form-calendar primitive the category exists to demo. form-integration is a div whose nested child was the offending node; only that child changed.

The bare keyword still resolves to plugin-calendar's ObjectCalendar. That is skipFallback: true working as designed, not something this PR routes around.

Piece 4 — the pin

examples/schema-catalog/test/catalog-gallery-render.test.tsx:

Untouched, as ruled: the deliberate OBJUI-001 demo entry, the three Monaco and three maplibre environment abstentions, and AUTHORED_TEXT_EXEMPT (#4627).

Red-first, then green

Predictions were written before the run. Pin edits made first, entries untouched, so the red is the pin reporting on the real corpus:

× components-disclosure-toggle-group/with-labels renders without a red tile 11ms
× components-form-calendar/custom-style renders without a red tile 12ms
× components-form-calendar/date-range renders without a red tile 6ms
× components-form-calendar/form-integration renders without a red tile 7ms
× components-form-calendar/multiple-dates renders without a red tile 6ms
× components-form-calendar/simple-calendar renders without a red tile 6ms
× components-form-calendar/single-date renders without a red tile 6ms
× components-overlay-tooltip/basic-tooltip renders without a red tile 1010ms
× the whole corpus produces zero unknown-type panels and zero error tiles 3003ms

Tests  9 failed | 431 passed (440)

Verbatim diagnostics:

AssertionError: components-disclosure-toggle-group/with-labels shows "Unknown component type":
expected 'Unknown component type: single...' not to contain 'Unknown component type'
+ Unknown component type: single (OBJUI-001)

AssertionError: components-form-calendar/custom-style shows "DataSource required for object/api providers":
Received: "Error: DataSource required for object/api providers"

AssertionError: components-form-calendar/form-integration ...
Received: "Select a dateError: DataSource required for object/api providers"

basic-tooltip and the corpus case fail differently — on the non-vacuity control inside renderEntry, expected true, received false at the drewSomething waitFor — because a tile that draws nothing never settles. That is the blank-tile signature, and it is the one #4626 half that reproduced.

components-overlay-hover-card/basic-hover-card is absent from that list: it passes with its exclusion removed and no entry change. Predicted red, measured green — reported rather than forced.

After the entry re-authoring, same command:

Test Files  1 passed (1)
     Tests  440 passed (440)

440 vs the 437 of the pre-change baseline: three entries left the exclusion table and became asserted cases.

Reverse verification. Fix taken back out with git checkout origin/main -- ... (never git stash), pin left in place: the same 9 cases fail, basic-hover-card again absent. Restored with git checkout HEAD -- ... and all nine files verified bit-identical by sha256sum -c.

Verification

pnpm exec vitest run --maxWorkers=2 scripts/ examples/schema-catalog
  Test Files  50 passed (50)
       Tests  2531 passed (2531)

pnpm --filter '@object-ui/example-schema-catalog^...' build   (build closure first)
pnpm --filter @object-ui/example-schema-catalog type-check     (clean)
pnpm --filter @object-ui/example-schema-catalog lint           (0 errors; 2 pre-existing warnings in untouched files)

Gate battery, all PASS: check-control-bytes, check-phantom-dependencies, check-changeset-presence, check-changeset-no-major, check-changeset-fixed, check-type-check-coverage, check-lint-coverage, check-doc-links. Control-byte self-scan over the changed files (and untracked: none) is clean.

Changeset

None owed, and skip-changeset is applied instead: @object-ui/example-* is in .changeset/config.json's ignore list and @object-ui/example-schema-catalog is "private": true. The diff is entirely under examples/schema-catalog/**. check-changeset-presence passes.

Out of scope, filed rather than fixed here


Generated by Claude Code

…4624)

Three catalog-authoring defects on one surface, plus the #4616 render pin's
exclusion tables shrinking to match.

- #4624: components-disclosure-toggle-group/with-labels named root type
  "single", which nothing registers. Now "toggle-group" + selectionType
  "single", the spelling both siblings use.
- #4626: components-overlay-tooltip/basic-tooltip authored its trigger under
  "children", which the tooltip renderer never reads (it reads schema.trigger
  at tooltip.tsx:28). Now "trigger".
- #4626: components-overlay-hover-card/basic-hover-card was measured NOT to
  be blank and NOT to author an unread key -- text.tsx:35,40 reads
  schema.content || schema.value, so the authored "value" was read and the
  tile drew a text node. Its real defect: a bare text node is not an element,
  so HoverCardTrigger asChild had nothing to attach to. Trigger is now a
  link-variant button, the shape the renderer's own defaultProps declare.
- #4625: the six components-form-calendar entries authored the bare
  "calendar" keyword, which plugin-calendar's data-bound ObjectCalendar owns.
  Measured first that "ui:calendar" is addressable as a schema type, then
  re-authored all six to it.

The pin now asserts all three diagnostics for every non-excluded entry: the
per-entry DATASOURCE_REQUIRED exemption table is gone, and only the
deliberate OBJUI-001 demo and the six Monaco/maplibre environment
abstentions remain excluded.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 14, 2026 3:50am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment