Updated tanstack table to v8.x (#2564)
parent
a4527a7942
commit
8beebce2e4
@ -1,23 +1,65 @@
|
|||||||
import { PluginHook, TableInstance, TableOptions, useTable } from "react-table";
|
import { MutableRefObject, useEffect, useMemo } from "react";
|
||||||
import BaseTable, { TableStyleProps } from "./BaseTable";
|
import {
|
||||||
import { useDefaultSettings } from "./plugins";
|
getCoreRowModel,
|
||||||
|
Row,
|
||||||
|
Table,
|
||||||
|
TableOptions,
|
||||||
|
useReactTable,
|
||||||
|
} from "@tanstack/react-table";
|
||||||
|
import BaseTable, { TableStyleProps } from "@/components/tables/BaseTable";
|
||||||
|
import { usePageSize } from "@/utilities/storage";
|
||||||
|
|
||||||
export type SimpleTableProps<T extends object> = TableOptions<T> & {
|
export type SimpleTableProps<T extends object> = Omit<
|
||||||
plugins?: PluginHook<T>[];
|
TableOptions<T>,
|
||||||
instanceRef?: React.MutableRefObject<TableInstance<T> | null>;
|
"getCoreRowModel"
|
||||||
|
> & {
|
||||||
|
instanceRef?: MutableRefObject<Table<T> | null>;
|
||||||
tableStyles?: TableStyleProps<T>;
|
tableStyles?: TableStyleProps<T>;
|
||||||
|
onRowSelectionChanged?: (selectedRows: Row<T>[]) => void;
|
||||||
|
onAllRowsExpandedChanged?: (isAllRowsExpanded: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function SimpleTable<T extends object>(
|
export default function SimpleTable<T extends object>(
|
||||||
props: SimpleTableProps<T>,
|
props: SimpleTableProps<T>,
|
||||||
) {
|
) {
|
||||||
const { plugins, instanceRef, tableStyles, ...options } = props;
|
const {
|
||||||
|
instanceRef,
|
||||||
|
tableStyles,
|
||||||
|
onRowSelectionChanged,
|
||||||
|
onAllRowsExpandedChanged,
|
||||||
|
...options
|
||||||
|
} = props;
|
||||||
|
|
||||||
const instance = useTable(options, useDefaultSettings, ...(plugins ?? []));
|
const pageSize = usePageSize();
|
||||||
|
|
||||||
|
const instance = useReactTable({
|
||||||
|
...options,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
autoResetPageIndex: false,
|
||||||
|
autoResetExpanded: false,
|
||||||
|
pageCount: pageSize,
|
||||||
|
});
|
||||||
|
|
||||||
if (instanceRef) {
|
if (instanceRef) {
|
||||||
instanceRef.current = instance;
|
instanceRef.current = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <BaseTable tableStyles={tableStyles} {...instance}></BaseTable>;
|
const selectedRows = instance.getSelectedRowModel().rows;
|
||||||
|
|
||||||
|
const memoizedRows = useMemo(() => selectedRows, [selectedRows]);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
const memoizedRowSelectionChanged = useMemo(() => onRowSelectionChanged, []);
|
||||||
|
|
||||||
|
const isAllRowsExpanded = instance.getIsAllRowsExpanded();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
memoizedRowSelectionChanged?.(memoizedRows);
|
||||||
|
}, [memoizedRowSelectionChanged, memoizedRows]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onAllRowsExpandedChanged?.(isAllRowsExpanded);
|
||||||
|
}, [onAllRowsExpandedChanged, isAllRowsExpanded]);
|
||||||
|
|
||||||
|
return <BaseTable tableStyles={tableStyles} instance={instance}></BaseTable>;
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
export { default as useCustomSelection } from "./useCustomSelection";
|
|
||||||
export { default as useDefaultSettings } from "./useDefaultSettings";
|
|
@ -1,113 +0,0 @@
|
|||||||
import { forwardRef, useEffect, useRef } from "react";
|
|
||||||
import {
|
|
||||||
CellProps,
|
|
||||||
Column,
|
|
||||||
ColumnInstance,
|
|
||||||
ensurePluginOrder,
|
|
||||||
HeaderProps,
|
|
||||||
Hooks,
|
|
||||||
MetaBase,
|
|
||||||
TableInstance,
|
|
||||||
TableToggleCommonProps,
|
|
||||||
} from "react-table";
|
|
||||||
import { Checkbox as MantineCheckbox } from "@mantine/core";
|
|
||||||
|
|
||||||
const pluginName = "useCustomSelection";
|
|
||||||
|
|
||||||
const checkboxId = "---selection---";
|
|
||||||
|
|
||||||
interface CheckboxProps {
|
|
||||||
idIn: string;
|
|
||||||
disabled?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Checkbox = forwardRef<
|
|
||||||
HTMLInputElement,
|
|
||||||
TableToggleCommonProps & CheckboxProps
|
|
||||||
>(({ indeterminate, checked, disabled, idIn, ...rest }, ref) => {
|
|
||||||
const defaultRef = useRef<HTMLInputElement>(null);
|
|
||||||
const resolvedRef = ref || defaultRef;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof resolvedRef === "object" && resolvedRef.current) {
|
|
||||||
resolvedRef.current.indeterminate = indeterminate ?? false;
|
|
||||||
|
|
||||||
if (disabled) {
|
|
||||||
resolvedRef.current.checked = false;
|
|
||||||
} else {
|
|
||||||
resolvedRef.current.checked = checked ?? false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [resolvedRef, indeterminate, checked, disabled]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MantineCheckbox
|
|
||||||
key={idIn}
|
|
||||||
disabled={disabled}
|
|
||||||
ref={resolvedRef}
|
|
||||||
{...rest}
|
|
||||||
></MantineCheckbox>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function useCustomSelection<T extends object>(hooks: Hooks<T>) {
|
|
||||||
hooks.visibleColumns.push(visibleColumns);
|
|
||||||
hooks.useInstance.push(useInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
useCustomSelection.pluginName = pluginName;
|
|
||||||
|
|
||||||
function useInstance<T extends object>(instance: TableInstance<T>) {
|
|
||||||
const {
|
|
||||||
plugins,
|
|
||||||
rows,
|
|
||||||
onSelect,
|
|
||||||
canSelect,
|
|
||||||
state: { selectedRowIds },
|
|
||||||
} = instance;
|
|
||||||
|
|
||||||
ensurePluginOrder(plugins, ["useRowSelect"], pluginName);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Performance
|
|
||||||
let items = Object.keys(selectedRowIds).flatMap(
|
|
||||||
(v) => rows.find((n) => n.id === v)?.original ?? [],
|
|
||||||
);
|
|
||||||
|
|
||||||
if (canSelect) {
|
|
||||||
items = items.filter((v) => canSelect(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect && onSelect(items);
|
|
||||||
}, [selectedRowIds, onSelect, rows, canSelect]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function visibleColumns<T extends object>(
|
|
||||||
columns: ColumnInstance<T>[],
|
|
||||||
meta: MetaBase<T>,
|
|
||||||
): Column<T>[] {
|
|
||||||
const { instance } = meta;
|
|
||||||
const checkbox: Column<T> = {
|
|
||||||
id: checkboxId,
|
|
||||||
Header: ({ getToggleAllRowsSelectedProps }: HeaderProps<T>) => (
|
|
||||||
<Checkbox
|
|
||||||
idIn="table-header-selection"
|
|
||||||
{...getToggleAllRowsSelectedProps()}
|
|
||||||
></Checkbox>
|
|
||||||
),
|
|
||||||
Cell: ({ row }: CellProps<T>) => {
|
|
||||||
const canSelect = instance.canSelect;
|
|
||||||
const disabled = (canSelect && !canSelect(row.original)) ?? false;
|
|
||||||
return (
|
|
||||||
<Checkbox
|
|
||||||
idIn={`table-cell-${row.index}`}
|
|
||||||
disabled={disabled}
|
|
||||||
{...row.getToggleRowSelectedProps()}
|
|
||||||
></Checkbox>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return [checkbox, ...columns];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useCustomSelection;
|
|
@ -1,33 +0,0 @@
|
|||||||
import { Hooks, TableOptions } from "react-table";
|
|
||||||
import { usePageSize } from "@/utilities/storage";
|
|
||||||
|
|
||||||
const pluginName = "useLocalSettings";
|
|
||||||
|
|
||||||
function useDefaultSettings<T extends object>(hooks: Hooks<T>) {
|
|
||||||
hooks.useOptions.push(useOptions);
|
|
||||||
}
|
|
||||||
useDefaultSettings.pluginName = pluginName;
|
|
||||||
|
|
||||||
function useOptions<T extends object>(options: TableOptions<T>) {
|
|
||||||
const pageSize = usePageSize();
|
|
||||||
|
|
||||||
if (options.autoResetPage === undefined) {
|
|
||||||
options.autoResetPage = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.autoResetExpanded === undefined) {
|
|
||||||
options.autoResetExpanded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.initialState === undefined) {
|
|
||||||
options.initialState = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.initialState.pageSize === undefined) {
|
|
||||||
options.initialState.pageSize = pageSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useDefaultSettings;
|
|
Loading…
Reference in new issue