Skip to content

fix(plugin-form,console): the form family's feedback chrome resolves through the i18n catalogue (objectui#11039) - #11066

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-11039-form-chrome-i18n
Sep 29, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-11039-form-chrome-i18n

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #11039
Clause-②: no

What

The form family's own feedback chrome now resolves through the i18n catalogue instead of English literals: the default success toast, the note it carries when a declared navigateOnSuccess was refused, the thank-you heading, the loading line, the load-failure heading, and the default submit and cancel labels. plugin-form goes through createSafeTranslation: a new shared hook in formChrome.ts (read by ObjectForm's default arm, TabbedForm, SplitForm and MasterDetailForm) and the tables WizardForm, DrawerForm and ModalForm already had. pnpm check:i18n-keys holds every table to the en pack, so a provider-less host still renders English. The console's FormPage uses the console's own hook, useObjectTranslation, with the same pack keys; main.tsx mounts the I18nProvider above every console route.

An authored value still wins, and it is untouched: each default sits behind the same || / ?? as before, after objectui#11050's resolution of the seven I18nLabel members (a locale map, or a plain string). No schema key is added, renamed or retyped.

The enumeration (on origin/main at 6466a09df, after PR 11050)

English default, as it was Where Author key that overrides it Key now
Created / Saved success toast default arm (three toasts, plus the confirmation after a refused redirect), WizardForm (the same four) successMessage; a thank-you behaviour's message form.created / form.saved (new)
Created, Saved, and "TITLE saved" MasterDetailForm's built-in save toast (shown only without a host onSuccess) title names the record; no message key form.created, form.saved, form.savedNamed (new, {{title}})
the refused-navigation note default arm, WizardForm none: chrome form.navigateRefused (new)
Thanks! default arm, WizardForm a thank-you behaviour's title publicForm.thankYouTitle (existing)
Loading form... default arm, TabbedForm, SplitForm, WizardForm, DrawerForm none publicForm.loading (existing)
Error loading form those five and ModalForm none form.errorLoading (new)
Create / Update submit label default arm (both render branches), TabbedForm, SplitForm, DrawerForm, ModalForm submitText form.create / form.update (existing)
Cancel DrawerForm, ModalForm cancelText common.cancel (existing)
Save / Create / Cancel MasterDetailForm submitText / cancelText common.save / form.create / common.cancel (existing)
Loading… FormPage none common.loading (existing)
Submitted toast FormPage none form.submitted (new)
Thanks! (two panels) FormPage the form's thank-you title publicForm.thankYouTitle
Your submission has been received. (two panels) FormPage the form's thank-you message publicForm.thankYouMessage (existing)

The card named the toast, Thanks!, the loading line, the load-failure heading and the note. The submit and cancel defaults are the same class in the same files (the brief's example); FormPage's loading line, its Submitted toast and the message under its Thanks! are the card's classes in the card's file. Beyond this line, see Acceptance notes.

Keys: reused where one already meant the same thing

  • publicForm.loading (Loading form…), publicForm.thankYouTitle and publicForm.thankYouMessage were in all ten packs with nothing reading them: pnpm check:i18n-dead-keys listed all three as confirmed dead at the merge base. They say exactly this, so they are reused, and they are off that list now (105 confirmed dead before, 102 after).
  • form.saveSuccess (Saved successfully, also confirmed dead) is not reused for the toast: it has no no-argument create twin (form.createSuccess takes {{object}}), so reusing it would either pair Created with Saved successfully or rewrite both toasts' English on every form. form.created / form.saved keep the toast byte-identical in English.
  • MasterDetailForm's edit Save is common.save, not form.saveRecord: seven packs word form.saveRecord as "save record" (de Datensatz speichern), while this button's English is the plain verb, which common.save is in every pack.
  • No existing key says "Error loading form"; form.errorLoading follows grid.errorLoading.

NAVIGATE_ON_SUCCESS_REFUSED_NOTE: an end user sees it, so it joins

It is passed as the description of toast.success(...) (sonner, through @object-ui/components), which renders under the toast's title, so the submitter reads it. Its own doc block says so ("What the submitter is told"), quoting the maintainer ruling of 2026-08-17: "the success toast carries a note that the declared navigation was not performed". The zh pin reads it on the toast (red on the base). The constant still exists: it is now read from the formChrome.ts table, so it has one spelling, and WizardForm re-exports it, because the tests import it from there. navigateOnSuccess stays as written in every pack, since it is the key's name.

Wording

zh: 已创建, 已保存, "TITLE已保存", 已提交, 表单加载失败, and 此表单声明的 navigateOnSuccess 跳转目标被拒绝,因此未执行跳转。 The reused keys read 正在加载表单…, 感谢您的提交! and 我们已成功收到您的信息。 The zh publicForm.thankYouTitle changes its ASCII ! to the full-width !, the zh pack's punctuation, now that a form shows it. The other eight packs follow each pack's own neighbours (form.createSuccess, grid.errorLoading, publicForm.loading). No new value carries an ellipsis; the reused publicForm.loading has U+2026 in all ten packs.

Three English strings change their rendered text, each because it is now a key whose English differs from the old literal. The changeset says so:

  • Loading form... becomes Loading form… (U+2026);
  • Thanks! becomes Thank you! (default arm, WizardForm, FormPage);
  • FormPage's Your submission has been received. becomes Your submission has been received successfully.

Every other English default renders the same text as before.

Pins

  • packages/plugin-form/src/formChrome.i18n-11039.test.tsx: 29 cases through ObjectForm under a real I18nProvider. Each zh case first waits for a probe outside the form to read the zh pack. The zh loading line in the simple, tabbed, split, wizard and drawer forms; the zh load-failure heading in all six; 创建 / 更新 in simple, tabbed, split, drawer and modal; 取消 in drawer and modal; 已创建 (simple, wizard) and 已保存 (simple edit) toasts; the zh thank-you heading (simple, wizard); and the zh note on a refused navigateOnSuccess (simple, wizard). Three CONTROL cases: an I18nLabel map successMessage with a plain submitText; a map submitText with a plain successMessage on a wizard, whose toast keeps the authored message and carries the zh note; and an authored thank-you title with a map cancelText. Plus an en case: Loading form…, Error loading form, Create, Created with the English note, and Thank you!.
  • apps/console/src/components/FormPage.chromeI18n-11039.test.tsx: 5 cases on the real /f/:slug route, with nothing wrapped around it: the zh loading line 加载中…, the zh toast 已提交, the zh thank-you heading and message, a CONTROL with a declared thank-you title and message, and en.

Red leg, at 80db9c47a. The eight edited containers (ObjectForm, WizardForm, TabbedForm, SplitForm, DrawerForm, ModalForm, MasterDetailForm, FormPage) were replaced by their merge-base blobs, each hash-checked on disk (t('form.errorLoading') in ObjectForm.tsx went from 1 to 0, and the Loading form... literal came back). Everything else stayed at HEAD. Over the two pins and the eight moved fixture files: 43 failed, 52 passed. The formChrome pin: 27 of 29 fail. Two CONTROL cases pass, because authored values always won, so they are the must-not-change guards. The wizard CONTROL fails only on the note, which is chrome. The FormPage pin: 4 of 5 fail, and its CONTROL passes. The script restored with git checkout HEAD -- under a trap, verified every file against its HEAD blob hash, and read an empty git diff HEAD. Green at the same head: 29 and 5 passed.

Fixtures that moved with the change (pin updates, not regressions)

  • ObjectForm.i18nLabels.test.tsx (zh): the create button is 创建, and the nothing-authored control's toast is 已创建.
  • MasterDetailForm.i18nLabels.test.tsx (zh): the toasts read 采购单已保存 and PO已保存, and the nothing-authored control reads 创建, 取消, 保存 and 已保存.
  • ObjectForm.submitRedirect.test.tsx, WizardForm.submitRedirect.test.tsx: Thank you!.
  • FormPage.submit, .outcomeToast, .recordId, .redirect: each now installs the en catalogue the way the app does (createI18n, whose global the harness resets after every test), and asserts the new message. The negative assertions moved to the new string too; left alone they would have passed vacuously.
  • examples/schema-catalog/test/catalog-gallery-render.test.tsx: FORM_LOADING is Loading form…. Its wait is negative (not.toContain), so the old literal would not have turned red: it would have silently stopped waiting. The comment's stale cross-file line citation is now a content citation.

Also: the pending objectui#10935 changeset said the master-detail defaults "are still English". Its prose now says this change moves them; its frontmatter is untouched (check-changeset-overwrite reports it under its case 2, a deliberate correction; report-only). The object-master-detail-form registry descriptions of submitText / cancelText now say the default is in the active UI language.

Verification (all at 80db9c47a)

  • pnpm exec vitest run packages/i18n/ packages/plugin-form/: Test Files 216 passed (216), Tests 2910 passed, 14 skipped. This includes all-locales-key-parity, en-zh-key-parity, ellipsis-glyph-3878, untranslated-identity-4376, de-quote-pairing-3876 and raw-key-call-sites-3546.
  • pnpm exec vitest run apps/console/: Test Files 131 passed (131), Tests 1475 passed.
  • packages/plugin-view/, plus app-shell's ObjectFormDesigner.test.tsx and RecordFormPage.i18n.test.tsx, plus the gallery test: 63 files, 1207 passed.
  • scripts/__tests__, derived with git grep -l -E over the touched names and paths (the form files, FormPage, formChrome, i18n/src/locales, plugin-form/src, .changeset, schema-catalog, apps/console/src/components): 46 files, Tests 2171 passed.
  • Type-check: @object-ui/i18n and @object-ui/plugin-form Done, and @object-ui/console exit 0, each after building its dependency closure. tsc -p tsconfig.test.json --listFilesOnly lists the plugin-form pin, and the console's --listFilesOnly lists its pin.
  • pnpm check:i18n-keys exit 0 (37 factory tables, 912 rows, 912 matching). pnpm check:i18n-drift exit 0 (0 en values changed, 6 keys added). pnpm check:control-bytes OK. pnpm check:new-line-citations: 0 new. node scripts/check-changeset-presence.mjs, pnpm changeset:check and pnpm check:pending-changeset-literals pass. pnpm check:changeset-claims (report-only) names seven pending changesets that mention a touched file (6237-wizard-step-config-split, 6661-app-launcher-nav-menu-renderers, 8738-object-form-fields-description, and four console-form… ones). All re-read, all still true: each is about another aspect of those files.
  • eslint on the 31 touched ts/tsx files (--format json reports 31): with inline config honoured, as each package's lint runs, 0 errors and 210 warnings; with --no-inline-config, 1 error and 217 warnings, and those per-file counts equal the merge-base blobs linted the same way through --stdin --stdin-filename. The one error is an existing, inline-suppressed react-hooks/static-components in FormPage's widget row. The narrowing excludes nothing: the population is the changed files from the diff against the merge base, eslint.config.js sets no parserOptions.project or projectService (no type-aware linting), and no rule under eslint-rules/ reads a file, so this diff cannot move a verdict on an untouched file.

Bundle

Console built at the merge-base sources and at HEAD: the sources were swapped, rebuilt, restored and rebuilt, and a marker was checked in dist both ways. The eager closure is 330 of 2446 chunks both times, so no chunk entered it, and 3,181,419 became 3,181,741 bytes gzipped (+322; raw +1,788). By chunk: i18n-locale-en +241 raw / +82 gzipped (the en pack), plugin-form +1,471 / +252, index (FormPage) +76 / −7. No new external module entered either chunk: FormPage already imported @object-ui/i18n, and the new formChrome.ts imports only createSafeTranslation, which plugin-form already did. check-eager-closure-budget: 3107.2 KB of 3149.4 KB (headroom 42.2 KB, 42.6 KB at the base). check-eager-locale-catalogues: exactly one eager catalogue, en.

Acceptance notes

Left English on purpose. Each is chrome, not a default behind an author key the card named, and each is noted rather than widened into here:

  • FormPage: the submit button's Submit / Submitting… / Uploading…, Redirecting…, and the Required: … refusal. The zh pin submits through that English Submit under a zh catalogue.
  • MasterDetailForm's line-item chrome: Loading columns…, Subtotal, Tax (…%), Total, Line item — row N, Apply, Add, and Saving… on its Save button.
  • ModalForm's master-detail dialog: its sr-only description, Enter the record and its line items, then save.
  • ObjectForm's field-security hint, You do not have edit access to this field.
  • EmbeddableForm takes its chrome from host-supplied texts (the publicForm.* vocabulary in public-forms.md), which is a different mechanism.

No README or content/docs page describes these defaults (grepped for the literals; the one Thanks! in public-forms.md is an authored title in an example), so no docs change is due.

Dispatched dev run for the domain:ui seat #1, session session_01DuWo5bdP9SdVebamn99GGk, claim comment 5885696581.


Generated by Claude Code

…8n catalogue (objectui#11039)

The success toast, the refused-navigation note, the thank-you heading, the
loading line, the load-failure heading and the default submit and cancel
labels of the form family now read the locale packs instead of English
literals. Authored values still win.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk
…h fixtures (objectui#11039)

A zh-CN render of each default, container by container, with authored-override
controls (an I18nLabel map and a plain string) and an en control. The
fixtures that asserted the old English literals, or the old English defaults
under a zh provider, move with the change.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk
Patch for plugin-form, i18n and the console. The pending objectui#10935
changeset no longer says the master-detail defaults stay English. The pin
headers state the measured red leg.

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

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 7 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/6237-wizard-step-config-split.md

  • names WizardForm.tsx → packages/plugin-form/src/WizardForm.tsx — edited by this change

    WizardStepConfig is now declared independently in WizardForm.tsx, which is simply what SplitFormSectionConfig, ModalFormSectionConfig and DrawerFormSectionConfig already do: each layout owns its group shape, documents className / gridClassName in its own terms, and declares visibleWhen only where its renderer honours it. The derivation flips from subtractive to additive — a key is authorable on a wizard step only if someone writes it there.

.changeset/6661-app-launcher-nav-menu-renderers.md

  • names en.ts → packages/i18n/src/locales/en.ts — edited by this change

    Three new strings — the launcher's and the menu's accessible names, and the menu's empty state — are declared under console.nav in en.ts and its nine sibling packs. An inline defaultValue alone is not a fix: it renders English at one call site and leaves the string untranslatable everywhere (objectui#3517).

.changeset/8738-object-form-fields-description.md

  • names ObjectForm.tsx → packages/plugin-form/src/ObjectForm.tsx — edited by this change

    The registration declared { name: 'fields', type: 'array' } with no description, so an author had nowhere to read that this key's members are bare field names — a different vocabulary from sections[].fields, which also accepts the spec FormFieldSchema object (identity key field, e.g. { field: 'note', colSpan: 2 }). Moving one of those objects to the top-level fields resolves to no name and is skipped by SimpleObjectForm (ObjectForm.tsx) and by buildFlatFields (flatFields.ts, shared by the drawer/modal presentations). Behaviour is unchanged by this entry; it only adds the description text an author would need to avoid the drop before writing it.

.changeset/console-form-container-specs-one-declaration-5596.md

  • names FormPage.tsx → apps/console/src/components/FormPage.tsx — edited by this change

    objectui#5542 converged the LEAF of this contract — the field spec — and left the two containers above it untouched, because converging them was a bigger call than a mechanical import. FormSectionSpec and FormViewSpec were each hand-declared twice under the same names, once in packages/app-shell's SchemaForm.tsx and once in apps/console's FormPage.tsx. Unlike the leaf — whose console copy was a clean subset — these two had already drifted, in both directions, so neither copy was a subset of the other and there were two live answers to "what may an author write":

.changeset/console-form-field-spec-one-declaration-5542.md

  • names FormPage.tsx → apps/console/src/components/FormPage.tsx — edited by this change

    objectui#5040 was not a missing key. It was that two hand-written descriptions of one contract drifted, and nothing could notice, because each was only ever checked against itself. PR metadata-admin: FormFieldSpec declares dependsOn, one declaration for both halves #5537 converged the two app-shell descriptions into views/metadata-admin/form-spec.ts. A third survived in apps/console: FormPage.tsx declared its own nine-key interface FormFieldSpec, under the same name, in a different package — so the same failure mode stayed fully available.

.changeset/console-formpage-runtime-default-seed-5727.md

  • names apps/console/src/components/FormPage.tsx → apps/console/src/components/FormPage.tsx — edited by this change

    readPrefill in apps/console/src/components/FormPage.tsx seeded every declared default unconditionally. A defaultValue may be a literal, or an instruction the server resolves per insert — a DEFAULT_VALUE_TOKENS token (NOW(), current_user) or a CEL Expression envelope. Seeding one of those literally put the text NOW() into a datetime input on both /forms/:name and the public /f/:slug route, and submitting it sent that string as the field's value — which is neither absent nor null, so ObjectQL.applyFieldDefaults never resolved the declared default and the column stored the token text instead of a timestamp.

.changeset/console-formpage-visible-predicates-5594.md

  • names apps/console/src/components/FormPage.tsx → apps/console/src/components/FormPage.tsx — edited by this change

    apps/console/src/components/FormPage.tsx is a second, independent form renderer — its own buildSections, its own JSX — and it serves both the public /f/:slug route and the internal /forms/:name route. It read neither spelling of the FormView field visibility predicate: a repo-wide grep for a visibleWhen / visibleOn read inside that file returned zero. So a field an author conditioned on record.priority == 'urgent' — legal, spec-strict metadata that @objectstack/spec normalises to visibleWhen (ADR-0089), and that the metadata-admin designer both authors and honours — rendered unconditionally on both routes. Fail-open and silent: the author saw the field always, with no diagnostic.

  • names FormPage.tsx → apps/console/src/components/FormPage.tsx — edited by this change

    objectui#2212 recorded this exact symptom and PR fix(form): evaluate view-level FormField.visibleOn with the canonical CEL engine #2214 fixed it — in a different chain: ModalForm → resolveFormViewLayout → @object-ui/plugin-form sectionFields.ts → @object-ui/components renderers/form/form.tsx. FormPage.tsx is on that chain at no point, and Form-view FormField.visibleOn (CEL) is never evaluated — conditional fields always render #2212's regression pin lives with the chain it fixed, so nothing in the suite could see this copy. One contract, two implementations, each only ever checked against itself.

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 827550193 (merge-base with origin/main): 31 file(s) changed outside .changeset/, read against 1734 pending declaration(s) that publish a body (2338 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3107.2 KB 3149.4 KB
Main entry chunk (gzip) 149.3 KB 350 KB
Entry file index-CxIobnRI.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.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
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) 27.13KB 7.95KB
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) 558.92KB 133.97KB
core (index.js) 9.94KB 3.94KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 227.99KB 63.22KB
fields (index.js) 261.01KB 66.28KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.35KB 9.18KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.32KB 11.09KB
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) 6.62KB 2.45KB
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.58KB 4.90KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.25KB 2.17KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
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) 16.01KB 3.93KB
plugin-calendar (index.js) 52.33KB 15.01KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 137.68KB 36.71KB
plugin-designer (index.js) 215.78KB 44.42KB
plugin-detail (index.js) 233.54KB 61.80KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 169.60KB 43.32KB
plugin-gantt (index.js) 171.12KB 42.43KB
plugin-grid (index.js) 228.33KB 62.59KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 115.86KB 28.64KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 31.07KB 9.15KB
plugin-tree (index.js) 11.21KB 3.89KB
plugin-view (index.js) 89.77KB 22.55KB
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.81KB 3.58KB
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) 119.16KB 39.05KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 7.50KB 3.05KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.16KB 2.71KB
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.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 19.75KB 6.81KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 3.83KB 1.49KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
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.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
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) 19.30KB 6.99KB
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

1 participant