Skip to content

fix(i18n): key the kanban / tree / view record-detail headings (#3459) - #3464

Merged
yinlianghui merged 2 commits into
mainfrom
claude/issue-3459-overlay-titles-remaining
Aug 6, 2026
Merged

fix(i18n): key the kanban / tree / view record-detail headings (#3459)#3464
yinlianghui merged 2 commits into
mainfrom
claude/issue-3459-overlay-titles-remaining

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3459

#3426(PR #3457)修了 ListView / ObjectGrid;同一把 grep 找到的另外三处宿主同样在 TypeScript 里拼英文标题,于是 zh/ja/de 会话拿到一个通体本地化的浮层、顶上挂一句英文。

一、先证伪:三处的可达性逐个重判(#3426 标准)

立单者未核验,派发要求先做判定。三处都在 origin/main 上跑了真实交互测试(渲染块 → 点卡片/行 → 读标题),不是看代码推断。结论两处如立单所述,一处的前提要修正:

站点 可达? 门槛
ObjectKanban 最低。navConfig 在 schema 不写 navigation默认 { mode: 'drawer' },每张卡的 onCardClick 直连 navigation.handleClick —— 页面里放个 object-kanban(公开页面块)就能开出这个抽屉
ObjectTree ,但更窄 必须显式编写 navigation: { mode: 'drawer' }(无默认),且只在独立渲染时;ListView 传自己的 onRowClick,两个宿主都不向下转发 navigationobject-tree 也不在 PUBLIC_BLOCKS 里 —— 是渲染能力而非编写词表
ObjectView(mode: 'split') navigation 是该注册项声明过的可编写输入({ name: 'navigation', type: 'object' }),handleRowClickmode === 'split' 下置 isFormOpenlayout 到不了:ObjectViewSchema.layout 是 `'drawer'

app-shell 的 ObjectView 包装器钉 layout: 'page' 并给 onNavigate,ListView 传自己的 onRowClick —— 都是宿主覆盖已注册的块,不是分支死掉(与 #3457 的判词一致)。

立单前提的两处修正(kanban)

  1. 消费者不是 NavigationOverlay,是 RecordDetailDrawer(来自 @object-ui/plugin-detail)。所以「resolvedTitle = title || t('detail.recordDetail') 默认值永不生效」这条论据对 kanban 不成立 —— 那里压根不经过 NavigationOverlay
  2. 不是可见标题RecordDetailDrawertitle 渲染进 SheetHeader className="sr-only"SheetTitle,可见标题由 DetailView 自己的 HeaderHighlight 画。所以这串字是浮层对读屏器的可访问名。缺陷依然成立(zh 会话下读屏器只被告知一句英文),而且同一个文件早就因为同样的理由把 resize handle 的 aria-label 接进了语言包(objectstack#5733);但断言写的是 toHaveAccessibleName,不是「找一个可见标题」,因为代码渲染的就是前者。

'Card Details' 那条分支是死的

const detailTitle = schema.objectName ? `${...} Detail` : 'Card Details';
...
if (!objectName || recordId == null) return null;   // ← 消费它的 IIFE,同一个条件

'Card Details' 只在 !schema.objectName 时产生,而消费它的 IIFE 在同一条件return null。实测:不带 objectName 渲染看板、点卡片,queryByRole('dialog')null,浮层根本不开。

处置:照样 key 化,但刻意不给它写断言 —— 那样的断言会「因为什么都没渲染」而通过,不是因为逻辑对。改为把「无 objectName 时压根不开浮层」这个事实本身钉成测试。死分支本身另立观察单 #3463

二、改动

三处都改走既有的 detail.* 两个 key:有标签走 detail.recordDetailWithLabel({{label}} Detail,让各语言包自己决定语序 —— de 用连字符复合、ja/zh 需要助词),无标签复用 detail.recordDetail(NavigationOverlay 自己兜底的那个 key)。

新增语言包 key:零个。 两个 key 在 #3457 已进十包,复用它们才能保证一个控件一句翻译、不各自漂移。

每个插件各自建英文兜底表(KANBAN_DEFAULT_TRANSLATIONS / TREE_DEFAULT_TRANSLATIONS / VIEW_DEFAULT_TRANSLATIONS),给无 I18nProvider 的宿主用;@object-ui/plugin-tree 为此新增了对 @object-ui/i18n 的依赖。

kanban 没有复用文件里已有的 tt(useSafeTranslate):它的签名是 tt(key, fallback),没有 options 参数,{{label}} 会原样进 DOM。

三、可见英文变化(明确列出)

一处,刻意的:tree 浮层标题 Record DetailsRecord Detail。按维护者对 #3459 的裁定(Option A:复数拼写归一到单数 detail.recordDetail 家族,一个控件一句翻译,不为复数另开 key)。这也是 NavigationOverlay 自己兜底、以及整个 detail.* 家族已经在用的拼写。

依赖前先 grep 过:全仓 Record Details / Card Details 三处命中,e2e/ 零命中,单元测试零命中;第三处是 plugin-detail/src/index.tsx 的注册面板 label,与浮层标题无关,未动。

kanban 的 Card Details 不计入可见变化 —— 见上,那条分支不可达,用户看不到任何差别。

其余每个分支英文逐字节不变(Contacts Detail / Support cases Detail / Contacts Detail),有无 provider 都一样。

四、验证(仓根跑,方向先预测后执行)

pnpm exec vitest run packages/plugin-kanban packages/plugin-tree packages/plugin-view \
  packages/i18n/src/__tests__/all-locales-key-parity.test.ts \
  packages/i18n/src/__tests__/en-zh-key-parity.test.ts --maxWorkers=2
→ Test Files  21 passed (21)      Tests  163 passed (163)

pnpm --workspace-concurrency=2 --filter @object-ui/plugin-{kanban,tree,view} type-check  → 3× Done
pnpm --workspace-concurrency=2 --filter @object-ui/plugin-{kanban,tree,view} lint        → 0 errors(仅既有 warning)
pnpm --workspace-concurrency=2 --filter @object-ui/plugin-{kanban,tree,view} build       → 3× built
node scripts/check-control-bytes.mjs   → OK(3659 个文本文件)
node scripts/check-changeset-no-major.mjs → 无 major

反向验证:三份源文件 git checkout origin/main -- 回退后重跑

预测与实测完全一致,20 条断言 11 红 9 绿:

断言 预测 实测(回退后)
kanban zh / ja / de 红 —— Expected accessible name: Contacts详情 / Received: Contacts Detail
view zh / ja / de 红 —— Unable to find an element with the text: 联系人详情
tree zh / ja / de
tree en(复数→单数,刻意) 红 —— Unable to find an element with the text: Record Detail
tree 无 provider en 红(同上,刻意)
kanban en ×2 / 记录标题优先 / 死分支 绿 绿
kanban 无 provider ×2 绿 绿
view en / view 无 provider ×2 绿 绿

注意 tree 的两条 en 断言是本 PR 唯一「改前绿改后也该绿」不成立的地方,而这是裁定的结果不是回归 —— 模板预设的「en 逐字节不变」在这一处不适用,如实标出。

无 provider 的英文兜底按要求每个包各自独立成文件(initReactI18next 把实例注册成模块全局,活过 cleanup(),与 provider 用例同文件会静默解析到上一个语言)。

五、围栏

未越界。未动 packages/components(NavigationOverlay 一行没改)、content/docs/releases/packages/specpackages/i18n/src/locales/*(零新 key)。

改动清单:三个插件源文件 + 六个测试文件 + plugin-treepackage.json/vite.config.ts(新依赖)+ pnpm-lock.yaml(仅该依赖一行)+ 一个 changeset(patch × 3,fixed 组约定,未声明 major)。

六、顺手发现,已另立单(未在本 PR 修)


Generated by Claude Code

#3426 (PR #3457) keyed ListView and ObjectGrid; the same grep found three
more hosts string-building an English heading in TypeScript, so the
surrounding drawer/panel was fully localized with one English phrase on it.

All three were re-verified against origin/main before implementing, each
with a test that drives the real interaction rather than by inspection:

- ObjectKanban — reachable, and needs no authoring at all: navConfig
  DEFAULTS to `{ mode: 'drawer' }` and every card's onCardClick is wired to
  navigation.handleClick. Two premise corrections: the consumer is
  RecordDetailDrawer, not NavigationOverlay, and its title renders as an
  sr-only SheetTitle — the drawer's accessible name, not a visible heading.
- ObjectTree — reachable, but only with `navigation` authored explicitly
  (no default) and only standalone; ListView passes its own onRowClick and
  neither host forwards `navigation`.
- ObjectView (mode 'split') — reachable; `navigation` is a declared
  authorable input and `layout` cannot reach the branch
  (ObjectViewSchema.layout excludes 'split', deriveRecordSurface never
  returns it). app-shell pins layout 'page', a host override.

Zero new locale keys: `detail.recordDetail` and
`detail.recordDetailWithLabel` already ship in all ten packs from #3457,
and reusing them keeps one heading on one control. Each plugin gains its
own English defaults map for the provider-less path; plugin-tree gains a
dependency on @object-ui/i18n for it.

Visible English change, one, deliberate: the tree overlay goes from the
plural `Record Details` to the singular `Record Detail` (maintainer ruling
on #3459 — normalize the strays, do not mint a plural key). A repo-wide
grep found no e2e spec and no unit test addressing the old string. Every
other branch is byte-identical with and without a provider.

The kanban's other plural (`'Card Details'`) is NOT a visible change: that
branch fires only when schema.objectName is falsy, while the drawer
consuming it returns null on the same condition. Keyed anyway so the
literal cannot leak if the guard relaxes; deliberately untested, with the
deadness itself pinned instead.

Reverse-verified by restoring all three files to origin/main: 11 of 20
assertions go red (kanban zh/ja/de, view zh/ja/de, tree en+zh/ja/de, tree
no-provider en) and 9 stay green (every byte-identical English branch).

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

vercel Bot commented Aug 6, 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 6, 2026 7:27am

Request Review

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

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

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.47KB 3.09KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
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) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
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) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 21.35KB 5.70KB
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) 5.30KB 2.24KB
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) 479.63KB 105.43KB
core (index.js) 2.47KB 0.91KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 136.23KB 34.75KB
fields (index.js) 229.92KB 56.48KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.53KB 10.71KB
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.05KB 1.53KB
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.71KB 3.79KB
plugin-calendar (index.js) 44.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 112.03KB 28.88KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.53KB 57.37KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 111.54KB 26.97KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 185.25KB 49.08KB
plugin-kanban (index.js) 48.03KB 13.22KB
plugin-list (index.js) 105.19KB 25.39KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.85KB 20.50KB
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) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
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 (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) 2.46KB 1.21KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 0.20KB 0.18KB
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

`KanbanRenderer` renders `React.lazy(() => import('./KanbanImpl'))` behind a
Suspense boundary, and every assertion in the two new overlay-heading files
sits AFTER that boundary — a card must be on screen before it can be clicked.
That is exactly the flake class AGENTS.md §测试纪律 describes: an unbounded
module load charged to a bounded `findBy` window (a first `import()` measured
at ~976ms against RTL's 1000ms default under full CI parallelism).

Moving the import to module scope pays the cost in the import phase, which no
test/hook timeout constrains. The specifier is byte-identical to `./index`'s
so ESM resolves both to one cache entry and the component's own lazy factory
settles immediately — not `beforeAll`, which is bound by the NARROWER 10s
hookTimeout.

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

Copy link
Copy Markdown
Collaborator Author

补一个提交 e6f85d7 与一条顺手发现,供 review 时一并看:

追加提交:两个看板测试在模块作用域预载 ./KanbanImpl

写完才意识到本 PR 新增的两个 kanban 测试踩在 AGENTS.md §测试纪律 的头号 flaky 成因上:KanbanRenderer 渲染 React.lazy(() => import('./KanbanImpl')),而这两个文件的每一条断言都在那道 Suspense 边界之后(卡片得先上屏才点得动),于是首包动态 import 被记进 RTL findBy 的 1000ms 预算 —— 实测满并行下一次首包 import 可达 976ms,占掉 97.6%。

按纪律移到模块作用域(不是 beforeAll —— 那受更窄的 10s hookTimeout 约束,且已被 object-ui/no-dynamic-import-in-test-hook 机械禁止),specifier 与 ./index 里的逐字节一致以命中同一个 ESM 缓存条目。

tree / view 两个包不需要:ObjectTree 全静态,ObjectView 静态 import ObjectGrid,都没有 lazy 边界。

追加发现 #3465(finding,不进队列)

同包既有的 KanbanRenderer.uncolumned.test.tsx 第 42 / 60 行是同一个形状,没有这条预载,heavyDomTests 也兜不住(vitest.setup.dom.tsx 没有 side-effect import plugin-kanban,且 ./index 只登记工厂不预热)。同包另两个文件已核过不受影响。目前没记录显示它红过,所以是潜在竞态而非已发生的失败 —— 未在本 PR 顺手改,以免越出 #3459 的围栏。


Generated by Claude Code

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

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

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.47KB 3.09KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
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) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
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) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 21.35KB 5.70KB
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) 5.30KB 2.24KB
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) 479.63KB 105.43KB
core (index.js) 2.47KB 0.91KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 136.23KB 34.75KB
fields (index.js) 229.92KB 56.48KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.53KB 10.71KB
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.05KB 1.53KB
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.71KB 3.79KB
plugin-calendar (index.js) 44.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 112.03KB 28.88KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.53KB 57.37KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 111.54KB 26.97KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 185.25KB 49.08KB
plugin-kanban (index.js) 48.03KB 13.22KB
plugin-list (index.js) 105.19KB 25.39KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.85KB 20.50KB
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) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
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 (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) 2.46KB 1.21KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 0.20KB 0.18KB
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

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.

[i18n] 另外三个插件也自拼英文标题传给 NavigationOverlay 的 title prop(kanban / tree / plugin-view),#3426 的围栏没覆盖到

2 participants