@trackunit/react-table 1.3.22 → 1.3.24

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 CHANGED
@@ -501,7 +501,7 @@ const Table = ({ rowHeight = 75, ...props }) => {
501
501
  maxWidth: header.column.columnDef.maxSize,
502
502
  textAlign: header.column.columnDef.meta?.alignment || "left",
503
503
  flexGrow: header.column.columnDef.meta?.shouldGrow ? 1 : 0,
504
- }, 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`,
504
+ }, tooltipLabel: tooltipLabel, children: [header.isPlaceholder ? null : (jsxRuntime.jsxs("div", { className: `${header.column.getCanSort() ? "cursor-pointer select-none flex pr-3" : "flex"} items-center gap-2 py-2 overflow-hidden w-full`,
505
505
  onClick: header.column.getToggleSortingHandler(), children: [jsxRuntime.jsxs("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: [reactTable.flexRender(header.column.columnDef.header, header.getContext()), header.column.columnDef.meta?.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] })), !header.column.columnDef.meta?.shouldGrow && header.column.getCanResize() ? (jsxRuntime.jsx(reactTableBaseComponents.ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null] }, header.id));
506
506
  }) }, headerGroup.id))) }), hasResults ? (jsxRuntime.jsx(reactTableBaseComponents.Tbody, { className: "text-sm font-normal", style: {
507
507
  height: `${getTotalSize()}px`,
@@ -580,18 +580,17 @@ const useTable = ({ onTableStateChange, initialState, columns, ...reactTableProp
580
580
  const updatedInitialColumnVisibility = react.useMemo(() => {
581
581
  const initialStateColumnVisibility = initialState?.columnVisibility;
582
582
  const resultFromInitialState = initialStateColumnVisibility
583
- ?
584
- Object.fromEntries(columns
585
- .map(column => {
586
- if (column.id && initialStateColumnVisibility[column.id]) {
587
- return [column.id, column.id && initialStateColumnVisibility[column.id]];
588
- }
589
- return null;
590
- })
591
- .filter(sharedUtils.nonNullable))
583
+ ? Object.fromEntries(columns
584
+ .map(column => {
585
+ if (column.id && initialStateColumnVisibility[column.id] !== undefined) {
586
+ return [column.id, initialStateColumnVisibility[column.id]];
587
+ }
588
+ return null;
589
+ })
590
+ .filter(sharedUtils.nonNullable))
592
591
  : {};
593
592
  columns.forEach(column => {
594
- if (column.id && !resultFromInitialState[column.id]) {
593
+ if (column.id && resultFromInitialState[column.id] === undefined) {
595
594
  resultFromInitialState[column.id] = column.meta?.hiddenByDefault === true ? false : true;
596
595
  }
597
596
  });
@@ -690,19 +689,20 @@ const useTable = ({ onTableStateChange, initialState, columns, ...reactTableProp
690
689
  * columns,
691
690
  * });
692
691
  */
693
- const useTableSelection = ({ data, defaultSelectedIds, enableRowSelection = true, }) => {
692
+ const useTableSelection = ({ data, idKey, defaultSelectedIds, enableRowSelection = true, }) => {
694
693
  const [t] = useTranslation();
695
694
  const [rowSelection, setRowSelection] = react.useState({});
696
695
  react.useEffect(() => {
697
696
  const initialSelection = {};
698
697
  defaultSelectedIds?.forEach(id => {
699
- initialSelection[id] = true;
698
+ initialSelection[String(id)] = true;
700
699
  });
701
700
  setRowSelection(() => ({ ...initialSelection }));
702
701
  }, [defaultSelectedIds]);
703
702
  const toggleRowSelectionState = react.useCallback((id) => {
704
703
  setRowSelection(prevRowSelection => {
705
- const newSelection = { ...prevRowSelection, [id]: !prevRowSelection[id] };
704
+ const stringId = String(id);
705
+ const newSelection = { ...prevRowSelection, [stringId]: !prevRowSelection[stringId] };
706
706
  const entries = sharedUtils.objectEntries(newSelection);
707
707
  if (entries.length !== 0 && entries.every(([_, selected]) => !selected)) {
708
708
  return {};
@@ -714,35 +714,47 @@ const useTableSelection = ({ data, defaultSelectedIds, enableRowSelection = true
714
714
  .filter(([_, selected]) => selected)
715
715
  .map(([id]) => id), [rowSelection]);
716
716
  const columnHelper = react.useMemo(() => reactTable.createColumnHelper(), []);
717
- const selectionColumn = react.useMemo(() => columnHelper.accessor(row => row.id, {
718
- cell: ({ row }) => (jsxRuntime.jsx(reactFormComponents.Checkbox, { className: "ml-1 p-1 flex", // Aligns the checkbox with the one in the header.
719
- checked: row.getIsSelected(),
720
- disabled: !row.getCanSelect(),
721
- indeterminate: row.getIsSomeSelected(),
722
- onChange: row.getToggleSelectedHandler(),
723
- stopPropagation: true,
724
- "aria-label": "rowSelector" })),
725
- header: ({ table }) => (jsxRuntime.jsx(reactFormComponents.Checkbox, { className: "p-1",
726
- checked: table.getIsAllRowsSelected(),
727
- indeterminate: table.getIsSomeRowsSelected(),
728
- onChange: table.getToggleAllRowsSelectedHandler(),
729
- disabled: !data.length })),
717
+ const selectionColumn = react.useMemo(() => columnHelper.accessor(row => row[idKey], {
718
+ header: ({ table }) => {
719
+ const hasRowSelection = table.getState().rowSelection !== undefined;
720
+ if (!hasRowSelection) {
721
+ return null;
722
+ }
723
+ return (jsxRuntime.jsx(reactFormComponents.Checkbox, { className: "ml-4",
724
+ checked: table.getIsAllRowsSelected(),
725
+ indeterminate: table.getIsSomeRowsSelected(),
726
+ onChange: table.getToggleAllRowsSelectedHandler(),
727
+ disabled: !data.length }));
728
+ },
729
+ cell: ({ row, table }) => {
730
+ const hasRowSelection = table.getState().rowSelection !== undefined;
731
+ if (!hasRowSelection) {
732
+ return null;
733
+ }
734
+ return (jsxRuntime.jsx(reactFormComponents.Checkbox, { className: "flex justify-center",
735
+ checked: row.getIsSelected(),
736
+ disabled: !row.getCanSelect(),
737
+ indeterminate: row.getIsSomeSelected(),
738
+ onChange: row.getToggleSelectedHandler(),
739
+ stopPropagation: true,
740
+ "aria-label": "rowSelector" }));
741
+ },
730
742
  id: "selection",
731
743
  enableSorting: false,
732
744
  enableResizing: false,
733
- size: 60,
745
+ size: 70,
734
746
  meta: {
735
747
  required: true,
736
- alignment: "left",
748
+ alignment: "center",
737
749
  columnFilterLabel: t("table.selection.label"),
738
750
  },
739
- }), [columnHelper, data.length, t]);
751
+ }), [columnHelper, data.length, idKey, t]);
740
752
  const selectionTableState = react.useMemo(() => ({ rowSelection }), [rowSelection]);
741
753
  const selectionTableProps = react.useMemo(() => ({
742
754
  onRowSelectionChange: setRowSelection,
743
- getRowId: row => row.id,
755
+ getRowId: row => String(row[idKey]),
744
756
  enableRowSelection,
745
- }), [enableRowSelection]);
757
+ }), [enableRowSelection, idKey]);
746
758
  return react.useMemo(() => ({
747
759
  toggleRowSelectionState,
748
760
  selectionColumn,
package/index.esm.js CHANGED
@@ -500,7 +500,7 @@ const Table = ({ rowHeight = 75, ...props }) => {
500
500
  maxWidth: header.column.columnDef.maxSize,
501
501
  textAlign: header.column.columnDef.meta?.alignment || "left",
502
502
  flexGrow: header.column.columnDef.meta?.shouldGrow ? 1 : 0,
503
- }, 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`,
503
+ }, tooltipLabel: tooltipLabel, children: [header.isPlaceholder ? null : (jsxs("div", { className: `${header.column.getCanSort() ? "cursor-pointer select-none flex pr-3" : "flex"} items-center gap-2 py-2 overflow-hidden w-full`,
504
504
  onClick: header.column.getToggleSortingHandler(), children: [jsxs("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: [flexRender(header.column.columnDef.header, header.getContext()), header.column.columnDef.meta?.subHeader ? (jsx(Text, { size: "small", subtle: true, children: header.column.columnDef.meta.subHeader })) : null] }), header.column.getCanSort() ? (jsx(SortIndicator, { sortingState: header.column.getIsSorted() })) : null] })), !header.column.columnDef.meta?.shouldGrow && header.column.getCanResize() ? (jsx(ResizeHandle, { isResizing: header.column.getIsResizing(), onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler() })) : null] }, header.id));
505
505
  }) }, headerGroup.id))) }), hasResults ? (jsx(Tbody, { className: "text-sm font-normal", style: {
506
506
  height: `${getTotalSize()}px`,
@@ -579,18 +579,17 @@ const useTable = ({ onTableStateChange, initialState, columns, ...reactTableProp
579
579
  const updatedInitialColumnVisibility = useMemo(() => {
580
580
  const initialStateColumnVisibility = initialState?.columnVisibility;
581
581
  const resultFromInitialState = initialStateColumnVisibility
582
- ?
583
- Object.fromEntries(columns
584
- .map(column => {
585
- if (column.id && initialStateColumnVisibility[column.id]) {
586
- return [column.id, column.id && initialStateColumnVisibility[column.id]];
587
- }
588
- return null;
589
- })
590
- .filter(nonNullable))
582
+ ? Object.fromEntries(columns
583
+ .map(column => {
584
+ if (column.id && initialStateColumnVisibility[column.id] !== undefined) {
585
+ return [column.id, initialStateColumnVisibility[column.id]];
586
+ }
587
+ return null;
588
+ })
589
+ .filter(nonNullable))
591
590
  : {};
592
591
  columns.forEach(column => {
593
- if (column.id && !resultFromInitialState[column.id]) {
592
+ if (column.id && resultFromInitialState[column.id] === undefined) {
594
593
  resultFromInitialState[column.id] = column.meta?.hiddenByDefault === true ? false : true;
595
594
  }
596
595
  });
@@ -689,19 +688,20 @@ const useTable = ({ onTableStateChange, initialState, columns, ...reactTableProp
689
688
  * columns,
690
689
  * });
691
690
  */
692
- const useTableSelection = ({ data, defaultSelectedIds, enableRowSelection = true, }) => {
691
+ const useTableSelection = ({ data, idKey, defaultSelectedIds, enableRowSelection = true, }) => {
693
692
  const [t] = useTranslation();
694
693
  const [rowSelection, setRowSelection] = useState({});
695
694
  useEffect(() => {
696
695
  const initialSelection = {};
697
696
  defaultSelectedIds?.forEach(id => {
698
- initialSelection[id] = true;
697
+ initialSelection[String(id)] = true;
699
698
  });
700
699
  setRowSelection(() => ({ ...initialSelection }));
701
700
  }, [defaultSelectedIds]);
702
701
  const toggleRowSelectionState = useCallback((id) => {
703
702
  setRowSelection(prevRowSelection => {
704
- const newSelection = { ...prevRowSelection, [id]: !prevRowSelection[id] };
703
+ const stringId = String(id);
704
+ const newSelection = { ...prevRowSelection, [stringId]: !prevRowSelection[stringId] };
705
705
  const entries = objectEntries(newSelection);
706
706
  if (entries.length !== 0 && entries.every(([_, selected]) => !selected)) {
707
707
  return {};
@@ -713,35 +713,47 @@ const useTableSelection = ({ data, defaultSelectedIds, enableRowSelection = true
713
713
  .filter(([_, selected]) => selected)
714
714
  .map(([id]) => id), [rowSelection]);
715
715
  const columnHelper = useMemo(() => createColumnHelper(), []);
716
- const selectionColumn = useMemo(() => columnHelper.accessor(row => row.id, {
717
- cell: ({ row }) => (jsx(Checkbox, { className: "ml-1 p-1 flex", // Aligns the checkbox with the one in the header.
718
- checked: row.getIsSelected(),
719
- disabled: !row.getCanSelect(),
720
- indeterminate: row.getIsSomeSelected(),
721
- onChange: row.getToggleSelectedHandler(),
722
- stopPropagation: true,
723
- "aria-label": "rowSelector" })),
724
- header: ({ table }) => (jsx(Checkbox, { className: "p-1",
725
- checked: table.getIsAllRowsSelected(),
726
- indeterminate: table.getIsSomeRowsSelected(),
727
- onChange: table.getToggleAllRowsSelectedHandler(),
728
- disabled: !data.length })),
716
+ const selectionColumn = useMemo(() => columnHelper.accessor(row => row[idKey], {
717
+ header: ({ table }) => {
718
+ const hasRowSelection = table.getState().rowSelection !== undefined;
719
+ if (!hasRowSelection) {
720
+ return null;
721
+ }
722
+ return (jsx(Checkbox, { className: "ml-4",
723
+ checked: table.getIsAllRowsSelected(),
724
+ indeterminate: table.getIsSomeRowsSelected(),
725
+ onChange: table.getToggleAllRowsSelectedHandler(),
726
+ disabled: !data.length }));
727
+ },
728
+ cell: ({ row, table }) => {
729
+ const hasRowSelection = table.getState().rowSelection !== undefined;
730
+ if (!hasRowSelection) {
731
+ return null;
732
+ }
733
+ return (jsx(Checkbox, { className: "flex justify-center",
734
+ checked: row.getIsSelected(),
735
+ disabled: !row.getCanSelect(),
736
+ indeterminate: row.getIsSomeSelected(),
737
+ onChange: row.getToggleSelectedHandler(),
738
+ stopPropagation: true,
739
+ "aria-label": "rowSelector" }));
740
+ },
729
741
  id: "selection",
730
742
  enableSorting: false,
731
743
  enableResizing: false,
732
- size: 60,
744
+ size: 70,
733
745
  meta: {
734
746
  required: true,
735
- alignment: "left",
747
+ alignment: "center",
736
748
  columnFilterLabel: t("table.selection.label"),
737
749
  },
738
- }), [columnHelper, data.length, t]);
750
+ }), [columnHelper, data.length, idKey, t]);
739
751
  const selectionTableState = useMemo(() => ({ rowSelection }), [rowSelection]);
740
752
  const selectionTableProps = useMemo(() => ({
741
753
  onRowSelectionChange: setRowSelection,
742
- getRowId: row => row.id,
754
+ getRowId: row => String(row[idKey]),
743
755
  enableRowSelection,
744
- }), [enableRowSelection]);
756
+ }), [enableRowSelection, idKey]);
745
757
  return useMemo(() => ({
746
758
  toggleRowSelectionState,
747
759
  selectionColumn,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-table",
3
- "version": "1.3.22",
3
+ "version": "1.3.24",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -19,9 +19,9 @@
19
19
  "@trackunit/shared-utils": "1.5.18",
20
20
  "@trackunit/css-class-variance-utilities": "1.3.18",
21
21
  "@trackunit/ui-icons": "1.3.18",
22
- "@trackunit/react-table-base-components": "1.3.21",
22
+ "@trackunit/react-table-base-components": "1.3.22",
23
23
  "@trackunit/react-table-pagination": "1.3.18",
24
- "@trackunit/react-form-components": "1.3.21",
24
+ "@trackunit/react-form-components": "1.3.22",
25
25
  "@trackunit/i18n-library-translation": "1.3.19",
26
26
  "@trackunit/react-core-contexts-api": "1.4.19"
27
27
  },
@@ -1,13 +1,31 @@
1
1
  import { ColumnDef, RowSelectionState } from "@tanstack/react-table";
2
2
  import { Dispatch, SetStateAction } from "react";
3
- export type selectableTableData = {
4
- id: string;
5
- } & object;
6
- export interface TableSelectionReturn<TData extends selectableTableData> {
3
+ export interface SelectableTableData {
4
+ }
5
+ export interface TableSelectionProps<TData extends SelectableTableData> {
6
+ /**
7
+ * The data that is displayed in the table.
8
+ */
9
+ data: TData[];
10
+ /**
11
+ * The key in TData that should be used as the unique identifier
12
+ * Example: 'id', 'assetId', 'userId', etc.
13
+ */
14
+ idKey: keyof TData & string;
15
+ /**
16
+ * An array of ids of the rows that should be selected by default.
17
+ */
18
+ defaultSelectedIds?: string[];
19
+ /**
20
+ * Whether or not to enable row selection.
21
+ */
22
+ enableRowSelection?: boolean;
23
+ }
24
+ export interface TableSelectionReturn<TData extends SelectableTableData> {
7
25
  /**
8
26
  * An array of the ids of the currently selected rows.
9
27
  */
10
- selectedIds: TData["id"][];
28
+ selectedIds: string[];
11
29
  /**
12
30
  * The current state of row selection.
13
31
  * Pass this to the `state` prop of the `useTable` Hook.
@@ -20,7 +38,7 @@ export interface TableSelectionReturn<TData extends selectableTableData> {
20
38
  */
21
39
  selectionTableProps: {
22
40
  onRowSelectionChange: Dispatch<SetStateAction<RowSelectionState>>;
23
- getRowId: (row: TData) => TData["id"];
41
+ getRowId: (row: TData) => string;
24
42
  enableRowSelection: boolean;
25
43
  };
26
44
  /**
@@ -31,30 +49,12 @@ export interface TableSelectionReturn<TData extends selectableTableData> {
31
49
  /**
32
50
  * A `ColumnDef` object for the selection column, which includes a checkbox in each cell and header.
33
51
  */
34
- selectionColumn: ColumnDef<TData, string>;
52
+ selectionColumn: ColumnDef<TData, TData[keyof TData & string]>;
35
53
  /**
36
54
  * A function to toggle the selection state of a single row.
37
55
  * This is usefull for example when you want to select a row when clicking on it, instead of the checkbox.
38
56
  */
39
- toggleRowSelectionState: (id: TData["id"]) => void;
40
- }
41
- export interface TableSelectionProps<TData extends selectableTableData> {
42
- /**
43
- * The data that is displayed in the table.
44
- * This must have an `id` field, to enable selection.
45
- * The same data should be passed to the `data` prop of the `useTable` Hook.
46
- */
47
- data: TData[];
48
- /**
49
- * An array of ids of the rows that should be selected by default.
50
- * This is useful when you want to preselect rows, for example when editing an existing entity.
51
- */
52
- defaultSelectedIds?: TData["id"][];
53
- /**
54
- * Whether or not to enable row selection.
55
- * If set to `false`, the selection column will still be displayed, but the checkboxes will be disabled.
56
- */
57
- enableRowSelection?: boolean;
57
+ toggleRowSelectionState: (id: TData[keyof TData]) => void;
58
58
  }
59
59
  /**
60
60
  * `useTableSelection` is a custom hook that provides functionality for row selection in a table.
@@ -83,4 +83,4 @@ export interface TableSelectionProps<TData extends selectableTableData> {
83
83
  * columns,
84
84
  * });
85
85
  */
86
- export declare const useTableSelection: <TData extends selectableTableData>({ data, defaultSelectedIds, enableRowSelection, }: TableSelectionProps<TData>) => TableSelectionReturn<TData>;
86
+ export declare const useTableSelection: <TData extends SelectableTableData>({ data, idKey, defaultSelectedIds, enableRowSelection, }: TableSelectionProps<TData>) => TableSelectionReturn<TData>;
@@ -1,5 +1,5 @@
1
- import { TableSelectionProps, selectableTableData } from "./useTableSelection";
2
- export interface UseTableSelectionDemoComponentProps<TData extends selectableTableData> extends TableSelectionProps<TData> {
1
+ import { SelectableTableData, TableSelectionProps } from "./useTableSelection";
2
+ export interface UseTableSelectionDemoComponentProps<TData extends SelectableTableData> extends TableSelectionProps<TData> {
3
3
  }
4
4
  /**
5
5
  * The `useTableSelection` Hook provides functionality for row selection in a table.
@@ -8,4 +8,4 @@ export interface UseTableSelectionDemoComponentProps<TData extends selectableTab
8
8
  *
9
9
  * It Also returns a `selectionColumn` object that can be used as a column definition in a table.
10
10
  */
11
- export declare const UseTableSelectionDemoComponent: <TData extends selectableTableData>(props: UseTableSelectionDemoComponentProps<TData>) => import("react/jsx-runtime").JSX.Element;
11
+ export declare const UseTableSelectionDemoComponent: <TData extends SelectableTableData>(props: UseTableSelectionDemoComponentProps<TData>) => import("react/jsx-runtime").JSX.Element;