tp-react-elements 3.0.1 → 3.0.2
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.esm5.js +2 -2
- package/dist/_virtual/index.esm6.js +2 -2
- package/dist/components/Form/FormRender.esm.js +7 -7
- package/dist/components/FormComponents/index.esm.js +19 -10
- package/dist/components/PaginatedGrid/GenericPaginatedGrid.esm.js +45 -9
- package/dist/node_modules/react-date-range/dist/components/DateRangePicker/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DefinedRange/index.esm.js +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DefinedRange = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DefinedRange as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DateRangePicker = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DateRangePicker as __exports };
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import require$$0__default, { lazy, Suspense } from 'react';
|
|
3
|
+
import FormCheckBox from '../FormComponents/FormCheckBox/FormCheckBox.esm.js';
|
|
3
4
|
import FormCheckBoxGroup from '../FormComponents/FormCheckBoxGroup/FormCheckBoxGroup.esm.js';
|
|
5
|
+
import FormNumberField from '../FormComponents/FormNumberField/FormNumberField.esm.js';
|
|
6
|
+
import FormNumberFieldDecimal from '../FormComponents/FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
7
|
+
import FormRadioGroup from '../FormComponents/FormRadioGroup/FormRadioGroup.esm.js';
|
|
8
|
+
import FormTextAreaField from '../FormComponents/FormTextAreaField/FormTextAreaField.esm.js';
|
|
9
|
+
import FormTextField from '../FormComponents/FormTextField/FormTextField.esm.js';
|
|
10
|
+
import PasswordField from '../FormComponents/PasswordField/PasswordField.esm.js';
|
|
4
11
|
import SingleSelect from '../FormComponents/Select/SingleSelect.esm.js';
|
|
5
12
|
import MultiSelectAutocomplete from '../FormComponents/Select/MultiSelectAutocomplete.esm.js';
|
|
6
13
|
import SingleSelectNonAutoComplete from '../FormComponents/Select/SingleSelectNonAutoComplete.esm.js';
|
|
@@ -11,13 +18,6 @@ import DateRangePickerComponent from '../DateRangePicker/DateRangePicker.esm.js'
|
|
|
11
18
|
import RichTextEditorWrapper from '../FormComponents/RichTextEditor/RichTextEditorWrapper.esm.js';
|
|
12
19
|
import SingleSelectSearchApi from '../FormComponents/Select/SingleSelectSearchApi.esm.js';
|
|
13
20
|
import DatetimepickerWrapper from '../FormComponents/DatePicker/DatetimepickerWrapper.esm.js';
|
|
14
|
-
import FormTextAreaField from '../FormComponents/FormTextAreaField/FormTextAreaField.esm.js';
|
|
15
|
-
import FormCheckBox from '../FormComponents/FormCheckBox/FormCheckBox.esm.js';
|
|
16
|
-
import FormRadioGroup from '../FormComponents/FormRadioGroup/FormRadioGroup.esm.js';
|
|
17
|
-
import FormNumberFieldDecimal from '../FormComponents/FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
18
|
-
import FormNumberField from '../FormComponents/FormNumberField/FormNumberField.esm.js';
|
|
19
|
-
import PasswordField from '../FormComponents/PasswordField/PasswordField.esm.js';
|
|
20
|
-
import FormTextField from '../FormComponents/FormTextField/FormTextField.esm.js';
|
|
21
21
|
|
|
22
22
|
// Lazy-loaded heavy components
|
|
23
23
|
// const RichTextEditorWrapper = lazy(() =>
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export { default as FormNumberField } from './FormNumberField/FormNumberField.esm.js';
|
|
2
|
+
export { default as FormNumberFieldDecimal } from './FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
3
|
+
export { default as FormTextAreaField } from './FormTextAreaField/FormTextAreaField.esm.js';
|
|
4
|
+
export { default as FormTextField } from './FormTextField/FormTextField.esm.js';
|
|
5
|
+
export { default as PasswordField } from './PasswordField/PasswordField.esm.js';
|
|
6
|
+
export { default as FormCheckBox } from './FormCheckBox/FormCheckBox.esm.js';
|
|
1
7
|
export { default as SingleSelect } from './Select/SingleSelect.esm.js';
|
|
2
8
|
export { default as SingleSelectNonAutoComplete } from './Select/SingleSelectNonAutoComplete.esm.js';
|
|
3
9
|
export { default as SingleSelectSearchApi } from './Select/SingleSelectSearchApi.esm.js';
|
|
@@ -5,6 +11,7 @@ export { default as MultiSelectV1 } from './Select/MultiSelectv1.esm.js';
|
|
|
5
11
|
export { default as MultiSelectTable } from './Select/MultiSelectTable.esm.js';
|
|
6
12
|
export { default as SearchableSelect } from './Select/SearchableSelect.esm.js';
|
|
7
13
|
export { default as FormCheckBoxGroup } from './FormCheckBoxGroup/FormCheckBoxGroup.esm.js';
|
|
14
|
+
export { default as FormRadioGroup } from './FormRadioGroup/FormRadioGroup.esm.js';
|
|
8
15
|
export { default as DatepickerWrapperV2 } from './DatePicker/DatepickerWrapperV2.esm.js';
|
|
9
16
|
export { default as Monthpickerrender } from './DatePicker/Monthpickerrender.esm.js';
|
|
10
17
|
import 'react/jsx-runtime';
|
|
@@ -17,17 +24,19 @@ import 'react-hook-form';
|
|
|
17
24
|
export { default as FormBottomField } from './FormBottomField/FormBottomField.esm.js';
|
|
18
25
|
import 'dayjs';
|
|
19
26
|
export { default as YearPickerField } from './YearPickerField/YearPickerField.esm.js';
|
|
20
|
-
export { default as
|
|
21
|
-
export { default as HelperText } from './HelperText/HelperText.esm.js';
|
|
22
|
-
export { default as FormCheckBox } from './FormCheckBox/FormCheckBox.esm.js';
|
|
23
|
-
export { default as FormNumberField } from './FormNumberField/FormNumberField.esm.js';
|
|
24
|
-
export { default as FormNumberFieldDecimal } from './FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
25
|
-
export { default as FormRadioGroup } from './FormRadioGroup/FormRadioGroup.esm.js';
|
|
27
|
+
export { default as TimePicker } from './TimePicker/TimePicker.esm.js';
|
|
26
28
|
export { default as FormRenderFileUpload } from './FileUpload/FormRenderFileUpload.esm.js';
|
|
27
29
|
export { default as FormRenderMultiFileUpload } from './FileUpload/FormRenderMultiFileUpload.esm.js';
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
import '@mui/icons-material/Visibility';
|
|
31
|
+
import '@mui/icons-material/Close';
|
|
32
|
+
import '@mui/icons-material/NavigateBefore';
|
|
33
|
+
import '@mui/icons-material/NavigateNext';
|
|
34
|
+
import '@mui/icons-material/Delete';
|
|
35
|
+
import '@mui/icons-material/UploadFile';
|
|
36
|
+
import '@mui/icons-material/PictureAsPdf';
|
|
37
|
+
import '@mui/icons-material/TableChart';
|
|
38
|
+
import '@mui/icons-material/Description';
|
|
39
|
+
export { default as FormErrorField } from './FormErrorField/FormErrorField.esm.js';
|
|
40
|
+
export { default as HelperText } from './HelperText/HelperText.esm.js';
|
|
31
41
|
export { default as RichTextEditor } from './RichTextEditor/RichTextEditor.esm.js';
|
|
32
42
|
export { default as RichTextEditorWrapper } from './RichTextEditor/RichTextEditorWrapper.esm.js';
|
|
33
|
-
export { default as TimePicker } from './TimePicker/TimePicker.esm.js';
|
|
@@ -2,7 +2,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useMemo, useState, useRef, useLayoutEffect, useCallback, useEffect } from 'react';
|
|
3
3
|
import { MRT_ToggleGlobalFilterButton, MRT_ShowHideColumnsButton, MRT_ToggleDensePaddingButton, MRT_ToggleFullScreenButton, useMaterialReactTable, MaterialReactTable } from 'material-react-table';
|
|
4
4
|
import { useQuery, keepPreviousData } from '@tanstack/react-query';
|
|
5
|
-
import { Box, Tooltip, IconButton, GlobalStyles, Typography, Select,
|
|
5
|
+
import { Box, Tooltip, IconButton, Menu, MenuItem, GlobalStyles, Typography, Select, Skeleton } from '@mui/material';
|
|
6
6
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
|
7
7
|
import FileDownloadIcon from '@mui/icons-material/FileDownload';
|
|
8
8
|
import FirstPageIcon from '@mui/icons-material/FirstPage';
|
|
@@ -125,6 +125,19 @@ const buildHeaderGlobalStyles = (headerMin, headerMax, headerFont, headerBgColor
|
|
|
125
125
|
width: '100% !important',
|
|
126
126
|
fontSize: `${headerFont} !important`,
|
|
127
127
|
},
|
|
128
|
+
// Column resize handle: MRT's own default sx wins over the equivalent
|
|
129
|
+
// rule in buildHeaderCellSx (same CSS specificity, applied later in the
|
|
130
|
+
// emotion cache), leaving the drag hotspot a short ~24px strip centered
|
|
131
|
+
// in a much taller header cell — most of the column border is then
|
|
132
|
+
// unresponsive to drag. GlobalStyles + !important guarantees this wins.
|
|
133
|
+
'.tp-gpg-root .MuiTableHead-root .Mui-TableHeadCell-ResizeHandle-Wrapper': {
|
|
134
|
+
height: '100% !important',
|
|
135
|
+
top: '0 !important',
|
|
136
|
+
},
|
|
137
|
+
'.tp-gpg-root .MuiTableHead-root .Mui-TableHeadCell-ResizeHandle-Divider': {
|
|
138
|
+
height: '100% !important',
|
|
139
|
+
borderRight: 'none !important',
|
|
140
|
+
},
|
|
128
141
|
};
|
|
129
142
|
};
|
|
130
143
|
/** Per-cell sx merged into MRT (via muiTableHeadCellProps). */
|
|
@@ -156,8 +169,6 @@ const buildHeaderCellSx = (align, headerMin, headerMax, headerFont, headerBgColo
|
|
|
156
169
|
borderBottom: '2px solid rgba(0,0,0,0.15)',
|
|
157
170
|
'& button[aria-label="Move"]': { display: 'none !important' },
|
|
158
171
|
'& .MuiTableSortLabel-icon': { display: 'none !important' },
|
|
159
|
-
'& .Mui-TableHeadCell-ResizeHandle-Wrapper': { height: '100%', top: 0 },
|
|
160
|
-
'& .Mui-TableHeadCell-ResizeHandle-Divider': { borderRight: 'none' },
|
|
161
172
|
'& .Mui-TableHeadCell-Content': {
|
|
162
173
|
alignItems: 'center',
|
|
163
174
|
justifyContent: flexJustify,
|
|
@@ -358,6 +369,18 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
358
369
|
const [columnFilters, setColumnFilters] = useState([]);
|
|
359
370
|
const [globalFilter, setGlobalFilter] = useState('');
|
|
360
371
|
const [columnPinning, setColumnPinning] = useState({});
|
|
372
|
+
const [exportMenuAnchor, setExportMenuAnchor] = useState(null);
|
|
373
|
+
// Whether any column filter or Global Search is currently narrowing what's
|
|
374
|
+
// displayed. When true, Export offers a choice (filtered vs. complete);
|
|
375
|
+
// when false there's nothing to choose between, so it downloads directly.
|
|
376
|
+
const isFiltered = columnFilters.length > 0 || globalFilter.trim() !== '';
|
|
377
|
+
// Always points at the latest MRT table instance (assigned right after
|
|
378
|
+
// useMaterialReactTable below) so handleExport — defined earlier in this
|
|
379
|
+
// component body — can read the CURRENT filtered row model at click time
|
|
380
|
+
// without needing `table` in its own dependency array (which would create
|
|
381
|
+
// a circular reference, since `table`'s own options include the toolbar
|
|
382
|
+
// renderer that uses handleExport).
|
|
383
|
+
const tableRef = useRef(null);
|
|
361
384
|
// ── Viewport-fill height (mount + resize only — never on scroll) ─────────────
|
|
362
385
|
//
|
|
363
386
|
// Previously a scroll listener recalculated height as the grid moved within the
|
|
@@ -524,17 +547,24 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
524
547
|
setGlobalFilter('');
|
|
525
548
|
setPagination((p) => ({ ...p, pageIndex: 0 }));
|
|
526
549
|
}, [defaultFilters, defaultVisible]);
|
|
527
|
-
const handleExport = useCallback(async () => {
|
|
550
|
+
const handleExport = useCallback(async (scope = 'all') => {
|
|
528
551
|
// Loaded on demand (and cached) so the xlsx-js-style library is excluded
|
|
529
552
|
// from the initial bundle for consumers who never click Export.
|
|
530
553
|
const XLSX = await getXLSX();
|
|
554
|
+
// "filtered" = exactly what's currently displayed (column filters + global
|
|
555
|
+
// search applied) — sourced from MRT's own row model so it can never drift
|
|
556
|
+
// from what the user sees. "all" = every row in the current fetched batch,
|
|
557
|
+
// ignoring column filters/global search (unchanged pre-existing behavior).
|
|
558
|
+
const exportRows = scope === 'filtered' && tableRef.current
|
|
559
|
+
? tableRef.current.getFilteredRowModel().rows.map((r) => r.original)
|
|
560
|
+
: rows;
|
|
531
561
|
const dataCols = columns.filter((c) => 'accessorKey' in c && c.accessorKey);
|
|
532
562
|
// xlsx-js-style requires 8-char ARGB (AA + RRGGBB). Prepend full-opacity "FF".
|
|
533
563
|
const toArgb = (hex, fallback = 'FF1565C0') => hex?.startsWith('#') ? 'FF' + hex.slice(1).toUpperCase().padEnd(6, '0') : fallback;
|
|
534
564
|
const headerArgb = toArgb(exportHeaderBgColor ?? headerBgColor);
|
|
535
565
|
const textArgb = toArgb(exportHeaderTextColor, 'FFFFFFFF');
|
|
536
566
|
const headerRow = dataCols.map((c) => c.header ?? '');
|
|
537
|
-
const dataRows =
|
|
567
|
+
const dataRows = exportRows.map((row) => dataCols.map((c) => String(row[c.accessorKey] ?? '')));
|
|
538
568
|
const ws = XLSX.utils.aoa_to_sheet([headerRow, ...dataRows]);
|
|
539
569
|
// Style header row
|
|
540
570
|
dataCols.forEach((_, colIdx) => {
|
|
@@ -554,7 +584,7 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
554
584
|
// Auto-fit column widths — single O(n) pass accumulates max length per column
|
|
555
585
|
// instead of one reduce() per column (was O(n × cols)).
|
|
556
586
|
const colWidths = dataCols.map((c) => (c.header ?? '').length);
|
|
557
|
-
for (const row of
|
|
587
|
+
for (const row of exportRows) {
|
|
558
588
|
const r = row;
|
|
559
589
|
for (let ci = 0; ci < dataCols.length; ci++) {
|
|
560
590
|
const len = String(r[dataCols[ci].accessorKey] ?? '').length;
|
|
@@ -565,7 +595,8 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
565
595
|
ws['!cols'] = colWidths.map((w) => ({ wch: Math.max(w, 8) + 2 }));
|
|
566
596
|
const wb = XLSX.utils.book_new();
|
|
567
597
|
XLSX.utils.book_append_sheet(wb, ws, 'Data');
|
|
568
|
-
|
|
598
|
+
const suffix = scope === 'filtered' ? '-filtered' : '';
|
|
599
|
+
XLSX.writeFile(wb, `${exportFilename}${suffix}-page${pagination.pageIndex + 1}.xlsx`);
|
|
569
600
|
}, [columns, rows, exportFilename, pagination.pageIndex, headerBgColor, exportHeaderBgColor, exportHeaderTextColor]);
|
|
570
601
|
// ── Memoized cell-prop builders ───────────────────────────────────────────
|
|
571
602
|
// These are functions passed to MRT per-cell. Without useCallback they get
|
|
@@ -630,9 +661,11 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
630
661
|
alignItems: 'center',
|
|
631
662
|
flexWrap: isNarrow ? 'wrap' : 'nowrap',
|
|
632
663
|
flex: 1, minWidth: 0, pr: 1, gap: 0.5,
|
|
633
|
-
}, 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: resolvedUiDensity === 'compact' ? 0.35 : 0.5 }, children: jsx(RefreshIcon, { sx: { fontSize: resolvedUiDensity === 'compact' ? 18 : 20 } }) }) }) }), jsx(Tooltip, { title:
|
|
664
|
+
}, 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: resolvedUiDensity === 'compact' ? 0.35 : 0.5 }, children: jsx(RefreshIcon, { sx: { fontSize: resolvedUiDensity === 'compact' ? 18 : 20 } }) }) }) }), jsx(Tooltip, { title: isFiltered
|
|
665
|
+
? 'Export as Excel (.xlsx) — choose filtered or complete data'
|
|
666
|
+
: 'Export as Excel (.xlsx)', children: jsx("span", { children: jsx(IconButton, { id: `${resolvedGridId}_export_icon`, size: "small", onClick: (e) => isFiltered ? setExportMenuAnchor(e.currentTarget) : handleExport('all'), disabled: rows.length === 0 || isFetching, sx: { p: resolvedUiDensity === 'compact' ? 0.35 : 0.5 }, children: jsx(FileDownloadIcon, { sx: { fontSize: resolvedUiDensity === 'compact' ? 18 : 20 } }) }) }) }), jsxs(Menu, { id: `${resolvedGridId}_export_menu`, anchorEl: exportMenuAnchor, open: Boolean(exportMenuAnchor), onClose: () => setExportMenuAnchor(null), children: [jsxs(MenuItem, { id: `${resolvedGridId}_export_filtered_option`, onClick: () => { setExportMenuAnchor(null); handleExport('filtered'); }, children: ["Filtered data (", (tableRef.current?.getFilteredRowModel().rows.length ?? rows.length).toLocaleString(), " rows)"] }), jsxs(MenuItem, { id: `${resolvedGridId}_export_all_option`, onClick: () => { setExportMenuAnchor(null); handleExport('all'); }, children: ["Complete data (", rows.length.toLocaleString(), " rows)"] })] })] }), jsx(Box, { sx: { flex: 1, minWidth: isNarrow ? '100%' : 0 }, children: jsx(DynamicFilterBar, { serverFilterDefs: serverFilterDefs, visibleFilterIds: visibleFilterIds, onToggleFilter: handleToggleFilter, filterValues: filterValues, onFilterValuesChange: handleFilterValuesChange, columnFilters: columnFilters, onColumnFilterChange: setColumnFilters, availableColumns: availableColumns, maxVisibleFilters: effectiveMaxVisibleFilters, uiDensity: resolvedUiDensity, filterChipFontSize: densityTokens.filterChipFontSize, filterChipMinHeight: densityTokens.filterChipMinHeight, filterLabelFontSize: densityTokens.filterLabelFontSize, gridId: resolvedGridId }) })] })), [
|
|
634
667
|
resolvedGridId, isFetching, rows.length, resolvedUiDensity, isNarrow,
|
|
635
|
-
handleClearAll, refetch, handleExport,
|
|
668
|
+
handleClearAll, refetch, handleExport, isFiltered, exportMenuAnchor,
|
|
636
669
|
serverFilterDefs, visibleFilterIds, handleToggleFilter,
|
|
637
670
|
filterValues, handleFilterValuesChange, columnFilters, setColumnFilters,
|
|
638
671
|
availableColumns, effectiveMaxVisibleFilters, densityTokens, handleToggleFilter,
|
|
@@ -826,6 +859,9 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
826
859
|
renderToolbarInternalActions,
|
|
827
860
|
renderBottomToolbar,
|
|
828
861
|
});
|
|
862
|
+
// Keep the latest table instance available to handleExport (see tableRef
|
|
863
|
+
// declaration above) without adding `table` to its dependency array.
|
|
864
|
+
tableRef.current = table;
|
|
829
865
|
return (jsxs(Box, { ref: containerRef, id: resolvedGridId, className: "tp-gpg-root", sx: {
|
|
830
866
|
position: 'relative',
|
|
831
867
|
height: resolvedHeight,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DateRangePicker } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DateRangePicker } from '../../../../../_virtual/index.esm6.js';
|
|
2
2
|
import require$$0__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 DefinedRange } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DefinedRange } from '../../../../../_virtual/index.esm5.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireStyles } from '../../styles.esm.js';
|