Skip to content

Commit 1434bb4

Browse files
feat(plugin-kanban)!: retire the unwired useColumnWidths hook and its storage key (objectui#8522) (#10549)
Fixes #8522 Clause-②: yes — a published export (`useColumnWidths` and its two types) is removed. Executes ruling `5810224713` (remove: reading 2 of the card, superseded and left behind). Dispatched by the `domain:ui` seat 2 PM; implemented by its `os-dev` in session `https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN`. ## What changed - `packages/plugin-kanban/src/useColumnWidths.ts` deleted: the hook, `UseColumnWidthsOptions`, `UseColumnWidthsReturn`, and its storage key `objectui:kanban-column-widths`. - `packages/plugin-kanban/src/index.tsx`: the three entry exports removed (the `useColumnWidths` value export and the two-type `export type` line). - `@object-ui/types` docblocks, comment-only hunks: - `complex.ts`, the bare-`kanban` retirement docblock: the "NOT retired" sentence no longer names the hook as a consumer. `KanbanCard` / `KanbanColumn` / `CardTemplate` keep the renderer and `CardTemplates` as consumers, and `ColumnWidthConfig` is recorded as having lost its one `plugin-kanban` reader to this card, which did not rule on the type. - `objectql.ts`, the `ObjectKanbanSchema` lane "member set is the READ set" paragraph: the hook is dropped from the list of read sites. The hook destructured `columns` as `_columns` and read no lane member, so the counted member set does not move. - `kanban-plugin-dialect-authoritative-7664.test.ts`: the pin-1 comment stops naming the hook. No assertion changed. - New pin `packages/plugin-kanban/src/__tests__/useColumnWidthsRetired-8522.test.ts`, following the `plugin-form` `entrySurface-6059` barrel-pin pattern (`import * as entry` + `Object.keys(entry)`) and the `spec-symbol-4650` compile-time `import('..').X` + `@ts-expect-error` pattern. - `.changeset/8522-retire-use-column-widths.md`: `'@object-ui/plugin-kanban': minor`, with a BREAKING body in migration terms. There is no `@object-ui/types` entry: `check-changeset-presence` asks for presence only, and the types hunks are comment-only. Its last migration bullet names objectui#7742. - `.changeset/7742-kanban-arm-batch70.md`, a pending changeset that this change falsifies, is reconciled here in prose only: - The sentences naming the `useColumnWidths` widths channel, and saying the prop and the hook consume the types, are scoped to "at this change". - A dated note (2026-09-25) records that the hook is retired (objectui#8522), that `ColumnWidthConfig` has no `plugin-kanban` reader, and that `CardTemplate` is still consumed by the `CardTemplates` component's `templates` prop. - The frontmatter is byte-identical: md5 of the frontmatter block is `b62313df8fb2af929fbe2c21c5ae3873` before and after. No tests were deleted. No test existed only to test the hook: the tracked tree had zero test importers of it. ## Premise, measured on `origin/main` `d461b0de8` - Readers. `git grep` over `packages apps examples content skills` found `useColumnWidths` 7 hits in 5 files, `UseColumnWidths` 4 hits in 2 files, and `kanban-column-widths` 1 hit in 1 file. Every hit was the hook's own file, the entry, the two docblocks, or the 7664 comment. On the same instrument, the control `useCrossSwimlaneMove` fired with 5 hits in 3 files. Zero readers holds. - Published surface. H3 answers yes. `@object-ui/plugin-kanban@17.6.0` from the npm registry exports the hook in its `dist/index.js` export list as `Ue as useColumnWidths`, and `dist/index.d.ts` re-exports it and both types. The storage-key literal is present in `dist/index.js` and `dist/index.umd.cjs`. That is why the changeset is written as a migration. - A tree-wide grep found one more carrier outside the file surface: the pending changeset `.changeset/7742-kanban-arm-batch70.md`. It names "a `useColumnWidths` hook option for widths" and says "the prop and the hook still consume the types". Both go false when this merges, and both would publish into the same release, so this PR reconciles it (see above). - A re-grep of every pending `.changeset/*.md` for `useColumnWidths`, `UseColumnWidths` and `kanban-column-widths` hits only 7742 and this PR's own changeset. - The control `CardTemplate` hits 3 files on the same instrument. - The two `7664-*` changesets that name `ColumnWidthConfig` claim only that it is declared and re-exported, which remains true. ## Verification The code legs below ran on `e62e390f4`. The only later commit, `8be30d7fc`, edits changeset prose only; the changeset gates were re-run on it. - Build, under the verify lock: `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-kanban...' build` printed `VERDICT command-exit 0`. The rebuilt `plugin-kanban/dist` has `useColumnWidths` 0 and `kanban-column-widths` 0 in `index.js`, `index.d.ts` and `index.umd.cjs`, and no `useColumnWidths.d.ts`. The control `useCrossSwimlaneMove` is 2 / 2 / 1. - `pnpm --filter @object-ui/plugin-kanban type-check` (`tsc --noEmit && tsc -p tsconfig.test.json`) exits 0. `tsc -p tsconfig.test.json --listFilesOnly` lists the new pin, so the compile-time half is compiled. - `pnpm --filter @object-ui/types type-check` (including `tsconfig.examples.json` and `tsconfig.test.json`) exits 0. - `pnpm exec vitest run --maxWorkers=2 packages/plugin-kanban/` reports `Test Files 61 passed (61)` and `Tests 412 passed (412)`. That is 61 tracked test files: 60 on base plus the new pin. - `pnpm exec vitest run --maxWorkers=2 packages/types/` reports `Test Files 233 passed (233)` and `Tests 5184 passed (5184)`. - Red on base. The base `index.tsx` and `useColumnWidths.ts` were written back onto disk. The landing was checked on disk: the entry had `useColumnWidths` twice and the hook file was present with its key. Under a `trap` restore: - vitest: `Tests 1 failed | 1 passed (2)`, with `AssertionError: expected [ 'KANBAN_UNCOLUMNED_ID', …(10) ] to not include 'useColumnWidths'`. The failure is the runtime pin; the type-only test is erased at runtime. - `tsc -p tsconfig.test.json` exits 2 with `error TS2578: Unused '@ts-expect-error' directive.` twice, once on each retired type query. - After restore, the `index.tsx` blob matches HEAD `7e09f2d92`, the hook file is absent, and `git diff HEAD` and `git status --porcelain` are both empty. - Changeset and prose gates, on `8be30d7fc`: - `node scripts/check-changeset-presence.mjs` printed `✅ 6 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)`. - `node scripts/check-changeset-overwrite.mjs` exited 0 (report-only). It printed `1 changeset(s) added, 1 modified, 0 deleted`. For 7742 it printed `declared at base: @object-ui/types: minor, @object-ui/plugin-kanban: minor` and `declares now: @object-ui/types: minor, @object-ui/plugin-kanban: minor`. - `node scripts/check-changeset-claims.mjs` exited 0 (report-only), reading `Corpus: 2 changeset(s) this change adds or modifies` with no self-contradiction. It listed 27 pending changesets that name `complex.ts` or `objectql.ts`; none of them names the hook. - `node scripts/check-pending-changeset-literals.mjs` printed `✅ No test source names a pending changeset`. - `node scripts/check-changeset-no-major.mjs` printed `✅ No changeset declares a major bump`. - `node scripts/check-new-cross-file-line-citations.mjs` printed `VERDICT new-cross-file-line-citations: 0 new citation(s)`. - `node scripts/check-control-bytes.mjs` passed. - Source gates, on `e62e390f4`. These exited 0: `check:unreferenced-sources`, `check:self-import`, `check:side-effects-array`, `check:handler-key-reads`, `check:entry-guard`, `check:phantom-deps`, `check:unused-deps`, `check:test-path-roots`, `check:vi-mock-specifiers`, `check:spec-symbols` and `check:esm-specifiers`. - `check:readme-exports` passed after the build. No README names any of the three removed exports. - ESLint on the 5 touched text files (`--no-inline-config --format json`): 0 errors. The 66 warnings are pre-existing `no-explicit-any` / `react-refresh` warnings in untouched lines, and there are none in the new pin. - NOT MEASURED: - `check:sdui-registration-pins`: it needs an `apps/console` build and exits 2 without one. No registration changed here. - `check:published-dist`: its turbo build of the whole workspace, `apps/console` included, was killed by my 300s timeout (exit 124). It was run outside the verify lock by mistake. That is declared to CI. ## Overlap The one `types/src/objectql.ts` hunk here is the one-line docblock edit in the `ObjectKanbanSchema` lane paragraph. objectui#10533 and #10522, which also edited that file while this PR was being written, have since merged, and this hunk still applies on `main`. At landing, the open PRs that edit `objectql.ts` are objectui#10550, #10546 and #8941, and all three are hunk-disjoint from this edit. ## Acceptance notes - After this change, `ColumnWidthConfig` (in `@object-ui/types`, re-exported by `plugin-kanban`, and mirrored by `ColumnWidthConfigSchema`) has no reader in `plugin-kanban`. The ruling named the hook, its exports and its key, not the type, so the type stays. Recorded here only: there is no reproducible defect, and nobody is known to own it next. - The 7664 pin-1 comment still says `KanbanColumn` / `KanbanCard` are consumed by `CardTemplates`. The `CardTemplates` component consumes `CardTemplate`, not those two. That wording predates this change and is kept, because the dispatch limits this file to removing the hook's name. --- _Generated by [Claude Code](https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f94cfa5 commit 1434bb4

8 files changed

Lines changed: 107 additions & 139 deletions

File tree

‎.changeset/7742-kanban-arm-batch70.md‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ failure objectui#7664's own first cut shipped at `onCardClick`.
2525
including tests: 0 hits / 0 files each, with `groupBy` (85 hits / 27 files),
2626
`cardTitle` (18/9) and `coverImageField` (17/3) firing as controls on the same
2727
instrument. An author who wrote `allowCollapse: true` validated green and got
28-
a board that never collapsed off that key. Each capability exists on a
29-
*different* channel, and the refusal message names it: a lane's own
30-
`columns[].collapsed` for collapsing, a `templates` component prop for card
31-
templates, a `useColumnWidths` hook option for widths. Wiring a board-level
32-
switch to any of them would be new behaviour and is not ordered here.
33-
`CardTemplate` and `ColumnWidthConfig` stay exported — the prop and the hook
34-
still consume the types.
28+
a board that never collapsed off that key. At this change, each capability
29+
existed on a *different* channel, and the refusal message named it: a lane's
30+
own `columns[].collapsed` for collapsing, a `templates` component prop for
31+
card templates, a `useColumnWidths` hook option for widths. Wiring a
32+
board-level switch to any of them would be new behaviour and is not ordered
33+
here. `CardTemplate` and `ColumnWidthConfig` stay exported — at this change,
34+
the prop and the hook consumed the types.
35+
36+
⚠️ **Dated note, 2026-09-25 — the `useColumnWidths` hook has since been
37+
retired (objectui#8522), so the widths channel named above no longer exists
38+
and `ColumnWidthConfig` has no `plugin-kanban` reader. `CardTemplate` is still
39+
consumed, by the `CardTemplates` component's `templates` prop.**
3540
- **`titleField`** — ⚠️ **not** an inertness retirement, and reading it as one
3641
gets the mechanism backwards. `ObjectKanban` still reads the key and the read
3742
stays, because the **sibling `object-kanban` arm declares it and keeps it**
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
'@object-ui/plugin-kanban': minor
3+
---
4+
5+
**BREAKING (scored `minor` per this repo's version-alignment convention)** —
6+
`useColumnWidths` is removed from `@object-ui/plugin-kanban`, together with its
7+
`UseColumnWidthsOptions` and `UseColumnWidthsReturn` types (objectui#8522,
8+
maintainer ruling: remove).
9+
10+
The hook kept per-column widths in `localStorage`, and no kanban board read
11+
them: a board sizes its lanes from its own width (`columnInlineStyle` in
12+
`KanbanImpl`, derived on every render), and no kanban component accepts a
13+
per-lane width. The published 17.6.0 entry exports the hook and both types, so
14+
an import of it compiled and ran while changing nothing on screen.
15+
16+
## Migration
17+
18+
- `import { useColumnWidths } from '@object-ui/plugin-kanban'`, and the type
19+
imports `UseColumnWidthsOptions` / `UseColumnWidthsReturn`, no longer resolve.
20+
Delete the import and the call. Nothing replaces the hook, and removing the
21+
call changes no rendered width, because no board ever consumed what it
22+
returned.
23+
- The `localStorage` key `objectui:kanban-column-widths` (and its per-board form,
24+
that key followed by `:` and the `storageKey` you passed) is no longer written
25+
or read by any package. Values already stored in a browser are inert; remove
26+
them if you want the storage back.
27+
- `ColumnWidthConfig` stays exported from `@object-ui/types` and from this
28+
package. This change does not retire it.
29+
- The objectui#7742 entry in this same release (batch #70, the `kanban` arm)
30+
names a `useColumnWidths` hook option as the channel for column widths. That
31+
channel is gone with this change, and no other channel replaces it. This
32+
change adds a dated note to that entry saying so, leaving its declaration
33+
untouched.

‎packages/plugin-kanban/src/__tests__/kanban-plugin-dialect-authoritative-7664.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ type _RegistryIsReal = Assert<Equal<IsAny<SchemaRegistry>, false>>;
7272
// `Equal` is invariant, so a re-declared twin that drifted by one member
7373
// turns this red. (`KanbanSchema` was the third member of this row until
7474
// objectui#8802 retired it with the bare `kanban` node key; the two that
75-
// remain are consumed by `KanbanImpl`, `CardTemplates` and `useColumnWidths`
76-
// and are NOT retired.)
75+
// remain are consumed by `KanbanImpl` and `CardTemplates` and are NOT
76+
// retired.)
7777
type _ColumnIsTheDeclaredOne = Assert<Equal<KanbanColumn, DeclaredKanbanColumn>>;
7878
type _CardIsTheDeclaredOne = Assert<Equal<KanbanCard, DeclaredKanbanCard>>;
7979

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* ObjectUI
3+
* Copyright (c) 2024-present ObjectStack Inc.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
/**
10+
* objectui#8522 — `useColumnWidths` is RETIRED from the package entry.
11+
*
12+
* The hook kept per-column widths in `localStorage` and no board read it: the
13+
* rendered lane width comes from `KanbanImpl`'s `columnInlineStyle`, derived
14+
* from the board's own width on every render. Ruled remove (a published
15+
* capability with zero consumers retires immediately); the hook, its two option
16+
* and return types, and its storage key went with it. ⛔ Resizable lanes are
17+
* not rebuilt to keep it alive; if they are ever wanted, they come back as
18+
* their own feature.
19+
*
20+
* What this pins is the entry's SHAPE, both halves:
21+
*
22+
* - runtime: the hook name is not an own key of the module namespace, with a
23+
* sibling hook exported the same way and the board renderer as firing
24+
* controls on the same probe;
25+
* - compile time: the two type names do not resolve through the entry, with a
26+
* sibling hook's return type resolving through the same type query as the
27+
* control. Compiled by this package's `tsconfig.test.json` (chained off
28+
* `type-check`); an export that comes back fails there with
29+
* "Unused '@ts-expect-error' directive".
30+
*/
31+
32+
import { describe, expect, it } from 'vitest';
33+
import * as entry from '../index';
34+
35+
describe('@object-ui/plugin-kanban entry — useColumnWidths retired (objectui#8522)', () => {
36+
it('no longer exports the hook, while live exports on the same probe still resolve', () => {
37+
const keys = Object.keys(entry);
38+
expect(keys).not.toContain('useColumnWidths');
39+
// Firing controls: a hook exported the same way, and the board renderer.
40+
// Without them an empty or mis-resolved namespace would pass the line above.
41+
expect(typeof (entry as Record<string, unknown>).useCrossSwimlaneMove).toBe('function');
42+
expect(keys).toContain('ObjectKanbanRenderer');
43+
});
44+
45+
it('no longer exports the hook option and return types', () => {
46+
// @ts-expect-error retired with the hook (objectui#8522). If the export
47+
// comes back, tsc fails with "Unused '@ts-expect-error' directive".
48+
type _OptionsRetired = import('../index').UseColumnWidthsOptions;
49+
// @ts-expect-error retired with the hook (objectui#8522), as above.
50+
type _ReturnRetired = import('../index').UseColumnWidthsReturn;
51+
// Control: the same type query resolves a sibling hook's return type, so
52+
// the two errors above are readings of the entry and not of a bad path.
53+
type _SiblingResolves = import('../index').UseCrossSwimlaneMoveReturn;
54+
});
55+
});

‎packages/plugin-kanban/src/index.tsx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,6 @@ export { InlineQuickAdd } from './InlineQuickAdd';
212212
export type { InlineQuickAddProps } from './InlineQuickAdd';
213213
export { CardTemplates } from './CardTemplates';
214214
export type { CardTemplatesProps } from './CardTemplates';
215-
export { useColumnWidths } from './useColumnWidths';
216-
export type { UseColumnWidthsOptions, UseColumnWidthsReturn } from './useColumnWidths';
217215
export { useCrossSwimlaneMove } from './useCrossSwimlaneMove';
218216
export type { Swimlane, CrossSwimlaneMoveEvent, UseCrossSwimlaneOptions, UseCrossSwimlaneMoveReturn } from './useCrossSwimlaneMove';
219217
export { useQuickAddReorder } from './useQuickAddReorder';

‎packages/plugin-kanban/src/useColumnWidths.ts‎

Lines changed: 0 additions & 125 deletions
This file was deleted.

‎packages/types/src/complex.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ export interface KanbanColumn {
246246
* documents.
247247
*
248248
* {@link KanbanCard}, {@link KanbanColumn}, {@link CardTemplate} and
249-
* {@link ColumnWidthConfig} are NOT retired — the renderer, the `CardTemplates`
250-
* component and the `useColumnWidths` hook still consume them.
249+
* {@link ColumnWidthConfig} are NOT retired — the renderer and the
250+
* `CardTemplates` component still consume the first three. The one
251+
* `plugin-kanban` reader of {@link ColumnWidthConfig} was removed by
252+
* objectui#8522, whose ruling did not reach the type itself.
251253
*
252254
* Pinned in `./__tests__/bare-kanban-node-key-retired-8802.test.ts`.
253255
*/

‎packages/types/src/objectql.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3738,7 +3738,7 @@ export interface ObjectKanbanSchema extends BaseSchema {
37383738
*
37393739
* `id` / `title` / `cards` / `limit` / `className` / `collapsed` are exactly
37403740
* the lane members the two board implementations read, counted off
3741-
* `KanbanImpl`, `KanbanEnhanced`, `useColumnWidths`, `useCrossSwimlaneMove`,
3741+
* `KanbanImpl`, `KanbanEnhanced`, `useCrossSwimlaneMove`,
37423742
* `useQuickAddReorder` and `bucketCardsIntoColumns`. Their VALUE types come
37433743
* from those read sites too — see {@link id} for the one this card had to
37443744
* correct.

0 commit comments

Comments
 (0)