Skip to content

fix(plugin-timeline): dates follow the active locale instead of hardcoded en-US (#4513) - #4523

Merged
yinlianghui merged 2 commits into
mainfrom
claude/issue-4513-timeline-locale
Aug 13, 2026
Merged

fix(plugin-timeline): dates follow the active locale instead of hardcoded en-US (#4513)#4523
yinlianghui merged 2 commits into
mainfrom
claude/issue-4513-timeline-locale

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Closes #4513

A zh console rendered a fully Chinese timeline widget whose axis read Aug 11 / Sep 2026. Nothing a user or a tenant configured could reach those dates.

The five sites (all verified on current main, no drift since the #4468 census)

anchor call zh before zh after
renderer.tsx:71 toLocaleString('en-US', { month, day, hour }) — hour gantt header Aug 11, 9 AM 8月11日 9时
renderer.tsx:77 toLocaleDateString('en-US', { month, day }) — day gantt header Aug 11 8月11日
renderer.tsx:108 toLocaleDateString('en-US', { month, year }) — month gantt header Aug 2026 2026年8月
renderer.tsx:157 toLocaleDateString()short item date 8/11/2026 2026/8/11
renderer.tsx:160 toLocaleDateString('en-US', { year, month, day })long item date August 11, 2026 2026年8月11日

:157 is the same defect spelled as an omission rather than a literal: a bare call means the machine's locale, so it agreed with the other four only by the accident of an en-US runner (this container resolves en-US, confirmed) and would render a third locale on anyone else's machine.

The fix — the established one-resolver

All five resolve through useDisplayLocale() from @object-ui/i18n (tenant regional default → active UI language → 'en'), the channel PR #4512 confirmed for all six @object-ui/fields sites. Intl accepts 'zh' verbatim, so there is no mapping table here or anywhere else.

Both date helpers are module-level functions and cannot host a hook, so the locale is read once in TimelineRenderer — above every variant's early return, so the hook count can never depend on variant — and threaded down to all seven call sites:

  • generateTimeScaleHeaders takes an optional trailing locale defaulting to 'en'. It is exported (index.tsx does export * from './renderer') and driven directly by the spec-parity test, so growing the signature was measured necessary — the alternative, a locale-less exported wrapper, would have left a second hardcoded channel inside the very function the card is about. Additive and back-compatible: existing three-argument callers keep compiling and keep producing byte-identical output, since 'en' and the retired 'en-US' agree at all three header sites.
  • the module-private formatDate takes it as a required parameter, so no future branch can silently reintroduce either wrong channel.

No other signature changed; TimelineRenderer's props are untouched.

Red-first, per site

Both test files were written against the unfixed renderer and re-run against origin/main after the fix as reverse verification. Predicted direction — zh red, en green — held exactly: 8 failed | 13 passed, and the 8 are precisely the zh sites plus the explicit-locale helper case. Verbatim pre-fix output:

AssertionError: expected 'ProjectsAug 11, 9 AMAug 11, 10 AMBackendAPI Design' to contain '8月11日 9时'
AssertionError: expected 'ProjectsAug 11Aug 12BackendAPI Design' to contain '8月11日'
AssertionError: expected 'ProjectsAug 2026Sep 2026BackendAPI Design' to contain '2026年8月'
AssertionError: expected '8/11/2026Beta ReleaseReleased beta version to testers' to contain '2026/8/11'
AssertionError: expected 'August 11, 2026Beta ReleaseReleased beta version to testers' to contain '2026年8月11日'
AssertionError: expected 'August 11, 2026Q3' to contain '2026年8月11日'          (horizontal variant)
AssertionError: expected 'API Design\nAugust 11, 2026 - Septemb…' to contain '2026年8月11日'  (gantt bar tooltip)
AssertionError: expected [ 'Aug 2026', 'Sep 2026' ] to deeply equal [ '2026年8月', '2026年9月' ]

After the fix: 45 passed (45) across all 6 files in the package.

Must-not-change (green on both sides)

  • English is byte-identical at every one of the five sites — pinned as its own en session block, and green before and after by construction.
  • Non-date rendering untouched: titles, descriptions, row labels, and the locale-free header vocabularies (Week n, Qn YYYY, YYYY).
  • dateFormat: 'iso' stays a machine format and does not become a locale one.
  • Channel precedence is the resolver's: an explicit tenant locale still outranks the active UI language, on the gantt axis as well as on item dates.

Two traps this card named

  • Machine-pinned expectations — none to move. No existing test in this package pinned bare-toLocale* output, so there is no respelling to do (the spec-parity test asserts only locale-free forms: Q1 2026, 2025, and non-empty length). The new fallback file spells its expectations 'en' explicitly rather than computing them from a bare call, so they cannot silently follow the runner the way the code under test used to.
  • Provider-less ordering (Mounting an I18nProvider in a test file silently changes what every LATER provider-less render in that file resolves #4514). The provider-less last-resort assertions live in their own file, timeline-date-locale-fallback.test.tsx, which mounts no I18nProvider at all — a provider-less render placed after a zh case in the same file would resolve 'zh' from react-i18next's global instance and assert test ordering rather than behavior. That file also states honestly that its rendered cases are green on both sides on an en-US runner and are therefore a must-not-change pin, not red-first evidence.

Grading

patch for @object-ui/plugin-timeline only — @object-ui/i18n is consumed, not changed. .d.ts measured both ways (build before, build after, diff), and the whole delta is one optional parameter:

-export declare function generateTimeScaleHeaders(scale: string, minDate: string, maxDate: string): string[];
+export declare function generateTimeScaleHeaders(scale: string, minDate: string, maxDate: string, locale?: string): string[];

Verification

Dependency closure built first; heavy runs serialized under the shared lock.

  • pnpm --filter '@object-ui/plugin-timeline^...' build — green
  • pnpm exec vitest run packages/plugin-timeline/ (repo root) — 45 passed (45), 6 files
  • npx tsc --noEmit — green; npx tsc -p tsconfig.test.json — green (both, per the package's type-check)
  • npx eslint . — 0 errors (68 pre-existing warnings, unchanged)
  • node scripts/check-control-bytes.mjs — OK, 4237 files; plus a targeted self-scan of the four changed files

Out of scope, filed

#4520 — the same renderer's Week n / Qn YYYY gantt headers and the 'Items' row-label default are hardcoded English strings. Same session, same surface, but they need the package's translate channel (useTimelineTranslation) rather than a locale tag, and they are vocabulary growth rather than a mechanical extension of this fix. No Intl call is involved, so the two edits are disjoint.


Generated by Claude Code

…oded en-US (#4513)

`renderer.tsx` passed a literal 'en-US' to four Intl calls (the hour, day and
month gantt headers, and the `long` item date) and passed nothing at all to a
fifth (the `short` item date), so a fully Chinese timeline rendered an English
axis and English item dates. The bare call is the same defect spelled as an
omission: no tag means the MACHINE's locale, which agreed with the other four
only by the accident of an en-US runner.

All five now resolve through `useDisplayLocale()` (tenant regional default →
active UI language → 'en'), the one channel objectui#4468 / PR #4512 converged
`@object-ui/fields` onto. The two date helpers are module-level functions, so
the locale is read once in `TimelineRenderer` and threaded down:
`generateTimeScaleHeaders` takes an optional trailing `locale` defaulting to
'en' (it is exported and driven directly by the spec-parity test), and the
module-private `formatDate` takes it as a required parameter so no future
branch can silently reintroduce either wrong channel.

English output is byte-identical at every site. The locale-free header
vocabularies (`Week n`, `Qn YYYY`, `YYYY`) are untouched — they need the
package's translate channel rather than a locale tag, filed as objectui#4520.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 13, 2026 4:23am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-aXqBuS2X.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 38.46KB 10.17KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.35KB 1.07KB
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.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 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.65KB 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) 489.32KB 108.45KB
core (index.js) 3.37KB 1.34KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 156.23KB 42.29KB
fields (index.js) 230.14KB 57.12KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 38.98KB 10.85KB
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.74KB
mobile (index.js) 1.50KB 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.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.41KB 1.44KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.86KB 12.91KB
plugin-charts (index.js) 62.07KB 17.65KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 120.95KB 31.53KB
plugin-designer (index.js) 212.58KB 42.83KB
plugin-detail (index.js) 239.88KB 59.99KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 114.58KB 27.68KB
plugin-gantt (index.js) 164.14KB 39.98KB
plugin-grid (index.js) 188.40KB 50.10KB
plugin-kanban (index.js) 48.62KB 13.42KB
plugin-list (index.js) 111.13KB 27.12KB
plugin-map (index.js) 18.16KB 5.81KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.16KB 10.96KB
plugin-timeline (index.js) 26.25KB 7.53KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.08KB 20.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.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 23.73KB 7.96KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.23KB 0.66KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
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) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 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-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
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 (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
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

`generateTimeScaleHeaders` is reachable from the package entry (`index.tsx`
does `export * from './renderer'`) and its published declaration grew an
optional trailing `locale?: string`. Entry-reachable additive API growth is
minor, not patch — patch is for changes with no API-surface movement at all.

`dist/index.d.ts` being byte-identical does not argue for patch: the entry
re-exports by reference, so the resolved public surface moved even though the
entry file's bytes did not. The contrapositive of #4496, which was graded patch
precisely because its .d.ts additions were NOT re-exported from the entry;
#4403 / #4177 / #4485 / #4495-regrade are the line this follows.

Additive and back-compatible is what minor means — no consumer breaks, existing
three-argument callers keep compiling and keep producing byte-identical output.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-6ngvBCBX.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 38.46KB 10.17KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.35KB 1.07KB
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.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 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.65KB 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) 489.32KB 108.45KB
core (index.js) 3.37KB 1.34KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 156.23KB 42.29KB
fields (index.js) 230.14KB 57.12KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 38.98KB 10.85KB
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.74KB
mobile (index.js) 1.50KB 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.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.41KB 1.44KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.86KB 12.91KB
plugin-charts (index.js) 62.07KB 17.65KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 120.95KB 31.53KB
plugin-designer (index.js) 212.58KB 42.83KB
plugin-detail (index.js) 239.88KB 59.99KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 114.58KB 27.68KB
plugin-gantt (index.js) 164.14KB 39.98KB
plugin-grid (index.js) 188.40KB 50.10KB
plugin-kanban (index.js) 48.62KB 13.42KB
plugin-list (index.js) 111.13KB 27.12KB
plugin-map (index.js) 18.16KB 5.81KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.16KB 10.96KB
plugin-timeline (index.js) 26.25KB 7.53KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.08KB 20.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.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 23.73KB 7.96KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.23KB 0.66KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
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) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 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-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
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 (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
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

@yinlianghui
yinlianghui marked this pull request as ready for review August 13, 2026 04:38

Copy link
Copy Markdown
Collaborator Author

PM step-7 复核 — ACCEPT (session_017Qqyix2QcnpUC9XeYVDzx3)

Auto-merge armed (squash).


Generated by Claude Code


Generated by Claude Code

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

plugin-timeline hardcodes 'en-US' at four date sites, so timeline headers stay English on every non-English session

2 participants