@dashforge/tw 0.7.0-beta → 0.8.1-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/dist/index.esm.js +1057 -74
  3. package/dist/src/components/DataGrid/DataGrid.d.ts.map +1 -1
  4. package/dist/src/components/DataGrid/dataGrid.types.d.ts +43 -0
  5. package/dist/src/components/DataGrid/dataGrid.types.d.ts.map +1 -1
  6. package/dist/src/components/DataGrid/dataGrid.variants.d.ts +6 -0
  7. package/dist/src/components/DataGrid/dataGrid.variants.d.ts.map +1 -1
  8. package/dist/src/components/DataGrid/filters/ColumnFilters.d.ts +23 -0
  9. package/dist/src/components/DataGrid/filters/ColumnFilters.d.ts.map +1 -0
  10. package/dist/src/components/DataGrid/reorder/useColumnReorder.d.ts +50 -0
  11. package/dist/src/components/DataGrid/reorder/useColumnReorder.d.ts.map +1 -0
  12. package/dist/src/components/DataGrid/resize/useColumnResize.d.ts +32 -0
  13. package/dist/src/components/DataGrid/resize/useColumnResize.d.ts.map +1 -0
  14. package/dist/src/components/DataGrid/visibility/ColumnVisibilityMenu.d.ts +40 -0
  15. package/dist/src/components/DataGrid/visibility/ColumnVisibilityMenu.d.ts.map +1 -0
  16. package/dist/src/components/Table/Table.d.ts.map +1 -1
  17. package/dist/src/components/Table/table.types.d.ts +67 -5
  18. package/dist/src/components/Table/table.types.d.ts.map +1 -1
  19. package/dist/src/components/_shared/data/useTableFilter.d.ts +30 -7
  20. package/dist/src/components/_shared/data/useTableFilter.d.ts.map +1 -1
  21. package/dist/src/index.d.ts +1 -1
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/package.json +3 -3
  24. package/src/components/DataGrid/DataGrid.test.tsx +418 -1
  25. package/src/components/DataGrid/DataGrid.tsx +416 -53
  26. package/src/components/DataGrid/dataGrid.types.ts +50 -1
  27. package/src/components/DataGrid/dataGrid.variants.ts +9 -1
  28. package/src/components/DataGrid/filters/ColumnFilters.tsx +432 -0
  29. package/src/components/DataGrid/reorder/useColumnReorder.test.ts +38 -0
  30. package/src/components/DataGrid/reorder/useColumnReorder.ts +144 -0
  31. package/src/components/DataGrid/resize/useColumnResize.ts +106 -0
  32. package/src/components/DataGrid/visibility/ColumnVisibilityMenu.tsx +169 -0
  33. package/src/components/Table/Table.tsx +11 -0
  34. package/src/components/Table/table.types.ts +72 -5
  35. package/src/components/_shared/data/useTableFilter.test.ts +166 -0
  36. package/src/components/_shared/data/useTableFilter.ts +97 -16
  37. package/src/index.ts +2 -0
package/CHANGELOG.md CHANGED
@@ -12,6 +12,261 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
12
12
  > duplicated intentionally — no shared "lowest common denominator" headless
13
13
  > layer.
14
14
 
15
+ ## [0.8.1-beta] — 2026-05-19
16
+
17
+ **UX swap on `DataGrid` column visibility.** The "Columns" toolbar
18
+ button now opens a lightweight **`<Popover>` menu** anchored to the
19
+ button instead of a modal `<Dialog>`. Toggles **auto-commit on
20
+ click** — no draft state, no "Done" button, dismissed via
21
+ outside-click / Esc. Matches the AG-Grid / MUI DataGrid v6 / TanStack
22
+ pattern for the same affordance.
23
+
24
+ Rationale: the previous Dialog was too heavyweight for a settings
25
+ toggle. A modal interrupts the user's interaction with the grid
26
+ (the very thing they're configuring), traps focus, and requires an
27
+ explicit commit step. The Popover variant reads as a "settings
28
+ panel": the user can keep referring to the grid while picking
29
+ columns, and changes flow into the model immediately.
30
+
31
+ ### Changed
32
+
33
+ - **`ColumnVisibilityTrigger`** (internal component used by
34
+ `<DataGrid enableColumnVisibility>`) — switched from `<Dialog>` to
35
+ `<Popover>`. Public DataGrid API surface unchanged: the
36
+ `enableColumnVisibility` flag, `hiddenColumns` /
37
+ `onHiddenColumnsChange` controllable state, and per-column
38
+ `hideable` / `defaultHidden` axes work identically.
39
+
40
+ - **`TableLabels`** — two now-unused keys removed:
41
+ - `columnsDescription` (the Dialog had a description line; the
42
+ Popover doesn't need one)
43
+ - `columnsDone` (no explicit commit step anymore — toggles
44
+ auto-commit)
45
+ The remaining four keys (`columnsButton`, `columnsTitle`,
46
+ `columnsShowAll`, `columnsHideAll`) are unchanged. Default for
47
+ `columnsTitle` adjusted from `"Manage columns"` to
48
+ `"Toggle columns"` (the action is now lighter).
49
+
50
+ ### Migration
51
+
52
+ ```bash
53
+ pnpm up @dashforge/tw@^0.8.1-beta
54
+ ```
55
+
56
+ If you customized the column-visibility labels via the `labels`
57
+ prop, drop the two removed keys:
58
+
59
+ ```diff
60
+ <DataGrid
61
+ rows={rows}
62
+ cols={cols}
63
+ labels={{
64
+ columnsButton: 'Colonne',
65
+ columnsTitle: 'Mostra colonne',
66
+ - columnsDescription: 'Mostra o nascondi colonne…',
67
+ columnsShowAll: 'Mostra tutte',
68
+ columnsHideAll: 'Nascondi tutte',
69
+ - columnsDone: 'Fatto',
70
+ }}
71
+ />
72
+ ```
73
+
74
+ If you don't customize the labels (>99% of consumers), no action
75
+ required — the visual swap happens automatically.
76
+
77
+ ## [0.8.0-beta] — 2026-05-19
78
+
79
+ **Sprint 4.2-bis — DataGrid v1-bis.** Ships the five power-user
80
+ features deferred from `0.7.0-beta`'s DataGrid v1:
81
+
82
+ - **Per-column filter UI chips** — text contains / number range /
83
+ date range / boolean radio, auto-detected by column type
84
+ - **Column visibility dialog** — toolbar "Columns" button +
85
+ modal with checkboxes
86
+ - **Column resize** — grab the right edge of a `<th>` to drag,
87
+ min/max clamping
88
+ - **Column reorder** — native HTML5 drag-and-drop on headers,
89
+ visual drop indicator
90
+ - **Right-sticky columns** — mirror of `sticky: 'left'` (Sprint 4.2)
91
+
92
+ **Minor bump** for the new public API surface (3 new DataGrid
93
+ props, 5 new `TableColumn` axes, 13 new i18n labels). **Strictly
94
+ additive — zero breaking changes** on existing component APIs.
95
+ Drop-in upgrade from `0.7.0-beta`.
96
+
97
+ Zero new runtime deps: filter UI built on the existing
98
+ `<Popover>` (Sprint 3), visibility on `<Dialog>` (Sprint 3),
99
+ resize/reorder on native pointer + HTML5 drag events.
100
+
101
+ ### Added
102
+
103
+ - **Per-column filter UI** — opt in via `cols[i].filterable: true`.
104
+ A filter icon appears in the column header; clicking it opens a
105
+ `<Popover>` with the right input for the column type:
106
+ - `number` → Min/Max inputs (operator: `between`)
107
+ - `date` → From/To date inputs (operator: `between`)
108
+ - `boolean` → All / True / False radios (operator: `equals`)
109
+ - text / unknown → single text input (operator: `contains`,
110
+ case-insensitive substring against the stringified value)
111
+ - **Override autodetect** with `cols[i].filterType` (`'text' |
112
+ 'number' | 'boolean' | 'date'`) — useful when an ID column is
113
+ typed as number but you want a text-contains UI.
114
+ - The filter model uses the new
115
+ `TableFilterOperator = 'contains' | 'equals' | 'between'`
116
+ discriminator. The `between` value shape is `[min, max]` where
117
+ each end can be `null` for an open range. Backwards-compatible:
118
+ `0.7.0-beta` only emitted `contains`; consumers reading
119
+ `filterModel` should now branch on `op`.
120
+ - **Active state** — the filter icon highlights primary-700 when
121
+ a filter is active on that column (`aria-pressed=true`).
122
+ - **i18n** via the existing `labels` prop. New keys:
123
+ `filterMin`, `filterMax`, `filterFrom`, `filterTo`,
124
+ `filterAll`, `filterTrue`, `filterFalse` (plus the existing
125
+ `filterColumn`, `filterApply`, `filterClear`).
126
+
127
+ - **Column visibility dialog** — opt in via the existing
128
+ `enableColumnVisibility` (defaults `true`). A "Columns" button
129
+ appears in the toolbar (alongside the optional search input).
130
+ Clicking opens a `<Dialog>` with one checkbox per `hideable`
131
+ column.
132
+ - `cols[i].hideable: false` excludes a column from the dialog
133
+ entirely (structurally required — typically the ID or primary
134
+ label column).
135
+ - `cols[i].defaultHidden: true` hides the column on first mount;
136
+ the user re-shows it via the dialog.
137
+ - Show all / Hide all shortcuts inside the dialog.
138
+ - Controllable via `hiddenColumns` + `onHiddenColumnsChange` for
139
+ persistence (LocalStorage, server-side prefs, etc.).
140
+ - New `labels` keys: `columnsButton`, `columnsTitle`,
141
+ `columnsDescription`, `columnsShowAll`, `columnsHideAll`,
142
+ `columnsDone`.
143
+
144
+ - **Column resize** — opt in via the existing `enableColumnResize`
145
+ (defaults `true`). Hovering the right edge of a `<th>` shows
146
+ `cursor: col-resize`; pointer-drag commits a new width.
147
+ - Native pointer events with `setPointerCapture` so the drag
148
+ continues even if the cursor leaves the handle.
149
+ - Clamping: `cols[i].minWidth` (default `40px`) /
150
+ `cols[i].maxWidth` (default `1200px`).
151
+ - Per-column opt-out via `cols[i].resizable: false`.
152
+ - Controllable via `columnWidths: Record<string, number>` +
153
+ `onColumnWidthsChange` for persistence.
154
+ - Works with sticky columns and the virtualized body — the
155
+ width is applied to `<th>` and matching `<td>` cells.
156
+
157
+ - **Column reorder** — opt in via the existing
158
+ `enableColumnReorder` (defaults `true`). Drag any column header
159
+ onto another; a 2px primary-500 vertical indicator marks the
160
+ drop side (LEFT half = insert before / RIGHT half = insert
161
+ after). Release to commit.
162
+ - Built on native HTML5 drag-and-drop (`draggable` + `dragstart`
163
+ / `dragover` / `drop` / `dragend`) — no library.
164
+ - The dragged header dims to `opacity-50` while in flight.
165
+ - Per-column opt-out via `cols[i].reorderable: false`.
166
+ - Controllable via `columnOrder: string[]` (list of `field`s in
167
+ display order) + `onColumnOrderChange`. Columns not in the
168
+ order list are appended at the end in their original `cols`
169
+ order — safe to omit.
170
+
171
+ - **Right-sticky columns** — `cols[i].sticky: 'right'` mirrors the
172
+ existing `'left'` value from Sprint 4.2. CSS
173
+ `position: sticky; right: 0` plus a left border to visually
174
+ separate the pinned column from the scrollable area.
175
+ - Header / cell z-index ladder maintained (header top-right
176
+ intersection at z-20, body sticky-right cell at z-[1]).
177
+ - Useful for trailing action columns (Edit / Delete) that should
178
+ always be visible.
179
+
180
+ ### Changed
181
+
182
+ - **`TableFilterItem.op`** now accepts `'contains' | 'equals' |
183
+ 'between'` (was effectively `'contains'`-only in `0.7.0-beta`).
184
+ Consumers reading the model should branch on `op` to handle the
185
+ three value shapes (`string` / `unknown` / `[min, max]` tuple).
186
+ Consumers only emitting filters via the new in-header UI need no
187
+ changes.
188
+
189
+ - **`useTableFilter`** rewritten to support all three operators
190
+ with auto-coercion (number from string, date from ISO string /
191
+ Date instance). Exposed `passesFilter` / `toNumber` / `toDateMs`
192
+ for testing. 28 new unit tests cover the helpers across all
193
+ operator + value-type combinations.
194
+
195
+ - **`useColumnAutoDetect`** is now also the source of truth for the
196
+ filter UI dispatch — `inferredType` maps to `TableFilterType`
197
+ via the new `resolveFilterType` helper inside `DataGrid.tsx`.
198
+
199
+ - **Bundle impact**: +16 KB raw (~+5 KB gz) on top of
200
+ `0.7.0-beta` — the new filter UI, visibility dialog, resize, and
201
+ reorder code paths combined. Zero new runtime deps.
202
+
203
+ ### Migration
204
+
205
+ No code changes required:
206
+
207
+ ```bash
208
+ pnpm up @dashforge/tw@^0.8.0-beta
209
+ ```
210
+
211
+ To adopt the new v1-bis features, opt in per-column / per-grid:
212
+
213
+ ```tsx
214
+ <DataGrid
215
+ rows={users}
216
+ cols={[
217
+ { field: 'name',
218
+ header: 'Name',
219
+ sticky: 'left',
220
+ hideable: false }, // required column
221
+
222
+ { field: 'age',
223
+ header: 'Age',
224
+ filterable: true }, // → number range filter (auto)
225
+
226
+ { field: 'joinedAt',
227
+ header: 'Joined',
228
+ filterable: true }, // → date range filter (auto)
229
+
230
+ { field: 'active',
231
+ header: 'Active',
232
+ filterable: true,
233
+ defaultHidden: true }, // hidden until user re-shows
234
+
235
+ { field: 'actions',
236
+ header: 'Actions',
237
+ sticky: 'right', // pinned to right edge
238
+ resizable: false,
239
+ reorderable: false,
240
+ cellRenderer: ({ row }) => <RowActionsMenu row={row} ... /> },
241
+ ]}
242
+ getRowId={(r) => r.id}
243
+ rowHeight={48}
244
+ height="600px"
245
+
246
+ // Per-feature opt-out flags (all default true):
247
+ enableColumnVisibility
248
+ enableColumnResize
249
+ enableColumnReorder
250
+
251
+ // Controllable state for persistence:
252
+ hiddenColumns={hidden} onHiddenColumnsChange={setHidden}
253
+ columnWidths={widths} onColumnWidthsChange={setWidths}
254
+ columnOrder={order} onColumnOrderChange={setOrder}
255
+ />
256
+ ```
257
+
258
+ `<Table>` (non-virtualized) is **unchanged** in `0.8.0-beta` —
259
+ the in-header v1-bis features are DataGrid-only for now. Promoting
260
+ them to Table is on the v1-bis roadmap.
261
+
262
+ ### Heads-up — companion releases coming
263
+
264
+ - **Sprint 5 → `0.9.0-beta`** + starter kits v1: separate repos
265
+ `dashforge-starter-mui` + `dashforge-starter-tw` with Auth + RBAC
266
+ + form CRUD + dashboard with DataGrid admin views.
267
+ - **Sprint 6 → `1.0.0-rc.1 → 1.0.0`**: final A11Y audit, bundle
268
+ lockdown, beta freeze, cut `1.0.0`.
269
+
15
270
  ## [0.7.0-beta] — 2026-05-19
16
271
 
17
272
  **Combined Sprint 4.2 + 4.3 release.** Ships **`<DataGrid>`** — a