@trackunit/react-table 0.0.586 → 0.0.590
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +105 -95
- package/index.esm.js +108 -99
- package/package.json +1 -1
- package/src/index.d.ts +2 -1
- package/src/useColumnHelper.d.ts +5 -0
package/index.cjs.js
CHANGED
|
@@ -7,14 +7,14 @@ var sharedUtils = require('@trackunit/shared-utils');
|
|
|
7
7
|
var React = require('react');
|
|
8
8
|
var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities');
|
|
9
9
|
var reactRouter = require('@tanstack/react-router');
|
|
10
|
-
var reactTable = require('@tanstack/react-table');
|
|
11
|
-
var reactTableBaseComponents = require('@trackunit/react-table-base-components');
|
|
12
|
-
var reactTablePagination = require('@trackunit/react-table-pagination');
|
|
13
|
-
var tailwindMerge = require('tailwind-merge');
|
|
14
10
|
var reactFormComponents = require('@trackunit/react-form-components');
|
|
15
11
|
var update = require('immutability-helper');
|
|
16
12
|
var reactDnd = require('react-dnd');
|
|
17
13
|
var reactDndHtml5Backend = require('react-dnd-html5-backend');
|
|
14
|
+
var reactTable = require('@tanstack/react-table');
|
|
15
|
+
var reactTableBaseComponents = require('@trackunit/react-table-base-components');
|
|
16
|
+
var reactTablePagination = require('@trackunit/react-table-pagination');
|
|
17
|
+
var tailwindMerge = require('tailwind-merge');
|
|
18
18
|
var reactCoreContextsApi = require('@trackunit/react-core-contexts-api');
|
|
19
19
|
|
|
20
20
|
function _interopNamespaceDefault(e) {
|
|
@@ -289,94 +289,6 @@ const ActionSheet = ({ actions, dropdownActions, moreActions = [], selections, r
|
|
|
289
289
|
moreActions: moreActions.map(action => actionDataToMenuItem(action, dataTestId)) })] }));
|
|
290
290
|
};
|
|
291
291
|
|
|
292
|
-
/**
|
|
293
|
-
* Table component for displaying large sets of data in tables with infinite scroll, sorting, filtering and others.
|
|
294
|
-
*
|
|
295
|
-
* @param {ReactTable} props - The props for the Table component
|
|
296
|
-
* @returns {JSX.Element} Table component
|
|
297
|
-
*/
|
|
298
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
299
|
-
const Table = ({ rowHeight = 75, ...props }) => {
|
|
300
|
-
var _a, _b, _c;
|
|
301
|
-
//we need a reference to the scrolling element for logic down below
|
|
302
|
-
const tableContainerRef = React.useRef(null);
|
|
303
|
-
const [t] = useTranslation();
|
|
304
|
-
const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize } = reactTablePagination.useInfiniteScroll({
|
|
305
|
-
pagination: props.pagination || reactTablePagination.noPagination,
|
|
306
|
-
containerRef: tableContainerRef,
|
|
307
|
-
rowSize: props.getRowModel().rows.length || 0,
|
|
308
|
-
rowHeight,
|
|
309
|
-
});
|
|
310
|
-
const hasResults = props.getRowModel().rows.length > 0;
|
|
311
|
-
return (jsxRuntime.jsxs(reactComponents.Card, { className: tailwindMerge.twMerge("flex flex-col overflow-hidden", props.className), dataTestId: props.dataTestId, children: [props.headerLeftActions || props.headerRightActions ? (jsxRuntime.jsxs("div", { className: "z-default flex justify-between gap-2 p-2", children: [jsxRuntime.jsx("div", { className: "flex items-center", children: props.headerLeftActions }), jsxRuntime.jsx("div", { className: "flex items-center", children: props.headerRightActions })] })) : null, jsxRuntime.jsx("div", { className: "h-full overflow-x-auto overflow-y-scroll border-b border-t border-gray-300", onScroll: e => fetchMoreOnBottomReached(e.target), ref: tableContainerRef, children: jsxRuntime.jsxs(reactTableBaseComponents.TableRoot, { style: {
|
|
312
|
-
height: hasResults ? "auto" : "100%",
|
|
313
|
-
width: "100%",
|
|
314
|
-
position: "relative",
|
|
315
|
-
}, children: [jsxRuntime.jsx(reactTableBaseComponents.Thead, { className: "z-default", children: props.getHeaderGroups().map(headerGroup => (jsxRuntime.jsx(reactTableBaseComponents.Tr, { className: "flex", children: headerGroup.headers.map(header => {
|
|
316
|
-
var _a, _b, _c, _d, _e, _f;
|
|
317
|
-
const tooltipLabel = (_b = (_a = header.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.tootipLabel) !== null && _b !== void 0 ? _b : (typeof header.column.columnDef.header === "string" ? header.column.columnDef.header : "");
|
|
318
|
-
return (jsxRuntime.jsxs(reactTableBaseComponents.Th, { className: "relative", style: {
|
|
319
|
-
width: header.getSize(),
|
|
320
|
-
minWidth: header.column.columnDef.minSize,
|
|
321
|
-
maxWidth: header.column.columnDef.maxSize,
|
|
322
|
-
textAlign: ((_c = header.column.columnDef.meta) === null || _c === void 0 ? void 0 : _c.alignment) || "left",
|
|
323
|
-
flexGrow: ((_d = header.column.columnDef.meta) === null || _d === void 0 ? void 0 : _d.shouldGrow) ? 1 : 0,
|
|
324
|
-
}, tooltipLabel: tooltipLabel, children: [header.isPlaceholder ? null : (jsxRuntime.jsxs("div", { className: `${header.column.getCanSort() ? "cursor-pointer select-none flex" : "flex"} items-center gap-2 py-2 overflow-hidden pr-3 w-full`,
|
|
325
|
-
onClick: header.column.getToggleSortingHandler(), children: [jsxRuntime.jsxs("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: [reactTable.flexRender(header.column.columnDef.header, header.getContext()), ((_e = header.column.columnDef.meta) === null || _e === void 0 ? void 0 : _e.subHeader) ? (jsxRuntime.jsx(reactComponents.Text, { size: "small", subtle: true, children: header.column.columnDef.meta.subHeader })) : null] }), header.column.getCanSort() ? (jsxRuntime.jsx(reactTableBaseComponents.SortIndicator, { sortingState: header.column.getIsSorted() })) : null] })), !((_f = header.column.columnDef.meta) === null || _f === void 0 ? void 0 : _f.shouldGrow) && header.column.getCanResize() ? (jsxRuntime.jsx(reactTableBaseComponents.ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null] }, header.id));
|
|
326
|
-
}) }, headerGroup.id))) }), hasResults ? (jsxRuntime.jsx(reactTableBaseComponents.Tbody, { className: "text-sm font-normal", style: {
|
|
327
|
-
height: `${getTotalSize()}px`,
|
|
328
|
-
flexGrow: 1,
|
|
329
|
-
}, children: getVirtualItems().map((virtualRow, index) => {
|
|
330
|
-
const row = props.getRowModel().rows[virtualRow.index];
|
|
331
|
-
if (!row) {
|
|
332
|
-
return null;
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
return (jsxRuntime.jsx(reactTableBaseComponents.Tr, { className: reactComponents.cvaInteractableItem({
|
|
336
|
-
cursor: !!props.onRowClick || row.getCanSelect() ? "pointer" : "default",
|
|
337
|
-
selected: "auto",
|
|
338
|
-
}), dataTestId: `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
|
|
339
|
-
if (props.onRowClick) {
|
|
340
|
-
props.onRowClick(row);
|
|
341
|
-
}
|
|
342
|
-
else if (row.getCanSelect()) {
|
|
343
|
-
row.toggleSelected();
|
|
344
|
-
}
|
|
345
|
-
}, style: {
|
|
346
|
-
height: `${virtualRow.size}px`,
|
|
347
|
-
transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
|
|
348
|
-
}, children: row.getVisibleCells().map(cell => {
|
|
349
|
-
var _a, _b;
|
|
350
|
-
return (jsxRuntime.jsx(reactTableBaseComponents.Td, { onClick: event => {
|
|
351
|
-
// prevent onRowClick action when clicking on a "selectable" cell with checkbox
|
|
352
|
-
if (props.selectionColId && cell.column.id === props.selectionColId) {
|
|
353
|
-
event.stopPropagation();
|
|
354
|
-
}
|
|
355
|
-
}, style: {
|
|
356
|
-
width: cell.column.getSize(),
|
|
357
|
-
minWidth: cell.column.columnDef.minSize,
|
|
358
|
-
maxWidth: cell.column.columnDef.maxSize,
|
|
359
|
-
textAlign: ((_a = cell.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.alignment) || "left",
|
|
360
|
-
flexGrow: ((_b = cell.column.columnDef.meta) === null || _b === void 0 ? void 0 : _b.shouldGrow) ? 1 : 0,
|
|
361
|
-
}, children: jsxRuntime.jsx("div", { className: "grid h-full items-center", children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }) }, cell.id));
|
|
362
|
-
}) }, row.id));
|
|
363
|
-
}
|
|
364
|
-
}) })) : (jsxRuntime.jsx("tbody", { className: cvaTBody({ emptyState: !props.loading && !props.noDataMessage }), children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { className: "b-0", children: props.loading ? (jsxRuntime.jsx(reactComponents.Spinner, { centering: "centered", containerClassName: "absolute inset-0" })) : props.noDataMessage ? (props.noDataMessage) : (jsxRuntime.jsx(reactComponents.EmptyState, { className: "absolute inset-0", description: t("table.noResults"), image: "SEARCH_DOCUMENT", ...props.emptyState })) }) }) }))] }) }), props.hideFooter ? null : (jsxRuntime.jsxs("div", { className: "flex items-center p-2", children: [jsxRuntime.jsx("div", { className: "whitespace-nowrap text-xs font-medium text-neutral-600", children: t("table.pagination.full", {
|
|
365
|
-
count: props.getRowModel().rows.length,
|
|
366
|
-
total: ((_b = (_a = props.pagination) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.count) || 0,
|
|
367
|
-
}) }), ((_c = props.pagination) === null || _c === void 0 ? void 0 : _c.isLoading) ? (jsxRuntime.jsx("span", { className: "ml-2", children: jsxRuntime.jsx(reactComponents.Spinner, { size: "small" }) })) : null, props.footerRightActions ? jsxRuntime.jsx("div", { className: "flex flex-1 justify-end", children: props.footerRightActions }) : null] }))] }));
|
|
368
|
-
};
|
|
369
|
-
const cvaTBody = cssClassVarianceUtilities.cvaMerge(["min-h-[40dvh]"], {
|
|
370
|
-
variants: {
|
|
371
|
-
emptyState: {
|
|
372
|
-
true: "min-h-[400px]",
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
defaultVariants: {
|
|
376
|
-
emptyState: false,
|
|
377
|
-
},
|
|
378
|
-
});
|
|
379
|
-
|
|
380
292
|
const cvaColumnFilterGrabbable = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "justify-center"], {
|
|
381
293
|
variants: {
|
|
382
294
|
disabled: {
|
|
@@ -582,6 +494,103 @@ const Sorting = ({ columns, }) => {
|
|
|
582
494
|
}) }), jsxRuntime.jsxs(reactFormComponents.RadioGroup, { id: "sortOrder", onChange: onSelectOrder, value: currentSortDirection, children: [jsxRuntime.jsx(reactFormComponents.RadioItem, { className: "w-full", label: t("table.sorting.ascending"), value: "asc" }), jsxRuntime.jsx(reactFormComponents.RadioItem, { className: "w-full", label: t("table.sorting.descending"), value: "desc" })] })] }) })] }) }));
|
|
583
495
|
};
|
|
584
496
|
|
|
497
|
+
/**
|
|
498
|
+
* Table component for displaying large sets of data in tables with infinite scroll, sorting, filtering and others.
|
|
499
|
+
*
|
|
500
|
+
* @param {ReactTable} props - The props for the Table component
|
|
501
|
+
* @returns {JSX.Element} Table component
|
|
502
|
+
*/
|
|
503
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
504
|
+
const Table = ({ rowHeight = 75, ...props }) => {
|
|
505
|
+
var _a, _b, _c;
|
|
506
|
+
//we need a reference to the scrolling element for logic down below
|
|
507
|
+
const tableContainerRef = React.useRef(null);
|
|
508
|
+
const [t] = useTranslation();
|
|
509
|
+
const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize } = reactTablePagination.useInfiniteScroll({
|
|
510
|
+
pagination: props.pagination || reactTablePagination.noPagination,
|
|
511
|
+
containerRef: tableContainerRef,
|
|
512
|
+
rowSize: props.getRowModel().rows.length || 0,
|
|
513
|
+
rowHeight,
|
|
514
|
+
});
|
|
515
|
+
const hasResults = props.getRowModel().rows.length > 0;
|
|
516
|
+
return (jsxRuntime.jsxs(reactComponents.Card, { className: tailwindMerge.twMerge("flex flex-col overflow-hidden", props.className), dataTestId: props.dataTestId, children: [props.headerLeftActions || props.headerRightActions ? (jsxRuntime.jsxs("div", { className: "z-default flex justify-between gap-2 p-2", children: [jsxRuntime.jsx("div", { className: "flex items-center", children: props.headerLeftActions }), jsxRuntime.jsx("div", { className: "flex items-center", children: props.headerRightActions })] })) : null, jsxRuntime.jsx("div", { className: "h-full overflow-x-auto overflow-y-scroll border-b border-t border-gray-300", onScroll: e => fetchMoreOnBottomReached(e.target), ref: tableContainerRef, children: jsxRuntime.jsxs(reactTableBaseComponents.TableRoot, { style: {
|
|
517
|
+
height: hasResults ? "auto" : "100%",
|
|
518
|
+
width: "100%",
|
|
519
|
+
position: "relative",
|
|
520
|
+
}, children: [jsxRuntime.jsx(reactTableBaseComponents.Thead, { className: "z-default", children: props.getHeaderGroups().map(headerGroup => (jsxRuntime.jsx(reactTableBaseComponents.Tr, { className: "flex", children: headerGroup.headers.map(header => {
|
|
521
|
+
var _a, _b, _c, _d, _e, _f;
|
|
522
|
+
const tooltipLabel = (_b = (_a = header.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.tootipLabel) !== null && _b !== void 0 ? _b : (typeof header.column.columnDef.header === "string" ? header.column.columnDef.header : "");
|
|
523
|
+
return (jsxRuntime.jsxs(reactTableBaseComponents.Th, { className: "relative", style: {
|
|
524
|
+
width: header.getSize(),
|
|
525
|
+
minWidth: header.column.columnDef.minSize,
|
|
526
|
+
maxWidth: header.column.columnDef.maxSize,
|
|
527
|
+
textAlign: ((_c = header.column.columnDef.meta) === null || _c === void 0 ? void 0 : _c.alignment) || "left",
|
|
528
|
+
flexGrow: ((_d = header.column.columnDef.meta) === null || _d === void 0 ? void 0 : _d.shouldGrow) ? 1 : 0,
|
|
529
|
+
}, tooltipLabel: tooltipLabel, children: [header.isPlaceholder ? null : (jsxRuntime.jsxs("div", { className: `${header.column.getCanSort() ? "cursor-pointer select-none flex" : "flex"} items-center gap-2 py-2 overflow-hidden pr-3 w-full`,
|
|
530
|
+
onClick: header.column.getToggleSortingHandler(), children: [jsxRuntime.jsxs("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: [reactTable.flexRender(header.column.columnDef.header, header.getContext()), ((_e = header.column.columnDef.meta) === null || _e === void 0 ? void 0 : _e.subHeader) ? (jsxRuntime.jsx(reactComponents.Text, { size: "small", subtle: true, children: header.column.columnDef.meta.subHeader })) : null] }), header.column.getCanSort() ? (jsxRuntime.jsx(reactTableBaseComponents.SortIndicator, { sortingState: header.column.getIsSorted() })) : null] })), !((_f = header.column.columnDef.meta) === null || _f === void 0 ? void 0 : _f.shouldGrow) && header.column.getCanResize() ? (jsxRuntime.jsx(reactTableBaseComponents.ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null] }, header.id));
|
|
531
|
+
}) }, headerGroup.id))) }), hasResults ? (jsxRuntime.jsx(reactTableBaseComponents.Tbody, { className: "text-sm font-normal", style: {
|
|
532
|
+
height: `${getTotalSize()}px`,
|
|
533
|
+
flexGrow: 1,
|
|
534
|
+
}, children: getVirtualItems().map((virtualRow, index) => {
|
|
535
|
+
const row = props.getRowModel().rows[virtualRow.index];
|
|
536
|
+
if (!row) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
return (jsxRuntime.jsx(reactTableBaseComponents.Tr, { className: reactComponents.cvaInteractableItem({
|
|
541
|
+
cursor: !!props.onRowClick || row.getCanSelect() ? "pointer" : "default",
|
|
542
|
+
selected: "auto",
|
|
543
|
+
}), dataTestId: `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
|
|
544
|
+
if (props.onRowClick) {
|
|
545
|
+
props.onRowClick(row);
|
|
546
|
+
}
|
|
547
|
+
else if (row.getCanSelect()) {
|
|
548
|
+
row.toggleSelected();
|
|
549
|
+
}
|
|
550
|
+
}, style: {
|
|
551
|
+
height: `${virtualRow.size}px`,
|
|
552
|
+
transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
|
|
553
|
+
}, children: row.getVisibleCells().map(cell => {
|
|
554
|
+
var _a, _b;
|
|
555
|
+
return (jsxRuntime.jsx(reactTableBaseComponents.Td, { onClick: event => {
|
|
556
|
+
// prevent onRowClick action when clicking on a "selectable" cell with checkbox
|
|
557
|
+
if (props.selectionColId && cell.column.id === props.selectionColId) {
|
|
558
|
+
event.stopPropagation();
|
|
559
|
+
}
|
|
560
|
+
}, style: {
|
|
561
|
+
width: cell.column.getSize(),
|
|
562
|
+
minWidth: cell.column.columnDef.minSize,
|
|
563
|
+
maxWidth: cell.column.columnDef.maxSize,
|
|
564
|
+
textAlign: ((_a = cell.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.alignment) || "left",
|
|
565
|
+
flexGrow: ((_b = cell.column.columnDef.meta) === null || _b === void 0 ? void 0 : _b.shouldGrow) ? 1 : 0,
|
|
566
|
+
}, children: jsxRuntime.jsx("div", { className: "grid h-full items-center", children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }) }, cell.id));
|
|
567
|
+
}) }, row.id));
|
|
568
|
+
}
|
|
569
|
+
}) })) : (jsxRuntime.jsx("tbody", { className: cvaTBody({ emptyState: !props.loading && !props.noDataMessage }), children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { className: "b-0", children: props.loading ? (jsxRuntime.jsx(reactComponents.Spinner, { centering: "centered", containerClassName: "absolute inset-0" })) : props.noDataMessage ? (props.noDataMessage) : (jsxRuntime.jsx(reactComponents.EmptyState, { className: "absolute inset-0", description: t("table.noResults"), image: "SEARCH_DOCUMENT", ...props.emptyState })) }) }) }))] }) }), props.hideFooter ? null : (jsxRuntime.jsxs("div", { className: "flex items-center p-2", children: [jsxRuntime.jsx("div", { className: "whitespace-nowrap text-xs font-medium text-neutral-600", children: t("table.pagination.full", {
|
|
570
|
+
count: props.getRowModel().rows.length,
|
|
571
|
+
total: ((_b = (_a = props.pagination) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.count) || 0,
|
|
572
|
+
}) }), ((_c = props.pagination) === null || _c === void 0 ? void 0 : _c.isLoading) ? (jsxRuntime.jsx("span", { className: "ml-2", children: jsxRuntime.jsx(reactComponents.Spinner, { size: "small" }) })) : null, props.footerRightActions ? jsxRuntime.jsx("div", { className: "flex flex-1 justify-end", children: props.footerRightActions }) : null] }))] }));
|
|
573
|
+
};
|
|
574
|
+
const cvaTBody = cssClassVarianceUtilities.cvaMerge(["min-h-[40dvh]"], {
|
|
575
|
+
variants: {
|
|
576
|
+
emptyState: {
|
|
577
|
+
true: "min-h-[400px]",
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
defaultVariants: {
|
|
581
|
+
emptyState: false,
|
|
582
|
+
},
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Creates and returns a memoized instance of a columnHelper
|
|
587
|
+
*/
|
|
588
|
+
const useColumnHelper = () => {
|
|
589
|
+
return React.useMemo(() => {
|
|
590
|
+
return reactTable.createColumnHelper();
|
|
591
|
+
}, []);
|
|
592
|
+
};
|
|
593
|
+
|
|
585
594
|
/**
|
|
586
595
|
* Hook for managing and controlling a table's state and behavior.
|
|
587
596
|
*
|
|
@@ -627,12 +636,12 @@ const useTable = ({ onTableStateChange, initialState, columns, ...reactTableProp
|
|
|
627
636
|
const [columnSizing, setColumnSizing] = React.useState(((_d = reactTableProps.state) === null || _d === void 0 ? void 0 : _d.columnSizing) || (initialState === null || initialState === void 0 ? void 0 : initialState.columnSizing) || {});
|
|
628
637
|
React.useEffect(() => {
|
|
629
638
|
if (initialState && sharedUtils.objectKeys(initialState).length > 0) {
|
|
630
|
-
setColumnVisibility(
|
|
631
|
-
setColumnOrder(
|
|
639
|
+
setColumnVisibility(updatedInitialColumnVisibility);
|
|
640
|
+
setColumnOrder(updatedInitialColumnOrder);
|
|
632
641
|
setSorting(initialState.sorting || []);
|
|
633
642
|
setColumnSizing(initialState.columnSizing || {});
|
|
634
643
|
}
|
|
635
|
-
}, [initialState,
|
|
644
|
+
}, [initialState, updatedInitialColumnOrder, updatedInitialColumnVisibility]);
|
|
636
645
|
const state = React.useMemo(() => {
|
|
637
646
|
return {
|
|
638
647
|
sorting,
|
|
@@ -817,5 +826,6 @@ exports.Sorting = Sorting;
|
|
|
817
826
|
exports.Table = Table;
|
|
818
827
|
exports.fromTUSortToTanStack = fromTUSortToTanStack;
|
|
819
828
|
exports.fromTanStackToTUSort = fromTanStackToTUSort;
|
|
829
|
+
exports.useColumnHelper = useColumnHelper;
|
|
820
830
|
exports.useTable = useTable;
|
|
821
831
|
exports.useTableSelection = useTableSelection;
|
package/index.esm.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
3
|
-
import { MenuItem, Icon, Button, useOverflowItems, MoreMenu, MenuList, Spacer,
|
|
3
|
+
import { MenuItem, Icon, Button, useOverflowItems, MoreMenu, MenuList, Spacer, Tooltip, Popover, PopoverTrigger, PopoverContent, Text, Card, cvaInteractableItem, Spinner, EmptyState } from '@trackunit/react-components';
|
|
4
4
|
import { objectValues, nonNullable, objectKeys, objectEntries } from '@trackunit/shared-utils';
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import { useMemo, Children, cloneElement,
|
|
6
|
+
import { useMemo, Children, cloneElement, useEffect, useRef, useState, useCallback } from 'react';
|
|
7
7
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
8
8
|
import { Link } from '@tanstack/react-router';
|
|
9
|
-
import { flexRender, useReactTable, getSortedRowModel, getCoreRowModel, createColumnHelper } from '@tanstack/react-table';
|
|
10
|
-
export { createColumnHelper } from '@tanstack/react-table';
|
|
11
|
-
import { TableRoot, Thead, Tr, Th, SortIndicator, ResizeHandle, Tbody, Td } from '@trackunit/react-table-base-components';
|
|
12
|
-
import { useInfiniteScroll, noPagination } from '@trackunit/react-table-pagination';
|
|
13
|
-
import { twMerge } from 'tailwind-merge';
|
|
14
9
|
import { Toggle, RadioGroup, RadioItem, Checkbox } from '@trackunit/react-form-components';
|
|
15
10
|
import update from 'immutability-helper';
|
|
16
11
|
import { DndProvider, useDrop, useDrag } from 'react-dnd';
|
|
17
12
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
13
|
+
import { flexRender, createColumnHelper, useReactTable, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
|
|
14
|
+
export { createColumnHelper } from '@tanstack/react-table';
|
|
15
|
+
import { TableRoot, Thead, Tr, Th, SortIndicator, ResizeHandle, Tbody, Td } from '@trackunit/react-table-base-components';
|
|
16
|
+
import { useInfiniteScroll, noPagination } from '@trackunit/react-table-pagination';
|
|
17
|
+
import { twMerge } from 'tailwind-merge';
|
|
18
18
|
import { SortOrder, validateStringAsAssetSortByProperty } from '@trackunit/react-core-contexts-api';
|
|
19
19
|
|
|
20
20
|
var defaultTranslations = {
|
|
@@ -270,94 +270,6 @@ const ActionSheet = ({ actions, dropdownActions, moreActions = [], selections, r
|
|
|
270
270
|
moreActions: moreActions.map(action => actionDataToMenuItem(action, dataTestId)) })] }));
|
|
271
271
|
};
|
|
272
272
|
|
|
273
|
-
/**
|
|
274
|
-
* Table component for displaying large sets of data in tables with infinite scroll, sorting, filtering and others.
|
|
275
|
-
*
|
|
276
|
-
* @param {ReactTable} props - The props for the Table component
|
|
277
|
-
* @returns {JSX.Element} Table component
|
|
278
|
-
*/
|
|
279
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
280
|
-
const Table = ({ rowHeight = 75, ...props }) => {
|
|
281
|
-
var _a, _b, _c;
|
|
282
|
-
//we need a reference to the scrolling element for logic down below
|
|
283
|
-
const tableContainerRef = useRef(null);
|
|
284
|
-
const [t] = useTranslation();
|
|
285
|
-
const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize } = useInfiniteScroll({
|
|
286
|
-
pagination: props.pagination || noPagination,
|
|
287
|
-
containerRef: tableContainerRef,
|
|
288
|
-
rowSize: props.getRowModel().rows.length || 0,
|
|
289
|
-
rowHeight,
|
|
290
|
-
});
|
|
291
|
-
const hasResults = props.getRowModel().rows.length > 0;
|
|
292
|
-
return (jsxs(Card, { className: twMerge("flex flex-col overflow-hidden", props.className), dataTestId: props.dataTestId, children: [props.headerLeftActions || props.headerRightActions ? (jsxs("div", { className: "z-default flex justify-between gap-2 p-2", children: [jsx("div", { className: "flex items-center", children: props.headerLeftActions }), jsx("div", { className: "flex items-center", children: props.headerRightActions })] })) : null, jsx("div", { className: "h-full overflow-x-auto overflow-y-scroll border-b border-t border-gray-300", onScroll: e => fetchMoreOnBottomReached(e.target), ref: tableContainerRef, children: jsxs(TableRoot, { style: {
|
|
293
|
-
height: hasResults ? "auto" : "100%",
|
|
294
|
-
width: "100%",
|
|
295
|
-
position: "relative",
|
|
296
|
-
}, children: [jsx(Thead, { className: "z-default", children: props.getHeaderGroups().map(headerGroup => (jsx(Tr, { className: "flex", children: headerGroup.headers.map(header => {
|
|
297
|
-
var _a, _b, _c, _d, _e, _f;
|
|
298
|
-
const tooltipLabel = (_b = (_a = header.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.tootipLabel) !== null && _b !== void 0 ? _b : (typeof header.column.columnDef.header === "string" ? header.column.columnDef.header : "");
|
|
299
|
-
return (jsxs(Th, { className: "relative", style: {
|
|
300
|
-
width: header.getSize(),
|
|
301
|
-
minWidth: header.column.columnDef.minSize,
|
|
302
|
-
maxWidth: header.column.columnDef.maxSize,
|
|
303
|
-
textAlign: ((_c = header.column.columnDef.meta) === null || _c === void 0 ? void 0 : _c.alignment) || "left",
|
|
304
|
-
flexGrow: ((_d = header.column.columnDef.meta) === null || _d === void 0 ? void 0 : _d.shouldGrow) ? 1 : 0,
|
|
305
|
-
}, tooltipLabel: tooltipLabel, children: [header.isPlaceholder ? null : (jsxs("div", { className: `${header.column.getCanSort() ? "cursor-pointer select-none flex" : "flex"} items-center gap-2 py-2 overflow-hidden pr-3 w-full`,
|
|
306
|
-
onClick: header.column.getToggleSortingHandler(), children: [jsxs("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: [flexRender(header.column.columnDef.header, header.getContext()), ((_e = header.column.columnDef.meta) === null || _e === void 0 ? void 0 : _e.subHeader) ? (jsx(Text, { size: "small", subtle: true, children: header.column.columnDef.meta.subHeader })) : null] }), header.column.getCanSort() ? (jsx(SortIndicator, { sortingState: header.column.getIsSorted() })) : null] })), !((_f = header.column.columnDef.meta) === null || _f === void 0 ? void 0 : _f.shouldGrow) && header.column.getCanResize() ? (jsx(ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null] }, header.id));
|
|
307
|
-
}) }, headerGroup.id))) }), hasResults ? (jsx(Tbody, { className: "text-sm font-normal", style: {
|
|
308
|
-
height: `${getTotalSize()}px`,
|
|
309
|
-
flexGrow: 1,
|
|
310
|
-
}, children: getVirtualItems().map((virtualRow, index) => {
|
|
311
|
-
const row = props.getRowModel().rows[virtualRow.index];
|
|
312
|
-
if (!row) {
|
|
313
|
-
return null;
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
return (jsx(Tr, { className: cvaInteractableItem({
|
|
317
|
-
cursor: !!props.onRowClick || row.getCanSelect() ? "pointer" : "default",
|
|
318
|
-
selected: "auto",
|
|
319
|
-
}), dataTestId: `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
|
|
320
|
-
if (props.onRowClick) {
|
|
321
|
-
props.onRowClick(row);
|
|
322
|
-
}
|
|
323
|
-
else if (row.getCanSelect()) {
|
|
324
|
-
row.toggleSelected();
|
|
325
|
-
}
|
|
326
|
-
}, style: {
|
|
327
|
-
height: `${virtualRow.size}px`,
|
|
328
|
-
transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
|
|
329
|
-
}, children: row.getVisibleCells().map(cell => {
|
|
330
|
-
var _a, _b;
|
|
331
|
-
return (jsx(Td, { onClick: event => {
|
|
332
|
-
// prevent onRowClick action when clicking on a "selectable" cell with checkbox
|
|
333
|
-
if (props.selectionColId && cell.column.id === props.selectionColId) {
|
|
334
|
-
event.stopPropagation();
|
|
335
|
-
}
|
|
336
|
-
}, style: {
|
|
337
|
-
width: cell.column.getSize(),
|
|
338
|
-
minWidth: cell.column.columnDef.minSize,
|
|
339
|
-
maxWidth: cell.column.columnDef.maxSize,
|
|
340
|
-
textAlign: ((_a = cell.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.alignment) || "left",
|
|
341
|
-
flexGrow: ((_b = cell.column.columnDef.meta) === null || _b === void 0 ? void 0 : _b.shouldGrow) ? 1 : 0,
|
|
342
|
-
}, children: jsx("div", { className: "grid h-full items-center", children: flexRender(cell.column.columnDef.cell, cell.getContext()) }) }, cell.id));
|
|
343
|
-
}) }, row.id));
|
|
344
|
-
}
|
|
345
|
-
}) })) : (jsx("tbody", { className: cvaTBody({ emptyState: !props.loading && !props.noDataMessage }), children: jsx("tr", { children: jsx("td", { className: "b-0", children: props.loading ? (jsx(Spinner, { centering: "centered", containerClassName: "absolute inset-0" })) : props.noDataMessage ? (props.noDataMessage) : (jsx(EmptyState, { className: "absolute inset-0", description: t("table.noResults"), image: "SEARCH_DOCUMENT", ...props.emptyState })) }) }) }))] }) }), props.hideFooter ? null : (jsxs("div", { className: "flex items-center p-2", children: [jsx("div", { className: "whitespace-nowrap text-xs font-medium text-neutral-600", children: t("table.pagination.full", {
|
|
346
|
-
count: props.getRowModel().rows.length,
|
|
347
|
-
total: ((_b = (_a = props.pagination) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.count) || 0,
|
|
348
|
-
}) }), ((_c = props.pagination) === null || _c === void 0 ? void 0 : _c.isLoading) ? (jsx("span", { className: "ml-2", children: jsx(Spinner, { size: "small" }) })) : null, props.footerRightActions ? jsx("div", { className: "flex flex-1 justify-end", children: props.footerRightActions }) : null] }))] }));
|
|
349
|
-
};
|
|
350
|
-
const cvaTBody = cvaMerge(["min-h-[40dvh]"], {
|
|
351
|
-
variants: {
|
|
352
|
-
emptyState: {
|
|
353
|
-
true: "min-h-[400px]",
|
|
354
|
-
},
|
|
355
|
-
},
|
|
356
|
-
defaultVariants: {
|
|
357
|
-
emptyState: false,
|
|
358
|
-
},
|
|
359
|
-
});
|
|
360
|
-
|
|
361
273
|
const cvaColumnFilterGrabbable = cvaMerge(["flex", "items-center", "justify-center"], {
|
|
362
274
|
variants: {
|
|
363
275
|
disabled: {
|
|
@@ -563,6 +475,103 @@ const Sorting = ({ columns, }) => {
|
|
|
563
475
|
}) }), jsxs(RadioGroup, { id: "sortOrder", onChange: onSelectOrder, value: currentSortDirection, children: [jsx(RadioItem, { className: "w-full", label: t("table.sorting.ascending"), value: "asc" }), jsx(RadioItem, { className: "w-full", label: t("table.sorting.descending"), value: "desc" })] })] }) })] }) }));
|
|
564
476
|
};
|
|
565
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Table component for displaying large sets of data in tables with infinite scroll, sorting, filtering and others.
|
|
480
|
+
*
|
|
481
|
+
* @param {ReactTable} props - The props for the Table component
|
|
482
|
+
* @returns {JSX.Element} Table component
|
|
483
|
+
*/
|
|
484
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
485
|
+
const Table = ({ rowHeight = 75, ...props }) => {
|
|
486
|
+
var _a, _b, _c;
|
|
487
|
+
//we need a reference to the scrolling element for logic down below
|
|
488
|
+
const tableContainerRef = useRef(null);
|
|
489
|
+
const [t] = useTranslation();
|
|
490
|
+
const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize } = useInfiniteScroll({
|
|
491
|
+
pagination: props.pagination || noPagination,
|
|
492
|
+
containerRef: tableContainerRef,
|
|
493
|
+
rowSize: props.getRowModel().rows.length || 0,
|
|
494
|
+
rowHeight,
|
|
495
|
+
});
|
|
496
|
+
const hasResults = props.getRowModel().rows.length > 0;
|
|
497
|
+
return (jsxs(Card, { className: twMerge("flex flex-col overflow-hidden", props.className), dataTestId: props.dataTestId, children: [props.headerLeftActions || props.headerRightActions ? (jsxs("div", { className: "z-default flex justify-between gap-2 p-2", children: [jsx("div", { className: "flex items-center", children: props.headerLeftActions }), jsx("div", { className: "flex items-center", children: props.headerRightActions })] })) : null, jsx("div", { className: "h-full overflow-x-auto overflow-y-scroll border-b border-t border-gray-300", onScroll: e => fetchMoreOnBottomReached(e.target), ref: tableContainerRef, children: jsxs(TableRoot, { style: {
|
|
498
|
+
height: hasResults ? "auto" : "100%",
|
|
499
|
+
width: "100%",
|
|
500
|
+
position: "relative",
|
|
501
|
+
}, children: [jsx(Thead, { className: "z-default", children: props.getHeaderGroups().map(headerGroup => (jsx(Tr, { className: "flex", children: headerGroup.headers.map(header => {
|
|
502
|
+
var _a, _b, _c, _d, _e, _f;
|
|
503
|
+
const tooltipLabel = (_b = (_a = header.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.tootipLabel) !== null && _b !== void 0 ? _b : (typeof header.column.columnDef.header === "string" ? header.column.columnDef.header : "");
|
|
504
|
+
return (jsxs(Th, { className: "relative", style: {
|
|
505
|
+
width: header.getSize(),
|
|
506
|
+
minWidth: header.column.columnDef.minSize,
|
|
507
|
+
maxWidth: header.column.columnDef.maxSize,
|
|
508
|
+
textAlign: ((_c = header.column.columnDef.meta) === null || _c === void 0 ? void 0 : _c.alignment) || "left",
|
|
509
|
+
flexGrow: ((_d = header.column.columnDef.meta) === null || _d === void 0 ? void 0 : _d.shouldGrow) ? 1 : 0,
|
|
510
|
+
}, tooltipLabel: tooltipLabel, children: [header.isPlaceholder ? null : (jsxs("div", { className: `${header.column.getCanSort() ? "cursor-pointer select-none flex" : "flex"} items-center gap-2 py-2 overflow-hidden pr-3 w-full`,
|
|
511
|
+
onClick: header.column.getToggleSortingHandler(), children: [jsxs("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: [flexRender(header.column.columnDef.header, header.getContext()), ((_e = header.column.columnDef.meta) === null || _e === void 0 ? void 0 : _e.subHeader) ? (jsx(Text, { size: "small", subtle: true, children: header.column.columnDef.meta.subHeader })) : null] }), header.column.getCanSort() ? (jsx(SortIndicator, { sortingState: header.column.getIsSorted() })) : null] })), !((_f = header.column.columnDef.meta) === null || _f === void 0 ? void 0 : _f.shouldGrow) && header.column.getCanResize() ? (jsx(ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null] }, header.id));
|
|
512
|
+
}) }, headerGroup.id))) }), hasResults ? (jsx(Tbody, { className: "text-sm font-normal", style: {
|
|
513
|
+
height: `${getTotalSize()}px`,
|
|
514
|
+
flexGrow: 1,
|
|
515
|
+
}, children: getVirtualItems().map((virtualRow, index) => {
|
|
516
|
+
const row = props.getRowModel().rows[virtualRow.index];
|
|
517
|
+
if (!row) {
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
return (jsx(Tr, { className: cvaInteractableItem({
|
|
522
|
+
cursor: !!props.onRowClick || row.getCanSelect() ? "pointer" : "default",
|
|
523
|
+
selected: "auto",
|
|
524
|
+
}), dataTestId: `table-body-row-${virtualRow.index}`, layout: "flex", onClick: () => {
|
|
525
|
+
if (props.onRowClick) {
|
|
526
|
+
props.onRowClick(row);
|
|
527
|
+
}
|
|
528
|
+
else if (row.getCanSelect()) {
|
|
529
|
+
row.toggleSelected();
|
|
530
|
+
}
|
|
531
|
+
}, style: {
|
|
532
|
+
height: `${virtualRow.size}px`,
|
|
533
|
+
transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
|
|
534
|
+
}, children: row.getVisibleCells().map(cell => {
|
|
535
|
+
var _a, _b;
|
|
536
|
+
return (jsx(Td, { onClick: event => {
|
|
537
|
+
// prevent onRowClick action when clicking on a "selectable" cell with checkbox
|
|
538
|
+
if (props.selectionColId && cell.column.id === props.selectionColId) {
|
|
539
|
+
event.stopPropagation();
|
|
540
|
+
}
|
|
541
|
+
}, style: {
|
|
542
|
+
width: cell.column.getSize(),
|
|
543
|
+
minWidth: cell.column.columnDef.minSize,
|
|
544
|
+
maxWidth: cell.column.columnDef.maxSize,
|
|
545
|
+
textAlign: ((_a = cell.column.columnDef.meta) === null || _a === void 0 ? void 0 : _a.alignment) || "left",
|
|
546
|
+
flexGrow: ((_b = cell.column.columnDef.meta) === null || _b === void 0 ? void 0 : _b.shouldGrow) ? 1 : 0,
|
|
547
|
+
}, children: jsx("div", { className: "grid h-full items-center", children: flexRender(cell.column.columnDef.cell, cell.getContext()) }) }, cell.id));
|
|
548
|
+
}) }, row.id));
|
|
549
|
+
}
|
|
550
|
+
}) })) : (jsx("tbody", { className: cvaTBody({ emptyState: !props.loading && !props.noDataMessage }), children: jsx("tr", { children: jsx("td", { className: "b-0", children: props.loading ? (jsx(Spinner, { centering: "centered", containerClassName: "absolute inset-0" })) : props.noDataMessage ? (props.noDataMessage) : (jsx(EmptyState, { className: "absolute inset-0", description: t("table.noResults"), image: "SEARCH_DOCUMENT", ...props.emptyState })) }) }) }))] }) }), props.hideFooter ? null : (jsxs("div", { className: "flex items-center p-2", children: [jsx("div", { className: "whitespace-nowrap text-xs font-medium text-neutral-600", children: t("table.pagination.full", {
|
|
551
|
+
count: props.getRowModel().rows.length,
|
|
552
|
+
total: ((_b = (_a = props.pagination) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.count) || 0,
|
|
553
|
+
}) }), ((_c = props.pagination) === null || _c === void 0 ? void 0 : _c.isLoading) ? (jsx("span", { className: "ml-2", children: jsx(Spinner, { size: "small" }) })) : null, props.footerRightActions ? jsx("div", { className: "flex flex-1 justify-end", children: props.footerRightActions }) : null] }))] }));
|
|
554
|
+
};
|
|
555
|
+
const cvaTBody = cvaMerge(["min-h-[40dvh]"], {
|
|
556
|
+
variants: {
|
|
557
|
+
emptyState: {
|
|
558
|
+
true: "min-h-[400px]",
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
defaultVariants: {
|
|
562
|
+
emptyState: false,
|
|
563
|
+
},
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Creates and returns a memoized instance of a columnHelper
|
|
568
|
+
*/
|
|
569
|
+
const useColumnHelper = () => {
|
|
570
|
+
return useMemo(() => {
|
|
571
|
+
return createColumnHelper();
|
|
572
|
+
}, []);
|
|
573
|
+
};
|
|
574
|
+
|
|
566
575
|
/**
|
|
567
576
|
* Hook for managing and controlling a table's state and behavior.
|
|
568
577
|
*
|
|
@@ -608,12 +617,12 @@ const useTable = ({ onTableStateChange, initialState, columns, ...reactTableProp
|
|
|
608
617
|
const [columnSizing, setColumnSizing] = useState(((_d = reactTableProps.state) === null || _d === void 0 ? void 0 : _d.columnSizing) || (initialState === null || initialState === void 0 ? void 0 : initialState.columnSizing) || {});
|
|
609
618
|
useEffect(() => {
|
|
610
619
|
if (initialState && objectKeys(initialState).length > 0) {
|
|
611
|
-
setColumnVisibility(
|
|
612
|
-
setColumnOrder(
|
|
620
|
+
setColumnVisibility(updatedInitialColumnVisibility);
|
|
621
|
+
setColumnOrder(updatedInitialColumnOrder);
|
|
613
622
|
setSorting(initialState.sorting || []);
|
|
614
623
|
setColumnSizing(initialState.columnSizing || {});
|
|
615
624
|
}
|
|
616
|
-
}, [initialState,
|
|
625
|
+
}, [initialState, updatedInitialColumnOrder, updatedInitialColumnVisibility]);
|
|
617
626
|
const state = useMemo(() => {
|
|
618
627
|
return {
|
|
619
628
|
sorting,
|
|
@@ -787,4 +796,4 @@ const fromTanStackToTUSort = (input) => {
|
|
|
787
796
|
*/
|
|
788
797
|
setupLibraryTranslations();
|
|
789
798
|
|
|
790
|
-
export { ActionSheet, ColumnFilter, RowSpacing, Sorting, Table, fromTUSortToTanStack, fromTanStackToTUSort, useTable, useTableSelection };
|
|
799
|
+
export { ActionSheet, ColumnFilter, RowSpacing, Sorting, Table, fromTUSortToTanStack, fromTanStackToTUSort, useColumnHelper, useTable, useTableSelection };
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ColumnSort } from "@tanstack/react-table";
|
|
2
2
|
export * from "./ActionSheet";
|
|
3
|
-
export * from "./Table";
|
|
4
3
|
export * from "./menus/ColumnFilter";
|
|
5
4
|
export * from "./menus/RowSpacing";
|
|
6
5
|
export * from "./menus/Sorting";
|
|
6
|
+
export * from "./Table";
|
|
7
7
|
export * from "./types";
|
|
8
|
+
export * from "./useColumnHelper";
|
|
8
9
|
export * from "./useTable";
|
|
9
10
|
export * from "./useTableSelection";
|
|
10
11
|
export * from "./utils";
|