aspire-react-data-table
Version:
A simple to use declarative react based data table
2,220 lines • 104 kB
JavaScript
import * as React from 'react';
import React__default, { useState, useRef } from 'react';
import styled, { css, ThemeProvider } from 'styled-components';
import { IoFilter, IoSearchOutline, IoCloseOutline, IoEllipsisHorizontalSharp, IoCloseSharp } from 'react-icons/io5';
import merge from 'deepmerge';
import { CiViewColumn } from 'react-icons/ci';
import { MdOutlineDragIndicator } from 'react-icons/md';
var SortOrder;
(function (SortOrder) {
SortOrder["ASC"] = "asc";
SortOrder["DESC"] = "desc";
})(SortOrder || (SortOrder = {}));
function prop(obj, key) {
return obj[key];
}
function isEmpty(field = '') {
if (typeof field === 'number') {
return false;
}
return !field || field.length === 0;
}
function sort(rows, selector, direction, sortFn) {
if (!selector) {
return rows;
}
if (sortFn && typeof sortFn === 'function') {
return sortFn(rows.slice(0), selector, direction);
}
return rows.slice(0).sort((a, b) => {
const aValue = selector(a);
const bValue = selector(b);
console.log('test sort ');
if (direction === 'asc') {
if (aValue < bValue) {
return -1;
}
if (aValue > bValue) {
return 1;
}
}
if (direction === 'desc') {
if (aValue > bValue) {
return -1;
}
if (aValue < bValue) {
return 1;
}
}
return 0;
});
}
function getProperty(row, selector, format, rowIndex) {
if (!selector) {
return null;
}
if (format && typeof format === 'function') {
return format(row, rowIndex);
}
return selector(row, rowIndex);
}
function insertItem(array = [], item, index = 0) {
return [...array.slice(0, index), item, ...array.slice(index)];
}
function removeItem(array = [], item, keyField = 'id') {
const newArray = array.slice();
const outerField = prop(item, keyField);
if (outerField) {
newArray.splice(newArray.findIndex((a) => {
const innerField = prop(a, keyField);
return innerField === outerField;
}), 1);
}
else {
newArray.splice(newArray.findIndex(a => a === item), 1);
}
return newArray;
}
function decorateColumns(columns) {
return columns.map((column, index) => {
const decoratedColumn = Object.assign(Object.assign({}, column), { sortable: column.sortable || !!column.sortFunction || undefined });
if (!column.id) {
decoratedColumn.id = index + 1;
return decoratedColumn;
}
return decoratedColumn;
});
}
function getSortDirection(ascDirection = false) {
return ascDirection ? SortOrder.ASC : SortOrder.DESC;
}
function handleFunctionProps(object, ...args) {
let newObject;
Object.keys(object)
.map(o => object[o])
.forEach((value, index) => {
const oldObject = object;
if (typeof value === 'function') {
newObject = Object.assign(Object.assign({}, oldObject), { [Object.keys(object)[index]]: value(...args) });
}
});
return newObject || object;
}
function getNumberOfPages(rowCount, rowsPerPage) {
return Math.ceil(rowCount / rowsPerPage);
}
function recalculatePage(prevPage, nextPage) {
return Math.min(prevPage, nextPage);
}
const noop = () => null;
function getConditionalStyle(row, conditionalRowStyles = [], baseClassNames = []) {
let rowStyle = {};
let classNames = [...baseClassNames];
if (conditionalRowStyles.length) {
conditionalRowStyles.forEach(crs => {
if (!crs.when || typeof crs.when !== 'function') {
throw new Error('"when" must be defined in the conditional style object and must be function');
}
if (crs.when(row)) {
rowStyle = crs.style || {};
if (crs.classNames) {
classNames = [...classNames, ...crs.classNames];
}
if (typeof crs.style === 'function') {
rowStyle = crs.style(row) || {};
}
}
});
}
return { conditionalStyle: rowStyle, classNames: classNames.join(' ') };
}
function isRowSelected(row, selectedRows = [], keyField = 'id') {
const outerField = prop(row, keyField);
if (outerField) {
return selectedRows.some(r => {
const innerField = prop(r, keyField);
return innerField === outerField;
});
}
return selectedRows.some(r => r === row);
}
function isOdd(num) {
return num % 2 === 0;
}
function findColumnIndexById(columns, id) {
if (!id) {
return -1;
}
return columns.findIndex(c => {
return equalizeId(c.id, id);
});
}
function equalizeId(a, b) {
return a == b;
}
function tableReducer(state, action) {
const toggleOnSelectedRowsChange = !state.toggleOnSelectedRowsChange;
switch (action.type) {
case 'SELECT_ALL_ROWS': {
const { keyField, rows, rowCount, mergeSelections } = action;
const allChecked = !state.allSelected;
const toggleOnSelectedRowsChange = !state.toggleOnSelectedRowsChange;
if (mergeSelections) {
const selections = allChecked
? [...state.selectedRows, ...rows.filter(row => !isRowSelected(row, state.selectedRows, keyField))]
: state.selectedRows.filter(row => !isRowSelected(row, rows, keyField));
return Object.assign(Object.assign({}, state), { allSelected: allChecked, selectedCount: selections.length, selectedRows: selections, toggleOnSelectedRowsChange });
}
return Object.assign(Object.assign({}, state), { allSelected: allChecked, selectedCount: allChecked ? rowCount : 0, selectedRows: allChecked ? rows : [], toggleOnSelectedRowsChange });
}
case 'SELECT_SINGLE_ROW': {
const { keyField, row, isSelected, rowCount, singleSelect } = action;
if (singleSelect) {
if (isSelected) {
return Object.assign(Object.assign({}, state), { selectedCount: 0, allSelected: false, selectedRows: [], toggleOnSelectedRowsChange });
}
return Object.assign(Object.assign({}, state), { selectedCount: 1, allSelected: false, selectedRows: [row], toggleOnSelectedRowsChange });
}
if (isSelected) {
return Object.assign(Object.assign({}, state), { selectedCount: state.selectedRows.length > 0 ? state.selectedRows.length - 1 : 0, allSelected: false, selectedRows: removeItem(state.selectedRows, row, keyField), toggleOnSelectedRowsChange });
}
return Object.assign(Object.assign({}, state), { selectedCount: state.selectedRows.length + 1, allSelected: state.selectedRows.length + 1 === rowCount, selectedRows: insertItem(state.selectedRows, row), toggleOnSelectedRowsChange });
}
case 'SELECT_MULTIPLE_ROWS': {
const { keyField, selectedRows, totalRows, mergeSelections } = action;
if (mergeSelections) {
const selections = [
...state.selectedRows,
...selectedRows.filter(row => !isRowSelected(row, state.selectedRows, keyField)),
];
return Object.assign(Object.assign({}, state), { selectedCount: selections.length, allSelected: false, selectedRows: selections, toggleOnSelectedRowsChange });
}
return Object.assign(Object.assign({}, state), { selectedCount: selectedRows.length, allSelected: selectedRows.length === totalRows, selectedRows,
toggleOnSelectedRowsChange });
}
case 'CLEAR_SELECTED_ROWS': {
const { selectedRowsFlag } = action;
return Object.assign(Object.assign({}, state), { allSelected: false, selectedCount: 0, selectedRows: [], selectedRowsFlag });
}
case 'SORT_CHANGE': {
const { sortDirection, selectedColumn, clearSelectedOnSort } = action;
return Object.assign(Object.assign(Object.assign({}, state), { selectedColumn,
sortDirection, currentPage: 1 }), (clearSelectedOnSort && {
allSelected: false,
selectedCount: 0,
selectedRows: [],
toggleOnSelectedRowsChange,
}));
}
case 'CHANGE_PAGE': {
const { page, paginationServer, visibleOnly, persistSelectedOnPageChange } = action;
const mergeSelections = paginationServer && persistSelectedOnPageChange;
const clearSelectedOnPage = (paginationServer && !persistSelectedOnPageChange) || visibleOnly;
return Object.assign(Object.assign(Object.assign(Object.assign({}, state), { currentPage: page }), (mergeSelections && {
allSelected: false,
})), (clearSelectedOnPage && {
allSelected: false,
selectedCount: 0,
selectedRows: [],
toggleOnSelectedRowsChange,
}));
}
case 'CHANGE_ROWS_PER_PAGE': {
const { rowsPerPage, page } = action;
return Object.assign(Object.assign({}, state), { currentPage: page, rowsPerPage });
}
}
}
const disabledCSS = css `
pointer-events: none;
opacity: 0.4;
`;
const TableStyle = styled.div `
position: relative;
box-sizing: border-box;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
max-width: 100%;
${({ disabled }) => disabled && disabledCSS};
${({ theme }) => theme.table.style};
`;
const fixedCSS = css `
position: sticky;
position: -webkit-sticky; /* Safari */
top: 0;
z-index: 1;
`;
const Head = styled.div `
display: flex;
width: 100%;
${({ $fixedHeader }) => $fixedHeader && fixedCSS};
${({ theme }) => theme.head.style};
`;
const HeadRow = styled.div `
display: flex;
align-items: stretch;
width: 100%;
${({ theme }) => theme.headRow.style};
${({ $dense, theme }) => $dense && theme.headRow.denseStyle};
`;
const SMALL = 599;
const MEDIUM = 959;
const LARGE = 1280;
const media = {
sm: (literals, ...args) => css `
@media screen and (max-width: ${SMALL}px) {
${css(literals, ...args)}
}
`,
md: (literals, ...args) => css `
@media screen and (max-width: ${MEDIUM}px) {
${css(literals, ...args)}
}
`,
lg: (literals, ...args) => css `
@media screen and (max-width: ${LARGE}px) {
${css(literals, ...args)}
}
`,
custom: (value) => (literals, ...args) => css `
@media screen and (max-width: ${value}px) {
${css(literals, ...args)}
}
`,
};
const CellBase = styled.div `
position: relative;
display: flex;
align-items: center;
box-sizing: border-box;
line-height: normal;
${({ theme, $headCell }) => theme[$headCell ? 'headCells' : 'cells'].style};
${({ $noPadding }) => $noPadding && 'padding: 0'};
`;
const CellExtended = styled(CellBase) `
flex-grow: ${({ button, grow }) => (grow === 0 || button ? 0 : grow || 1)};
flex-shrink: 0;
flex-basis: 0;
max-width: ${({ maxWidth }) => maxWidth || '100%'};
min-width: ${({ minWidth }) => minWidth || '110px'};
${({ width }) => width &&
css `
min-width: ${width};
max-width: ${width};
`};
${({ right }) => right && 'justify-content: flex-end'};
${({ button, center }) => (center || button) && 'justify-content: center'};
${({ compact, button }) => (compact || button) && 'padding: 0'};
/* handle hiding cells */
${({ hide }) => hide &&
hide === 'sm' &&
media.sm `
display: none;
`};
${({ hide }) => hide &&
hide === 'md' &&
media.md `
display: none;
`};
${({ hide }) => hide &&
hide === 'lg' &&
media.lg `
display: none;
`};
${({ hide }) => hide &&
Number.isInteger(hide) &&
media.custom(hide) `
display: none;
`};
`;
const overflowCSS = css `
div:first-child {
white-space: ${({ $wrapCell }) => ($wrapCell ? 'normal' : 'nowrap')};
overflow: ${({ $allowOverflow }) => ($allowOverflow ? 'visible' : 'hidden')};
text-overflow: ellipsis;
}
`;
const CellStyle = styled(CellExtended).attrs(props => ({
style: props.style,
})) `
${({ $renderAsCell }) => !$renderAsCell && overflowCSS};
${({ theme, $isDragging }) => $isDragging && theme.cells.draggingStyle};
${({ $cellStyle }) => $cellStyle};
`;
function Cell({ id, column, row, rowIndex, dataTag, isDragging, onDragStart, onDragOver, onDragEnd, onDragEnter, onDragLeave, }) {
const { conditionalStyle, classNames } = getConditionalStyle(row, column.conditionalCellStyles, ['rdt_TableCell']);
const [showTooltip, setShowTooltip] = React.useState(false);
const cellContentRef = React.useRef(null);
React.useEffect(() => {
if (cellContentRef.current) {
setShowTooltip(cellContentRef.current.scrollWidth > cellContentRef.current.clientWidth);
}
}, []);
return (React.createElement(CellStyle, { id: id, "data-column-id": column.id, role: "cell", className: classNames, "data-tag": dataTag, "$cellStyle": column.style, "$renderAsCell": !!column.cell, "$allowOverflow": column.allowOverflow, button: column.button, center: column.center, compact: column.compact, grow: column.grow, hide: column.hide, maxWidth: column.maxWidth, minWidth: column.minWidth, right: column.right, width: column.width, "$wrapCell": column.wrap, style: conditionalStyle, "$isDragging": isDragging, onDragStart: onDragStart, onDragOver: onDragOver, onDragEnd: onDragEnd, onDragEnter: onDragEnter, onDragLeave: onDragLeave },
!column.cell && (React.createElement("div", { ref: cellContentRef, "data-tag": dataTag, title: showTooltip ? String(getProperty(row, column.selector, column.format, rowIndex)) : undefined }, getProperty(row, column.selector, column.format, rowIndex))),
column.cell && column.cell(row, rowIndex, column, id)));
}
var TableCell = React.memo(Cell);
const defaultComponentName = 'input';
const calculateBaseStyle = (disabled) => (Object.assign(Object.assign({ fontSize: '18px' }, (!disabled && { cursor: 'pointer' })), { padding: 0, marginTop: '1px', verticalAlign: 'middle', position: 'relative' }));
function Checkbox({ name, component = defaultComponentName, componentOptions = { style: {} }, indeterminate = false, checked = false, disabled = false, onClick = noop, }) {
const setCheckboxRef = (checkbox) => {
if (checkbox) {
checkbox.indeterminate = indeterminate;
}
};
const TagName = component;
const baseStyle = TagName !== defaultComponentName ? componentOptions.style : calculateBaseStyle(disabled);
const resolvedComponentOptions = React.useMemo(() => handleFunctionProps(componentOptions, indeterminate), [componentOptions, indeterminate]);
return (React.createElement(TagName, Object.assign({ type: "checkbox", ref: setCheckboxRef, style: baseStyle, onClick: disabled ? noop : onClick, name: name, "aria-label": name, checked: checked, disabled: disabled }, resolvedComponentOptions, { onChange: noop })));
}
var Checkbox$1 = React.memo(Checkbox);
const TableCellCheckboxStyle = styled(CellBase) `
flex: 0 0 48px;
min-width: 48px;
justify-content: center;
align-items: center;
user-select: none;
white-space: nowrap;
`;
function TableCellCheckbox({ name, keyField, row, rowCount, selected, selectableRowsComponent, selectableRowsComponentProps, selectableRowsSingle, selectableRowDisabled, onSelectedRow, }) {
const disabled = !!(selectableRowDisabled && selectableRowDisabled(row));
const handleOnRowSelected = () => {
onSelectedRow({
type: 'SELECT_SINGLE_ROW',
row,
isSelected: selected,
keyField,
rowCount,
singleSelect: selectableRowsSingle,
});
};
return (React.createElement(TableCellCheckboxStyle, { onClick: (e) => e.stopPropagation(), className: "rdt_TableCell", "$noPadding": true },
React.createElement(Checkbox$1, { name: name, component: selectableRowsComponent, componentOptions: selectableRowsComponentProps, checked: selected, "aria-checked": selected, onClick: handleOnRowSelected, disabled: disabled })));
}
const ButtonStyle = styled.button `
display: inline-flex;
align-items: center;
user-select: none;
white-space: nowrap;
border: none;
background-color: transparent;
${({ theme }) => theme.expanderButton.style};
`;
function ExpanderButton({ disabled = false, expanded = false, expandableIcon, id, row, onToggled, }) {
const icon = expanded ? expandableIcon.expanded : expandableIcon.collapsed;
const handleToggle = () => onToggled && onToggled(row);
return (React.createElement(ButtonStyle, { "aria-disabled": disabled, onClick: handleToggle, "data-testid": `expander-button-${id}`, disabled: disabled, "aria-label": expanded ? 'Collapse Row' : 'Expand Row', role: "button", type: "button" }, icon));
}
const CellExpanderStyle = styled(CellBase) `
white-space: nowrap;
font-weight: 400;
min-width: 48px;
${({ theme }) => theme.expanderCell.style};
`;
function CellExpander({ row, expanded = false, expandableIcon, id, onToggled, disabled = false, }) {
return (React.createElement(CellExpanderStyle, { onClick: (e) => e.stopPropagation(), "$noPadding": true },
React.createElement(ExpanderButton, { id: id, row: row, expanded: expanded, expandableIcon: expandableIcon, disabled: disabled, onToggled: onToggled })));
}
const ExpanderRowStyle = styled.div `
width: 100%;
box-sizing: border-box;
${({ theme }) => theme.expanderRow.style};
${({ $extendedRowStyle }) => $extendedRowStyle};
`;
function ExpanderRow({ data, ExpanderComponent, expanderComponentProps, extendedRowStyle, extendedClassNames, }) {
const classNamesSplit = extendedClassNames.split(' ').filter(c => c !== 'rdt_TableRow');
const classNames = ['rdt_ExpanderRow', ...classNamesSplit].join(' ');
return (React.createElement(ExpanderRowStyle, { className: classNames, "$extendedRowStyle": extendedRowStyle },
React.createElement(ExpanderComponent, Object.assign({ data: data }, expanderComponentProps))));
}
var ExpanderRow$1 = React.memo(ExpanderRow);
const STOP_PROP_TAG = 'allowRowEvents';
var Direction;
(function (Direction) {
Direction["LTR"] = "ltr";
Direction["RTL"] = "rtl";
Direction["AUTO"] = "auto";
})(Direction || (Direction = {}));
var Alignment;
(function (Alignment) {
Alignment["LEFT"] = "left";
Alignment["RIGHT"] = "right";
Alignment["CENTER"] = "center";
})(Alignment || (Alignment = {}));
var Media;
(function (Media) {
Media["SM"] = "sm";
Media["MD"] = "md";
Media["LG"] = "lg";
})(Media || (Media = {}));
const highlightCSS = css `
&:hover {
${({ $highlightOnHover, theme }) => $highlightOnHover && theme.rows.highlightOnHoverStyle};
}
`;
const pointerCSS = css `
&:hover {
cursor: pointer;
}
`;
const TableRowStyle = styled.div.attrs(props => ({
style: props.style,
})) `
display: flex;
align-items: stretch;
align-content: stretch;
width: 100%;
box-sizing: border-box;
${({ theme }) => theme.rows.style};
${({ $dense, theme }) => $dense && theme.rows.denseStyle};
${({ $striped, theme }) => $striped && theme.rows.stripedStyle};
${({ $highlightOnHover }) => $highlightOnHover && highlightCSS};
${({ $pointerOnHover }) => $pointerOnHover && pointerCSS};
${({ $selected, theme }) => $selected && theme.rows.selectedHighlightStyle};
${({ $conditionalStyle }) => $conditionalStyle};
${({ $highlighted, theme }) => {
var _a;
return $highlighted && css `
background-color: ${((_a = theme.rows.highlightStyle) === null || _a === void 0 ? void 0 : _a.backgroundColor) || '#e3f2fd'};
`;
}}
`;
function Row({ columns = [], conditionalRowStyles = [], defaultExpanded = false, defaultExpanderDisabled = false, dense = false, expandableIcon, expandableRows = false, expandableRowsComponent, expandableRowsComponentProps, expandableRowsHideExpander, expandOnRowClicked = false, expandOnRowDoubleClicked = false, highlightOnHover = false, id, expandableInheritConditionalStyles, keyField, onRowClicked = noop, onRowDoubleClicked = noop, onRowMouseEnter = noop, onRowMouseLeave = noop, onRowExpandToggled = noop, onSelectedRow = noop, pointerOnHover = false, row, rowCount, rowIndex, selectableRowDisabled = null, selectableRows = false, selectableRowsComponent, selectableRowsComponentProps, selectableRowsHighlight = false, selectableRowsSingle = false, selected, striped = false, draggingColumnId, onDragStart, onDragOver, onDragEnd, onDragEnter, onDragLeave, selectRowFunction, highlighted = false, }) {
const [expanded, setExpanded] = React.useState(defaultExpanded);
React.useEffect(() => {
setExpanded(defaultExpanded);
}, [defaultExpanded]);
const handleExpanded = React.useCallback(() => {
setExpanded(!expanded);
onRowExpandToggled(!expanded, row);
}, [expanded, onRowExpandToggled, row]);
const showPointer = pointerOnHover || (expandableRows && (expandOnRowClicked || expandOnRowDoubleClicked));
const handleRowClick = React.useCallback((e) => {
const target = e.target;
if (target.getAttribute('data-tag') === STOP_PROP_TAG) {
onRowClicked(row, e);
if (!defaultExpanderDisabled && expandableRows && expandOnRowClicked) {
handleExpanded();
}
if (selectRowFunction) {
selectRowFunction(row, e);
}
}
}, [defaultExpanderDisabled, expandOnRowClicked, expandableRows, handleExpanded, onRowClicked, row, selectRowFunction]);
const handleRowDoubleClick = React.useCallback((e) => {
const target = e.target;
if (target.getAttribute('data-tag') === STOP_PROP_TAG) {
onRowDoubleClicked(row, e);
if (!defaultExpanderDisabled && expandableRows && expandOnRowDoubleClicked) {
handleExpanded();
}
}
}, [defaultExpanderDisabled, expandOnRowDoubleClicked, expandableRows, handleExpanded, onRowDoubleClicked, row]);
const handleRowMouseEnter = React.useCallback((e) => {
onRowMouseEnter(row, e);
}, [onRowMouseEnter, row]);
const handleRowMouseLeave = React.useCallback((e) => {
onRowMouseLeave(row, e);
}, [onRowMouseLeave, row]);
const rowKeyField = prop(row, keyField);
const { conditionalStyle, classNames } = getConditionalStyle(row, conditionalRowStyles, ['rdt_TableRow']);
const highlightSelected = selectableRowsHighlight && selected;
const inheritStyles = expandableInheritConditionalStyles ? conditionalStyle : {};
const isStriped = striped && isOdd(rowIndex);
React.useEffect(() => {
if (highlighted) {
console.log('highlighted', highlighted);
}
}, [highlighted]);
return (React.createElement(React.Fragment, null,
React.createElement(TableRowStyle, { id: `row-${id}`, role: "row", "$striped": isStriped, "$highlightOnHover": highlightOnHover, "$pointerOnHover": !defaultExpanderDisabled && showPointer, "$dense": dense, onClick: handleRowClick, onDoubleClick: handleRowDoubleClick, onMouseEnter: handleRowMouseEnter, onMouseLeave: handleRowMouseLeave, className: classNames, "$selected": highlightSelected, "$conditionalStyle": conditionalStyle, "$highlighted": highlighted },
selectableRows && (React.createElement(TableCellCheckbox, { name: `select-row-${rowKeyField}`, keyField: keyField, row: row, rowCount: rowCount, selected: selected, selectableRowsComponent: selectableRowsComponent, selectableRowsComponentProps: selectableRowsComponentProps, selectableRowDisabled: selectableRowDisabled, selectableRowsSingle: selectableRowsSingle, onSelectedRow: onSelectedRow })),
expandableRows && !expandableRowsHideExpander && (React.createElement(CellExpander, { id: rowKeyField, expandableIcon: expandableIcon, expanded: expanded, row: row, onToggled: handleExpanded, disabled: defaultExpanderDisabled })),
columns.map((column, index) => {
if (column.omit) {
return null;
}
if (column.isHidden)
return null;
return (React.createElement(TableCell, { id: `cell-${column.id}-${rowKeyField}`, key: `cell-${column.id}-${rowKeyField}`, dataTag: column.ignoreRowClick || column.button ? null : STOP_PROP_TAG, column: column, row: row, rowIndex: rowIndex, isDragging: equalizeId(draggingColumnId, column.id), onDragStart: onDragStart, onDragOver: onDragOver, onDragEnd: onDragEnd, onDragEnter: onDragEnter, onDragLeave: onDragLeave, "data-last-cell": index === columns.length - 1 }));
})),
expandableRows && expanded && (React.createElement(ExpanderRow$1, { key: `expander-${rowKeyField}`, data: row, extendedRowStyle: inheritStyles, extendedClassNames: classNames, ExpanderComponent: expandableRowsComponent, expanderComponentProps: expandableRowsComponentProps }))));
}
const Icon = styled.span `
padding: 2px;
color: inherit;
flex-grow: 0;
flex-shrink: 0;
${({ $sortActive }) => ($sortActive ? 'opacity: 1' : 'opacity: 0')};
${({ $sortDirection }) => $sortDirection === 'desc' && 'transform: rotate(180deg)'};
`;
const NativeSortIcon = ({ sortActive, sortDirection }) => (React__default.createElement(Icon, { "$sortActive": sortActive, "$sortDirection": sortDirection }, "\u25B2"));
const ColumnStyled = styled(CellExtended) `
${({ button }) => button && 'text-align: center'};
${({ theme, $isDragging }) => $isDragging && theme.headCells.draggingStyle};
`;
const sortableCSS = css `
span.__rdt_custom_sort_icon__ {
i,
svg {
transform: 'translate3d(0, 0, 0)';
${({ $sortActive }) => ($sortActive ? 'opacity: 1' : 'opacity: 0')};
color: inherit;
font-size: 10px;
height: 10px;
width: 10px;
backface-visibility: hidden;
transform-style: preserve-3d;
transition-duration: 95ms;
transition-property: transform;
}
&.asc i,
&.asc svg {
transform: rotate(180deg);
}
}
${({ $sortActive }) => !$sortActive &&
css `
&:hover,
&:focus {
opacity: 0.7;
span,
span.__rdt_custom_sort_icon__ * {
opacity: 0.7;
}
}
`};
`;
const ColumnSortable = styled.div `
display: inline-flex;
align-items: center;
justify-content: inherit;
height: 100%;
width: 100%;
outline: none;
user-select: none;
overflow: hidden;
${({ disabled }) => !disabled && sortableCSS};
`;
const ColumnText = styled.div `
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
`;
const IconBtn = styled.button `
background-color: transparent;
border: none;
cursor: pointer;
margin-left: 5px;
margin-right: 5px;
`;
function TableCol({ column, disabled, draggingColumnId, selectedColumn = {
identifier: '',
isHidden: undefined
}, sortDirection, sortIcon, sortServer, pagination, paginationServer, persistSelectedOnSort, selectableRowsVisibleOnly, onSort, onDragStart, onDragOver, onDragEnd, onDragEnter, onDragLeave, showFilter, showFilterList }) {
React.useEffect(() => {
if (typeof column.selector === 'string') {
console.error(`Warning: ${column.selector} is a string based column selector which has been deprecated as of v7 and will be removed in v8. Instead, use a selector function e.g. row => row[field]...`);
}
}, []);
const [showTooltip, setShowTooltip] = React.useState(false);
const columnRef = React.useRef(null);
React.useEffect(() => {
if (columnRef.current) {
setShowTooltip(columnRef.current.scrollWidth > columnRef.current.clientWidth);
}
}, [showTooltip]);
if (column.omit) {
return null;
}
const handleSortChange = () => {
if (!column.sortable && !column.selector) {
return;
}
let direction = sortDirection;
if (equalizeId(selectedColumn.id, column.id)) {
direction = sortDirection === SortOrder.DESC ? SortOrder.ASC : SortOrder.DESC;
}
onSort({
type: 'SORT_CHANGE',
sortDirection: direction,
selectedColumn: column,
clearSelectedOnSort: (pagination && paginationServer && !persistSelectedOnSort) || sortServer || selectableRowsVisibleOnly,
});
};
const handleKeyPress = (event) => {
if (event.key === 'Enter') {
handleSortChange();
}
};
const renderNativeSortIcon = (sortActive, onClick) => (React.createElement(IconBtn, { onClick: onClick },
React.createElement(NativeSortIcon, { sortActive: sortActive, sortDirection: sortDirection })));
const renderCustomSortIcon = (onClick) => (React.createElement(IconBtn, { onClick: onClick, style: { margin: '1px' } },
React.createElement("span", { className: [sortDirection, '__rdt_custom_sort_icon__'].join(' ') }, sortIcon)));
const sortActive = !!(column.sortable && equalizeId(selectedColumn.id, column.id));
const disableSort = !column.sortable || disabled;
const nativeSortIconLeft = column.sortable && !sortIcon && !column.right;
const nativeSortIconRight = column.sortable && !sortIcon && column.right;
const customSortIconLeft = column.sortable && sortIcon && !column.right;
const customSortIconRight = column.sortable && sortIcon && column.right;
return (React.createElement(ColumnStyled, { "data-column-id": column.id, className: "rdt_TableCol", "$headCell": true, allowOverflow: column.allowOverflow, button: column.button, compact: column.compact, grow: column.grow, hide: column.hide, maxWidth: column.maxWidth, minWidth: column.minWidth, right: column.right, center: column.center, width: column.width, draggable: column.reorder, "$isDragging": equalizeId(column.id, draggingColumnId), onDragStart: onDragStart, onDragOver: onDragOver, onDragEnd: onDragEnd, onDragEnter: onDragEnter, onDragLeave: onDragLeave }, column.name && (React.createElement(ColumnSortable, { "data-column-id": column.id, "data-sort-id": column.id, role: "columnheader", tabIndex: 0, className: "rdt_TableCol_Sortable", onKeyPress: !disableSort ? handleKeyPress : undefined, "$sortActive": !disableSort && sortActive, disabled: disableSort },
React.createElement("div", { style: { display: 'flex', justifyContent: "space-between", width: "100%" } },
!disableSort && customSortIconRight && renderCustomSortIcon(!disableSort ? handleSortChange : null),
!disableSort && nativeSortIconRight && renderNativeSortIcon(sortActive, !disableSort ? handleSortChange : null),
React.createElement("div", { style: { display: 'flex', justifyContent: "space-between" } },
typeof column.name === 'string' ? (React.createElement(ColumnText, { title: showTooltip ? column.name : undefined, ref: columnRef, "data-column-id": column.id }, column.name)) : (column.name),
(showFilter && column.identifier && column.identifier != 'actions') && React.createElement(IconBtn, { onClick: (e) => { showFilterList(e, column.identifier); } },
React.createElement(IoFilter, null))),
!disableSort && customSortIconLeft && renderCustomSortIcon(!disableSort ? handleSortChange : null),
!disableSort && nativeSortIconLeft && renderNativeSortIcon(sortActive, !disableSort ? handleSortChange : null))))));
}
var Column = React.memo(TableCol);
const ColumnStyle = styled(CellBase) `
flex: 0 0 48px;
justify-content: center;
align-items: center;
user-select: none;
white-space: nowrap;
font-size: unset;
`;
function ColumnCheckbox({ headCell = true, rowData, keyField, allSelected, mergeSelections, selectedRows, selectableRowsComponent, selectableRowsComponentProps, selectableRowDisabled, onSelectAllRows, }) {
const indeterminate = selectedRows.length > 0 && !allSelected;
const rows = selectableRowDisabled ? rowData.filter((row) => !selectableRowDisabled(row)) : rowData;
const isDisabled = rows.length === 0;
const rowCount = Math.min(rowData.length, rows.length);
const handleSelectAll = () => {
onSelectAllRows({
type: 'SELECT_ALL_ROWS',
rows,
rowCount,
mergeSelections,
keyField,
});
};
return (React.createElement(ColumnStyle, { className: "rdt_TableCol", "$headCell": headCell, "$noPadding": true },
React.createElement(Checkbox$1, { name: "select-all-rows", component: selectableRowsComponent, componentOptions: selectableRowsComponentProps, onClick: handleSelectAll, checked: allSelected, indeterminate: indeterminate, disabled: isDisabled })));
}
function useRTL(direction = Direction.AUTO) {
const isClient = typeof window === 'object';
const [isRTL, setIsRTL] = React.useState(false);
React.useEffect(() => {
if (!isClient) {
return;
}
if (direction === 'auto') {
const canUse = !!(window.document && window.document.createElement);
const bodyRTL = document.getElementsByTagName('BODY')[0];
const htmlTRL = document.getElementsByTagName('HTML')[0];
const hasRTL = bodyRTL.dir === 'rtl' || htmlTRL.dir === 'rtl';
setIsRTL(canUse && hasRTL);
return;
}
setIsRTL(direction === 'rtl');
}, [direction, isClient]);
return isRTL;
}
const Title$1 = styled.div `
display: flex;
align-items: center;
flex: 1 0 auto;
height: 100%;
color: ${({ theme }) => theme.contextMenu.fontColor};
font-size: ${({ theme }) => theme.contextMenu.fontSize};
font-weight: 400;
`;
const ContextActions = styled.div `
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
`;
const ContextMenuStyle = styled.div `
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-sizing: inherit;
z-index: 1;
align-items: center;
justify-content: space-between;
display: flex;
${({ $rtl }) => $rtl && 'direction: rtl'};
${({ theme }) => theme.contextMenu.style};
${({ theme, $visible }) => $visible && theme.contextMenu.activeStyle};
`;
const generateDefaultContextTitle = (contextMessage, selectedCount, rtl) => {
if (selectedCount === 0) {
return null;
}
const datumName = selectedCount === 1 ? contextMessage.singular : contextMessage.plural;
if (rtl) {
return `${selectedCount} ${contextMessage.message || ''} ${datumName}`;
}
return `${selectedCount} ${datumName} ${contextMessage.message || ''}`;
};
function ContextMenu({ contextMessage, contextActions, contextComponent, selectedCount, direction, }) {
const isRTL = useRTL(direction);
const visible = selectedCount > 0;
if (contextComponent) {
return (React.createElement(ContextMenuStyle, { "$visible": visible }, React.cloneElement(contextComponent, { selectedCount })));
}
return (React.createElement(ContextMenuStyle, { "$visible": visible, "$rtl": isRTL },
React.createElement(Title$1, null, generateDefaultContextTitle(contextMessage, selectedCount, isRTL)),
React.createElement(ContextActions, null, contextActions)));
}
const HeaderStyle = styled.div `
position: relative;
box-sizing: border-box;
overflow: hidden;
display: flex;
flex: 1 1 auto;
align-items: center;
justify-content: space-between;
width: 100%;
flex-wrap: wrap;
${({ theme }) => theme.header.style}
`;
const Title = styled.div `
flex: 1 0 auto;
color: ${({ theme }) => theme.header.fontColor};
font-size: ${({ theme }) => theme.header.fontSize};
font-weight: 400;
`;
const Actions = styled.div `
flex: 1 0 auto;
display: flex;
align-items: center;
justify-content: flex-end;
> * {
margin-left: 5px;
}
`;
const Header = ({ title, actions = null, contextMessage, contextActions, contextComponent, selectedCount, direction, showMenu = true, }) => (React.createElement(HeaderStyle, { className: "rdt_TableHeader", role: "heading", "aria-level": 1 },
React.createElement(Title, null, title),
actions && React.createElement(Actions, null, actions),
showMenu && (React.createElement(ContextMenu, { contextMessage: contextMessage, contextActions: contextActions, contextComponent: contextComponent, direction: direction, selectedCount: selectedCount }))));
/******************************************************************************
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 alignMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
};
const SubheaderWrapper = styled.header `
position: relative;
display: flex;
flex: 1 1 auto;
box-sizing: border-box;
align-items: center;
padding: 4px 16px 4px 24px;
width: 100%;
justify-content: ${({ align }) => alignMap[align]};
flex-wrap: ${({ $wrapContent }) => ($wrapContent ? 'wrap' : 'nowrap')};
${({ theme }) => theme.subHeader.style}
`;
const Subheader = (_a) => {
var { align = 'right', wrapContent = true } = _a, rest = __rest(_a, ["align", "wrapContent"]);
return (React.createElement(SubheaderWrapper, Object.assign({ align: align, "$wrapContent": wrapContent }, rest)));
};
const Body = styled.div `
display: flex;
flex-direction: column;
`;
const ResponsiveWrapper = styled.div `
position: relative;
width: 100%;
border-radius: inherit;
${({ $responsive, $fixedHeader }) => $responsive &&
css `
overflow-x: auto;
// hidden prevents vertical scrolling in firefox when fixedHeader is disabled
overflow-y: ${$fixedHeader ? 'auto' : 'hidden'};
min-height: 0;
`};
${({ $fixedHeader = false, $fixedHeaderScrollHeight = '100vh' }) => $fixedHeader &&
css `
max-height: ${$fixedHeaderScrollHeight};
-webkit-overflow-scrolling: touch;
`};
${({ theme }) => theme.responsiveWrapper.style};
`;
const ProgressWrapper = styled.div `
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
${props => props.theme.progress.style};
`;
const Wrapper = styled.div `
position: relative;
width: 100%;
${({ theme }) => theme.tableWrapper.style};
`;
const ColumnExpander = styled(CellBase) `
white-space: nowrap;
${({ theme }) => theme.expanderCell.style};
`;
const NoDataWrapper = styled.div `
box-sizing: border-box;
width: 100%;
height: 100%;
${({ theme }) => theme.noData.style};
`;
const DropdownIcon = () => (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24" },
React__default.createElement("path", { d: "M7 10l5 5 5-5z" }),
React__default.createElement("path", { d: "M0 0h24v24H0z", fill: "none" })));
const SelectControl = styled.select `
cursor: pointer;
height: 24px;
max-width: 100%;
user-select: none;
padding-left: 8px;
padding-right: 24px;
box-sizing: content-box;
font-size: inherit;
color: inherit;
border: none;
background-color: transparent;
appearance: none;
direction: ltr;
flex-shrink: 0;
&::-ms-expand {
display: none;
}
&:disabled::-ms-expand {
background: #f60;
}
option {
color: initial;
}
`;
const SelectWrapper = styled.div `
position: relative;
flex-shrink: 0;
font-size: inherit;
color: inherit;
margin-top: 1px;
svg {
top: 0;
right: 0;
color: inherit;
position: absolute;
fill: currentColor;
width: 24px;
height: 24px;
display: inline-block;
user-select: none;
pointer-events: none;
}
`;
const Select = (_a) => {
var { defaultValue, onChange } = _a, rest = __rest(_a, ["defaultValue", "onChange"]);
return (React.createElement(SelectWrapper, null,
React.createElement(SelectControl, Object.assign({ onChange: onChange, defaultValue: defaultValue }, rest)),
React.createElement(DropdownIcon, null)));
};
const useWindowSize = () => {
const isClient = typeof window === 'object';
function getSize() {
return {
width: isClient ? window.innerWidth : undefined,
height: isClient ? window.innerHeight : undefined,
};
}
const [windowSize, setWindowSize] = React.useState(getSize);
React.useEffect(() => {
if (!isClient) {
return () => null;
}
function handleResize() {
setWindowSize(getSize());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowSize;
};
const FirstPage = () => (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", "aria-hidden": "true", role: "presentation" },
React__default.createElement("path", { d: "M18.41 16.59L13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z" }),
React__default.createElement("path", { fill: "none", d: "M24 24H0V0h24v24z" })));
const LastPage = () => (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", "aria-hidden": "true", role: "presentation" },
React__default.createElement("path", { d: "M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z" }),
React__default.createElement("path", { fill: "none", d: "M0 0h24v24H0V0z" })));
const Left = () => (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", "aria-hidden": "true", role: "presentation" },
React__default.createElement("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }),
React__default.createElement("path", { d: "M0 0h24v24H0z", fill: "none" })));
const Right = () => (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", "aria-hidden": "true", role: "presentation" },
React__default.createElement("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }),
React__default.createElement("path", { d: "M0 0h24v24H0z", fill: "none" })));
const ExpanderCollapsedIcon = () => (React__default.createElement("svg", { fill: "currentColor", height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg" },
React__default.createElement("path", { d: "M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z" }),
React__default.createElement("path", { d: "M0-.25h24v24H0z", fill: "none" })));
const ExpanderExpandedIcon = () => (React__default.createElement("svg", { fill: "currentColor", height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg" },
React__default.createElement("path", { d: "M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z" }),
React__default.createElement("path", { d: "M0-.75h24v24H0z", fill: "none" })));
const defaultProps = {
columns: [],
data: [],
title: '',
keyField: 'id',
selectableRows: false,
selectableRowsHighlight: false,
selectableRowsNoSelectAll: false,
selectableRowSelected: null,
selectableRowDisabled: null,
selectableRowsComponent: 'input',
selectableRowsComponentProps: {},
selectableRowsVisibleOnly: false,
selectableRowsSingle: false,
clearSelectedRows: false,
expandableRows: false,
expandableRowDisabled: null,
expandableRowExpanded: null,
expandOnRowClicked: false,
expandableRowsHideExpander: false,
expandOnRowDoubleClicked: false,
expandableInheritConditionalStyles: false,
expandableRowsComponent: function DefaultExpander() {
return (React__default.createElement("div", null,
"To add an expander pass in a component instance via ",
React__default.createElement("strong", null, "expandableRowsComponent"),
". You can then access props.data from this component."));
},
expandableIcon: {
collapsed: React__default.createElement(ExpanderCollapsedIcon, null),
expanded: React__default.createElement(ExpanderExpandedIcon, null),
},
expandableRowsComponentProps: {},
progressPending: false,
progressComponent: React__default.createElement("div", { style: { fontSize: '24px', fontWeight: 700, padding: '24px' } }, "Loading..."),
persistTableHead: false,
sortIcon: null,
sortFunction: null,
sortServer: false,
striped: false,
highlightOnHover: false,
pointerOnHover: false,
noContextMenu: false,
contextMessage: { singular: 'item', plural: 'items', message: 'selected' },
actions: null,
contextActions: null,
contextComponent: null,
defaultSortFieldId: null,
defaultSortAsc: true,
responsive: true,
noDataComponent: React__default.createElement("div", { style: { padding: '24px' } }, "There are no records to display"),
disabled: false,
noTableHead: false,
noHeader: false,
subHeader: false,
subHeaderAlign: Alignment.RIGHT,
subHeaderWrap: true,
subHeaderComponent: null,
fixedHeader: false,
fixedHeaderScrollHeight: '100vh',
pagination: false,
paginationServer: false,
paginationServerOptions: {
persistSelectedOnSort: false,
persistSelectedOnPageChange: false,
},
paginationDefaultPage: 1,
paginationResetDefaultPage: false,
paginationTotalRows: 0,
paginationPerPage: 10,
paginationRowsPerPageOptions: [10, 15, 20, 25, 30],
paginationComponent: null,
paginationComponentOptions: {},
paginationIconFirstPage: React__default.createElement(FirstPage, null),
paginationIconLastPage: React__default.createElement(LastPage, null),
paginationIconNext: React__default.createElement(Right, null),
paginationIconPrevious: React__default.createElement(Left, null),
dense: false,
conditionalRowStyles: [],
theme: 'default',
customStyles: {},
direction: Direction.AUTO,
onChangePage: noop,
onChangeRowsPerPage: noop,
onRowClicked: noop,
onRowDoubleClicked: noop,
onRowMouseEnter: noop,
onRowMouseLeave: noop,
onRowExpandToggled: noop,
onSelectedRowsChange: noop,
onSort: noop,
onColumnOrderChange: noop,
};
const defaultComponentOptions = {
rowsPerPageText: 'Rows per page:',
rangeSeparatorText: 'of',
noRowsPerPage: false,
selectAllRowsItem: false,
selectAllRowsItemText: 'All',
};
const PaginationWrapper = styled.nav `
display: flex;
flex: 1 1 auto;
justify-content: flex-end;
align-items: center;
box-sizing: border-box;
padding-right: 8px;
padding-left: 8px;
width: 100%;
${({ theme }) => theme.pagination.style};
`;
const Button = styled.button `
position: relative;
display: block;
user-select: none;
border: none;
${({ theme }) => theme.pagination.pageButtonsStyle};
${({ $isRTL }) => $isRTL && 'transform: scale(-1, -1)'};
`;
const PageList = styled.div `
display: flex;
align-items: center;
border-radius: 4px;
white-space: nowrap;
${media.sm `
width: 100%;
justify-content: space-around;
`};
`;
const Span = styled.span `
flex-shrink: 1;
user-select: none;
`;
const Range = styled(Span) `
margin: 0 24px;
`;
const RowLabel = styled(Span) `
margin: 0 4px;
`;
function Pagination({ rowsPerPage, rowCount, currentPage, direction = defaultProps.direction, paginationRowsPerPageOptions = defaultProps.paginationRowsPerPageOptions, paginationIconLastPage = defaultProps.paginationIconLastPage, paginationIconFirstPage = defaultProps.paginationIconFirstPage, paginationIconNext = defaultProps.paginationIconNext, paginationIconPrevious = defaultProps.paginationIconPrevious, paginationComponentOptions = defaultProps.paginationComponentOptions, onChangeRowsPerPage = defaultProps.onChangeRowsPerPage, onChangePage = defaultProps.onChangePage, }) {
const windowSize = useWindowSize();
const isRTL = useRTL(direction);
const shouldShow = windowSize.width && windowSize.width > SMALL;
const numPages = getNumberOfPages(rowCount, rowsPerPage);
const lastIndex = currentPage * rowsPerPage;
const firstIndex = lastIndex - rowsPerPage + 1;
const disabledLesser = currentPage === 1;
const disabledGreater = currentPage === numPages;
const options = Object.assign(Object.assign({}, defaultComponentOptions), paginationComponentOptions);
const range = currentPage === numPages
? `${firstIndex}-${rowCount} ${options.rangeSeparatorText} ${rowCount}`
: `${firstIndex}-${lastIndex} ${options.rangeSeparatorText} ${rowCount}`;
const handlePrevious = React.useCallback(() => onChangePage(currentPage - 1), [currentPage, onChangePage]);
const handleNext = React.useCallback(() => onChangePage(currentPage + 1), [currentPage, onChangePage]);
const handleFirst = React.useCallback(() => onChangePage(1), [onChangePage]);
const handleLast = React.useCallback(() => onChangePage(getNumberOfPages(rowCount, rowsPerPage)), [onChangePage, rowCount, rowsPerPage]);
const handleRowsPerPage = React.useCallback((e) => onChangeRowsPerPage(Number(e.target.value), currentPage), [currentPage, onChangeRowsPerPage]);
const selectOptions = paginationRowsPerPageOptions.map((num) => (React.createElement("option", { key: num, value: num }, num)));
if (options.selectAllRowsItem) {
selectOptions.push(React.createElement("option", { key: -1, value: rowCount }, options.selectAllRowsItemText));
}
const select = (React.createElement(Select, { onChange: handleRowsPerPage, defaultValue: rowsPerPage, "aria-label": options.rowsPerPageText }, selectOptions));
return (React.createElement(PaginationWrapper, { className: "rdt_Pagination" },
!options.noRowsPerPage && shouldShow && (React.createElement(React.Fragment, null,
React.createElement(RowLabel, null, options.rowsPerPageText),
select)),
shouldShow && React.createElement(Range, null, range),
React.createElement(PageList, null,
React.createElement(Button, { id: "pagination-first-page", type: "button", "aria-label": "First Page", "aria-disabled": disabledLesser, onClick: handleFirst, disabled: disabledLesser, "$isRTL": isRTL }, paginationIconFirstPage),
React.createElement(Button, { id: "pagination-previous-page", type: "button", "aria-label": "Previous Page", "aria-disabled": disabledLesser, onClick: handlePrevious, disabled: disabledLesser, "$isRTL": isRTL }, paginationIconPrevious),
!options.noRowsPerPage && !shouldShow && select,
React.createElement(Button, { id: "pagination-next-page", type: "button", "aria-label": "Next Page", "aria-disabled": disabledGreater, onClick: handleNext, disabled: disabledGreater, "$isRTL": isRTL }, paginationIconNext),
React.createElement(Button, { id: "pagination-last-page", type: "button", "aria-label": "Last Page", "aria-disabled": disabledGreater, onClick: handleLast, disabled: disabledGreater, "$isRTL": isRTL }, paginationIconLastPage))));
}
var NativePagination = React.memo(Pagination);
const useFirstUpdate = (fn, inputs) => {
const firstUpdate = React.useRef(true);
React.useEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
fn();
}, inputs);
};
const defaultTheme = {
text: {
primary: 'rgba(0, 0, 0, 0.87)',
secondary: 'rgba(0, 0, 0, 0.54)',
disabled: 'rgba(0, 0, 0, 0.38)',
},
background: {
default: '#FFFFFF',
},
context: {
background: '#e3f2fd',
text: 'rgba(0, 0, 0, 0.87)',
},
divider: {
default: 'rgba(0,0,0,.12)',
},
button: {
default: 'rgba(0,0,0,.54)',
focus: 'rgba(0,0,0,.12)',
hover: 'rgba(0,0,0,.12)',
disabled: 'rgba(0, 0, 0, .18)',
},
selected: {
default: '#e3f2fd',
text: 'rgba(0, 0, 0, 0.87)',
},
highlightOnHover: {
default: '#EEEEEE',
text: 'rgba(0, 0, 0, 0.87)',
},
striped: {
default: '#FAFAFA',
text: 'rgba(0, 0, 0, 0.87)',
},
};
const defaultThemes = {
default: defaultTheme,
light: defaultTheme,
dark: {
text: {
primary: '#FFFFFF',
secondary: 'rgba(255, 255, 255, 0.7)',
disabled: 'rgba(0,0,0,.12)',
},
background: {
default: '#424242',
},
context: {
background: '#E91E63',
text: '#FFFFFF',
},
divider: {
default: 'rgba(81, 81, 81, 1)',
},
button: {
default: '#FFFFFF',
focus: 'rgba(255, 255, 255, .54)',
hover: 'rgba(255, 255, 255, .12)',
disabled: 'rgba(255, 255, 255, .18)',
},
selected: {
default: 'rgba(0, 0, 0, .7)',
text: '#FFFFFF',
},
highlightOnHover: {
default: 'rgba(0, 0, 0, .7)',
text: '#FFFFFF',
},
striped: {
default: 'rgba(0, 0, 0, .87)',
text: '#FFFFFF',
},
},
};
function createTheme(name = 'default', customTheme, inherit = 'default') {
if (!defaultThemes[name]) {
defaultThemes[name] = merge(defaultThemes[inherit], customTheme || {});
}
defaultThemes[name] = merge(defaultThemes[name], customTheme || {});
return defaultThemes[name];
}
const defaultStyles = (theme) => ({
table: {
style: {
color: theme.text.primary,
backgroundColor: theme.background.default,
},
},
tableWrapper: {
style: {
display: 'table',
},
},
responsiveWrapper: {
style: {},
},
header: {
style: {
fontSize: '22px',
color: theme.text.primary,
backgroundColor: theme.background.default,
minHeight: '56px',
paddingLeft: '16px',
paddingRight: '8px',
},
},
subHeader: {
style: {
backgroundColor: theme.background.default,
minHeight: '52px',
},
},
head: {
style: {
color: theme.text.primary,
fontSize: '12px',
fontWeight: 500,
},
},
headRow: {
style: {
backgroundColor: theme.background.default,
minHeight: '52px',
borderBottomWidth: '1px',
borderBottomColor: theme.divider.default,
borderBottomStyle: 'solid',
},
denseStyle: {
minHeight: '32px',
},
},
headCells: {
style: {
paddingLeft: '16px',
paddingRight: '16px',
},
draggingStyle: {
cursor: 'move',
},
},
contextMenu: {
style: {
backgroundColor: theme.context.background,
fontSize: '18px',
fontWeight: 400,
color: theme.context.text,
paddingLeft: '16px',
paddingRight: '8px',
transform: 'translate3d(0, -100%, 0)',
transitionDuration: '125ms',
transitionTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)',
willChange: 'transform',
},
activeStyle: {
transform: 'translate3d(0, 0, 0)',
},
},
cells: {
style: {
paddingLeft: '16px',
paddingRight: '16px',
wordBreak: 'break-word',
},
draggingStyle: {},
},
rows: {
style: {
fontSize: '13px',
fontWeight: 400,
color: theme.text.primary,
backgroundColor: theme.background.default,
minHeight: '48px',
'&:not(:last-of-type)': {
borderBottomStyle: 'solid',
borderBottomWidth: '1px',
borderBottomColor: theme.divider.default,
},
},
denseStyle: {
minHeight: '32px',
},
selectedHighlightStyle: {
'&:nth-of-type(n)': {
color: theme.selected.text,
backgroundColor: theme.selected.default,
borderBottomColor: theme.background.default,
},
},
highlightOnHoverStyle: {
color: theme.highlightOnHover.text,
backgroundColor: theme.highlightOnHover.default,
transitionDuration: '0.15s',
transitionProperty: 'background-color',
borderBottomColor: theme.background.default,
outlineStyle: 'solid',
outlineWidth: '1px',
outlineColor: theme.background.default,
},
stripedStyle: {
color: theme.striped.text,
backgroundColor: theme.striped.default,
},
},
expanderRow: {
style: {
color: theme.text.primary,
backgroundColor: theme.background.default,
},
},
expanderCell: {
style: {
flex: '0 0 48px',
},
},
expanderButton: {
style: {
color: theme.button.default,
fill: theme.button.default,
backgroundColor: 'transparent',
borderRadius: '2px',
transition: '0.25s',
height: '100%',
width: '100%',
'&:hover:enabled': {
cursor: 'pointer',
},
'&:disabled': {
color: theme.button.disabled,
},
'&:hover:not(:disabled)': {
cursor: 'pointer',
backgroundColor: theme.button.hover,
},
'&:focus': {
outline: 'none',
backgroundColor: theme.button.focus,
},
svg: {
margin: 'auto',
},
},
},
pagination: {
style: {
color: theme.text.secondary,
fontSize: '13px',
minHeight: '56px',
backgroundColor: theme.background.default,
borderTopStyle: 'solid',
borderTopWidth: '1px',
borderTopColor: theme.divider.default,
},
pageButtonsStyle: {
borderRadius: '50%',
height: '40px',
width: '40px',
padding: '8px',
margin: 'px',
cursor: 'pointer',
transition: '0.4s',
color: theme.button.default,
fill: theme.button.default,
backgroundColor: 'transparent',
'&:disabled': {
cursor: 'unset',
color: theme.button.disabled,
fill: theme.button.disabled,
},
'&:hover:not(:disabled)': {
backgroundColor: theme.button.hover,
},
'&:focus': {
outline: 'none',
backgroundColor: theme.button.focus,
},
},
},
noData: {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: theme.text.primary,
backgroundColor: theme.background.default,
},
},
progress: {
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: theme.text.primary,
backgroundColor: theme.background.default,
},
},
});
const createStyles = (customStyles = {}, themeName = 'default', inherit = 'default') => {
const themeType = defaultThemes[themeName] ? themeName : inherit;
return merge(defaultStyles(defaultThemes[themeType]), customStyles);
};
function useColumns(columns, onColumnOrderChange, defaultSortFieldId, defaultSortAsc) {
const [tableColumns, setTableColumns] = React.useState(() => decorateColumns(columns));
const [draggingColumnId, setDraggingColumn] = React.useState('');
const sourceColumnId = React.useRef('');
useFirstUpdate(() => {
setTableColumns(decorateColumns(columns));
}, [columns]);
const handleDragStart = React.useCallback((e) => {
var _a, _b, _c;
const { attributes } = e.target;
const id = (_a = attributes.getNamedItem('data-column-id')) === null || _a === void 0 ? void 0 : _a.value;
if (id) {
sourceColumnId.current = ((_c = (_b = tableColumns[findColumnIndexById(tableColumns, id)]) === null || _b === void 0 ? void 0 : _b.id) === null || _c === void 0 ? void 0 : _c.toString()) || '';
setDraggingColumn(sourceColumnId.current);
}
}, [tableColumns]);
const handleDragEnter = React.useCallback((e) => {
var _a;
const { attributes } = e.target;
const id = (_a = attributes.getNamedItem('data-column-id')) === null || _a === void 0 ? void 0 : _a.value;
if (id && sourceColumnId.current && id !== sourceColumnId.current) {
const selectedColIndex = findColumnIndexById(tableColumns, sourceColumnId.current);
const targetColIndex = findColumnIndexById(tableColumns, id);
const reorderedCols = [...tableColumns];
reorderedCols[selectedColIndex] = tableColumns[targetColIndex];
reorderedCols[targetColIndex] = tableColumns[selectedColIndex];
setTableColumns(reorderedCols);
onColumnOrderChange(reorderedCols);
}
}, [onColumnOrderChange, tableColumns]);
const handleDragOver = React.useCallback((e) => {
e.preventDefault();
}, []);
const handleDragLeave = React.useCallback((e) => {
e.preventDefault();
}, []);
const handleDragEnd = React.useCallback((e) => {
e.preventDefault();
sourceColumnId.current = '';
setDraggingColumn('');
}, []);
const defaultSortDirection = getSortDirection(defaultSortAsc);
const defaultSortColumn = React.useMemo(() => tableColumns[findColumnIndexById(tableColumns, defaultSortFieldId === null || defaultSortFieldId === void 0 ? void 0 : defaultSortFieldId.toString())] || {}, [defaultSortFieldId, tableColumns]);
return {
tableColumns,
draggingColumnId,
handleDragStart,
handleDragEnter,
handleDragOver,
handleDragLeave,
handleDragEnd,
defaultSortDirection,
defaultSortColumn,
};
}
const ActionsMenu = ({ position, theme, actions, rowData }) => {
const actionsBoxStyle = {
width: 'auto',
height: 'auto',
position: 'absolute',
padding: '10px',
borderRadius: '12px',
gap: '5px',
boxShadow: '0px 4px 3px rgba(0, 0, 0, 0.2)',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
backgroundColor: theme.table.style.backgroundColor,
left: `${position === null || position === void 0 ? void 0 : position.x}px`,
top: `${position === null || position === void 0 ? void 0 : position.y}px`,
zIndex: 1,
};
const actionButton = {
backgroundColor: 'transparent',
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
gap: '10px',
minWidth: '125px',
padding: '6px 12px 6px 12px',
borderRadius: '8px',
border: '1px solid #efefef',
cursor: 'pointer',
};
return (React__default.createElement("div", { id: "actionsBox", style: actionsBoxStyle }, actions.map((action, index) => (React__default.createElement("button", { key: index, onClick: () => action.onClick(rowData), style: actionButton },
React__default.createElement(action.icon),
React__default.createElement("span", null, action.name))))));
};
function SearchComponent(props) {
const { filterText, onFilter, wrapperStyle } = props;
return (React__default.createElement("div", { style: Object.assign(Object.assign({}, (wrapperStyle ? wrapperStyle : {
border: '1px solid #E2E8F0',
width: '300px',
borderRadius: '8px',
})), { display: 'flex', alignItems: 'center', alignContent: 'center', gap: '2px', padding: '10px', margin: '2px' }) },
React__default.createElement("div", { style: { display: 'flex', justifyContent: "center", alignItems: "center" } },
React__default.createElement(IoSearchOutline, null)),
React__default.createElement("input", { id: "search", type: "text", placeholder: "Search", value: filterText, onChange: onFilter, style: {
width: '200px',
border: 'none',
outline: 'none',
backgroundColor: 'transparent'
} })));
}
const ListStyledDiv = styled.div `
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
background-color: #f1f1f1;
}
&::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: #555;
}
`;
const ColumnFilterList = ({ position, listData, handleFilteredData, selectedFilterList, theme, }) => {
const listStyle = {
width: '250px',
maxHeight: '200px',
position: 'absolute',
overflow: 'auto',
padding: '10px',
borderRadius: '12px',
gap: '5px',
boxShadow: '0px 4px 3px rgba(0, 0, 0, 0.2)',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
backgroundColor: theme.table.style.backgroundColor,
left: `${position === null || position === void 0 ? void 0 : position.x}px`,
top: `${position === null || position === void 0 ? void 0 : position.y}px`,
};
const checkboxStyle = {
accentColor: theme.expanderButton.style.color,
};
const [selectedFilter, setSelectedFilter] = useState(selectedFilterList || []);
const [availableValues, setAvailableValues] = useState(listData.filter((item) => !selectedFilter.includes(item)));
const handleFilter = (event) => {
const searchText = event.target.value;
const filteredData = listData.filter((item) => item.toLowerCase().includes(searchText.toLowerCase()));
setAvailableValues(filteredData.filter((item) => !selectedFilter.includes(item)));
};
const handleAvailableValueCheck = (value) => {
setSelectedFilter((prevState) => {
const newFilter = [...prevState, value];
setAvailableValues((prevAvailableValues) => prevAvailableValues.filter((item) => item !== value));
handleFilteredData(newFilter);
return newFilter;
});
};
const handleSelectedValueUncheck = (value) => {
setSelectedFilter((prevState) => {
const newFilter = prevState.filter((item) => item !== value);
setAvailableValues((prevAvailableValues) => [...prevAvailableValues, value]);
handleFilteredData(newFilter);
return newFilter;
});
};
const selectAll = () => {
setSelectedFilter(listData);
setAvailableValues([]);
handleFilteredData(listData);
};
return (React__default.createElement(ListStyledDiv, { style: listStyle, id: "filterBox" },
React__default.createElement("input", { type: "text", onChange: handleFilter, placeholder: "Search", style: { padding: '5px', border: '1px solid #E2E8F0', borderRadius: '8px', backgroundColor: 'transparent' } }),
React__default.createElement("div", { id: "selectedValues" }, selectedFilter.map((value, index) => (React__default.createElement("div", { key: index, style: { display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: '2px' } },
React__default.createElement("input", { type: "checkbox", onChange: () => handleSelectedValueUncheck(value), checked: true, style: checkboxStyle }),
value.length > 20 ? value.substring(0, 20) + '...' : value)))),
React__default.createElement("hr", { style: { borderColor: '#f7f7f7', margin: '0px 0px' } }),
React__default.createElement("div", { id: "availableValues" },
React__default.createElement("button", { onClick: selectAll, style: {
border: "1px solid", borderColor: theme.expanderButton.style.color, backgroundColor: theme.table.style.backgroundColor,
width: '100%', borderRadius: '5px', cursor: 'pointer', color: theme.expanderButton.style.color,
margin: '5px 0px',
padding: '5px 0px',
fontWeight: 'bold'
} }, " Select All"),
availableValues.map((value, index) => (React__default.createElement("div", { key: index, style: {
display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: '10px',
width: '100%',
margin: ' 5px',
} },
React__default.createElement("input", { type: "checkbox", onChange: () => handleAvailableValueCheck(value), style: checkboxStyle }),
value.length > 20 ? value.substring(0, 20) + '...' : value))))));
};
const ColumnSelector = ({ theme, closeModal, handleColumnSelector, columns }) => {
const [columnList, setColumnList] = useState(columns);
const dragItem = useRef(null);
const dragOverItem = useRef(null);
const [isDragging, setIsDragging] = useState(false);
const selectorStyle = {
position: 'relative',
backgroundColor: theme.table.style.backgroundColor,
padding: '20px',
borderRadius: '8px',
overflowY: 'auto',
overflowX: 'hidden',
};
const wrapperStyle = {
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 2
};
const closeButtonStyle = {
position: 'absolute',
top: '10px',
right: '10px',
cursor: 'pointer',
};
const checkboxStyle = {
accentColor: theme.expanderButton.style.color,
};
const getItemStyle = (index) => ({
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
userSelect: 'none',
padding: 7,
margin: '0 0 8px 0',
color: 'black',
borderRadius: '8px',
border: '1px solid #E2E8F0',
cursor: 'move',
background: isDragging && dragOverItem.current === index ? 'lightblue' : 'white',
opacity: isDragging && dragItem.current === index ? 0.5 : 1,
transform: isDragging && dragItem.current === index ? 'scale(1.05)' : 'scale(1)',
transition: 'transform 0.2s, opacity 0.2s, background-color 0.2s',
});
const handleDragStart = (e, index) => {
dragItem.current = index;
setIsDragging(true);
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', e.currentTarget.innerHTML);
const dragImage = e.currentTarget;
e.dataTransfer.setDragImage(dragImage, 20, 20);
};
const handleDragEnter = (e, index) => {
e.preventDefault();
dragOverItem.current = index;
};
const handleDragOver = (e) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
};
const handleDragEnd = () => {
if (dragItem.current !== null && dragOverItem.current !== null) {
const newColumnList = [...columnList];
const draggedItemContent = newColumnList[dragItem.current];
newColumnList.splice(dragItem.current, 1);
newColumnList.splice(dragOverItem.current, 0, draggedItemContent);
setColumnList(newColumnList);
}
dragItem.current = null;
dragOverItem.current = null;
setIsDragging(false);
};
const handleCheckboxChange = (index) => {
const newColumnList = columnList.map((column, i) => {
if (i === index) {
return Object.assign(Object.assign({}, column), { isHidden: !column.isHidden });
}
return column;
});
setColumnList(newColumnList);
};
return (React__default.createElement("div", { id: "selector-wrapper", style: wrapperStyle },
React__default.createElement("div", { style: selectorStyle, id: "columnSelector" },
React__default.createElement("div", { style: closeButtonStyle, onClick: closeModal },
React__default.createElement(IoCloseOutline, { size: 24, color: theme.expanderButton.style.color })),
React__default.createElement("h3", { style: { fontWeight: 'bold' } }, "Columns"),
React__default.createElement("div", { style: { padding: 4, width: 250 } }, columnList.map((column, index) => (React__default.createElement("div", { key: column.identifier, draggable: true, onDragStart: (e) => handleDragStart(e, index), onDragEnter: (e) => handleDragEnter(e, index), onDragOver: handleDragOver, onDragEnd: handleDragEnd, style: getItemStyle(index) },
React__default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 3 } },
React__default.createElement("input", { type: "checkbox", onChange: () => handleCheckboxChange(index), checked: !column.isHidden, style: checkboxStyle }),
column.name),
React__default.createElement(MdOutlineDragIndicator, null))))),
React__default.createElement("div", { style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: '20px'
} },
React__default.createElement("button", { onClick: () => {
handleColumnSelector(columnList);
closeModal();
}, style: {
border: '1px solid',
backgroundColor: theme.expanderButton.style.color,
width: '30%',
borderRadius: '5px',
cursor: 'pointer',
color: '#fff',
fontWeight: 'bold',
padding: '5px 0px'
} }, "Save"),
React__default.createElement("button", { onClick: closeModal, style: {
border: '1px solid',
borderColor: theme.expanderButton.style.color,
backgroundColor: theme.table.style.backgroundColor,
width: '30%',
borderRadius: '5px',
cursor: 'pointer',
color: theme.expanderButton.style.color,
fontWeight: 'bold',
padding: '5px 0px'
} }, "Cancel")))));
};
function DataTable(props) {
var _a;
const { data = defaultProps.data, columns = defaultProps.columns, title = defaultProps.title, actions = defaultProps.actions, keyField = defaultProps.keyField, striped = defaultProps.striped, highlightOnHover = defaultProps.highlightOnHover, pointerOnHover = defaultProps.pointerOnHover, dense = defaultProps.dense, selectableRows = defaultProps.selectableRows, selectableRowsSingle = defaultProps.selectableRowsSingle, selectableRowsHighlight = defaultProps.selectableRowsHighlight, selectableRowsNoSelectAll = defaultProps.selectableRowsNoSelectAll, selectableRowsVisibleOnly = defaultProps.selectableRowsVisibleOnly, selectableRowSelected = defaultProps.selectableRowSelected, selectableRowDisabled = defaultProps.selectableRowDisabled, selectableRowsComponent = defaultProps.selectableRowsComponent, selectableRowsComponentProps = defaultProps.selectableRowsComponentProps, onRowExpandToggled = defaultProps.onRowExpandToggled, onSelectedRowsChange = defaultProps.onSelectedRowsChange, expandableIcon = defaultProps.expandableIcon, onChangeRowsPerPage = defaultProps.onChangeRowsPerPage, onChangePage = defaultProps.onChangePage, paginationServer = defaultProps.paginationServer, paginationServerOptions = defaultProps.paginationServerOptions, paginationTotalRows = defaultProps.paginationTotalRows, paginationDefaultPage = defaultProps.paginationDefaultPage, paginationResetDefaultPage = defaultProps.paginationResetDefaultPage, paginationPerPage = defaultProps.paginationPerPage, paginationRowsPerPageOptions = defaultProps.paginationRowsPerPageOptions, paginationIconLastPage = defaultProps.paginationIconLastPage, paginationIconFirstPage = defaultProps.paginationIconFirstPage, paginationIconNext = defaultProps.paginationIconNext, paginationIconPrevious = defaultProps.paginationIconPrevious, paginationComponent = defaultProps.paginationComponent, paginationComponentOptions = defaultProps.paginationComponentOptions, responsive = defaultProps.responsive, progressPending = defaultProps.progressPending, progressComponent = defaultProps.progressComponent, persistTableHead = defaultProps.persistTableHead, noDataComponent = defaultProps.noDataComponent, disabled = defaultProps.disabled, noTableHead = defaultProps.noTableHead, noHeader = defaultProps.noHeader, fixedHeader = defaultProps.fixedHeader, fixedHeaderScrollHeight = defaultProps.fixedHeaderScrollHeight, pagination = defaultProps.pagination, subHeader = defaultProps.subHeader, subHeaderAlign = defaultProps.subHeaderAlign, subHeaderWrap = defaultProps.subHeaderWrap, subHeaderComponent = defaultProps.subHeaderComponent, noContextMenu = defaultProps.noContextMenu, contextMessage = defaultProps.contextMessage, contextActions = defaultProps.contextActions, contextComponent = defaultProps.contextComponent, expandableRows = defaultProps.expandableRows, onRowClicked = defaultProps.onRowClicked, onRowDoubleClicked = defaultProps.onRowDoubleClicked, onRowMouseEnter = defaultProps.onRowMouseEnter, onRowMouseLeave = defaultProps.onRowMouseLeave, sortIcon = defaultProps.sortIcon, onSort = defaultProps.onSort, sortFunction = defaultProps.sortFunction, sortServer = defaultProps.sortServer, expandableRowsComponent = defaultProps.expandableRowsComponent, expandableRowsComponentProps = defaultProps.expandableRowsComponentProps, expandableRowDisabled = defaultProps.expandableRowDisabled, expandableRowsHideExpander = defaultProps.expandableRowsHideExpander, expandOnRowClicked = defaultProps.expandOnRowClicked, expandOnRowDoubleClicked = defaultProps.expandOnRowDoubleClicked, expandableRowExpanded = defaultProps.expandableRowExpanded, expandableInheritConditionalStyles = defaultProps.expandableInheritConditionalStyles, defaultSortFieldId = defaultProps.defaultSortFieldId, defaultSortAsc = defaultProps.defaultSortAsc, clearSelectedRows = defaultProps.clearSelectedRows, conditionalRowStyles = defaultProps.conditionalRowStyles, theme = defaultProps.theme, customStyles = defaultProps.customStyles, direction = defaultProps.direction, onColumnOrderChange = defaultProps.onColumnOrderChange, className, showActions, showSearch, searchComponentStyle, actionsIcon, showFilter, mainComtainerId = '', showColumnSelector = false, propActions = [], selectRowFunction } = props;
const { tableColumns, draggingColumnId, handleDragStart, handleDragEnter, handleDragOver, handleDragLeave, handleDragEnd, defaultSortDirection, defaultSortColumn, } = useColumns(columns, onColumnOrderChange, defaultSortFieldId, defaultSortAsc);
const [{ rowsPerPage, currentPage, selectedRows, allSelected, selectedCount, selectedColumn, sortDirection, toggleOnSelectedRowsChange, }, dispatch,] = React.useReducer(tableReducer, {
allSelected: false,
selectedCount: 0,
selectedRows: [],
selectedColumn: defaultSortColumn,
toggleOnSelectedRowsChange: false,
sortDirection: defaultSortDirection,
currentPage: paginationDefaultPage,
rowsPerPage: paginationPerPage,
selectedRowsFlag: false,
contextMessage: defaultProps.contextMessage,
});
const [filterText, setFilterText] = React.useState('');
const [filters, setFilters] = React.useState([]);
const [columnSelectorOpen, setIsColumnSelectorOpen] = React.useState(false);
const { persistSelectedOnSort = false, persistSelectedOnPageChange = false } = paginationServerOptions;
const mergeSelections = !!(paginationServer && (persistSelectedOnPageChange || persistSelectedOnSort));
const enabledPagination = pagination && !progressPending && data.length > 0;
const Pagination = paginationComponent || NativePagination;
const [highlightedRowId, setHighlightedRowId] = React.useState(null);
const currentTheme = React.useMemo(() => createStyles(customStyles, theme), [customStyles, theme]);
const wrapperProps = React.useMemo(() => (Object.assign({}, (direction !== 'auto' && { dir: direction }))), [direction]);
const sortedData = React.useMemo(() => {
if (sortServer) {
return data;
}
if ((selectedColumn === null || selectedColumn === void 0 ? void 0 : selectedColumn.sortFunction) && typeof selectedColumn.sortFunction === 'function') {
const sortFn = selectedColumn.sortFunction;
const customSortFunction = sortDirection === SortOrder.ASC ? sortFn : (a, b) => sortFn(a, b) * -1;
return [...data].sort(customSortFunction);
}
return sort(data, selectedColumn === null || selectedColumn === void 0 ? void 0 : selectedColumn.selector, sortDirection, sortFunction);
}, [sortServer, selectedColumn, sortDirection, data, sortFunction]);
const tableRows = React.useMemo(() => {
let filtered = null;
if (filterText && filterText != '') {
filtered = sortedData.filter(item => JSON.stringify(item)
.toLowerCase()
.indexOf(filterText.toLowerCase()) !== -1);
}
if (pagination && !paginationServer) {
const lastIndex = currentPage * rowsPerPage;
const firstIndex = lastIndex - rowsPerPage;
let tableData = filtered != null && filtered.length > 0 ? filtered : sortedData;
if (filters && filters.length > 0) {
let filteredData = tableData.filter((item) => {
return filters.every(filter => {
const columnValue = item[filter.columnName];
const filterValues = filter.filterText;
if (filterValues === undefined || filterValues.length === 0) {
return true;
}
return filterValues.includes(columnValue);
});
});
return filteredData.length > 0 ? filteredData.slice(firstIndex, lastIndex) : [];
}
else {
return tableData.slice(firstIndex, lastIndex);
}
}
if (filtered != null && filtered.length > 0) {
return filtered;
}
else {
return sortedData;
}
}, [currentPage, pagination, paginationServer, rowsPerPage, sortedData, filterText, filters]);
const handleSort = React.useCallback((action) => {
dispatch(action);
}, []);
const handleSelectAllRows = React.useCallback((action) => {
dispatch(action);
}, []);
const handleSelectedRow = React.useCallback((action) => {
dispatch(action);
}, []);
const handleRowClicked = React.useCallback((row, e) => {
onRowClicked(row, e);
if (selectRowFunction) {
const rowId = prop(row, keyField);
if (rowId !== undefined && rowId !== null) {
if (typeof rowId === 'string' || typeof rowId === 'number' || rowId === null) {
setHighlightedRowId(rowId);
}
else {
console.error('Invalid rowId type:', typeof rowId);
}
selectRowFunction(row, e);
}
else {
console.error('Failed to extract rowId. Row:', row, 'keyField:', keyField);
}
}
}, [onRowClicked, selectRowFunction, keyField]);
const handleRowDoubleClicked = React.useCallback((row, e) => onRowDoubleClicked(row, e), [onRowDoubleClicked]);
const handleRowMouseEnter = React.useCallback((row, e) => onRowMouseEnter(row, e), [onRowMouseEnter]);
const handleRowMouseLeave = React.useCallback((row, e) => onRowMouseLeave(row, e), [onRowMouseLeave]);
const handleChangePage = React.useCallback((page) => dispatch({
type: 'CHANGE_PAGE',
page,
paginationServer,
visibleOnly: selectableRowsVisibleOnly,
persistSelectedOnPageChange,
}), [paginationServer, persistSelectedOnPageChange, selectableRowsVisibleOnly]);
const handleChangeRowsPerPage = React.useCallback((newRowsPerPage) => {
const rowCount = paginationTotalRows || tableRows.length;
const updatedPage = getNumberOfPages(rowCount, newRowsPerPage);
const recalculatedPage = recalculatePage(currentPage, updatedPage);
if (!paginationServer) {
handleChangePage(recalculatedPage);
}
dispatch({ type: 'CHANGE_ROWS_PER_PAGE', page: recalculatedPage, rowsPerPage: newRowsPerPage });
}, [currentPage, handleChangePage, paginationServer, paginationTotalRows, tableRows.length]);
const showTableHead = () => {
if (noTableHead) {
return false;
}
if (persistTableHead) {
return true;
}
return sortedData.length > 0 && !progressPending;
};
const showHeader = () => {
if (noHeader) {
return false;
}
if (title) {
return true;
}
if (actions) {
return true;
}
return false;
};
if (pagination && !paginationServer && sortedData.length > 0 && tableRows.length === 0) {
const updatedPage = getNumberOfPages(sortedData.length, rowsPerPage);
const recalculatedPage = recalculatePage(currentPage, updatedPage);
handleChangePage(recalculatedPage);
}
useFirstUpdate(() => {
onSelectedRowsChange({ allSelected, selectedCount, selectedRows: selectedRows.slice(0) });
}, [toggleOnSelectedRowsChange]);
useFirstUpdate(() => {
onSort(selectedColumn, sortDirection, sortedData.slice(0));
}, [selectedColumn, sortDirection]);
useFirstUpdate(() => {
onChangePage(currentPage, paginationTotalRows || sortedData.length);
}, [currentPage]);
useFirstUpdate(() => {
onChangeRowsPerPage(rowsPerPage, currentPage);
}, [rowsPerPage]);
useFirstUpdate(() => {
handleChangePage(paginationDefaultPage);
}, [paginationDefaultPage, paginationResetDefaultPage]);
useFirstUpdate(() => {
if (pagination && paginationServer && paginationTotalRows > 0) {
const updatedPage = getNumberOfPages(paginationTotalRows, rowsPerPage);
const recalculatedPage = recalculatePage(currentPage, updatedPage);
if (currentPage !== recalculatedPage) {
handleChangePage(recalculatedPage);
}
}
}, [paginationTotalRows]);
React.useEffect(() => {
dispatch({ type: 'CLEAR_SELECTED_ROWS', selectedRowsFlag: clearSelectedRows });
}, [selectableRowsSingle, clearSelectedRows]);
React.useEffect(() => {
if (!selectableRowSelected) {
return;
}
const preSelectedRows = sortedData.filter(row => selectableRowSelected(row));
const selected = selectableRowsSingle ? preSelectedRows.slice(0, 1) : preSelectedRows;
dispatch({
type: 'SELECT_MULTIPLE_ROWS',
keyField,
selectedRows: selected,
totalRows: sortedData.length,
mergeSelections,
});
}, [data, selectableRowSelected]);
const visibleRows = selectableRowsVisibleOnly ? tableRows : sortedData;
const showSelectAll = persistSelectedOnPageChange || selectableRowsSingle || selectableRowsNoSelectAll;
const [customTableColumns, setCustomTableColumns] = React.useState(tableColumns);
const [showActionsColumn, setShowActionsColumn] = React.useState(showActions);
const [showActionMenu, setShowActionMenu] = React.useState(false);
const [position, setPosition] = React.useState({ x: 0, y: 0 });
const [showFilterMenu, setShowFilterMenu] = React.useState(false);
const [filterListData, setFilterListData] = React.useState([]);
const [selectedFilterColumn, setSelectedFilterColumn] = React.useState('');
const [selectedFilterList, setSelectedFilterList] = React.useState([]);
const [selectedRow, setSelectedRow] = React.useState(null);
const handleShowActions = (event, row) => {
const x = event.clientX;
const y = event.clientY;
setPosition({ x, y });
setSelectedRow(row);
setShowActionMenu(true);
};
React.useEffect(() => {
if (showActionsColumn) {
const columns = [
...tableColumns,
{
name: 'Actions',
cell: (row) => (React.createElement("button", { style: { background: 'transparent', border: 'none' }, onClick: (e) => handleShowActions(e, row) }, actionsIcon ? actionsIcon : React.createElement(IoEllipsisHorizontalSharp, null))),
with: '10px',
wrap: false,
identifier: 'actions',
isHidden: false
}
];
setCustomTableColumns(columns);
setShowActionsColumn(false);
}
}, []);
React.useEffect(() => {
const scrollableElement = mainComtainerId == '' ? document : document.getElementById(mainComtainerId);
const handleScroll = () => {
hideMenus();
};
if (scrollableElement) {
scrollableElement.addEventListener('scroll', handleScroll);
}
return () => {
if (scrollableElement) {
scrollableElement.removeEventListener('scroll', handleScroll);
}
};
}, []);
const hideMenus = () => {
setShowActionMenu(false);
setShowFilterMenu(false);
};
const handleClickOutside = (event) => {
let targetElement = event.target;
do {
if (targetElement.id && (targetElement.id.includes('actionsBox') || targetElement.id.includes('filterBox'))) {
return;
}
targetElement = targetElement.parentNode;
} while (targetElement);
hideMenus();
};
React.useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
document.addEventListener("touchstart", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
document.removeEventListener("touchstart", handleClickOutside);
};
}, []);
function extractField(array, fieldName) {
const uniqueValues = new Set();
array.forEach((item) => {
uniqueValues.add(item[fieldName]);
});
return Array.from(uniqueValues);
}
const getSelectedFilter = (columnName) => {
const filter = filters.find((filter) => filter.columnName === columnName);
if (filter) {
return filter.filterText;
}
return [];
};
const handleFilterClick = (event, identifier) => {
const x = event.clientX;
const y = event.clientY;
setPosition({ x, y });
setShowFilterMenu(true);
const fieldValues = extractField(data, identifier);
setFilterListData(fieldValues);
setSelectedFilterColumn(identifier);
setSelectedFilterList(getSelectedFilter(identifier));
};
const handleFilteredData = (selectedFilters) => {
const newFilter = {
columnName: selectedFilterColumn,
filterText: selectedFilters,
};
const existingFilterIndex = filters.findIndex((filter) => filter.columnName === selectedFilterColumn);
if (existingFilterIndex !== -1) {
if (selectedFilters.length === 0) {
setFilters((prevFilterArray) => {
const newFilterArray = [...prevFilterArray];
newFilterArray.splice(existingFilterIndex, 1);
return newFilterArray;
});
}
else {
setFilters((prevFilterArray) => {
const newFilterArray = [...prevFilterArray];
newFilterArray[existingFilterIndex] = newFilter;
return newFilterArray;
});
}
}
else {
if (selectedFilters.length > 0) {
setFilters((prevFilterArray) => [...prevFilterArray, newFilter]);
}
}
};
const handleClearFilter = (columnName) => {
setFilters(prevFilters => prevFilters.filter(filter => filter.columnName !== columnName));
};
const openColumnSelector = () => {
setIsColumnSelectorOpen(true);
};
const closeModal = () => {
setIsColumnSelectorOpen(false);
};
const handleColumnSelector = (columns) => {
setCustomTableColumns(columns);
setIsColumnSelectorOpen(false);
};
return (React.createElement(ThemeProvider, { theme: currentTheme },
showHeader() && (React.createElement(Header, { title: title, actions: actions, showMenu: !noContextMenu, selectedCount: selectedCount, direction: direction, contextActions: contextActions, contextComponent: contextComponent, contextMessage: contextMessage })),
subHeader && (React.createElement(Subheader, { align: subHeaderAlign, wrapContent: subHeaderWrap }, subHeaderComponent)),
React.createElement(ResponsiveWrapper, Object.assign({ "$responsive": responsive, "$fixedHeader": fixedHeader, "$fixedHeaderScrollHeight": fixedHeaderScrollHeight, className: className }, wrapperProps),
React.createElement(Wrapper, null,
progressPending && !persistTableHead && React.createElement(ProgressWrapper, null, progressComponent),
showSearch && React.createElement(SearchComponent, { onFilter: e => setFilterText(e.target.value), filterText: filterText, wrapperStyle: searchComponentStyle }),
React.createElement("div", { style: {
display: "flex", flexDirection: 'row', gap: '10px',
justifyContent: filters.length > 0 ? "space-between" : "flex-end", alignItems: 'flex-end'
} },
filters && filters.map((filter, index) => {
return (filter.filterText.length > 0 && (React.createElement("div", { key: index, style: { marginTop: "5px", border: '2px solid #DB4A11', padding: '10px', borderRadius: '10px', display: "flex", flexDirection: "row" } },
React.createElement("p", { style: { fontWeight: "bold", color: "#DB4A11" } }, filter.columnName + ': ' + filter.filterText.map(text => text.substring(0, 10) + '..').join(', ')),
React.createElement("button", { style: { backgroundColor: "transparent", border: "none", fontSize: '19px', color: "#DB4A11" }, onClick: () => handleClearFilter(filter.columnName) },
React.createElement(IoCloseSharp, null)))));
}),
showColumnSelector ? (React.createElement("button", { style: { backgroundColor: "transparent", border: "none", fontSize: '19px', color: (_a = currentTheme.expanderButton) === null || _a === void 0 ? void 0 : _a.style.color }, onClick: openColumnSelector },
React.createElement(CiViewColumn, null))) : null),
React.createElement(TableStyle, { disabled: disabled, className: "rdt_Table", role: "table" },
showTableHead() && (React.createElement(Head, { className: "rdt_TableHead", role: "rowgroup", "$fixedHeader": fixedHeader },
React.createElement(HeadRow, { className: "rdt_TableHeadRow", role: "row", "$dense": dense },
selectableRows &&
(showSelectAll ? (React.createElement(CellBase, { style: { flex: '0 0 48px' } })) : (React.createElement(ColumnCheckbox, { allSelected: allSelected, selectedRows: selectedRows, selectableRowsComponent: selectableRowsComponent, selectableRowsComponentProps: selectableRowsComponentProps, selectableRowDisabled: selectableRowDisabled, rowData: visibleRows, keyField: keyField, mergeSelections: mergeSelections, onSelectAllRows: handleSelectAllRows }))),
expandableRows && !expandableRowsHideExpander && React.createElement(ColumnExpander, null),
customTableColumns.map(column => (!column.isHidden && (React.createElement(Column, { key: `${column.id}-${Math.random()}`, column: column, selectedColumn: selectedColumn, disabled: progressPending || sortedData.length === 0, pagination: pagination, paginationServer: paginationServer, persistSelectedOnSort: persistSelectedOnSort, selectableRowsVisibleOnly: selectableRowsVisibleOnly, sortDirection: sortDirection, sortIcon: sortIcon, sortServer: sortServer, onSort: handleSort, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnd: handleDragEnd, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, draggingColumnId: draggingColumnId, showFilter: showFilter !== null && showFilter !== void 0 ? showFilter : true, showFilterList: handleFilterClick }))))))),
!sortedData.length && !progressPending && React.createElement(NoDataWrapper, null, noDataComponent),
progressPending && persistTableHead && React.createElement(ProgressWrapper, null, progressComponent),
!progressPending && sortedData.length > 0 && (React.createElement(Body, { className: "rdt_TableBody", role: "rowgroup" }, tableRows.map((row, i) => {
const key = prop(row, keyField);
const id = isEmpty(key) ? i : key;
const selected = isRowSelected(row, selectedRows, keyField);
const expanderExpander = !!(expandableRows && expandableRowExpanded && expandableRowExpanded(row));
const expanderDisabled = !!(expandableRows && expandableRowDisabled && expandableRowDisabled(row));
return (React.createElement(Row, { id: id, key: id, keyField: keyField, "data-row-id": id, columns: customTableColumns, row: row, rowCount: sortedData.length, rowIndex: i, selectableRows: selectableRows, expandableRows: expandableRows, expandableIcon: expandableIcon, highlightOnHover: highlightOnHover, pointerOnHover: pointerOnHover, dense: dense, expandOnRowClicked: expandOnRowClicked, expandOnRowDoubleClicked: expandOnRowDoubleClicked, expandableRowsComponent: expandableRowsComponent, expandableRowsComponentProps: expandableRowsComponentProps, expandableRowsHideExpander: expandableRowsHideExpander, defaultExpanderDisabled: expanderDisabled, defaultExpanded: expanderExpander, expandableInheritConditionalStyles: expandableInheritConditionalStyles, conditionalRowStyles: conditionalRowStyles, selected: selected, selectableRowsHighlight: selectableRowsHighlight, selectableRowsComponent: selectableRowsComponent, selectableRowsComponentProps: selectableRowsComponentProps, selectableRowDisabled: selectableRowDisabled, selectableRowsSingle: selectableRowsSingle, striped: striped, onRowExpandToggled: onRowExpandToggled, onRowClicked: handleRowClicked, onRowDoubleClicked: handleRowDoubleClicked, onRowMouseEnter: handleRowMouseEnter, onRowMouseLeave: handleRowMouseLeave, onSelectedRow: handleSelectedRow, draggingColumnId: draggingColumnId, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnd: handleDragEnd, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, selectRowFunction: selectRowFunction, highlighted: id === highlightedRowId }));
})))))),
enabledPagination && (React.createElement("div", null,
React.createElement(Pagination, { onChangePage: handleChangePage, onChangeRowsPerPage: handleChangeRowsPerPage, rowCount: paginationTotalRows || sortedData.length, currentPage: currentPage, rowsPerPage: rowsPerPage, direction: direction, paginationRowsPerPageOptions: paginationRowsPerPageOptions, paginationIconLastPage: paginationIconLastPage, paginationIconFirstPage: paginationIconFirstPage, paginationIconNext: paginationIconNext, paginationIconPrevious: paginationIconPrevious, paginationComponentOptions: paginationComponentOptions }))),
showActionMenu && (React.createElement(ActionsMenu, { position: position, theme: currentTheme, actions: propActions, rowData: selectedRow })),
showFilterMenu && (React.createElement(ColumnFilterList, { position: position, theme: currentTheme, listData: filterListData, handleFilteredData: handleFilteredData, selectedFilterList: selectedFilterList })),
columnSelectorOpen && (React.createElement(ColumnSelector, { theme: currentTheme, closeModal: closeModal, handleColumnSelector: handleColumnSelector, columns: customTableColumns }))));
}
var DataTable$1 = React.memo(DataTable);
export { Alignment, Direction, Media, STOP_PROP_TAG, createTheme, DataTable$1 as default, defaultThemes };