Repository navigation
fix(components): page:header stops drawing an empty breadcrumb slot; the key is ignored until the spec retires it (objectui#11166) - #11172
Conversation
The renderer no longer reads `breadcrumb` and drops both empty `data-page-breadcrumb-slot` divs (bare and record-chip layouts). Nothing ever filled the slot, and the console's app header already draws the trail, so triage ruled RETIRE (the spec half is objectstack#20758). The spec still accepts the key until that lands, so an authored value keeps rendering without error: it is ignored. The registration keeps the input declared, now described as inert, because the parity ledger's reverse direction reads inputs against the accepted spec keys. Pinned in both layouts through the real SchemaRenderer: `breadcrumb: true` (in `properties` and on the node) and `false` render no slot and the same header as the absent key, with no console error. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
`page-header.mdx` stops listing the key: the prop-table row, the "renders an empty slot element" paragraph and the diagram's slot line go, replaced by one sentence saying the key is accepted until the spec retires it and is ignored. `guide/layout.md` described the key as a display toggle for the slot above the title, which this change makes false: its Schema API line goes and the three cross-references now say it draws nothing. Its overview bullet stops promising breadcrumbs from PageHeader, which draws none in either renderer. Changeset: '@object-ui/components' patch, naming the visible shift (the title moves up by the removed gap-2 / mb-1). Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ 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
|
Contract reviewServed-tier: Inputs: card #11166 (body; triage Check-runs on the head ( ① Derived judgments
② Semver level
③ Boundary flags
Out-of-scope notes:
Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #11166
Clause-②: no
Implements the renderer and docs half of triage
5903152845(ruling RETIRE). The spec half is objectstack-ai/objectstack#20758; this PR does not depend on it. Dispatched by thedomain:uiseat 2 PM, sessionhttps://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec, branchclaude/issue-11166-page-header-breadcrumb-retire.What changed
PageHeaderRendererinpackages/components/src/renderers/layout/containers.tsxno longer readsbreadcrumb. It drops both emptydata-page-breadcrumb-slotdivs: the record-chip layout's (aboveRecordTitleChip) and the bare layout's (above the title row). An authoredbreadcrumb(trueorfalse, inpropertiesor on the node) renders exactly like an absent key: no slot and no error. ⛔ No trail is drawn in its place.inputskeeps{ name: 'breadcrumb', type: 'boolean' }and adds a description saying the key is ignored. It stays declared while the installed spec (17.4.0) still accepts the key; the measured reasons are in Zone 2 item 2 below. It leaves at the pin bump that brings objectstack#20758's tombstone, when the parity file's forward direction will name it.content/docs/layout/page-header.mdxdrops the key's prop-table row, the "renders an empty slot element" paragraph, and the layout diagram's(breadcrumb slot)line. One sentence replaces the paragraph. I chose one sentence over none because the spec still publishes the key as "Show breadcrumb", defaulttrue, and this page is where an author learns it draws nothing.content/docs/guide/layout.md. It is outside the claimed surface, but this change makes it false, so it is a must-fix.page:headerSchema API excerpt listedbreadcrumb?: boolean // default true — the breadcrumb slot above the title. That line goes.@object-ui/layout'sPageHeaderdraws one; the latter's render body has no breadcrumb element.'@object-ui/components': patch, which names the visible spacing shift.Zone 2 measurements (base
c2a8d23c6)Sites. All confirmed by content:
const breadcrumb = (schema?.breadcrumb ?? schema?.properties?.breadcrumb) !== false;;{breadcrumb && (...data-page-breadcrumb-slot...)}blocks;Root class strings are byte-unchanged. The bare root is
flex flex-col gap-2 pb-4 border-b, and the record root keepsgap-3 sm:gap-4. The demo pinpageheader-with-actions.test.tsxstays green ongap-2/pb-4/border-b.The rendered spacing does move. Measured in Chromium 1194 (headless) with plain CSS equal to the Tailwind utilities, not the built stylesheet:
The empty div was a flex item in the root's
gap-2column (bare), or carriedmb-1(record). A header that already setbreadcrumb: falsedoes not move.Registration inputs list
breadcrumb. ⛔ The parity fileapps/console/src/__tests__/registry-inputs-spec-parity.test.tsis untouched.page:header.breadcrumbrow.NO_READ_SITE_TO_PINlives in its member-pin ledger, which covers array- and object-armed inputs only, andbreadcrumbis boolean. So removing the read moves no row, and the file stays green at head.breadcrumb: truedraws zero manifest diagnostics;unknown-prop, whose message says page:header has no prop "breadcrumb";UNPUBLISHED_EXEMPTIONSentry in that file, which belongs to objectui#11086.Docs. The key leaves all three sites. One sentence was chosen (see above).
Existing pins. None moved.
git grep -n breadcrumb -- '*.test.*'underpackages/componentsandexamples/schema-cataloghits onlyui:breadcrumband config-panel suites.actions-slotpins are green: the full components suite is below, and the new pin assertsdata-page-actions-slotin both layouts.Tests (all at head
8ef26fe20, unless marked)New pin:
packages/components/src/__tests__/page-header-breadcrumb-ignored-11166.test.tsx. It mounts through the realSchemaRendererand registry, in both layouts.properties.breadcrumb: true,breadcrumb: trueon the node, andproperties.breadcrumb: false.breadcrumbtext anywhere in the header, with noconsole.error.h1anddata-page-actions-slot, so the test cannot pass on an empty header.Tests 8 passed (8), run at26bc72b6e, wherecontainers.tsxhas the same blob as head.@object-ui/componentsplusexamples/schema-catalog. Run aspnpm exec vitest run packages/components/ examples/schema-catalog/ --shard=N/4, four shards under the verify lock. The unsharded run hit the 560s timeout on the shared box, so it was sharded.That is 374 files, which equals the 376
*.test.*filesgit ls-fileslists minus two.snapfiles.Cross-package readers: 75 files, 75 passed, 2006 tests. This covers every test outside those two trees that reads
containers.tsxor the two edited docs pages from disk, or namespage:header. That includes:registry-inputs-spec-parity,public-contractandcomponent-input-union-specimens;widget-dom-leak-sweep,block-config*andPageBlockInspector.i18n;page-breadcrumbs-refusal-8871andzod-mirror-parity;scripts/__tests__/check-doc-component-typesanddoc-version-claims.Type-check.
pnpm --filter @object-ui/components type-checkexits 0, afterpnpm --workspace-concurrency=2 --filter '@object-ui/components^...' build.tsc -p tsconfig.test.json --listFilesincludes the new pin.Ablation (fix committed first; mutation and restore via
ablation-replace.mjsWRAP mode)Each leg re-planted the old read-plus-slot in one layout only.
truespellings, andfalsebecause it no longer matches the control.c07608e4cc2a),git diff HEADis empty, andgit statusis clean.Gates
Pass (exit 0):
check:doc-typescheck:doc-snippets: 679 of 679 blocks judged, 0 failed. It ran afterturbo run buildover its own--build-filterclosure (35/35 tasks); the first run exited 2 on unbuilt packages.check:doc-examples: exited 2 on the first run, then passed after the same build.docs:check-linkscheck:doc-fencescheck:doc-example-idscheck:doc-example-readerscheck-doc-expression-carriagecheck:control-bytes, plus a self-scan of the five changed files for control bytes, which found nonecheck:new-line-citationscheck-changeset-presencechangeset:checkcheck-changeset-overwritecheck:changeset-claimscheck:pending-changeset-literalscheck:installed-pin-claimscheck:handler-key-readscheck:action-forward-paritycheck:element-data-source-declarationcheck:designer-field-key-paritycheck:prompt-keyscheck:spec-symbolscheck:unreferenced-sourcescheck:readme-exportscheck:test-path-rootscheck:vi-mock-specifiers/inherit/override-shapelint:coveragetype-check:coveragecheck:phantom-depscheck:self-importcheck:i18n-designer-paritycheck:metadata-write-doorsNot governed.
check-governed-queue-guard --testover the five paths reports NOT GOVERNED. The PR stays draft because it was dispatched.NOT MEASURED:
check:sdui-registration-pins. Reason: it needs a console bundle (apps/console/dist/assets) and exits 2 without one. This diff adds or removes no registration and moves nosideEffects. Left to CI.ESLint, a proven narrowing of CI's
pnpm lint:.tsxfiles match a configuration. For the.md/.mdx/ changeset files eslint reports "File ignored because no matching configuration was supplied".--format json: 2 files, 0 errors.containers.tsxhas 97 warnings, identical to base by rule:no-explicit-any89,only-export-components7,exhaustive-deps1. Base was read via--stdinat the same path.eslint.config.jsenables no type-aware linting (noparserOptions.project/projectService), so this diff cannot move a verdict on an untouched file.Acceptance notes (not filed)
breadcrumbentry ininputsmust go; the parity file's forward direction will name it;gap-2now spaces a single child, the title row, so it is inert. It is kept because the ruling moves no class and the demo pin and docs quote it. Polish; carrier: none.packages/types/src/__tests__/page-breadcrumbs-refusal-8871.test.ts, the LIT CONTROL comment calls.breadcrumb"the livepage:headertoggle", which is no longer true. The control itself still fires on many other hits, and the test is green. It is an unpublished comment; carrier: none.PageHeaderProps.breadcrumb("Show breadcrumb", default true) — no renderer draws a trail and the console shell already draws one; the spec half of objectui#11166 objectstack#20758's measurement. Triage says the spec'snav:breadcrumb"has no objectui renderer". The parity file'sEXPECTED_WITHOUT_INPUTSlistsnav:breadcrumbas "Registered, spec-carried, and deliberately propless". This is a read-only inference; carrier: spec(ui): retirePageHeaderProps.breadcrumb("Show breadcrumb", default true) — no renderer draws a trail and the console shell already draws one; the spec half of objectui#11166 objectstack#20758.content/docs/guide/slotted-pages.md's example still authorsbreadcrumb: true. That file belongs to objectui#11165 and is left untouched. The value renders without error and is ignored.Out-of-scope finding (reported to the seat for filing, class c)
The Studio page designer still offers a "Show breadcrumb" toggle for
page:header.BLOCK_CONFIG['page:header']inpackages/app-shell/src/views/metadata-admin/previews/block-config.ts, labelled byengine.inspector.pageBlock.field.page:header.breadcrumb(en "Show breadcrumb", zh "显示面包屑").breadcrumbinto stored page metadata, which the renderer now ignores. Once objectstack#20758's tombstone is installed, the platform will refuse the whole node by name.iconprecedent pin says "A retirement that leaves its producer standing makes the failure worse, not better."block-config.test.tspins the field set as['title', 'subtitle', 'breadcrumb'].packages/app-shelland i18n to the verification surface, which fails condition ④ of the bounded in-place fix.Generated by Claude Code