@dashforge/tw 0.8.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.
package/CHANGELOG.md CHANGED
@@ -12,6 +12,68 @@ 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
+
15
77
  ## [0.8.0-beta] — 2026-05-19
16
78
 
17
79
  **Sprint 4.2-bis — DataGrid v1-bis.** Ships the five power-user
package/dist/index.esm.js CHANGED
@@ -8675,11 +8675,9 @@ const DEFAULT_LABELS$1 = {
8675
8675
  densityComfortable: 'Comfortable',
8676
8676
  densitySpacious: 'Spacious',
8677
8677
  columnsButton: 'Columns',
8678
- columnsTitle: 'Manage columns',
8679
- columnsDescription: 'Show or hide columns. Required columns cannot be toggled.',
8678
+ columnsTitle: 'Toggle columns',
8680
8679
  columnsShowAll: 'Show all',
8681
- columnsHideAll: 'Hide all',
8682
- columnsDone: 'Done'
8680
+ columnsHideAll: 'Hide all'
8683
8681
  };
8684
8682
  const DEFAULT_GET_ROW_ID = (_row, index)=>String(index);
8685
8683
  /**
@@ -10216,11 +10214,9 @@ function FilterIcon() {
10216
10214
 
10217
10215
  const DEFAULT_VISIBILITY_LABELS = {
10218
10216
  columnsButton: 'Columns',
10219
- columnsTitle: 'Manage columns',
10220
- columnsDescription: 'Show or hide columns. Required columns cannot be toggled.',
10217
+ columnsTitle: 'Toggle columns',
10221
10218
  columnsShowAll: 'Show all',
10222
- columnsHideAll: 'Hide all',
10223
- columnsDone: 'Done'
10219
+ columnsHideAll: 'Hide all'
10224
10220
  };
10225
10221
  function ColumnVisibilityTrigger(props) {
10226
10222
  const { cols, hiddenColumns, onChange, disabled, labels: labelsProp } = props;
@@ -10230,118 +10226,91 @@ function ColumnVisibilityTrigger(props) {
10230
10226
  // defaults to `true` — a column is hideable unless explicitly opted
10231
10227
  // out with `hideable: false` (structurally required column).
10232
10228
  const hideableCols = cols.filter((c)=>c.hideable !== false);
10233
- return jsxs(Fragment$1, {
10234
- children: [
10235
- jsxs("button", {
10236
- type: "button",
10237
- onClick: ()=>setOpen(true),
10238
- disabled: disabled,
10239
- className: cn('inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-md', 'text-sm text-neutral-700 hover:text-neutral-900', 'border border-neutral-300 bg-neutral-50 hover:bg-neutral-100', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500', 'transition-colors motion-reduce:transition-none', 'disabled:opacity-50 disabled:cursor-not-allowed'),
10240
- children: [
10241
- jsx(ColumnsIcon, {}),
10242
- jsx("span", {
10243
- children: labels.columnsButton
10244
- })
10245
- ]
10246
- }),
10247
- jsx(Dialog, {
10248
- open: open,
10249
- onOpenChange: setOpen,
10250
- title: labels.columnsTitle,
10251
- description: labels.columnsDescription,
10252
- size: "sm",
10253
- children: jsx(ColumnVisibilityBody, {
10254
- cols: hideableCols,
10255
- hiddenColumns: hiddenColumns,
10256
- onChange: onChange,
10257
- onDone: ()=>setOpen(false),
10258
- labels: labels
10259
- })
10260
- })
10261
- ]
10262
- });
10263
- }
10264
- // ───── Dialog body ─────
10265
- function ColumnVisibilityBody(props) {
10266
- const { cols, hiddenColumns, onChange, onDone, labels } = props;
10267
- // Local draft so the user can stage changes; commit on Done.
10268
- const [draft, setDraft] = useState(hiddenColumns);
10269
- // Re-sync when the dialog re-opens with a different external state.
10270
- useEffect(()=>{
10271
- setDraft(hiddenColumns);
10272
- }, [
10273
- hiddenColumns
10274
- ]);
10275
10229
  const toggle = (field)=>{
10276
- setDraft((prev)=>prev.includes(field) ? prev.filter((f)=>f !== field) : [
10277
- ...prev,
10278
- field
10279
- ]);
10230
+ onChange(hiddenColumns.includes(field) ? hiddenColumns.filter((f)=>f !== field) : [
10231
+ ...hiddenColumns,
10232
+ field
10233
+ ]);
10280
10234
  };
10281
- const showAll = ()=>setDraft([]);
10282
- const hideAll = ()=>setDraft(cols.map((c)=>c.field));
10283
- return jsxs("div", {
10284
- className: "flex flex-col gap-3",
10285
- children: [
10286
- jsxs("div", {
10287
- className: "flex items-center gap-2 pb-2 border-b border-neutral-200",
10288
- children: [
10289
- jsx("button", {
10290
- type: "button",
10291
- onClick: showAll,
10292
- className: "text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline",
10293
- children: labels.columnsShowAll
10294
- }),
10295
- jsx("span", {
10296
- className: "text-neutral-300",
10297
- children: "\u00B7"
10298
- }),
10299
- jsx("button", {
10300
- type: "button",
10301
- onClick: hideAll,
10302
- className: "text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline",
10303
- children: labels.columnsHideAll
10304
- })
10305
- ]
10306
- }),
10307
- jsx("ul", {
10308
- className: "flex flex-col gap-1.5 max-h-72 overflow-auto",
10309
- children: cols.map((col)=>{
10310
- const field = col.field;
10311
- const hidden = draft.includes(field);
10312
- const header = typeof col.header === 'function' ? col.header() : col.header;
10313
- return jsx("li", {
10314
- children: jsxs("label", {
10315
- className: "flex items-center gap-2 cursor-pointer py-1 px-1 rounded hover:bg-neutral-100",
10235
+ const showAll = ()=>onChange([]);
10236
+ const hideAll = ()=>onChange(hideableCols.map((c)=>c.field));
10237
+ return jsx(Popover, {
10238
+ open: open,
10239
+ onOpenChange: setOpen,
10240
+ side: "bottom",
10241
+ align: "end",
10242
+ content: jsxs("div", {
10243
+ className: "flex flex-col gap-2 min-w-[220px]",
10244
+ children: [
10245
+ jsxs("div", {
10246
+ className: "flex items-center justify-between pb-2 border-b border-neutral-200",
10247
+ children: [
10248
+ jsx("span", {
10249
+ className: "text-xs font-semibold text-neutral-700 uppercase tracking-wide",
10250
+ children: labels.columnsTitle
10251
+ }),
10252
+ jsxs("div", {
10253
+ className: "flex items-center gap-2",
10316
10254
  children: [
10317
- jsx("input", {
10318
- type: "checkbox",
10319
- checked: !hidden,
10320
- onChange: ()=>toggle(field),
10321
- className: "cursor-pointer"
10255
+ jsx("button", {
10256
+ type: "button",
10257
+ onClick: showAll,
10258
+ className: "text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline",
10259
+ children: labels.columnsShowAll
10322
10260
  }),
10323
10261
  jsx("span", {
10324
- className: "text-sm text-neutral-900",
10325
- children: header
10262
+ className: "text-neutral-300",
10263
+ "aria-hidden": "true",
10264
+ children: "\u00B7"
10265
+ }),
10266
+ jsx("button", {
10267
+ type: "button",
10268
+ onClick: hideAll,
10269
+ className: "text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline",
10270
+ children: labels.columnsHideAll
10326
10271
  })
10327
10272
  ]
10328
10273
  })
10329
- }, field);
10274
+ ]
10275
+ }),
10276
+ jsx("ul", {
10277
+ className: "flex flex-col gap-0.5 max-h-72 overflow-auto",
10278
+ children: hideableCols.map((col)=>{
10279
+ const field = col.field;
10280
+ const hidden = hiddenColumns.includes(field);
10281
+ const header = typeof col.header === 'function' ? col.header() : col.header;
10282
+ return jsx("li", {
10283
+ children: jsxs("label", {
10284
+ className: "flex items-center gap-2 cursor-pointer py-1 px-1 rounded hover:bg-neutral-100",
10285
+ children: [
10286
+ jsx("input", {
10287
+ type: "checkbox",
10288
+ checked: !hidden,
10289
+ onChange: ()=>toggle(field),
10290
+ className: "cursor-pointer"
10291
+ }),
10292
+ jsx("span", {
10293
+ className: "text-sm text-neutral-900",
10294
+ children: header
10295
+ })
10296
+ ]
10297
+ })
10298
+ }, field);
10299
+ })
10330
10300
  })
10331
- }),
10332
- jsx("div", {
10333
- className: "flex justify-end gap-2 pt-2 border-t border-neutral-200",
10334
- children: jsx("button", {
10335
- type: "button",
10336
- onClick: ()=>{
10337
- onChange(draft);
10338
- onDone();
10339
- },
10340
- className: "text-sm bg-primary-500 text-white rounded-md hover:bg-primary-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 px-3 py-1.5",
10341
- children: labels.columnsDone
10301
+ ]
10302
+ }),
10303
+ children: jsxs("button", {
10304
+ type: "button",
10305
+ disabled: disabled,
10306
+ className: cn('inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-md', 'text-sm text-neutral-700 hover:text-neutral-900', 'border border-neutral-300 bg-neutral-50 hover:bg-neutral-100', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500', 'transition-colors motion-reduce:transition-none', 'disabled:opacity-50 disabled:cursor-not-allowed'),
10307
+ children: [
10308
+ jsx(ColumnsIcon, {}),
10309
+ jsx("span", {
10310
+ children: labels.columnsButton
10342
10311
  })
10343
- })
10344
- ]
10312
+ ]
10313
+ })
10345
10314
  });
10346
10315
  }
10347
10316
  // ───── Icon ─────
@@ -10550,11 +10519,9 @@ const DEFAULT_LABELS = {
10550
10519
  densityComfortable: 'Comfortable',
10551
10520
  densitySpacious: 'Spacious',
10552
10521
  columnsButton: 'Columns',
10553
- columnsTitle: 'Manage columns',
10554
- columnsDescription: 'Show or hide columns. Required columns cannot be toggled.',
10522
+ columnsTitle: 'Toggle columns',
10555
10523
  columnsShowAll: 'Show all',
10556
- columnsHideAll: 'Hide all',
10557
- columnsDone: 'Done'
10524
+ columnsHideAll: 'Hide all'
10558
10525
  };
10559
10526
  /**
10560
10527
  * Dashforge TW `<DataGrid>` — virtualized data table.
@@ -10805,7 +10772,7 @@ const DEFAULT_LABELS = {
10805
10772
  ]
10806
10773
  }),
10807
10774
  enableColumnVisibility && jsx(ColumnVisibilityTrigger, {
10808
- cols: cols.filter((c)=>// RBAC-hidden columns are never offered in the dialog.
10775
+ cols: cols.filter((c)=>// RBAC-hidden columns are never offered in the menu.
10809
10776
  !c.access || c.access.onUnauthorized !== 'hide'),
10810
10777
  hiddenColumns: hiddenColumns,
10811
10778
  onChange: setHiddenColumns,
@@ -10813,10 +10780,8 @@ const DEFAULT_LABELS = {
10813
10780
  labels: {
10814
10781
  columnsButton: labels.columnsButton,
10815
10782
  columnsTitle: labels.columnsTitle,
10816
- columnsDescription: labels.columnsDescription,
10817
10783
  columnsShowAll: labels.columnsShowAll,
10818
- columnsHideAll: labels.columnsHideAll,
10819
- columnsDone: labels.columnsDone
10784
+ columnsHideAll: labels.columnsHideAll
10820
10785
  }
10821
10786
  })
10822
10787
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"DataGrid.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/DataGrid.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA6CzD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,kDAohBjE"}
1
+ {"version":3,"file":"DataGrid.d.ts","sourceRoot":"","sources":["../../../../src/components/DataGrid/DataGrid.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA0CzD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,kDAkhBjE"}
@@ -0,0 +1,40 @@
1
+ import type { TableColumn } from '../../Table/table.types.js';
2
+ /**
3
+ * Column visibility menu for DataGrid.
4
+ *
5
+ * Renders a toolbar button (the trigger) that opens a `<Popover>`
6
+ * with one checkbox per `hideable` column. Auto-commits on every
7
+ * toggle — there's no draft / commit step. Outside-click and Esc
8
+ * close the popover (Radix-managed).
9
+ *
10
+ * UX rationale for Popover-over-Dialog:
11
+ * - Lightweight, non-modal: the user can keep referring to the grid
12
+ * while picking columns. A modal Dialog would interrupt the flow.
13
+ * - Auto-commit reads as a "settings panel" rather than a
14
+ * "configuration form" — matches AG-Grid / MUI DataGrid v6 /
15
+ * TanStack examples.
16
+ * - No focus trap on the rest of the page; the user can scroll the
17
+ * grid or click the column resize handles without dismissing the
18
+ * panel first.
19
+ *
20
+ * Columns with `hideable: false` are NEVER shown in the menu —
21
+ * those are considered structurally required (e.g. an ID column).
22
+ *
23
+ * RBAC-hidden columns (`access.onUnauthorized === 'hide'`) are also
24
+ * excluded — they're already removed from `visibleCols` upstream.
25
+ */
26
+ export interface ColumnVisibilityLabels {
27
+ columnsButton?: string;
28
+ columnsTitle?: string;
29
+ columnsShowAll?: string;
30
+ columnsHideAll?: string;
31
+ }
32
+ export interface ColumnVisibilityTriggerProps<T extends object> {
33
+ cols: TableColumn<T>[];
34
+ hiddenColumns: string[];
35
+ onChange: (next: string[]) => void;
36
+ disabled?: boolean;
37
+ labels?: ColumnVisibilityLabels;
38
+ }
39
+ export declare function ColumnVisibilityTrigger<T extends object>(props: ColumnVisibilityTriggerProps<T>): import("react/jsx-runtime").JSX.Element;
40
+ //# sourceMappingURL=ColumnVisibilityMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColumnVisibilityMenu.d.ts","sourceRoot":"","sources":["../../../../../src/components/DataGrid/visibility/ColumnVisibilityMenu.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,sBAAsB;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AASD,MAAM,WAAW,4BAA4B,CAAC,CAAC,SAAS,MAAM;IAC5D,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EACtD,KAAK,EAAE,4BAA4B,CAAC,CAAC,CAAC,2CA6FvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,kBAAkB,CAAC;AAwC1B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,kDAgW3D"}
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,kBAAkB,CAAC;AAqC1B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,kDAgW3D"}
@@ -245,13 +245,11 @@ export interface TableLabels {
245
245
  densityCompact?: string;
246
246
  densityComfortable?: string;
247
247
  densitySpacious?: string;
248
- /** Column visibility dialog. */
248
+ /** Column visibility menu (Popover-based, auto-commit). */
249
249
  columnsButton?: string;
250
250
  columnsTitle?: string;
251
- columnsDescription?: string;
252
251
  columnsShowAll?: string;
253
252
  columnsHideAll?: string;
254
- columnsDone?: string;
255
253
  }
256
254
  export interface TableSlotProps {
257
255
  root?: {
@@ -1 +1 @@
1
- {"version":3,"file":"table.types.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/table.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.types.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/table.types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dashforge/tw",
3
- "version": "0.8.0-beta",
3
+ "version": "0.8.1-beta",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",
@@ -31,12 +31,12 @@
31
31
  "tailwind-variants": "^3.1.1",
32
32
  "vitest": "*",
33
33
  "@dashforge/forms": "0.2.3-beta",
34
- "@dashforge/ui-core": "0.2.3-beta",
35
- "@dashforge/rbac": "0.2.3-beta"
34
+ "@dashforge/rbac": "0.2.3-beta",
35
+ "@dashforge/ui-core": "0.2.3-beta"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": "^18.0.0 || ^19.0.0",
39
- "@dashforge/tw-tokens": "0.1.0-beta",
40
- "@dashforge/tw-theme": "0.1.0-beta"
39
+ "@dashforge/tw-theme": "0.1.0-beta",
40
+ "@dashforge/tw-tokens": "0.1.0-beta"
41
41
  }
42
42
  }
@@ -667,11 +667,11 @@ describe('DataGrid — column visibility', () => {
667
667
  expect(screen.queryByRole('button', { name: 'Columns' })).toBeNull();
668
668
  });
669
669
 
670
- it('opens dialog with one checkbox per hideable column', () => {
670
+ it('opens a popover menu with one checkbox per hideable column', () => {
671
671
  const cols: TableColumn<User>[] = [
672
672
  { field: 'name', header: 'Name' },
673
673
  { field: 'email', header: 'Email' },
674
- // hideable: false → not shown in the dialog (structurally required)
674
+ // hideable: false → not shown in the menu (structurally required)
675
675
  { field: 'age', header: 'Age', hideable: false },
676
676
  ];
677
677
  render(
@@ -684,16 +684,13 @@ describe('DataGrid — column visibility', () => {
684
684
  />,
685
685
  );
686
686
  fireEvent.click(screen.getByRole('button', { name: 'Columns' }));
687
+ // Radix Popover content has role="dialog" too.
687
688
  expect(screen.queryByRole('dialog')).not.toBeNull();
688
- // The dialog should expose checkboxes for Name + Email (not Age).
689
- const labels = screen.getAllByText(/Name|Email|Age/);
690
- // Name + Email appear in BOTH the table header and the dialog; Age
691
- // appears only in the header (hideable=false → excluded from dialog).
692
- const dialog = screen.getByRole('dialog');
693
- expect(dialog.textContent).toContain('Name');
694
- expect(dialog.textContent).toContain('Email');
695
- expect(dialog.textContent).not.toContain('Age');
696
- void labels;
689
+ // The menu should expose checkboxes for Name + Email (not Age).
690
+ const menu = screen.getByRole('dialog');
691
+ expect(menu.textContent).toContain('Name');
692
+ expect(menu.textContent).toContain('Email');
693
+ expect(menu.textContent).not.toContain('Age');
697
694
  });
698
695
 
699
696
  it('respects col.defaultHidden on first render', () => {
@@ -716,7 +713,7 @@ describe('DataGrid — column visibility', () => {
716
713
  expect(screen.queryByText('Name')).not.toBeNull();
717
714
  });
718
715
 
719
- it('toggling a column hides it from the table after Done', () => {
716
+ it('toggling a column auto-commits via onHiddenColumnsChange (no Done button)', () => {
720
717
  const onHiddenColumnsChange = vi.fn();
721
718
  render(
722
719
  <DataGrid
@@ -729,18 +726,17 @@ describe('DataGrid — column visibility', () => {
729
726
  />,
730
727
  );
731
728
  fireEvent.click(screen.getByRole('button', { name: 'Columns' }));
732
- // Uncheck "Email" inside the dialog
733
- const dialog = screen.getByRole('dialog');
729
+ // Uncheck "Email" inside the popover menu
730
+ const menu = screen.getByRole('dialog');
734
731
  const emailCheckbox = Array.from(
735
- dialog.querySelectorAll('input[type="checkbox"]'),
732
+ menu.querySelectorAll('input[type="checkbox"]'),
736
733
  ).find((el) => {
737
734
  const li = el.closest('label');
738
735
  return li?.textContent?.includes('Email');
739
736
  }) as HTMLInputElement | undefined;
740
737
  expect(emailCheckbox).toBeDefined();
741
738
  fireEvent.click(emailCheckbox!);
742
- // Commit via Done
743
- fireEvent.click(screen.getByRole('button', { name: 'Done' }));
739
+ // Auto-commit on toggle — no Done button anymore
744
740
  expect(onHiddenColumnsChange).toHaveBeenCalledWith(['email']);
745
741
  });
746
742
 
@@ -33,7 +33,7 @@ import type {
33
33
  } from '../Table/table.types.js';
34
34
  import type { DataGridProps } from './dataGrid.types.js';
35
35
  import { ColumnFilterTrigger } from './filters/ColumnFilters.js';
36
- import { ColumnVisibilityTrigger } from './visibility/ColumnVisibilityDialog.js';
36
+ import { ColumnVisibilityTrigger } from './visibility/ColumnVisibilityMenu.js';
37
37
  import { useColumnResize } from './resize/useColumnResize.js';
38
38
  import {
39
39
  useColumnReorder,
@@ -68,12 +68,9 @@ const DEFAULT_LABELS: Required<TableLabels> = {
68
68
  densityComfortable: 'Comfortable',
69
69
  densitySpacious: 'Spacious',
70
70
  columnsButton: 'Columns',
71
- columnsTitle: 'Manage columns',
72
- columnsDescription:
73
- 'Show or hide columns. Required columns cannot be toggled.',
71
+ columnsTitle: 'Toggle columns',
74
72
  columnsShowAll: 'Show all',
75
73
  columnsHideAll: 'Hide all',
76
- columnsDone: 'Done',
77
74
  };
78
75
 
79
76
  /**
@@ -414,7 +411,7 @@ export function DataGrid<T extends object>(props: DataGridProps<T>) {
414
411
  <ColumnVisibilityTrigger
415
412
  cols={cols.filter(
416
413
  (c) =>
417
- // RBAC-hidden columns are never offered in the dialog.
414
+ // RBAC-hidden columns are never offered in the menu.
418
415
  !c.access || c.access.onUnauthorized !== 'hide',
419
416
  )}
420
417
  hiddenColumns={hiddenColumns}
@@ -423,10 +420,8 @@ export function DataGrid<T extends object>(props: DataGridProps<T>) {
423
420
  labels={{
424
421
  columnsButton: labels.columnsButton,
425
422
  columnsTitle: labels.columnsTitle,
426
- columnsDescription: labels.columnsDescription,
427
423
  columnsShowAll: labels.columnsShowAll,
428
424
  columnsHideAll: labels.columnsHideAll,
429
- columnsDone: labels.columnsDone,
430
425
  }}
431
426
  />
432
427
  )}
@@ -0,0 +1,169 @@
1
+ import { useState, type ReactNode } from 'react';
2
+ import { Popover } from '../../Popover/Popover.js';
3
+ import { cn } from '../../../utils/cn.js';
4
+ import type { TableColumn } from '../../Table/table.types.js';
5
+
6
+ /**
7
+ * Column visibility menu for DataGrid.
8
+ *
9
+ * Renders a toolbar button (the trigger) that opens a `<Popover>`
10
+ * with one checkbox per `hideable` column. Auto-commits on every
11
+ * toggle — there's no draft / commit step. Outside-click and Esc
12
+ * close the popover (Radix-managed).
13
+ *
14
+ * UX rationale for Popover-over-Dialog:
15
+ * - Lightweight, non-modal: the user can keep referring to the grid
16
+ * while picking columns. A modal Dialog would interrupt the flow.
17
+ * - Auto-commit reads as a "settings panel" rather than a
18
+ * "configuration form" — matches AG-Grid / MUI DataGrid v6 /
19
+ * TanStack examples.
20
+ * - No focus trap on the rest of the page; the user can scroll the
21
+ * grid or click the column resize handles without dismissing the
22
+ * panel first.
23
+ *
24
+ * Columns with `hideable: false` are NEVER shown in the menu —
25
+ * those are considered structurally required (e.g. an ID column).
26
+ *
27
+ * RBAC-hidden columns (`access.onUnauthorized === 'hide'`) are also
28
+ * excluded — they're already removed from `visibleCols` upstream.
29
+ */
30
+
31
+ export interface ColumnVisibilityLabels {
32
+ columnsButton?: string;
33
+ columnsTitle?: string;
34
+ columnsShowAll?: string;
35
+ columnsHideAll?: string;
36
+ }
37
+
38
+ const DEFAULT_VISIBILITY_LABELS: Required<ColumnVisibilityLabels> = {
39
+ columnsButton: 'Columns',
40
+ columnsTitle: 'Toggle columns',
41
+ columnsShowAll: 'Show all',
42
+ columnsHideAll: 'Hide all',
43
+ };
44
+
45
+ export interface ColumnVisibilityTriggerProps<T extends object> {
46
+ cols: TableColumn<T>[];
47
+ hiddenColumns: string[];
48
+ onChange: (next: string[]) => void;
49
+ disabled?: boolean;
50
+ labels?: ColumnVisibilityLabels;
51
+ }
52
+
53
+ export function ColumnVisibilityTrigger<T extends object>(
54
+ props: ColumnVisibilityTriggerProps<T>,
55
+ ) {
56
+ const { cols, hiddenColumns, onChange, disabled, labels: labelsProp } = props;
57
+ const labels = { ...DEFAULT_VISIBILITY_LABELS, ...labelsProp };
58
+ const [open, setOpen] = useState(false);
59
+
60
+ // Hideable cols are the only ones the user can toggle. `hideable`
61
+ // defaults to `true` — a column is hideable unless explicitly opted
62
+ // out with `hideable: false` (structurally required column).
63
+ const hideableCols = cols.filter((c) => c.hideable !== false);
64
+
65
+ const toggle = (field: string) => {
66
+ onChange(
67
+ hiddenColumns.includes(field)
68
+ ? hiddenColumns.filter((f) => f !== field)
69
+ : [...hiddenColumns, field],
70
+ );
71
+ };
72
+
73
+ const showAll = () => onChange([]);
74
+ const hideAll = () => onChange(hideableCols.map((c) => c.field as string));
75
+
76
+ return (
77
+ <Popover
78
+ open={open}
79
+ onOpenChange={setOpen}
80
+ side="bottom"
81
+ align="end"
82
+ content={
83
+ <div className="flex flex-col gap-2 min-w-[220px]">
84
+ <div className="flex items-center justify-between pb-2 border-b border-neutral-200">
85
+ <span className="text-xs font-semibold text-neutral-700 uppercase tracking-wide">
86
+ {labels.columnsTitle}
87
+ </span>
88
+ <div className="flex items-center gap-2">
89
+ <button
90
+ type="button"
91
+ onClick={showAll}
92
+ className="text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline"
93
+ >
94
+ {labels.columnsShowAll}
95
+ </button>
96
+ <span className="text-neutral-300" aria-hidden="true">·</span>
97
+ <button
98
+ type="button"
99
+ onClick={hideAll}
100
+ className="text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline"
101
+ >
102
+ {labels.columnsHideAll}
103
+ </button>
104
+ </div>
105
+ </div>
106
+ <ul className="flex flex-col gap-0.5 max-h-72 overflow-auto">
107
+ {hideableCols.map((col) => {
108
+ const field = col.field as string;
109
+ const hidden = hiddenColumns.includes(field);
110
+ const header =
111
+ typeof col.header === 'function' ? col.header() : col.header;
112
+ return (
113
+ <li key={field}>
114
+ <label className="flex items-center gap-2 cursor-pointer py-1 px-1 rounded hover:bg-neutral-100">
115
+ <input
116
+ type="checkbox"
117
+ checked={!hidden}
118
+ onChange={() => toggle(field)}
119
+ className="cursor-pointer"
120
+ />
121
+ <span className="text-sm text-neutral-900">{header}</span>
122
+ </label>
123
+ </li>
124
+ );
125
+ })}
126
+ </ul>
127
+ </div>
128
+ }
129
+ >
130
+ <button
131
+ type="button"
132
+ disabled={disabled}
133
+ className={cn(
134
+ 'inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-md',
135
+ 'text-sm text-neutral-700 hover:text-neutral-900',
136
+ 'border border-neutral-300 bg-neutral-50 hover:bg-neutral-100',
137
+ 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500',
138
+ 'transition-colors motion-reduce:transition-none',
139
+ 'disabled:opacity-50 disabled:cursor-not-allowed',
140
+ )}
141
+ >
142
+ <ColumnsIcon />
143
+ <span>{labels.columnsButton}</span>
144
+ </button>
145
+ </Popover>
146
+ );
147
+ }
148
+
149
+ // ───── Icon ─────
150
+
151
+ function ColumnsIcon(): ReactNode {
152
+ return (
153
+ <svg
154
+ width="0.875em"
155
+ height="0.875em"
156
+ viewBox="0 0 16 16"
157
+ fill="none"
158
+ stroke="currentColor"
159
+ strokeWidth="1.5"
160
+ strokeLinecap="round"
161
+ strokeLinejoin="round"
162
+ aria-hidden="true"
163
+ >
164
+ <rect x="2" y="3" width="3.5" height="10" rx="0.5" />
165
+ <rect x="6.25" y="3" width="3.5" height="10" rx="0.5" />
166
+ <rect x="10.5" y="3" width="3.5" height="10" rx="0.5" />
167
+ </svg>
168
+ );
169
+ }
@@ -52,12 +52,9 @@ const DEFAULT_LABELS: Required<TableLabels> = {
52
52
  densityComfortable: 'Comfortable',
53
53
  densitySpacious: 'Spacious',
54
54
  columnsButton: 'Columns',
55
- columnsTitle: 'Manage columns',
56
- columnsDescription:
57
- 'Show or hide columns. Required columns cannot be toggled.',
55
+ columnsTitle: 'Toggle columns',
58
56
  columnsShowAll: 'Show all',
59
57
  columnsHideAll: 'Hide all',
60
- columnsDone: 'Done',
61
58
  };
62
59
 
63
60
  const DEFAULT_GET_ROW_ID = <T extends object>(_row: T, index: number) => String(index);
@@ -288,13 +288,11 @@ export interface TableLabels {
288
288
  densityCompact?: string;
289
289
  densityComfortable?: string;
290
290
  densitySpacious?: string;
291
- /** Column visibility dialog. */
291
+ /** Column visibility menu (Popover-based, auto-commit). */
292
292
  columnsButton?: string;
293
293
  columnsTitle?: string;
294
- columnsDescription?: string;
295
294
  columnsShowAll?: string;
296
295
  columnsHideAll?: string;
297
- columnsDone?: string;
298
296
  }
299
297
 
300
298
  // ───── Slot props ─────
@@ -1,33 +0,0 @@
1
- import type { TableColumn } from '../../Table/table.types.js';
2
- /**
3
- * Column visibility dialog for DataGrid.
4
- *
5
- * Renders a toolbar button (the trigger) that opens a `<Dialog>` with
6
- * one checkbox per `hideable` column. The consumer can:
7
- * - Show/hide individual columns
8
- * - "Show all" / "Hide all" shortcuts
9
- * - Persist visibility via the controllable `hiddenColumns` model
10
- *
11
- * Columns with `hideable: false` are NEVER shown in the dialog —
12
- * those are considered structurally required (e.g. an ID column).
13
- *
14
- * RBAC-hidden columns (`access.onUnauthorized === 'hide'`) are also
15
- * excluded — they're already removed from `visibleCols` upstream.
16
- */
17
- export interface ColumnVisibilityLabels {
18
- columnsButton?: string;
19
- columnsTitle?: string;
20
- columnsDescription?: string;
21
- columnsShowAll?: string;
22
- columnsHideAll?: string;
23
- columnsDone?: string;
24
- }
25
- export interface ColumnVisibilityTriggerProps<T extends object> {
26
- cols: TableColumn<T>[];
27
- hiddenColumns: string[];
28
- onChange: (next: string[]) => void;
29
- disabled?: boolean;
30
- labels?: ColumnVisibilityLabels;
31
- }
32
- export declare function ColumnVisibilityTrigger<T extends object>(props: ColumnVisibilityTriggerProps<T>): import("react/jsx-runtime").JSX.Element;
33
- //# sourceMappingURL=ColumnVisibilityDialog.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ColumnVisibilityDialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/DataGrid/visibility/ColumnVisibilityDialog.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,sBAAsB;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAWD,MAAM,WAAW,4BAA4B,CAAC,CAAC,SAAS,MAAM;IAC5D,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EACtD,KAAK,EAAE,4BAA4B,CAAC,CAAC,CAAC,2CA8CvC"}
@@ -1,200 +0,0 @@
1
- import { useState, useEffect, type ReactNode } from 'react';
2
- import { Dialog } from '../../Dialog/Dialog.js';
3
- import { cn } from '../../../utils/cn.js';
4
- import type { TableColumn } from '../../Table/table.types.js';
5
-
6
- /**
7
- * Column visibility dialog for DataGrid.
8
- *
9
- * Renders a toolbar button (the trigger) that opens a `<Dialog>` with
10
- * one checkbox per `hideable` column. The consumer can:
11
- * - Show/hide individual columns
12
- * - "Show all" / "Hide all" shortcuts
13
- * - Persist visibility via the controllable `hiddenColumns` model
14
- *
15
- * Columns with `hideable: false` are NEVER shown in the dialog —
16
- * those are considered structurally required (e.g. an ID column).
17
- *
18
- * RBAC-hidden columns (`access.onUnauthorized === 'hide'`) are also
19
- * excluded — they're already removed from `visibleCols` upstream.
20
- */
21
-
22
- export interface ColumnVisibilityLabels {
23
- columnsButton?: string;
24
- columnsTitle?: string;
25
- columnsDescription?: string;
26
- columnsShowAll?: string;
27
- columnsHideAll?: string;
28
- columnsDone?: string;
29
- }
30
-
31
- const DEFAULT_VISIBILITY_LABELS: Required<ColumnVisibilityLabels> = {
32
- columnsButton: 'Columns',
33
- columnsTitle: 'Manage columns',
34
- columnsDescription: 'Show or hide columns. Required columns cannot be toggled.',
35
- columnsShowAll: 'Show all',
36
- columnsHideAll: 'Hide all',
37
- columnsDone: 'Done',
38
- };
39
-
40
- export interface ColumnVisibilityTriggerProps<T extends object> {
41
- cols: TableColumn<T>[];
42
- hiddenColumns: string[];
43
- onChange: (next: string[]) => void;
44
- disabled?: boolean;
45
- labels?: ColumnVisibilityLabels;
46
- }
47
-
48
- export function ColumnVisibilityTrigger<T extends object>(
49
- props: ColumnVisibilityTriggerProps<T>,
50
- ) {
51
- const { cols, hiddenColumns, onChange, disabled, labels: labelsProp } = props;
52
- const labels = { ...DEFAULT_VISIBILITY_LABELS, ...labelsProp };
53
- const [open, setOpen] = useState(false);
54
-
55
- // Hideable cols are the only ones the user can toggle. `hideable`
56
- // defaults to `true` — a column is hideable unless explicitly opted
57
- // out with `hideable: false` (structurally required column).
58
- const hideableCols = cols.filter((c) => c.hideable !== false);
59
-
60
- return (
61
- <>
62
- <button
63
- type="button"
64
- onClick={() => setOpen(true)}
65
- disabled={disabled}
66
- className={cn(
67
- 'inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-md',
68
- 'text-sm text-neutral-700 hover:text-neutral-900',
69
- 'border border-neutral-300 bg-neutral-50 hover:bg-neutral-100',
70
- 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500',
71
- 'transition-colors motion-reduce:transition-none',
72
- 'disabled:opacity-50 disabled:cursor-not-allowed',
73
- )}
74
- >
75
- <ColumnsIcon />
76
- <span>{labels.columnsButton}</span>
77
- </button>
78
- <Dialog
79
- open={open}
80
- onOpenChange={setOpen}
81
- title={labels.columnsTitle}
82
- description={labels.columnsDescription}
83
- size="sm"
84
- >
85
- <ColumnVisibilityBody
86
- cols={hideableCols}
87
- hiddenColumns={hiddenColumns}
88
- onChange={onChange}
89
- onDone={() => setOpen(false)}
90
- labels={labels}
91
- />
92
- </Dialog>
93
- </>
94
- );
95
- }
96
-
97
- // ───── Dialog body ─────
98
-
99
- function ColumnVisibilityBody<T extends object>(props: {
100
- cols: TableColumn<T>[];
101
- hiddenColumns: string[];
102
- onChange: (next: string[]) => void;
103
- onDone: () => void;
104
- labels: Required<ColumnVisibilityLabels>;
105
- }) {
106
- const { cols, hiddenColumns, onChange, onDone, labels } = props;
107
- // Local draft so the user can stage changes; commit on Done.
108
- const [draft, setDraft] = useState<string[]>(hiddenColumns);
109
-
110
- // Re-sync when the dialog re-opens with a different external state.
111
- useEffect(() => {
112
- setDraft(hiddenColumns);
113
- }, [hiddenColumns]);
114
-
115
- const toggle = (field: string) => {
116
- setDraft((prev) =>
117
- prev.includes(field) ? prev.filter((f) => f !== field) : [...prev, field],
118
- );
119
- };
120
-
121
- const showAll = () => setDraft([]);
122
- const hideAll = () => setDraft(cols.map((c) => c.field as string));
123
-
124
- return (
125
- <div className="flex flex-col gap-3">
126
- <div className="flex items-center gap-2 pb-2 border-b border-neutral-200">
127
- <button
128
- type="button"
129
- onClick={showAll}
130
- className="text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline"
131
- >
132
- {labels.columnsShowAll}
133
- </button>
134
- <span className="text-neutral-300">·</span>
135
- <button
136
- type="button"
137
- onClick={hideAll}
138
- className="text-xs text-neutral-600 hover:text-neutral-900 underline-offset-2 hover:underline focus:outline-none focus-visible:underline"
139
- >
140
- {labels.columnsHideAll}
141
- </button>
142
- </div>
143
- <ul className="flex flex-col gap-1.5 max-h-72 overflow-auto">
144
- {cols.map((col) => {
145
- const field = col.field as string;
146
- const hidden = draft.includes(field);
147
- const header =
148
- typeof col.header === 'function' ? col.header() : col.header;
149
- return (
150
- <li key={field}>
151
- <label className="flex items-center gap-2 cursor-pointer py-1 px-1 rounded hover:bg-neutral-100">
152
- <input
153
- type="checkbox"
154
- checked={!hidden}
155
- onChange={() => toggle(field)}
156
- className="cursor-pointer"
157
- />
158
- <span className="text-sm text-neutral-900">{header}</span>
159
- </label>
160
- </li>
161
- );
162
- })}
163
- </ul>
164
- <div className="flex justify-end gap-2 pt-2 border-t border-neutral-200">
165
- <button
166
- type="button"
167
- onClick={() => {
168
- onChange(draft);
169
- onDone();
170
- }}
171
- className="text-sm bg-primary-500 text-white rounded-md hover:bg-primary-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 px-3 py-1.5"
172
- >
173
- {labels.columnsDone}
174
- </button>
175
- </div>
176
- </div>
177
- );
178
- }
179
-
180
- // ───── Icon ─────
181
-
182
- function ColumnsIcon(): ReactNode {
183
- return (
184
- <svg
185
- width="0.875em"
186
- height="0.875em"
187
- viewBox="0 0 16 16"
188
- fill="none"
189
- stroke="currentColor"
190
- strokeWidth="1.5"
191
- strokeLinecap="round"
192
- strokeLinejoin="round"
193
- aria-hidden="true"
194
- >
195
- <rect x="2" y="3" width="3.5" height="10" rx="0.5" />
196
- <rect x="6.25" y="3" width="3.5" height="10" rx="0.5" />
197
- <rect x="10.5" y="3" width="3.5" height="10" rx="0.5" />
198
- </svg>
199
- );
200
- }