@trail-ui/react
Version:
200 lines (197 loc) • 6.38 kB
JavaScript
import {
Pagination
} from "./chunk-62BQUHRK.mjs";
import {
EditableTableBody
} from "./chunk-FMKV2ETI.mjs";
import {
EditableTableHeader
} from "./chunk-WIOT6RBS.mjs";
import {
FocusHandlerContextProvider
} from "./chunk-SSX6C2M6.mjs";
import {
TableContextProvider
} from "./chunk-LRSSE262.mjs";
import {
dateSortingFn,
multiSelectFilter
} from "./chunk-KFZT7QCH.mjs";
// src/editable-table/editable-table.tsx
import { useState, useCallback, useEffect } from "react";
import {
useReactTable,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
getFacetedRowModel,
getFacetedUniqueValues
} from "@tanstack/react-table";
import { jsx, jsxs } from "react/jsx-runtime";
var TanstackEditableTable = ({
tableId,
tableName,
data,
columns,
isLoading,
//Save data callback
handleSaveData,
idSelector,
tableHeight,
checkBoxSelectedName,
selectAllCheckBoxName,
tableInstanceRef,
setColumnFilters,
hiddenColumnIds,
isCellDisabled,
//Server pagination props
serverPagination = false,
totalCount,
currentPage = 1,
onPageChange,
currentPageSize,
onPageSizeChange,
defaultSortingHeaders,
handleSort,
globalFilter,
setGlobalFilter,
paginationSizeOptions
}) => {
var _a;
const [tableData, setTableData] = useState(data || []);
const [sorting, setSorting] = useState(defaultSortingHeaders || []);
const [tableColumnFilters, setTableColumnFilters] = useState([]);
const [pagination, setPagination] = useState({
pageSize: currentPageSize != null ? currentPageSize : 100,
pageIndex: currentPage - 1
});
const updateData = useCallback((rowId, columnId, value) => {
setTableData((prev) => {
const updatedData = [...prev];
const rowIndex = updatedData.findIndex((r) => idSelector(r) === rowId);
if (rowIndex === -1)
return prev;
updatedData[rowIndex] = {
...updatedData[rowIndex],
[columnId]: value
};
return updatedData;
});
}, []);
const totalPages = serverPagination && totalCount && pagination.pageSize ? Math.ceil(totalCount / pagination.pageSize) : Math.ceil(tableData.length / pagination.pageSize);
const table = useReactTable({
data: tableData,
columns,
state: {
sorting,
pagination,
columnFilters: tableColumnFilters,
globalFilter,
...(hiddenColumnIds == null ? void 0 : hiddenColumnIds.length) && {
columnVisibility: Object.fromEntries(hiddenColumnIds.map((col) => [col, false]))
}
},
manualPagination: serverPagination,
...serverPagination && { pageCount: totalPages },
onPaginationChange: setPagination,
manualSorting: serverPagination,
getSortedRowModel: serverPagination ? void 0 : getSortedRowModel(),
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
onColumnFiltersChange: setTableColumnFilters,
onGlobalFilterChange: setGlobalFilter,
enableSortingRemoval: false,
sortingFns: { dateSortingFn },
filterFns: { multiSelectFilter },
meta: {
updateData
}
});
useEffect(() => {
if (serverPagination && sorting.length > 0 && handleSort) {
const { id, desc } = sorting[0];
const order = desc === void 0 ? "default" /* DEFAULT */ : desc ? "desc" /* DESC */ : "asc" /* ASC */;
handleSort({ columnId: id, order });
}
}, [sorting]);
if (tableInstanceRef)
tableInstanceRef.current = table;
if (setColumnFilters)
setColumnFilters(tableColumnFilters);
const totalResults = serverPagination ? totalCount != null ? totalCount : 0 : table.getFilteredRowModel().rows.length;
useEffect(() => {
if (JSON.stringify(data) !== JSON.stringify(tableData)) {
setTableData(data);
}
}, [data]);
useEffect(() => {
if (serverPagination && currentPage !== void 0) {
setPagination((prev) => ({ ...prev, pageIndex: currentPage - 1 }));
}
}, [serverPagination, currentPage]);
useEffect(() => {
if (serverPagination && currentPageSize !== void 0) {
setPagination((prev) => ({ ...prev, pageSize: currentPageSize }));
}
}, [serverPagination, currentPageSize]);
return /* @__PURE__ */ jsx("div", { id: tableId, className: "max-w-full rounded", children: /* @__PURE__ */ jsxs("div", { className: "editable-table flex flex-col gap-4", tabIndex: -1, children: [
/* @__PURE__ */ jsx("div", { className: "h-full overflow-auto rounded border border-neutral-200", children: /* @__PURE__ */ jsx("div", { className: `${tableHeight != null ? tableHeight : "max-h-[60vh]"} relative`, children: /* @__PURE__ */ jsx(
TableContextProvider,
{
handleSaveData,
idSelector,
table,
children: /* @__PURE__ */ jsx(FocusHandlerContextProvider, { table, children: /* @__PURE__ */ jsxs("table", { role: "grid", "aria-label": tableName != null ? tableName : "", className: "w-full", children: [
/* @__PURE__ */ jsx(
EditableTableHeader,
{
table,
tableName,
selectAllCheckBoxName
}
),
/* @__PURE__ */ jsx(
EditableTableBody,
{
table,
columns,
handleSaveData,
checkBoxSelectedName,
isLoading,
idSelctor: idSelector,
isCellDisabled
}
)
] }) })
}
) }) }),
/* @__PURE__ */ jsx(
Pagination,
{
totalCount: totalResults,
size: pagination.pageSize,
currentPage: pagination.pageIndex + 1,
selectedCount: (_a = table.getSelectedRowModel()) == null ? void 0 : _a.rows.length,
onPageChange: (page) => {
table.setPageIndex(page - 1);
onPageChange == null ? void 0 : onPageChange(page);
},
onPageSizeChange: (size) => {
table.setPageSize(size);
table.setPageIndex(0);
onPageSizeChange == null ? void 0 : onPageSizeChange(size);
},
readsResults: true,
sizeOptions: paginationSizeOptions
}
)
] }) });
};
export {
TanstackEditableTable
};