UNPKG

material-react-table

Version:

A fully featured Material UI V6 implementation of TanStack React Table V8, written from the ground up in TypeScript.

965 lines (946 loc) 281 kB
import { flexRender as flexRender$1, createRow as createRow$1, sortingFns, aggregationFns, filterFns, getCoreRowModel, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGroupedRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from '@tanstack/react-table'; import { useMemo, useState, useId, useReducer, useRef, useEffect, useCallback, memo, Fragment as Fragment$1, useLayoutEffect } from 'react'; import { compareItems, rankItem, rankings } from '@tanstack/match-sorter-utils'; import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import CircularProgress from '@mui/material/CircularProgress'; import { lighten, darken, alpha, useTheme } from '@mui/material/styles'; import Menu from '@mui/material/Menu'; import ListItemIcon from '@mui/material/ListItemIcon'; import MenuItem from '@mui/material/MenuItem'; import Stack from '@mui/material/Stack'; import Checkbox from '@mui/material/Checkbox'; import Radio from '@mui/material/Radio'; import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import CancelIcon from '@mui/icons-material/Cancel'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ClearAllIcon from '@mui/icons-material/ClearAll'; import CloseIcon from '@mui/icons-material/Close'; import ContentCopy from '@mui/icons-material/ContentCopy'; import DensityLargeIcon from '@mui/icons-material/DensityLarge'; import DensityMediumIcon from '@mui/icons-material/DensityMedium'; import DensitySmallIcon from '@mui/icons-material/DensitySmall'; import DragHandleIcon from '@mui/icons-material/DragHandle'; import DynamicFeedIcon from '@mui/icons-material/DynamicFeed'; import EditIcon from '@mui/icons-material/Edit'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import FilterAltIcon from '@mui/icons-material/FilterAlt'; import FilterListIcon from '@mui/icons-material/FilterList'; import FilterListOffIcon from '@mui/icons-material/FilterListOff'; import FirstPageIcon from '@mui/icons-material/FirstPage'; import FullscreenIcon from '@mui/icons-material/Fullscreen'; import FullscreenExitIcon from '@mui/icons-material/FullscreenExit'; import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown'; import LastPageIcon from '@mui/icons-material/LastPage'; import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import PushPinIcon from '@mui/icons-material/PushPin'; import RestartAltIcon from '@mui/icons-material/RestartAlt'; import SaveIcon from '@mui/icons-material/Save'; import SearchIcon from '@mui/icons-material/Search'; import SearchOffIcon from '@mui/icons-material/SearchOff'; import SortIcon from '@mui/icons-material/Sort'; import SyncAltIcon from '@mui/icons-material/SyncAlt'; import ViewColumnIcon from '@mui/icons-material/ViewColumn'; import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; import { defaultRangeExtractor, useVirtualizer } from '@tanstack/react-virtual'; import Paper from '@mui/material/Paper'; import TableContainer from '@mui/material/TableContainer'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import Typography from '@mui/material/Typography'; import TableRow from '@mui/material/TableRow'; import Skeleton from '@mui/material/Skeleton'; import TableCell from '@mui/material/TableCell'; import highlightWords from 'highlight-words'; import TextField from '@mui/material/TextField'; import Collapse from '@mui/material/Collapse'; import TableFooter from '@mui/material/TableFooter'; import TableHead from '@mui/material/TableHead'; import FormControlLabel from '@mui/material/FormControlLabel'; import Autocomplete from '@mui/material/Autocomplete'; import Chip from '@mui/material/Chip'; import InputAdornment from '@mui/material/InputAdornment'; import { debounce } from '@mui/material/utils'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { TimePicker } from '@mui/x-date-pickers/TimePicker'; import FormHelperText from '@mui/material/FormHelperText'; import Slider from '@mui/material/Slider'; import Grow from '@mui/material/Grow'; import Popover from '@mui/material/Popover'; import Divider from '@mui/material/Divider'; import Badge from '@mui/material/Badge'; import TableSortLabel from '@mui/material/TableSortLabel'; import Alert from '@mui/material/Alert'; import AlertTitle from '@mui/material/AlertTitle'; import Dialog from '@mui/material/Dialog'; import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import useMediaQuery from '@mui/material/useMediaQuery'; import LinearProgress from '@mui/material/LinearProgress'; import InputLabel from '@mui/material/InputLabel'; import Pagination from '@mui/material/Pagination'; import PaginationItem from '@mui/material/PaginationItem'; import Select from '@mui/material/Select'; import Fade from '@mui/material/Fade'; import Switch from '@mui/material/Switch'; const getColumnId = (columnDef) => { var _a, _b, _c, _d; return (_d = (_a = columnDef.id) !== null && _a !== void 0 ? _a : (_c = (_b = columnDef.accessorKey) === null || _b === void 0 ? void 0 : _b.toString) === null || _c === void 0 ? void 0 : _c.call(_b)) !== null && _d !== void 0 ? _d : columnDef.header; }; const getAllLeafColumnDefs = (columns) => { const allLeafColumnDefs = []; const getLeafColumns = (cols) => { cols.forEach((col) => { if (col.columns) { getLeafColumns(col.columns); } else { allLeafColumnDefs.push(col); } }); }; getLeafColumns(columns); return allLeafColumnDefs; }; const prepareColumns = ({ columnDefs, tableOptions, }) => { const { aggregationFns = {}, defaultDisplayColumn, filterFns = {}, sortingFns = {}, state: { columnFilterFns = {} } = {}, } = tableOptions; return columnDefs.map((columnDef) => { var _a, _b; //assign columnId if (!columnDef.id) columnDef.id = getColumnId(columnDef); //assign columnDefType if (!columnDef.columnDefType) columnDef.columnDefType = 'data'; if ((_a = columnDef.columns) === null || _a === void 0 ? void 0 : _a.length) { columnDef.columnDefType = 'group'; //recursively prepare columns if this is a group column columnDef.columns = prepareColumns({ columnDefs: columnDef.columns, tableOptions, }); } else if (columnDef.columnDefType === 'data') { //assign aggregationFns if multiple aggregationFns are provided if (Array.isArray(columnDef.aggregationFn)) { const aggFns = columnDef.aggregationFn; columnDef.aggregationFn = (columnId, leafRows, childRows) => aggFns.map((fn) => { var _a; return (_a = aggregationFns[fn]) === null || _a === void 0 ? void 0 : _a.call(aggregationFns, columnId, leafRows, childRows); }); } //assign filterFns if (Object.keys(filterFns).includes(columnFilterFns[columnDef.id])) { columnDef.filterFn = (_b = filterFns[columnFilterFns[columnDef.id]]) !== null && _b !== void 0 ? _b : filterFns.fuzzy; columnDef._filterFn = columnFilterFns[columnDef.id]; } //assign sortingFns if (Object.keys(sortingFns).includes(columnDef.sortingFn)) { // @ts-expect-error columnDef.sortingFn = sortingFns[columnDef.sortingFn]; } } else if (columnDef.columnDefType === 'display') { columnDef = Object.assign(Object.assign({}, defaultDisplayColumn), columnDef); } return columnDef; }); }; const reorderColumn = (draggedColumn, targetColumn, columnOrder) => { if (draggedColumn.getCanPin()) { draggedColumn.pin(targetColumn.getIsPinned()); } const newColumnOrder = [...columnOrder]; newColumnOrder.splice(newColumnOrder.indexOf(targetColumn.id), 0, newColumnOrder.splice(newColumnOrder.indexOf(draggedColumn.id), 1)[0]); return newColumnOrder; }; const getDefaultColumnFilterFn = (columnDef) => { const { filterVariant } = columnDef; if (filterVariant === 'multi-select') return 'arrIncludesSome'; if (filterVariant === null || filterVariant === void 0 ? void 0 : filterVariant.includes('range')) return 'betweenInclusive'; if (filterVariant === 'select' || filterVariant === 'checkbox') return 'equals'; return 'fuzzy'; }; const getColumnFilterInfo = ({ header, table, }) => { var _a; const { options: { columnFilterModeOptions }, } = table; const { column } = header; const { columnDef } = column; const { filterVariant } = columnDef; const isDateFilter = !!((filterVariant === null || filterVariant === void 0 ? void 0 : filterVariant.startsWith('date')) || (filterVariant === null || filterVariant === void 0 ? void 0 : filterVariant.startsWith('time'))); const isAutocompleteFilter = filterVariant === 'autocomplete'; const isRangeFilter = (filterVariant === null || filterVariant === void 0 ? void 0 : filterVariant.includes('range')) || ['between', 'betweenInclusive', 'inNumberRange'].includes(columnDef._filterFn); const isSelectFilter = filterVariant === 'select'; const isMultiSelectFilter = filterVariant === 'multi-select'; const isTextboxFilter = ['autocomplete', 'text'].includes(filterVariant) || (!isSelectFilter && !isMultiSelectFilter); const currentFilterOption = columnDef._filterFn; const allowedColumnFilterOptions = (_a = columnDef === null || columnDef === void 0 ? void 0 : columnDef.columnFilterModeOptions) !== null && _a !== void 0 ? _a : columnFilterModeOptions; const facetedUniqueValues = column.getFacetedUniqueValues(); return { allowedColumnFilterOptions, currentFilterOption, facetedUniqueValues, isAutocompleteFilter, isDateFilter, isMultiSelectFilter, isRangeFilter, isSelectFilter, isTextboxFilter, }; }; const useDropdownOptions = ({ header, table, }) => { const { column } = header; const { columnDef } = column; const { facetedUniqueValues, isAutocompleteFilter, isMultiSelectFilter, isSelectFilter, } = getColumnFilterInfo({ header, table }); return useMemo(() => { var _a; return (_a = columnDef.filterSelectOptions) !== null && _a !== void 0 ? _a : ((isSelectFilter || isMultiSelectFilter || isAutocompleteFilter) && facetedUniqueValues ? Array.from(facetedUniqueValues.keys()) .filter((value) => value !== null && value !== undefined) .sort((a, b) => a.localeCompare(b)) : undefined); }, [ columnDef.filterSelectOptions, facetedUniqueValues, isMultiSelectFilter, isSelectFilter, ]); }; const flexRender = flexRender$1; function createMRTColumnHelper() { return { accessor: (accessor, column) => { return typeof accessor === 'function' ? Object.assign(Object.assign({}, column), { accessorFn: accessor }) : Object.assign(Object.assign({}, column), { accessorKey: accessor }); }, display: (column) => column, group: (column) => column, }; } const createRow = (table, originalRow, rowIndex = -1, depth = 0, subRows, parentId) => createRow$1(table, 'mrt-row-create', originalRow !== null && originalRow !== void 0 ? originalRow : Object.assign({}, ...getAllLeafColumnDefs(table.options.columns).map((col) => ({ [getColumnId(col)]: '', }))), rowIndex, depth, subRows, parentId); const fuzzy$1 = (rowA, rowB, columnId) => { let dir = 0; if (rowA.columnFiltersMeta[columnId]) { dir = compareItems(rowA.columnFiltersMeta[columnId], rowB.columnFiltersMeta[columnId]); } // Provide a fallback for when the item ranks are equal return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir; }; const MRT_SortingFns = Object.assign(Object.assign({}, sortingFns), { fuzzy: fuzzy$1 }); const rankGlobalFuzzy = (rowA, rowB) => Math.max(...Object.values(rowB.columnFiltersMeta).map((v) => v.rank)) - Math.max(...Object.values(rowA.columnFiltersMeta).map((v) => v.rank)); const parseFromValuesOrFunc = (fn, arg) => (fn instanceof Function ? fn(arg) : fn); const getValueAndLabel = (option) => { var _a, _b; let label = ''; let value = ''; if (option) { if (typeof option !== 'object') { label = option; value = option; } else { label = (_a = option.label) !== null && _a !== void 0 ? _a : option.value; value = (_b = option.value) !== null && _b !== void 0 ? _b : label; } } return { label, value }; }; const getMRT_Rows = (table, all) => { const { getCenterRows, getPrePaginationRowModel, getRowModel, getState, getTopRows, options: { createDisplayMode, enablePagination, enableRowPinning, manualPagination, positionCreatingRow, rowPinningDisplayMode, }, } = table; const { creatingRow, pagination } = getState(); const isRankingRows = getIsRankingRows(table); let rows = []; if (!isRankingRows) { rows = !enableRowPinning || (rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.includes('sticky')) ? all ? getPrePaginationRowModel().rows : getRowModel().rows : getCenterRows(); } else { // fuzzy ranking adjustments rows = getPrePaginationRowModel().rows.sort((a, b) => rankGlobalFuzzy(a, b)); if (enablePagination && !manualPagination && !all) { const start = pagination.pageIndex * pagination.pageSize; rows = rows.slice(start, start + pagination.pageSize); } if (enableRowPinning && !(rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.includes('sticky'))) { // "re-center-ize" the rows (no top or bottom pinned rows unless sticky) rows = rows.filter((row) => !row.getIsPinned()); } } // row pinning adjustments if (enableRowPinning && (rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.includes('sticky'))) { const centerPinnedRowIds = rows .filter((row) => row.getIsPinned()) .map((r) => r.id); rows = [ ...getTopRows().filter((row) => !centerPinnedRowIds.includes(row.id)), ...rows, ]; } // blank inserted creating row adjustments if (positionCreatingRow !== undefined && creatingRow && createDisplayMode === 'row') { const creatingRowIndex = !isNaN(+positionCreatingRow) ? +positionCreatingRow : positionCreatingRow === 'top' ? 0 : rows.length; rows = [ ...rows.slice(0, creatingRowIndex), creatingRow, ...rows.slice(creatingRowIndex), ]; } return rows; }; const getCanRankRows = (table) => { const { getState, options: { enableGlobalFilterRankedResults, manualExpanding, manualFiltering, manualGrouping, manualSorting, }, } = table; const { expanded, globalFilterFn } = getState(); return (!manualExpanding && !manualFiltering && !manualGrouping && !manualSorting && enableGlobalFilterRankedResults && globalFilterFn === 'fuzzy' && expanded !== true && !Object.values(expanded).some(Boolean)); }; const getIsRankingRows = (table) => { const { globalFilter, sorting } = table.getState(); return (getCanRankRows(table) && globalFilter && !Object.values(sorting).some(Boolean)); }; const getIsRowSelected = ({ row, table, }) => { const { options: { enableRowSelection }, } = table; return (row.getIsSelected() || (parseFromValuesOrFunc(enableRowSelection, row) && row.getCanSelectSubRows() && row.getIsAllSubRowsSelected())); }; const getMRT_RowSelectionHandler = ({ row, staticRowIndex = 0, table, }) => (event, value) => { var _a; const { getState, options: { enableBatchRowSelection, enableMultiRowSelection, enableRowPinning, manualPagination, rowPinningDisplayMode, }, refs: { lastSelectedRowId: lastSelectedRowId }, } = table; const { pagination: { pageIndex, pageSize }, } = getState(); const paginationOffset = manualPagination ? 0 : pageSize * pageIndex; const wasCurrentRowChecked = getIsRowSelected({ row, table }); // toggle selection of this row row.toggleSelected(value !== null && value !== void 0 ? value : !wasCurrentRowChecked); const changedRowIds = new Set([row.id]); // if shift key is pressed, select all rows between last selected and this one if (enableBatchRowSelection && enableMultiRowSelection && event.nativeEvent.shiftKey && lastSelectedRowId.current !== null) { const rows = getMRT_Rows(table, true); const lastIndex = rows.findIndex((r) => r.id === lastSelectedRowId.current); if (lastIndex !== -1) { const isLastIndexChecked = getIsRowSelected({ row: rows === null || rows === void 0 ? void 0 : rows[lastIndex], table, }); const currentIndex = staticRowIndex + paginationOffset; const [start, end] = lastIndex < currentIndex ? [lastIndex, currentIndex] : [currentIndex, lastIndex]; // toggle selection of all rows between last selected and this one // but only if the last selected row is not the same as the current one if (wasCurrentRowChecked !== isLastIndexChecked) { for (let i = start; i <= end; i++) { rows[i].toggleSelected(!wasCurrentRowChecked); changedRowIds.add(rows[i].id); } } } } // record the last selected row id lastSelectedRowId.current = row.id; // if all sub rows were selected, unselect them if (row.getCanSelectSubRows() && row.getIsAllSubRowsSelected()) { (_a = row.subRows) === null || _a === void 0 ? void 0 : _a.forEach((r) => r.toggleSelected(false)); } if (enableRowPinning && (rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.includes('select'))) { changedRowIds.forEach((rowId) => { const rowToTogglePin = table.getRow(rowId); rowToTogglePin.pin(!wasCurrentRowChecked //was not previously pinned or selected ? (rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.includes('bottom')) ? 'bottom' : 'top' : false); }); } }; const getMRT_SelectAllHandler = ({ table }) => (event, value, forceAll) => { const { options: { enableRowPinning, rowPinningDisplayMode, selectAllMode }, refs: { lastSelectedRowId }, } = table; selectAllMode === 'all' || forceAll ? table.toggleAllRowsSelected(value !== null && value !== void 0 ? value : event.target.checked) : table.toggleAllPageRowsSelected(value !== null && value !== void 0 ? value : event.target.checked); if (enableRowPinning && (rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.includes('select'))) { table.setRowPinning({ bottom: [], top: [] }); } lastSelectedRowId.current = null; }; const isWinCtrlMacMeta = (event) => { return ((event.ctrlKey && navigator.platform.toLowerCase().includes('win')) || (event.metaKey && navigator.platform.toLowerCase().includes('mac'))); }; const isCellEditable = ({ cell, table, }) => { const { enableEditing } = table.options; const { column: { columnDef }, row, } = cell; return (!cell.getIsPlaceholder() && parseFromValuesOrFunc(enableEditing, row) && parseFromValuesOrFunc(columnDef.enableEditing, row) !== false); }; const openEditingCell = ({ cell, table, }) => { const { options: { editDisplayMode }, refs: { editInputRefs }, } = table; const { column } = cell; if (isCellEditable({ cell, table }) && editDisplayMode === 'cell') { table.setEditingCell(cell); queueMicrotask(() => { var _a, _b; const textField = (_a = editInputRefs.current) === null || _a === void 0 ? void 0 : _a[column.id]; if (textField) { textField.focus(); (_b = textField.select) === null || _b === void 0 ? void 0 : _b.call(textField); } }); } }; const cellKeyboardShortcuts = ({ cell, cellElements, cellValue, containerElement, event, header, parentElement, table, }) => { var _a, _b, _c, _d, _e, _f, _g, _h; if (!table.options.enableKeyboardShortcuts) return; if (event.isPropagationStopped()) return; const currentCell = event.currentTarget; if (cellValue && isWinCtrlMacMeta(event) && event.key === 'c') { navigator.clipboard.writeText(cellValue); } else if (['Enter', ' '].includes(event.key)) { if (((_a = cell === null || cell === void 0 ? void 0 : cell.column) === null || _a === void 0 ? void 0 : _a.id) === 'mrt-row-select') { event.preventDefault(); getMRT_RowSelectionHandler({ row: cell.row, table, //@ts-expect-error staticRowIndex: +event.target.getAttribute('data-index'), })(event); } else if (((_b = header === null || header === void 0 ? void 0 : header.column) === null || _b === void 0 ? void 0 : _b.id) === 'mrt-row-select' && table.options.enableSelectAll) { event.preventDefault(); getMRT_SelectAllHandler({ table, })(event); } else if (((_c = cell === null || cell === void 0 ? void 0 : cell.column) === null || _c === void 0 ? void 0 : _c.id) === 'mrt-row-expand' && (cell.row.getCanExpand() || ((_e = (_d = table.options).renderDetailPanel) === null || _e === void 0 ? void 0 : _e.call(_d, { row: cell.row, table })))) { event.preventDefault(); cell.row.toggleExpanded(); } else if (((_f = header === null || header === void 0 ? void 0 : header.column) === null || _f === void 0 ? void 0 : _f.id) === 'mrt-row-expand' && table.options.enableExpandAll) { event.preventDefault(); table.toggleAllRowsExpanded(); } else if ((cell === null || cell === void 0 ? void 0 : cell.column.id) === 'mrt-row-pin') { event.preventDefault(); cell.row.getIsPinned() ? cell.row.pin(false) : cell.row.pin(((_g = table.options.rowPinningDisplayMode) === null || _g === void 0 ? void 0 : _g.includes('bottom')) ? 'bottom' : 'top'); } else if (header && isWinCtrlMacMeta(event)) { const actionsButton = currentCell.querySelector(`button[aria-label="${table.options.localization.columnActions}"]`); if (actionsButton) { actionsButton.click(); } } else if ((_h = header === null || header === void 0 ? void 0 : header.column) === null || _h === void 0 ? void 0 : _h.getCanSort()) { event.preventDefault(); header.column.toggleSorting(); } } else if ([ 'ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown', ].includes(event.key)) { event.preventDefault(); const currentRow = parentElement || currentCell.closest('tr'); const tableElement = containerElement || currentCell.closest('table'); const allCells = cellElements || Array.from((tableElement === null || tableElement === void 0 ? void 0 : tableElement.querySelectorAll('th, td')) || []); const currentCellIndex = allCells.indexOf(currentCell); const currentIndex = parseInt(currentCell.getAttribute('data-index') || '0'); let nextCell = undefined; //home/end first or last cell in row const findEdgeCell = (rowIndex, edge) => { var _a; const row = rowIndex === 'c' ? currentRow : rowIndex === 'f' ? tableElement === null || tableElement === void 0 ? void 0 : tableElement.querySelector('tr') : (_a = tableElement === null || tableElement === void 0 ? void 0 : tableElement.lastElementChild) === null || _a === void 0 ? void 0 : _a.lastElementChild; const rowCells = Array.from((row === null || row === void 0 ? void 0 : row.children) || []); const targetCell = edge === 'f' ? rowCells[0] : rowCells[rowCells.length - 1]; return targetCell; }; //page up/down first or last cell in column const findBottomTopCell = (columnIndex, edge) => { var _a; const row = edge === 't' ? tableElement === null || tableElement === void 0 ? void 0 : tableElement.querySelector('tr') : (_a = tableElement === null || tableElement === void 0 ? void 0 : tableElement.lastElementChild) === null || _a === void 0 ? void 0 : _a.lastElementChild; const rowCells = Array.from((row === null || row === void 0 ? void 0 : row.children) || []); const targetCell = rowCells[columnIndex]; return targetCell; }; const findAdjacentCell = (columnIndex, searchDirection) => { const searchArray = searchDirection === 'f' ? allCells.slice(currentCellIndex + 1) : allCells.slice(0, currentCellIndex).reverse(); return searchArray.find((cell) => cell.matches(`[data-index="${columnIndex}"]`)); }; switch (event.key) { case 'ArrowRight': nextCell = findAdjacentCell(currentIndex + 1, 'f'); break; case 'ArrowLeft': nextCell = findAdjacentCell(currentIndex - 1, 'b'); break; case 'ArrowUp': nextCell = findAdjacentCell(currentIndex, 'b'); break; case 'ArrowDown': nextCell = findAdjacentCell(currentIndex, 'f'); break; case 'Home': nextCell = findEdgeCell(isWinCtrlMacMeta(event) ? 'f' : 'c', 'f'); break; case 'End': nextCell = findEdgeCell(isWinCtrlMacMeta(event) ? 'l' : 'c', 'l'); break; case 'PageUp': nextCell = findBottomTopCell(currentIndex, 't'); break; case 'PageDown': nextCell = findBottomTopCell(currentIndex, 'b'); break; } if (nextCell) { nextCell.focus(); } } }; function defaultDisplayColumnProps({ header, id, size, tableOptions, }) { const { defaultDisplayColumn, displayColumnDefOptions, localization } = tableOptions; return Object.assign(Object.assign(Object.assign(Object.assign({}, defaultDisplayColumn), { header: header ? localization[header] : '', size }), displayColumnDefOptions === null || displayColumnDefOptions === void 0 ? void 0 : displayColumnDefOptions[id]), { id }); } const showRowPinningColumn = (tableOptions) => { const { enableRowPinning, rowPinningDisplayMode } = tableOptions; return !!(enableRowPinning && !(rowPinningDisplayMode === null || rowPinningDisplayMode === void 0 ? void 0 : rowPinningDisplayMode.startsWith('select'))); }; const showRowDragColumn = (tableOptions) => { const { enableRowDragging, enableRowOrdering } = tableOptions; return !!(enableRowDragging || enableRowOrdering); }; const showRowExpandColumn = (tableOptions) => { const { enableExpanding, enableGrouping, renderDetailPanel, state: { grouping }, } = tableOptions; return !!(enableExpanding || (enableGrouping && (grouping === null || grouping === void 0 ? void 0 : grouping.length)) || renderDetailPanel); }; const showRowActionsColumn = (tableOptions) => { const { createDisplayMode, editDisplayMode, enableEditing, enableRowActions, state: { creatingRow }, } = tableOptions; return !!(enableRowActions || (creatingRow && createDisplayMode === 'row') || (enableEditing && ['modal', 'row'].includes(editDisplayMode !== null && editDisplayMode !== void 0 ? editDisplayMode : ''))); }; const showRowSelectionColumn = (tableOptions) => !!tableOptions.enableRowSelection; const showRowNumbersColumn = (tableOptions) => !!tableOptions.enableRowNumbers; const showRowSpacerColumn = (tableOptions) => tableOptions.layoutMode === 'grid-no-grow'; const getLeadingDisplayColumnIds = (tableOptions) => [ showRowPinningColumn(tableOptions) && 'mrt-row-pin', showRowDragColumn(tableOptions) && 'mrt-row-drag', tableOptions.positionActionsColumn === 'first' && showRowActionsColumn(tableOptions) && 'mrt-row-actions', tableOptions.positionExpandColumn === 'first' && showRowExpandColumn(tableOptions) && 'mrt-row-expand', showRowSelectionColumn(tableOptions) && 'mrt-row-select', showRowNumbersColumn(tableOptions) && 'mrt-row-numbers', ].filter(Boolean); const getTrailingDisplayColumnIds = (tableOptions) => [ tableOptions.positionActionsColumn === 'last' && showRowActionsColumn(tableOptions) && 'mrt-row-actions', tableOptions.positionExpandColumn === 'last' && showRowExpandColumn(tableOptions) && 'mrt-row-expand', showRowSpacerColumn(tableOptions) && 'mrt-row-spacer', ].filter(Boolean); const getDefaultColumnOrderIds = (tableOptions, reset = false) => { const { state: { columnOrder: currentColumnOrderIds = [] }, } = tableOptions; const leadingDisplayColIds = getLeadingDisplayColumnIds(tableOptions); const trailingDisplayColIds = getTrailingDisplayColumnIds(tableOptions); const defaultColumnDefIds = getAllLeafColumnDefs(tableOptions.columns).map((columnDef) => getColumnId(columnDef)); let allLeafColumnDefIds = reset ? defaultColumnDefIds : Array.from(new Set([...currentColumnOrderIds, ...defaultColumnDefIds])); allLeafColumnDefIds = allLeafColumnDefIds.filter((colId) => !leadingDisplayColIds.includes(colId) && !trailingDisplayColIds.includes(colId)); return [ ...leadingDisplayColIds, ...allLeafColumnDefIds, ...trailingDisplayColIds, ]; }; const MRT_AggregationFns = Object.assign({}, aggregationFns); const fuzzy = (row, columnId, filterValue, addMeta) => { const itemRank = rankItem(row.getValue(columnId), filterValue, { threshold: rankings.MATCHES, }); addMeta(itemRank); return itemRank.passed; }; fuzzy.autoRemove = (val) => !val; const contains = (row, id, filterValue) => { var _a; return !!((_a = row .getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().trim().includes(filterValue.toString().toLowerCase().trim())); }; contains.autoRemove = (val) => !val; const startsWith = (row, id, filterValue) => { var _a; return !!((_a = row .getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().trim().startsWith(filterValue.toString().toLowerCase().trim())); }; startsWith.autoRemove = (val) => !val; const endsWith = (row, id, filterValue) => { var _a; return !!((_a = row .getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().trim().endsWith(filterValue.toString().toLowerCase().trim())); }; endsWith.autoRemove = (val) => !val; const equals = (row, id, filterValue) => { var _a; return ((_a = row.getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().trim()) === filterValue.toString().toLowerCase().trim(); }; equals.autoRemove = (val) => !val; const notEquals = (row, id, filterValue) => { var _a; return ((_a = row.getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().trim()) !== filterValue.toString().toLowerCase().trim(); }; notEquals.autoRemove = (val) => !val; const greaterThan = (row, id, filterValue) => { var _a, _b, _c; return !isNaN(+filterValue) && !isNaN(+row.getValue(id)) ? +((_a = row.getValue(id)) !== null && _a !== void 0 ? _a : 0) > +filterValue : ((_c = ((_b = row.getValue(id)) !== null && _b !== void 0 ? _b : '')) === null || _c === void 0 ? void 0 : _c.toString().toLowerCase().trim()) > filterValue.toString().toLowerCase().trim(); }; greaterThan.autoRemove = (val) => !val; const greaterThanOrEqualTo = (row, id, filterValue) => equals(row, id, filterValue) || greaterThan(row, id, filterValue); greaterThanOrEqualTo.autoRemove = (val) => !val; const lessThan = (row, id, filterValue) => { var _a, _b, _c; return !isNaN(+filterValue) && !isNaN(+row.getValue(id)) ? +((_a = row.getValue(id)) !== null && _a !== void 0 ? _a : 0) < +filterValue : ((_c = ((_b = row.getValue(id)) !== null && _b !== void 0 ? _b : '')) === null || _c === void 0 ? void 0 : _c.toString().toLowerCase().trim()) < filterValue.toString().toLowerCase().trim(); }; lessThan.autoRemove = (val) => !val; const lessThanOrEqualTo = (row, id, filterValue) => equals(row, id, filterValue) || lessThan(row, id, filterValue); lessThanOrEqualTo.autoRemove = (val) => !val; const between = (row, id, filterValues) => (['', undefined].includes(filterValues[0]) || greaterThan(row, id, filterValues[0])) && ((!isNaN(+filterValues[0]) && !isNaN(+filterValues[1]) && +filterValues[0] > +filterValues[1]) || ['', undefined].includes(filterValues[1]) || lessThan(row, id, filterValues[1])); between.autoRemove = (val) => !val; const betweenInclusive = (row, id, filterValues) => (['', undefined].includes(filterValues[0]) || greaterThanOrEqualTo(row, id, filterValues[0])) && ((!isNaN(+filterValues[0]) && !isNaN(+filterValues[1]) && +filterValues[0] > +filterValues[1]) || ['', undefined].includes(filterValues[1]) || lessThanOrEqualTo(row, id, filterValues[1])); betweenInclusive.autoRemove = (val) => !val; const empty = (row, id, _filterValue) => { var _a; return !((_a = row.getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().trim()); }; empty.autoRemove = (val) => !val; const notEmpty = (row, id, _filterValue) => { var _a; return !!((_a = row.getValue(id)) === null || _a === void 0 ? void 0 : _a.toString().trim()); }; notEmpty.autoRemove = (val) => !val; const MRT_FilterFns = Object.assign(Object.assign({}, filterFns), { between, betweenInclusive, contains, empty, endsWith, equals, fuzzy, greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo, notEmpty, notEquals, startsWith }); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; const MRT_EditActionButtons = (_a) => { var { row, table, variant = 'icon' } = _a, rest = __rest(_a, ["row", "table", "variant"]); const { getState, options: { icons: { CancelIcon, SaveIcon }, localization, onCreatingRowCancel, onCreatingRowSave, onEditingRowCancel, onEditingRowSave, }, refs: { editInputRefs }, setCreatingRow, setEditingRow, } = table; const { creatingRow, editingRow, isSaving } = getState(); const isCreating = (creatingRow === null || creatingRow === void 0 ? void 0 : creatingRow.id) === row.id; const isEditing = (editingRow === null || editingRow === void 0 ? void 0 : editingRow.id) === row.id; const handleCancel = () => { if (isCreating) { onCreatingRowCancel === null || onCreatingRowCancel === void 0 ? void 0 : onCreatingRowCancel({ row, table }); setCreatingRow(null); } else if (isEditing) { onEditingRowCancel === null || onEditingRowCancel === void 0 ? void 0 : onEditingRowCancel({ row, table }); setEditingRow(null); } row._valuesCache = {}; //reset values cache }; const handleSubmitRow = () => { var _a, _b; //look for auto-filled input values (_b = Object.values((_a = editInputRefs.current) !== null && _a !== void 0 ? _a : {}) .filter((inputRef) => { var _a, _b; return row.id === ((_b = (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.name) === null || _a === void 0 ? void 0 : _a.split('_')) === null || _b === void 0 ? void 0 : _b[0]); })) === null || _b === void 0 ? void 0 : _b.forEach((input) => { if (input.value !== undefined && Object.hasOwn(row === null || row === void 0 ? void 0 : row._valuesCache, input.name)) { // @ts-expect-error row._valuesCache[input.name] = input.value; } }); if (isCreating) onCreatingRowSave === null || onCreatingRowSave === void 0 ? void 0 : onCreatingRowSave({ exitCreatingMode: () => setCreatingRow(null), row, table, values: row._valuesCache, }); else if (isEditing) { onEditingRowSave === null || onEditingRowSave === void 0 ? void 0 : onEditingRowSave({ exitEditingMode: () => setEditingRow(null), row, table, values: row === null || row === void 0 ? void 0 : row._valuesCache, }); } }; return (jsx(Box, { onClick: (e) => e.stopPropagation(), sx: (theme) => (Object.assign({ display: 'flex', gap: '0.75rem' }, parseFromValuesOrFunc(rest === null || rest === void 0 ? void 0 : rest.sx, theme))), children: variant === 'icon' ? (jsxs(Fragment, { children: [jsx(Tooltip, { title: localization.cancel, children: jsx(IconButton, { "aria-label": localization.cancel, onClick: handleCancel, children: jsx(CancelIcon, {}) }) }), ((isCreating && onCreatingRowSave) || (isEditing && onEditingRowSave)) && (jsx(Tooltip, { title: localization.save, children: jsx(IconButton, { "aria-label": localization.save, color: "info", disabled: isSaving, onClick: handleSubmitRow, children: isSaving ? jsx(CircularProgress, { size: 18 }) : jsx(SaveIcon, {}) }) }))] })) : (jsxs(Fragment, { children: [jsx(Button, { onClick: handleCancel, sx: { minWidth: '100px' }, children: localization.cancel }), jsxs(Button, { disabled: isSaving, onClick: handleSubmitRow, sx: { minWidth: '100px' }, variant: "contained", children: [isSaving && jsx(CircularProgress, { color: "inherit", size: 18 }), localization.save] })] })) })); }; const parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, '_'); const getMRTTheme = (mrtTheme, muiTheme) => { var _a; const mrtThemeOverrides = parseFromValuesOrFunc(mrtTheme, muiTheme); const baseBackgroundColor = (_a = mrtThemeOverrides === null || mrtThemeOverrides === void 0 ? void 0 : mrtThemeOverrides.baseBackgroundColor) !== null && _a !== void 0 ? _a : (muiTheme.palette.mode === 'dark' ? lighten(muiTheme.palette.background.default, 0.05) : muiTheme.palette.background.default); return Object.assign({ baseBackgroundColor, cellNavigationOutlineColor: muiTheme.palette.primary.main, draggingBorderColor: muiTheme.palette.primary.main, matchHighlightColor: muiTheme.palette.mode === 'dark' ? darken(muiTheme.palette.warning.dark, 0.25) : lighten(muiTheme.palette.warning.light, 0.5), menuBackgroundColor: lighten(baseBackgroundColor, 0.07), pinnedRowBackgroundColor: alpha(muiTheme.palette.primary.main, 0.1), selectedRowBackgroundColor: alpha(muiTheme.palette.primary.main, 0.2) }, mrtThemeOverrides); }; const commonCellBeforeAfterStyles = { content: '""', height: '100%', left: 0, position: 'absolute', top: 0, width: '100%', zIndex: -1, }; const getCommonPinnedCellStyles = ({ column, table, theme, }) => { const { baseBackgroundColor } = table.options.mrtTheme; const isPinned = column === null || column === void 0 ? void 0 : column.getIsPinned(); return { '&[data-pinned="true"]': { '&:before': Object.assign({ backgroundColor: alpha(darken(baseBackgroundColor, theme.palette.mode === 'dark' ? 0.05 : 0.01), 0.97), boxShadow: column ? isPinned === 'left' && column.getIsLastColumn(isPinned) ? `-4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` : isPinned === 'right' && column.getIsFirstColumn(isPinned) ? `4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` : undefined : undefined }, commonCellBeforeAfterStyles), }, }; }; const getCommonMRTCellStyles = ({ column, header, table, tableCellProps, theme, }) => { var _a, _b, _c, _d, _e, _f; const { getState, options: { enableColumnVirtualization, layoutMode }, } = table; const { draggingColumn } = getState(); const { columnDef } = column; const { columnDefType } = columnDef; const isColumnPinned = columnDef.columnDefType !== 'group' && column.getIsPinned(); const widthStyles = { minWidth: `max(calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId((_a = header === null || header === void 0 ? void 0 : header.id) !== null && _a !== void 0 ? _a : column.id)}-size) * 1px), ${(_b = columnDef.minSize) !== null && _b !== void 0 ? _b : 30}px)`, width: `calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId((_c = header === null || header === void 0 ? void 0 : header.id) !== null && _c !== void 0 ? _c : column.id)}-size) * 1px)`, }; if (layoutMode === 'grid') { widthStyles.flex = `${[0, false].includes(columnDef.grow) ? 0 : `var(--${header ? 'header' : 'col'}-${parseCSSVarId((_d = header === null || header === void 0 ? void 0 : header.id) !== null && _d !== void 0 ? _d : column.id)}-size)`} 0 auto`; } else if (layoutMode === 'grid-no-grow') { widthStyles.flex = `${+(columnDef.grow || 0)} 0 auto`; } const pinnedStyles = isColumnPinned ? Object.assign(Object.assign({}, getCommonPinnedCellStyles({ column, table, theme })), { left: isColumnPinned === 'left' ? `${column.getStart('left')}px` : undefined, opacity: 0.97, position: 'sticky', right: isColumnPinned === 'right' ? `${column.getAfter('right')}px` : undefined }) : {}; return Object.assign(Object.assign(Object.assign({ backgroundColor: 'inherit', backgroundImage: 'inherit', display: (layoutMode === null || layoutMode === void 0 ? void 0 : layoutMode.startsWith('grid')) ? 'flex' : undefined, justifyContent: columnDefType === 'group' ? 'center' : (layoutMode === null || layoutMode === void 0 ? void 0 : layoutMode.startsWith('grid')) ? tableCellProps.align : undefined, opacity: ((_e = table.getState().draggingColumn) === null || _e === void 0 ? void 0 : _e.id) === column.id || ((_f = table.getState().hoveredColumn) === null || _f === void 0 ? void 0 : _f.id) === column.id ? 0.5 : 1, position: 'relative', transition: enableColumnVirtualization ? 'none' : `padding 150ms ease-in-out`, zIndex: column.getIsResizing() || (draggingColumn === null || draggingColumn === void 0 ? void 0 : draggingColumn.id) === column.id ? 2 : columnDefType !== 'group' && isColumnPinned ? 1 : 0, '&:focus-visible': { outline: `2px solid ${table.options.mrtTheme.cellNavigationOutlineColor}`, outlineOffset: '-2px', } }, pinnedStyles), widthStyles), parseFromValuesOrFunc(tableCellProps === null || tableCellProps === void 0 ? void 0 : tableCellProps.sx, theme)); }; const getCommonToolbarStyles = ({ table, }) => ({ alignItems: 'flex-start', backgroundColor: table.options.mrtTheme.baseBackgroundColor, display: 'grid', flexWrap: 'wrap-reverse', minHeight: '3.5rem', overflow: 'hidden', position: 'relative', transition: 'all 150ms ease-in-out', zIndex: 1, }); const flipIconStyles = (theme) => theme.direction === 'rtl' ? { style: { transform: 'scaleX(-1)' } } : undefined; const getCommonTooltipProps = (placement) => ({ disableInteractive: true, enterDelay: 1000, enterNextDelay: 1000, placement, }); const MRT_ActionMenuItem = (_a) => { var { icon, label, onOpenSubMenu, table } = _a, rest = __rest(_a, ["icon", "label", "onOpenSubMenu", "table"]); const { options: { icons: { ArrowRightIcon }, }, } = table; return (jsxs(MenuItem, Object.assign({ sx: { alignItems: 'center', justifyContent: 'space-between', minWidth: '120px', my: 0, py: '6px', }, tabIndex: 0 }, rest, { children: [jsxs(Box, { sx: { alignItems: 'center', display: 'flex', }, children: [jsx(ListItemIcon, { children: icon }), label] }), onOpenSubMenu && (jsx(IconButton, { onClick: onOpenSubMenu, onMouseEnter: onOpenSubMenu, size: "small", sx: { p: 0 }, children: jsx(ArrowRightIcon, {}) }))] }))); }; const MRT_RowActionMenu = (_a) => { var { anchorEl, handleEdit, row, setAnchorEl, staticRowIndex, table } = _a, rest = __rest(_a, ["anchorEl", "handleEdit", "row", "setAnchorEl", "staticRowIndex", "table"]); const { getState, options: { editDisplayMode, enableEditing, icons: { EditIcon }, localization, mrtTheme: { menuBackgroundColor }, renderRowActionMenuItems, }, } = table; const { density } = getState(); const menuItems = useMemo(() => { const items = []; const editItem = parseFromValuesOrFunc(enableEditing, row) && ['modal', 'row'].includes(editDisplayMode) && (jsx(MRT_ActionMenuItem, { icon: jsx(EditIcon, {}), label: localization.edit, onClick: handleEdit, table: table }, 'edit')); if (editItem) items.push(editItem); const rowActionMenuItems = renderRowActionMenuItems === null || renderRowActionMenuItems === void 0 ? void 0 : renderRowActionMenuItems({ closeMenu: () => setAnchorEl(null), row, staticRowIndex, table, }); if (rowActionMenuItems === null || rowActionMenuItems === void 0 ? void 0 : rowActionMenuItems.length) items.push(...rowActionMenuItems); return items; }, [renderRowActionMenuItems, row, staticRowIndex, table]); if (!menuItems.length) return null; return (jsx(Menu, Object.assign({ MenuListProps: { dense: density === 'compact', sx: { backgroundColor: menuBackgroundColor, }, }, anchorEl: anchorEl, disableScrollLock: true, onClick: (event) => event.stopPropagation(), onClose: () => setAnchorEl(null), open: !!anchorEl }, rest, { children: menuItems }))); }; const commonIconButtonStyles = { '&:hover': { opacity: 1, }, height: '2rem', ml: '10px', opacity: 0.5, transition: 'opacity 150ms', width: '2rem', }; const MRT_ToggleRowActionMenuButton = (_a) => { var _b; var { cell, row, staticRowIndex, table } = _a, rest = __rest(_a, ["cell", "row", "staticRowIndex", "table"]); const { getState, options: { createDisplayM