@inbuild/material-react-table
Version:
A fully featured Material UI V5 implementation of TanStack React Table V8, written from the ground up in TypeScript.
964 lines (948 loc) • 254 kB
JavaScript
import * as React from 'react';
import React__default, { useMemo, useRef, useState, useCallback, useEffect, Fragment, createElement, PureComponent, forwardRef, memo, useLayoutEffect } from 'react';
import { aggregationFns, filterFns, sortingFns, useReactTable, getCoreRowModel, getExpandedRowModel, getFacetedRowModel, getFilteredRowModel, getGroupedRowModel, getPaginationRowModel, getSortedRowModel } from '@tanstack/react-table';
import { alpha, lighten, useTheme, darken } from '@mui/material/styles';
import { rankItem, rankings, compareItems } from '@tanstack/match-sorter-utils';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
import CancelIcon from '@mui/icons-material/Cancel';
import ClearAllIcon from '@mui/icons-material/ClearAll';
import CloseIcon from '@mui/icons-material/Close';
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 FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown';
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 ViewColumnIcon from '@mui/icons-material/ViewColumn';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import Box from '@mui/material/Box';
import Dialog from '@mui/material/Dialog';
import Grow from '@mui/material/Grow';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import ListItemIcon from '@mui/material/ListItemIcon';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import Button from '@mui/material/Button';
import Divider from '@mui/material/Divider';
import FormControlLabel from '@mui/material/FormControlLabel';
import Switch from '@mui/material/Switch';
import Typography from '@mui/material/Typography';
import Checkbox from '@mui/material/Checkbox';
import Radio from '@mui/material/Radio';
import Paper from '@mui/material/Paper';
import Toolbar from '@mui/material/Toolbar';
import useMediaQuery from '@mui/material/useMediaQuery';
import Collapse from '@mui/material/Collapse';
import InputAdornment from '@mui/material/InputAdornment';
import TextField from '@mui/material/TextField';
import { debounce } from '@mui/material/utils';
import LinearProgress from '@mui/material/LinearProgress';
import TablePagination from '@mui/material/TablePagination';
import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle';
import Chip from '@mui/material/Chip';
import Fade from '@mui/material/Fade';
import TableContainer from '@mui/material/TableContainer';
import { useVirtualizer, defaultRangeExtractor } from '@tanstack/react-virtual';
import Table from '@mui/material/Table';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import TableCell from '@mui/material/TableCell';
import Badge from '@mui/material/Badge';
import TableSortLabel from '@mui/material/TableSortLabel';
import TableBody from '@mui/material/TableBody';
import Skeleton from '@mui/material/Skeleton';
import { Autocomplete as Autocomplete$1, TextField as TextField$1, Chip as Chip$1 } from '@mui/material';
import { NumericFormat } from 'react-number-format';
import Autocomplete from '@mui/material/Autocomplete';
import highlightWords from 'highlight-words';
import TableFooter from '@mui/material/TableFooter';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import Stack from '@mui/material/Stack';
/******************************************************************************
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;
}
const MRT_AggregationFns = Object.assign({}, aggregationFns);
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 = ({ aggregationFns, columnDefs, columnFilterFns, defaultDisplayColumn, filterFns, sortingFns, }) => columnDefs.map((columnDef) => {
var _a, _b;
//assign columnId
if (!columnDef.id)
columnDef.id = getColumnId(columnDef);
if (process.env.NODE_ENV !== 'production' && !columnDef.id) {
console.error('Column definitions must have a valid `accessorKey` or `id` property');
}
//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({
aggregationFns,
columnDefs: columnDef.columns,
columnFilterFns,
defaultDisplayColumn,
filterFns,
sortingFns,
});
}
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-ignore
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());
}
columnOrder.splice(columnOrder.indexOf(targetColumn.id), 0, columnOrder.splice(columnOrder.indexOf(draggedColumn.id), 1)[0]);
return [...columnOrder];
};
const showExpandColumn = (props, grouping) => !!(props.enableExpanding ||
(props.enableGrouping && (grouping === undefined || (grouping === null || grouping === void 0 ? void 0 : grouping.length))) ||
props.renderDetailPanel);
const getLeadingDisplayColumnIds = (props) => {
var _a;
return [
(props.enableRowDragging || props.enableRowOrdering) && 'mrt-row-drag',
props.positionActionsColumn === 'first' &&
(props.enableRowActions ||
(props.enableEditing &&
['row', 'modal'].includes((_a = props.editingMode) !== null && _a !== void 0 ? _a : ''))) &&
'mrt-row-actions',
props.positionExpandColumn === 'first' &&
showExpandColumn(props) &&
'mrt-row-expand',
props.enableRowSelection && 'mrt-row-select',
props.enableRowNumbers && 'mrt-row-numbers',
].filter(Boolean);
};
const getTrailingDisplayColumnIds = (props) => {
var _a;
return [
props.positionActionsColumn === 'last' &&
(props.enableRowActions ||
(props.enableEditing &&
['row', 'modal'].includes((_a = props.editingMode) !== null && _a !== void 0 ? _a : ''))) &&
'mrt-row-actions',
props.positionExpandColumn === 'last' &&
showExpandColumn(props) &&
'mrt-row-expand',
];
};
const getDefaultColumnOrderIds = (props) => [
...getLeadingDisplayColumnIds(props),
...getAllLeafColumnDefs(props.columns).map((columnDef) => getColumnId(columnDef)),
...getTrailingDisplayColumnIds(props),
].filter(Boolean);
const getDefaultColumnFilterFn = (columnDef) => {
if (columnDef.filterVariant === 'multi-select')
return 'arrIncludesSome';
if (columnDef.filterVariant === 'range')
return 'betweenInclusive';
if (columnDef.filterVariant === 'select' ||
columnDef.filterVariant === 'checkbox')
return 'equals';
return 'fuzzy';
};
const getIsFirstColumn = (column, table) => {
return table.getVisibleLeafColumns()[0].id === column.id;
};
const getIsLastColumn = (column, table) => {
const columns = table.getVisibleLeafColumns();
return columns[columns.length - 1].id === column.id;
};
const getIsLastLeftPinnedColumn = (table, column) => {
return (column.getIsPinned() === 'left' &&
table.getLeftLeafHeaders().length - 1 === column.getPinnedIndex());
};
const getIsFirstRightPinnedColumn = (column) => {
return column.getIsPinned() === 'right' && column.getPinnedIndex() === 0;
};
const getTotalRight = (table, column) => {
return ((table.getRightLeafHeaders().length - 1 - column.getPinnedIndex()) * 200);
};
const getCommonCellStyles = ({ column, header, table, tableCellProps, theme, }) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
return (Object.assign(Object.assign({ backgroundColor: column.getIsPinned() && column.columnDef.columnDefType !== 'group'
? alpha(lighten(theme.palette.background.default, 0.04), 0.97)
: 'inherit', backgroundImage: 'inherit', boxShadow: getIsLastLeftPinnedColumn(table, column)
? `-4px 0 8px -6px ${alpha(theme.palette.common.black, 0.2)} inset`
: getIsFirstRightPinnedColumn(column)
? `4px 0 8px -6px ${alpha(theme.palette.common.black, 0.2)} inset`
: undefined, display: table.options.layoutMode === 'grid' ? 'flex' : 'table-cell', flex: table.options.layoutMode === 'grid'
? `var(--${header ? 'header' : 'col'}-${parseCSSVarId((_a = header === null || header === void 0 ? void 0 : header.id) !== null && _a !== void 0 ? _a : column.id)}-size) 0 auto`
: undefined, left: column.getIsPinned() === 'left'
? `${column.getStart('left')}px`
: undefined, ml: table.options.enableColumnVirtualization &&
column.getIsPinned() === 'left' &&
column.getPinnedIndex() === 0
? `-${column.getSize() * ((_c = (_b = table.getState().columnPinning.left) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 1)}px`
: undefined, mr: table.options.enableColumnVirtualization &&
column.getIsPinned() === 'right' &&
column.getPinnedIndex() === table.getVisibleLeafColumns().length - 1
? `-${column.getSize() *
((_e = (_d = table.getState().columnPinning.right) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 1) *
1.2}px`
: undefined, opacity: ((_f = table.getState().draggingColumn) === null || _f === void 0 ? void 0 : _f.id) === column.id ||
((_g = table.getState().hoveredColumn) === null || _g === void 0 ? void 0 : _g.id) === column.id
? 0.5
: 1, position: column.getIsPinned() && column.columnDef.columnDefType !== 'group'
? 'sticky'
: undefined, right: column.getIsPinned() === 'right'
? `${getTotalRight(table, column)}px`
: undefined, transition: table.options.enableColumnVirtualization
? 'none'
: `padding 150ms ease-in-out` }, ((tableCellProps === null || tableCellProps === void 0 ? void 0 : tableCellProps.sx) instanceof Function
? tableCellProps.sx(theme)
: tableCellProps === null || tableCellProps === void 0 ? void 0 : tableCellProps.sx)), { minWidth: `max(calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId((_h = header === null || header === void 0 ? void 0 : header.id) !== null && _h !== void 0 ? _h : column.id)}-size) * 1px), ${(_j = column.columnDef.minSize) !== null && _j !== void 0 ? _j : 30}px)`, width: `calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId((_k = header === null || header === void 0 ? void 0 : header.id) !== null && _k !== void 0 ? _k : column.id)}-size) * 1px)` }));
};
const MRT_DefaultColumn = {
filterVariant: 'text',
minSize: 40,
maxSize: 1000,
size: 180,
};
const MRT_DefaultDisplayColumn = {
columnDefType: 'display',
enableClickToCopy: false,
enableColumnActions: false,
enableColumnDragging: false,
enableColumnFilter: false,
enableColumnOrdering: false,
enableEditing: false,
enableGlobalFilter: false,
enableGrouping: false,
enableHiding: false,
enableResizing: false,
enableSorting: false,
};
const parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, '_');
const padZero = (str, len) => {
len = len || 2;
const zeros = new Array(len).join('0');
return (zeros + str).slice(-len);
};
const invertColor = (hex, bw, alp) => {
let alpha = 'FF';
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length === 8) {
alpha = hex.slice(6, 8);
hex = hex.slice(0, 6);
}
else if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
let r = parseInt(hex.slice(0, 2), 16);
let g = parseInt(hex.slice(2, 4), 16);
let b = parseInt(hex.slice(4, 6), 16);
if (bw) {
// https://stackoverflow.com/a/3943023/112731
return r * 0.299 + g * 0.587 + b * 0.114 > 186
? `#000000${alp ? alpha : ''}`
: `#FFFFFF${alp ? alpha : ''}`;
}
// invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16);
// pad each with zeros and return
return `#${padZero(r)}${padZero(g)}${padZero(b)}${alp ? alpha : ''}`;
};
const fuzzy$1 = (row, columnId, filterValue, addMeta) => {
const itemRank = rankItem(row.getValue(columnId), filterValue, {
threshold: rankings.MATCHES,
});
addMeta(itemRank);
return itemRank.passed;
};
fuzzy$1.autoRemove = (val) => !val;
const contains = (row, id, filterValue) => row
.getValue(id)
.toString()
.toLowerCase()
.trim()
.includes(filterValue.toString().toLowerCase().trim());
contains.autoRemove = (val) => !val;
const startsWith = (row, id, filterValue) => row
.getValue(id)
.toString()
.toLowerCase()
.trim()
.startsWith(filterValue.toString().toLowerCase().trim());
startsWith.autoRemove = (val) => !val;
const endsWith = (row, id, filterValue) => row
.getValue(id)
.toString()
.toLowerCase()
.trim()
.endsWith(filterValue.toString().toLowerCase().trim());
endsWith.autoRemove = (val) => !val;
const equals = (row, id, filterValue) => row.getValue(id).toString().toLowerCase().trim() ===
filterValue.toString().toLowerCase().trim();
equals.autoRemove = (val) => !val;
const notEquals = (row, id, filterValue) => row.getValue(id).toString().toLowerCase().trim() !==
filterValue.toString().toLowerCase().trim();
notEquals.autoRemove = (val) => !val;
const greaterThan = (row, id, filterValue) => !isNaN(+filterValue) && !isNaN(+row.getValue(id))
? +row.getValue(id) > +filterValue
: row.getValue(id).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) => !isNaN(+filterValue) && !isNaN(+row.getValue(id))
? +row.getValue(id) < +filterValue
: row.getValue(id).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) => !row.getValue(id).toString().trim();
empty.autoRemove = (val) => !val;
const notEmpty = (row, id, _filterValue) => !!row.getValue(id).toString().trim();
notEmpty.autoRemove = (val) => !val;
const MRT_FilterFns = Object.assign(Object.assign({}, filterFns), { between,
betweenInclusive,
contains,
empty,
endsWith,
equals,
fuzzy: fuzzy$1,
greaterThan,
greaterThanOrEqualTo,
lessThan,
lessThanOrEqualTo,
notEmpty,
notEquals,
startsWith });
const MRT_Default_Icons = {
ArrowDownwardIcon,
ArrowRightIcon,
CancelIcon,
ClearAllIcon,
CloseIcon,
DensityLargeIcon,
DensityMediumIcon,
DensitySmallIcon,
DragHandleIcon,
DynamicFeedIcon,
EditIcon,
ExpandMoreIcon,
FilterAltIcon,
FilterListIcon,
FilterListOffIcon,
FullscreenExitIcon,
FullscreenIcon,
KeyboardDoubleArrowDownIcon,
MoreHorizIcon,
MoreVertIcon,
PushPinIcon,
RestartAltIcon,
SaveIcon,
SearchIcon,
SearchOffIcon,
SortIcon,
ViewColumnIcon,
VisibilityOffIcon,
};
const fuzzy = (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 });
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 MRT_ExpandAllButton = ({ table }) => {
var _a, _b;
const { getIsAllRowsExpanded, getIsSomeRowsExpanded, getCanSomeRowsExpand, getState, options: { icons: { KeyboardDoubleArrowDownIcon }, localization, muiExpandAllButtonProps, renderDetailPanel, }, toggleAllRowsExpanded, } = table;
const { density, isLoading } = getState();
const iconButtonProps = muiExpandAllButtonProps instanceof Function
? muiExpandAllButtonProps({ table })
: muiExpandAllButtonProps;
const isAllRowsExpanded = getIsAllRowsExpanded();
return (React__default.createElement(Tooltip, { arrow: true, enterDelay: 1000, enterNextDelay: 1000, title: ((_a = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.title) !== null && _a !== void 0 ? _a : isAllRowsExpanded)
? localization.collapseAll
: localization.expandAll },
React__default.createElement("span", null,
React__default.createElement(IconButton, Object.assign({ "aria-label": localization.expandAll, disabled: isLoading || (!renderDetailPanel && !getCanSomeRowsExpand()), onClick: () => toggleAllRowsExpanded(!isAllRowsExpanded) }, iconButtonProps, { sx: (theme) => (Object.assign({ height: density === 'compact' ? '1.75rem' : '2.25rem', width: density === 'compact' ? '1.75rem' : '2.25rem', mt: density !== 'compact' ? '-0.25rem' : undefined }, ((iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx) instanceof Function
? iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx(theme)
: iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx))), title: undefined }), (_b = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.children) !== null && _b !== void 0 ? _b : (React__default.createElement(KeyboardDoubleArrowDownIcon, { style: {
transform: `rotate(${isAllRowsExpanded ? -180 : getIsSomeRowsExpanded() ? -90 : 0}deg)`,
transition: 'transform 150ms',
} }))))));
};
const MRT_ExpandButton = ({ row, table, }) => {
var _a, _b;
const { getState, options: { icons: { ExpandMoreIcon }, localization, muiExpandButtonProps, renderDetailPanel, }, } = table;
const { density } = getState();
const iconButtonProps = muiExpandButtonProps instanceof Function
? muiExpandButtonProps({ table, row })
: muiExpandButtonProps;
const canExpand = row.getCanExpand();
const isExpanded = row.getIsExpanded();
const handleToggleExpand = (event) => {
var _a;
event.stopPropagation();
row.toggleExpanded();
(_a = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.onClick) === null || _a === void 0 ? void 0 : _a.call(iconButtonProps, event);
};
return (React__default.createElement(Tooltip, { arrow: true, disableHoverListener: !canExpand && !renderDetailPanel, enterDelay: 1000, enterNextDelay: 1000, title: ((_a = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.title) !== null && _a !== void 0 ? _a : isExpanded)
? localization.collapse
: localization.expand },
React__default.createElement("span", null,
React__default.createElement(IconButton, Object.assign({ "aria-label": localization.expand, disabled: !canExpand && !renderDetailPanel }, iconButtonProps, { onClick: handleToggleExpand, sx: (theme) => (Object.assign({ height: density === 'compact' ? '1.75rem' : '2.25rem', width: density === 'compact' ? '1.75rem' : '2.25rem' }, ((iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx) instanceof Function
? iconButtonProps.sx(theme)
: iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx))), title: undefined }), (_b = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.children) !== null && _b !== void 0 ? _b : (React__default.createElement(ExpandMoreIcon, { style: {
transform: `rotate(${!canExpand && !renderDetailPanel ? -90 : isExpanded ? -180 : 0}deg)`,
transition: 'transform 150ms',
} }))))));
};
const mrtFilterOptions = (localization) => [
{
option: 'fuzzy',
symbol: '≈',
label: localization.filterFuzzy,
divider: false,
},
{
option: 'contains',
symbol: '*',
label: localization.filterContains,
divider: false,
},
{
option: 'startsWith',
symbol: 'a',
label: localization.filterStartsWith,
divider: false,
},
{
option: 'endsWith',
symbol: 'z',
label: localization.filterEndsWith,
divider: true,
},
{
option: 'equals',
symbol: '=',
label: localization.filterEquals,
divider: false,
},
{
option: 'notEquals',
symbol: '≠',
label: localization.filterNotEquals,
divider: true,
},
{
option: 'between',
symbol: '⇿',
label: localization.filterBetween,
divider: false,
},
{
option: 'betweenInclusive',
symbol: '⬌',
label: localization.filterBetweenInclusive,
divider: true,
},
{
option: 'greaterThan',
symbol: '>',
label: localization.filterGreaterThan,
divider: false,
},
{
option: 'greaterThanOrEqualTo',
symbol: '≥',
label: localization.filterGreaterThanOrEqualTo,
divider: false,
},
{
option: 'lessThan',
symbol: '<',
label: localization.filterLessThan,
divider: false,
},
{
option: 'lessThanOrEqualTo',
symbol: '≤',
label: localization.filterLessThanOrEqualTo,
divider: true,
},
{
option: 'empty',
symbol: '∅',
label: localization.filterEmpty,
divider: false,
},
{
option: 'notEmpty',
symbol: '!∅',
label: localization.filterNotEmpty,
divider: false,
},
];
const rangeModes = ['between', 'betweenInclusive', 'inNumberRange'];
const emptyModes = ['empty', 'notEmpty'];
const arrModes = ['arrIncludesSome', 'arrIncludesAll', 'arrIncludes'];
const MRT_FilterOptionMenu = ({ anchorEl, header, onSelect, setAnchorEl, setFilterValue, table, }) => {
var _a, _b, _c, _d;
const { getState, options: { columnFilterModeOptions, globalFilterModeOptions, localization, renderColumnFilterModeMenuItems, renderGlobalFilterModeMenuItems, }, setColumnFilterFns, setGlobalFilterFn, } = table;
const { globalFilterFn, density } = getState();
const { column } = header !== null && header !== void 0 ? header : {};
const { columnDef } = column !== null && column !== void 0 ? column : {};
const currentFilterValue = column === null || column === void 0 ? void 0 : column.getFilterValue();
const allowedColumnFilterOptions = (_a = columnDef === null || columnDef === void 0 ? void 0 : columnDef.columnFilterModeOptions) !== null && _a !== void 0 ? _a : columnFilterModeOptions;
const internalFilterOptions = useMemo(() => mrtFilterOptions(localization).filter((filterOption) => columnDef
? allowedColumnFilterOptions === undefined ||
(allowedColumnFilterOptions === null || allowedColumnFilterOptions === void 0 ? void 0 : allowedColumnFilterOptions.includes(filterOption.option))
: (!globalFilterModeOptions ||
globalFilterModeOptions.includes(filterOption.option)) &&
['fuzzy', 'contains', 'startsWith'].includes(filterOption.option)), []);
const handleSelectFilterMode = (option) => {
var _a;
const prevFilterMode = (_a = columnDef === null || columnDef === void 0 ? void 0 : columnDef._filterFn) !== null && _a !== void 0 ? _a : '';
if (!header || !column) {
// global filter mode
setGlobalFilterFn(option);
}
else if (option !== prevFilterMode) {
// column filter mode
setColumnFilterFns((prev) => (Object.assign(Object.assign({}, prev), { [header.id]: option })));
// reset filter value and/or perform new filter render
if (emptyModes.includes(option)) {
// will now be empty/notEmpty filter mode
if (currentFilterValue !== ' ' &&
!emptyModes.includes(prevFilterMode)) {
column.setFilterValue(' ');
}
else if (currentFilterValue) {
column.setFilterValue(currentFilterValue); // perform new filter render
}
}
else if ((columnDef === null || columnDef === void 0 ? void 0 : columnDef.filterVariant) === 'multi-select' ||
arrModes.includes(option)) {
// will now be array filter mode
if (currentFilterValue instanceof String ||
(currentFilterValue === null || currentFilterValue === void 0 ? void 0 : currentFilterValue.length)) {
column.setFilterValue([]);
setFilterValue === null || setFilterValue === void 0 ? void 0 : setFilterValue([]);
}
else if (currentFilterValue) {
column.setFilterValue(currentFilterValue); // perform new filter render
}
}
else if ((columnDef === null || columnDef === void 0 ? void 0 : columnDef.filterVariant) === 'range' ||
rangeModes.includes(option)) {
// will now be range filter mode
if (!Array.isArray(currentFilterValue) ||
(!(currentFilterValue === null || currentFilterValue === void 0 ? void 0 : currentFilterValue.every((v) => v === '')) &&
!rangeModes.includes(prevFilterMode))) {
column.setFilterValue(['', '']);
setFilterValue === null || setFilterValue === void 0 ? void 0 : setFilterValue('');
}
else {
column.setFilterValue(currentFilterValue); // perform new filter render
}
}
else {
// will now be single value filter mode
if (Array.isArray(currentFilterValue)) {
column.setFilterValue('');
setFilterValue === null || setFilterValue === void 0 ? void 0 : setFilterValue('');
}
else {
column.setFilterValue(currentFilterValue); // perform new filter render
}
}
}
setAnchorEl(null);
onSelect === null || onSelect === void 0 ? void 0 : onSelect();
};
const filterOption = !!header && columnDef ? columnDef._filterFn : globalFilterFn;
return (React__default.createElement(Menu, { anchorEl: anchorEl, anchorOrigin: { vertical: 'center', horizontal: 'right' }, onClose: () => setAnchorEl(null), open: !!anchorEl, MenuListProps: {
dense: density === 'compact',
} }, (_d = (header && column && columnDef
? (_c = (_b = columnDef.renderColumnFilterModeMenuItems) === null || _b === void 0 ? void 0 : _b.call(columnDef, {
column: column,
internalFilterOptions,
onSelectFilterMode: handleSelectFilterMode,
table,
})) !== null && _c !== void 0 ? _c : renderColumnFilterModeMenuItems === null || renderColumnFilterModeMenuItems === void 0 ? void 0 : renderColumnFilterModeMenuItems({
column: column,
internalFilterOptions,
onSelectFilterMode: handleSelectFilterMode,
table,
})
: renderGlobalFilterModeMenuItems === null || renderGlobalFilterModeMenuItems === void 0 ? void 0 : renderGlobalFilterModeMenuItems({
internalFilterOptions,
onSelectFilterMode: handleSelectFilterMode,
table,
}))) !== null && _d !== void 0 ? _d : internalFilterOptions.map(({ option, label, divider, symbol }, index) => (React__default.createElement(MenuItem, { divider: divider, key: index, onClick: () => handleSelectFilterMode(option), selected: option === filterOption, sx: {
alignItems: 'center',
display: 'flex',
gap: '2ch',
my: 0,
py: '6px',
}, value: option },
React__default.createElement(Box, { sx: { fontSize: '1.25rem', width: '2ch' } }, symbol),
label)))));
};
const MRT_ColumnPinningButtons = ({ column, table, }) => {
const { options: { icons: { PushPinIcon }, localization, }, } = table;
const handlePinColumn = (pinDirection) => {
column.pin(pinDirection);
};
return (React__default.createElement(Box, { sx: { minWidth: '70px', textAlign: 'center' } }, column.getIsPinned() ? (React__default.createElement(Tooltip, { arrow: true, title: localization.unpin },
React__default.createElement(IconButton, { onClick: () => handlePinColumn(false), size: "small" },
React__default.createElement(PushPinIcon, null)))) : (React__default.createElement(React__default.Fragment, null,
React__default.createElement(Tooltip, { arrow: true, title: localization.pinToLeft },
React__default.createElement(IconButton, { onClick: () => handlePinColumn('left'), size: "small" },
React__default.createElement(PushPinIcon, { style: {
transform: 'rotate(90deg)',
} }))),
React__default.createElement(Tooltip, { arrow: true, title: localization.pinToRight },
React__default.createElement(IconButton, { onClick: () => handlePinColumn('right'), size: "small" },
React__default.createElement(PushPinIcon, { style: {
transform: 'rotate(-90deg)',
} })))))));
};
const MRT_GrabHandleButton = ({ iconButtonProps, onDragEnd, onDragStart, table, }) => {
var _a;
const { options: { icons: { DragHandleIcon }, localization, }, } = table;
return (React__default.createElement(Tooltip, { arrow: true, enterDelay: 1000, enterNextDelay: 1000, placement: "top", title: (_a = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.title) !== null && _a !== void 0 ? _a : localization.move },
React__default.createElement(IconButton, Object.assign({ disableRipple: true, draggable: "true", size: "small" }, iconButtonProps, { onClick: (e) => {
var _a;
e.stopPropagation();
(_a = iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.onClick) === null || _a === void 0 ? void 0 : _a.call(iconButtonProps, e);
}, onDragStart: onDragStart, onDragEnd: onDragEnd, sx: (theme) => (Object.assign({ cursor: 'grab', m: '0 -0.1rem', opacity: 0.5, p: '2px', transition: 'all 150ms ease-in-out', '&:hover': {
backgroundColor: 'transparent',
opacity: 1,
}, '&:active': {
cursor: 'grabbing',
} }, ((iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx) instanceof Function
? iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx(theme)
: iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.sx))), title: undefined }),
React__default.createElement(DragHandleIcon, null))));
};
const MRT_ShowHideColumnsMenuItems = ({ allColumns, hoveredColumn, setHoveredColumn, column, isSubMenu, table, }) => {
var _a;
const { getState, options: { enableColumnOrdering, enableHiding, enablePinning, localization, }, setColumnOrder, } = table;
const { columnOrder } = getState();
const { columnDef } = column;
const { columnDefType } = columnDef;
const switchChecked = (columnDefType !== 'group' && column.getIsVisible()) ||
(columnDefType === 'group' &&
column.getLeafColumns().some((col) => col.getIsVisible()));
const handleToggleColumnHidden = (column) => {
var _a, _b;
if (columnDefType === 'group') {
(_b = (_a = column === null || column === void 0 ? void 0 : column.columns) === null || _a === void 0 ? void 0 : _a.forEach) === null || _b === void 0 ? void 0 : _b.call(_a, (childColumn) => {
childColumn.toggleVisibility(!switchChecked);
});
}
else {
column.toggleVisibility();
}
};
const menuItemRef = useRef(null);
const [isDragging, setIsDragging] = useState(false);
const handleDragStart = (e) => {
setIsDragging(true);
e.dataTransfer.setDragImage(menuItemRef.current, 0, 0);
};
const handleDragEnd = (_e) => {
setIsDragging(false);
setHoveredColumn(null);
if (hoveredColumn) {
setColumnOrder(reorderColumn(column, hoveredColumn, columnOrder));
}
};
const handleDragEnter = (_e) => {
if (!isDragging && columnDef.enableColumnOrdering !== false) {
setHoveredColumn(column);
}
};
return (React__default.createElement(React__default.Fragment, null,
React__default.createElement(MenuItem, { disableRipple: true, ref: menuItemRef, onDragEnter: handleDragEnter, sx: (theme) => ({
alignItems: 'center',
justifyContent: 'flex-start',
my: 0,
opacity: isDragging ? 0.5 : 1,
outlineOffset: '-2px',
outline: isDragging
? `2px dashed ${theme.palette.divider}`
: (hoveredColumn === null || hoveredColumn === void 0 ? void 0 : hoveredColumn.id) === column.id
? `2px dashed ${theme.palette.primary.main}`
: 'none',
pl: `${(column.depth + 0.5) * 2}rem`,
py: '6px',
}) },
React__default.createElement(Box, { sx: {
display: 'flex',
flexWrap: 'nowrap',
gap: '8px',
} },
!isSubMenu &&
columnDefType !== 'group' &&
enableColumnOrdering &&
!allColumns.some((col) => col.columnDef.columnDefType === 'group') &&
(columnDef.enableColumnOrdering !== false ? (React__default.createElement(MRT_GrabHandleButton, { onDragEnd: handleDragEnd, onDragStart: handleDragStart, table: table })) : (React__default.createElement(Box, { sx: { width: '28px' } }))),
!isSubMenu &&
enablePinning &&
(column.getCanPin() ? (React__default.createElement(MRT_ColumnPinningButtons, { column: column, table: table })) : (React__default.createElement(Box, { sx: { width: '70px' } }))),
enableHiding ? (React__default.createElement(FormControlLabel, { componentsProps: {
typography: {
sx: {
mb: 0,
opacity: columnDefType !== 'display' ? 1 : 0.5,
},
},
}, checked: switchChecked, control: React__default.createElement(Tooltip, { arrow: true, enterDelay: 1000, enterNextDelay: 1000, title: localization.toggleVisibility },
React__default.createElement(Switch, null)), disabled: (isSubMenu && switchChecked) || !column.getCanHide(), label: columnDef.header, onChange: () => handleToggleColumnHidden(column) })) : (React__default.createElement(Typography, { sx: { alignSelf: 'center' } }, columnDef.header)))), (_a = column.columns) === null || _a === void 0 ? void 0 :
_a.map((c, i) => (React__default.createElement(MRT_ShowHideColumnsMenuItems, { allColumns: allColumns, column: c, hoveredColumn: hoveredColumn, isSubMenu: isSubMenu, key: `${i}-${c.id}`, setHoveredColumn: setHoveredColumn, table: table })))));
};
const MRT_ShowHideColumnsMenu = ({ anchorEl, isSubMenu, setAnchorEl, table, }) => {
const { getAllColumns, getAllLeafColumns, getCenterLeafColumns, getIsAllColumnsVisible, getIsSomeColumnsPinned, getIsSomeColumnsVisible, getLeftLeafColumns, getRightLeafColumns, getState, toggleAllColumnsVisible, options: { enableColumnOrdering, enableHiding, enablePinning, localization, }, } = table;
const { density, columnOrder, columnPinning } = getState();
const hideAllColumns = () => {
getAllLeafColumns()
.filter((col) => col.columnDef.enableHiding !== false)
.forEach((col) => col.toggleVisibility(false));
};
const allColumns = useMemo(() => {
const columns = getAllColumns();
if (columnOrder.length > 0 &&
!columns.some((col) => col.columnDef.columnDefType === 'group')) {
return [
...getLeftLeafColumns(),
...Array.from(new Set(columnOrder)).map((colId) => getCenterLeafColumns().find((col) => (col === null || col === void 0 ? void 0 : col.id) === colId)),
...getRightLeafColumns(),
].filter(Boolean);
}
return columns;
}, [
columnOrder,
columnPinning,
getAllColumns(),
getCenterLeafColumns(),
getLeftLeafColumns(),
getRightLeafColumns(),
]);
const [hoveredColumn, setHoveredColumn] = useState(null);
return (React__default.createElement(Menu, { anchorEl: anchorEl, open: !!anchorEl, onClose: () => setAnchorEl(null), MenuListProps: {
dense: density === 'compact',
} },
React__default.createElement(Box, { sx: {
display: 'flex',
justifyContent: isSubMenu ? 'center' : 'space-between',
p: '0.5rem',
pt: 0,
} },
!isSubMenu && enableHiding && (React__default.createElement(Button, { disabled: !getIsSomeColumnsVisible(), onClick: hideAllColumns }, localization.hideAll)),
!isSubMenu && enableColumnOrdering && (React__default.createElement(Button, { onClick: () => table.setColumnOrder(getDefaultColumnOrderIds(table.options)) }, localization.resetOrder)),
!isSubMenu && enablePinning && (React__default.createElement(Button, { disabled: !getIsSomeColumnsPinned(), onClick: () => table.resetColumnPinning(true) }, localization.unpinAll)),
enableHiding && (React__default.createElement(Button, { disabled: getIsAllColumnsVisible(), onClick: () => toggleAllColumnsVisible(true) }, localization.showAll))),
React__default.createElement(Divider, null),
allColumns.map((column, index) => (React__default.createElement(MRT_ShowHideColumnsMenuItems, { allColumns: allColumns, column: column, hoveredColumn: hoveredColumn, isSubMenu: isSubMenu, key: `${index}-${column.id}`, setHoveredColumn: setHoveredColumn, table: table })))));
};
const commonMenuItemStyles = {
py: '6px',
my: 0,
justifyContent: 'space-between',
alignItems: 'center',
};
const commonListItemStyles = {
display: 'flex',
alignItems: 'center',
};
const MRT_ColumnActionMenu = ({ anchorEl, header, setAnchorEl, table, }) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
const { getState, toggleAllColumnsVisible, setColumnOrder, options: { columnFilterModeOptions, enableColumnFilterModes, enableColumnFilters, enableColumnResizing, enableGrouping, enableHiding, enablePinning, enableSorting, icons: { ArrowRightIcon, ClearAllIcon, ViewColumnIcon, DynamicFeedIcon, FilterListIcon, FilterListOffIcon, PushPinIcon, SortIcon, RestartAltIcon, VisibilityOffIcon, }, localization, renderColumnActionsMenuItems, }, refs: { filterInputRefs }, setColumnSizingInfo, setShowFilters, } = table;
const { column } = header;
const { columnDef } = column;
const { columnSizing, columnVisibility, density } = getState();
const [filterMenuAnchorEl, setFilterMenuAnchorEl] = useState(null);
const [showHideColumnsMenuAnchorEl, setShowHideColumnsMenuAnchorEl] = useState(null);
const handleClearSort = () => {
column.clearSorting();
setAnchorEl(null);
};
const handleSortAsc = () => {
column.toggleSorting(false);
setAnchorEl(null);
};
const handleSortDesc = () => {
column.toggleSorting(true);
setAnchorEl(null);
};
const handleResetColumnSize = () => {
setColumnSizingInfo((old) => (Object.assign(Object.assign({}, old), { isResizingColumn: false })));
column.resetSize();
setAnchorEl(null);
};
const handleHideColumn = () => {
column.toggleVisibility(false);
setAnchorEl(null);
};
const handlePinColumn = (pinDirection) => {
column.pin(pinDirection);
setAnchorEl(null);
};
const handleGroupByColumn = () => {
column.toggleGrouping();
setColumnOrder((old) => ['mrt-row-expand', ...old]);
setAnchorEl(null);
};
const handleClearFilter = () => {
column.setFilterValue('');
setAnchorEl(null);
};
const handleFilterByColumn = () => {
setShowFilters(true);
queueMicrotask(() => { var _a; return (_a = filterInputRefs.current[`${column.id}-0`]) === null || _a === void 0 ? void 0 : _a.focus(); });
setAnchorEl(null);
};
const handleShowAllColumns = () => {
toggleAllColumnsVisible(true);
setAnchorEl(null);
};
const handleOpenFilterModeMenu = (event) => {
event.stopPropagation();
setFilterMenuAnchorEl(event.currentTarget);
};
const handleOpenShowHideColumnsMenu = (event) => {
event.stopPropagation();
setShowHideColumnsMenuAnchorEl(event.currentTarget);
};
const isSelectFilter = !!columnDef.filterSelectOptions;
const allowedColumnFilterOptions = (_a = columnDef === null || columnDef === void 0 ? void 0 : columnDef.columnFilterModeOptions) !== null && _a !== void 0 ? _a : columnFilterModeOptions;
const showFilterModeSubMenu = enableColumnFilterModes &&
columnDef.enableColumnFilterModes !== false &&
!isSelectFilter &&
(allowedColumnFilterOptions === undefined ||
!!(allowedColumnFilterOptions === null || allowedColumnFilterOptions === void 0 ? void 0 : allowedColumnFilterOptions.length));
return (React__default.createElement(Menu, { anchorEl: anchorEl, open: !!anchorEl, onClose: () => setAnchorEl(null), MenuListProps: {
dense: density === 'compact',
} }, (_d = (_c = (_b = columnDef.renderColumnActionsMenuItems) === null || _b === void 0 ? void 0 : _b.call(columnDef, {
closeMenu: () => setAnchorEl(null),
column,
table,
})) !== null && _c !== void 0 ? _c : renderColumnActionsMenuItems === null || renderColumnActionsMenuItems === void 0 ? void 0 : renderColumnActionsMenuItems({
closeMenu: () => setAnchorEl(null),
column,
table,
})) !== null && _d !== void 0 ? _d : (enableSorting &&
column.getCanSort() && [
React__default.createElement(MenuItem, { disabled: !column.getIsSorted(), key: 0, onClick: handleClearSort, sx: commonMenuItemStyles },
React__default.createElement(Box, { sx: commonListItemStyles },
React__default.createElement(ListItemIcon, null,
React__default.createElement(ClearAllIcon, null)),
localization.clearSort)),
React__default.createElement(MenuItem, { disabled: column.getIsSorted() === 'asc', key: 1, onClick: handleSortAsc, sx: commonMenuItemStyles },
React__default.createElement(Box, { sx: commonListItemStyles },
React__default.createElement(ListItemIcon, null,
React__default.createElement(SortIcon, { style: { transform: 'rotate(180deg) scaleX(-1)' } })), (_e = localization.sortByColumnAsc) === null || _e === void 0 ? void 0 :
_e.replace('{column}', String(columnDef.header)))),
React__default.createElement(MenuItem, { divider: enableColumnFilters || enableGrouping || enableHiding, key: 2, disabled: column.getIsSorted() === 'desc', onClick: handleSortDesc, sx: commonMenuI