@bsol-oss/react-datatable5 1.0.63 → 1.0.64
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/index.d.ts +105 -70
- package/dist/index.js +218 -205
- package/dist/index.mjs +136 -123
- package/dist/types/components/DataTable/DataTableContext.d.ts +1 -0
- package/dist/types/components/DataTable/useDataTable.d.ts +1 -0
- package/dist/types/index.d.ts +40 -6
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,27 +1,123 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { IconButton, Button, useDisclosure, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Flex, ModalFooter, Text, Menu, MenuButton, MenuList, MenuItem, Box, FormLabel, Checkbox, Grid, Spinner, Tooltip, Icon, Tfoot, Tr as Tr$1, Th, Thead, Portal, Table as Table$1, Card, CardBody, VStack, FormControl, Input, RangeSlider, RangeSliderTrack, RangeSliderFilledTrack, RangeSliderThumb, WrapItem, Tag, TagLabel, TagCloseButton, Select, ButtonGroup, Switch, InputGroup, InputLeftElement } from '@chakra-ui/react';
|
|
3
|
+
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
4
|
+
import { MdFilterAlt, MdOutlineMoveDown, MdOutlineSort, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdArrowUpward, MdArrowDownward, MdFirstPage, MdArrowBack, MdArrowForward, MdLastPage, MdOutlineChecklist, MdClose, MdSearch } from 'react-icons/md';
|
|
5
|
+
import { UpDownIcon, ChevronDownIcon, ChevronUpIcon, CloseIcon } from '@chakra-ui/icons';
|
|
6
|
+
import { createContext, useContext, useState, useEffect } from 'react';
|
|
7
|
+
import { IoMdEye, IoMdCheckbox } from 'react-icons/io';
|
|
2
8
|
import { makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, flexRender } from '@tanstack/react-table';
|
|
3
|
-
import { createContext, useState, useEffect, useContext } from 'react';
|
|
4
9
|
import { rankItem } from '@tanstack/match-sorter-utils';
|
|
5
10
|
import axios from 'axios';
|
|
6
|
-
import { Box, FormLabel, Checkbox, Grid, Flex, Text, Tfoot, Tr as Tr$1, Th, Menu, MenuButton, Thead, Portal, MenuList, MenuItem, IconButton, Button, useDisclosure, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, ModalFooter, InputGroup, InputLeftElement, Icon, Input, Table as Table$1, Card, CardBody, VStack, FormControl, RangeSlider, RangeSliderTrack, RangeSliderFilledTrack, RangeSliderThumb, WrapItem, Tag, TagLabel, TagCloseButton, Select, ButtonGroup, Switch, Tooltip } from '@chakra-ui/react';
|
|
7
11
|
import { Tbody, Tr, Td } from '@chakra-ui/table';
|
|
8
|
-
import {
|
|
9
|
-
import { ChevronUpIcon, ChevronDownIcon, UpDownIcon, CloseIcon } from '@chakra-ui/icons';
|
|
12
|
+
import { BsExclamationCircleFill } from 'react-icons/bs';
|
|
10
13
|
import { GrAscend, GrDescend } from 'react-icons/gr';
|
|
11
|
-
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
12
|
-
import { IoMdEye, IoMdCheckbox } from 'react-icons/io';
|
|
13
14
|
import { IoReload } from 'react-icons/io5';
|
|
14
15
|
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
|
15
16
|
import { FaGripLinesVertical } from 'react-icons/fa';
|
|
16
17
|
|
|
18
|
+
const DensityToggleButton = ({ text, icon = jsx(AiOutlineColumnWidth, {}), }) => {
|
|
19
|
+
const { table } = useDataTable();
|
|
20
|
+
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { variant: "ghost", "aria-label": "Toggle Density", icon: icon, onClick: () => {
|
|
21
|
+
table.toggleDensity();
|
|
22
|
+
} })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", "aria-label": "Toggle Density", onClick: () => {
|
|
23
|
+
table.toggleDensity();
|
|
24
|
+
}, children: text }))] }));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const EditFilterButton = ({ text, title = "Edit Filter", closeText = "Close", resetText = "Reset", icon = jsx(MdFilterAlt, {}), ...props }) => {
|
|
28
|
+
const filterModal = useDisclosure();
|
|
29
|
+
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: filterModal.onOpen, "aria-label": "filter", ...props })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: filterModal.onOpen, ...props, children: text })), jsxs(Modal, { isOpen: filterModal.isOpen, onClose: filterModal.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsxs(Flex, { flexFlow: "column", gap: "1rem", children: [jsx(TableFilter, {}), jsx(ResetFilteringButton, { text: resetText })] }) }), jsx(ModalFooter, { children: jsx(Button, { onClick: filterModal.onClose, children: closeText }) })] })] })] }));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const EditOrderButton = ({ text, icon = jsx(MdOutlineMoveDown, {}), title = "Change Order", }) => {
|
|
33
|
+
const orderModal = useDisclosure();
|
|
34
|
+
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: orderModal.onOpen, "aria-label": "change order" })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: orderModal.onOpen, children: text })), jsxs(Modal, { isOpen: orderModal.isOpen, onClose: orderModal.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { padding: "0 0 1rem 0", children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsx(Flex, { flexFlow: "column", gap: "0.25rem", children: jsx(TableOrderer, {}) }) })] })] })] }));
|
|
35
|
+
};
|
|
36
|
+
|
|
17
37
|
const TableContext = createContext({
|
|
18
38
|
table: {},
|
|
19
39
|
refreshData: () => { },
|
|
20
40
|
globalFilter: "",
|
|
21
41
|
setGlobalFilter: () => { },
|
|
22
42
|
loading: false,
|
|
43
|
+
hasError: false,
|
|
23
44
|
});
|
|
24
45
|
|
|
46
|
+
const useDataTable = () => {
|
|
47
|
+
const { table, refreshData, globalFilter, setGlobalFilter, loading, hasError, } = useContext(TableContext);
|
|
48
|
+
return {
|
|
49
|
+
table,
|
|
50
|
+
refreshData,
|
|
51
|
+
globalFilter,
|
|
52
|
+
setGlobalFilter,
|
|
53
|
+
loading,
|
|
54
|
+
hasError,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const TableSorter = () => {
|
|
59
|
+
const { table } = useDataTable();
|
|
60
|
+
return (jsx(Fragment, { children: table.getHeaderGroups().map((headerGroup) => (jsx(Fragment, { children: headerGroup.headers.map((header) => {
|
|
61
|
+
const displayName = header.column.columnDef.meta === undefined
|
|
62
|
+
? header.column.id
|
|
63
|
+
: header.column.columnDef.meta.displayName;
|
|
64
|
+
return (jsx(Fragment, { children: header.column.getCanSort() && (jsxs(Flex, { alignItems: "center", gap: "0.5rem", padding: "0.5rem", children: [jsx(Text, { children: displayName }), jsxs(Button, { variant: "ghost", onClick: (e) => {
|
|
65
|
+
header.column.toggleSorting();
|
|
66
|
+
}, children: [header.column.getIsSorted() === false && (
|
|
67
|
+
// <Text>To No sort</Text>
|
|
68
|
+
jsx(UpDownIcon, {})), header.column.getIsSorted() === "asc" && (
|
|
69
|
+
// <Text>To asc</Text>
|
|
70
|
+
jsx(ChevronDownIcon, {})), header.column.getIsSorted() === "desc" && (
|
|
71
|
+
// <Text>To desc</Text>
|
|
72
|
+
jsx(ChevronUpIcon, {}))] }), header.column.getIsSorted() && (jsx(Button, { onClick: (e) => {
|
|
73
|
+
header.column.clearSorting();
|
|
74
|
+
}, children: jsx(CloseIcon, {}) }))] })) }));
|
|
75
|
+
}) }))) }));
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const EditSortingButton = ({ text, icon = jsx(MdOutlineSort, {}), title = "Edit Sorting", }) => {
|
|
79
|
+
const sortingModal = useDisclosure();
|
|
80
|
+
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: sortingModal.onOpen, "aria-label": "change sorting" })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: sortingModal.onOpen, children: text })), jsxs(Modal, { isOpen: sortingModal.isOpen, onClose: sortingModal.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { padding: "0 0 1rem 0", children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(TableSorter, {}), jsx(ResetSortingButton, {})] }) })] })] })] }));
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const EditViewButton = ({ text, icon = jsx(IoMdEye, {}), title = "Edit View", }) => {
|
|
84
|
+
const viewModel = useDisclosure();
|
|
85
|
+
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: viewModel.onOpen, "aria-label": "change sorting" })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: viewModel.onOpen, children: text })), jsxs(Modal, { isOpen: viewModel.isOpen, onClose: viewModel.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { padding: "0 0 1rem 0", children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsx(TableViewer, {}) })] })] })] }));
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const PageSizeControl = ({ pageSizes = [10, 20, 30, 40, 50], }) => {
|
|
89
|
+
const { table } = useDataTable();
|
|
90
|
+
return (jsx(Fragment, { children: jsxs(Menu, { children: [jsx(MenuButton, { as: Button, variant: "ghost", rightIcon: jsx(ChevronDownIcon, {}), gap: "0.5rem", children: table.getState().pagination.pageSize }), jsx(MenuList, { children: pageSizes.map((pageSize) => (jsx(MenuItem, { onClick: () => {
|
|
91
|
+
table.setPageSize(Number(pageSize));
|
|
92
|
+
}, children: pageSize }, crypto.randomUUID()))) })] }) }));
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const ResetFilteringButton = ({ text = "Reset Filtering", }) => {
|
|
96
|
+
const { table } = useDataTable();
|
|
97
|
+
return (jsx(Button, { onClick: () => {
|
|
98
|
+
table.resetColumnFilters();
|
|
99
|
+
}, children: text }));
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const ResetSelectionButton = ({ text = "Reset Selection", }) => {
|
|
103
|
+
const { table } = useDataTable();
|
|
104
|
+
return (jsx(Button, { onClick: () => {
|
|
105
|
+
table.resetRowSelection();
|
|
106
|
+
}, children: text }));
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const ResetSortingButton = ({ text = "Reset Sorting", }) => {
|
|
110
|
+
const { table } = useDataTable();
|
|
111
|
+
return (jsx(Button, { onClick: () => {
|
|
112
|
+
table.resetSorting();
|
|
113
|
+
}, children: text }));
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const RowCountText = () => {
|
|
117
|
+
const { table } = useDataTable();
|
|
118
|
+
return jsx(Text, { children: table.getRowCount() });
|
|
119
|
+
};
|
|
120
|
+
|
|
25
121
|
// Reference: https://tanstack.com/table/latest/docs/framework/react/examples/custom-features
|
|
26
122
|
// TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features
|
|
27
123
|
// end of TS setup!
|
|
@@ -172,6 +268,7 @@ const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
172
268
|
globalFilter: globalFilter,
|
|
173
269
|
setGlobalFilter: setGlobalFilter,
|
|
174
270
|
loading: false,
|
|
271
|
+
hasError: false,
|
|
175
272
|
}, children: children }));
|
|
176
273
|
};
|
|
177
274
|
|
|
@@ -184,6 +281,7 @@ const useDataFromUrl = ({ url, params = {}, disableFirstFetch = false, onFetchSu
|
|
|
184
281
|
};
|
|
185
282
|
const getData = async () => {
|
|
186
283
|
try {
|
|
284
|
+
setHasError(false);
|
|
187
285
|
setLoading(true);
|
|
188
286
|
const { data } = await axios.get(url, { params: params });
|
|
189
287
|
console.debug("get DataFromUrl success", data);
|
|
@@ -294,7 +392,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
|
|
|
294
392
|
});
|
|
295
393
|
useEffect(() => {
|
|
296
394
|
refreshData();
|
|
297
|
-
}, [pagination, sorting, columnFilters, globalFilter]);
|
|
395
|
+
}, [pagination, sorting, columnFilters, globalFilter, url]);
|
|
298
396
|
useEffect(() => {
|
|
299
397
|
setColumnOrder(table.getAllLeafColumns().map((column) => column.id));
|
|
300
398
|
}, []);
|
|
@@ -307,6 +405,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
|
|
|
307
405
|
globalFilter,
|
|
308
406
|
setGlobalFilter,
|
|
309
407
|
loading: loading,
|
|
408
|
+
hasError: hasError,
|
|
310
409
|
}, children: children }));
|
|
311
410
|
};
|
|
312
411
|
|
|
@@ -360,16 +459,12 @@ const TableRowSelector = ({ index, row, hoveredRow, pinnedBgColor = { light: "gr
|
|
|
360
459
|
};
|
|
361
460
|
|
|
362
461
|
const TableControls = ({ totalText = "Total:", showFilter = false, fitTableWidth = false, fitTableHeight = false, isMobile = false, children = jsx(Fragment, {}), showFilterName = false, showFilterTags = false, filterOptions = [], }) => {
|
|
363
|
-
|
|
462
|
+
const { loading, hasError } = useDataTable();
|
|
463
|
+
return (jsxs(Grid, { templateRows: "auto auto auto 1fr auto", templateColumns: "1fr 1fr", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", justifySelf: "center", alignSelf: "center", gap: "0.5rem", children: [jsxs(Flex, { justifyContent: "space-between", gridColumn: "1 / span 2", children: [jsx(Box, { children: jsx(EditViewButton, { text: isMobile ? undefined : "View", icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: "1rem", alignItems: "center", justifySelf: "end", children: [loading && jsx(Spinner, { size: "sm" }), hasError && (jsx(Tooltip, { label: "An error occurred while fetching data", children: jsx(Box, { children: jsx(Icon, { as: BsExclamationCircleFill, color: "red.400" }) }) })), showFilter && (jsxs(Fragment, { children: [jsx(GlobalFilter, {}), jsx(EditFilterButton, { text: isMobile ? undefined : "Advanced Filter" })] }))] })] }), jsx(Flex, { gridColumn: "1 / span 2", flexFlow: "column", gap: "0.5rem", children: filterOptions.map((column) => {
|
|
364
464
|
return (jsxs(Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [showFilterName && jsxs(Text, { children: [column, ":"] }), jsx(FilterOptions, { column: column })] }));
|
|
365
465
|
}) }), jsx(Flex, { gridColumn: "1 / span 2", children: showFilterTags && jsx(TableFilterTags, {}) }), jsx(Box, { overflow: "auto", gridColumn: "1 / span 2", width: "100%", height: "100%", children: children }), jsxs(Flex, { gap: "1rem", alignItems: "center", children: [jsx(PageSizeControl, {}), jsxs(Flex, { children: [jsx(Text, { paddingRight: "0.5rem", children: totalText }), jsx(RowCountText, {})] })] }), jsx(Box, { justifySelf: "end", children: jsx(TablePagination, {}) })] }));
|
|
366
466
|
};
|
|
367
467
|
|
|
368
|
-
const useDataTable = () => {
|
|
369
|
-
const { table, refreshData, globalFilter, setGlobalFilter, loading } = useContext(TableContext);
|
|
370
|
-
return { table, refreshData, globalFilter, setGlobalFilter, loading };
|
|
371
|
-
};
|
|
372
|
-
|
|
373
468
|
const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
|
|
374
469
|
const table = useDataTable().table;
|
|
375
470
|
const SELECTION_BOX_WIDTH = 20;
|
|
@@ -504,115 +599,6 @@ const DefaultTable = ({ totalText = "Total:", showFilter = false, showFooter = f
|
|
|
504
599
|
return (jsx(TableControls, { totalText: totalText, showFilter: showFilter, fitTableWidth: fitTableWidth, fitTableHeight: fitTableHeight, isMobile: isMobile, filterOptions: filterOptions, showFilterName: showFilterName, showFilterTags: showFilterTags, children: jsxs(Table, { variant: "striped", children: [jsx(TableHeader, { canResize: true }), jsx(TableBody, {}), showFooter && jsx(TableFooter, {})] }) }));
|
|
505
600
|
};
|
|
506
601
|
|
|
507
|
-
const DensityToggleButton = ({ text, icon = jsx(AiOutlineColumnWidth, {}), }) => {
|
|
508
|
-
const { table } = useDataTable();
|
|
509
|
-
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { variant: "ghost", "aria-label": "Toggle Density", icon: icon, onClick: () => {
|
|
510
|
-
table.toggleDensity();
|
|
511
|
-
} })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", "aria-label": "Toggle Density", onClick: () => {
|
|
512
|
-
table.toggleDensity();
|
|
513
|
-
}, children: text }))] }));
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
const EditFilterButton = ({ text, title = "Edit Filter", closeText = "Close", resetText = "Reset", icon = jsx(MdFilterAlt, {}), ...props }) => {
|
|
517
|
-
const filterModal = useDisclosure();
|
|
518
|
-
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: filterModal.onOpen, "aria-label": "filter", ...props })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: filterModal.onOpen, ...props, children: text })), jsxs(Modal, { isOpen: filterModal.isOpen, onClose: filterModal.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsxs(Flex, { flexFlow: "column", gap: "1rem", children: [jsx(TableFilter, {}), jsx(ResetFilteringButton, { text: resetText })] }) }), jsx(ModalFooter, { children: jsx(Button, { onClick: filterModal.onClose, children: closeText }) })] })] })] }));
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
const EditOrderButton = ({ text, icon = jsx(MdOutlineMoveDown, {}), title = "Change Order", }) => {
|
|
522
|
-
const orderModal = useDisclosure();
|
|
523
|
-
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: orderModal.onOpen, "aria-label": "change order" })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: orderModal.onOpen, children: text })), jsxs(Modal, { isOpen: orderModal.isOpen, onClose: orderModal.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { padding: "0 0 1rem 0", children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsx(Flex, { flexFlow: "column", gap: "0.25rem", children: jsx(TableOrderer, {}) }) })] })] })] }));
|
|
524
|
-
};
|
|
525
|
-
|
|
526
|
-
const TableSorter = () => {
|
|
527
|
-
const { table } = useDataTable();
|
|
528
|
-
return (jsx(Fragment, { children: table.getHeaderGroups().map((headerGroup) => (jsx(Fragment, { children: headerGroup.headers.map((header) => {
|
|
529
|
-
const displayName = header.column.columnDef.meta === undefined
|
|
530
|
-
? header.column.id
|
|
531
|
-
: header.column.columnDef.meta.displayName;
|
|
532
|
-
return (jsx(Fragment, { children: header.column.getCanSort() && (jsxs(Flex, { alignItems: "center", gap: "0.5rem", padding: "0.5rem", children: [jsx(Text, { children: displayName }), jsxs(Button, { variant: "ghost", onClick: (e) => {
|
|
533
|
-
header.column.toggleSorting();
|
|
534
|
-
}, children: [header.column.getIsSorted() === false && (
|
|
535
|
-
// <Text>To No sort</Text>
|
|
536
|
-
jsx(UpDownIcon, {})), header.column.getIsSorted() === "asc" && (
|
|
537
|
-
// <Text>To asc</Text>
|
|
538
|
-
jsx(ChevronDownIcon, {})), header.column.getIsSorted() === "desc" && (
|
|
539
|
-
// <Text>To desc</Text>
|
|
540
|
-
jsx(ChevronUpIcon, {}))] }), header.column.getIsSorted() && (jsx(Button, { onClick: (e) => {
|
|
541
|
-
header.column.clearSorting();
|
|
542
|
-
}, children: jsx(CloseIcon, {}) }))] })) }));
|
|
543
|
-
}) }))) }));
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
const EditSortingButton = ({ text, icon = jsx(MdOutlineSort, {}), title = "Edit Sorting", }) => {
|
|
547
|
-
const sortingModal = useDisclosure();
|
|
548
|
-
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: sortingModal.onOpen, "aria-label": "change sorting" })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: sortingModal.onOpen, children: text })), jsxs(Modal, { isOpen: sortingModal.isOpen, onClose: sortingModal.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { padding: "0 0 1rem 0", children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(TableSorter, {}), jsx(ResetSortingButton, {})] }) })] })] })] }));
|
|
549
|
-
};
|
|
550
|
-
|
|
551
|
-
const EditViewButton = ({ text, icon = jsx(IoMdEye, {}), title = "Edit View", }) => {
|
|
552
|
-
const viewModel = useDisclosure();
|
|
553
|
-
return (jsxs(Fragment, { children: [!!text === false && (jsx(IconButton, { icon: icon, variant: "ghost", onClick: viewModel.onOpen, "aria-label": "change sorting" })), !!text !== false && (jsx(Button, { leftIcon: icon, variant: "ghost", onClick: viewModel.onOpen, children: text })), jsxs(Modal, { isOpen: viewModel.isOpen, onClose: viewModel.onClose, size: ["full", "full", "md", "md"], children: [jsx(ModalOverlay, {}), jsxs(ModalContent, { padding: "0 0 1rem 0", children: [jsx(ModalHeader, { children: title }), jsx(ModalCloseButton, {}), jsx(ModalBody, { children: jsx(TableViewer, {}) })] })] })] }));
|
|
554
|
-
};
|
|
555
|
-
|
|
556
|
-
const FilterOptions = ({ column }) => {
|
|
557
|
-
const { table } = useDataTable();
|
|
558
|
-
const tableColumn = table.getColumn(column);
|
|
559
|
-
const options = tableColumn?.columnDef.meta?.filterOptions ?? [];
|
|
560
|
-
return (jsx(Fragment, { children: options.map((option) => {
|
|
561
|
-
const selected = table.getColumn(column)?.getFilterValue() === option;
|
|
562
|
-
return (jsxs(Button, { size: "sm", onClick: () => {
|
|
563
|
-
if (selected) {
|
|
564
|
-
table.setColumnFilters((state) => {
|
|
565
|
-
return state.filter((filter) => {
|
|
566
|
-
return filter.id !== column;
|
|
567
|
-
});
|
|
568
|
-
});
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
table.getColumn(column)?.setFilterValue(option);
|
|
572
|
-
}, variant: selected ? "solid" : "outline", display: "flex", gap: "0.25rem", children: [option, selected && jsx(MdClose, {})] }, option));
|
|
573
|
-
}) }));
|
|
574
|
-
};
|
|
575
|
-
|
|
576
|
-
const GlobalFilter = ({ icon = MdSearch }) => {
|
|
577
|
-
const { globalFilter, setGlobalFilter } = useDataTable();
|
|
578
|
-
return (jsx(Fragment, { children: jsx(Box, { children: jsxs(InputGroup, { children: [jsx(InputLeftElement, { pointerEvents: "none", children: jsx(Icon, { as: icon, color: "gray.300" }) }), jsx(Input, { value: globalFilter, onChange: (e) => {
|
|
579
|
-
setGlobalFilter(e.target.value);
|
|
580
|
-
} })] }) }) }));
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
const PageSizeControl = ({ pageSizes = [10, 20, 30, 40, 50], }) => {
|
|
584
|
-
const { table } = useDataTable();
|
|
585
|
-
return (jsx(Fragment, { children: jsxs(Menu, { children: [jsx(MenuButton, { as: Button, variant: "ghost", rightIcon: jsx(ChevronDownIcon, {}), gap: "0.5rem", children: table.getState().pagination.pageSize }), jsx(MenuList, { children: pageSizes.map((pageSize) => (jsx(MenuItem, { onClick: () => {
|
|
586
|
-
table.setPageSize(Number(pageSize));
|
|
587
|
-
}, children: pageSize }, crypto.randomUUID()))) })] }) }));
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
const ResetFilteringButton = ({ text = "Reset Filtering", }) => {
|
|
591
|
-
const { table } = useDataTable();
|
|
592
|
-
return (jsx(Button, { onClick: () => {
|
|
593
|
-
table.resetColumnFilters();
|
|
594
|
-
}, children: text }));
|
|
595
|
-
};
|
|
596
|
-
|
|
597
|
-
const ResetSelectionButton = ({ text = "Reset Selection", }) => {
|
|
598
|
-
const { table } = useDataTable();
|
|
599
|
-
return (jsx(Button, { onClick: () => {
|
|
600
|
-
table.resetRowSelection();
|
|
601
|
-
}, children: text }));
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
const ResetSortingButton = ({ text = "Reset Sorting", }) => {
|
|
605
|
-
const { table } = useDataTable();
|
|
606
|
-
return (jsx(Button, { onClick: () => {
|
|
607
|
-
table.resetSorting();
|
|
608
|
-
}, children: text }));
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
const RowCountText = () => {
|
|
612
|
-
const { table } = useDataTable();
|
|
613
|
-
return jsx(Text, { children: table.getRowCount() });
|
|
614
|
-
};
|
|
615
|
-
|
|
616
602
|
const Table = ({ children, showLoading = false, loadingComponent = jsx(Fragment, { children: "Loading..." }), ...props }) => {
|
|
617
603
|
const { table, loading } = useDataTable();
|
|
618
604
|
if (showLoading) {
|
|
@@ -877,4 +863,31 @@ const TextCell = ({ label, noOfLines = [1], padding = "0rem", children, tooltipP
|
|
|
877
863
|
return (jsx(Flex, { alignItems: "center", height: "100%", padding: padding, children: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", noOfLines: noOfLines, ...props, children: children }) }));
|
|
878
864
|
};
|
|
879
865
|
|
|
866
|
+
const FilterOptions = ({ column }) => {
|
|
867
|
+
const { table } = useDataTable();
|
|
868
|
+
const tableColumn = table.getColumn(column);
|
|
869
|
+
const options = tableColumn?.columnDef.meta?.filterOptions ?? [];
|
|
870
|
+
return (jsx(Fragment, { children: options.map((option) => {
|
|
871
|
+
const selected = table.getColumn(column)?.getFilterValue() === option;
|
|
872
|
+
return (jsxs(Button, { size: "sm", onClick: () => {
|
|
873
|
+
if (selected) {
|
|
874
|
+
table.setColumnFilters((state) => {
|
|
875
|
+
return state.filter((filter) => {
|
|
876
|
+
return filter.id !== column;
|
|
877
|
+
});
|
|
878
|
+
});
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
table.getColumn(column)?.setFilterValue(option);
|
|
882
|
+
}, variant: selected ? "solid" : "outline", display: "flex", gap: "0.25rem", children: [option, selected && jsx(MdClose, {})] }, option));
|
|
883
|
+
}) }));
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
const GlobalFilter = ({ icon = MdSearch }) => {
|
|
887
|
+
const { globalFilter, setGlobalFilter } = useDataTable();
|
|
888
|
+
return (jsx(Fragment, { children: jsx(Box, { children: jsxs(InputGroup, { children: [jsx(InputLeftElement, { pointerEvents: "none", children: jsx(Icon, { as: icon, color: "gray.300" }) }), jsx(Input, { value: globalFilter, onChange: (e) => {
|
|
889
|
+
setGlobalFilter(e.target.value);
|
|
890
|
+
} })] }) }) }));
|
|
891
|
+
};
|
|
892
|
+
|
|
880
893
|
export { DataTable, DataTableServer, DefaultTable, DensityToggleButton, EditFilterButton, EditOrderButton, EditSortingButton, EditViewButton, FilterOptions, GlobalFilter, PageSizeControl, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableOrderer, TablePagination, TableSelector, TableSorter, TableViewer, TextCell, useDataFromUrl, useDataTable };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,36 +2,68 @@
|
|
|
2
2
|
import { Column, RowData } from "@tanstack/react-table";
|
|
3
3
|
declare module "@tanstack/react-table" {
|
|
4
4
|
interface ColumnMeta<TData extends RowData, TValue> {
|
|
5
|
+
/**
|
|
6
|
+
* The display name of the column, used for rendering headers.
|
|
7
|
+
*/
|
|
5
8
|
displayName?: string;
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
10
|
+
* Specifies the type of filter to be used for the column.
|
|
11
|
+
*
|
|
12
|
+
* @remarks You should provide a proper `filterfn` to handle filtering when choosing `boolean`, `dateRange`, and `custom`.
|
|
13
|
+
*
|
|
14
|
+
* @remarks You should decide `renderFilter` to display filter ui when choosing `custom`.
|
|
15
|
+
*
|
|
16
|
+
* Possible values:
|
|
17
|
+
* - "text": A text input filter.
|
|
18
|
+
* - "range": A numerical range filter.
|
|
19
|
+
* - "select": A dropdown select filter.
|
|
20
|
+
* - "tag": A tag-based filter.
|
|
21
|
+
* - "boolean": A true/false filter.
|
|
22
|
+
* - "dateRange": A date range filter.
|
|
23
|
+
* - "custom": A custom filter function.
|
|
8
24
|
*/
|
|
9
25
|
filterVariant?: "text" | "range" | "select" | "tag" | "boolean" | "dateRange" | "custom";
|
|
26
|
+
/**
|
|
27
|
+
* Options for the select filter variant, if applicable.
|
|
28
|
+
*/
|
|
10
29
|
filterOptions?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for the range filter variant, if applicable.
|
|
32
|
+
*
|
|
33
|
+
* Properties:
|
|
34
|
+
* - `min`: Minimum value for the range.
|
|
35
|
+
* - `max`: Maximum value for the range.
|
|
36
|
+
* - `step`: Step increment for the range.
|
|
37
|
+
* - `defaultValue`: Default range values for the filter.
|
|
38
|
+
*/
|
|
11
39
|
filterRangeConfig?: {
|
|
12
40
|
min: number;
|
|
13
41
|
max: number;
|
|
14
42
|
step: number;
|
|
15
43
|
defaultValue: [number, number];
|
|
16
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* A function that renders the filter component for the column.
|
|
47
|
+
*
|
|
48
|
+
* @param column - The column for which the filter is being rendered.
|
|
49
|
+
* @returns A JSX element representing the filter UI.
|
|
50
|
+
*/
|
|
17
51
|
renderFilter?: (column: Column<TData>) => JSX.Element;
|
|
18
52
|
}
|
|
19
53
|
}
|
|
20
|
-
export * from "./components/DataTable/DataTable";
|
|
21
|
-
export * from "./components/DataTable/DataTableServer";
|
|
22
|
-
export * from "./components/DataTable/DefaultTable";
|
|
23
54
|
export * from "./components/Controls/DensityToggleButton";
|
|
24
55
|
export * from "./components/Controls/EditFilterButton";
|
|
25
56
|
export * from "./components/Controls/EditOrderButton";
|
|
26
57
|
export * from "./components/Controls/EditSortingButton";
|
|
27
58
|
export * from "./components/Controls/EditViewButton";
|
|
28
|
-
export * from "./components/Filter/FilterOptions";
|
|
29
|
-
export * from "./components/Filter/GlobalFilter";
|
|
30
59
|
export * from "./components/Controls/PageSizeControl";
|
|
31
60
|
export * from "./components/Controls/ResetFilteringButton";
|
|
32
61
|
export * from "./components/Controls/ResetSelectionButton";
|
|
33
62
|
export * from "./components/Controls/ResetSortingButton";
|
|
34
63
|
export * from "./components/Controls/RowCountText";
|
|
64
|
+
export * from "./components/DataTable/DataTable";
|
|
65
|
+
export * from "./components/DataTable/DataTableServer";
|
|
66
|
+
export * from "./components/DataTable/DefaultTable";
|
|
35
67
|
export * from "./components/DataTable/Table";
|
|
36
68
|
export * from "./components/DataTable/TableBody";
|
|
37
69
|
export * from "./components/DataTable/TableCardContainer";
|
|
@@ -52,3 +84,5 @@ export * from "./components/DataTable/TableViewer";
|
|
|
52
84
|
export * from "./components/DataTable/TextCell";
|
|
53
85
|
export * from "./components/DataTable/useDataFromUrl";
|
|
54
86
|
export * from "./components/DataTable/useDataTable";
|
|
87
|
+
export * from "./components/Filter/FilterOptions";
|
|
88
|
+
export * from "./components/Filter/GlobalFilter";
|