tp-react-elements 2.0.4 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.esm11.js +2 -2
- package/dist/_virtual/index.esm12.js +2 -2
- package/dist/_virtual/index.esm14.js +2 -2
- package/dist/_virtual/index.esm4.js +2 -2
- package/dist/_virtual/index.esm6.js +2 -2
- package/dist/_virtual/index.esm7.js +2 -2
- package/dist/components/DateRangePicker/DateRangePicker.esm.js +49 -72
- package/dist/components/Form/FormRender.esm.js +1 -1
- package/dist/components/FormComponents/DatePicker/DatepickerWrapperV2.esm.js +10 -15
- package/dist/components/FormComponents/DatePicker/DatetimepickerWrapper.esm.js +53 -61
- package/dist/components/FormComponents/FileUpload/FormRenderFileUpload.esm.js +54 -68
- package/dist/components/FormComponents/FileUpload/FormRenderMultiFileUpload.esm.js +61 -76
- package/dist/components/FormComponents/FileUpload/MultiFileWithPreview.esm.js +103 -132
- package/dist/components/FormComponents/FormNumberField/FormNumberField.d.ts +0 -38
- package/dist/components/FormComponents/FormNumberField/FormNumberField.esm.js +32 -97
- package/dist/components/FormComponents/FormNumberField/FormNumberFieldDecimal.esm.js +44 -38
- package/dist/components/FormComponents/FormTextField/FormTextField.esm.js +3 -3
- package/dist/components/FormComponents/FormTextFieldWithSelect/FormTextFieldWithSelect.esm.js +3 -2
- package/dist/components/FormComponents/PasswordField/PasswordField.esm.js +4 -4
- package/dist/components/FormComponents/RichTextEditor/RichTextEditor.esm.js +23 -22
- package/dist/components/FormComponents/Select/SearchableSelect.esm.js +9 -9
- package/dist/components/FormComponents/TimePicker/TimePicker.esm.js +19 -19
- package/dist/components/FormComponents/index.esm.js +2 -2
- package/dist/components/ModalField/ConfirmationDialog.esm.js +3 -3
- package/dist/components/ModalField/ModalField.esm.js +5 -12
- package/dist/components/PaginatedGrid/DynamicFilterBar.d.ts +1 -1
- package/dist/components/PaginatedGrid/DynamicFilterBar.esm.js +27 -24
- package/dist/components/PaginatedGrid/GenericPaginatedGrid.d.ts +13 -1
- package/dist/components/PaginatedGrid/GenericPaginatedGrid.esm.js +102 -85
- package/dist/components/SelectField/MultiSelectFieldComponent.esm.js +3 -3
- package/dist/components/SessionTimeOut/SessionTimeOut.esm.js +33 -34
- package/dist/node_modules/react-date-range/dist/components/Calendar/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DateRange/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DateRangePicker/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DayCell/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/InputRangeField/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/Month/index.esm.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { memo, useState, useEffect } from 'react';
|
|
2
|
+
import { memo, useState, useEffect, useCallback } from 'react';
|
|
3
3
|
import { useForm } from 'react-hook-form';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
@@ -410,21 +410,21 @@ const GlobalSearchInput = memo(({ value, onChange, chipStyle, placeholder = 'Sea
|
|
|
410
410
|
} }));
|
|
411
411
|
});
|
|
412
412
|
GlobalSearchInput.displayName = 'GlobalSearchInput';
|
|
413
|
+
// ─── PillBox — module-level so ManageFiltersButton never creates a new type ───
|
|
414
|
+
const PillBox = ({ bg, color, label }) => (jsx(Box, { component: "span", sx: {
|
|
415
|
+
mr: 1.25, flexShrink: 0,
|
|
416
|
+
fontSize: 10, fontWeight: 700,
|
|
417
|
+
px: 0.75, py: '2px',
|
|
418
|
+
borderRadius: '4px',
|
|
419
|
+
bgcolor: bg,
|
|
420
|
+
color,
|
|
421
|
+
textTransform: 'uppercase',
|
|
422
|
+
letterSpacing: 0.4,
|
|
423
|
+
lineHeight: 1.6,
|
|
424
|
+
}, children: label }));
|
|
413
425
|
const ManageFiltersButton = ({ serverFilterDefs, visibleIds, availableColumns, onToggle, maxVisible = 4, chipStyle, gridId, }) => {
|
|
414
426
|
const [anchor, setAnchor] = useState(null);
|
|
415
427
|
const atLimit = visibleIds.length >= maxVisible;
|
|
416
|
-
// Shared pill box renderer
|
|
417
|
-
const PillBox = ({ bg, color, label }) => (jsx(Box, { component: "span", sx: {
|
|
418
|
-
mr: 1.25, flexShrink: 0,
|
|
419
|
-
fontSize: 10, fontWeight: 700,
|
|
420
|
-
px: 0.75, py: '2px',
|
|
421
|
-
borderRadius: '4px',
|
|
422
|
-
bgcolor: bg,
|
|
423
|
-
color,
|
|
424
|
-
textTransform: 'uppercase',
|
|
425
|
-
letterSpacing: 0.4,
|
|
426
|
-
lineHeight: 1.6,
|
|
427
|
-
}, children: label }));
|
|
428
428
|
return (jsxs(Fragment, { children: [jsx(Tooltip, { title: "Add or remove filter chips", children: jsx(Button, { id: gridId ? `${gridId}_manage_filters_icon` : undefined, size: "small", variant: "outlined", startIcon: jsx(TuneIcon, { sx: { fontSize: 14 } }), onClick: (e) => setAnchor(e.currentTarget), sx: {
|
|
429
429
|
borderRadius: 5, textTransform: 'none', fontSize: chipStyle.fontSize,
|
|
430
430
|
borderColor: 'divider', color: 'text.secondary',
|
|
@@ -464,20 +464,24 @@ const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter,
|
|
|
464
464
|
const labelFontSize = filterLabelFontSize ?? (uiDensity === 'compact' ? 11 : 12);
|
|
465
465
|
// ── Single-value column filter helpers ──────────────────────────────────────
|
|
466
466
|
const getColValue = (id) => columnFilters.find((f) => f.id === id)?.value ?? '';
|
|
467
|
-
const applyColFilter = (id, value) => {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
467
|
+
const applyColFilter = useCallback((id, value) => {
|
|
468
|
+
onColumnFilterChange((prev) => {
|
|
469
|
+
const rest = prev.filter((f) => f.id !== id);
|
|
470
|
+
return value ? [...rest, { id, value }] : rest;
|
|
471
|
+
});
|
|
472
|
+
}, [onColumnFilterChange]);
|
|
471
473
|
// ── Multi-value column filter helpers ────────────────────────────────────────
|
|
472
474
|
const getColValues = (id) => {
|
|
473
475
|
const val = columnFilters.find((f) => f.id === id)?.value;
|
|
474
476
|
return Array.isArray(val) ? val : [];
|
|
475
477
|
};
|
|
476
|
-
const applyColMultiFilter = (id, values) => {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
478
|
+
const applyColMultiFilter = useCallback((id, values) => {
|
|
479
|
+
onColumnFilterChange((prev) => {
|
|
480
|
+
const rest = prev.filter((f) => f.id !== id);
|
|
481
|
+
return values.length > 0 ? [...rest, { id, value: values }] : rest;
|
|
482
|
+
});
|
|
483
|
+
}, [onColumnFilterChange]);
|
|
484
|
+
const removeFilter = useCallback((id) => {
|
|
481
485
|
const def = serverFilterDefs.find((d) => d.id === id);
|
|
482
486
|
if (def?.type === 'dateRange') {
|
|
483
487
|
onFilterValuesChange({ ...filterValues, [def.fromKey]: '', [def.toKey]: '' });
|
|
@@ -493,7 +497,6 @@ const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter,
|
|
|
493
497
|
applyColFilter(def.columnKey, '');
|
|
494
498
|
}
|
|
495
499
|
else {
|
|
496
|
-
// Column filter — multi-select stores string[], others store string
|
|
497
500
|
const colDef = availableColumns.find((c) => c.id === id);
|
|
498
501
|
if (colDef?.filterType === 'multi-select') {
|
|
499
502
|
applyColMultiFilter(id, []);
|
|
@@ -503,7 +506,7 @@ const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter,
|
|
|
503
506
|
}
|
|
504
507
|
}
|
|
505
508
|
onToggleFilter(id);
|
|
506
|
-
};
|
|
509
|
+
}, [filterValues, serverFilterDefs, availableColumns, onFilterValuesChange, onToggleFilter, applyColFilter, applyColMultiFilter]);
|
|
507
510
|
return (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 0.75 }, children: [jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 0.4, mr: 0.25 }, children: [jsx(FilterListIcon, { sx: { fontSize: labelFontSize + 3, color: 'text.disabled' } }), jsx(Typography, { sx: { fontSize: labelFontSize }, color: "text.secondary", fontWeight: 500, noWrap: true, children: "Filter by:" })] }), visibleFilterIds.map((id) => {
|
|
508
511
|
const def = serverFilterDefs.find((d) => d.id === id);
|
|
509
512
|
if (def?.type === 'dateRange') {
|
|
@@ -109,6 +109,18 @@ export interface GenericPaginatedGridProps<TData extends object> {
|
|
|
109
109
|
* Accepts any valid CSS colour string.
|
|
110
110
|
*/
|
|
111
111
|
headerBgColor?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Background colour for the Excel export header row.
|
|
114
|
+
* Accepts a hex colour string (`#RRGGBB`).
|
|
115
|
+
* Falls back to `headerBgColor` when omitted, then to the default blue `#1565C0`.
|
|
116
|
+
*/
|
|
117
|
+
exportHeaderBgColor?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Text colour for the Excel export header row.
|
|
120
|
+
* Accepts a hex colour string (`#RRGGBB`).
|
|
121
|
+
* Defaults to white (`#FFFFFF`) when omitted.
|
|
122
|
+
*/
|
|
123
|
+
exportHeaderTextColor?: string;
|
|
112
124
|
/**
|
|
113
125
|
* Minimum height of every header cell (CSS length or px number).
|
|
114
126
|
* Default: `40px` (`34px` when `uiDensity="compact"`).
|
|
@@ -198,5 +210,5 @@ export interface GenericPaginatedGridProps<TData extends object> {
|
|
|
198
210
|
*/
|
|
199
211
|
enableExpanding?: boolean;
|
|
200
212
|
}
|
|
201
|
-
declare function GenericPaginatedGrid<TData extends object>({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize, exportFilename, gridId, tableHeight, tableMinHeight, tableMaxHeight, autoFillViewport, layoutMode, uiDensity, uiDensityOptions, pageSizeOptions, showGlobalSearchByDefault, headerBgColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, renderDetailPanel, enableExpanding, }: GenericPaginatedGridProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
213
|
+
declare function GenericPaginatedGrid<TData extends object>({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize, exportFilename, gridId, tableHeight, tableMinHeight, tableMaxHeight, autoFillViewport, layoutMode, uiDensity, uiDensityOptions, pageSizeOptions, showGlobalSearchByDefault, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, renderDetailPanel, enableExpanding, }: GenericPaginatedGridProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
202
214
|
export default GenericPaginatedGrid;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useMemo, useState, useRef, useLayoutEffect, useCallback } from 'react';
|
|
3
3
|
import * as XLSX from 'xlsx-js-style';
|
|
4
|
-
import {
|
|
4
|
+
import { MRT_ToggleGlobalFilterButton, MRT_ShowHideColumnsButton, MRT_ToggleDensePaddingButton, MRT_ToggleFullScreenButton, useMaterialReactTable, MaterialReactTable } from 'material-react-table';
|
|
5
5
|
import { useQuery, keepPreviousData } from '@tanstack/react-query';
|
|
6
6
|
import { Box, Tooltip, IconButton, GlobalStyles, Typography, Select, MenuItem, CircularProgress } from '@mui/material';
|
|
7
7
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
|
@@ -224,7 +224,7 @@ const PaginationFooter = ({ pageIndex, pageSize, totalRecords, isFetching, isLoa
|
|
|
224
224
|
}, children: pageIndex + 1 }), jsx(Tooltip, { title: "Next page", children: jsx("span", { children: jsx(IconButton, { id: `${gridId}_next_page_icon`, size: "small", onClick: onNext, disabled: !canNext, sx: { p: 0.5 }, children: jsx(ChevronRightIcon, { sx: { fontSize: density.footerIconSize } }) }) }) }), jsx(Tooltip, { title: "Last page", children: jsx("span", { children: jsx(IconButton, { id: `${gridId}_last_page_icon`, size: "small", onClick: onLast, disabled: !canNext, sx: { p: 0.5 }, children: jsx(LastPageIcon, { sx: { fontSize: density.footerIconSize } }) }) }) })] })] }));
|
|
225
225
|
};
|
|
226
226
|
// ─── GenericPaginatedGrid ─────────────────────────────────────────────────────
|
|
227
|
-
function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize = 10000, exportFilename = 'export', gridId, tableHeight, tableMinHeight = '300px', tableMaxHeight, autoFillViewport = true, layoutMode = 'grid', uiDensity = 'default', uiDensityOptions, pageSizeOptions = [1000, 5000, 10000], showGlobalSearchByDefault = false, headerBgColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters = 4, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, renderDetailPanel, enableExpanding = !!renderDetailPanel, }) {
|
|
227
|
+
function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize = 10000, exportFilename = 'export', gridId, tableHeight, tableMinHeight = '300px', tableMaxHeight, autoFillViewport = true, layoutMode = 'grid', uiDensity = 'default', uiDensityOptions, pageSizeOptions = [1000, 5000, 10000], showGlobalSearchByDefault = false, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters = 4, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, renderDetailPanel, enableExpanding = !!renderDetailPanel, }) {
|
|
228
228
|
const densityTokens = useMemo(() => ({ ...UI_DENSITY_PRESETS[uiDensity], ...uiDensityOptions }), [uiDensity, uiDensityOptions]);
|
|
229
229
|
const resolvedGridId = gridId ?? exportFilename;
|
|
230
230
|
const resolvedHeaderMinHeight = toCssSize(headerMinHeight, uiDensity === 'compact' ? '34px' : '40px');
|
|
@@ -232,6 +232,13 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
232
232
|
const resolvedHeaderFontSize = toCssSize(headerFontSize ?? densityTokens.headerFontSize, uiDensity === 'compact' ? '11px' : '12px');
|
|
233
233
|
const resolvedBodyFontSize = toCssSize(bodyFontSize ?? densityTokens.bodyFontSize, uiDensity === 'compact' ? '11px' : '12px');
|
|
234
234
|
const tableStyleOverrides = useMemo(() => ({
|
|
235
|
+
// Static rules folded in here so the whole object comes from one useMemo
|
|
236
|
+
// and GlobalStyles receives a stable reference unless these props change.
|
|
237
|
+
'button[aria-label="Pin to right"]': { display: 'none' },
|
|
238
|
+
'.tp-gpg-root .MuiTableSortLabel-icon': { display: 'none !important' },
|
|
239
|
+
'.tp-gpg-root button[aria-label="Move"]': { display: 'none !important' },
|
|
240
|
+
'.tp-gpg-root [data-column-id="mrt-row-spacer"]': { display: 'none !important' },
|
|
241
|
+
'.tp-gpg-root .Mui-TableHeadCell-ColumnSpacer': { display: 'none !important' },
|
|
235
242
|
...buildHeaderGlobalStyles(resolvedHeaderMinHeight, resolvedHeaderMaxHeight, resolvedHeaderFontSize, headerBgColor),
|
|
236
243
|
...buildBodyGlobalStyles(resolvedBodyFontSize),
|
|
237
244
|
}), [
|
|
@@ -414,9 +421,9 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
414
421
|
const handleExport = useCallback(() => {
|
|
415
422
|
const dataCols = columns.filter((c) => 'accessorKey' in c && c.accessorKey);
|
|
416
423
|
// xlsx-js-style requires 8-char ARGB (AA + RRGGBB). Prepend full-opacity "FF".
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
424
|
+
const toArgb = (hex, fallback = 'FF1565C0') => hex?.startsWith('#') ? 'FF' + hex.slice(1).toUpperCase().padEnd(6, '0') : fallback;
|
|
425
|
+
const headerArgb = toArgb(exportHeaderBgColor ?? headerBgColor);
|
|
426
|
+
const textArgb = toArgb(exportHeaderTextColor, 'FFFFFFFF');
|
|
420
427
|
const headerRow = dataCols.map((c) => c.header ?? '');
|
|
421
428
|
const dataRows = rows.map((row) => dataCols.map((c) => String(row[c.accessorKey] ?? '')));
|
|
422
429
|
const ws = XLSX.utils.aoa_to_sheet([headerRow, ...dataRows]);
|
|
@@ -426,7 +433,7 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
426
433
|
if (ws[cellRef]) {
|
|
427
434
|
ws[cellRef].s = {
|
|
428
435
|
fill: { patternType: 'solid', fgColor: { rgb: headerArgb } },
|
|
429
|
-
font: { bold: true, color: { rgb:
|
|
436
|
+
font: { bold: true, color: { rgb: textArgb }, sz: 10 },
|
|
430
437
|
alignment: { horizontal: 'center', vertical: 'center', wrapText: true },
|
|
431
438
|
border: {
|
|
432
439
|
bottom: { style: 'thin', color: { rgb: 'FFCCCCCC' } },
|
|
@@ -435,19 +442,89 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
435
442
|
};
|
|
436
443
|
}
|
|
437
444
|
});
|
|
438
|
-
// Auto-fit column widths
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
445
|
+
// Auto-fit column widths — single O(n) pass accumulates max length per column
|
|
446
|
+
// instead of one reduce() per column (was O(n × cols)).
|
|
447
|
+
const colWidths = dataCols.map((c) => (c.header ?? '').length);
|
|
448
|
+
for (const row of rows) {
|
|
449
|
+
const r = row;
|
|
450
|
+
for (let ci = 0; ci < dataCols.length; ci++) {
|
|
451
|
+
const len = String(r[dataCols[ci].accessorKey] ?? '').length;
|
|
452
|
+
if (len > colWidths[ci])
|
|
453
|
+
colWidths[ci] = len;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
ws['!cols'] = colWidths.map((w) => ({ wch: Math.max(w, 8) + 2 }));
|
|
447
457
|
const wb = XLSX.utils.book_new();
|
|
448
458
|
XLSX.utils.book_append_sheet(wb, ws, 'Data');
|
|
449
459
|
XLSX.writeFile(wb, `${exportFilename}-page${pagination.pageIndex + 1}.xlsx`);
|
|
450
|
-
}, [columns, rows, exportFilename, pagination.pageIndex, headerBgColor]);
|
|
460
|
+
}, [columns, rows, exportFilename, pagination.pageIndex, headerBgColor, exportHeaderBgColor, exportHeaderTextColor]);
|
|
461
|
+
// ── Memoized cell-prop builders ───────────────────────────────────────────
|
|
462
|
+
// These are functions passed to MRT per-cell. Without useCallback they get
|
|
463
|
+
// new references on every render, forcing MRT to rebuild every cell's sx.
|
|
464
|
+
const memoizedHeadCellProps = useCallback((params) => {
|
|
465
|
+
const { column, table } = params;
|
|
466
|
+
const colDef = column.columnDef.muiTableHeadCellProps;
|
|
467
|
+
const colResolved = typeof colDef === 'function' ? (colDef({ column, table }) ?? {}) : colDef ?? {};
|
|
468
|
+
const gridResolved = typeof gridHeadCellProps === 'function'
|
|
469
|
+
? (gridHeadCellProps({ column, table }) ?? {})
|
|
470
|
+
: gridHeadCellProps ?? {};
|
|
471
|
+
const align = (colResolved.align ?? gridResolved.align ?? 'left');
|
|
472
|
+
const { sx: gridSx, align: _ga, ...gridRest } = gridResolved;
|
|
473
|
+
const { sx: colSx, align: _ca, ...colRest } = colResolved;
|
|
474
|
+
return {
|
|
475
|
+
...gridRest,
|
|
476
|
+
...colRest,
|
|
477
|
+
align,
|
|
478
|
+
sx: [
|
|
479
|
+
buildHeaderCellSx(align, resolvedHeaderMinHeight, resolvedHeaderMaxHeight, resolvedHeaderFontSize, headerBgColor, headerMaxLines),
|
|
480
|
+
...(gridSx ? [gridSx] : []),
|
|
481
|
+
...(colSx ? [colSx] : []),
|
|
482
|
+
],
|
|
483
|
+
};
|
|
484
|
+
}, [
|
|
485
|
+
resolvedHeaderMinHeight,
|
|
486
|
+
resolvedHeaderMaxHeight,
|
|
487
|
+
resolvedHeaderFontSize,
|
|
488
|
+
headerBgColor,
|
|
489
|
+
headerMaxLines,
|
|
490
|
+
gridHeadCellProps,
|
|
491
|
+
]);
|
|
492
|
+
const memoizedBodyCellProps = useCallback((params) => {
|
|
493
|
+
const { cell, column, row, table } = params;
|
|
494
|
+
const colDef = column.columnDef.muiTableBodyCellProps;
|
|
495
|
+
const colResolved = typeof colDef === 'function' ? (colDef({ cell, column, row, table }) ?? {}) : colDef ?? {};
|
|
496
|
+
const gridResolved = typeof gridBodyCellProps === 'function'
|
|
497
|
+
? (gridBodyCellProps({ cell, column, row, table }) ?? {})
|
|
498
|
+
: gridBodyCellProps ?? {};
|
|
499
|
+
const { sx: gridSx, ...gridRest } = gridResolved;
|
|
500
|
+
const { sx: colSx, ...colRest } = colResolved;
|
|
501
|
+
return {
|
|
502
|
+
...gridRest,
|
|
503
|
+
...colRest,
|
|
504
|
+
sx: [
|
|
505
|
+
{
|
|
506
|
+
whiteSpace: 'nowrap',
|
|
507
|
+
fontSize: resolvedBodyFontSize,
|
|
508
|
+
lineHeight: 1.35,
|
|
509
|
+
borderRight: '1px solid rgba(224,224,224,1)',
|
|
510
|
+
},
|
|
511
|
+
...(gridSx ? [gridSx] : []),
|
|
512
|
+
...(colSx ? [colSx] : []),
|
|
513
|
+
],
|
|
514
|
+
};
|
|
515
|
+
}, [resolvedBodyFontSize, gridBodyCellProps]);
|
|
516
|
+
// ── Memoized toolbar render functions ─────────────────────────────────────
|
|
517
|
+
// Defined with useCallback so MRT receives stable references and does not
|
|
518
|
+
// re-render the toolbar on every isFetching / data update cycle.
|
|
519
|
+
const renderTopToolbarCustomActions = useCallback(() => (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0, pr: 1, gap: 0.5 }, children: [jsxs(Box, { sx: { display: 'flex', alignItems: 'center', flexShrink: 0, gap: 0.25 }, children: [jsx(Tooltip, { title: "Clear filters & refresh", children: jsx("span", { children: jsx(IconButton, { id: `${resolvedGridId}_refresh_icon`, size: "small", onClick: () => { handleClearAll(); refetch(); }, disabled: isFetching, sx: { p: uiDensity === 'compact' ? 0.35 : 0.5 }, children: jsx(RefreshIcon, { sx: { fontSize: uiDensity === 'compact' ? 18 : 20 } }) }) }) }), jsx(Tooltip, { title: "Export batch as Excel (.xlsx)", children: jsx("span", { children: jsx(IconButton, { id: `${resolvedGridId}_export_icon`, size: "small", onClick: handleExport, disabled: rows.length === 0 || isFetching, sx: { p: uiDensity === 'compact' ? 0.35 : 0.5 }, children: jsx(FileDownloadIcon, { sx: { fontSize: uiDensity === 'compact' ? 18 : 20 } }) }) }) })] }), jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: jsx(DynamicFilterBar, { serverFilterDefs: serverFilterDefs, visibleFilterIds: visibleFilterIds, onToggleFilter: handleToggleFilter, filterValues: filterValues, onFilterValuesChange: handleFilterValuesChange, columnFilters: columnFilters, onColumnFilterChange: setColumnFilters, availableColumns: availableColumns, maxVisibleFilters: maxVisibleFilters, uiDensity: uiDensity, filterChipFontSize: densityTokens.filterChipFontSize, filterChipMinHeight: densityTokens.filterChipMinHeight, filterLabelFontSize: densityTokens.filterLabelFontSize, gridId: resolvedGridId }) })] })), [
|
|
520
|
+
resolvedGridId, isFetching, rows.length, uiDensity,
|
|
521
|
+
handleClearAll, refetch, handleExport,
|
|
522
|
+
serverFilterDefs, visibleFilterIds, handleToggleFilter,
|
|
523
|
+
filterValues, handleFilterValuesChange, columnFilters, setColumnFilters,
|
|
524
|
+
availableColumns, maxVisibleFilters, densityTokens, handleToggleFilter,
|
|
525
|
+
]);
|
|
526
|
+
const renderToolbarInternalActions = useCallback(({ table: t }) => (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 0.5 }, children: [jsx(MRT_ToggleGlobalFilterButton, { table: t, id: `${resolvedGridId}_global_search_icon` }), jsx(MRT_ShowHideColumnsButton, { table: t, id: `${resolvedGridId}_columns_icon` }), jsx(MRT_ToggleDensePaddingButton, { table: t, id: `${resolvedGridId}_density_icon` }), jsx(MRT_ToggleFullScreenButton, { table: t, id: `${resolvedGridId}_fullscreen_icon` })] })), [resolvedGridId]);
|
|
527
|
+
const renderBottomToolbar = useCallback(({ table: t }) => (jsx(PaginationFooter, { pageIndex: t.getState().pagination.pageIndex, pageSize: t.getState().pagination.pageSize, totalRecords: totalRecords, isFetching: isFetching, isLoading: isLoading, canPrev: t.getCanPreviousPage() && !isFetching, canNext: t.getCanNextPage() && !isFetching, onFirst: () => t.firstPage(), onPrev: () => t.previousPage(), onNext: () => t.nextPage(), onLast: () => t.lastPage(), onPageSizeChange: (s) => t.setPageSize(s), pageSizeOptions: pageSizeOptions, density: densityTokens, gridId: resolvedGridId })), [totalRecords, isFetching, isLoading, pageSizeOptions, densityTokens, resolvedGridId]);
|
|
451
528
|
// ── Table instance ─────────────────────────────────────────────────────────
|
|
452
529
|
const table = useMaterialReactTable({
|
|
453
530
|
columns: processedColumns,
|
|
@@ -604,69 +681,16 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
604
681
|
...(headerBgColor ? { backgroundColor: headerBgColor } : {}),
|
|
605
682
|
},
|
|
606
683
|
},
|
|
607
|
-
muiTableHeadCellProps:
|
|
608
|
-
|
|
609
|
-
// ── Resolve column-level props ────────────────────────────────────────
|
|
610
|
-
const colDef = column.columnDef.muiTableHeadCellProps;
|
|
611
|
-
const colResolved = typeof colDef === 'function' ? (colDef({ column, table }) ?? {}) : colDef ?? {};
|
|
612
|
-
// ── Resolve grid-level props ──────────────────────────────────────────
|
|
613
|
-
const gridResolved = typeof gridHeadCellProps === 'function'
|
|
614
|
-
? (gridHeadCellProps({ column, table }) ?? {})
|
|
615
|
-
: gridHeadCellProps ?? {};
|
|
616
|
-
// Column align overrides grid align; default 'left'
|
|
617
|
-
const align = (colResolved.align ?? gridResolved.align ?? 'left');
|
|
618
|
-
const { sx: gridSx, align: _ga, ...gridRest } = gridResolved;
|
|
619
|
-
const { sx: colSx, align: _ca, ...colRest } = colResolved;
|
|
620
|
-
return {
|
|
621
|
-
...gridRest, // grid-level props (className, etc.)
|
|
622
|
-
...colRest, // column-level overrides
|
|
623
|
-
align,
|
|
624
|
-
sx: [
|
|
625
|
-
buildHeaderCellSx(align, resolvedHeaderMinHeight, resolvedHeaderMaxHeight, resolvedHeaderFontSize, headerBgColor, headerMaxLines),
|
|
626
|
-
...(gridSx ? [gridSx] : []),
|
|
627
|
-
...(colSx ? [colSx] : []),
|
|
628
|
-
],
|
|
629
|
-
};
|
|
630
|
-
},
|
|
631
|
-
muiTableBodyCellProps: (params) => {
|
|
632
|
-
const { cell, column, row, table } = params;
|
|
633
|
-
// ── Resolve column-level props ────────────────────────────────────────
|
|
634
|
-
const colDef = column.columnDef.muiTableBodyCellProps;
|
|
635
|
-
const colResolved = typeof colDef === 'function' ? (colDef({ cell, column, row, table }) ?? {}) : colDef ?? {};
|
|
636
|
-
// ── Resolve grid-level props ──────────────────────────────────────────
|
|
637
|
-
const gridResolved = typeof gridBodyCellProps === 'function'
|
|
638
|
-
? (gridBodyCellProps({ cell, column, row, table }) ?? {})
|
|
639
|
-
: gridBodyCellProps ?? {};
|
|
640
|
-
const { sx: gridSx, ...gridRest } = gridResolved;
|
|
641
|
-
const { sx: colSx, ...colRest } = colResolved;
|
|
642
|
-
return {
|
|
643
|
-
...gridRest, // grid-level props (title, className, etc.)
|
|
644
|
-
...colRest, // column-level overrides (align, etc.)
|
|
645
|
-
sx: [
|
|
646
|
-
// 1. base styles — always applied
|
|
647
|
-
{
|
|
648
|
-
whiteSpace: 'nowrap',
|
|
649
|
-
fontSize: resolvedBodyFontSize,
|
|
650
|
-
lineHeight: 1.35,
|
|
651
|
-
borderRight: '1px solid rgba(224,224,224,1)',
|
|
652
|
-
},
|
|
653
|
-
// 2. grid-level sx additions
|
|
654
|
-
...(gridSx ? [gridSx] : []),
|
|
655
|
-
// 3. column-level sx overrides (minWidth, maxWidth, textAlign, etc.)
|
|
656
|
-
...(colSx ? [colSx] : []),
|
|
657
|
-
],
|
|
658
|
-
};
|
|
659
|
-
},
|
|
684
|
+
muiTableHeadCellProps: memoizedHeadCellProps,
|
|
685
|
+
muiTableBodyCellProps: memoizedBodyCellProps,
|
|
660
686
|
muiToolbarAlertBannerProps: isError
|
|
661
687
|
? { color: 'error', children: 'Failed to load data. Please try again.' }
|
|
662
688
|
: undefined,
|
|
663
|
-
|
|
664
|
-
//
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
renderToolbarInternalActions: ({ table: t }) => (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 0.5 }, children: [jsx(MRT_ToggleGlobalFilterButton, { table: t, id: `${resolvedGridId}_global_search_icon` }), jsx(MRT_ShowHideColumnsButton, { table: t, id: `${resolvedGridId}_columns_icon` }), jsx(MRT_ToggleDensePaddingButton, { table: t, id: `${resolvedGridId}_density_icon` }), jsx(MRT_ToggleFullScreenButton, { table: t, id: `${resolvedGridId}_fullscreen_icon` })] })),
|
|
669
|
-
renderBottomToolbar: ({ table: t }) => (jsx(PaginationFooter, { pageIndex: t.getState().pagination.pageIndex, pageSize: t.getState().pagination.pageSize, totalRecords: totalRecords, isFetching: isFetching, isLoading: isLoading, canPrev: t.getCanPreviousPage() && !isFetching, canNext: t.getCanNextPage() && !isFetching, onFirst: () => t.firstPage(), onPrev: () => t.previousPage(), onNext: () => t.nextPage(), onLast: () => t.lastPage(), onPageSizeChange: (s) => t.setPageSize(s), pageSizeOptions: pageSizeOptions, density: densityTokens, gridId: resolvedGridId })),
|
|
689
|
+
// Memoized via useCallback above — stable references prevent MRT from
|
|
690
|
+
// re-rendering the toolbar on every isFetching / data update cycle.
|
|
691
|
+
renderTopToolbarCustomActions,
|
|
692
|
+
renderToolbarInternalActions,
|
|
693
|
+
renderBottomToolbar,
|
|
670
694
|
});
|
|
671
695
|
return (jsxs(Box, { ref: containerRef, id: resolvedGridId, className: "tp-gpg-root", sx: {
|
|
672
696
|
position: 'relative',
|
|
@@ -676,14 +700,7 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
676
700
|
display: 'flex',
|
|
677
701
|
flexDirection: 'column',
|
|
678
702
|
overflow: 'hidden',
|
|
679
|
-
}, children: [jsx(GlobalStyles, { styles: {
|
|
680
|
-
'button[aria-label="Pin to right"]': { display: 'none' },
|
|
681
|
-
'.tp-gpg-root .MuiTableSortLabel-icon': { display: 'none !important' },
|
|
682
|
-
'.tp-gpg-root button[aria-label="Move"]': { display: 'none !important' },
|
|
683
|
-
'.tp-gpg-root [data-column-id="mrt-row-spacer"]': { display: 'none !important' },
|
|
684
|
-
'.tp-gpg-root .Mui-TableHeadCell-ColumnSpacer': { display: 'none !important' },
|
|
685
|
-
...tableStyleOverrides,
|
|
686
|
-
} }), isLoading && jsx(OverlayLoader, { message: "Loading data\u2026" }), !isLoading && isFetching && jsx(OverlayLoader, { message: "Updating data\u2026" }), jsx(Box, { sx: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }, children: jsx(MaterialReactTable, { table: table }) })] }));
|
|
703
|
+
}, children: [jsx(GlobalStyles, { styles: tableStyleOverrides }), isLoading && jsx(OverlayLoader, { message: "Loading data\u2026" }), !isLoading && isFetching && jsx(OverlayLoader, { message: "Updating data\u2026" }), jsx(Box, { sx: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }, children: jsx(MaterialReactTable, { table: table }) })] }));
|
|
687
704
|
}
|
|
688
705
|
|
|
689
706
|
export { GenericPaginatedGrid as default };
|
|
@@ -6,7 +6,7 @@ import ListItemText from '@mui/material/ListItemText';
|
|
|
6
6
|
import MenuItem from '@mui/material/MenuItem';
|
|
7
7
|
import Select from '@mui/material/Select';
|
|
8
8
|
import * as React from 'react';
|
|
9
|
-
import { useState } from 'react';
|
|
9
|
+
import { useState, useCallback } from 'react';
|
|
10
10
|
|
|
11
11
|
const ITEM_HEIGHT = 36;
|
|
12
12
|
const ITEM_PADDING_TOP = 2;
|
|
@@ -52,11 +52,11 @@ function MultiSelectFieldComponent({ value, options, onChangeFn, disable = false
|
|
|
52
52
|
setSelectAll(false);
|
|
53
53
|
}
|
|
54
54
|
}, [filterOptions, fieldValue]);
|
|
55
|
-
const handleChange = (event) => {
|
|
55
|
+
const handleChange = useCallback((event) => {
|
|
56
56
|
const { target: { value }, } = event;
|
|
57
57
|
setPersonName(typeof value === 'string' ? value?.split(',') : value);
|
|
58
58
|
onChangeFn((typeof value === 'string' ? value?.split(',') : value).join(','));
|
|
59
|
-
};
|
|
59
|
+
}, [onChangeFn]);
|
|
60
60
|
const selectedOptions = options.filter((item) => fieldValue?.split(',').some((value) => value === item.value));
|
|
61
61
|
const selectedValues = selectedOptions.map((item) => item.label).join(' , ');
|
|
62
62
|
return (jsx(Box, { children: jsx(FormControl, { fullWidth: true, ref: containerRef, sx: {
|
|
@@ -1,62 +1,61 @@
|
|
|
1
|
-
import { jsx
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
3
3
|
import { useIdleTimer } from 'react-idle-timer';
|
|
4
4
|
import ConfirmationDialog from '../ModalField/ConfirmationDialog.esm.js';
|
|
5
5
|
|
|
6
6
|
const secondsToMMSS = (totalSeconds) => {
|
|
7
7
|
const minutes = Math.floor(totalSeconds / 60);
|
|
8
8
|
const seconds = Math.floor(totalSeconds % 60);
|
|
9
|
-
|
|
10
|
-
const formattedSeconds = String(seconds).padStart(2, '0');
|
|
11
|
-
return `${formattedMinutes}:${formattedSeconds}`;
|
|
9
|
+
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
|
12
10
|
};
|
|
13
11
|
const promptBeforeValue = 120000;
|
|
14
12
|
const SessionTimeOut = ({ sessionTime, handleSubmitSession, onSessionExpire, handleSessionCancel, SubmitButtonName = 'Submit', }) => {
|
|
15
13
|
const [openConfirmModal, setOpenConfirmModal] = useState(false);
|
|
16
|
-
const
|
|
17
|
-
const providedTimestamp = new Date(expiryDetails).getTime();
|
|
14
|
+
const providedTimestamp = new Date(sessionTime).getTime();
|
|
18
15
|
const currentTimestamp = new Date().getTime();
|
|
19
|
-
const
|
|
20
|
-
const timeout = remainingTime;
|
|
16
|
+
const timeout = providedTimestamp - currentTimestamp;
|
|
21
17
|
const promptBeforeIdle = Math.min(promptBeforeValue, timeout - 1000);
|
|
22
18
|
const [, setRemainingTimeInSeconds] = useState(Math.ceil(timeout / 1000));
|
|
23
19
|
const [formattedRemainingTime, setFormattedRemainingTime] = useState(secondsToMMSS(Math.ceil(timeout / 1000)));
|
|
24
|
-
const onIdle = () => {
|
|
25
|
-
if (sessionTime)
|
|
20
|
+
const onIdle = useCallback(() => {
|
|
21
|
+
if (sessionTime)
|
|
26
22
|
onSessionExpire();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const handleSubmit = () => {
|
|
30
|
-
handleSubmitSession();
|
|
31
|
-
setOpenConfirmModal(false);
|
|
32
|
-
};
|
|
33
|
-
const handleCancel = () => {
|
|
34
|
-
handleSessionCancel();
|
|
35
|
-
setOpenConfirmModal(false);
|
|
36
|
-
};
|
|
37
|
-
const onPrompt = () => {
|
|
23
|
+
}, [sessionTime, onSessionExpire]);
|
|
24
|
+
const onPrompt = useCallback(() => {
|
|
38
25
|
setOpenConfirmModal(true);
|
|
39
|
-
};
|
|
26
|
+
}, []);
|
|
40
27
|
const { getRemainingTime } = useIdleTimer({
|
|
41
28
|
onIdle,
|
|
42
29
|
onPrompt,
|
|
43
30
|
promptBeforeIdle,
|
|
44
31
|
timeout,
|
|
45
|
-
throttle: 1000,
|
|
32
|
+
throttle: 1000,
|
|
46
33
|
});
|
|
34
|
+
// Keep a ref to getRemainingTime so the interval effect never needs it
|
|
35
|
+
// as a reactive dependency — react-idle-timer guarantees it is stable,
|
|
36
|
+
// but ESLint cannot verify that, which previously caused a spurious
|
|
37
|
+
// re-subscription on every render.
|
|
38
|
+
const getRemainingTimeRef = useRef(getRemainingTime);
|
|
39
|
+
getRemainingTimeRef.current = getRemainingTime;
|
|
47
40
|
useEffect(() => {
|
|
48
41
|
const interval = setInterval(() => {
|
|
49
|
-
const remainingSeconds = Math.ceil(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
setFormattedRemainingTime(
|
|
53
|
-
}, 1000);
|
|
54
|
-
return () =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
42
|
+
const remainingSeconds = Math.ceil(getRemainingTimeRef.current() / 1000);
|
|
43
|
+
const show = promptBeforeIdle !== promptBeforeValue;
|
|
44
|
+
setRemainingTimeInSeconds(show ? remainingSeconds : 0);
|
|
45
|
+
setFormattedRemainingTime(show ? secondsToMMSS(remainingSeconds) : '00:00');
|
|
46
|
+
}, 1000);
|
|
47
|
+
return () => clearInterval(interval);
|
|
48
|
+
}, [promptBeforeIdle]); // getRemainingTime intentionally omitted — stable ref used instead
|
|
49
|
+
const handleSubmit = useCallback(() => {
|
|
50
|
+
handleSubmitSession();
|
|
51
|
+
setOpenConfirmModal(false);
|
|
52
|
+
}, [handleSubmitSession]);
|
|
53
|
+
const handleCancel = useCallback(() => {
|
|
54
|
+
handleSessionCancel();
|
|
55
|
+
setOpenConfirmModal(false);
|
|
56
|
+
}, [handleSessionCancel]);
|
|
58
57
|
const sessionMessage = `Your session will expire in ${formattedRemainingTime} seconds. Do you want to extend the session?`;
|
|
59
|
-
return (jsx(
|
|
58
|
+
return (jsx(ConfirmationDialog, { openConfirmDialog: openConfirmModal, handleCancel: handleCancel, onClickSubmit: handleSubmit, text: sessionMessage, Submit: SubmitButtonName }));
|
|
60
59
|
};
|
|
61
60
|
|
|
62
61
|
export { SessionTimeOut as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as Calendar } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as Calendar } from '../../../../../_virtual/index.esm7.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireDayCell } from '../DayCell/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DateRange } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DateRange } from '../../../../../_virtual/index.esm6.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireCalendar } from '../Calendar/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DateRangePicker } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DateRangePicker } from '../../../../../_virtual/index.esm4.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireDateRange } from '../DateRange/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DayCell } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DayCell } from '../../../../../_virtual/index.esm12.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireClassnames } from '../../../../classnames/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as InputRangeField } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as InputRangeField } from '../../../../../_virtual/index.esm11.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as Month } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as Month } from '../../../../../_virtual/index.esm14.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireDayCell } from '../DayCell/index.esm.js';
|