Skip to content

Commit 195a651

Browse files
authored
refactor(spec-bridge): derive list-view bridge types from @objectstack/spec/ui (#2231 follow-up) (#2636)
Retires the third hand-written copy of the ListView shape: the SpecBridge list-view bridge's local ListViewSpec/ListColumn interfaces are replaced by Partial<ListView> and ListColumn from @objectstack/spec/ui, so the bridge input can no longer drift from the protocol. Behavior fix surfaced by the real types: spec columns is string[] | ListColumn[]; bare field-name columns previously mapped to a broken { accessorKey: undefined } and now map to a default column.
1 parent ca0f5f0 commit 195a651

2 files changed

Lines changed: 29 additions & 65 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@object-ui/react": patch
3+
---
4+
5+
refactor(spec-bridge): retire the hand-written `ListViewSpec`/`ListColumn` mirrors in the list-view bridge (#2231 follow-up)
6+
7+
The SpecBridge's list-view bridge kept a third hand-written copy of the ListView shape
8+
(after the zod schema and the TS interface unified in the previous #2231 PR). It now
9+
derives its input type from `@objectstack/spec/ui` (`Partial<ListView>`, spec `ListColumn`),
10+
so the bridge can no longer drift from the protocol.
11+
12+
Behavior fix surfaced by the real types: spec `columns` is `string[] | ListColumn[]`, but
13+
the old local interface only admitted `ListColumn[]` — a bare field-name column would have
14+
produced a broken `{ accessorKey: undefined }` mapping. String columns now map to a default
15+
column (`{ accessorKey: field, header: field }`).

packages/react/src/spec-bridge/bridges/list-view.ts

Lines changed: 14 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -8,74 +8,23 @@
88

99
import type { SchemaNode } from '@object-ui/core';
1010
import type { BridgeContext, BridgeFn } from '../types';
11-
import type { ListViewGalleryConfig, ListViewTimelineConfig } from '@object-ui/types';
11+
import type { ListView, ListColumn } from '@objectstack/spec/ui';
1212

13-
interface ListColumn {
14-
field: string;
15-
label?: string;
16-
width?: number;
17-
align?: string;
18-
hidden?: boolean;
19-
sortable?: boolean;
20-
resizable?: boolean;
21-
wrap?: boolean;
22-
type?: string;
23-
pinned?: string;
24-
summary?: any;
25-
link?: any;
26-
action?: any;
27-
}
13+
/**
14+
* Bridge input: the spec-canonical ListView (#2231 — the former hand-written
15+
* `ListViewSpec`/`ListColumn` mirrors are retired; the shape now derives from
16+
* `@objectstack/spec/ui` and can no longer drift). Relaxed to `Partial` because
17+
* hosts routinely hand the bridge fragmentary view-configs (every field was
18+
* optional in the old mirror too, including spec-required `columns`).
19+
*/
20+
type ListViewSpec = Partial<ListView>;
2821

29-
interface ListViewSpec {
30-
name?: string;
31-
label?: string;
32-
type?: string;
33-
data?: any;
34-
columns?: ListColumn[];
35-
filter?: any;
36-
sort?: any;
37-
searchableFields?: string[];
38-
filterableFields?: string[];
39-
selection?: any;
40-
pagination?: any;
41-
rowHeight?: string;
42-
resizable?: boolean;
43-
striped?: boolean;
44-
bordered?: boolean;
45-
grouping?: any;
46-
rowColor?: any;
47-
navigation?: any;
48-
kanban?: any;
49-
calendar?: any;
50-
gantt?: any;
51-
gallery?: ListViewGalleryConfig;
52-
timeline?: ListViewTimelineConfig;
53-
// P1.1 additions
54-
rowActions?: string[];
55-
bulkActions?: string[];
56-
bulkActionDefs?: any[];
57-
virtualScroll?: boolean;
58-
conditionalFormatting?: Array<{ condition: string; style: Record<string, string> }>;
59-
inlineEdit?: boolean;
60-
exportOptions?: any;
61-
emptyState?: { title?: string; message?: string; icon?: string };
62-
userActions?: any;
63-
appearance?: any;
64-
/** UX-only hint: collapse appearance/grouping cluster into a single popover. */
65-
compactToolbar?: boolean;
66-
tabs?: any[];
67-
addRecord?: any;
68-
showRecordCount?: boolean;
69-
allowPrinting?: boolean;
70-
// P1.6 i18n & ARIA
71-
aria?: { ariaLabel?: string; ariaDescribedBy?: string; role?: string };
72-
sharing?: any;
73-
hiddenFields?: string[];
74-
fieldOrder?: string[];
75-
description?: string;
76-
}
22+
function mapColumn(col: ListColumn | string): Record<string, any> {
23+
// Spec-legacy shorthand: a bare field name stands for a default column.
24+
if (typeof col === 'string') {
25+
return { accessorKey: col, header: col };
26+
}
7727

78-
function mapColumn(col: ListColumn): Record<string, any> {
7928
const mapped: Record<string, any> = {
8029
accessorKey: col.field,
8130
header: col.label ?? col.field,

0 commit comments

Comments
 (0)