Skip to content

fix(app-shell): keep a labelable element on every control picker's catalog-failure arm - #9995

Merged
os-tesla merged 1 commit into
mainfrom
claude/issue-9931-picker-failure-arm-labelable
Sep 19, 2026
Merged

os-tesla merged 1 commit into
mainfrom
claude/issue-9931-picker-failure-arm-labelable

Conversation

@os-tesla

Copy link
Copy Markdown
Collaborator

Fixes #9931

PickerLoadFailure is a div[role="status"]. Four widgets the WIDGET_LABELLING table declares labelling: 'control' rendered it INSTEAD of their picker when the option catalog failed to load, so the id FieldRow hands a 'control' widget landed on no element at all: the visible label's for attribute dangled and the field had no accessible name — in the CARD layout as well as in a grid cell, which is the worse half, because there the label is right on screen and points at nothing.

⚠️ Angle-bracket-shaped fragments are spelled out in words throughout this body (LABEL element, for attribute, BUTTON) — GitHub's body sanitizer eats them, including inside backticks and fences.

1. The 'control' population, DERIVED — ⛔ not taken from the card's four

Read on edbcf1e7a, this branch's base and the same commit the claim measured.

The derivation is two mechanical steps:

  1. the 'control' set is whatever Object.entries(WIDGET_LABELLING).filter(([, v]) => v === 'control') returns. On this base that is eleven keys: ref:object, ref:component, object-selector, field-selector, field-ref, filter-builder, view-ref, icon, color-input, string-tags, secret;
  2. the catalog-failure arms are whatever grep -n "status === 'error'" -e loadError finds in widgets.tsx. Every one of them renders PickerLoadFailure; there is no second failure shape in the file.

⭐ The claim's reading that PickerLoadFailure has eleven occurrences is confirmed and resolved: one is the declaration, ten are render sites. Six are on 'control' widgets, four on 'group' ones — so the six the card's body assumed are the six, and the other four are ⛔ not this card's business:

render site on edbcf1e7a widget declared labelable element on that arm, on this base
widgets.tsx:401 ref:object control YES — the banner renders beside a freeform Input carrying controlNaming
widgets.tsx:656 object-selector control NO
widgets.tsx:854 field-selector control NO
widgets.tsx:1380 field-ref control NO
widgets.tsx:1457 view-ref control NO
widgets.tsx:1605 field-multi group n/a — the named role="group" container still renders and the banner decorates it
widgets.tsx:2014 filter-mode (fields) group n/a — same
widgets.tsx:2090 filter-mode (tabs) group n/a — same
widgets.tsx:2143 action-multi group n/a — same
widgets.tsx:2290 filter-builder control YES — the failure renders inside the popover; the trigger BUTTON that carries controlNaming renders on every arm

no fifth 'control' widget has an unnamed failure arm, and none of the card's four is mis-declared. The other five 'control' keys read no catalog at all, so they have no failure arm to check — which the new pin asserts rather than assumes: it renders all eleven with every catalog failed.

Rejected on the record, per the stop condition: ref:object and filter-builder already rendered a labelable element on their failure arm on this base. Neither is touched, and both are still asserted here so the repair cannot quietly regress them.

2. Re-taken line numbers (all on edbcf1e7a)

the card says on edbcf1e7a
object-selector :593 :656
field-selector :790 :854
field-ref :1316 :1380
view-ref :1393 :1457
widgets.tsx:2793, the 'control' docblock parenthetical unmoved:2793
SchemaForm.tsx:1606 labelAssociation unmovedconst labelAssociation = groupLabelled ? { id: labelId } : { htmlFor: id };
CONTROL: WIDGET_LABELLING occurrences in widgets.tsx 7 — instrument lit, matches the claim

These addresses are a dated reading on a named commit and are ⛔ not written into any source file: the comments this PR adds cite by symbol name and card number only.

3. ⭐ The fork: reading (a) — a VIOLATION, ⛔ not a contract gap

Quoted verbatim from the 'control' half's own docblock on edbcf1e7a:

The widget puts id on the ONE labelable element that is the field's primary control, in EVERY branch it can render (loading, empty-catalog, read-only)

Four readings decided it — two from the text, two from what the other 'control' branches actually do:

  1. The quantifier is the rule, and the parenthetical cannot be the scope without erasing it. The same docblock says so in as many words: "In every branch" is the load-bearing half. A three-item list cannot be the meaning of a phrase the paragraph itself calls load-bearing.
  2. The membership test the docblock applies is the universal, not the list. field-multi and action-multi are excluded from 'control' because they were measured DANGLING in the read-only one — dangling in ONE arm disqualifies a widget, whichever arm that is. Read as exhaustive, the list would let a widget that dangles in a FOURTH arm keep the declaration — exactly the state this card found — and the table would then assert "the host label reaches a labelable element" about widgets where it provably does not. A reading that makes the declaration false about its own members is not the reading.
  3. ref:object is the counter-example already in the file. It is the one 'control' picker whose failure arm was authored with the naming on it, under a comment reasoning about that arm specifically: "The freeform input is kept, and enabled, so a failed catalog does not also block authoring." filter-builder likewise keeps its named trigger in every arm. Under (b) both would be doing unrequired work; under (a) they are simply the two that already comply — which is why the card could point at them as the shapes to copy.
  4. The branch already carries a SECOND in-file contract. PickerLoadFailure's own docblock states the invariant the four violate: "Every picker keeps whatever control lets the author see and edit the value already stored, because a failed catalog must not also block authoring." A branch two independent declarations govern is ⛔ not an uncovered branch.

⛔ The sub-option triage offered — put the id on PickerLoadFailure's container and make it labelable — is unavailable, and that is worth stating rather than leaving implied: the container is a DIV, and the for attribute addresses only labelable elements (INPUT / TEXTAREA / SELECT / BUTTON / METER / OUTPUT / PROGRESS). Making that container labelable means not being a DIV.

What moved in the contract text, and what did not. The parenthetical now names the failed-catalog branch, so the examples match the rule they gloss, and a short paragraph records the settled reading and points at the new pin as the instrument that re-derives it. That is a record, ⛔ not (b) performed quietly: the rule phrase in EVERY branch it can render is unchanged, no key changed labelling, and WIDGET_LABELLING itself is untouched.

4. The repair shape — the ref:object shape for all four, ⛔ never the filter-builder shape

The card named this as the decision, not a detail of it. All four take the editable-anchor shape, and the reason is written in each widget's own comment:

  • field-ref / view-ref — the banner now renders beside a freeform Input carrying controlNaming, showing the stored name and editable unless readOnly. Same stored shape (one name) and same situation as ref:object's error arm, so this is that arm copied rather than a shape invented here.
  • object-selector / field-selector — the selected chips already answer see and remove; what the arm had no way to do at all was add. The freeform entry is that arm's primary control: chips beside one entry box that takes controlNaming, which is string-tags' shape in this same file. It commits on Enter or blur and writes the SAME value shape the picker writes — an array when multiple, a bare name otherwise — so a name typed while the catalog is unknown round-trips exactly like a picked one.

The picker itself is still not rendered on any of the four. field-selector's own comment argues against it — "with no options it could only render as a dead, disabled dropdown next to a banner saying the options are unknown, which is the very conflation this arm exists to end" — and objectui#5227's pin asserts no combobox on that arm. A disabled trigger would have undone objectui#5170's repair and turned that pin red.

No new i18n keys. The new inputs carry no placeholder, exactly as ref:object's error-arm input carries none. i18n.ts sits outside the declared file face and was not touched.

SchemaForm.tsx was read as evidence and ⛔ not edited — the fix needed nothing outside the declared face, so there is no stop-and-report here.

5. ⭐ Acceptance: the RED leg, and the SUCCESS leg that stayed green beside it

New pin: packages/app-shell/src/views/metadata-admin/__tests__/SchemaForm.controlWidgetFailureArmNaming-9931.test.tsx, 34 assertions. Its first test asserts the case table equals the 'control' key set read off WIDGET_LABELLING, so the population is derived at run time and a twelfth 'control' widget cannot be added without a reading here.

The ablation was run from the committed fix, so the restore had a real commit to come back to. The source file was reverted to its pre-fix blob on disk and both directions were proven by blob hash, ⛔ never by an exit code:

blob HEAD  (fixed)     3040ca18a2e10381c7d90c788ef0c3b031e5c79f
blob BASE  (pre-fix)   1056270d40b66af4dcb3d8bf80a136ea7f42594e
worktree after mutation  1056270d…  == pre-fix blob   MUTATION LANDED
worktree after restore   3040ca18…  == HEAD blob      RESTORE PROVEN
git diff HEAD after restore: empty
controlNaming call sites on disk: 24 (fixed) -> 20 (mutated) -> 24 (restored)

RED legTest Files 1 failed (1) · Tests 8 failed | 26 passed (34). Exactly the four in-scope arms, in BOTH layouts:

x object-selector — the host label names a labelable element on the failure arm
x field-selector  — the host label names a labelable element on the failure arm
x field-ref       — the host label names a labelable element on the failure arm
x view-ref        — the host label names a labelable element on the failure arm
x object-selector — the cell control answers the column-header IDREF
x field-selector  — the cell control answers the column-header IDREF
x field-ref       — the cell control answers the column-header IDREF
x view-ref        — the cell control answers the column-header IDREF

AssertionError: object-selector: the host id is on NO element — the visible
label's `for` dangles: expected null not to be null

GREEN in that same run — this is what makes the eight reds a measurement rather than a switch being flipped, and it is the half objectui#9889 lost:

  • the SUCCESS leg: the same eleven keys with every catalog LOADED, named the same way, with no failure block anywhere and no second naming channel;
  • the ARM LEDGER: the PickerLoadFailure each key renders on a failed catalog, read off the DOM and compared with the declared column. A widget that stopped entering its failure arm goes red here even while the naming assertions go green — which is exactly the "the check was switched off" move this lane already paid for once;
  • ref:object and filter-builder in both layouts — the two rejected-on-the-record arms, which must stay named.

With the fix restored: Test Files 1 passed (1) · Tests 34 passed (34).

6. What was run

run verdict
the new pin alone Test Files 1 passed (1) · Tests 34 passed (34)
35 affected test files (derived by git grep -l for importers of widgets / SchemaForm, the -load-failed test ids and WIDGET_LABELLING) Test Files 35 passed (35) · Tests 397 passed (397)
pnpm --filter @object-ui/app-shell run type-check (tsc --noEmit and tsc -p tsconfig.test.json, so the new test file is covered) exit 0, after pnpm --filter '@object-ui/app-shell^...' build — the first attempt was a PREREQUISITE NOT MET (unbuilt workspace .d.ts), ⛔ not a red gate
pnpm --filter @object-ui/app-shell run lint exit 0 — 0 errors (3044 pre-existing warnings, none on the added lines)
node scripts/check-changeset-presence.mjs 1 released-package source file changed, 1 changeset declared
check:control-bytes, check:new-line-citations, check:test-path-roots, check:changeset-claims, check:pending-changeset-literals, check:vi-mock-specifiers, check:i18n-keys, check:unreferenced-sources all exit 0
node scripts/check-governed-queue-guard.mjs --test over the three changed paths NOT GOVERNED

Declared narrowing: the whole-repo turbo run lint and the full vitest run are CI's; what ran locally is the affected package's own lint and type-check plus the derived 35-file test set.

⚠️ NOT MEASURED: the chronology of the docblock parenthetical against the arrival of the failure arms. This checkout is shallow and git log -S resolves both strings to the shallow-boundary commit, which is an artifact and not a reading; a deepen of 300 commits did not reach that era. The fork above rests on the text and on the code, both of which are self-contained on this base.

⛔ Draft on purpose: ⛔ not marked ready, ⛔ not enqueued, ⛔ not merged.


Generated by Claude Code

…talog-failure arm

`PickerLoadFailure` is a `div[role="status"]`, and four widgets `WIDGET_LABELLING`
declares `labelling: 'control'` rendered it INSTEAD of their picker on a failed
catalog. The `id` `FieldRow` hands a `'control'` widget therefore landed on no
element, the visible label's `for` dangled, and the field had no accessible name
in the card layout as well as in a grid cell.

`object-selector`, `field-selector`, `field-ref` and `view-ref` now render the
failure banner beside a freeform entry that carries `controlNaming` and keeps the
stored value editable while the catalog is unknown -- the shape `ref:object`
already used on this arm. The picker itself is still not rendered there.

The `'control'` docblock names the failure branch in its list of example
branches; the rule it glosses ("in EVERY branch it can render") is unchanged and
no widget's declaration moved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq
@github-actions

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 11 address(es) in this pull request's own prose name a tree it replaced

Each was read from a tree this change itself moves, so a reader who follows it lands somewhere else. ⛔ Nothing here blocks and nothing here says the sentence is false — the question asked is arithmetic: does this diff move the line that number points at?

  • in this body, widgets.tsx:656 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:656 to :681

    | widgets.tsx:656 | object-selector | control | NO |

  • in this body, widgets.tsx:854 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:854 to :917

    | widgets.tsx:854 | field-selector | control | NO |

  • in this body, widgets.tsx:1380 — this change rewrites packages/app-shell/src/views/metadata-admin/widgets.tsx:1380

    | widgets.tsx:1380 | field-ref | control | NO |

  • in this body, widgets.tsx:1457 — this change rewrites packages/app-shell/src/views/metadata-admin/widgets.tsx:1457

    | widgets.tsx:1457 | view-ref | control | NO |

  • in this body, widgets.tsx:1605 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:1605 to :1720

    | widgets.tsx:1605 | field-multi | group | n/a — the named role="group" container still renders and the banner decorates it |

  • in this body, widgets.tsx:2014 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:2014 to :2129

    | widgets.tsx:2014 | filter-mode (fields) | group | n/a — same |

  • in this body, widgets.tsx:2090 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:2090 to :2205

    | widgets.tsx:2090 | filter-mode (tabs) | group | n/a — same |

  • in this body, widgets.tsx:2143 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:2143 to :2258

    | widgets.tsx:2143 | action-multi | group | n/a — same |

  • in this body, widgets.tsx:2290 — this change moves packages/app-shell/src/views/metadata-admin/widgets.tsx:2290 to :2405

    | widgets.tsx:2290 | filter-builder | control | YES — the failure renders inside the popover; the trigger BUTTON that carries controlNaming renders on every arm |

  • in this body, widgets.tsx:2793 — this change rewrites packages/app-shell/src/views/metadata-admin/widgets.tsx:2793

    | widgets.tsx:2793, the 'control' docblock parenthetical | unmoved:2793 |

  • in this body, :2793 — this change rewrites packages/app-shell/src/views/metadata-admin/widgets.tsx:2793

    | widgets.tsx:2793, the 'control' docblock parenthetical | unmoved:2793 |

The repair is not to correct the number. Changing :246 to :274 is true today and born false again on the next insertion — objectui#9509 states that before anything else. Bind the number to the tree it was read from (`:246` at `b8a006883d`, `:274` at this head), which cannot re-stale because each number names its own tree; or state a rule instead of a coordinate, the way objectui#9495 replaced a file count with "every file in git diff --name-only against the merge base".

⚠️ 3 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/7125-dashboard-empty-state-keys-retired.md

  • names widgets.tsxpackages/app-shell/src/views/metadata-admin/widgets.tsx — edited by this change

    Not touched: table.noRows ('No rows to display') and engine.form.noRows (packages/app-shell/src/views/metadata-admin/i18n.ts, read at widgets.tsx) — two different, same-named keys in different namespaces. Nor the comments in WidgetEmptyState.tsx, DatasetWidget.tsx, ObjectDataTable.tsx and PivotTable.tsx that record WHY three widgets with three strings became one shared empty state; the packs' own comment keeps that rationale and now names the retirement instead of a row that is gone.

.changeset/8218-studio-property-panel-de-developerize.md

  • names widgets.tsxpackages/app-shell/src/views/metadata-admin/widgets.tsx — edited by this change

    SchemaForm + widgets.tsx were written for an administrator editing metadata. Studio's interface panel renders the very same form for someone who has never seen a JSON Schema, so four developer habits landed inside an otherwise fully Chinese surface. Same cause, one pass:

.changeset/formfieldspec-dependson-5040.md

  • names widgets.tsxpackages/app-shell/src/views/metadata-admin/widgets.tsx — edited by this change

    FormFieldSpec — the authoring type for a metadata-admin form layout, the element type of FormSectionSpec.fields[] — did not declare dependsOn. widgets.tsx held a second, inline description of the same object as WidgetProps.fieldSpec, and that one did, because two registered widgets read it as their primary configuration: field-selector resolves dependsOn || reference || 'objectName' to decide whose field catalog to offer, and dynamic-config uses it to pick a sub-schema out of WidgetContext.dynamicSchemas. One value travelling down one channel, described twice, disagreeing on the one key that decides what those widgets show — so

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Compared the checked-out tree with edbcf1e7a (merge-base with origin/main): 2 file(s) changed outside .changeset/, read against 1203 pending declaration(s) that publish a body (1762 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3054.4 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-CUy1apLh.js
Status PASS

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

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
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) 11.08KB 4.58KB
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) 545.91KB 130.72KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 216.90KB 60.15KB
fields (index.js) 249.62KB 63.02KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
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.99KB 0.87KB
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 (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
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) 8.39KB 3.10KB
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) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.73KB 20.08KB
plugin-chatbot (index.js) 195.35KB 46.52KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 254.30KB 66.21KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 137.49KB 34.64KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 213.44KB 58.21KB
plugin-kanban (index.js) 48.10KB 14.94KB
plugin-list (index.js) 113.42KB 27.95KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.05KB 21.01KB
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) 109.04KB 36.08KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.38KB 1.98KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.74KB 2.54KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 15.71KB 5.30KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
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 (expression.js) 0.20KB 0.18KB
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.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
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 (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.04KB 5.36KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
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

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

Projects

None yet

2 participants