UNPKG

@trail-ui/react

Version:
245 lines (242 loc) 7.68 kB
import { EditableTableBody } from "./chunk-JNO4KZC7.mjs"; import { EditabletableFooter } from "./chunk-CADGCYST.mjs"; import { EditableTablePagination } from "./chunk-IYSTD2VQ.mjs"; import { EditableTableHeader } from "./chunk-GUQNTN2I.mjs"; import { FocusHandlerContextProvider } from "./chunk-F5W73ZFA.mjs"; import { TableContextProvider } from "./chunk-A4IWBDSQ.mjs"; import { dateSortingFn, multiSelectFilter } from "./chunk-KFZT7QCH.mjs"; // src/editable-table/editable-table.tsx import { useState, useCallback, useEffect, useRef } from "react"; import { useReactTable, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, getFacetedRowModel, getFacetedUniqueValues } from "@tanstack/react-table"; import { twMerge } from "@trail-ui/shared-utils"; import { jsx, jsxs } from "react/jsx-runtime"; function TanstackEditableTable({ tableId, classNames, tableName, data, columns, isLoading, //Save data callback handleSaveData, idSelector, selectAllCheckBoxName, setTable, setColumnFilters, hiddenColumnIds, isCellDisabled, //Server pagination props showPagination = true, serverPagination = false, totalCount, currentPage = 1, onPageChange, currentPageSize, onPageSizeChange, defaultSortingHeaders, handleSort, globalFilter, setGlobalFilter, paginationSizeOptions, //Table footer props showTableFooter = false, //row selection onSelectionChange }) { const [tableData, setTableData] = useState(data || []); const [sorting, setSorting] = useState(defaultSortingHeaders || []); const [tableColumnFilters, setTableColumnFilters] = useState([]); const [rowSelection, setRowSelection] = useState({}); const tableRef = useRef(null); const [pagination, setPagination] = useState({ pageSize: currentPageSize != null ? currentPageSize : 100, pageIndex: currentPage - 1 }); const updateData = useCallback((rowId, accessorKey, value) => { setTableData((prev) => { const updatedData = [...prev]; const rowIndex = updatedData.findIndex((r) => idSelector(r) === rowId); if (rowIndex === -1) { return prev; } updatedData[rowIndex] = { ...updatedData[rowIndex], [accessorKey]: 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, rowSelection, ...(hiddenColumnIds == null ? void 0 : hiddenColumnIds.length) && { columnVisibility: Object.fromEntries(hiddenColumnIds.map((col) => [col, false])) } }, onRowSelectionChange: (updater) => { setRowSelection((prev) => { const newSelection = typeof updater === "function" ? updater(prev) : updater; return newSelection; }); }, getRowId: idSelector, 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]); useEffect(() => { if (onSelectionChange) { const ids = Object.keys(rowSelection).filter((id) => rowSelection[id]); onSelectionChange(ids); } }, [rowSelection]); 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(() => setTable == null ? void 0 : setTable(table), [table]); 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( TableContextProvider, { handleSaveData, idSelector, table, tableName, groupData: [], allowBulkGroupSelection: false, tableRef, doesRowHeaderExist: table.getAllColumns().map((col) => col.columnDef).some((col) => (col == null ? void 0 : col.columnType) === "th"), hasFooter: showTableFooter, serverPagination, children: /* @__PURE__ */ jsx(FocusHandlerContextProvider, { table, groupData: [], children: /* @__PURE__ */ jsxs( "div", { id: tableId, className: twMerge("flex max-h-full max-w-full flex-col gap-4", classNames == null ? void 0 : classNames.wrapper), children: [ /* @__PURE__ */ jsx( "div", { className: twMerge( "relative h-full max-h-[100%-3.5rem] overflow-auto rounded border border-neutral-200", classNames == null ? void 0 : classNames.tableWrapper ), children: /* @__PURE__ */ jsxs( "table", { ref: tableRef, role: "grid", "aria-label": tableName != null ? tableName : "", className: twMerge("w-full", classNames == null ? void 0 : classNames.table), children: [ /* @__PURE__ */ jsx( EditableTableHeader, { table, tableName, selectAllCheckBoxName } ), /* @__PURE__ */ jsx( EditableTableBody, { table, columns, isLoading, isCellDisabled } ), showTableFooter && /* @__PURE__ */ jsx(EditabletableFooter, {}) ] } ) } ), showPagination && /* @__PURE__ */ jsx( EditableTablePagination, { totalResults, pagination, table, onPageChange, onPageSizeChange, paginationSizeOptions } ) ] } ) }) } ); } export { TanstackEditableTable };