Uh oh!
There was an error while loading. Please reload this page.
fix(plugin-kanban,plugin-calendar): stop spelling the house drawer width as a renderer default - #6581
Conversation
…dth as a renderer default `min(960px, 60vw)` was a house default duplicated across the record-navigation drawers of three renderers. #6305 converged ObjectGantt only; kanban and calendar still carried the old shape at two sites each — the `navConfig` default and a render-site `?? 'min(960px, 60vw)'` fallback, the second of which would have kept the old width alive had only the first been taken. `width` is `@deprecated [#2578 -> size]` and `resolveOverlayWidth` gives an explicit `width` priority OVER `size`, so spelling it kept the deprecated branch load-bearing on the path most boards and calendars take (no declared `navigation`) and made the size buckets unreachable there. Omitting both leaves `resolveOverlayWidth` returning `undefined`, which is what RecordDetailDrawer's own `width` default is for; that default is the identical `min(960px, 60vw)`, so this is a zero-pixel change on every viewport. Not converged on `size: 'lg'`: that bucket is `min(92vw, 960px)`, up to 53% wider below a 1600px viewport. That move is a real behaviour change and stays open for a human ruling. Pinned by ObjectKanban.navWidthDefault.test.tsx and ObjectCalendar.navWidthDefault.test.tsx, both halves each, because the equivalence now depends on the drawer's own default too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011SfZeFWrhGLHmfq61xbz4q
…s releasing nothing Empty frontmatter, matching the precedent the gantt half of this convergence set: the resolved overlay width is unchanged on every viewport, so there is no published behaviour to describe. `check-changeset-presence.mjs` names the empty frontmatter as the explicit exemption and a complete answer to the gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011SfZeFWrhGLHmfq61xbz4q
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
os-support-ai
commented
Aug 26, 2026
ACCEPT on the diff. ⏸ Landing held until every check is green — 20 success / 3 skipped / 6 still running (4 test shards, Type Check, Lint), zero failures at The two ⛔ exclusions, verified from the file list rather than from the report
That second one is better than compliance: it carries the open half forward in the code, naming the card that owns it, which is the same convention All four sites converged, both copies in each file — kanban Why the test design is the strongest part
Restoration after both ablation legs was proved by byte identity — Independently checked by this seat
The escalation clauseIt was checked rather than assumed, and correctly did not fire: both renderers import Every line number in the dispatch matched Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#6303
Converges
ObjectKanbanandObjectCalendaron the shape #6305 gaveObjectGantt. Only the decidedwidthhalf; thesize: 'lg'bucket question is untouched and stays open on #6303 for a human ruling.The four sites
Each renderer carried two copies of the house default. Taking only the first would have left the old width alive by a different route — which is what the card was filed to prevent.
mainplugin-kanban/src/ObjectKanban.tsx(schema as any).navigation ?? { mode: 'drawer', width: 'min(960px, 60vw)' }(schema as any).navigation ?? { mode: 'drawer' }plugin-kanban/src/ObjectKanban.tsxwidth={(navigation.width as any) ?? 'min(960px, 60vw)'}width={navigation.width as any}plugin-calendar/src/ObjectCalendar.tsx(schema as any).navigation ?? { mode: 'drawer', width: 'min(960px, 60vw)' }(schema as any).navigation ?? { mode: 'drawer' }plugin-calendar/src/ObjectCalendar.tsxwidth={(navigation.width as any) ?? 'min(960px, 60vw)'}width={navigation.width as any}All four line numbers were re-measured on
origin/main@b1a732b22and matched the dispatch reading exactly. After this PR the literal survives in these two files only inside the explanatory comments;grepfinds no remaining producer.Why this is zero-pixel
widthis@deprecated [#2578 -> size]andresolveOverlayWidthgives an explicitwidthpriority oversize, so spelling it kept the deprecated branch load-bearing on the path most boards and calendars take (no declarednavigation) and made the size buckets unreachable there. With both copies omitted,resolveOverlayWidthreturnsundefinedandRecordDetailDrawer's ownwidthdefault supplies the identicalmin(960px, 60vw).The escalation clause was checked rather than assumed. Both renderers reach the drawer by the same path the gantt does —
import { RecordDetailDrawer } from '@object-ui/plugin-detail', rendered directly withwidth={…}— andresolveOverlayWidthreturnsundefined, nevernull, so the drawer's default parameter does apply.navConfig.widthandnavigation.widthhave no other consumer in either file. Nothing contradicts the zero-pixel finding.RecordDetailDrawer.tsxis not touched: it is the source the other three now delegate to, and:76-78carries the only written rationale for the value.Pin tests, both halves each
ObjectKanban.navWidthDefault.test.tsxandObjectCalendar.navWidthDefault.test.tsxmirrorObjectGantt.navWidthDefault.test.tsx's posture — half 1 (the renderer injects no width of its own) and half 2 (the width the real drawer then resolves is still the pinned value), because the equivalence depends on both. A third case pins the other direction: an authorednavigation.widthstill reaches the drawer unchanged, so the deprecated key stays accepted as an authored value.Reverse-verification — direction predicted first, then measured
Prediction: restoring the pre-fix expressions turns only half 1 red in each file. Half 2 and the authored-width control cannot see a re-added
??fallback — its value is the same string the drawer default produces — and that blind spot is exactly why half 1 exists.Leg A — both files restored to
b1a732b22(mutation proved on disk by grep counts of both the injected and the deleted text, not by an exit code):Both failures are
half 1; bothhalf 2and both authored-width controls stayed green. Matches the prediction exactly.Leg B — half 2's own load-bearing check:
RecordDetailDrawer's default temporarily moved tomin(900px, 55vw):Both failures are
half 2this time; bothhalf 1and the controls stayed green — so half 2 really measures the drawer's default rather than restating half 1.Both legs ran under a
trap … EXIT INT TERMwith absolute paths and were restored withgit checkout HEAD -- <path>. Restoration is proved by byte identity, not by an exit code:git diff HEADempty, and each file'sgit hash-objectback to the HEAD blob recorded before the mutation (ace66b96…,2592c8aa…,da15724a…).Gates — each gate's own printed verdict, exit code captured before any pipe
Measured at
d8814f129. The commit after the source commit adds.changeset/*.mdand nothing else (git diff 087514d61 d8814f129 --stat= 1 file), so the suite and lint runs measured a byte-identicalpackages/**.vitest run packages/plugin-kanban/ packages/plugin-calendar/Test Files 34 passed (34)·Tests 210 passed (210)d8814f129Test Files 2 passed (2)·Tests 6 passed (6)turbo run lint(whole repo, not narrowed)Tasks: 47 successful, 47 totaltype-check(both packages)packages/plugin-{kanban,calendar} type-check: Doneturbo run build(dependency closure)Tasks: 15 successful, 15 totalcheck-changeset-presence✅ … declares 1 changeset(s)check-changeset-no-major✅ No changeset declares a major bump.check-changeset-fixed✅ All workspace packages are in the changeset fixed group.check-changeset-overwrite✅ No pre-existing changeset was modified or deleted.check-control-bytes✅ OK (scanned 5435 tracked text file(s); skipped 85 binary).check-vi-mock-specifiers✅ OK (… 694 bare (out of scope) …)check-lint-coverage✅ lint coverage: 46/46 packages linted, 0 with outstanding errors (0 total).check-type-check-coverage✅ type-check coverage: 45/46 via type-check …check-package-self-import✅ No package names itself inside its own src/.check-phantom-dependencies✅ Every in-scope import is declared by the package that publishes it.The type-check green is proved to cover the new tests rather than merely coexist with them:
tsc -p tsconfig.test.json --listFilesfinds each new file as a program input (1 hit each). The two new files add 3@typescript-eslint/no-explicit-anywarnings each — the same rule the gantt pin test triggers;lint.yml:20deliberately sets no--max-warnings, and the error count is 0.Changeset
.changeset/kanban-calendar-nav-width-converge.md, empty frontmatter, matching what #6305 used for the gantt half.check-changeset-presence.mjsreports that as "declared as releasing nothing, which is the explicit exemption and a complete answer to this gate". The body says the change is zero-pixel rather than inventing a behaviour claim.Out of scope, deliberately
size: 'lg'on any renderer.min(92vw, 960px)agrees with the current default only at viewport >= 1600px and is up to 53% wider below it — a published-behaviour change, andmin(960px, 60vw)is a four-site house default, not one renderer's choice — thewidth/sizequestion on #6259 decides all of them #6303 stays open for it.RecordDetailDrawer.tsx, for the reason above.One check the card did not ask for: a repo-wide sweep for a fifth divergent renderer found none. All three
navConfigdefaults now read{ mode: 'drawer' }, andplugin-view/src/ObjectView.tsx(:1901,:1958) already passesnavigationConfig?.widthwith no literal fallback, so it delegates too.plugin-treeandplugin-mapuseuseNavigationOverlaybut spell no width. No new issues filed.Generated by Claude Code