Uh oh!
There was an error while loading. Please reload this page.
docs(components): spell the inherited disabled as boolean | string - #7341
Conversation
objectui#7087 (maintainer ruling 2026-09-01, option 1 scoped to `disabled`) removed the 18 `disabled?: boolean` narrowings from the concrete schemas, so the member is now inherited from `BaseSchema` as `boolean | string` — a boolean, or a predicate expression on the same evaluated path as `visible`. 13 component pages went on spelling the removed narrowing in their illustrative interfaces, teaching a type the shipped tree no longer has. Each of the 22 `disabled?:` rows under `content/docs/components` was attributed to its enclosing interface before editing: 13 belong to schemas that inherit the member and were corrected; 8 belong to independent item/option shapes that declare their own `disabled?: boolean` and are left at plain `boolean`; `basic/button-group.mdx` was already correct (objectui#6347) and is the spelling the other 13 converged on. No gate can see this drift — the rows live in `plaintext`/`text` fences and `check-doc-snippet-types` compiles only `ts`/`tsx` (objectui#6143) — so the invariant is pinned instead: `packages/types/src/__tests__/component-docs-disabled-inherited-7239.test.ts` holds all 14 inherited rows to the union, cross-checks against the shipped interfaces so a re-narrowing fails pointing at `packages/types`, keeps the 8 independent rows at `boolean` as a blanket-replace control, and asserts the two tables account for every documented row. Also corrects the now-false 13-of-14 paragraph in the header of `button-group-doc-surface-6347.test.ts` (comment text only; its assertions are untouched and stay green). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NRRumy89BYdW9ogbcdHTho
|
| Step | Outcome |
|---|---|
| Build packages | success |
| Check console performance budget | failure |
Which half objected:
| Eager-closure half | Verdict |
|---|---|
| Aggregate closure ceiling | ✅ pass |
| Per-chunk ceilings | ✅ pass |
| Ceiling sensitivity (headroom) | ✅ pass |
| Ceiling freshness (checkout vs. base branch) |
⚠️ A superseded ceiling is neither a size regression nor a drifted gauge. The bundle was measured correctly and the ceilings on the base branch are correct — but this checkout predates a change to them, so the verdicts above were weighed against numbers that are no longer in force. Nothing grew. Update this branch onto the base branch and letBundle Analysisrun again; do not widen a ceiling to clear it. TheCheck console performance budgetstep log names each superseded constant with both values (objectui#6245).
Reason: The entry chunk measured 142.6 KB, but the eager-closure half of this gate returned no trustworthy VERDICT: the report could not be read, a ceiling has drifted out of range of the regression it must catch, or (objectui#6245) a ceiling was replaced on the base branch after this checkout was made. The step log says which. This is not a passing budget — and it is not a size regression either.
See the workflow run for details.
📦 Bundle Size Report
| Package | Size | Gzipped |
|---|---|---|
| app-shell (consoleActionDispatch.js) | 0.20KB | 0.19KB |
| app-shell (index.js) | 15.33KB | 5.59KB |
| app-shell (runtime-config.js) | 20.68KB | 7.36KB |
| app-shell (types.js) | 0.01KB | 0.04KB |
| app-shell (urlParams.js) | 10.06KB | 3.86KB |
| auth (ActiveOrganizationStorage.js) | 25.05KB | 9.16KB |
| auth (AuthContext.js) | 0.31KB | 0.24KB |
| auth (AuthGuard.js) | 2.07KB | 1.00KB |
| auth (AuthProvider.js) | 40.18KB | 10.59KB |
| auth (AuthShell.js) | 3.49KB | 1.40KB |
| auth (ForgotPasswordForm.js) | 12.21KB | 3.45KB |
| auth (LoginForm.js) | 18.15KB | 5.39KB |
| auth (PreviewBanner.js) | 0.90KB | 0.50KB |
| auth (RegisterForm.js) | 6.65KB | 2.22KB |
| auth (SocialSignInButtons.js) | 9.61KB | 3.89KB |
| auth (UserMenu.js) | 3.41KB | 1.23KB |
| auth (auth-gate-events.js) | 1.29KB | 0.66KB |
| auth (authStyles.js) | 5.04KB | 1.72KB |
| auth (createAuthClient.js) | 40.21KB | 10.80KB |
| auth (createAuthenticatedFetch.js) | 8.46KB | 3.43KB |
| auth (index.js) | 3.19KB | 1.44KB |
| auth (invitation-status.js) | 1.22KB | 0.70KB |
| auth (org-roles.js) | 6.66KB | 2.78KB |
| auth (phone-identifier.js) | 1.11KB | 0.66KB |
| auth (types.js) | 0.59KB | 0.35KB |
| auth (useAuth.js) | 5.30KB | 1.02KB |
| auth (useWorkspaceAdminStatus.js) | 5.13KB | 2.35KB |
| collaboration (CommentThread.js) | 26.08KB | 7.56KB |
| collaboration (LiveCursors.js) | 3.17KB | 1.27KB |
| collaboration (PresenceAvatars.js) | 6.49KB | 2.64KB |
| collaboration (PresenceProvider.js) | 2.79KB | 1.13KB |
| collaboration (index.js) | 1.68KB | 0.73KB |
| collaboration (useCollaborationTranslation.js) | 6.05KB | 2.52KB |
| collaboration (useCommentSearch.js) | 1.98KB | 0.88KB |
| collaboration (useConflictResolution.js) | 7.75KB | 1.86KB |
| collaboration (useMentionNotifications.js) | 1.81KB | 0.68KB |
| collaboration (usePresence.js) | 6.33KB | 1.84KB |
| collaboration (useRealtimeSubscription.js) | 7.91KB | 2.01KB |
| components (index.js) | 514.48KB | 117.36KB |
| core (index.js) | 5.55KB | 2.23KB |
| create-plugin (index.js) | 10.08KB | 3.26KB |
| data-objectstack (index.js) | 178.20KB | 49.60KB |
| fields (index.js) | 244.25KB | 61.73KB |
| i18n (LocalizationContext.js) | 1.76KB | 0.96KB |
| i18n (currency.js) | 1.22KB | 0.64KB |
| i18n (fallbackInterpolation.js) | 6.25KB | 2.77KB |
| i18n (i18n.js) | 4.28KB | 1.75KB |
| i18n (index.js) | 3.44KB | 1.39KB |
| i18n (pickLocalized.js) | 7.62KB | 3.26KB |
| i18n (provider.js) | 26.89KB | 9.04KB |
| i18n (useDisplayLocale.js) | 2.85KB | 1.45KB |
| i18n (useObjectLabel.js) | 33.40KB | 8.71KB |
| i18n (useSafeTranslation.js) | 5.60KB | 2.33KB |
| layout (index.js) | 38.98KB | 10.98KB |
| mobile (MobileProvider.js) | 0.92KB | 0.49KB |
| mobile (ResponsiveContainer.js) | 0.94KB | 0.38KB |
| mobile (breakpoints.js) | 1.51KB | 0.70KB |
| mobile (createOfflineDataSource.js) | 5.61KB | 1.75KB |
| mobile (index.js) | 1.55KB | 0.62KB |
| mobile (offlineQueue.js) | 3.91KB | 1.35KB |
| mobile (pwa.js) | 0.97KB | 0.49KB |
| mobile (serviceWorker.js) | 1.48KB | 0.62KB |
| mobile (serviceWorkerSource.js) | 3.41KB | 1.48KB |
| mobile (useBreakpoint.js) | 1.54KB | 0.65KB |
| mobile (useGesture.js) | 6.96KB | 1.98KB |
| mobile (useOfflineSync.js) | 1.99KB | 0.72KB |
| mobile (usePullToRefresh.js) | 2.53KB | 0.85KB |
| mobile (useResponsive.js) | 0.72KB | 0.42KB |
| mobile (useResponsiveConfig.js) | 1.37KB | 0.63KB |
| mobile (useSpecGesture.js) | 4.32KB | 1.64KB |
| mobile (useTouchTarget.js) | 1.01KB | 0.54KB |
| permissions (MePermissionsProvider.js) | 11.71KB | 4.29KB |
| permissions (PermissionContext.js) | 0.31KB | 0.25KB |
| permissions (PermissionGuard.js) | 0.89KB | 0.45KB |
| permissions (PermissionProvider.js) | 6.24KB | 2.16KB |
| permissions (discardProofCache.js) | 1.04KB | 0.55KB |
| permissions (evaluator.js) | 5.12KB | 1.74KB |
| permissions (index.js) | 0.93KB | 0.41KB |
| permissions (store.js) | 0.91KB | 0.42KB |
| permissions (useFieldPermissions.js) | 1.28KB | 0.53KB |
| permissions (usePermissions.js) | 4.83KB | 2.27KB |
| plugin-ai (index.js) | 15.75KB | 3.80KB |
| plugin-calendar (index.js) | 46.92KB | 12.93KB |
| plugin-charts (index.js) | 70.02KB | 19.44KB |
| plugin-chatbot (index.js) | 190.53KB | 45.18KB |
| plugin-dashboard (index.js) | 132.63KB | 34.56KB |
| plugin-designer (index.js) | 212.87KB | 43.19KB |
| plugin-detail (index.js) | 250.63KB | 63.90KB |
| plugin-editor (index.js) | 2.46KB | 1.10KB |
| plugin-form (index.js) | 132.78KB | 32.58KB |
| plugin-gantt (index.js) | 166.77KB | 40.76KB |
| plugin-grid (index.js) | 208.88KB | 56.59KB |
| plugin-kanban (index.js) | 53.21KB | 14.66KB |
| plugin-list (index.js) | 113.51KB | 27.67KB |
| plugin-map (index.js) | 20.20KB | 6.66KB |
| plugin-markdown (index.js) | 13.72KB | 4.69KB |
| plugin-report (index.js) | 43.51KB | 11.94KB |
| plugin-timeline (index.js) | 29.34KB | 8.47KB |
| plugin-tree (index.js) | 8.98KB | 3.08KB |
| plugin-view (index.js) | 85.90KB | 21.12KB |
| providers (DataSourceProvider.js) | 0.75KB | 0.39KB |
| providers (MetadataProvider.js) | 1.37KB | 0.59KB |
| providers (ThemeProvider.js) | 1.90KB | 0.85KB |
| providers (UploadProvider.js) | 11.66KB | 3.50KB |
| providers (index.js) | 0.45KB | 0.23KB |
| providers (types.js) | 0.01KB | 0.04KB |
| react-runtime (index.js) | 5.62KB | 2.34KB |
| react (LazyPluginLoader.js) | 4.47KB | 1.63KB |
| react (SchemaRenderer.js) | 81.07KB | 26.86KB |
| react (data-invalidation.js) | 5.05KB | 2.08KB |
| react (index.js) | 3.11KB | 1.48KB |
| react (schema-input.js) | 2.32KB | 1.24KB |
| react (spec-input.js) | 0.20KB | 0.18KB |
| sdui-parser (codegen.js) | 5.41KB | 2.34KB |
| sdui-parser (dashboard-widget-options.js) | 3.08KB | 1.30KB |
| sdui-parser (index.js) | 4.93KB | 2.24KB |
| sdui-parser (input-type.js) | 2.84KB | 1.40KB |
| sdui-parser (parse.js) | 20.57KB | 5.88KB |
| sdui-parser (provenance.js) | 3.66KB | 1.82KB |
| sdui-parser (types.js) | 0.28KB | 0.23KB |
| sdui-parser (validate.js) | 10.35KB | 3.60KB |
| types (ai.js) | 0.20KB | 0.17KB |
| types (api-types.js) | 0.20KB | 0.18KB |
| types (app.js) | 2.87KB | 0.99KB |
| types (base.js) | 0.20KB | 0.18KB |
| types (blocks.js) | 0.20KB | 0.18KB |
| types (complex.js) | 2.74KB | 1.41KB |
| types (crud.js) | 0.20KB | 0.18KB |
| types (dashboard-filter-alias.js) | 6.23KB | 2.74KB |
| types (data-display.js) | 3.75KB | 1.85KB |
| types (data-protocol.js) | 0.20KB | 0.19KB |
| types (data.js) | 0.20KB | 0.18KB |
| types (designer.js) | 1.85KB | 0.85KB |
| types (disclosure.js) | 0.20KB | 0.18KB |
| types (error-code.js) | 1.54KB | 0.88KB |
| types (feedback.js) | 0.20KB | 0.18KB |
| types (field-types.js) | 0.20KB | 0.18KB |
| types (form.js) | 0.20KB | 0.18KB |
| types (http-inflight.js) | 8.87KB | 3.73KB |
| types (http-retry.js) | 4.32KB | 2.02KB |
| types (icon-key-migration.js) | 4.26KB | 1.63KB |
| types (index.js) | 4.72KB | 2.24KB |
| types (layout.js) | 0.20KB | 0.18KB |
| types (managed-by.js) | 0.19KB | 0.18KB |
| types (mobile.js) | 2.59KB | 1.31KB |
| types (navigation.js) | 0.20KB | 0.18KB |
| types (objectql.js) | 0.20KB | 0.18KB |
| types (overlay.js) | 0.20KB | 0.18KB |
| types (permissions.js) | 0.20KB | 0.18KB |
| types (plugin-scope.js) | 0.20KB | 0.18KB |
| types (record-components.js) | 0.20KB | 0.19KB |
| types (record-semantics.js) | 1.28KB | 0.67KB |
| types (registry.js) | 0.20KB | 0.18KB |
| types (reports.js) | 0.20KB | 0.18KB |
| types (spec-report.js) | 5.05KB | 1.93KB |
| types (spec-ui-namespace.js) | 0.20KB | 0.19KB |
| types (system-fields.js) | 3.33KB | 1.54KB |
| types (theme.js) | 6.28KB | 2.87KB |
| types (ui-action.js) | 3.40KB | 1.71KB |
| types (views.js) | 0.20KB | 0.18KB |
| types (widget.js) | 0.20KB | 0.18KB |
Size Limits
- ✅ Core packages should be < 50KB gzipped
- ✅ Component packages should be < 100KB gzipped
⚠️ Plugin packages should be < 150KB gzipped
✅ 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
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#7239
The docs half of the #7087 ruling (maintainer, 2026-09-01, option 1 scoped to
disabled). That ruling removed the 18disabled?: booleannarrowings from the concrete schemas, so the member is now inherited fromBaseSchemaasboolean | string— a boolean, or a predicate expression on the same evaluated path asvisible. 13 component pages went on spelling the removed narrowing in their illustrative interfaces, teaching a type the shipped tree no longer has. A reader copying those rows would conclude thatdisabled: "${data.status === 'locked'}"is invalid, which is exactly the capability the ruling restored.Premise re-verified on the base, not taken from the card
Base
ebc05b4d6. Every one of the 22disabled?:rows undercontent/docs/componentswas attributed to its enclosing interface by walking back to the nearest declaration, rather than trusting the card's table — the table turned out to be exactly right, including the two files that carry one in-scope and one out-of-scope row each:disabledfromBaseSchemabasic/button-group.mdx(ButtonGroupSchema)booleanAll 13 in-scope interfaces were confirmed to
extends BaseSchemawith nodisabledof their own on this base, and all remainingdisabled?: booleandeclarations inpackages/types/srcwere confirmed to belong to independent shapes (ListItem,AccordionItem,ToggleGroupItem,SelectOptionMetadata,SelectOption,RadioOption,FormField,ComboboxOption,TabItem,NavLink,ButtonGroupButton,MenuCommandItem) — so the narrowings really are gone and the pages really were the stale side.Why a pin instead of a gate turning red-then-green
No gate can see this drift, and that was measured rather than assumed:
check-doc-snippet-types.mjscompiles only the fence languages in its ownTS_FENCE_LANGUAGESset (line 317:ts,tsx,typescript), and all 14 rows in question live inplaintextfences (13) or atextfence (1).check-doc-component-typesreads only thetypestring literals. So a member row in those fences may name any type at all and every gate stays green — the hole #6143 records.The new pin
packages/types/src/__tests__/component-docs-disabled-inherited-7239.test.ts(44 cases) therefore carries the invariant:disabledrow readsboolean | string, and the shipped interface of the same name still extendsBaseSchemawithout redeclaringdisabled. The second half is what keeps the pin honest in the other direction: a future re-narrowing fails pointing atpackages/types, not at the page, because in that world the page would be the thing that is right.boolean. This is the blanket-replace control: a sweep that rewrote everydisabled?: booleanundercontent/docs/componentsturns these red.disabled?:row undercontent/docs/componentsby measurement, so a new page carrying the stale spelling fails here instead of sitting unclassified.Boundary stated in the file rather than implied: the three overlay menu-item rows are doc-local names with no shipped counterpart (
ContextMenuCommandItem/DropdownMenuCommandItem/MenubarCommandItemagainst a shippedMenuCommandItem), so only their doc text is asserted.Bounded in-place fix, named with evidence
packages/types/src/__tests__/button-group-doc-surface-6347.test.tsheader said 13 of those 14 component schemas REDECLAREdisabled?: booleanthemselves … so their pages are right. After #7087 that sentence is false in both halves. The paragraph is rewritten to mark the 13-of-14 reading as history and point at the new pin. Comment text only — mechanically confirmed:git diff -U0on that file, with comment lines filtered out, is empty, and the file's assertions stay green in the run below (it is one of the 87 files in thepackages/typessuite).It qualifies as a bounded in-place fix on all four counts: same defect class as the card (a stale
disabled?: booleanreading left behind by #7087), mechanical with the correct shape pinned by the landed ruling, no other claim holds that file, and no new verification surface (it is already covered by thepackages/typessuite).Ablation — mutation and restore both proven on disk
The pin resolves nothing through any package
dist/(it imports onlyvitestandnode:fs/node:path/node:urland reads source files off disk), so no rebuild is involved in either leg; the mutations were confirmed by anchored text counts, not by an editor's exit code.wide_union_rows=0,bare_boolean_rows=15ButtonGroupSchemaand all 8 independent rows stayed greenform/select.mdxalone narrowedinjected_bare=1,removed_wide=0Expected: "form/select.mdx SelectSchema -> boolean | string"/Received: "... -> boolean"form/form.mdxFormFieldalone widened (blanket-replace control)injected_wide=1,removed_bare=0Expected: "form/form.mdx FormField -> boolean"/Received: "... -> boolean | string"Those results match the predictions written into the pin's header before the first run. Every restore leg used
git checkout HEAD -- ABSOLUTE_PATHunder atrap … EXIT INT TERMwith absolute paths, and was proven by blob hash rather than by an exit code: 13/13 and 2/2 disk hashes equal to theirHEADblobs, none empty, withgit diff HEADempty andgit status --porcelainclean afterwards.Verification — union run at
dd802b688on a clean treeTest Files 1 passed (1)/Tests 44 passed (44)packages/typessuiteTest Files 87 passed (87)/Tests 1221 passed (1221)@object-ui/typestype-check--listFilesontsconfig.test.jsonconfirms both touched test files are in the 543-file compiled set (tsconfig.jsonexcludes**/*.test.ts, so this was checked rather than assumed)check:doc-fences✅ check:doc-fences — every TypeScript block in 224 document(s) is fenced ts/tsx/typescript …check:doc-types✅ Every documented component type is registered.docs:check-linksLinks are valid across 17 scan roots.check:control-bytes✅ check-control-bytes: OK (scanned 6026 tracked text file(s); skipped 85 binary).check:docs-route-closure✅ MEASURED_PAYLOAD is honest …check-changeset-presence✅ 2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s) …check-changeset-no-major✅ No changeset declares amajorbump.check-governed-queue-guard --test✅ NOT GOVERNED — 16 path(s) checked against 5 governed surface(s); none matched.Declared narrowing —
check:doc-snippetswas not run locally. It exits 2, which its own output defines asPRECONDITION NOT MET … This is "I could not run", NOT "I ran and found errors" (exit 1): it needs a 25-package build first. The narrowing is backed by measurement, not convenience: (1) the population comes from the gate's ownTS_FENCE_LANGUAGESset rather than a guess about which files count; (2) 0 of the 14 changed doc rows are in that population — 13 sit inplaintextfences, 1 in atextfence; (3) the diff adds and removes no fence and changes no fence language (check:doc-fencesgreen), and the other two changed files are a comment-only test edit and a new test, neither of which is a document, so the gate's verdict on untouched files cannot move. CI runs it regardless.A changeset is owed and is included with empty frontmatter (declaring that nothing releases) — the two touched files under
packages/types/src/are published source, so the presence gate asks; its own text calls the empty-frontmatter form "a pass, not a workaround", and there is precedent in.changeset/theme-schema-doc-rewrite-5648.md.Staying draft for the PM to land.
#7087remains closed by its own PR and is only referenced here; nothing in this PR changespackages/typessource orcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01NRRumy89BYdW9ogbcdHTho
Generated by Claude Code
Generated by Claude Code