@techsio/ui-kit 0.37.0 → 0.38.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.
@@ -0,0 +1,1736 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
3
+ import { restrictToHorizontalAxis, restrictToVerticalAxis } from "@dnd-kit/modifiers";
4
+ import { SortableContext, arrayMove, horizontalListSortingStrategy, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
5
+ import { CSS } from "@dnd-kit/utilities";
6
+ import { flexRender, useTable } from "@tanstack/react-table";
7
+ import { useVirtualizer } from "@tanstack/react-virtual";
8
+ import { Fragment as external_react_Fragment, createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
9
+ import { ActionIcon } from "../atoms/action-icon.js";
10
+ import { Button } from "../atoms/button.js";
11
+ import { Checkbox } from "../atoms/checkbox.js";
12
+ import { Icon } from "../atoms/icon.js";
13
+ import { Skeleton } from "../atoms/skeleton.js";
14
+ import { Menu } from "../molecules/menu.js";
15
+ import { Pagination } from "../molecules/pagination.js";
16
+ import { SearchForm } from "../molecules/search-form.js";
17
+ import { tv } from "../utils.js";
18
+ import { DEFAULT_EDITOR_RENDERERS, DEFAULT_FILTER_RENDERERS, FieldSelect, columnLabel, isBlank } from "./data-table.fields.js";
19
+ import { DATA_TABLE_Z, applyColumnDefaults, conditionalFilterFn, dataTableFeatures, getColumnSizeStyles, getPinningStyles, isFirstEndPinned, isLastStartPinned, resolveColumnType } from "./data-table.helpers.js";
20
+ import { Table } from "./table.js";
21
+ const dataTableVariants = tv({
22
+ slots: {
23
+ wrapper: [
24
+ "flex w-full flex-col overflow-hidden rounded-table",
25
+ "border-(length:--border-table-width) border-table-border"
26
+ ],
27
+ toolbar: [
28
+ "flex items-center justify-between gap-200",
29
+ "bg-table-header-bg text-table-header-fg",
30
+ "px-300 py-200",
31
+ "border-b-(length:--border-table-width) border-table-border"
32
+ ],
33
+ toolbarSearch: [
34
+ "min-w-0 flex-1"
35
+ ],
36
+ toolbarActions: [
37
+ "flex shrink-0 items-center gap-200"
38
+ ],
39
+ scroll: [
40
+ "relative w-full overflow-auto"
41
+ ],
42
+ headerLabel: [
43
+ "inline-flex items-center gap-100 whitespace-nowrap"
44
+ ],
45
+ sortButton: [
46
+ "inline-flex items-center gap-100 whitespace-nowrap",
47
+ "cursor-pointer select-none bg-transparent text-left",
48
+ "data-[disabled=true]:cursor-default"
49
+ ],
50
+ sortIcon: [
51
+ "text-fg-secondary",
52
+ "data-[active=true]:text-fg-accent-primary"
53
+ ],
54
+ dragHandle: [
55
+ "inline-flex cursor-grab items-center rounded-table text-fg-secondary",
56
+ "opacity-0 transition-opacity duration-200 motion-reduce:transition-none",
57
+ "hover:bg-table-row-bg-hover hover:opacity-100 focus-visible:opacity-100",
58
+ "group-hover/header:opacity-100 group-hover/row:opacity-100",
59
+ "group-focus-within/header:opacity-100 group-focus-within/row:opacity-100",
60
+ "group-data-dragging/header:opacity-100 group-data-dragging/row:opacity-100",
61
+ "active:cursor-grabbing"
62
+ ],
63
+ resizeHandle: [
64
+ "absolute end-0 top-0 h-full w-100 cursor-col-resize touch-none select-none",
65
+ "opacity-0 transition-opacity duration-200 motion-reduce:transition-none",
66
+ "bg-table-border hover:opacity-100 focus-visible:opacity-100",
67
+ "group-hover/header:opacity-100"
68
+ ],
69
+ filterRow: [
70
+ "bg-table-header-bg"
71
+ ],
72
+ filterCell: [
73
+ "px-200 py-100",
74
+ "min-w-fit",
75
+ "border-b-(length:--border-table-width) border-table-border"
76
+ ],
77
+ filterControl: [
78
+ "flex flex-wrap items-center gap-100"
79
+ ],
80
+ editorControl: [
81
+ "flex flex-col gap-50"
82
+ ],
83
+ editorError: [
84
+ "text-danger-fg text-table-sm"
85
+ ],
86
+ actionsCell: [
87
+ "flex items-center justify-end gap-100"
88
+ ],
89
+ empty: [
90
+ "flex flex-col items-center justify-center gap-200",
91
+ "p-700 text-center text-fg-secondary"
92
+ ],
93
+ paginationBar: [
94
+ "flex flex-wrap items-center justify-between gap-300",
95
+ "bg-table-header-bg text-table-header-fg",
96
+ "px-300 py-200",
97
+ "border-t-(length:--border-table-width) border-table-border"
98
+ ],
99
+ detailBox: [
100
+ "w-full p-300"
101
+ ],
102
+ paginationInfo: [
103
+ "whitespace-nowrap text-table-sm"
104
+ ],
105
+ paginationControls: [
106
+ "flex items-center gap-300"
107
+ ]
108
+ },
109
+ variants: {
110
+ outlined: {
111
+ true: {
112
+ wrapper: "shadow-table-outline"
113
+ }
114
+ }
115
+ }
116
+ });
117
+ const DATA_TABLE_MAX_TOOLBAR_ACTIONS = 3;
118
+ function useControllable(controlled, initial, callback) {
119
+ const [internal, setInternal] = useState(initial);
120
+ const isControlled = void 0 !== controlled;
121
+ const value = isControlled ? controlled : internal;
122
+ const latest = useRef(value);
123
+ latest.current = value;
124
+ const onChange = (updater)=>{
125
+ const next = "function" == typeof updater ? updater(latest.current) : updater;
126
+ latest.current = next;
127
+ if (!isControlled) setInternal(next);
128
+ callback?.(next);
129
+ };
130
+ return [
131
+ value,
132
+ onChange
133
+ ];
134
+ }
135
+ function dropEdge(sortable, edges) {
136
+ if (!sortable.isOver || sortable.isDragging) return;
137
+ return sortable.activeIndex < sortable.overIndex ? edges.after : edges.before;
138
+ }
139
+ function SortableHeaderContent({ columnId, children }) {
140
+ const sortable = useSortable({
141
+ id: columnId,
142
+ data: {
143
+ type: "column"
144
+ }
145
+ });
146
+ const style = {
147
+ transform: CSS.Translate.toString(sortable.transform),
148
+ transition: sortable.transition,
149
+ opacity: sortable.isDragging ? 0.4 : 1
150
+ };
151
+ const dropSide = dropEdge({
152
+ isOver: sortable.isOver,
153
+ isDragging: sortable.isDragging,
154
+ activeIndex: sortable.activeIndex ?? 0,
155
+ overIndex: sortable.overIndex ?? 0
156
+ }, {
157
+ after: "end",
158
+ before: "start"
159
+ });
160
+ return /*#__PURE__*/ jsx(Fragment, {
161
+ children: children({
162
+ setActivatorNodeRef: sortable.setActivatorNodeRef,
163
+ listeners: sortable.listeners,
164
+ style,
165
+ setNodeRef: sortable.setNodeRef,
166
+ isDragging: sortable.isDragging,
167
+ dropSide,
168
+ attributes: sortable.attributes
169
+ })
170
+ });
171
+ }
172
+ function SortableRow({ row, enabled, children }) {
173
+ const sortable = useSortable({
174
+ id: row.id,
175
+ disabled: !enabled,
176
+ data: {
177
+ type: "row"
178
+ }
179
+ });
180
+ const style = {
181
+ transform: CSS.Transform.toString(sortable.transform),
182
+ transition: sortable.transition,
183
+ opacity: sortable.isDragging ? 0.4 : 1,
184
+ position: "relative",
185
+ zIndex: sortable.isDragging ? 1 : void 0
186
+ };
187
+ const dropSide = dropEdge({
188
+ isOver: sortable.isOver,
189
+ isDragging: sortable.isDragging,
190
+ activeIndex: sortable.activeIndex ?? 0,
191
+ overIndex: sortable.overIndex ?? 0
192
+ }, {
193
+ after: "bottom",
194
+ before: "top"
195
+ });
196
+ const dragHandleProps = {
197
+ ref: sortable.setActivatorNodeRef,
198
+ ...sortable.attributes,
199
+ ...sortable.listeners
200
+ };
201
+ return /*#__PURE__*/ jsx(Fragment, {
202
+ children: children({
203
+ setNodeRef: sortable.setNodeRef,
204
+ style,
205
+ dragHandleProps,
206
+ isDragging: sortable.isDragging,
207
+ dropSide
208
+ })
209
+ });
210
+ }
211
+ const DataTableContext = /*#__PURE__*/ createContext(null);
212
+ function useDataTableContext() {
213
+ const ctx = useContext(DataTableContext);
214
+ if (!ctx) throw new Error("DataTable sub-components must be used within DataTable");
215
+ return ctx;
216
+ }
217
+ const DEFAULT_TRANSLATIONS = {
218
+ searchPlaceholder: "Search…",
219
+ searchLabel: "Search",
220
+ clearSearchLabel: "Clear search",
221
+ searchButtonLabel: "Submit search",
222
+ columnsLabel: "Column settings",
223
+ emptyTitle: "No records",
224
+ emptyDescription: "There is no data to display.",
225
+ pageSizeLabel: "Rows per page",
226
+ actionsLabel: "Actions",
227
+ filtersLabel: "Column filters",
228
+ selectAllLabel: "Select all rows",
229
+ loadingLabel: "Loading data",
230
+ operatorLabels: {},
231
+ editingLabel: "Editing a row — other table controls are locked",
232
+ rangeLabel: ({ start, end, total })=>`${start}–${end} of ${total}`,
233
+ requiredLabel: "Required"
234
+ };
235
+ const SELECTION_COLUMN_ID = "__select";
236
+ const EMPTY_COLUMN_PINNING = {
237
+ start: [],
238
+ end: []
239
+ };
240
+ const DRAG_COLUMN_ID = "__drag";
241
+ const BUILTIN_COLUMN_IDS = new Set([
242
+ SELECTION_COLUMN_ID,
243
+ DRAG_COLUMN_ID
244
+ ]);
245
+ function pinClass(column, kind) {
246
+ if (!column.getIsPinned()) return;
247
+ return [
248
+ "header" === kind ? "bg-table-header-bg" : "data-table-frozen-cell",
249
+ isLastStartPinned(column) ? "border-e-(length:--border-table-width) border-table-border" : "",
250
+ isFirstEndPinned(column) ? "border-s-(length:--border-table-width) border-table-border" : ""
251
+ ].join(" ");
252
+ }
253
+ function HeaderDragHandle({ styles, setActivatorNodeRef, listeners, attributes, label }) {
254
+ return /*#__PURE__*/ jsx("button", {
255
+ "aria-label": `Drag to reorder ${label}`,
256
+ className: styles.dragHandle(),
257
+ ref: setActivatorNodeRef,
258
+ type: "button",
259
+ ...attributes,
260
+ ...listeners,
261
+ children: /*#__PURE__*/ jsx(Icon, {
262
+ icon: "icon-[mdi--drag-vertical]",
263
+ size: "current"
264
+ })
265
+ });
266
+ }
267
+ function HeaderSortLabel({ header, styles, enableSorting, locked }) {
268
+ const column = header.column;
269
+ const canSort = enableSorting && column.getCanSort();
270
+ const sortDir = column.getIsSorted();
271
+ const label = header.isPlaceholder ? null : flexRender(column.columnDef.header, header.getContext());
272
+ if (!canSort) return /*#__PURE__*/ jsx(Fragment, {
273
+ children: label
274
+ });
275
+ let sortIconName = "icon-[mdi--unfold-more-horizontal]";
276
+ if ("desc" === sortDir) sortIconName = "token-icon-chevron-down";
277
+ else if ("asc" === sortDir) sortIconName = "token-icon-chevron-up";
278
+ return /*#__PURE__*/ jsxs("button", {
279
+ className: styles.sortButton(),
280
+ "data-disabled": locked || void 0,
281
+ disabled: locked,
282
+ onClick: (event)=>column.getToggleSortingHandler()?.(event),
283
+ type: "button",
284
+ children: [
285
+ label,
286
+ /*#__PURE__*/ jsx(Icon, {
287
+ className: styles.sortIcon(),
288
+ "data-active": !!sortDir,
289
+ icon: sortIconName,
290
+ size: "current"
291
+ })
292
+ ]
293
+ });
294
+ }
295
+ function renderCellContent({ cell, column, styles, enableRowReorder, dnd, editor, editorError, editorErrorId, isDragCol, rowLabel }) {
296
+ if (isDragCol && enableRowReorder && dnd) return /*#__PURE__*/ jsx("button", {
297
+ "aria-label": `Drag to reorder ${rowLabel}`,
298
+ className: styles.dragHandle(),
299
+ onClick: (e)=>e.stopPropagation(),
300
+ type: "button",
301
+ ...dnd.dragHandleProps,
302
+ children: /*#__PURE__*/ jsx(Icon, {
303
+ icon: "icon-[mdi--drag-horizontal]",
304
+ size: "current"
305
+ })
306
+ });
307
+ if (editor) return /*#__PURE__*/ jsxs("div", {
308
+ className: styles.editorControl(),
309
+ "data-editor-control": "",
310
+ children: [
311
+ editor,
312
+ editorError ? /*#__PURE__*/ jsx("span", {
313
+ className: styles.editorError(),
314
+ id: editorErrorId,
315
+ role: "alert",
316
+ children: editorError
317
+ }) : null
318
+ ]
319
+ });
320
+ return flexRender(column.columnDef.cell, cell.getContext());
321
+ }
322
+ function stickyRowOffset(stickyHeader, offsets, groupIndex) {
323
+ if (!stickyHeader) return;
324
+ return {
325
+ top: offsets[groupIndex] ?? 0
326
+ };
327
+ }
328
+ function DataTableBodyCell({ cell, span, row, styles, columnSizing, enableColumnResizing, enableRowReorder, dnd, editor, editorError, editorErrorId, indentColumnId, rowLabel }) {
329
+ const column = cell.column;
330
+ const pinned = column.getIsPinned();
331
+ const isDragCol = column.id === DRAG_COLUMN_ID;
332
+ const indent = row.depth > 0 && column.id === indentColumnId ? {
333
+ paddingInlineStart: `${1.5 * row.depth}rem`
334
+ } : void 0;
335
+ return /*#__PURE__*/ jsx(Table.Cell, {
336
+ align: column.columnDef.meta?.align,
337
+ className: pinClass(column, "body"),
338
+ colSpan: span?.colSpan,
339
+ "data-pinned": pinned || void 0,
340
+ rowSpan: span?.rowSpan,
341
+ style: {
342
+ ...getPinningStyles(column),
343
+ ...getColumnSizeStyles(column, enableColumnResizing, columnSizing),
344
+ ...indent
345
+ },
346
+ children: renderCellContent({
347
+ cell,
348
+ column,
349
+ styles,
350
+ enableRowReorder,
351
+ dnd,
352
+ editor,
353
+ editorError,
354
+ editorErrorId,
355
+ isDragCol,
356
+ rowLabel
357
+ })
358
+ });
359
+ }
360
+ function validateDraft(columns, draft, requiredLabel) {
361
+ const errors = {};
362
+ for (const column of columns){
363
+ const meta = column.columnDef.meta;
364
+ if (!meta?.editable) continue;
365
+ const value = draft[column.id];
366
+ const empty = isBlank(value) || "number" == typeof value && Number.isNaN(value) || Array.isArray(value) && 0 === value.length;
367
+ if (meta.required && empty) {
368
+ errors[column.id] = requiredLabel;
369
+ continue;
370
+ }
371
+ const message = meta.validate?.(value, draft);
372
+ if (message) errors[column.id] = message;
373
+ }
374
+ return errors;
375
+ }
376
+ function renderExpandedDetailRow({ row, renderExpandedRow, colSpan, instanceId, styles, tintNestedRows }) {
377
+ return /*#__PURE__*/ jsx(Table.Row, {
378
+ className: tintNestedRows ? "data-table-row-nested-tint" : void 0,
379
+ "data-depth": row.depth + 1,
380
+ children: /*#__PURE__*/ jsx(Table.Cell, {
381
+ colSpan: colSpan,
382
+ children: /*#__PURE__*/ jsx("div", {
383
+ className: styles.detailBox(),
384
+ id: `${instanceId}-detail-${row.id}`,
385
+ children: renderExpandedRow(row)
386
+ })
387
+ })
388
+ });
389
+ }
390
+ function rowDragClass(dnd, opts) {
391
+ const { className, striped, tintNestedRows, rowIndex } = opts;
392
+ return [
393
+ "group/row",
394
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width) focus-visible:outline-primary",
395
+ "data-[selected=true]:[--dt-row-tint:var(--color-table-row-bg-selected)]",
396
+ "group-hover/row:[--dt-row-tint:var(--color-table-row-bg-hover)]",
397
+ "hover:[--dt-row-tint:var(--color-table-row-bg-hover)]",
398
+ striped ? `${(rowIndex ?? 0) % 2 === 0 ? "bg-table-row-striped-primary [--dt-row-tint:var(--color-table-row-striped-primary)]" : "bg-table-row-striped-secondary [--dt-row-tint:var(--color-table-row-striped-secondary)]"} border-b-0` : "",
399
+ tintNestedRows ? "data-[depth]:data-table-row-nested-tint" : "",
400
+ dnd?.isDragging ? "shadow-table-outline" : "",
401
+ dnd?.dropSide === "top" ? "border-primary border-t-2" : "",
402
+ dnd?.dropSide === "bottom" ? "border-primary border-b-2" : "",
403
+ className ?? ""
404
+ ].filter(Boolean).join(" ");
405
+ }
406
+ const OPAQUE_HEADER_BG = {
407
+ backgroundColor: "var(--color-table-bg)",
408
+ backgroundImage: "linear-gradient(var(--color-table-header-bg), var(--color-table-header-bg))"
409
+ };
410
+ function sortState(column, enableSorting) {
411
+ if (!(enableSorting && column.getCanSort())) return;
412
+ const sorted = column.getIsSorted();
413
+ if ("asc" === sorted) return "ascending";
414
+ if ("desc" === sorted) return "descending";
415
+ return "none";
416
+ }
417
+ function activateRowByKeyboard(event, activate) {
418
+ if ("Enter" !== event.key && " " !== event.key) return;
419
+ if (event.target !== event.currentTarget) return;
420
+ event.preventDefault();
421
+ activate();
422
+ }
423
+ function checkReachEnd(distance, reachEndThreshold, reachedEndRef, onReachEnd) {
424
+ if (distance <= reachEndThreshold) {
425
+ if (!reachedEndRef.current) {
426
+ reachedEndRef.current = true;
427
+ onReachEnd();
428
+ }
429
+ } else reachedEndRef.current = false;
430
+ }
431
+ const useIsomorphicLayoutEffect = "undefined" == typeof window ? useEffect : useLayoutEffect;
432
+ function clampSelection(selectedIds, previous, max) {
433
+ return [
434
+ ...selectedIds.filter((id)=>previous[id]),
435
+ ...selectedIds.filter((id)=>!previous[id])
436
+ ].slice(0, max);
437
+ }
438
+ function buildRowKeyDownHandler(row, onRowClick, blocked) {
439
+ return (event)=>activateRowByKeyboard(event, ()=>{
440
+ if (!blocked("rowClick")) onRowClick?.(row, event);
441
+ });
442
+ }
443
+ function buildRowClickHandler(row, rowOnClick, onRowClick, blocked) {
444
+ return (event)=>{
445
+ rowOnClick?.(event);
446
+ if (onRowClick && !blocked("rowClick")) onRowClick(row, event);
447
+ };
448
+ }
449
+ function editedRowElementId(instanceId, rowId) {
450
+ return `${instanceId}-editing-${rowId}`;
451
+ }
452
+ function editingRowElementId(editingRowId, instanceId, rowId) {
453
+ return editingRowId === rowId ? editedRowElementId(instanceId, rowId) : void 0;
454
+ }
455
+ function composeRowRef(dnd, consumerRef) {
456
+ return (node)=>{
457
+ dnd?.setNodeRef(node);
458
+ if ("function" == typeof consumerRef) consumerRef(node);
459
+ else if (consumerRef) consumerRef.current = node;
460
+ };
461
+ }
462
+ function DataTable(props) {
463
+ const { data, columns: userColumns, getRowId, id: idProp, className, ref, variant = "line", size = "md", stickyHeader, interactive, showColumnBorder, caption, hideHeader, maxHeight, enableSorting = true, enableGlobalFilter = false, enableColumnFilters = false, enableRowSelection = false, enableColumnVisibility = false, enableColumnPinning = false, enableColumnReorder = false, enableColumnResizing = false, tableLayout = "auto", enableRowReorder = false, enableExpanding = false, enablePagination = false, enableVirtualization = false, getSubRows, getRowCanExpand, getCellSpan, sorting: sortingProp, onSortingChange, columnFilters: columnFiltersProp, onColumnFiltersChange, globalFilter: globalFilterProp, onGlobalFilterChange, rowSelection: rowSelectionProp, onRowSelectionChange, columnVisibility: columnVisibilityProp, onColumnVisibilityChange, columnOrder: columnOrderProp, onColumnOrderChange, columnPinning: columnPinningProp, onColumnPinningChange, expanded: expandedProp, onExpandedChange, pagination: paginationProp, onPaginationChange, pageSizeOptions = [
464
+ 10,
465
+ 25,
466
+ 50,
467
+ 100
468
+ ], manualSorting, manualFiltering, manualPagination, rowCount, pageCount, onRowClick, onReachEnd, onColumnReorder, onRowReorder, onCellEditCommit, onReady, renderToolbar, toolbarActions, renderEmpty, renderRowActions, renderHeaderFilter, renderExpandedRow, slotProps, translations: translationsProp, estimateRowHeight = 44, reachEndThreshold = 240, enableInlineEdit = false, editingRowId: editingRowIdProp, onEditingRowIdChange, onEditStart, onEditChange, onEditCommit, onEditCancel, onEditValidationError, lockInteractionsWhileEditing = true, onInteractionBlocked, filterRenderers, editorRenderers, stickyActions = true, paginationProps, canEditRow, rowActions, getRowLabel, striped = false, tintNestedRows = false, loading = false, loadingRowCount = 5, loadingMore = false, selectionMode = "multiple", maxSelectedRows, canSelectRow, onSelectionLimitReached } = props;
469
+ const translations = {
470
+ ...DEFAULT_TRANSLATIONS
471
+ };
472
+ if (translationsProp) {
473
+ for (const [key, value] of Object.entries(translationsProp))if (void 0 !== value) translations[key] = value;
474
+ }
475
+ const outlined = "outline" === variant;
476
+ const effectiveStriped = striped || "striped" === variant;
477
+ const styles = dataTableVariants({
478
+ outlined
479
+ });
480
+ const generatedId = useId();
481
+ const instanceId = idProp ?? generatedId;
482
+ const scrollRef = useRef(null);
483
+ const reachedEndRef = useRef(false);
484
+ const lastReachEndCountRef = useRef(-1);
485
+ const reportedSelectionLimitRef = useRef(null);
486
+ const dataLengthRef = useRef(data.length);
487
+ dataLengthRef.current = data.length;
488
+ const fireReachEnd = ()=>{
489
+ lastReachEndCountRef.current = dataLengthRef.current;
490
+ onReachEnd?.();
491
+ };
492
+ const headerRowRefs = useRef([]);
493
+ const [headerOffsets, setHeaderOffsets] = useState([
494
+ 0
495
+ ]);
496
+ const headerHeight = headerOffsets.at(-1) ?? 0;
497
+ const [sorting, setSorting] = useControllable(sortingProp, [], onSortingChange);
498
+ const [columnFilters, setColumnFilters] = useControllable(columnFiltersProp, [], onColumnFiltersChange);
499
+ const [globalFilter, setGlobalFilter] = useControllable(globalFilterProp, "", onGlobalFilterChange);
500
+ const [rowSelection, setRowSelectionState] = useControllable(rowSelectionProp, {}, onRowSelectionChange);
501
+ const setRowSelection = (updater)=>{
502
+ let limitReached;
503
+ setRowSelectionState((old)=>{
504
+ const next = "function" == typeof updater ? updater(old) : updater;
505
+ if (null == maxSelectedRows) return next;
506
+ const selectedIds = Object.keys(next).filter((id)=>next[id]);
507
+ const previousCount = Object.keys(old).filter((id)=>old[id]).length;
508
+ if (selectedIds.length <= maxSelectedRows) {
509
+ if (selectedIds.length === maxSelectedRows && selectedIds.length > previousCount) limitReached = {
510
+ limit: maxSelectedRows,
511
+ selectedCount: selectedIds.length
512
+ };
513
+ return next;
514
+ }
515
+ const kept = clampSelection(selectedIds, old, maxSelectedRows);
516
+ limitReached = {
517
+ limit: maxSelectedRows,
518
+ selectedCount: kept.length
519
+ };
520
+ return Object.fromEntries(kept.map((id)=>[
521
+ id,
522
+ true
523
+ ]));
524
+ });
525
+ if (limitReached) onSelectionLimitReached?.(limitReached);
526
+ };
527
+ useEffect(()=>{
528
+ if (null == maxSelectedRows) return;
529
+ const selectedIds = Object.keys(rowSelection).filter((id)=>rowSelection[id]);
530
+ if (selectedIds.length <= maxSelectedRows) {
531
+ reportedSelectionLimitRef.current = null;
532
+ return;
533
+ }
534
+ const signature = `${maxSelectedRows}:${selectedIds.join(",")}`;
535
+ if (reportedSelectionLimitRef.current === signature) return;
536
+ reportedSelectionLimitRef.current = signature;
537
+ const kept = selectedIds.slice(0, maxSelectedRows);
538
+ setRowSelectionState(Object.fromEntries(kept.map((id)=>[
539
+ id,
540
+ true
541
+ ])));
542
+ onSelectionLimitReached?.({
543
+ limit: maxSelectedRows,
544
+ selectedCount: kept.length
545
+ });
546
+ }, [
547
+ maxSelectedRows,
548
+ rowSelection
549
+ ]);
550
+ const [columnVisibility, setColumnVisibility] = useControllable(columnVisibilityProp, {}, onColumnVisibilityChange);
551
+ const [columnOrder, setColumnOrder] = useControllable(columnOrderProp, [], onColumnOrderChange);
552
+ const [columnPinning, setColumnPinning] = useControllable(columnPinningProp, EMPTY_COLUMN_PINNING, onColumnPinningChange);
553
+ const [expanded, setExpanded] = useControllable(expandedProp, {}, onExpandedChange);
554
+ const [pagination, setPagination] = useControllable(paginationProp, {
555
+ pageIndex: 0,
556
+ pageSize: pageSizeOptions[0] ?? 10
557
+ }, onPaginationChange);
558
+ const [columnSizing, setColumnSizing] = useState({});
559
+ const editTriggerIdRef = useRef(null);
560
+ const draftRowIdRef = useRef(null);
561
+ const [editingRowId, setEditingRowId] = useControllable(editingRowIdProp, null, onEditingRowIdChange);
562
+ const [draft, setDraft] = useState({});
563
+ const draftRef = useRef(draft);
564
+ draftRef.current = draft;
565
+ const [editErrors, setEditErrors] = useState({});
566
+ const [dirty, setDirty] = useState(false);
567
+ const isEditing = null != editingRowId;
568
+ const locked = isEditing && lockInteractionsWhileEditing;
569
+ const blocked = (action)=>{
570
+ if (!locked) return false;
571
+ onInteractionBlocked?.({
572
+ action,
573
+ reason: "editing",
574
+ rowId: editingRowId
575
+ });
576
+ return true;
577
+ };
578
+ const selectedCount = Object.values(rowSelection).filter(Boolean).length;
579
+ const selectionLimitReached = null != maxSelectedRows && selectedCount >= maxSelectedRows;
580
+ const rowSelectionPredicate = (row)=>{
581
+ const isSelected = true === rowSelection[row.id];
582
+ if (canSelectRow && !canSelectRow(row, {
583
+ selectedCount,
584
+ isSelected
585
+ })) return false;
586
+ if (selectionLimitReached && !isSelected) return false;
587
+ return true;
588
+ };
589
+ const columns = useMemo(()=>buildColumns({
590
+ userColumns: applyColumnDefaults(userColumns),
591
+ enableRowReorder,
592
+ enableRowSelection,
593
+ locked,
594
+ getRowLabel,
595
+ selectAllLabel: translations.selectAllLabel,
596
+ showSelectAll: "multiple" === selectionMode && null == maxSelectedRows
597
+ }), [
598
+ userColumns,
599
+ enableRowReorder,
600
+ enableRowSelection,
601
+ locked,
602
+ getRowLabel,
603
+ translations.selectAllLabel,
604
+ selectionMode,
605
+ maxSelectedRows
606
+ ]);
607
+ const effectiveColumnOrder = useMemo(()=>{
608
+ if (0 === columnOrder.length) return columnOrder;
609
+ const builtIns = [
610
+ DRAG_COLUMN_ID,
611
+ SELECTION_COLUMN_ID
612
+ ].filter((id)=>!columnOrder.includes(id));
613
+ return builtIns.length > 0 ? [
614
+ ...builtIns,
615
+ ...columnOrder
616
+ ] : columnOrder;
617
+ }, [
618
+ columnOrder
619
+ ]);
620
+ const table = useTable({
621
+ features: dataTableFeatures,
622
+ data,
623
+ columns,
624
+ getRowId,
625
+ state: {
626
+ sorting,
627
+ columnFilters,
628
+ globalFilter,
629
+ rowSelection,
630
+ columnVisibility,
631
+ columnOrder: effectiveColumnOrder,
632
+ columnPinning,
633
+ expanded,
634
+ pagination,
635
+ columnSizing
636
+ },
637
+ enableSorting,
638
+ enableRowSelection: enableRowSelection ? rowSelectionPredicate : false,
639
+ enableMultiRowSelection: "multiple" === selectionMode,
640
+ enableRowRangeSelection: false,
641
+ enableColumnFilters,
642
+ enableColumnPinning,
643
+ enableColumnResizing,
644
+ columnResizeMode: "onChange",
645
+ manualSorting,
646
+ manualFiltering,
647
+ manualPagination: manualPagination || !enablePagination,
648
+ rowCount,
649
+ pageCount,
650
+ getSubRows,
651
+ getRowCanExpand: getRowCanExpand ?? (renderExpandedRow ? ()=>true : void 0),
652
+ onSortingChange: setSorting,
653
+ onColumnFiltersChange: setColumnFilters,
654
+ onGlobalFilterChange: setGlobalFilter,
655
+ onRowSelectionChange: setRowSelection,
656
+ onColumnVisibilityChange: setColumnVisibility,
657
+ onColumnOrderChange: setColumnOrder,
658
+ onColumnPinningChange: setColumnPinning,
659
+ onExpandedChange: setExpanded,
660
+ onPaginationChange: setPagination,
661
+ onColumnSizingChange: setColumnSizing,
662
+ globalFilterFn: "includesString",
663
+ meta: {
664
+ updateData: (rowId, columnId, value)=>{
665
+ const target = table.getCoreRowModel().rowsById[rowId];
666
+ if (!target) return;
667
+ onCellEditCommit?.({
668
+ rowId,
669
+ columnId,
670
+ value,
671
+ row: target.original
672
+ });
673
+ }
674
+ }
675
+ });
676
+ useEffect(()=>{
677
+ onReady?.(table);
678
+ }, []);
679
+ useEffect(()=>{
680
+ if (editingRowId) {
681
+ const row = document.getElementById(editedRowElementId(instanceId, editingRowId));
682
+ const candidates = row?.querySelectorAll("[data-editor-control] input, [data-editor-control] select, [data-editor-control] textarea, [data-editor-control] button");
683
+ const first = Array.from(candidates ?? []).find((node)=>!node.disabled);
684
+ first?.focus();
685
+ return;
686
+ }
687
+ const trigger = editTriggerIdRef.current ? document.getElementById(editTriggerIdRef.current) : null;
688
+ trigger?.focus();
689
+ editTriggerIdRef.current = null;
690
+ }, [
691
+ editingRowId,
692
+ instanceId
693
+ ]);
694
+ useEffect(()=>{
695
+ if (!editingRowId) {
696
+ draftRowIdRef.current = null;
697
+ setDraft({});
698
+ setEditErrors({});
699
+ setDirty(false);
700
+ return;
701
+ }
702
+ if (draftRowIdRef.current === editingRowId) return;
703
+ const row = table.getCoreRowModel().rowsById[editingRowId];
704
+ if (row) seedDraft(row);
705
+ }, [
706
+ editingRowId
707
+ ]);
708
+ useEffect(()=>{
709
+ if (editingRowId && !table.getCoreRowModel().rowsById[editingRowId]) cancelEdit();
710
+ }, [
711
+ editingRowId,
712
+ data
713
+ ]);
714
+ const headerGroupCount = table.getHeaderGroups().length;
715
+ useIsomorphicLayoutEffect(()=>{
716
+ if (!stickyHeader) return;
717
+ const nodes = headerRowRefs.current.filter((n)=>null != n);
718
+ if (0 === nodes.length) return;
719
+ const measure = ()=>{
720
+ const offsets = [
721
+ 0
722
+ ];
723
+ for (const node of nodes)offsets.push((offsets.at(-1) ?? 0) + node.getBoundingClientRect().height);
724
+ setHeaderOffsets(offsets);
725
+ };
726
+ const observer = new ResizeObserver(measure);
727
+ for (const node of nodes)observer.observe(node);
728
+ measure();
729
+ return ()=>observer.disconnect();
730
+ }, [
731
+ stickyHeader,
732
+ headerGroupCount
733
+ ]);
734
+ const seedDraft = (row)=>{
735
+ const initial = {};
736
+ for (const column of table.getAllLeafColumns())if (column.columnDef.meta?.editable) initial[column.id] = row.getValue(column.id);
737
+ draftRowIdRef.current = row.id;
738
+ setDraft(initial);
739
+ setEditErrors({});
740
+ setDirty(false);
741
+ };
742
+ const startEdit = (row)=>{
743
+ if (isEditing || canEditRow && !canEditRow(row)) return;
744
+ editTriggerIdRef.current = `${instanceId}-edit-${row.id}`;
745
+ seedDraft(row);
746
+ setEditingRowId(row.id);
747
+ onEditStart?.({
748
+ rowId: row.id,
749
+ row: row.original
750
+ });
751
+ };
752
+ const setDraftValue = (rowId, columnId, value)=>{
753
+ const next = {
754
+ ...draftRef.current,
755
+ [columnId]: value
756
+ };
757
+ draftRef.current = next;
758
+ setDraft(next);
759
+ onEditChange?.({
760
+ rowId,
761
+ columnId,
762
+ value,
763
+ draft: next
764
+ });
765
+ setDirty(true);
766
+ setEditErrors((old)=>old[columnId] ? {
767
+ ...old,
768
+ [columnId]: ""
769
+ } : old);
770
+ };
771
+ const cancelEdit = ()=>{
772
+ if (!isEditing) return;
773
+ const rowId = editingRowId;
774
+ setEditingRowId(null);
775
+ onEditCancel?.({
776
+ rowId,
777
+ dirty
778
+ });
779
+ };
780
+ const commitEdit = ()=>{
781
+ if (!isEditing) return;
782
+ const rowId = editingRowId;
783
+ const row = table.getCoreRowModel().rowsById[rowId];
784
+ if (!row) return void cancelEdit();
785
+ const editableColumns = table.getVisibleLeafColumns().filter((column)=>{
786
+ const meta = column.columnDef.meta;
787
+ if (!meta?.editable) return false;
788
+ if ("custom" !== resolveColumnType(meta)) return true;
789
+ return Boolean(meta.renderEditor || editorRenderers?.custom);
790
+ });
791
+ const committed = draftRef.current;
792
+ const errors = validateDraft(editableColumns, committed, translations.requiredLabel);
793
+ if (Object.keys(errors).length > 0) {
794
+ setEditErrors(errors);
795
+ onEditValidationError?.({
796
+ rowId,
797
+ errors
798
+ });
799
+ return;
800
+ }
801
+ onEditCommit?.({
802
+ rowId,
803
+ draft: committed,
804
+ row: row.original
805
+ });
806
+ setEditingRowId(null);
807
+ };
808
+ const rows = table.getRowModel().rows;
809
+ const rootRowIds = useMemo(()=>rows.filter((r)=>0 === r.depth).map((r)=>r.id), [
810
+ rows
811
+ ]);
812
+ const headerGroups = table.getHeaderGroups();
813
+ const leafColumns = useMemo(()=>headerGroups.at(-1)?.headers.map((h)=>h.column) ?? table.getVisibleLeafColumns(), [
814
+ headerGroups
815
+ ]);
816
+ const columnCount = leafColumns.length;
817
+ const virtualizationUsable = enableVirtualization && !!maxHeight;
818
+ const hasWarnedAboutUnboundedVirtualization = useRef(false);
819
+ const hasWarnedAboutVirtualizedCellSpan = useRef(false);
820
+ useEffect(()=>{
821
+ if (!(virtualizationUsable && getCellSpan) || hasWarnedAboutVirtualizedCellSpan.current || "undefined" == typeof process || process.env?.NODE_ENV === "production") return;
822
+ hasWarnedAboutVirtualizedCellSpan.current = true;
823
+ console.warn("DataTable: getCellSpan and enableVirtualization are both set. rowSpan/colSpan require the merged rows to be adjacent DOM siblings, which virtualization's windowing does not guarantee — a spanning cell's owner row can scroll out of view while a `hidden: true` follower row stays rendered, leaving a gap.");
824
+ }, [
825
+ virtualizationUsable,
826
+ getCellSpan
827
+ ]);
828
+ const hasWarnedAboutVirtualizedRowReorder = useRef(false);
829
+ useEffect(()=>{
830
+ if (!(virtualizationUsable && enableRowReorder) || hasWarnedAboutVirtualizedRowReorder.current || "undefined" == typeof process || process.env?.NODE_ENV === "production") return;
831
+ hasWarnedAboutVirtualizedRowReorder.current = true;
832
+ console.warn("DataTable: enableRowReorder and enableVirtualization are both set. Dragging a row toward a target outside the currently rendered window is unreliable — dnd-kit only tracks rows that are actually mounted, not the full row list.");
833
+ }, [
834
+ virtualizationUsable,
835
+ enableRowReorder
836
+ ]);
837
+ useEffect(()=>{
838
+ if (!enableVirtualization || maxHeight) {
839
+ hasWarnedAboutUnboundedVirtualization.current = false;
840
+ return;
841
+ }
842
+ if (hasWarnedAboutUnboundedVirtualization.current || "undefined" == typeof process || process.env?.NODE_ENV === "production") return;
843
+ hasWarnedAboutUnboundedVirtualization.current = true;
844
+ console.warn("DataTable: enableVirtualization has no effect without maxHeight — the scroll container never gets a bounded height to measure scrollTop against, so only the first batch of rows would render. Pass maxHeight to enable virtualization.");
845
+ }, [
846
+ enableVirtualization,
847
+ maxHeight
848
+ ]);
849
+ const rowVirtualizer = useVirtualizer({
850
+ count: rows.length,
851
+ getScrollElement: ()=>scrollRef.current,
852
+ estimateSize: ()=>estimateRowHeight,
853
+ overscan: 12,
854
+ enabled: virtualizationUsable
855
+ });
856
+ const virtualItems = virtualizationUsable ? rowVirtualizer.getVirtualItems() : [];
857
+ const firstVirtual = virtualItems[0];
858
+ const lastVirtual = virtualItems.at(-1);
859
+ const paddingTop = firstVirtual ? firstVirtual.start : 0;
860
+ const paddingBottom = lastVirtual ? rowVirtualizer.getTotalSize() - lastVirtual.end : 0;
861
+ const renderRows = virtualizationUsable ? virtualItems.flatMap((vi)=>{
862
+ const row = rows[vi.index];
863
+ return row ? [
864
+ {
865
+ row,
866
+ index: vi.index
867
+ }
868
+ ] : [];
869
+ }) : rows.map((row, index)=>({
870
+ row,
871
+ index
872
+ }));
873
+ const [activeDragAxis, setActiveDragAxis] = useState(null);
874
+ const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
875
+ coordinateGetter: sortableKeyboardCoordinates
876
+ }));
877
+ useEffect(()=>{
878
+ if (!onReachEnd || maxHeight) return;
879
+ const onWindowScroll = ()=>{
880
+ if (dataLengthRef.current === lastReachEndCountRef.current) return;
881
+ const distance = document.documentElement.scrollHeight - window.scrollY - window.innerHeight;
882
+ checkReachEnd(distance, reachEndThreshold, reachedEndRef, fireReachEnd);
883
+ };
884
+ window.addEventListener("scroll", onWindowScroll, {
885
+ passive: true
886
+ });
887
+ return ()=>window.removeEventListener("scroll", onWindowScroll);
888
+ }, [
889
+ onReachEnd,
890
+ maxHeight,
891
+ reachEndThreshold
892
+ ]);
893
+ useEffect(()=>{
894
+ if (!onReachEnd || loadingMore || maxHeight) return;
895
+ if (data.length === lastReachEndCountRef.current) return;
896
+ const distance = document.documentElement.scrollHeight - window.scrollY - window.innerHeight;
897
+ reachedEndRef.current = distance <= reachEndThreshold;
898
+ if (reachedEndRef.current) fireReachEnd();
899
+ }, [
900
+ data.length,
901
+ loadingMore,
902
+ reachEndThreshold,
903
+ maxHeight
904
+ ]);
905
+ useEffect(()=>{
906
+ if (!onReachEnd || loadingMore || !maxHeight) return;
907
+ const el = scrollRef.current;
908
+ if (!el) return;
909
+ if (data.length === lastReachEndCountRef.current) return;
910
+ const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
911
+ reachedEndRef.current = distance <= reachEndThreshold;
912
+ if (reachedEndRef.current) fireReachEnd();
913
+ }, [
914
+ data.length,
915
+ loadingMore,
916
+ reachEndThreshold
917
+ ]);
918
+ const handleScroll = (event)=>{
919
+ if (!(onReachEnd && maxHeight)) return;
920
+ const el = event.currentTarget;
921
+ if (el.scrollHeight <= el.clientHeight) return;
922
+ if (data.length === lastReachEndCountRef.current) return;
923
+ const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
924
+ checkReachEnd(distance, reachEndThreshold, reachedEndRef, fireReachEnd);
925
+ };
926
+ const handleColumnDragEnd = (event)=>{
927
+ const { active, over } = event;
928
+ if (!over || active.id === over.id) return;
929
+ const current = table.state.columnOrder.length ? table.state.columnOrder : table.getAllLeafColumns().map((c)=>c.id);
930
+ const from = current.indexOf(active.id);
931
+ const to = current.indexOf(over.id);
932
+ if (-1 === from || -1 === to) return;
933
+ const next = arrayMove(current, from, to);
934
+ setColumnOrder(next);
935
+ const publicBefore = current.filter((id)=>!BUILTIN_COLUMN_IDS.has(id));
936
+ const publicOrder = next.filter((id)=>!BUILTIN_COLUMN_IDS.has(id));
937
+ onColumnReorder?.({
938
+ from: publicBefore.indexOf(active.id),
939
+ to: publicOrder.indexOf(active.id),
940
+ columnId: active.id,
941
+ order: publicOrder
942
+ });
943
+ };
944
+ const handleRowDragEnd = (event)=>{
945
+ const { active, over } = event;
946
+ if (!over || active.id === over.id) return;
947
+ const coreRowsById = table.getCoreRowModel().rowsById;
948
+ const from = coreRowsById[active.id]?.index;
949
+ const to = coreRowsById[over.id]?.index;
950
+ if (void 0 === from || void 0 === to) return;
951
+ const next = arrayMove([
952
+ ...data
953
+ ], from, to);
954
+ onRowReorder?.({
955
+ from,
956
+ to,
957
+ rowId: active.id,
958
+ data: next
959
+ });
960
+ };
961
+ const hasFooter = table.getAllLeafColumns().some((c)=>null != c.columnDef.footer);
962
+ const indentColumnId = leafColumns.find((c)=>!BUILTIN_COLUMN_IDS.has(c.id))?.id;
963
+ const reorderableLeafIds = useMemo(()=>leafColumns.filter((c)=>!(BUILTIN_COLUMN_IDS.has(c.id) || c.getIsPinned())).map((c)=>c.id), [
964
+ leafColumns
965
+ ]);
966
+ const hasActionsColumn = !!renderRowActions || !!rowActions?.length || enableInlineEdit || enableExpanding && (!!renderExpandedRow || !!getSubRows || !!getRowCanExpand);
967
+ const hasWarnedAboutPinnedActionsOverlap = useRef(false);
968
+ useEffect(()=>{
969
+ const endPinned = enableColumnPinning && table.getAllLeafColumns().some((c)=>"end" === c.getIsPinned());
970
+ if (!(endPinned && stickyActions && hasActionsColumn) || hasWarnedAboutPinnedActionsOverlap.current || "undefined" == typeof process || process.env?.NODE_ENV === "production") return;
971
+ hasWarnedAboutPinnedActionsOverlap.current = true;
972
+ console.warn("DataTable: a column pinned to 'end' and the sticky actions cell both freeze at the trailing edge, so they overlap — the actions column is not part of the column model, so end-pinned offsets cannot account for its width. Use stickyActions={false}, or pin to 'start' instead.");
973
+ }, [
974
+ enableColumnPinning,
975
+ stickyActions,
976
+ hasActionsColumn,
977
+ table
978
+ ]);
979
+ const hasWarnedAboutPinnedStringWidth = useRef(false);
980
+ useEffect(()=>{
981
+ const offender = enableColumnPinning && table.getAllLeafColumns().find((c)=>c.getIsPinned() && "string" == typeof c.columnDef.meta?.width);
982
+ if (!offender || hasWarnedAboutPinnedStringWidth.current || "undefined" == typeof process || process.env?.NODE_ENV === "production") return;
983
+ hasWarnedAboutPinnedStringWidth.current = true;
984
+ console.warn(`DataTable: pinned column "${offender.id}" declares a string meta.width, which cannot be mirrored into TanStack's numeric \`size\`. Frozen offsets are computed from \`size\`, so this column will be positioned as if it were the default width and overlap its neighbours. Give pinned columns a numeric meta.width.`);
985
+ }, [
986
+ enableColumnPinning,
987
+ table
988
+ ]);
989
+ const renderColumnFilter = (column)=>{
990
+ const meta = column.columnDef.meta;
991
+ const type = resolveColumnType(meta);
992
+ const ctx = {
993
+ column,
994
+ type,
995
+ value: column.getFilterValue(),
996
+ setValue: (next)=>column.setFilterValue(next),
997
+ disabled: locked,
998
+ size,
999
+ operatorLabels: translations.operatorLabels,
1000
+ options: meta?.options ?? meta?.filterOptions ?? []
1001
+ };
1002
+ if (meta?.renderFilter) return meta.renderFilter(ctx);
1003
+ const slot = renderHeaderFilter?.(column);
1004
+ if (void 0 !== slot) return slot;
1005
+ const renderer = filterRenderers?.[type] ?? DEFAULT_FILTER_RENDERERS[type];
1006
+ return renderer?.(ctx) ?? null;
1007
+ };
1008
+ const renderHeaderCell = (header, groupIndex, dnd)=>{
1009
+ const column = header.column;
1010
+ const ariaSort = sortState(column, enableSorting);
1011
+ let dropClass = "";
1012
+ if (dnd?.dropSide === "start") dropClass = "border-primary border-s-2";
1013
+ else if (dnd?.dropSide === "end") dropClass = "border-primary border-e-2";
1014
+ return /*#__PURE__*/ jsxs(Table.ColumnHeader, {
1015
+ align: column.columnDef.meta?.align,
1016
+ "aria-sort": ariaSort,
1017
+ className: `group/header ${stickyHeader ? "" : "relative"} ${pinClass(column, "header") ?? ""} ${dropClass}`,
1018
+ colSpan: header.colSpan,
1019
+ "data-dragging": dnd?.isDragging || void 0,
1020
+ "data-pinned": column.getIsPinned() || void 0,
1021
+ ref: dnd?.setNodeRef,
1022
+ style: {
1023
+ ...OPAQUE_HEADER_BG,
1024
+ ...stickyRowOffset(stickyHeader, headerOffsets, groupIndex),
1025
+ ...getPinningStyles(column, "header"),
1026
+ ...dnd?.style,
1027
+ ...getColumnSizeStyles(column, enableColumnResizing, columnSizing)
1028
+ },
1029
+ children: [
1030
+ /*#__PURE__*/ jsxs("div", {
1031
+ className: styles.headerLabel(),
1032
+ children: [
1033
+ dnd && /*#__PURE__*/ jsx(HeaderDragHandle, {
1034
+ attributes: dnd.attributes,
1035
+ label: columnLabel(column),
1036
+ listeners: dnd.listeners,
1037
+ setActivatorNodeRef: dnd.setActivatorNodeRef,
1038
+ styles: styles
1039
+ }),
1040
+ /*#__PURE__*/ jsx(HeaderSortLabel, {
1041
+ enableSorting: enableSorting,
1042
+ header: header,
1043
+ locked: locked,
1044
+ styles: styles
1045
+ })
1046
+ ]
1047
+ }),
1048
+ enableColumnResizing && column.getCanResize() ? /*#__PURE__*/ jsx("button", {
1049
+ "aria-label": `Resize ${columnLabel(column)}`,
1050
+ className: styles.resizeHandle(),
1051
+ onDoubleClick: ()=>column.resetSize(),
1052
+ onMouseDown: header.getResizeHandler(),
1053
+ onTouchStart: header.getResizeHandler(),
1054
+ type: "button"
1055
+ }) : null
1056
+ ]
1057
+ }, header.id);
1058
+ };
1059
+ const headerContent = /*#__PURE__*/ jsxs(Table.Header, {
1060
+ ...slotProps?.header,
1061
+ children: [
1062
+ table.getHeaderGroups().map((headerGroup, groupIndex)=>/*#__PURE__*/ jsxs(Table.Row, {
1063
+ className: hideHeader ? "sr-only" : void 0,
1064
+ ref: (node)=>{
1065
+ headerRowRefs.current[groupIndex] = node;
1066
+ },
1067
+ children: [
1068
+ headerGroup.headers.map((header)=>{
1069
+ const reorderable = enableColumnReorder && !locked && 0 === header.subHeaders.length && !header.column.getIsPinned() && !BUILTIN_COLUMN_IDS.has(header.column.id);
1070
+ return reorderable ? /*#__PURE__*/ jsx(SortableHeaderContent, {
1071
+ columnId: header.column.id,
1072
+ children: (dnd)=>renderHeaderCell(header, groupIndex, dnd)
1073
+ }, header.id) : renderHeaderCell(header, groupIndex);
1074
+ }),
1075
+ hasActionsColumn && 0 === groupIndex && /*#__PURE__*/ jsx(Table.ColumnHeader, {
1076
+ className: stickyActions ? "sticky end-0" : void 0,
1077
+ numeric: true,
1078
+ rowSpan: table.getHeaderGroups().length,
1079
+ style: {
1080
+ ...OPAQUE_HEADER_BG,
1081
+ ...stickyActions ? {
1082
+ zIndex: DATA_TABLE_Z.stickyActionsHeaderCell
1083
+ } : void 0
1084
+ },
1085
+ children: translations.actionsLabel
1086
+ })
1087
+ ]
1088
+ }, headerGroup.id)),
1089
+ enableColumnFilters && /*#__PURE__*/ jsxs("tr", {
1090
+ "aria-label": translations.filtersLabel,
1091
+ className: styles.filterRow(),
1092
+ children: [
1093
+ leafColumns.map((column)=>/*#__PURE__*/ jsx("td", {
1094
+ className: `${styles.filterCell()} ${pinClass(column, "header") ?? ""}`,
1095
+ "data-pinned": column.getIsPinned() || void 0,
1096
+ style: {
1097
+ ...OPAQUE_HEADER_BG,
1098
+ ...getPinningStyles(column, "header"),
1099
+ ...stickyHeader ? {
1100
+ position: "sticky",
1101
+ top: headerHeight,
1102
+ zIndex: DATA_TABLE_Z.stickyHeaderCell
1103
+ } : void 0,
1104
+ ...column.getIsPinned() && stickyHeader ? {
1105
+ zIndex: DATA_TABLE_Z.pinnedHeaderCell
1106
+ } : void 0
1107
+ },
1108
+ children: /*#__PURE__*/ jsx("div", {
1109
+ className: styles.filterControl(),
1110
+ children: column.getCanFilter() ? renderColumnFilter(column) : null
1111
+ })
1112
+ }, column.id)),
1113
+ hasActionsColumn && /*#__PURE__*/ jsx("td", {
1114
+ className: stickyActions ? `${styles.filterCell()} sticky end-0 bg-table-header-bg` : styles.filterCell(),
1115
+ style: {
1116
+ ...OPAQUE_HEADER_BG,
1117
+ ...stickyHeader ? {
1118
+ position: "sticky",
1119
+ top: headerHeight
1120
+ } : void 0,
1121
+ ...stickyActions ? {
1122
+ zIndex: DATA_TABLE_Z.stickyActionsHeaderCell
1123
+ } : void 0
1124
+ }
1125
+ })
1126
+ ]
1127
+ })
1128
+ ]
1129
+ });
1130
+ const renderCellEditor = (row, column)=>{
1131
+ const meta = column.columnDef.meta;
1132
+ if (!(enableInlineEdit && meta?.editable) || editingRowId !== row.id) return;
1133
+ const type = resolveColumnType(meta);
1134
+ const ctx = {
1135
+ row,
1136
+ column,
1137
+ type,
1138
+ value: draft[column.id],
1139
+ setValue: (next)=>setDraftValue(row.id, column.id, next),
1140
+ disabled: false,
1141
+ size,
1142
+ options: meta.options ?? meta.filterOptions ?? [],
1143
+ error: editErrors[column.id] || void 0,
1144
+ errorId: `${instanceId}-err-${row.id}-${column.id}`,
1145
+ commit: commitEdit,
1146
+ cancel: cancelEdit
1147
+ };
1148
+ if (meta.renderEditor) return meta.renderEditor(ctx);
1149
+ const renderer = editorRenderers?.[type] ?? DEFAULT_EDITOR_RENDERERS[type];
1150
+ return renderer?.(ctx) ?? void 0;
1151
+ };
1152
+ const defaultRowActions = (row)=>{
1153
+ if (!enableInlineEdit) return null;
1154
+ if (editingRowId === row.id) return /*#__PURE__*/ jsxs(Fragment, {
1155
+ children: [
1156
+ /*#__PURE__*/ jsx(Button, {
1157
+ "aria-label": "Save row",
1158
+ icon: "token-icon-check",
1159
+ onClick: (e)=>{
1160
+ e.stopPropagation();
1161
+ commitEdit();
1162
+ },
1163
+ size: "sm",
1164
+ theme: "borderless",
1165
+ variant: "primary"
1166
+ }),
1167
+ /*#__PURE__*/ jsx(Button, {
1168
+ "aria-label": "Cancel edit",
1169
+ icon: "token-icon-close",
1170
+ onClick: (e)=>{
1171
+ e.stopPropagation();
1172
+ cancelEdit();
1173
+ },
1174
+ size: "sm",
1175
+ theme: "borderless",
1176
+ variant: "secondary"
1177
+ })
1178
+ ]
1179
+ });
1180
+ return /*#__PURE__*/ jsx(ActionIcon, {
1181
+ "aria-label": `Edit ${getRowLabel?.(row) ?? `row ${row.id}`}`,
1182
+ disabled: isEditing || (canEditRow ? !canEditRow(row) : false),
1183
+ icon: "icon-[mdi--pencil-outline]",
1184
+ id: `${instanceId}-edit-${row.id}`,
1185
+ onClick: (e)=>{
1186
+ e.stopPropagation();
1187
+ startEdit(row);
1188
+ },
1189
+ size: size,
1190
+ tone: "neutral"
1191
+ });
1192
+ };
1193
+ const rowActionsContent = (row)=>{
1194
+ const custom = renderRowActions?.(row, {
1195
+ isEditing: editingRowId === row.id,
1196
+ startEdit: ()=>startEdit(row),
1197
+ commitEdit,
1198
+ cancelEdit,
1199
+ disabled: locked && editingRowId !== row.id
1200
+ });
1201
+ return void 0 === custom ? defaultRowActions(row) : custom;
1202
+ };
1203
+ const expandAriaControls = (rowId)=>renderExpandedRow ? `${instanceId}-detail-${rowId}` : void 0;
1204
+ const renderActionsCell = (row)=>/*#__PURE__*/ jsx(Table.Cell, {
1205
+ className: stickyActions ? "data-table-frozen-cell sticky end-0" : void 0,
1206
+ numeric: true,
1207
+ style: stickyActions ? {
1208
+ zIndex: DATA_TABLE_Z.stickyActionsCell
1209
+ } : void 0,
1210
+ children: /*#__PURE__*/ jsxs("div", {
1211
+ className: styles.actionsCell(),
1212
+ children: [
1213
+ enableExpanding && row.getCanExpand() ? /*#__PURE__*/ jsx(Button, {
1214
+ "aria-controls": expandAriaControls(row.id),
1215
+ "aria-expanded": row.getIsExpanded(),
1216
+ "aria-label": row.getIsExpanded() ? "Collapse row" : "Expand row",
1217
+ disabled: locked,
1218
+ icon: row.getIsExpanded() ? "token-icon-chevron-down" : "token-icon-chevron-right",
1219
+ onClick: (e)=>{
1220
+ e.stopPropagation();
1221
+ if (blocked("expand")) return;
1222
+ row.getToggleExpandedHandler()();
1223
+ },
1224
+ size: "sm",
1225
+ theme: "borderless",
1226
+ variant: "secondary"
1227
+ }) : null,
1228
+ rowActions?.map((action)=>action.hidden?.(row) ? null : /*#__PURE__*/ jsx(Button, {
1229
+ "aria-label": action.label,
1230
+ disabled: action.disabled?.(row) || locked,
1231
+ icon: action.icon,
1232
+ onClick: (e)=>{
1233
+ e.stopPropagation();
1234
+ action.onAction(row);
1235
+ },
1236
+ size: "sm",
1237
+ theme: "borderless",
1238
+ variant: "danger" === action.tone ? "danger" : "secondary"
1239
+ }, action.id)),
1240
+ rowActionsContent(row)
1241
+ ]
1242
+ })
1243
+ });
1244
+ const { onClick: rowOnClick, style: rowStyle, ref: rowRef, ...restRowProps } = slotProps?.row ?? {};
1245
+ const renderRowCells = (row, cells, rowIndex, dnd)=>{
1246
+ const rowLabel = getRowLabel?.(row) ?? `row ${row.id}`;
1247
+ return cells.map((cell)=>{
1248
+ const span = getCellSpan?.(cell, {
1249
+ row,
1250
+ rows,
1251
+ rowIndex
1252
+ });
1253
+ if (span?.hidden) return null;
1254
+ const column = cell.column;
1255
+ return /*#__PURE__*/ jsx(DataTableBodyCell, {
1256
+ cell: cell,
1257
+ columnSizing: columnSizing,
1258
+ dnd: dnd,
1259
+ editor: renderCellEditor(row, column),
1260
+ editorError: editingRowId === row.id ? editErrors[column.id] || void 0 : void 0,
1261
+ editorErrorId: `${instanceId}-err-${row.id}-${column.id}`,
1262
+ enableColumnResizing: enableColumnResizing,
1263
+ enableRowReorder: enableRowReorder,
1264
+ indentColumnId: indentColumnId,
1265
+ row: row,
1266
+ rowLabel: rowLabel,
1267
+ span: span,
1268
+ styles: styles
1269
+ }, cell.id);
1270
+ });
1271
+ };
1272
+ const headerRowCount = table.getHeaderGroups().length + (enableColumnFilters ? 1 : 0);
1273
+ const pageRowOffset = enablePagination ? pagination.pageIndex * pagination.pageSize : 0;
1274
+ const buildMainRow = (row, rowIndex, dnd, opts)=>/*#__PURE__*/ jsxs(Table.Row, {
1275
+ ...restRowProps,
1276
+ "aria-rowindex": headerRowCount + pageRowOffset + rowIndex + 1,
1277
+ className: rowDragClass(dnd, {
1278
+ className: restRowProps.className,
1279
+ striped: effectiveStriped,
1280
+ tintNestedRows,
1281
+ rowIndex
1282
+ }),
1283
+ "data-depth": row.depth || void 0,
1284
+ "data-dragging": dnd?.isDragging || void 0,
1285
+ id: opts.rowElementId ?? restRowProps.id,
1286
+ onClick: buildRowClickHandler(row, rowOnClick, onRowClick, blocked),
1287
+ onKeyDown: (event)=>{
1288
+ restRowProps.onKeyDown?.(event);
1289
+ opts.rowKeyDown?.(event);
1290
+ },
1291
+ ref: composeRowRef(dnd, rowRef),
1292
+ selected: enableRowSelection ? row.getIsSelected() : void 0,
1293
+ style: {
1294
+ ...rowStyle,
1295
+ ...dnd?.style
1296
+ },
1297
+ tabIndex: opts.rowIsClickable ? 0 : restRowProps.tabIndex,
1298
+ children: [
1299
+ renderRowCells(row, row.getVisibleCells(), rowIndex, dnd),
1300
+ hasActionsColumn ? renderActionsCell(row) : null
1301
+ ]
1302
+ });
1303
+ const renderBodyRow = (row, rowIndex, dnd)=>{
1304
+ const rowIsClickable = !!onRowClick && !locked;
1305
+ const actionsColumn = hasActionsColumn ? 1 : 0;
1306
+ const rowElementId = editingRowElementId(editingRowId, instanceId, row.id);
1307
+ const rowKeyDown = rowIsClickable ? buildRowKeyDownHandler(row, onRowClick, blocked) : void 0;
1308
+ const mainRow = buildMainRow(row, rowIndex, dnd, {
1309
+ rowIsClickable,
1310
+ rowElementId,
1311
+ rowKeyDown
1312
+ });
1313
+ const expandedRow = renderExpandedRow && row.getIsExpanded() ? renderExpandedDetailRow({
1314
+ row,
1315
+ renderExpandedRow,
1316
+ colSpan: columnCount + actionsColumn,
1317
+ instanceId,
1318
+ styles,
1319
+ tintNestedRows
1320
+ }) : null;
1321
+ return /*#__PURE__*/ jsxs(external_react_Fragment, {
1322
+ children: [
1323
+ mainRow,
1324
+ expandedRow
1325
+ ]
1326
+ }, row.id);
1327
+ };
1328
+ const rowReorderActive = enableRowReorder && !locked && 0 === sorting.length && 0 === columnFilters.length && !globalFilter;
1329
+ const bodyRows = renderRows.map(({ row, index: rowIndex })=>rowReorderActive && 0 === row.depth ? /*#__PURE__*/ jsx(SortableRow, {
1330
+ enabled: enableRowReorder,
1331
+ row: row,
1332
+ children: (dnd)=>renderBodyRow(row, rowIndex, dnd)
1333
+ }, row.id) : renderBodyRow(row, rowIndex));
1334
+ const skeletonRows = (count, keyPrefix)=>Array.from({
1335
+ length: count
1336
+ }, (_, i)=>`${keyPrefix}-${i}`).map((rowKey)=>/*#__PURE__*/ jsxs(Table.Row, {
1337
+ "aria-hidden": "true",
1338
+ children: [
1339
+ leafColumns.map((column)=>/*#__PURE__*/ jsx(Table.Cell, {
1340
+ children: /*#__PURE__*/ jsx(Skeleton.Text, {
1341
+ noOfLines: 1,
1342
+ size: size
1343
+ })
1344
+ }, `${rowKey}-${column.id}`)),
1345
+ hasActionsColumn && /*#__PURE__*/ jsx(Table.Cell, {
1346
+ className: stickyActions ? "data-table-frozen-cell sticky end-0" : void 0,
1347
+ numeric: true,
1348
+ style: stickyActions ? {
1349
+ zIndex: DATA_TABLE_Z.stickyActionsCell
1350
+ } : void 0,
1351
+ children: /*#__PURE__*/ jsx(Skeleton.Text, {
1352
+ noOfLines: 1,
1353
+ size: size
1354
+ })
1355
+ })
1356
+ ]
1357
+ }, rowKey));
1358
+ const emptyState = renderEmpty ? renderEmpty() : /*#__PURE__*/ jsxs("div", {
1359
+ className: styles.empty(),
1360
+ children: [
1361
+ /*#__PURE__*/ jsx(Icon, {
1362
+ icon: "icon-[mdi--table-off]",
1363
+ size: "xl"
1364
+ }),
1365
+ /*#__PURE__*/ jsxs("div", {
1366
+ children: [
1367
+ /*#__PURE__*/ jsx("p", {
1368
+ children: translations.emptyTitle
1369
+ }),
1370
+ /*#__PURE__*/ jsx("p", {
1371
+ className: "text-table-sm",
1372
+ children: translations.emptyDescription
1373
+ })
1374
+ ]
1375
+ })
1376
+ ]
1377
+ });
1378
+ let statusMessage = "";
1379
+ if (loading) statusMessage = translations.loadingLabel;
1380
+ else if (0 === rows.length) statusMessage = translations.emptyTitle;
1381
+ else if (isEditing) statusMessage = translations.editingLabel;
1382
+ const emptyRow = /*#__PURE__*/ jsx("tr", {
1383
+ children: /*#__PURE__*/ jsx(Table.Cell, {
1384
+ colSpan: columnCount + (hasActionsColumn ? 1 : 0),
1385
+ children: emptyState
1386
+ })
1387
+ });
1388
+ let bodyState = "rows";
1389
+ if (loading) bodyState = "loading";
1390
+ else if (0 === rows.length) bodyState = loadingMore ? "loading" : "empty";
1391
+ const bodyContent = /*#__PURE__*/ jsxs(Table.Body, {
1392
+ ...slotProps?.body,
1393
+ children: [
1394
+ "loading" === bodyState && skeletonRows(loadingRowCount, "skeleton"),
1395
+ "empty" === bodyState && emptyRow,
1396
+ "rows" === bodyState && /*#__PURE__*/ jsxs(Fragment, {
1397
+ children: [
1398
+ paddingTop > 0 && /*#__PURE__*/ jsx("tr", {
1399
+ children: /*#__PURE__*/ jsx("td", {
1400
+ colSpan: columnCount + (hasActionsColumn ? 1 : 0),
1401
+ style: {
1402
+ height: paddingTop
1403
+ }
1404
+ })
1405
+ }),
1406
+ bodyRows,
1407
+ loadingMore && skeletonRows(1, "skeleton-more"),
1408
+ paddingBottom > 0 && /*#__PURE__*/ jsx("tr", {
1409
+ children: /*#__PURE__*/ jsx("td", {
1410
+ colSpan: columnCount + (hasActionsColumn ? 1 : 0),
1411
+ style: {
1412
+ height: paddingBottom
1413
+ }
1414
+ })
1415
+ })
1416
+ ]
1417
+ })
1418
+ ]
1419
+ });
1420
+ const footerContent = hasFooter ? /*#__PURE__*/ jsx(Table.Footer, {
1421
+ children: table.getFooterGroups().map((footerGroup)=>/*#__PURE__*/ jsxs(Table.Row, {
1422
+ children: [
1423
+ footerGroup.headers.map((header)=>/*#__PURE__*/ jsx(Table.Cell, {
1424
+ children: header.isPlaceholder ? null : flexRender(header.column.columnDef.footer, header.getContext())
1425
+ }, header.id)),
1426
+ hasActionsColumn && /*#__PURE__*/ jsx(Table.Cell, {
1427
+ className: stickyActions ? "sticky end-0 bg-table-footer-bg" : void 0,
1428
+ numeric: true,
1429
+ style: stickyActions ? {
1430
+ zIndex: DATA_TABLE_Z.stickyActionsCell
1431
+ } : void 0
1432
+ })
1433
+ ]
1434
+ }, footerGroup.id))
1435
+ }) : null;
1436
+ const tableEl = /*#__PURE__*/ jsxs(Table, {
1437
+ "aria-busy": loading || loadingMore || void 0,
1438
+ "aria-rowcount": headerRowCount + table.getRowCount(),
1439
+ interactive: (interactive || !!onRowClick) && !locked,
1440
+ showColumnBorder: showColumnBorder,
1441
+ size: size,
1442
+ stickyHeader: stickyHeader,
1443
+ variant: outlined || "striped" === variant ? "line" : variant,
1444
+ ...slotProps?.root,
1445
+ style: {
1446
+ tableLayout,
1447
+ ...slotProps?.root?.style
1448
+ },
1449
+ children: [
1450
+ caption && /*#__PURE__*/ jsx(Table.Caption, {
1451
+ children: caption
1452
+ }),
1453
+ enableColumnReorder ? /*#__PURE__*/ jsx(SortableContext, {
1454
+ items: reorderableLeafIds,
1455
+ strategy: horizontalListSortingStrategy,
1456
+ children: headerContent
1457
+ }) : headerContent,
1458
+ rowReorderActive ? /*#__PURE__*/ jsx(SortableContext, {
1459
+ items: rootRowIds,
1460
+ strategy: verticalListSortingStrategy,
1461
+ children: bodyContent
1462
+ }) : bodyContent,
1463
+ footerContent
1464
+ ]
1465
+ });
1466
+ const isColumnDrag = (event)=>event.active.data.current?.type === "column";
1467
+ const handleDragEnd = (event)=>{
1468
+ if (enableColumnReorder && isColumnDrag(event)) return void handleColumnDragEnd(event);
1469
+ if (rowReorderActive) handleRowDragEnd(event);
1470
+ };
1471
+ let scrollBody = tableEl;
1472
+ if (enableColumnReorder || rowReorderActive) scrollBody = /*#__PURE__*/ jsx(DndContext, {
1473
+ collisionDetection: closestCenter,
1474
+ modifiers: [
1475
+ "column" === activeDragAxis ? restrictToHorizontalAxis : restrictToVerticalAxis
1476
+ ],
1477
+ onDragEnd: (event)=>{
1478
+ handleDragEnd(event);
1479
+ setActiveDragAxis(null);
1480
+ },
1481
+ onDragStart: (event)=>setActiveDragAxis(enableColumnReorder && isColumnDrag(event) ? "column" : "row"),
1482
+ sensors: sensors,
1483
+ children: scrollBody
1484
+ });
1485
+ const ctxValue = {
1486
+ table,
1487
+ pageSizeOptions,
1488
+ translations,
1489
+ locked,
1490
+ blocked,
1491
+ size,
1492
+ paginationProps,
1493
+ toolbarActions
1494
+ };
1495
+ return /*#__PURE__*/ jsx(DataTableContext.Provider, {
1496
+ value: ctxValue,
1497
+ children: /*#__PURE__*/ jsxs("div", {
1498
+ className: styles.wrapper({
1499
+ className
1500
+ }),
1501
+ id: instanceId,
1502
+ ref: ref,
1503
+ children: [
1504
+ /*#__PURE__*/ jsx("output", {
1505
+ "aria-live": "polite",
1506
+ className: "sr-only",
1507
+ children: statusMessage
1508
+ }),
1509
+ (enableGlobalFilter || enableColumnVisibility || toolbarActions?.length || renderToolbar) && (renderToolbar ? renderToolbar(table) : /*#__PURE__*/ jsxs(DataTable.Toolbar, {
1510
+ children: [
1511
+ enableGlobalFilter && /*#__PURE__*/ jsx(DataTable.GlobalSearch, {}),
1512
+ /*#__PURE__*/ jsxs("div", {
1513
+ className: styles.toolbarActions(),
1514
+ children: [
1515
+ enableColumnVisibility && /*#__PURE__*/ jsx(DataTable.ColumnVisibility, {}),
1516
+ /*#__PURE__*/ jsx(DataTable.ToolbarActions, {})
1517
+ ]
1518
+ })
1519
+ ]
1520
+ })),
1521
+ /*#__PURE__*/ jsx("div", {
1522
+ className: styles.scroll(),
1523
+ onScroll: handleScroll,
1524
+ ref: scrollRef,
1525
+ style: maxHeight ? {
1526
+ maxHeight
1527
+ } : void 0,
1528
+ children: scrollBody
1529
+ }),
1530
+ enablePagination && /*#__PURE__*/ jsx(DataTable.Pagination, {})
1531
+ ]
1532
+ })
1533
+ });
1534
+ }
1535
+ function buildColumns({ userColumns, enableRowReorder, enableRowSelection, locked, getRowLabel, selectAllLabel, showSelectAll }) {
1536
+ const leading = [];
1537
+ if (enableRowReorder) leading.push({
1538
+ id: DRAG_COLUMN_ID,
1539
+ header: ()=>null,
1540
+ cell: ()=>null,
1541
+ enableSorting: false,
1542
+ enableColumnFilter: false,
1543
+ size: 40,
1544
+ meta: {
1545
+ width: 40
1546
+ }
1547
+ });
1548
+ if (enableRowSelection) leading.push({
1549
+ id: SELECTION_COLUMN_ID,
1550
+ header: ({ table })=>showSelectAll ? /*#__PURE__*/ jsx(Checkbox, {
1551
+ "aria-label": selectAllLabel,
1552
+ checked: table.getIsAllRowsSelected(),
1553
+ disabled: locked,
1554
+ indeterminate: table.getIsSomeRowsSelected() && !table.getIsAllRowsSelected(),
1555
+ onChange: table.getToggleAllRowsSelectedHandler()
1556
+ }) : null,
1557
+ cell: ({ row })=>/*#__PURE__*/ jsx(Checkbox, {
1558
+ "aria-label": `Select ${getRowLabel?.(row) ?? `row ${row.id}`}`,
1559
+ checked: row.getIsSelected(),
1560
+ disabled: locked || !row.getCanSelect(),
1561
+ indeterminate: row.getIsSomeSelected(),
1562
+ onChange: row.getToggleSelectedHandler(),
1563
+ onClick: (e)=>e.stopPropagation()
1564
+ }),
1565
+ enableSorting: false,
1566
+ enableColumnFilter: false,
1567
+ size: 44,
1568
+ meta: {
1569
+ width: 44
1570
+ }
1571
+ });
1572
+ return [
1573
+ ...leading,
1574
+ ...userColumns
1575
+ ];
1576
+ }
1577
+ DataTable.Toolbar = function({ children }) {
1578
+ const styles = dataTableVariants();
1579
+ return /*#__PURE__*/ jsx("div", {
1580
+ className: styles.toolbar(),
1581
+ children: children
1582
+ });
1583
+ };
1584
+ DataTable.GlobalSearch = function({ className }) {
1585
+ const { table, translations, locked, blocked, size } = useDataTableContext();
1586
+ const styles = dataTableVariants();
1587
+ return /*#__PURE__*/ jsx("div", {
1588
+ className: styles.toolbarSearch({
1589
+ className
1590
+ }),
1591
+ children: /*#__PURE__*/ jsx(SearchForm, {
1592
+ className: "w-full",
1593
+ onSubmit: (event)=>event.preventDefault(),
1594
+ onValueChange: (value)=>{
1595
+ if (blocked("globalFilter")) return;
1596
+ table.setGlobalFilter(value);
1597
+ },
1598
+ size: size,
1599
+ value: table.state.globalFilter ?? "",
1600
+ children: /*#__PURE__*/ jsxs(SearchForm.Control, {
1601
+ children: [
1602
+ /*#__PURE__*/ jsx(SearchForm.Input, {
1603
+ "aria-label": translations.searchLabel,
1604
+ disabled: locked,
1605
+ placeholder: translations.searchPlaceholder
1606
+ }),
1607
+ /*#__PURE__*/ jsx(SearchForm.ClearButton, {
1608
+ "aria-label": translations.clearSearchLabel
1609
+ }),
1610
+ /*#__PURE__*/ jsx(SearchForm.Button, {
1611
+ "aria-label": translations.searchButtonLabel,
1612
+ disabled: locked,
1613
+ showSearchIcon: true
1614
+ })
1615
+ ]
1616
+ })
1617
+ })
1618
+ });
1619
+ };
1620
+ DataTable.ToolbarActions = function() {
1621
+ const { toolbarActions, size, locked } = useDataTableContext();
1622
+ const styles = dataTableVariants();
1623
+ const count = toolbarActions?.length ?? 0;
1624
+ const hasWarnedAboutToolbarOverflow = useRef(false);
1625
+ useEffect(()=>{
1626
+ if (count <= DATA_TABLE_MAX_TOOLBAR_ACTIONS) {
1627
+ hasWarnedAboutToolbarOverflow.current = false;
1628
+ return;
1629
+ }
1630
+ if (hasWarnedAboutToolbarOverflow.current || "undefined" == typeof process || process.env?.NODE_ENV === "production") return;
1631
+ hasWarnedAboutToolbarOverflow.current = true;
1632
+ console.warn(`[DataTable] toolbarActions has ${count} actions; at most ${DATA_TABLE_MAX_TOOLBAR_ACTIONS} is recommended. They still render, but the toolbar gets crowded — consider moving the extras into a menu.`);
1633
+ }, [
1634
+ count
1635
+ ]);
1636
+ if (!count) return null;
1637
+ return /*#__PURE__*/ jsx("div", {
1638
+ className: styles.toolbarActions(),
1639
+ children: toolbarActions?.map(({ id, label, children, disabled, ...action }, i)=>/*#__PURE__*/ jsx(Button, {
1640
+ disabled: disabled || locked,
1641
+ size: size,
1642
+ ...action,
1643
+ children: label ?? children
1644
+ }, id ?? `toolbar-action-${i}`))
1645
+ });
1646
+ };
1647
+ DataTable.ColumnVisibility = function() {
1648
+ const { table, translations, blocked, size } = useDataTableContext();
1649
+ const hideableColumns = table.getAllLeafColumns().filter((c)=>c.getCanHide() && ![
1650
+ SELECTION_COLUMN_ID,
1651
+ DRAG_COLUMN_ID
1652
+ ].includes(c.id));
1653
+ const items = hideableColumns.map((column)=>({
1654
+ type: "checkbox",
1655
+ value: column.id,
1656
+ label: columnLabel(column),
1657
+ checked: column.getIsVisible()
1658
+ }));
1659
+ return /*#__PURE__*/ jsx(Menu, {
1660
+ closeOnSelect: false,
1661
+ customTrigger: /*#__PURE__*/ jsx(Button, {
1662
+ "aria-label": translations.columnsLabel,
1663
+ icon: "icon-[mdi--cog-outline]",
1664
+ size: "sm",
1665
+ title: translations.columnsLabel,
1666
+ variant: "primary"
1667
+ }),
1668
+ items: items,
1669
+ onCheckedChange: (item)=>{
1670
+ if ("checkbox" === item.type && !blocked("columnVisibility")) table.getColumn(item.value)?.toggleVisibility();
1671
+ },
1672
+ size: size
1673
+ });
1674
+ };
1675
+ DataTable.Pagination = function() {
1676
+ const { table, pageSizeOptions, translations, locked, blocked, size, paginationProps } = useDataTableContext();
1677
+ const state = table.state.pagination;
1678
+ const declaredPageCount = table.options.pageCount;
1679
+ const total = table.options.rowCount ?? (null != declaredPageCount && declaredPageCount >= 0 ? declaredPageCount * state.pageSize : table.getRowCount());
1680
+ const start = 0 === total ? 0 : state.pageIndex * state.pageSize + 1;
1681
+ const end = Math.min((state.pageIndex + 1) * state.pageSize, total);
1682
+ const styles = dataTableVariants();
1683
+ const pageSizeItems = pageSizeOptions.map((n)=>({
1684
+ label: String(n),
1685
+ value: String(n)
1686
+ }));
1687
+ return /*#__PURE__*/ jsxs("div", {
1688
+ className: styles.paginationBar(),
1689
+ style: OPAQUE_HEADER_BG,
1690
+ children: [
1691
+ /*#__PURE__*/ jsx("span", {
1692
+ className: styles.paginationInfo(),
1693
+ children: translations.rangeLabel({
1694
+ start,
1695
+ end,
1696
+ total
1697
+ })
1698
+ }),
1699
+ /*#__PURE__*/ jsxs("div", {
1700
+ className: styles.paginationControls(),
1701
+ children: [
1702
+ /*#__PURE__*/ jsx(Pagination, {
1703
+ size: size,
1704
+ ...paginationProps,
1705
+ count: total,
1706
+ getPageUrl: ()=>"#",
1707
+ linkProps: {
1708
+ ...paginationProps?.linkProps,
1709
+ onClick: (event)=>{
1710
+ paginationProps?.linkProps?.onClick?.(event);
1711
+ event.preventDefault();
1712
+ }
1713
+ },
1714
+ onPageChange: (page)=>{
1715
+ if (!blocked("paginate")) table.setPageIndex(page - 1);
1716
+ },
1717
+ page: state.pageIndex + 1,
1718
+ pageSize: state.pageSize
1719
+ }),
1720
+ /*#__PURE__*/ jsx(FieldSelect, {
1721
+ ariaLabel: translations.pageSizeLabel,
1722
+ disabled: locked,
1723
+ items: pageSizeItems,
1724
+ onChange: (v)=>{
1725
+ if (!blocked("paginate")) table.setPageSize(Number(v));
1726
+ },
1727
+ size: size,
1728
+ value: String(state.pageSize)
1729
+ })
1730
+ ]
1731
+ })
1732
+ ]
1733
+ });
1734
+ };
1735
+ DataTable.displayName = "DataTable";
1736
+ export { DATA_TABLE_MAX_TOOLBAR_ACTIONS, DataTable, conditionalFilterFn };