@worknice/whiteboard 0.53.0 → 0.55.0

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.
@@ -258,6 +258,7 @@ const MenuButton = ({ autoFocus = false, ariaLabel, disabled = false, id, size =
258
258
  [__WEBPACK_EXTERNAL_MODULE__MenuButton_module_js_872b1a55__["default"].iconOnly]: void 0 === children
259
259
  }),
260
260
  tabIndex: 0,
261
+ title: ariaLabel,
261
262
  type: "button",
262
263
  ref: floatingUiRefs.setReference,
263
264
  ...getReferenceProps({
@@ -31,6 +31,7 @@ type Props<Type> = {
31
31
  globalFiltering?: boolean;
32
32
  size?: number;
33
33
  enableSorting?: boolean;
34
+ sortingFn?: SortingColumnDef<Type>["sortingFn"];
34
35
  sortUndefined?: SortingColumnDef<Type>["sortUndefined"];
35
36
  } & ({
36
37
  type?: "accessor";
@@ -54,6 +55,19 @@ type Props<Type> = {
54
55
  isLoading?: boolean;
55
56
  estimatedRowSize?: number;
56
57
  emptyState?: ReactNode;
58
+ bulkActions?: BulkAction<Type>[];
59
+ secondaryBulkActions?: BulkAction<Type>[];
57
60
  };
58
- declare const CustomizableTable: <Type>({ data, columns, csvFilename, getRowId, availableColumnGroups, view, onViewChange, isLoading, estimatedRowSize, emptyState, }: Props<Type>) => import("react/jsx-runtime").JSX.Element;
61
+ type BulkAction<Type> = {
62
+ key: string;
63
+ label: string;
64
+ icon?: ReactNode;
65
+ render: (props: {
66
+ rows: Array<Type>;
67
+ resetRowSelection: () => void;
68
+ onClose: () => void;
69
+ }) => ReactNode;
70
+ predicate?: (row: Type) => boolean;
71
+ };
72
+ declare const CustomizableTable: <Type>({ data, columns, csvFilename, getRowId, availableColumnGroups, view, onViewChange, isLoading, estimatedRowSize, emptyState, bulkActions, secondaryBulkActions, }: Props<Type>) => import("react/jsx-runtime").JSX.Element;
59
73
  export default CustomizableTable;
@@ -3,6 +3,7 @@ import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__ from "react/j
3
3
  import * as __WEBPACK_EXTERNAL_MODULE__dnd_kit_core_a545325d__ from "@dnd-kit/core";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE__dnd_kit_sortable_a8361dd8__ from "@dnd-kit/sortable";
5
5
  import * as __WEBPACK_EXTERNAL_MODULE__dnd_kit_utilities_3c8eb4c2__ from "@dnd-kit/utilities";
6
+ import * as __WEBPACK_EXTERNAL_MODULE__floating_ui_react_dom_d5bb3c23__ from "@floating-ui/react-dom";
6
7
  import * as __WEBPACK_EXTERNAL_MODULE__react_hook_throttle_d66151d4__ from "@react-hook/throttle";
7
8
  import * as __WEBPACK_EXTERNAL_MODULE__tanstack_react_table_777e1b4b__ from "@tanstack/react-table";
8
9
  import * as __WEBPACK_EXTERNAL_MODULE__tanstack_react_virtual_e7b31bc6__ from "@tanstack/react-virtual";
@@ -11,18 +12,28 @@ import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
11
12
  import * as __WEBPACK_EXTERNAL_MODULE__controls_Button_js_2f50b64a__ from "../../controls/Button.js";
12
13
  import * as __WEBPACK_EXTERNAL_MODULE__controls_Disclosure_js_07249afc__ from "../../controls/Disclosure.js";
13
14
  import * as __WEBPACK_EXTERNAL_MODULE__controls_FilterModal_js_c5dcd344__ from "../../controls/FilterModal.js";
15
+ import * as __WEBPACK_EXTERNAL_MODULE__controls_MenuButton_js_fa7c5c89__ from "../../controls/MenuButton.js";
16
+ import * as __WEBPACK_EXTERNAL_MODULE__inputs_CheckboxInput_js_0c849015__ from "../../inputs/CheckboxInput.js";
14
17
  import * as __WEBPACK_EXTERNAL_MODULE__inputs_StringInput_js_39dae7d5__ from "../../inputs/StringInput.js";
15
18
  import * as __WEBPACK_EXTERNAL_MODULE__utils_tables_js_ad146866__ from "../../utils/tables.js";
19
+ import * as __WEBPACK_EXTERNAL_MODULE__Badge_js_a2cbb2b8__ from "../Badge.js";
20
+ import * as __WEBPACK_EXTERNAL_MODULE__Card_js_2e00482a__ from "../Card.js";
21
+ import * as __WEBPACK_EXTERNAL_MODULE__CardContent_js_bacbf899__ from "../CardContent.js";
22
+ import * as __WEBPACK_EXTERNAL_MODULE__HStack_js_5c2eb952__ from "../HStack.js";
16
23
  import * as __WEBPACK_EXTERNAL_MODULE__Icon_js_e5f9af80__ from "../Icon.js";
24
+ import * as __WEBPACK_EXTERNAL_MODULE__PlainText_js_6d36b5d5__ from "../PlainText.js";
17
25
  import * as __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__ from "../Table.module.js";
18
26
  import * as __WEBPACK_EXTERNAL_MODULE__ConfigureColumnsModal_js_cdac33d6__ from "./ConfigureColumnsModal.js";
19
27
  import * as __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__ from "./CustomizableTable.module.js";
28
+ const selectColumnId = "_selectColumn";
20
29
  function asFilter(filter) {
21
30
  return filter;
22
31
  }
23
32
  const DraggableColumnHeader = ({ header, getColumnStyle, showResizer = true })=>{
33
+ const isFixedWidth = header.column.columnDef.meta?.fixedWidth === true;
24
34
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = (0, __WEBPACK_EXTERNAL_MODULE__dnd_kit_sortable_a8361dd8__.useSortable)({
25
- id: header.column.id
35
+ id: header.column.id,
36
+ disabled: isFixedWidth
26
37
  });
27
38
  const style = {
28
39
  transform: __WEBPACK_EXTERNAL_MODULE__dnd_kit_utilities_3c8eb4c2__.CSS.Transform.toString(transform),
@@ -30,7 +41,8 @@ const DraggableColumnHeader = ({ header, getColumnStyle, showResizer = true })=>
30
41
  opacity: isDragging ? 0.5 : 1,
31
42
  ...getColumnStyle(header.column),
32
43
  flexGrow: 0,
33
- position: "relative"
44
+ position: "relative",
45
+ cursor: isFixedWidth ? "default" : void 0
34
46
  };
35
47
  const headerContent = header.isPlaceholder ? null : header.column.getCanSort() ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
36
48
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("button", {
@@ -61,12 +73,12 @@ const DraggableColumnHeader = ({ header, getColumnStyle, showResizer = true })=>
61
73
  return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("th", {
62
74
  ref: setNodeRef,
63
75
  style: style,
64
- className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableCell, __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableHeader, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].cell, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].headerCell),
65
- ...attributes,
66
- ...listeners,
76
+ className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableCell, __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableHeader, header.column.id === selectColumnId ? __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].selectionCell : void 0, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].cell, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].headerCell),
77
+ ...isFixedWidth ? {} : attributes,
78
+ ...isFixedWidth ? {} : listeners,
67
79
  children: [
68
80
  headerContent,
69
- showResizer ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
81
+ showResizer && !isFixedWidth ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
70
82
  onPointerDown: (e)=>e.stopPropagation(),
71
83
  onMouseDown: (e)=>{
72
84
  e.stopPropagation();
@@ -81,14 +93,30 @@ const DraggableColumnHeader = ({ header, getColumnStyle, showResizer = true })=>
81
93
  ]
82
94
  });
83
95
  };
84
- const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColumnGroups, view, onViewChange, isLoading = false, estimatedRowSize = 100, emptyState = "No results" })=>{
96
+ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColumnGroups, view, onViewChange, isLoading = false, estimatedRowSize = 100, emptyState = "No results", bulkActions = [], secondaryBulkActions = [] })=>{
85
97
  const [searchTerm, setSearchTerm] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)("");
86
98
  const [isFilterModalOpen, setIsFilterModalOpen] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(false);
87
99
  const [activeId, setActiveId] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(null);
88
100
  const mountedRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(false);
89
101
  const resizeEmitTimeoutRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(null);
102
+ const lastSelectedRow = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(void 0);
103
+ const { refs, x: bulkSelectionModalXCoordinate } = (0, __WEBPACK_EXTERNAL_MODULE__floating_ui_react_dom_d5bb3c23__.useFloating)({
104
+ placement: "bottom",
105
+ whileElementsMounted: __WEBPACK_EXTERNAL_MODULE__floating_ui_react_dom_d5bb3c23__.autoUpdate
106
+ });
90
107
  const scrollRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(null);
91
108
  const [scrollContainerWidth, setScrollContainerWidth] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(0);
109
+ const enableRowSelection = bulkActions.length + secondaryBulkActions.length > 0;
110
+ const isRowSelectable = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((row)=>{
111
+ const allBulkActions = [
112
+ ...bulkActions,
113
+ ...secondaryBulkActions
114
+ ];
115
+ return allBulkActions.some((bulkAction)=>!bulkAction.predicate || bulkAction.predicate(row.original));
116
+ }, [
117
+ bulkActions,
118
+ secondaryBulkActions
119
+ ]);
92
120
  const sensors = (0, __WEBPACK_EXTERNAL_MODULE__dnd_kit_core_a545325d__.useSensors)((0, __WEBPACK_EXTERNAL_MODULE__dnd_kit_core_a545325d__.useSensor)(__WEBPACK_EXTERNAL_MODULE__dnd_kit_core_a545325d__.MouseSensor, {
93
121
  activationConstraint: {
94
122
  distance: 10
@@ -102,13 +130,14 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
102
130
  const columnDefs = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>{
103
131
  const columnHelper = (0, __WEBPACK_EXTERNAL_MODULE__tanstack_react_table_777e1b4b__.createColumnHelper)();
104
132
  const result = columns.map((column)=>{
105
- const { filter, header, id, cell, globalFiltering, type, size, enableSorting, sortUndefined } = column;
133
+ const { filter, header, id, cell, globalFiltering, type, size, enableSorting, sortingFn, sortUndefined } = column;
106
134
  const columnSize = view.columns?.find((col)=>col.id === id)?.size ?? size ?? 150;
107
135
  const tableFilter = filter ? asFilter(filter) : void 0;
108
136
  if ("accessor" === type || void 0 === type) return columnHelper.accessor((row)=>column.value(row), {
109
137
  cell: cell ? (props)=>cell(props.row.original) : void 0,
110
138
  enableGlobalFilter: false !== globalFiltering,
111
139
  enableSorting: enableSorting ?? true,
140
+ sortingFn: sortingFn ?? "auto",
112
141
  filterFn: tableFilter ? (row, _, filterValue)=>{
113
142
  const f = tableFilter;
114
143
  if (f.isMulti && Array.isArray(filterValue)) {
@@ -142,9 +171,56 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
142
171
  }
143
172
  });
144
173
  });
145
- return result;
174
+ const rowSelectionColumn = enableRowSelection ? columnHelper.display({
175
+ id: selectColumnId,
176
+ header: ({ table })=>{
177
+ const selectableRows = table.getRowModel().rows.filter((row)=>row.getCanSelect());
178
+ const allRowsSelected = table.getIsAllRowsSelected();
179
+ return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__inputs_CheckboxInput_js_0c849015__["default"], {
180
+ disabled: 0 === selectableRows.length,
181
+ value: allRowsSelected,
182
+ onChange: ()=>{
183
+ table.toggleAllRowsSelected(!(allRowsSelected || table.getIsSomeRowsSelected()));
184
+ },
185
+ indeterminate: table.getIsSomeRowsSelected()
186
+ });
187
+ },
188
+ cell: ({ table, row })=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__inputs_CheckboxInput_js_0c849015__["default"], {
189
+ disabled: !row.getCanSelect(),
190
+ value: row.getIsSelected(),
191
+ onClick: (event)=>{
192
+ if (event.shiftKey && lastSelectedRow.current) {
193
+ const visibleRows = table.getRowModel().rows;
194
+ const visibleIndex = visibleRows.findIndex((r)=>r.id === row.id);
195
+ const lastIndex = visibleRows.findIndex((r)=>r.id === lastSelectedRow.current?.id);
196
+ const startIndex = Math.min(lastIndex, visibleIndex);
197
+ const endIndex = Math.max(lastIndex, visibleIndex);
198
+ const rowsToSelect = visibleRows.slice(startIndex, endIndex + 1).filter((r)=>0 === r.subRows.length && r.getCanSelect());
199
+ rowsToSelect.forEach((rowToSelect)=>rowToSelect.toggleSelected(!row.getIsSelected()));
200
+ }
201
+ lastSelectedRow.current = row;
202
+ },
203
+ onChange: (value)=>{
204
+ row.toggleSelected(value);
205
+ }
206
+ }),
207
+ size: 45,
208
+ minSize: 45,
209
+ enableSorting: false,
210
+ enableHiding: false,
211
+ enableResizing: false,
212
+ enableColumnFilter: false,
213
+ meta: {
214
+ fixedWidth: true
215
+ }
216
+ }) : void 0;
217
+ return [
218
+ rowSelectionColumn,
219
+ ...result
220
+ ].filter((column)=>void 0 !== column);
146
221
  }, [
147
222
  columns,
223
+ enableRowSelection,
148
224
  view.columns
149
225
  ]);
150
226
  const filterableColumns = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>columns.filter((column)=>void 0 !== column.filter && column.filter.options.length > 0), [
@@ -179,16 +255,29 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
179
255
  columnFilters: columnFiltersInitialState,
180
256
  sorting: view.sorting,
181
257
  grouping: [],
182
- columnVisibility: Object.fromEntries(columns.map((col)=>[
258
+ columnVisibility: Object.fromEntries([
259
+ ...enableRowSelection ? [
260
+ {
261
+ id: selectColumnId
262
+ }
263
+ ] : [],
264
+ ...columns.map((col)=>({
265
+ id: col.id
266
+ }))
267
+ ].map((col)=>[
183
268
  col.id,
184
- view.columns.some((c)=>c.id === col.id)
269
+ col.id === selectColumnId || view.columns.some((viewColumn)=>viewColumn.id === col.id)
185
270
  ])),
186
271
  columnOrder: [
272
+ ...enableRowSelection ? [
273
+ selectColumnId
274
+ ] : [],
187
275
  ...view.columns.map((col)=>col.id)
188
276
  ],
189
277
  globalFilter: ""
190
278
  }), [
191
279
  columns,
280
+ enableRowSelection,
192
281
  view,
193
282
  columnFiltersInitialState
194
283
  ]);
@@ -214,15 +303,28 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
214
303
  getColumnCanGlobalFilter,
215
304
  columnResizeMode: "onChange",
216
305
  enableColumnResizing: true,
306
+ enableRowSelection: enableRowSelection ? isRowSelectable : false,
217
307
  initialState: mountedRef.current ? {
218
308
  expanded: true,
219
309
  columnFilters: columnFiltersInitialState,
220
310
  sorting: view.sorting,
221
- columnVisibility: Object.fromEntries(columns.map((col)=>[
311
+ columnVisibility: Object.fromEntries([
312
+ ...enableRowSelection ? [
313
+ {
314
+ id: selectColumnId
315
+ }
316
+ ] : [],
317
+ ...columns.map((col)=>({
318
+ id: col.id
319
+ }))
320
+ ].map((col)=>[
222
321
  col.id,
223
- view.columns.some((c)=>c.id === col.id)
322
+ col.id === selectColumnId || view.columns.some((viewColumn)=>viewColumn.id === col.id)
224
323
  ])),
225
324
  columnOrder: [
325
+ ...enableRowSelection ? [
326
+ selectColumnId
327
+ ] : [],
226
328
  ...view.columns.map((col)=>col.id)
227
329
  ],
228
330
  globalFilter: ""
@@ -233,7 +335,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
233
335
  enableGlobalFilter: false,
234
336
  enableSorting: false,
235
337
  size: 150,
236
- minSize: 50
338
+ minSize: 100
237
339
  }
238
340
  });
239
341
  const tableState = reactTable.getState();
@@ -303,7 +405,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
303
405
  }, []);
304
406
  const emitView = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)(()=>{
305
407
  onViewChange({
306
- columns: Object.entries(reactTable.getState().columnVisibility).filter(([, visible])=>visible).map(([id])=>({
408
+ columns: Object.entries(reactTable.getState().columnVisibility).filter(([id, visible])=>visible && id !== selectColumnId).map(([id])=>({
307
409
  id: id,
308
410
  size: reactTable.getColumn(id)?.getSize() ?? 150
309
411
  })).sort((a, b)=>{
@@ -312,6 +414,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
312
414
  return aIndex - bIndex;
313
415
  }),
314
416
  filters: reactTable.getState().columnFilters.filter((filter)=>{
417
+ if (filter.id === selectColumnId) return false;
315
418
  const column = reactTable.getColumn(filter.id);
316
419
  return column?.getIsVisible();
317
420
  }).map((filter)=>({
@@ -365,6 +468,18 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
365
468
  reactTable
366
469
  ]);
367
470
  const hasFilterableColumns = filterableColumnsForModal.length > 0;
471
+ (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
472
+ if (!enableRowSelection) return;
473
+ if (columnOrder[0] === selectColumnId) return;
474
+ reactTable.setColumnOrder([
475
+ selectColumnId,
476
+ ...columnOrder.filter((id)=>id !== selectColumnId)
477
+ ]);
478
+ }, [
479
+ columnOrder,
480
+ enableRowSelection,
481
+ reactTable
482
+ ]);
368
483
  const applyColumnSelection = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((selected)=>{
369
484
  if (0 === availableColumnGroups.length) return;
370
485
  const availableIds = new Set(availableColumnGroups.flatMap((group)=>group.columns.map((c)=>c.id)));
@@ -397,6 +512,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
397
512
  const handleDragEnd = (event)=>{
398
513
  const { active, over } = event;
399
514
  setActiveId(null);
515
+ if (active.id === selectColumnId || over?.id === selectColumnId) return;
400
516
  if (over && active.id !== over.id) {
401
517
  const order = reactTable.getState().columnOrder;
402
518
  const oldIndex = order.indexOf(active.id);
@@ -405,6 +521,14 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
405
521
  }
406
522
  };
407
523
  const getColumnStyle = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((column)=>{
524
+ if (column.columnDef.meta?.fixedWidth === true) {
525
+ const size = column.getSize();
526
+ return {
527
+ width: `${size}px`,
528
+ minWidth: `${size}px`,
529
+ maxWidth: `${size}px`
530
+ };
531
+ }
408
532
  if (!mountedRef.current) return {
409
533
  width: `${column.getSize()}px`,
410
534
  minWidth: "50px"
@@ -432,9 +556,129 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
432
556
  ]);
433
557
  const showTableFilterBar = 0 !== globalFilterableColumns.length || 0 !== filterableColumns.length || 0 !== availableColumnGroups.length;
434
558
  const tableLayoutWidthPx = reactTable.getTotalSize();
559
+ const visibleLeafColumns = reactTable.getVisibleLeafColumns();
560
+ const visibleDataColumnCount = visibleLeafColumns.filter((column)=>column.id !== selectColumnId).length;
561
+ const shouldShowCsvExport = csvExportableColumns.length > 0 && csvFilename;
562
+ const filteredSelectedRows = reactTable.getFilteredSelectedRowModel();
563
+ const validPrimaryBulkActions = bulkActions.filter((bulkAction)=>filteredSelectedRows.rows.some((row)=>bulkAction.predicate ? bulkAction.predicate(row.original) : true));
564
+ const validSecondaryBulkActions = secondaryBulkActions.filter((bulkAction)=>filteredSelectedRows.rows.some((row)=>bulkAction.predicate ? bulkAction.predicate(row.original) : true));
565
+ const shouldShowMoreActions = validSecondaryBulkActions.length > 0 || shouldShowCsvExport;
566
+ const getBulkActionRows = (bulkAction)=>filteredSelectedRows.flatRows.filter((row)=>bulkAction.predicate ? bulkAction.predicate(row.original) : true).map((row)=>row.original);
567
+ const primaryBulkActionRowsMap = new Map(validPrimaryBulkActions.map((bulkAction)=>[
568
+ bulkAction.key,
569
+ getBulkActionRows(bulkAction)
570
+ ]));
571
+ const secondaryBulkActionRowsMap = new Map(validSecondaryBulkActions.map((bulkAction)=>[
572
+ bulkAction.key,
573
+ getBulkActionRows(bulkAction)
574
+ ]));
575
+ const allBulkActionRowCounts = [
576
+ ...Array.from(primaryBulkActionRowsMap.values()).map((actionRows)=>actionRows.length),
577
+ ...Array.from(secondaryBulkActionRowsMap.values()).map((actionRows)=>actionRows.length)
578
+ ];
579
+ const bulkActionRowCountsDiffer = new Set(allBulkActionRowCounts).size > 1;
580
+ const hasMultipleActions = allBulkActionRowCounts.length > 1;
581
+ const allRowsCanDoAllActions = hasMultipleActions && allBulkActionRowCounts.every((count)=>count === filteredSelectedRows.rows.length);
582
+ const showBulkActionCounts = bulkActionRowCountsDiffer || hasMultipleActions && !allRowsCanDoAllActions;
435
583
  return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
436
584
  className: __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].root,
585
+ ref: refs.setReference,
437
586
  children: [
587
+ validPrimaryBulkActions.length > 0 || validSecondaryBulkActions.length > 0 ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
588
+ ref: refs.setFloating,
589
+ className: __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].bulkSelectionModal,
590
+ style: {
591
+ left: bulkSelectionModalXCoordinate
592
+ },
593
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Card_js_2e00482a__["default"], {
594
+ hasShadow: true,
595
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__CardContent_js_bacbf899__["default"], {
596
+ spacing: "00",
597
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
598
+ className: __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].bulkSelectionModalContent,
599
+ children: [
600
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)(__WEBPACK_EXTERNAL_MODULE__HStack_js_5c2eb952__["default"], {
601
+ spacing: "n2",
602
+ align: "center",
603
+ children: [
604
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Badge_js_a2cbb2b8__["default"], {
605
+ color: "purple",
606
+ children: filteredSelectedRows.rows.length
607
+ }),
608
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__PlainText_js_6d36b5d5__["default"], {
609
+ font: "regular-bold",
610
+ children: "selected"
611
+ })
612
+ ]
613
+ }),
614
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
615
+ className: __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].bulkSelectionActions,
616
+ children: [
617
+ validPrimaryBulkActions.map((bulkAction)=>{
618
+ const actionRows = primaryBulkActionRowsMap.get(bulkAction.key) ?? [];
619
+ return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_Disclosure_js_07249afc__["default"], {
620
+ icon: bulkAction.icon,
621
+ render: (onClose)=>bulkAction.render({
622
+ rows: actionRows,
623
+ resetRowSelection: ()=>reactTable.resetRowSelection(),
624
+ onClose
625
+ }),
626
+ children: showBulkActionCounts ? `${bulkAction.label} (${actionRows.length})` : bulkAction.label
627
+ }, bulkAction.key);
628
+ }),
629
+ shouldShowMoreActions ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_MenuButton_js_fa7c5c89__["default"], {
630
+ id: "bulkActionOverflow",
631
+ ariaLabel: "More actions",
632
+ type: "ghost",
633
+ options: [
634
+ ...validSecondaryBulkActions.map((bulkAction)=>{
635
+ const actionRows = secondaryBulkActionRowsMap.get(bulkAction.key) ?? [];
636
+ return {
637
+ id: bulkAction.key,
638
+ label: showBulkActionCounts ? `${bulkAction.label} (${actionRows.length})` : bulkAction.label,
639
+ icon: bulkAction.icon,
640
+ type: "render",
641
+ render: (onClose)=>bulkAction.render({
642
+ rows: actionRows,
643
+ resetRowSelection: ()=>reactTable.resetRowSelection(),
644
+ onClose
645
+ })
646
+ };
647
+ }),
648
+ ...shouldShowCsvExport ? [
649
+ {
650
+ id: "download-selected-rows",
651
+ label: "Download CSV",
652
+ icon: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Icon_js_e5f9af80__["default"], {
653
+ symbol: "Download",
654
+ size: "small"
655
+ }),
656
+ type: "onClick",
657
+ onClick: ()=>(0, __WEBPACK_EXTERNAL_MODULE__utils_tables_js_ad146866__.handleDownloadCsv)(csvFilename, csvExportableColumns, reactTable.getSelectedRowModel().rows)
658
+ }
659
+ ] : []
660
+ ],
661
+ icon: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Icon_js_e5f9af80__["default"], {
662
+ symbol: "Overflow"
663
+ })
664
+ }) : null,
665
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_Button_js_2f50b64a__["default"], {
666
+ icon: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Icon_js_e5f9af80__["default"], {
667
+ symbol: "Close"
668
+ }),
669
+ onClick: ()=>{
670
+ reactTable.resetRowSelection(true);
671
+ },
672
+ title: `Deselect ${reactTable.getFilteredSelectedRowModel().rows.length} ${1 === reactTable.getFilteredSelectedRowModel().rows.length ? "selection" : "selections"}`,
673
+ type: "ghost"
674
+ })
675
+ ]
676
+ })
677
+ ]
678
+ })
679
+ })
680
+ })
681
+ }) : null,
438
682
  /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
439
683
  className: __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].mainColumn,
440
684
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
@@ -491,7 +735,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
491
735
  }),
492
736
  children: "Columns"
493
737
  }) : null,
494
- data.length > 0 ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_Button_js_2f50b64a__["default"], {
738
+ data.length > 0 && shouldShowCsvExport ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_Button_js_2f50b64a__["default"], {
495
739
  type: "secondary",
496
740
  icon: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Icon_js_e5f9af80__["default"], {
497
741
  symbol: "Download"
@@ -580,14 +824,14 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
580
824
  className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableRow, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].row),
581
825
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("td", {
582
826
  className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].noRows, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].loadingCell),
583
- colSpan: Math.max(reactTable.getVisibleLeafColumns().length, 1),
827
+ colSpan: Math.max(visibleLeafColumns.length, 1),
584
828
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__Icon_js_e5f9af80__["default"], {
585
829
  symbol: "Loading",
586
830
  size: "large",
587
831
  animate: true
588
832
  })
589
833
  })
590
- }) : 0 === reactTable.getVisibleLeafColumns().length ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("tr", {
834
+ }) : 0 === visibleDataColumnCount ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("tr", {
591
835
  className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableRow, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].row),
592
836
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("td", {
593
837
  className: __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].noRows,
@@ -605,7 +849,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
605
849
  transform: `translateY(${virtualRow.start}px)`
606
850
  },
607
851
  children: row.getVisibleCells().map((cell)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("td", {
608
- className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableCell, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].cell),
852
+ className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableCell, cell.column.id === selectColumnId ? __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].selectionCell : void 0, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].cell),
609
853
  style: {
610
854
  ...getColumnStyle(cell.column),
611
855
  flexGrow: 0
@@ -620,7 +864,7 @@ const CustomizableTable = ({ data, columns, csvFilename, getRowId, availableColu
620
864
  className: (0, __WEBPACK_EXTERNAL_MODULE_clsx__["default"])(__WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].tableRow, __WEBPACK_EXTERNAL_MODULE__CustomizableTable_module_js_80cff08d__["default"].row),
621
865
  children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("td", {
622
866
  className: __WEBPACK_EXTERNAL_MODULE__Table_module_js_61474ffd__["default"].noRows,
623
- colSpan: reactTable.getVisibleLeafColumns().length,
867
+ colSpan: visibleLeafColumns.length,
624
868
  children: emptyState
625
869
  })
626
870
  })
@@ -7,7 +7,7 @@
7
7
  }
8
8
 
9
9
  .columnStack-supahl {
10
- gap: var(--size-p2);
10
+ gap: var(--size-n1);
11
11
  flex-direction: column;
12
12
  flex: 1;
13
13
  min-width: 0;
@@ -64,13 +64,10 @@
64
64
 
65
65
  .cell-TKX6Qc {
66
66
  border-right: solid var(--size-n5) var(--color-grey-t08);
67
- padding-left: var(--size-00);
68
- padding-top: var(--size-00);
69
- padding-bottom: var(--size-00);
67
+ padding: var(--size-n1);
70
68
  }
71
69
 
72
70
  .cell-TKX6Qc:last-child {
73
- padding-right: var(--size-00);
74
71
  border-right: none;
75
72
  }
76
73
 
@@ -99,16 +96,10 @@
99
96
 
100
97
  .headerCell-HsDaea {
101
98
  cursor: grab;
102
- padding-top: var(--size-00);
103
- padding-bottom: var(--size-00);
104
- padding-left: var(--size-00);
99
+ padding: var(--size-n1);
105
100
  position: relative;
106
101
  }
107
102
 
108
- .headerCell-HsDaea:last-child {
109
- padding-right: var(--size-00);
110
- }
111
-
112
103
  .headerSortable-fnjI8P {
113
104
  gap: var(--size-n2);
114
105
  text-align: left;
@@ -77,10 +77,13 @@ type CommonProps<Type> = {
77
77
  * (`rowMainCompact`).
78
78
  * - Main-slot `prefixOnWide` / `suffixOnWide` adornments are hidden
79
79
  * (`rowListAtCompactBreakpoint`).
80
- * - Hover-only controls become always-visible (row bulk-action checkbox lane,
81
- * toolbar select-all) and toolbar button labels collapse to icons. These rules
82
- * live in CSS keyed off the `data-richlist-compact` attribute that JS sets on
83
- * `.richListQueryScope` from this same `isCompactContentSlots` signal.
80
+ * - Hover-only row select become always-visible (row bulk-action checkbox lane,
81
+ * toolbar select-all) and **modal** toolbar button labels collapse to icons **only**
82
+ * for Buttons with `.toolbarButtonLabel` (Filters modal, Display, CSV). A **single**
83
+ * single-column filter is rendered as an inline label-less `MenuButton` in the toolbar
84
+ * instead (`filter.label` is not shown there; optional `aria-label` only).
85
+ * That control is not collapsed this way. Label collapse rules live in CSS keyed off
86
+ * `data-richlist-compact` on `.richListQueryScope` from `isCompactContentSlots`.
84
87
  * - The Display dialog's column-visibility section is hidden (no room).
85
88
  *
86
89
  * @default `RICH_LIST_CONTENT_COMPACT_MAX_PX` (1024); see `helpers.ts`