fix(examples): author the four alert-dialog fixtures in the dialect the renderer reads (objectui#7693) - #7962
Merged
baozhoutao merged 3 commits intoSep 6, 2026
Conversation
…he renderer reads (objectui#7693)
All four `components-overlay-alert-dialog/*` fixtures authored an `actions`
array of two button nodes. Nothing carries that key: the renderer
(`packages/components/src/renderers/overlay/alert-dialog.tsx:37-38`) draws
`AlertDialogCancel` ONLY from `schema.cancelText` and `AlertDialogAction` ONLY
from `schema.actionText`, and `schema.actions` has zero read sites in the repo.
`AlertDialogSchema` and its zod twin do not declare it either. So the four
demos the docs page embeds rendered a dialog with an EMPTY footer — the one
thing an alert dialog exists for was missing from every one of its examples.
Nothing was red because `BaseSchema` is `.passthrough()`
(`packages/types/src/zod/base.zod.ts:241`): `actions` rode through
`safeValidateSchema` unvalidated, and no gate parses a JSON fixture as a schema.
Measured on this base, the keys `AlertDialogSchema` declares AND the renderer
reads: `type`, `title`, `description`, `content`, `trigger`, `defaultOpen`,
`open`, `cancelText`, `actionText`, `className` (plus the runtime slots
`onAction` / `onOpenChange`, which have no JSON spelling and are refused by
name). `cancelLabel`, `confirmLabel` and `confirmVariant` are still DECLARED but
read by nothing, so no fixture is moved onto them.
Conversion, per fixture: `actions[0]` -> `cancelText`, `actions[1]` ->
`actionText`. The per-button `variant` is DROPPED — the read dialect has no
spelling for it, and the footer's styling is fixed by the primitives
(`AlertDialogCancel` is always `buttonVariants({ variant: 'outline' })`,
`AlertDialogAction` always the default). Giving `confirmVariant` a read site is
a renderer + types change on the manual floor and is deliberately not ridden
along here.
The pin, `test/alert-dialog-footer-read-dialect-7693.test.tsx`, has two halves,
each with a live control: a DOM half that renders every fixture through the real
registry and requires at least one footer button, and a fixture-key half that
walks the WHOLE catalog and requires no `alert-dialog` node anywhere to carry
`actions`. Both went red on this base (4 + 1 failures) while both controls
stayed green, so the red is a reading about the spelling and not about the
harness.
`form-control-dom-leak-5632.test.tsx`'s `NODE_CENSUS` moves `button` 126 -> 118:
the eight action-array button nodes are now two strings, so they leave a
`type`-keyed walk. That table's own header sanctions the update for a
catalog-authored diff that touches no renderer, which this one is.
Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M
Co-authored-by: Claude <noreply@anthropic.com>
…read dialect (objectui#7693)
`alert-dialog-read-dialect-7104.test.ts` pinned the FILED PREMISE of
objectui#7693 — that all four schema-catalog fixtures author `actions` and
neither label key — precisely so the card's fix would have to come back here and
re-derive it. Converting the fixtures did exactly that: the four membership legs
went red on CI shard 4/4. This is the other side of that flip.
The file's own header prescribes re-derivation, not deletion, so the block is
inverted rather than dropped, and the header bullet that listed this premise as
UNRESOLVED is rewritten to record that it resolved and how.
What the re-derived block asserts is the TYPES-side reading, not a second copy
of the catalog-side one:
- each fixture authors `cancelText` and `actionText` as strings and no
`actions` array;
- the UNION of every key the four fixtures author is a subset of
`AlertDialogZod.shape` — membership in the mirror, which is the question
`.success` cannot answer because `BaseSchema` is `.passthrough()`, and
which is not askable from the catalog package at all;
- two live controls: that `actions` is genuinely absent from `shape` (so the
membership leg is not a tautology), and that the pre-repair document STILL
parses green (so the reason nothing red covered this card stays a live
reading rather than a historical note).
The render-side half — footer buttons actually drawn, and a catalog-wide walk
for `actions` on any alert-dialog node — stays with the catalog in
`examples/schema-catalog/test/alert-dialog-footer-read-dialect-7693.test.tsx`.
Neither package can host both: this one cannot see a renderer, that one cannot
see the mirror's shape.
No face change: `packages/types/src/overlay.ts` and
`packages/types/src/zod/overlay.zod.ts` are untouched.
Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M
Co-authored-by: Claude <noreply@anthropic.com>
…g (objectui#7693) Editing any file under a released package's `src/` owes a changeset, and the re-derived premise pin lives at `packages/types/src/__tests__/`. The change publishes nothing: the declaration and its zod twin are untouched and the only edited file is a test, so this is the empty-frontmatter form the gate names as its explicit exemption rather than a version bump. Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ 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
|
baozhoutao
deleted the
claude/issue-7693-alert-dialog-fixtures-read-dialect
branch
September 6, 2026 05:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7693
What was wrong
All four fixtures under
examples/schema-catalog/src/schemas/components-overlay-alert-dialog/authored their footer as anactionsarray of twobuttonnodes. No surface carries that key:packages/components/src/renderers/overlay/alert-dialog.tsx:37drawsAlertDialogCancelonly whenschema.cancelTextis truthy;:38drawsAlertDialogActiononly whenschema.actionTextis truthy.schema.actionshas zero read sites.AlertDialogSchema(packages/types/src/overlay.ts:89) and its zod twin (packages/types/src/zod/overlay.zod.ts:42) do not declareactionseither.So the four demos the docs page embeds through its
SchemaExamplehost rendered a dialog with a header and an empty footer — including the one under the heading "With Custom Actions".Nothing was red because
BaseSchemais.passthrough()(packages/types/src/zod/base.zod.ts:241):actionsrode throughsafeValidateSchemaunvalidated, and no gate parses a JSON fixture as a schema.The key set I measured on this base
origin/mainatd39ede24e, after objectui#7104 (PR #7700, the declaration half) and objectui#7768 (triggerwidened to a node array) had both landed.Declared AND read — the dialect the fixtures now speak:
type,title,description,content,trigger,defaultOpen,open,cancelText,actionText,className. Plus the runtime slotsonActionandonOpenChange, which are host-supplied functions with no JSON spelling — the zod twin refuses them by name.Declared but read by nothing — deliberately not authored by any fixture:
cancelLabel,confirmLabel,confirmVariant. All three still exist on the declared face (overlay.ts:145-158, mirrored atoverlay.zod.ts:60-62); the renderer reads none of them. Authoring a key that is only declared would trade one inert spelling for another.The conversion, and the variant loss
Per fixture:
actions[0]becomescancelText,actions[1]becomesactionText. The per-buttonvariantis dropped — the read dialect has no spelling for it, and the footer's styling is fixed by the primitives themselves (AlertDialogCancelalways rendersbuttonVariants({ variant: 'outline' }),AlertDialogActionalways the default). Three variants are lost:destructiveon the confirm button ofbasic-alert-dialoganddestructive-action, andghoston the cancel button ofconfirmation-dialog. Trigger variants are untouched — those are ordinarybuttonnodes the button renderer does read.This follows the default route the triage comment adopted, quoted here in the original and not translated:
Giving
confirmVarianta read site is a renderer plus types change on the manual floor (domain:ui/domain:spec) and is explicitly out of this card's scope. It is not ridden along here, and no new card was opened for it — the triage comment already records the route and declines to open one.basic-alert-dialogdestructiveconfirmation-dialogghostcustom-actionsdestructive-actiondestructivecustom-actionsstill demonstrates something of its own after the conversion — custom labels on both footer buttons rather than the palette'sCancel/Continue— so it is not a duplicate ofbasic-alert-dialog. It is kept regardless: the docs page references it by id, and deleting a referenced fixture is out of scope.The pin
examples/schema-catalog/test/alert-dialog-footer-read-dialect-7693.test.tsx, both halves the triage comment listed, because they fail for different reasons:overlay-trigger-mirror-6939.test.tsxharness, forced open withdefaultOpen, since a closed Radix dialog mounts no content at all) and must draw at least one footer button carrying text.alert-dialognode anywhere authorsactions. This closes the class rather than the four files; today the catalog holds exactly these fouralert-dialognodes, so it needed no edit outside the anchor.Each half carries a live control, because a render that draws nothing satisfies both assertions trivially:
RENDERS_IN_THE_READ_DIALECT— an inline node in the read dialect must draw two footer buttons. If the harness cannot see a footer button at all, this reds first and every fixture row below means nothing.THE_PRE_REPAIR_SHAPE_DRAWS_NOTHING— the same node with anactionsarray and no label keys must draw zero footer buttons and still validate. That is the defect reproduced in one place, and it is what makes a red fixture row a reading about the spelling.alert-dialognodes, and that its offender predicate reports one when handed one.It would have gone red on this base
Run before the fixtures were touched, with the branch at
origin/maincontent:Both controls were green in that same run, so the five reds are readings about the fixtures, not about the harness.
Ablation on the committed tree
destructive-action.jsonwas restored to theactionsshape at commite25327f00, the mutation proven on disk before the run (actionscount 1,cancelTextcount 0,actionTextcount 0; blobc461f143differs from HEAD blobcfd178b2), then restored:Exactly the mutated fixture's row and the catalog-wide row went red; the other three fixture rows and both controls stayed green. The restore is proven by blob equality plus an empty
git diff HEAD, not by an exit code.The census that moved with it
examples/schema-catalog/test/form-control-dom-leak-5632.test.tsxasserts a per-type node census over the catalog, andbuttonmoves 126 to 118: the eight action-array button nodes are now two strings per fixture, so they leave atype-keyed walk. That table's own header sanctions exactly this ("These move when the CATALOG is authored, not when a renderer changes ... update them"); this diff touches no renderer, andnoElementstays 0 everywhere.Not touched
content/docs/components/overlay/alert-dialog.mdx— verified, not assumed. Its Schema block was already corrected by PR fix(types): declare the four alert-dialog keys the renderer reads (objectui#7104) #7700 and listscancelText/actionTextwith noactionsrow, and its prose at:46describes the footer correctly ("the cancel button renders only whencancelTextis set and the confirm button only whenactionTextis set"). No sentence there is wrong, so the page is left alone.packages/types.node scripts/check-changeset-presence.mjsreports "6 file(s) changed, 0 of them published source of a package the release covers ... no changeset is owed" (examples/**is a private workspace).Verification
All of the below on
e25327f00(working tree byte-identical to it,git diff HEADempty).pnpm exec vitest run --maxWorkers=2 examples/schema-catalog/Test Files 29 passed (29)/Tests 2088 passed (2088)pnpm --filter @object-ui/example-schema-catalog type-check(tsc --noEmit && tsc -p tsconfig.test.json)--listFilespnpm --filter @object-ui/example-schema-catalog regenerate:checksrc/index.ts is up to date (431 entries)pnpm --filter @object-ui/example-schema-catalog lint--format jsoncounts 31 files, 0 errors, 0 warnings, the new file among thempnpm check:doc-snippets(after its scoped build)477 of 477 block(s) judged, 0 failedpnpm check:doc-typesEvery documented component type is registered.pnpm check:control-bytesOK (scanned 6412 tracked text file(s))pnpm check:doc-example-readersOK 80 documented symbol(s) ... no @example hand-spells onenode scripts/check-type-check-coverage.mjs42/42 packages compile their testspnpm check:unreferenced-sourcesEvery shipped source file in every covered package is reachable.node scripts/check-governed-queue-guard.mjs --test(all 6 paths)NOT GOVERNED — 6 path(s) checked ... none matchedturbo ls --affectedfrom the branch base names two packages:@object-ui/example-schema-catalog(fully run above) and@object-ui/site, which is affected only because it depends on the catalog. The catalog's registry is typed as aRecordkeyed by STRING withExamplevalues — written out in words rather than in angle brackets, because GitHub's body sanitizer eats short angle-bracket fragments even inside backticks — andExampleleavesschemaatunknown(examples/schema-catalog/src/index.ts:457,src/types.ts), so a JSON content change crosses that boundary with no type surface at all, and no example id was added or removed. The site's owntype-checkandnext buildare left to CI.Heavy runs went through the shared verify lock; the wall-clock figures in its verdict lines are shared-box seconds.
Rework — the premise pin this card had to flip (added after the first CI run)
One sentence, since it is the substance of the rework:
packages/types/src/__tests__/alert-dialog-read-dialect-7104.test.tspinned this card's FILED PREMISE — that all four fixtures authoractionsand neither label key — precisely so the fix would have to come back and re-derive it, and the first push of this PR flipped the fixtures while leaving that pin, which is what turned CI's Test shard 4/4 red on four cases at:324.That pin is now re-derived rather than deleted, because the file's own header prescribes re-derivation in those words: "Pinned here as that card's filed premise; its fix goes red here and re-derives the pin." The block now reads:
cancelTextandactionTextas strings and noactionsarray;AlertDialogZod.shape— membership in the mirror, which is the question.successcannot answer under.passthrough(), and which is not askable from the catalog package at all;actionsis genuinely absent fromshape(so the membership leg is not a tautology), and that the pre-repair document STILL parses green (so the reason nothing red covered this card stays a live reading, not a historical note).The render-side half stays with the catalog and is deliberately not duplicated: neither package can host both, since
packages/typescannot see a renderer andexamples/schema-catalogcannot see the mirror's shape. The header bullet that listed this premise as UNRESOLVED is rewritten to record that it resolved and how. No face change —packages/types/src/overlay.tsandpackages/types/src/zod/overlay.zod.tsare untouched, andgit diffagainst the branch base names exactly eight files, none of them a declaration.The standing line I had skipped
git grep -l 'components-overlay-alert-dialog' packages/ scripts/ examples/ apps/— every reader of these fixtures:examples/schema-catalog/src/index.tsregenerate:checkgreen, no id added or removedexamples/schema-catalog/test/alert-dialog-footer-read-dialect-7693.test.tsxexamples/schema-catalog/test/form-control-dom-leak-5632.test.tsxpackages/types/src/__tests__/alert-dialog-read-dialect-7104.test.tsOutside those four paths,
content/docs/components/overlay/alert-dialog.mdxis the only other reference in the repo, and it is verified correct and untouched.Ablation of the re-derived pin
confirmation-dialog.jsonrestored to theactionsshape on the committed tree, mutation proven on disk first (actionscount 1,cancelText0,actionText0; blobad076ac6differs from HEAD blobff9eb780):Exactly the mutated fixture's row and the membership leg; both controls and the other three fixture rows stayed green.
Changeset, now owed
Editing any file under a released package's
src/owes a changeset, and the re-derived pin lives atpackages/types/src/__tests__/. Nothing is published by it, so.changeset/alert-dialog-fixture-premise-pin-7693.mdcarries the EMPTY frontmatter the gate names as its explicit exemption:1 changeset(s) ... Every one of them has an EMPTY frontmatter — declared as releasing nothing, which is the explicit exemption and a complete answer to this gate.check-changeset-no-majoris green.Re-run, at
c070119cdpnpm exec vitest run --maxWorkers=2 packages/types/src/__tests__/alert-dialog-read-dialect-7104.test.tsTest Files 1 passed (1)/Tests 42 passed (42)pnpm exec vitest run --maxWorkers=2 packages/types/ examples/schema-catalog/Test Files 158 passed (158)/Tests 4479 passed (4479)pnpm --filter @object-ui/types type-check(tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json)--listFileseslinton the edited file,--format jsonpnpm check:control-bytesOK (scanned 6414 tracked text file(s))node scripts/check-governed-queue-guard.mjs --test(all 8 changed paths)NOT GOVERNED — 8 path(s) checked ... none matchednode scripts/check-changeset-presence.mjsturbo ls --affectednow names most of the tree, because turbo works at package granularity and the edited file sits underpackages/types/src/. That fan-out is not real: the file is a leaf test, imported by nothing (git grepfor its name outside itself finds one prose mention in a sibling test's comment and no import), so no downstream package's behaviour can move. The types package's own suite and the catalog's were both run in full above; the rest is left to CI.Session reference, in prose and as a code span so it survives a body edit:
https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1MGenerated by Claude Code