@trackunit/react-table 0.0.175 → 0.0.177
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 +83 -1
- package/index.esm.js +85 -4
- package/package.json +1 -1
- package/src/index.d.ts +1 -0
- package/src/useTableSelection.d.ts +72 -0
package/index.cjs.js
CHANGED
|
@@ -345,6 +345,7 @@ const Table = (_a) => {
|
|
|
345
345
|
rowHeight,
|
|
346
346
|
});
|
|
347
347
|
const hasResults = props.getRowModel().rows.length > 0;
|
|
348
|
+
console.log("onRowClick", props.onRowClick);
|
|
348
349
|
return (jsxRuntime.jsxs(reactComponents.Card, { className: `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", children: props.headerLeftActions }), jsxRuntime.jsx("div", { className: "flex", children: props.headerRightActions })] })), jsxRuntime.jsx("div", { className: "min-h[500px] h-full overflow-x-auto overflow-y-scroll border-b border-t border-gray-300", ref: tableContainerRef, onScroll: e => fetchMoreOnBottomReached(e.target), children: jsxRuntime.jsxs(reactTableBaseComponents.TableRoot, { style: {
|
|
349
350
|
height: getTotalSize() > 0 ? getTotalSize() : "100%",
|
|
350
351
|
width: "100%",
|
|
@@ -366,7 +367,14 @@ const Table = (_a) => {
|
|
|
366
367
|
return (jsxRuntime.jsx(reactTableBaseComponents.Tr, { layout: "flex", style: {
|
|
367
368
|
height: `${virtualRow.size}px`,
|
|
368
369
|
transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
|
|
369
|
-
}, onClick: () =>
|
|
370
|
+
}, onClick: () => {
|
|
371
|
+
if (props.onRowClick) {
|
|
372
|
+
props.onRowClick(row);
|
|
373
|
+
}
|
|
374
|
+
else if (row.getCanSelect()) {
|
|
375
|
+
row.toggleSelected();
|
|
376
|
+
}
|
|
377
|
+
}, className: `${(props.onRowClick || row.getCanSelect()) && "cursor-pointer"} hover:bg-neutral-100`, dataTestId: `table-body-row-${virtualRow.index}`, children: row === null || row === void 0 ? void 0 : row.getVisibleCells().map(cell => {
|
|
370
378
|
return (jsxRuntime.jsx(reactTableBaseComponents.Td, { key: cell.id,
|
|
371
379
|
style: {
|
|
372
380
|
width: cell.column.getSize(),
|
|
@@ -686,6 +694,79 @@ const useTable = (_a) => {
|
|
|
686
694
|
return memoizedTable;
|
|
687
695
|
};
|
|
688
696
|
|
|
697
|
+
/**
|
|
698
|
+
* `useTableSelection` is a custom hook that provides functionality for row selection in a table.
|
|
699
|
+
* It returns an object containing methods and values related to row selection.
|
|
700
|
+
*
|
|
701
|
+
* @template TData - The type of data in the table. It must extend `selectableTableData`, which means it should at least have an `id` field.
|
|
702
|
+
* @returns {TableSelectionReturn<TData>} An object containing:
|
|
703
|
+
* - `selectionColumn`: A `ColumnDef` object for the selection column, which includes a checkbox in each cell and header.
|
|
704
|
+
* - `rowSelection`: The current state of row selection.
|
|
705
|
+
* - `setRowSelection`: A function to update the row selection state.
|
|
706
|
+
* @example
|
|
707
|
+
* const {
|
|
708
|
+
* selectionColumn,
|
|
709
|
+
* rowSelection,
|
|
710
|
+
* setRowSelection,
|
|
711
|
+
* } = useTableSelection<MyDataType>();
|
|
712
|
+
*
|
|
713
|
+
* const columns = [selectionColumn, ...otherColumns]
|
|
714
|
+
*
|
|
715
|
+
* const tableProps = useTable({
|
|
716
|
+
* ...selectionTableProps,
|
|
717
|
+
* state: {
|
|
718
|
+
* ...selectionTableState,
|
|
719
|
+
* },
|
|
720
|
+
* data,
|
|
721
|
+
* columns
|
|
722
|
+
* });
|
|
723
|
+
*/
|
|
724
|
+
const useTableSelection = ({ data, }) => {
|
|
725
|
+
const [rowSelection, setRowSelection] = React.useState({});
|
|
726
|
+
const toggleRowSelectionState = React.useCallback((id) => {
|
|
727
|
+
setRowSelection(prevRowSelection => (Object.assign(Object.assign({}, prevRowSelection), { [id]: !prevRowSelection[id] })));
|
|
728
|
+
}, []);
|
|
729
|
+
const selectedIds = React.useMemo(() => Object.entries(rowSelection)
|
|
730
|
+
.filter(([_, selected]) => selected)
|
|
731
|
+
.map(([id]) => id), [rowSelection]);
|
|
732
|
+
const columnHelper = React.useMemo(() => reactTable.createColumnHelper(), []);
|
|
733
|
+
const selectionColumn = React.useMemo(() => columnHelper.accessor(row => row.id, {
|
|
734
|
+
cell: ({ row }) => (jsxRuntime.jsx(reactFormComponents.Checkbox, { className: "ml-1",
|
|
735
|
+
checked: row.getIsSelected(),
|
|
736
|
+
disabled: !row.getCanSelect(),
|
|
737
|
+
indeterminate: row.getIsSomeSelected(),
|
|
738
|
+
onChange: row.getToggleSelectedHandler(),
|
|
739
|
+
stopPropagation: true })),
|
|
740
|
+
header: ({ table }) => (jsxRuntime.jsx(reactFormComponents.Checkbox, { checked: table.getIsAllRowsSelected(),
|
|
741
|
+
indeterminate: table.getIsSomeRowsSelected(),
|
|
742
|
+
onChange: table.getToggleAllRowsSelectedHandler() })),
|
|
743
|
+
id: "selection",
|
|
744
|
+
enableSorting: false,
|
|
745
|
+
enableResizing: false,
|
|
746
|
+
size: 55,
|
|
747
|
+
meta: {
|
|
748
|
+
required: true,
|
|
749
|
+
alignment: "left",
|
|
750
|
+
},
|
|
751
|
+
}), [columnHelper]);
|
|
752
|
+
const selectionTableState = React.useMemo(() => ({
|
|
753
|
+
rowSelection,
|
|
754
|
+
}), [rowSelection]);
|
|
755
|
+
const selectionTableProps = React.useMemo(() => ({
|
|
756
|
+
onRowSelectionChange: setRowSelection,
|
|
757
|
+
getRowId: row => row.id,
|
|
758
|
+
enableRowSelection: true,
|
|
759
|
+
}), []);
|
|
760
|
+
return React.useMemo(() => ({
|
|
761
|
+
toggleRowSelectionState,
|
|
762
|
+
selectionColumn,
|
|
763
|
+
selectedIds,
|
|
764
|
+
selectionTableState,
|
|
765
|
+
selectionTableProps,
|
|
766
|
+
setRowSelection,
|
|
767
|
+
}), [selectedIds, selectionColumn, selectionTableProps, selectionTableState, toggleRowSelectionState]);
|
|
768
|
+
};
|
|
769
|
+
|
|
689
770
|
//TODO: find a more appropriate place for this file
|
|
690
771
|
/**
|
|
691
772
|
* Convert a sorting state from the TUSort format to the TanStack format.
|
|
@@ -752,3 +833,4 @@ exports.fromTanStackToTUSort = fromTanStackToTUSort;
|
|
|
752
833
|
exports.fromTanStackToTUSortSite = fromTanStackToTUSortSite;
|
|
753
834
|
exports.useRelayPagination = useRelayPagination;
|
|
754
835
|
exports.useTable = useTable;
|
|
836
|
+
exports.useTableSelection = useTableSelection;
|
package/index.esm.js
CHANGED
|
@@ -5,11 +5,11 @@ import * as React from 'react';
|
|
|
5
5
|
import { useMemo, Children, cloneElement, useCallback, useEffect, useRef, useState } from 'react';
|
|
6
6
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
7
7
|
import { Link } from 'react-router-dom';
|
|
8
|
-
import { flexRender, useReactTable, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
|
|
8
|
+
import { flexRender, useReactTable, getSortedRowModel, getCoreRowModel, createColumnHelper } from '@tanstack/react-table';
|
|
9
9
|
export { createColumnHelper } from '@tanstack/react-table';
|
|
10
10
|
import { TableRoot, Thead, Tr, Th, SortIndicator, ResizeHandle, Tbody, Td } from '@trackunit/react-table-base-components';
|
|
11
11
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
12
|
-
import { Toggle, RadioGroup, RadioItem } from '@trackunit/react-form-components';
|
|
12
|
+
import { Toggle, RadioGroup, RadioItem, Checkbox } from '@trackunit/react-form-components';
|
|
13
13
|
import update from 'immutability-helper';
|
|
14
14
|
import { DndProvider, useDrop, useDrag } from 'react-dnd';
|
|
15
15
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
@@ -320,6 +320,7 @@ const Table = (_a) => {
|
|
|
320
320
|
rowHeight,
|
|
321
321
|
});
|
|
322
322
|
const hasResults = props.getRowModel().rows.length > 0;
|
|
323
|
+
console.log("onRowClick", props.onRowClick);
|
|
323
324
|
return (jsxs(Card, { className: `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", children: props.headerLeftActions }), jsx("div", { className: "flex", children: props.headerRightActions })] })), jsx("div", { className: "min-h[500px] h-full overflow-x-auto overflow-y-scroll border-b border-t border-gray-300", ref: tableContainerRef, onScroll: e => fetchMoreOnBottomReached(e.target), children: jsxs(TableRoot, { style: {
|
|
324
325
|
height: getTotalSize() > 0 ? getTotalSize() : "100%",
|
|
325
326
|
width: "100%",
|
|
@@ -341,7 +342,14 @@ const Table = (_a) => {
|
|
|
341
342
|
return (jsx(Tr, { layout: "flex", style: {
|
|
342
343
|
height: `${virtualRow.size}px`,
|
|
343
344
|
transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
|
|
344
|
-
}, onClick: () =>
|
|
345
|
+
}, onClick: () => {
|
|
346
|
+
if (props.onRowClick) {
|
|
347
|
+
props.onRowClick(row);
|
|
348
|
+
}
|
|
349
|
+
else if (row.getCanSelect()) {
|
|
350
|
+
row.toggleSelected();
|
|
351
|
+
}
|
|
352
|
+
}, className: `${(props.onRowClick || row.getCanSelect()) && "cursor-pointer"} hover:bg-neutral-100`, dataTestId: `table-body-row-${virtualRow.index}`, children: row === null || row === void 0 ? void 0 : row.getVisibleCells().map(cell => {
|
|
345
353
|
return (jsx(Td, { key: cell.id,
|
|
346
354
|
style: {
|
|
347
355
|
width: cell.column.getSize(),
|
|
@@ -661,6 +669,79 @@ const useTable = (_a) => {
|
|
|
661
669
|
return memoizedTable;
|
|
662
670
|
};
|
|
663
671
|
|
|
672
|
+
/**
|
|
673
|
+
* `useTableSelection` is a custom hook that provides functionality for row selection in a table.
|
|
674
|
+
* It returns an object containing methods and values related to row selection.
|
|
675
|
+
*
|
|
676
|
+
* @template TData - The type of data in the table. It must extend `selectableTableData`, which means it should at least have an `id` field.
|
|
677
|
+
* @returns {TableSelectionReturn<TData>} An object containing:
|
|
678
|
+
* - `selectionColumn`: A `ColumnDef` object for the selection column, which includes a checkbox in each cell and header.
|
|
679
|
+
* - `rowSelection`: The current state of row selection.
|
|
680
|
+
* - `setRowSelection`: A function to update the row selection state.
|
|
681
|
+
* @example
|
|
682
|
+
* const {
|
|
683
|
+
* selectionColumn,
|
|
684
|
+
* rowSelection,
|
|
685
|
+
* setRowSelection,
|
|
686
|
+
* } = useTableSelection<MyDataType>();
|
|
687
|
+
*
|
|
688
|
+
* const columns = [selectionColumn, ...otherColumns]
|
|
689
|
+
*
|
|
690
|
+
* const tableProps = useTable({
|
|
691
|
+
* ...selectionTableProps,
|
|
692
|
+
* state: {
|
|
693
|
+
* ...selectionTableState,
|
|
694
|
+
* },
|
|
695
|
+
* data,
|
|
696
|
+
* columns
|
|
697
|
+
* });
|
|
698
|
+
*/
|
|
699
|
+
const useTableSelection = ({ data, }) => {
|
|
700
|
+
const [rowSelection, setRowSelection] = useState({});
|
|
701
|
+
const toggleRowSelectionState = useCallback((id) => {
|
|
702
|
+
setRowSelection(prevRowSelection => (Object.assign(Object.assign({}, prevRowSelection), { [id]: !prevRowSelection[id] })));
|
|
703
|
+
}, []);
|
|
704
|
+
const selectedIds = useMemo(() => Object.entries(rowSelection)
|
|
705
|
+
.filter(([_, selected]) => selected)
|
|
706
|
+
.map(([id]) => id), [rowSelection]);
|
|
707
|
+
const columnHelper = useMemo(() => createColumnHelper(), []);
|
|
708
|
+
const selectionColumn = useMemo(() => columnHelper.accessor(row => row.id, {
|
|
709
|
+
cell: ({ row }) => (jsx(Checkbox, { className: "ml-1",
|
|
710
|
+
checked: row.getIsSelected(),
|
|
711
|
+
disabled: !row.getCanSelect(),
|
|
712
|
+
indeterminate: row.getIsSomeSelected(),
|
|
713
|
+
onChange: row.getToggleSelectedHandler(),
|
|
714
|
+
stopPropagation: true })),
|
|
715
|
+
header: ({ table }) => (jsx(Checkbox, { checked: table.getIsAllRowsSelected(),
|
|
716
|
+
indeterminate: table.getIsSomeRowsSelected(),
|
|
717
|
+
onChange: table.getToggleAllRowsSelectedHandler() })),
|
|
718
|
+
id: "selection",
|
|
719
|
+
enableSorting: false,
|
|
720
|
+
enableResizing: false,
|
|
721
|
+
size: 55,
|
|
722
|
+
meta: {
|
|
723
|
+
required: true,
|
|
724
|
+
alignment: "left",
|
|
725
|
+
},
|
|
726
|
+
}), [columnHelper]);
|
|
727
|
+
const selectionTableState = useMemo(() => ({
|
|
728
|
+
rowSelection,
|
|
729
|
+
}), [rowSelection]);
|
|
730
|
+
const selectionTableProps = useMemo(() => ({
|
|
731
|
+
onRowSelectionChange: setRowSelection,
|
|
732
|
+
getRowId: row => row.id,
|
|
733
|
+
enableRowSelection: true,
|
|
734
|
+
}), []);
|
|
735
|
+
return useMemo(() => ({
|
|
736
|
+
toggleRowSelectionState,
|
|
737
|
+
selectionColumn,
|
|
738
|
+
selectedIds,
|
|
739
|
+
selectionTableState,
|
|
740
|
+
selectionTableProps,
|
|
741
|
+
setRowSelection,
|
|
742
|
+
}), [selectedIds, selectionColumn, selectionTableProps, selectionTableState, toggleRowSelectionState]);
|
|
743
|
+
};
|
|
744
|
+
|
|
664
745
|
//TODO: find a more appropriate place for this file
|
|
665
746
|
/**
|
|
666
747
|
* Convert a sorting state from the TUSort format to the TanStack format.
|
|
@@ -712,4 +793,4 @@ const fromTanStackToTUSortSite = (input) => {
|
|
|
712
793
|
*/
|
|
713
794
|
setupLibraryTranslations();
|
|
714
795
|
|
|
715
|
-
export { ActionSheet, ColumnFilter, RowSpacing, Sorting, Table, fromTUSortToTanStack, fromTUSortToTanStackSite, fromTanStackToTUSort, fromTanStackToTUSortSite, useRelayPagination, useTable };
|
|
796
|
+
export { ActionSheet, ColumnFilter, RowSpacing, Sorting, Table, fromTUSortToTanStack, fromTUSortToTanStackSite, fromTanStackToTUSort, fromTanStackToTUSortSite, useRelayPagination, useTable, useTableSelection };
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ColumnDef, RowSelectionState } from "@tanstack/react-table";
|
|
2
|
+
import { Dispatch, SetStateAction } from "react";
|
|
3
|
+
type selectableTableData = {
|
|
4
|
+
id: string;
|
|
5
|
+
} & object;
|
|
6
|
+
export interface TableSelectionReturn<TData extends selectableTableData> {
|
|
7
|
+
/**
|
|
8
|
+
* An array of the ids of the currently selected rows.
|
|
9
|
+
*/
|
|
10
|
+
selectedIds: TData["id"][];
|
|
11
|
+
/**
|
|
12
|
+
* The current state of row selection.
|
|
13
|
+
* Pass this to the `state` prop of the `useTable` Hook.
|
|
14
|
+
*/
|
|
15
|
+
selectionTableState: {
|
|
16
|
+
rowSelection?: RowSelectionState | undefined;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Props to pass to the `useTable` Hook.
|
|
20
|
+
*/
|
|
21
|
+
selectionTableProps: {
|
|
22
|
+
onRowSelectionChange: Dispatch<SetStateAction<RowSelectionState>>;
|
|
23
|
+
getRowId: (row: TData) => TData["id"];
|
|
24
|
+
enableRowSelection: true;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* A function to update the row selection state.
|
|
28
|
+
* Pass this to the `onRowSelectionChange` prop of the `useTable` Hook.
|
|
29
|
+
*/
|
|
30
|
+
setRowSelection: Dispatch<SetStateAction<RowSelectionState>>;
|
|
31
|
+
/**
|
|
32
|
+
* A `ColumnDef` object for the selection column, which includes a checkbox in each cell and header.
|
|
33
|
+
*/
|
|
34
|
+
selectionColumn: ColumnDef<TData, string>;
|
|
35
|
+
/**
|
|
36
|
+
* A function to toggle the selection state of a single row.
|
|
37
|
+
* This is usefull for example when you want to select a row when clicking on it, instead of the checkbox.
|
|
38
|
+
*/
|
|
39
|
+
toggleRowSelectionState: (id: TData["id"]) => void;
|
|
40
|
+
}
|
|
41
|
+
export interface TableSelectionProps<TData extends selectableTableData> {
|
|
42
|
+
data: TData[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* `useTableSelection` is a custom hook that provides functionality for row selection in a table.
|
|
46
|
+
* It returns an object containing methods and values related to row selection.
|
|
47
|
+
*
|
|
48
|
+
* @template TData - The type of data in the table. It must extend `selectableTableData`, which means it should at least have an `id` field.
|
|
49
|
+
* @returns {TableSelectionReturn<TData>} An object containing:
|
|
50
|
+
* - `selectionColumn`: A `ColumnDef` object for the selection column, which includes a checkbox in each cell and header.
|
|
51
|
+
* - `rowSelection`: The current state of row selection.
|
|
52
|
+
* - `setRowSelection`: A function to update the row selection state.
|
|
53
|
+
* @example
|
|
54
|
+
* const {
|
|
55
|
+
* selectionColumn,
|
|
56
|
+
* rowSelection,
|
|
57
|
+
* setRowSelection,
|
|
58
|
+
* } = useTableSelection<MyDataType>();
|
|
59
|
+
*
|
|
60
|
+
* const columns = [selectionColumn, ...otherColumns]
|
|
61
|
+
*
|
|
62
|
+
* const tableProps = useTable({
|
|
63
|
+
* ...selectionTableProps,
|
|
64
|
+
* state: {
|
|
65
|
+
* ...selectionTableState,
|
|
66
|
+
* },
|
|
67
|
+
* data,
|
|
68
|
+
* columns
|
|
69
|
+
* });
|
|
70
|
+
*/
|
|
71
|
+
export declare const useTableSelection: <TData extends selectableTableData>({ data, }: TableSelectionProps<TData>) => TableSelectionReturn<TData>;
|
|
72
|
+
export {};
|