@bsol-oss/react-datatable5 1.0.25 → 1.0.27

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/README.md CHANGED
@@ -12,18 +12,18 @@ npm install @tanstack/react-table @chakra-ui/react @bsol-oss/react-datatable5
12
12
 
13
13
  ```tsx
14
14
  <DataTable columns={columns} data={data}>
15
- <Flex gap="0.25rem">
15
+ <Flex>
16
16
  <TablePagination />
17
17
  <ButtonGroup isAttached>
18
18
  <EditViewButton />
19
19
  <EditFilterButton />
20
- <EditSortingButton />
21
20
  </ButtonGroup>
22
21
  <EditOrderButton />
23
22
  <PageSizeControl />
24
23
  <ButtonGroup isAttached>
25
24
  <TableSelector />
26
25
  </ButtonGroup>
26
+ <GlobalFilter />
27
27
  </Flex>
28
28
  <Table>
29
29
  <TableHeader canResize />
@@ -42,31 +42,43 @@ npm install @tanstack/react-table @chakra-ui/react @bsol-oss/react-datatable5
42
42
  columns={columns}
43
43
  url={"http://localhost:8333/api/v1/gpt/chat/history/all"}
44
44
  >
45
- <Flex gap="0.25rem">
45
+ <Flex>
46
46
  <TablePagination />
47
47
  <ButtonGroup isAttached>
48
48
  <EditViewButton />
49
49
  <EditFilterButton />
50
- <EditSortingButton />
50
+ <DensityToggleButton />
51
51
  </ButtonGroup>
52
52
  <EditOrderButton />
53
53
  <PageSizeControl />
54
54
  <ButtonGroup isAttached>
55
55
  <TableSelector />
56
56
  </ButtonGroup>
57
+ <GlobalFilter />
57
58
  </Flex>
58
59
  <Table>
59
60
  <TableHeader canResize />
60
61
  <TableBody />
61
62
  <TableFooter />
62
63
  </Table>
63
- <PageSizeControl />
64
- <TablePagination />
64
+ <Flex gap="0.25rem">
65
+ <TablePagination />
66
+ <ButtonGroup isAttached>
67
+ <EditViewButton />
68
+ <EditFilterButton />
69
+ </ButtonGroup>
70
+ <EditOrderButton />
71
+ <PageSizeControl />
72
+ <ButtonGroup isAttached>
73
+ <TableSelector />
74
+ </ButtonGroup>
75
+ </Flex>
65
76
  </DataTableServer>
66
77
  ```
67
78
 
68
79
  Example Url generated by the DataTableServer
69
80
 
70
81
  ```
71
- GET http://localhost:8333/api/v1/gpt/chat/history/all?pagination={"offset":0,"rows":10}&sorting={"field":"session_id","sort":"asc"}&where={"last_user_message":"vdsdf"}
72
- ```
82
+ GET
83
+ http://localhost:8333/api/v1/gpt/chat/history/all?pagination={"offset":0,"rows":10}&sorting={}&where={}&searching=hello
84
+ ```
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import { RankingInfo } from '@tanstack/match-sorter-utils';
5
5
  import { ReactNode } from 'react';
6
6
  import * as _tanstack_table_core from '@tanstack/table-core';
7
7
 
8
- declare module '@tanstack/react-table' {
8
+ declare module "@tanstack/react-table" {
9
9
  interface FilterFns {
10
10
  fuzzy: FilterFn<unknown>;
11
11
  }
@@ -46,6 +46,8 @@ declare module "@tanstack/react-table" {
46
46
  }
47
47
  declare const DataTableServer: <TData>({ columns, url, enableRowSelection, enableMultiRowSelection, enableSubRowSelection, children, }: DataTableServerProps<TData>) => react_jsx_runtime.JSX.Element;
48
48
 
49
+ declare const DensityToggleButton: () => react_jsx_runtime.JSX.Element;
50
+
49
51
  declare const EditFilterButton: () => react_jsx_runtime.JSX.Element;
50
52
 
51
53
  declare const EditOrderButton: () => react_jsx_runtime.JSX.Element;
@@ -70,9 +72,15 @@ declare const ResetSortingButton: () => react_jsx_runtime.JSX.Element;
70
72
  interface TableProps {
71
73
  children: ReactNode;
72
74
  }
73
- declare const Table: ({ children }: TableProps) => react_jsx_runtime.JSX.Element;
75
+ declare const Table: ({ children, ...props }: TableProps) => react_jsx_runtime.JSX.Element;
74
76
 
75
- declare const TableBody: () => react_jsx_runtime.JSX.Element;
77
+ interface TableBodyProps {
78
+ pinnedBgColor?: {
79
+ light: string;
80
+ dark: string;
81
+ };
82
+ }
83
+ declare const TableBody: ({ pinnedBgColor, }: TableBodyProps) => react_jsx_runtime.JSX.Element;
76
84
 
77
85
  interface TableCardContainerProps {
78
86
  children: JSX.Element;
@@ -85,12 +93,22 @@ declare const TableCards: ({}: TableCardsProps) => react_jsx_runtime.JSX.Element
85
93
 
86
94
  declare const TableFilter: () => react_jsx_runtime.JSX.Element;
87
95
 
88
- declare const TableFooter: () => react_jsx_runtime.JSX.Element;
96
+ interface TableFooterProps {
97
+ pinnedBgColor?: {
98
+ light: string;
99
+ dark: string;
100
+ };
101
+ }
102
+ declare const TableFooter: ({ pinnedBgColor, }: TableFooterProps) => react_jsx_runtime.JSX.Element;
89
103
 
90
104
  interface TableHeaderProps {
91
105
  canResize?: boolean;
106
+ pinnedBgColor?: {
107
+ light: string;
108
+ dark: string;
109
+ };
92
110
  }
93
- declare const TableHeader: ({ canResize }: TableHeaderProps) => react_jsx_runtime.JSX.Element;
111
+ declare const TableHeader: ({ canResize, pinnedBgColor, }: TableHeaderProps) => react_jsx_runtime.JSX.Element;
94
112
 
95
113
  declare const TableOrderer: () => react_jsx_runtime.JSX.Element;
96
114
 
@@ -132,4 +150,4 @@ declare const useDataTable: () => {
132
150
  setGlobalFilter: (filter: string) => void;
133
151
  };
134
152
 
135
- export { type DataResponse, DataTable, type DataTableProps, DataTableServer, type DataTableServerProps, EditFilterButton, EditOrderButton, EditSortingButton, EditViewButton, GlobalFilter, PageSizeControl, type PageSizeControlProps, type PaginationProps, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, type Result, Table, TableBody, TableCardContainer, type TableCardContainerProps, TableCards, type TableCardsProps, TableFilter, TableFooter, TableHeader, type TableHeaderProps, TableOrderer, TablePagination, type TableProps, TableSelector, TableSorter, TableViewer, TextCell, type TextCellProps, useDataFromUrl, type useDataFromUrlProps, type useDataFromUrlReturn, useDataTable };
153
+ export { type DataResponse, DataTable, type DataTableProps, DataTableServer, type DataTableServerProps, DensityToggleButton, EditFilterButton, EditOrderButton, EditSortingButton, EditViewButton, GlobalFilter, PageSizeControl, type PageSizeControlProps, type PaginationProps, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, type Result, Table, TableBody, type TableBodyProps, TableCardContainer, type TableCardContainerProps, TableCards, type TableCardsProps, TableFilter, TableFooter, type TableFooterProps, TableHeader, type TableHeaderProps, TableOrderer, TablePagination, type TableProps, TableSelector, TableSorter, TableViewer, TextCell, type TextCellProps, useDataFromUrl, type useDataFromUrlProps, type useDataFromUrlReturn, useDataTable };
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ var react = require('react');
6
6
  var matchSorterUtils = require('@tanstack/match-sorter-utils');
7
7
  var axios = require('axios');
8
8
  var react$1 = require('@chakra-ui/react');
9
+ var ai = require('react-icons/ai');
9
10
  var md = require('react-icons/md');
10
11
  var icons = require('@chakra-ui/icons');
11
12
  var io = require('react-icons/io');
@@ -18,6 +19,63 @@ const TableContext = react.createContext({
18
19
  setGlobalFilter: () => { },
19
20
  });
20
21
 
22
+ // Reference: https://tanstack.com/table/latest/docs/framework/react/examples/custom-features
23
+ // TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features
24
+ // end of TS setup!
25
+ // Here is all of the actual javascript code for our new feature
26
+ const DensityFeature = {
27
+ // define the new feature's initial state
28
+ getInitialState: (state) => {
29
+ return {
30
+ density: "1rem",
31
+ ...state,
32
+ };
33
+ },
34
+ // define the new feature's default options
35
+ getDefaultOptions: (table) => {
36
+ return {
37
+ enableDensity: true,
38
+ onDensityChange: reactTable.makeStateUpdater("density", table),
39
+ };
40
+ },
41
+ // if you need to add a default column definition...
42
+ // getDefaultColumnDef: <TData extends RowData>(): Partial<ColumnDef<TData>> => {
43
+ // return { meta: {} } //use meta instead of directly adding to the columnDef to avoid typescript stuff that's hard to workaround
44
+ // },
45
+ // define the new feature's table instance methods
46
+ createTable: (table) => {
47
+ table.setDensity = (updater) => {
48
+ const safeUpdater = (old) => {
49
+ let newState = reactTable.functionalUpdate(updater, old);
50
+ return newState;
51
+ };
52
+ return table.options.onDensityChange?.(safeUpdater);
53
+ };
54
+ table.toggleDensity = (value) => {
55
+ table.setDensity((old) => {
56
+ if (value)
57
+ return value;
58
+ if (old === "0.5rem") {
59
+ return "1rem";
60
+ }
61
+ if (old === "1rem") {
62
+ return "2rem";
63
+ }
64
+ return "0.5rem";
65
+ });
66
+ };
67
+ },
68
+ // if you need to add row instance APIs...
69
+ // createRow: <TData extends RowData>(row, table): void => {},
70
+ // if you need to add cell instance APIs...
71
+ // createCell: <TData extends RowData>(cell, column, row, table): void => {},
72
+ // if you need to add column instance APIs...
73
+ // createColumn: <TData extends RowData>(column, table): void => {},
74
+ // if you need to add header instance APIs...
75
+ // createHeader: <TData extends RowData>(header, table): void => {},
76
+ };
77
+ //end of custom feature code
78
+
21
79
  // Define a custom fuzzy filter function that will apply ranking info to rows (using match-sorter utils)
22
80
  const fuzzyFilter = (row, columnId, value, addMeta) => {
23
81
  // Rank the item
@@ -31,8 +89,10 @@ const fuzzyFilter = (row, columnId, value, addMeta) => {
31
89
  };
32
90
  const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, children, }) => {
33
91
  const [columnOrder, setColumnOrder] = react.useState([]);
34
- const [globalFilter, setGlobalFilter] = react.useState('');
92
+ const [globalFilter, setGlobalFilter] = react.useState("");
93
+ const [density, setDensity] = react.useState("1rem");
35
94
  const table = reactTable.useReactTable({
95
+ _features: [DensityFeature],
36
96
  data: data,
37
97
  columns: columns,
38
98
  getCoreRowModel: reactTable.getCoreRowModel(),
@@ -47,6 +107,7 @@ const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSel
47
107
  state: {
48
108
  columnOrder,
49
109
  globalFilter,
110
+ density,
50
111
  },
51
112
  onColumnOrderChange: (state) => {
52
113
  setColumnOrder(state);
@@ -55,11 +116,14 @@ const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSel
55
116
  enableMultiRowSelection: enableMultiRowSelection,
56
117
  enableSubRowSelection: enableSubRowSelection,
57
118
  columnResizeMode: "onChange",
119
+ // global filter start
58
120
  filterFns: {
59
- fuzzy: fuzzyFilter, //define as a filter function that can be used in column definitions
121
+ fuzzy: fuzzyFilter,
60
122
  },
61
123
  onGlobalFilterChange: setGlobalFilter,
62
- globalFilterFn: 'fuzzy', //apply fuzzy filter to the global filter (most common use case for fuzzy filter)
124
+ globalFilterFn: "fuzzy",
125
+ // global filter end
126
+ onDensityChange: setDensity,
63
127
  });
64
128
  react.useEffect(() => {
65
129
  setColumnOrder(table.getAllLeafColumns().map((column) => column.id));
@@ -113,6 +177,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
113
177
  const [rowSelection, setRowSelection] = react.useState({});
114
178
  const [columnOrder, setColumnOrder] = react.useState([]);
115
179
  const [globalFilter, setGlobalFilter] = react.useState("");
180
+ const [density, setDensity] = react.useState("1rem");
116
181
  const { data, loading, hasError, refreshData } = useDataFromUrl({
117
182
  url: url,
118
183
  defaultData: {
@@ -138,6 +203,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
138
203
  },
139
204
  });
140
205
  const table = reactTable.useReactTable({
206
+ _features: [DensityFeature],
141
207
  data: data.results,
142
208
  columns: columns,
143
209
  getCoreRowModel: reactTable.getCoreRowModel(),
@@ -155,6 +221,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
155
221
  rowSelection,
156
222
  columnOrder,
157
223
  globalFilter,
224
+ density,
158
225
  },
159
226
  defaultColumn: {
160
227
  size: 150, //starting column size
@@ -178,6 +245,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
178
245
  },
179
246
  },
180
247
  // for tanstack-table ts bug end
248
+ onDensityChange: setDensity,
181
249
  });
182
250
  react.useEffect(() => {
183
251
  refreshData();
@@ -193,6 +261,13 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
193
261
  }, children: children }));
194
262
  };
195
263
 
264
+ const DensityToggleButton = () => {
265
+ const { table } = react.useContext(TableContext);
266
+ return (jsxRuntime.jsx(react$1.Tooltip, { label: "Toggle Density", children: jsxRuntime.jsx(react$1.IconButton, { variant: "ghost", "aria-label": "Toggle Density", icon: jsxRuntime.jsx(ai.AiOutlineColumnWidth, {}), onClick: (event) => {
267
+ table.toggleDensity();
268
+ } }) }));
269
+ };
270
+
196
271
  const ResetFilteringButton = () => {
197
272
  const { table } = react.useContext(TableContext);
198
273
  return (jsxRuntime.jsx(react$1.Button, { onClick: () => {
@@ -347,37 +422,33 @@ const ResetSelectionButton = () => {
347
422
  }, children: "Reset Selection" }));
348
423
  };
349
424
 
350
- const Table = ({ children }) => {
425
+ const Table = ({ children, ...props }) => {
351
426
  const { table } = useDataTable();
352
- return (jsxRuntime.jsx(react$1.Container, { padding: '0rem', maxW: "100%", overflowX: "scroll", children: jsxRuntime.jsx(react$1.Table, { width: table.getCenterTotalSize(), variant: "unstyled", children: children }) }));
427
+ return (jsxRuntime.jsx(react$1.Table, { width: table.getCenterTotalSize(), overflowX: "scroll", ...props, children: children }));
353
428
  };
354
429
 
355
- const TableBody = () => {
430
+ const TableBody = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
356
431
  const { table: table$1 } = react.useContext(TableContext);
357
432
  return (jsxRuntime.jsx(table.Tbody, { children: table$1.getRowModel().rows.map((row) => {
358
- return (jsxRuntime.jsxs(table.Tr, { display: "flex", _hover: { backgroundColor: "rgba(178,178,178,0.1)" }, zIndex: 1, children: [jsxRuntime.jsx(table.Td
359
- // styling resize and pinning start
360
- , {
361
- // styling resize and pinning start
362
- padding: "0.5rem", ...(table$1.getIsSomeColumnsPinned("left")
433
+ return (jsxRuntime.jsxs(table.Tr, { display: "flex", _hover: { backgroundColor: "rgba(178,178,178,0.1)" }, zIndex: 1, children: [jsxRuntime.jsx(table.Td, { padding: "0rem", ...(table$1.getIsSomeColumnsPinned("left")
363
434
  ? {
364
435
  left: `0px`,
365
- backgroundColor: "gray.50",
436
+ backgroundColor: pinnedBgColor.light,
366
437
  position: "sticky",
367
438
  zIndex: 1,
368
- _dark: { backgroundColor: "gray.700" },
439
+ _dark: { backgroundColor: pinnedBgColor.dark },
369
440
  }
370
- : {}), children: jsxRuntime.jsx(react$1.Checkbox, { isChecked: row.getIsSelected(),
441
+ : {}), children: jsxRuntime.jsx(react$1.Checkbox, { padding: table$1.getState().density, isChecked: row.getIsSelected(),
371
442
  disabled: !row.getCanSelect(),
372
443
  // indeterminate: row.getIsSomeSelected(),
373
444
  onChange: row.getToggleSelectedHandler() }) }), row.getVisibleCells().map((cell) => {
374
- return (jsxRuntime.jsx(table.Td, { padding: "0rem",
445
+ return (jsxRuntime.jsx(table.Td, { padding: table$1.getState().density,
375
446
  // styling resize and pinning start
376
447
  maxWidth: `${cell.column.getSize()}px`, width: `${cell.column.getSize()}px`, left: cell.column.getIsPinned()
377
448
  ? `${cell.column.getStart("left") + 32}px`
378
- : undefined, backgroundColor: cell.column.getIsPinned() ? "gray.50" : undefined, position: cell.column.getIsPinned() ? "sticky" : "relative", zIndex: cell.column.getIsPinned() ? 1 : 0, _dark: {
449
+ : undefined, backgroundColor: cell.column.getIsPinned() ? pinnedBgColor.light : undefined, position: cell.column.getIsPinned() ? "sticky" : "relative", zIndex: cell.column.getIsPinned() ? 1 : 0, _dark: {
379
450
  backgroundColor: cell.column.getIsPinned()
380
- ? "gray.700"
451
+ ? pinnedBgColor.dark
381
452
  : undefined,
382
453
  }, children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, crypto.randomUUID()));
383
454
  })] }, crypto.randomUUID()));
@@ -400,54 +471,56 @@ const TableCards = ({}) => {
400
471
  }) }));
401
472
  };
402
473
 
403
- const TableFooter = () => {
474
+ const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
404
475
  const table = useDataTable().table;
405
476
  const SELECTION_BOX_WIDTH = 32;
406
477
  return (jsxRuntime.jsx(react$1.Tfoot, { children: table.getFooterGroups().map((footerGroup) => (jsxRuntime.jsxs(react$1.Tr, { display: "flex", children: [jsxRuntime.jsx(react$1.Th
407
478
  // styling resize and pinning start
408
479
  , {
409
480
  // styling resize and pinning start
410
- padding: "0.5rem", ...(table.getIsSomeColumnsPinned("left")
481
+ padding: table.getState().density, ...(table.getIsSomeColumnsPinned("left")
411
482
  ? {
412
483
  left: `0px`,
413
- backgroundColor: "gray.50",
484
+ backgroundColor: pinnedBgColor.light,
414
485
  position: "sticky",
415
486
  zIndex: 1,
416
- _dark: { backgroundColor: "gray.700" },
487
+ _dark: { backgroundColor: pinnedBgColor.dark },
417
488
  }
418
489
  : {}), children: jsxRuntime.jsx(react$1.Checkbox, { isChecked: table.getIsAllRowsSelected(),
419
490
  // indeterminate: table.getIsSomeRowsSelected(),
420
- onChange: table.getToggleAllRowsSelectedHandler() }) }), footerGroup.headers.map((header) => (jsxRuntime.jsx(react$1.Th, { padding: "0rem", colSpan: header.colSpan,
491
+ onChange: table.getToggleAllRowsSelectedHandler() }) }), footerGroup.headers.map((header) => (jsxRuntime.jsx(react$1.Th, { padding: "0", colSpan: header.colSpan,
421
492
  // styling resize and pinning start
422
493
  maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, left: header.column.getIsPinned()
423
494
  ? `${header.getStart("left") + SELECTION_BOX_WIDTH}px`
424
- : undefined, backgroundColor: header.column.getIsPinned() ? "gray.50" : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
495
+ : undefined, backgroundColor: header.column.getIsPinned() ? pinnedBgColor.light : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
425
496
  backgroundColor: header.column.getIsPinned()
426
- ? "gray.700"
497
+ ? pinnedBgColor.dark
427
498
  : undefined,
428
499
  },
429
500
  // styling resize and pinning end
430
- display: "flex", alignItems: "center", children: header.isPlaceholder
431
- ? null
432
- : reactTable.flexRender(header.column.columnDef.footer, header.getContext()) }, crypto.randomUUID())))] }, crypto.randomUUID()))) }));
501
+ display: "grid", children: jsxRuntime.jsx(react$1.Menu, { children: jsxRuntime.jsx(react$1.MenuButton, { as: react$1.Box, padding: table.getState().density, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", _hover: { backgroundColor: "gray.100" }, children: jsxRuntime.jsxs(react$1.Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
502
+ ? null
503
+ : reactTable.flexRender(header.column.columnDef.footer, header.getContext()), jsxRuntime.jsx(react$1.Box, { children: header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [header.column.getIsSorted() === false && (
504
+ // <UpDownIcon />
505
+ jsxRuntime.jsx(jsxRuntime.Fragment, {})), header.column.getIsSorted() === "asc" && (jsxRuntime.jsx(icons.ChevronUpIcon, {})), header.column.getIsSorted() === "desc" && (jsxRuntime.jsx(icons.ChevronDownIcon, {}))] })) })] }) }) }) }, crypto.randomUUID())))] }, crypto.randomUUID()))) }));
433
506
  };
434
507
 
435
- const TableHeader = ({ canResize }) => {
508
+ const TableHeader = ({ canResize, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
436
509
  const { table } = useDataTable();
437
510
  const SELECTION_BOX_WIDTH = 32;
438
511
  return (jsxRuntime.jsx(react$1.Thead, { children: table.getHeaderGroups().map((headerGroup) => (jsxRuntime.jsxs(react$1.Tr, { display: "flex", children: [jsxRuntime.jsx(react$1.Th
439
512
  // styling resize and pinning start
440
- , {
441
- // styling resize and pinning start
442
- padding: "0.5rem", ...(table.getIsSomeColumnsPinned("left")
513
+ , { ...(table.getIsSomeColumnsPinned("left")
443
514
  ? {
444
515
  left: `0px`,
445
- backgroundColor: "gray.50",
516
+ backgroundColor: pinnedBgColor.light,
446
517
  position: "sticky",
447
518
  zIndex: 1,
448
- _dark: { backgroundColor: "gray.700" },
519
+ _dark: { backgroundColor: pinnedBgColor.dark },
449
520
  }
450
- : {}), children: jsxRuntime.jsx(react$1.Checkbox, { isChecked: table.getIsAllRowsSelected(),
521
+ : {}),
522
+ // styling resize and pinning end
523
+ padding: "0rem", children: jsxRuntime.jsx(react$1.Checkbox, { padding: table.getState().density, isChecked: table.getIsAllRowsSelected(),
451
524
  // indeterminate: table.getIsSomeRowsSelected(),
452
525
  onChange: table.getToggleAllRowsSelectedHandler() }) }), headerGroup.headers.map((header) => {
453
526
  const resizeProps = {
@@ -460,23 +533,25 @@ const TableHeader = ({ canResize }) => {
460
533
  // styling resize and pinning start
461
534
  maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, left: header.column.getIsPinned()
462
535
  ? `${header.getStart("left") + SELECTION_BOX_WIDTH}px`
463
- : undefined, backgroundColor: header.column.getIsPinned() ? "gray.50" : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
536
+ : undefined, backgroundColor: header.column.getIsPinned() ? pinnedBgColor.light : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
464
537
  backgroundColor: header.column.getIsPinned()
465
- ? "gray.700"
538
+ ? pinnedBgColor.dark
466
539
  : undefined,
467
540
  },
468
541
  // styling resize and pinning end
469
- display: "grid", children: [jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(react$1.Menu, { children: [jsxRuntime.jsx(react$1.MenuButton, { as: react$1.Box, display: "flex", alignItems: "center", justifyContent: "start", _hover: { backgroundColor: "gray.100" }, _dark: { _hover: { backgroundColor: "gray.700" } }, children: jsxRuntime.jsxs(react$1.Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
470
- ? null
471
- : reactTable.flexRender(header.column.columnDef.header, header.getContext()), jsxRuntime.jsx(react$1.Box, { children: header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [header.column.getIsSorted() === false && (jsxRuntime.jsx(icons.UpDownIcon, {})), header.column.getIsSorted() === "asc" && (jsxRuntime.jsx(icons.ChevronUpIcon, {})), header.column.getIsSorted() === "desc" && (jsxRuntime.jsx(icons.ChevronDownIcon, {}))] })) })] }) }), jsxRuntime.jsx(react$1.Portal, { children: jsxRuntime.jsxs(react$1.MenuList, { children: [!header.column.getIsPinned() && (jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(md.MdPushPin, {}), onClick: () => {
472
- header.column.pin("left");
473
- }, children: "Pin Column" })), header.column.getIsPinned() && (jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(md.MdCancel, {}), onClick: () => {
474
- header.column.pin(false);
475
- }, children: "Cancel Pin" })), header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(md.MdSort, {}), onClick: () => {
476
- header.column.toggleSorting();
477
- }, children: "Toggle Sorting" }), header.column.getIsSorted() && (jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(io.IoMdClose, {}), onClick: () => {
478
- header.column.clearSorting();
479
- }, children: "Clear Sorting" }))] }))] }) })] }) }), header.column.getIsFiltered() && jsxRuntime.jsx(md.MdFilterListAlt, {}), canResize && (jsxRuntime.jsx(react$1.Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing() ? "gray.700" : "transparent", position: "absolute", right: "0", top: "0", height: "100%", width: "5px", userSelect: "none", style: { touchAction: "none" }, _hover: {
542
+ display: "grid", children: [jsxRuntime.jsxs(react$1.Menu, { children: [jsxRuntime.jsx(react$1.MenuButton, { as: react$1.Box, padding: table.getState().density, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", _hover: { backgroundColor: "gray.100" }, children: jsxRuntime.jsxs(react$1.Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
543
+ ? null
544
+ : reactTable.flexRender(header.column.columnDef.header, header.getContext()), jsxRuntime.jsx(react$1.Box, { children: header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [header.column.getIsSorted() === false && (
545
+ // <UpDownIcon />
546
+ jsxRuntime.jsx(jsxRuntime.Fragment, {})), header.column.getIsSorted() === "asc" && (jsxRuntime.jsx(icons.ChevronUpIcon, {})), header.column.getIsSorted() === "desc" && (jsxRuntime.jsx(icons.ChevronDownIcon, {}))] })) })] }) }), jsxRuntime.jsx(react$1.Portal, { children: jsxRuntime.jsxs(react$1.MenuList, { children: [!header.column.getIsPinned() && (jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(md.MdPushPin, {}), onClick: () => {
547
+ header.column.pin("left");
548
+ }, children: "Pin Column" })), header.column.getIsPinned() && (jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(md.MdCancel, {}), onClick: () => {
549
+ header.column.pin(false);
550
+ }, children: "Cancel Pin" })), header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(md.MdSort, {}), onClick: () => {
551
+ header.column.toggleSorting();
552
+ }, children: "Toggle Sorting" }), header.column.getIsSorted() && (jsxRuntime.jsx(react$1.MenuItem, { icon: jsxRuntime.jsx(io.IoMdClose, {}), onClick: () => {
553
+ header.column.clearSorting();
554
+ }, children: "Clear Sorting" }))] }))] }) })] }), header.column.getIsFiltered() && jsxRuntime.jsx(md.MdFilterListAlt, {}), canResize && (jsxRuntime.jsx(react$1.Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing() ? "gray.700" : "transparent", position: "absolute", right: "0", top: "0", height: "100%", width: "5px", userSelect: "none", style: { touchAction: "none" }, _hover: {
480
555
  borderRightColor: header.column.getIsResizing()
481
556
  ? "gray.700"
482
557
  : "gray.400",
@@ -505,13 +580,14 @@ const TableSelector = () => {
505
580
 
506
581
  const TextCell = ({ label, noOfLines = [1], padding = "0rem", children, }) => {
507
582
  if (label) {
508
- return (jsxRuntime.jsx(react$1.Box, { padding: padding, children: jsxRuntime.jsx(react$1.Tooltip, { label: jsxRuntime.jsx(react$1.Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", noOfLines: [5], children: label }), placement: "auto", children: jsxRuntime.jsx(react$1.Text, { as: "span", textOverflow: "ellipsis", noOfLines: noOfLines, children: children }) }) }));
583
+ return (jsxRuntime.jsx(react$1.Box, { padding: padding, children: jsxRuntime.jsx(react$1.Tooltip, { label: jsxRuntime.jsx(react$1.Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", noOfLines: [5], children: label }), placement: "auto", children: jsxRuntime.jsx(react$1.Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", noOfLines: noOfLines, children: children }) }) }));
509
584
  }
510
- return (jsxRuntime.jsx(react$1.Box, { padding: padding, children: jsxRuntime.jsx(react$1.Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", noOfLines: noOfLines, children: children }) }));
585
+ return (jsxRuntime.jsx(react$1.Box, { padding: padding, children: jsxRuntime.jsx(react$1.Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", noOfLines: noOfLines, children: children }) }));
511
586
  };
512
587
 
513
588
  exports.DataTable = DataTable;
514
589
  exports.DataTableServer = DataTableServer;
590
+ exports.DensityToggleButton = DensityToggleButton;
515
591
  exports.EditFilterButton = EditFilterButton;
516
592
  exports.EditOrderButton = EditOrderButton;
517
593
  exports.EditSortingButton = EditSortingButton;
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
- import { useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, flexRender } from '@tanstack/react-table';
2
+ import { makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, flexRender } from '@tanstack/react-table';
3
3
  import { createContext, useState, useEffect, useContext } from 'react';
4
4
  import { rankItem } from '@tanstack/match-sorter-utils';
5
5
  import axios from 'axios';
6
- import { Button, Box, Text, Input, Popover, Tooltip, PopoverTrigger, IconButton, PopoverContent, PopoverArrow, PopoverBody, Flex, Switch, Menu, MenuButton, MenuList, MenuItem, Container, Table as Table$1, Checkbox, Grid, Card, CardBody, Tfoot, Tr as Tr$1, Th, Thead, Portal, ButtonGroup, Icon } from '@chakra-ui/react';
6
+ import { Tooltip, IconButton, Button, Box, Text, Input, Popover, PopoverTrigger, PopoverContent, PopoverArrow, PopoverBody, Flex, Switch, Menu, MenuButton, MenuList, MenuItem, Table as Table$1, Checkbox, Grid, Card, CardBody, Tfoot, Tr as Tr$1, Th, Thead, Portal, ButtonGroup, Icon } from '@chakra-ui/react';
7
+ import { AiOutlineColumnWidth } from 'react-icons/ai';
7
8
  import { MdFilterAlt, MdArrowUpward, MdArrowDownward, MdOutlineMoveDown, MdOutlineSort, MdPushPin, MdCancel, MdSort, MdFilterListAlt, MdFirstPage, MdArrowBack, MdArrowForward, MdLastPage, MdClear, MdOutlineChecklist } from 'react-icons/md';
8
9
  import { UpDownIcon, ChevronDownIcon, ChevronUpIcon, CloseIcon } from '@chakra-ui/icons';
9
10
  import { IoMdEye, IoMdClose, IoMdCheckbox } from 'react-icons/io';
@@ -16,6 +17,63 @@ const TableContext = createContext({
16
17
  setGlobalFilter: () => { },
17
18
  });
18
19
 
20
+ // Reference: https://tanstack.com/table/latest/docs/framework/react/examples/custom-features
21
+ // TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features
22
+ // end of TS setup!
23
+ // Here is all of the actual javascript code for our new feature
24
+ const DensityFeature = {
25
+ // define the new feature's initial state
26
+ getInitialState: (state) => {
27
+ return {
28
+ density: "1rem",
29
+ ...state,
30
+ };
31
+ },
32
+ // define the new feature's default options
33
+ getDefaultOptions: (table) => {
34
+ return {
35
+ enableDensity: true,
36
+ onDensityChange: makeStateUpdater("density", table),
37
+ };
38
+ },
39
+ // if you need to add a default column definition...
40
+ // getDefaultColumnDef: <TData extends RowData>(): Partial<ColumnDef<TData>> => {
41
+ // return { meta: {} } //use meta instead of directly adding to the columnDef to avoid typescript stuff that's hard to workaround
42
+ // },
43
+ // define the new feature's table instance methods
44
+ createTable: (table) => {
45
+ table.setDensity = (updater) => {
46
+ const safeUpdater = (old) => {
47
+ let newState = functionalUpdate(updater, old);
48
+ return newState;
49
+ };
50
+ return table.options.onDensityChange?.(safeUpdater);
51
+ };
52
+ table.toggleDensity = (value) => {
53
+ table.setDensity((old) => {
54
+ if (value)
55
+ return value;
56
+ if (old === "0.5rem") {
57
+ return "1rem";
58
+ }
59
+ if (old === "1rem") {
60
+ return "2rem";
61
+ }
62
+ return "0.5rem";
63
+ });
64
+ };
65
+ },
66
+ // if you need to add row instance APIs...
67
+ // createRow: <TData extends RowData>(row, table): void => {},
68
+ // if you need to add cell instance APIs...
69
+ // createCell: <TData extends RowData>(cell, column, row, table): void => {},
70
+ // if you need to add column instance APIs...
71
+ // createColumn: <TData extends RowData>(column, table): void => {},
72
+ // if you need to add header instance APIs...
73
+ // createHeader: <TData extends RowData>(header, table): void => {},
74
+ };
75
+ //end of custom feature code
76
+
19
77
  // Define a custom fuzzy filter function that will apply ranking info to rows (using match-sorter utils)
20
78
  const fuzzyFilter = (row, columnId, value, addMeta) => {
21
79
  // Rank the item
@@ -29,8 +87,10 @@ const fuzzyFilter = (row, columnId, value, addMeta) => {
29
87
  };
30
88
  const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, children, }) => {
31
89
  const [columnOrder, setColumnOrder] = useState([]);
32
- const [globalFilter, setGlobalFilter] = useState('');
90
+ const [globalFilter, setGlobalFilter] = useState("");
91
+ const [density, setDensity] = useState("1rem");
33
92
  const table = useReactTable({
93
+ _features: [DensityFeature],
34
94
  data: data,
35
95
  columns: columns,
36
96
  getCoreRowModel: getCoreRowModel(),
@@ -45,6 +105,7 @@ const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSel
45
105
  state: {
46
106
  columnOrder,
47
107
  globalFilter,
108
+ density,
48
109
  },
49
110
  onColumnOrderChange: (state) => {
50
111
  setColumnOrder(state);
@@ -53,11 +114,14 @@ const DataTable = ({ columns, data, enableRowSelection = true, enableMultiRowSel
53
114
  enableMultiRowSelection: enableMultiRowSelection,
54
115
  enableSubRowSelection: enableSubRowSelection,
55
116
  columnResizeMode: "onChange",
117
+ // global filter start
56
118
  filterFns: {
57
- fuzzy: fuzzyFilter, //define as a filter function that can be used in column definitions
119
+ fuzzy: fuzzyFilter,
58
120
  },
59
121
  onGlobalFilterChange: setGlobalFilter,
60
- globalFilterFn: 'fuzzy', //apply fuzzy filter to the global filter (most common use case for fuzzy filter)
122
+ globalFilterFn: "fuzzy",
123
+ // global filter end
124
+ onDensityChange: setDensity,
61
125
  });
62
126
  useEffect(() => {
63
127
  setColumnOrder(table.getAllLeafColumns().map((column) => column.id));
@@ -111,6 +175,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
111
175
  const [rowSelection, setRowSelection] = useState({});
112
176
  const [columnOrder, setColumnOrder] = useState([]);
113
177
  const [globalFilter, setGlobalFilter] = useState("");
178
+ const [density, setDensity] = useState("1rem");
114
179
  const { data, loading, hasError, refreshData } = useDataFromUrl({
115
180
  url: url,
116
181
  defaultData: {
@@ -136,6 +201,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
136
201
  },
137
202
  });
138
203
  const table = useReactTable({
204
+ _features: [DensityFeature],
139
205
  data: data.results,
140
206
  columns: columns,
141
207
  getCoreRowModel: getCoreRowModel(),
@@ -153,6 +219,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
153
219
  rowSelection,
154
220
  columnOrder,
155
221
  globalFilter,
222
+ density,
156
223
  },
157
224
  defaultColumn: {
158
225
  size: 150, //starting column size
@@ -176,6 +243,7 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
176
243
  },
177
244
  },
178
245
  // for tanstack-table ts bug end
246
+ onDensityChange: setDensity,
179
247
  });
180
248
  useEffect(() => {
181
249
  refreshData();
@@ -191,6 +259,13 @@ const DataTableServer = ({ columns, url, enableRowSelection = true, enableMultiR
191
259
  }, children: children }));
192
260
  };
193
261
 
262
+ const DensityToggleButton = () => {
263
+ const { table } = useContext(TableContext);
264
+ return (jsx(Tooltip, { label: "Toggle Density", children: jsx(IconButton, { variant: "ghost", "aria-label": "Toggle Density", icon: jsx(AiOutlineColumnWidth, {}), onClick: (event) => {
265
+ table.toggleDensity();
266
+ } }) }));
267
+ };
268
+
194
269
  const ResetFilteringButton = () => {
195
270
  const { table } = useContext(TableContext);
196
271
  return (jsx(Button, { onClick: () => {
@@ -345,37 +420,33 @@ const ResetSelectionButton = () => {
345
420
  }, children: "Reset Selection" }));
346
421
  };
347
422
 
348
- const Table = ({ children }) => {
423
+ const Table = ({ children, ...props }) => {
349
424
  const { table } = useDataTable();
350
- return (jsx(Container, { padding: '0rem', maxW: "100%", overflowX: "scroll", children: jsx(Table$1, { width: table.getCenterTotalSize(), variant: "unstyled", children: children }) }));
425
+ return (jsx(Table$1, { width: table.getCenterTotalSize(), overflowX: "scroll", ...props, children: children }));
351
426
  };
352
427
 
353
- const TableBody = () => {
428
+ const TableBody = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
354
429
  const { table } = useContext(TableContext);
355
430
  return (jsx(Tbody, { children: table.getRowModel().rows.map((row) => {
356
- return (jsxs(Tr, { display: "flex", _hover: { backgroundColor: "rgba(178,178,178,0.1)" }, zIndex: 1, children: [jsx(Td
357
- // styling resize and pinning start
358
- , {
359
- // styling resize and pinning start
360
- padding: "0.5rem", ...(table.getIsSomeColumnsPinned("left")
431
+ return (jsxs(Tr, { display: "flex", _hover: { backgroundColor: "rgba(178,178,178,0.1)" }, zIndex: 1, children: [jsx(Td, { padding: "0rem", ...(table.getIsSomeColumnsPinned("left")
361
432
  ? {
362
433
  left: `0px`,
363
- backgroundColor: "gray.50",
434
+ backgroundColor: pinnedBgColor.light,
364
435
  position: "sticky",
365
436
  zIndex: 1,
366
- _dark: { backgroundColor: "gray.700" },
437
+ _dark: { backgroundColor: pinnedBgColor.dark },
367
438
  }
368
- : {}), children: jsx(Checkbox, { isChecked: row.getIsSelected(),
439
+ : {}), children: jsx(Checkbox, { padding: table.getState().density, isChecked: row.getIsSelected(),
369
440
  disabled: !row.getCanSelect(),
370
441
  // indeterminate: row.getIsSomeSelected(),
371
442
  onChange: row.getToggleSelectedHandler() }) }), row.getVisibleCells().map((cell) => {
372
- return (jsx(Td, { padding: "0rem",
443
+ return (jsx(Td, { padding: table.getState().density,
373
444
  // styling resize and pinning start
374
445
  maxWidth: `${cell.column.getSize()}px`, width: `${cell.column.getSize()}px`, left: cell.column.getIsPinned()
375
446
  ? `${cell.column.getStart("left") + 32}px`
376
- : undefined, backgroundColor: cell.column.getIsPinned() ? "gray.50" : undefined, position: cell.column.getIsPinned() ? "sticky" : "relative", zIndex: cell.column.getIsPinned() ? 1 : 0, _dark: {
447
+ : undefined, backgroundColor: cell.column.getIsPinned() ? pinnedBgColor.light : undefined, position: cell.column.getIsPinned() ? "sticky" : "relative", zIndex: cell.column.getIsPinned() ? 1 : 0, _dark: {
377
448
  backgroundColor: cell.column.getIsPinned()
378
- ? "gray.700"
449
+ ? pinnedBgColor.dark
379
450
  : undefined,
380
451
  }, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, crypto.randomUUID()));
381
452
  })] }, crypto.randomUUID()));
@@ -398,54 +469,56 @@ const TableCards = ({}) => {
398
469
  }) }));
399
470
  };
400
471
 
401
- const TableFooter = () => {
472
+ const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
402
473
  const table = useDataTable().table;
403
474
  const SELECTION_BOX_WIDTH = 32;
404
475
  return (jsx(Tfoot, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Tr$1, { display: "flex", children: [jsx(Th
405
476
  // styling resize and pinning start
406
477
  , {
407
478
  // styling resize and pinning start
408
- padding: "0.5rem", ...(table.getIsSomeColumnsPinned("left")
479
+ padding: table.getState().density, ...(table.getIsSomeColumnsPinned("left")
409
480
  ? {
410
481
  left: `0px`,
411
- backgroundColor: "gray.50",
482
+ backgroundColor: pinnedBgColor.light,
412
483
  position: "sticky",
413
484
  zIndex: 1,
414
- _dark: { backgroundColor: "gray.700" },
485
+ _dark: { backgroundColor: pinnedBgColor.dark },
415
486
  }
416
487
  : {}), children: jsx(Checkbox, { isChecked: table.getIsAllRowsSelected(),
417
488
  // indeterminate: table.getIsSomeRowsSelected(),
418
- onChange: table.getToggleAllRowsSelectedHandler() }) }), footerGroup.headers.map((header) => (jsx(Th, { padding: "0rem", colSpan: header.colSpan,
489
+ onChange: table.getToggleAllRowsSelectedHandler() }) }), footerGroup.headers.map((header) => (jsx(Th, { padding: "0", colSpan: header.colSpan,
419
490
  // styling resize and pinning start
420
491
  maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, left: header.column.getIsPinned()
421
492
  ? `${header.getStart("left") + SELECTION_BOX_WIDTH}px`
422
- : undefined, backgroundColor: header.column.getIsPinned() ? "gray.50" : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
493
+ : undefined, backgroundColor: header.column.getIsPinned() ? pinnedBgColor.light : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
423
494
  backgroundColor: header.column.getIsPinned()
424
- ? "gray.700"
495
+ ? pinnedBgColor.dark
425
496
  : undefined,
426
497
  },
427
498
  // styling resize and pinning end
428
- display: "flex", alignItems: "center", children: header.isPlaceholder
429
- ? null
430
- : flexRender(header.column.columnDef.footer, header.getContext()) }, crypto.randomUUID())))] }, crypto.randomUUID()))) }));
499
+ display: "grid", children: jsx(Menu, { children: jsx(MenuButton, { as: Box, padding: table.getState().density, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", _hover: { backgroundColor: "gray.100" }, children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
500
+ ? null
501
+ : flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && (
502
+ // <UpDownIcon />
503
+ jsx(Fragment, {})), header.column.getIsSorted() === "asc" && (jsx(ChevronUpIcon, {})), header.column.getIsSorted() === "desc" && (jsx(ChevronDownIcon, {}))] })) })] }) }) }) }, crypto.randomUUID())))] }, crypto.randomUUID()))) }));
431
504
  };
432
505
 
433
- const TableHeader = ({ canResize }) => {
506
+ const TableHeader = ({ canResize, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, }) => {
434
507
  const { table } = useDataTable();
435
508
  const SELECTION_BOX_WIDTH = 32;
436
509
  return (jsx(Thead, { children: table.getHeaderGroups().map((headerGroup) => (jsxs(Tr$1, { display: "flex", children: [jsx(Th
437
510
  // styling resize and pinning start
438
- , {
439
- // styling resize and pinning start
440
- padding: "0.5rem", ...(table.getIsSomeColumnsPinned("left")
511
+ , { ...(table.getIsSomeColumnsPinned("left")
441
512
  ? {
442
513
  left: `0px`,
443
- backgroundColor: "gray.50",
514
+ backgroundColor: pinnedBgColor.light,
444
515
  position: "sticky",
445
516
  zIndex: 1,
446
- _dark: { backgroundColor: "gray.700" },
517
+ _dark: { backgroundColor: pinnedBgColor.dark },
447
518
  }
448
- : {}), children: jsx(Checkbox, { isChecked: table.getIsAllRowsSelected(),
519
+ : {}),
520
+ // styling resize and pinning end
521
+ padding: "0rem", children: jsx(Checkbox, { padding: table.getState().density, isChecked: table.getIsAllRowsSelected(),
449
522
  // indeterminate: table.getIsSomeRowsSelected(),
450
523
  onChange: table.getToggleAllRowsSelectedHandler() }) }), headerGroup.headers.map((header) => {
451
524
  const resizeProps = {
@@ -458,23 +531,25 @@ const TableHeader = ({ canResize }) => {
458
531
  // styling resize and pinning start
459
532
  maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, left: header.column.getIsPinned()
460
533
  ? `${header.getStart("left") + SELECTION_BOX_WIDTH}px`
461
- : undefined, backgroundColor: header.column.getIsPinned() ? "gray.50" : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
534
+ : undefined, backgroundColor: header.column.getIsPinned() ? pinnedBgColor.light : undefined, position: header.column.getIsPinned() ? "sticky" : "relative", zIndex: header.column.getIsPinned() ? 1 : undefined, _dark: {
462
535
  backgroundColor: header.column.getIsPinned()
463
- ? "gray.700"
536
+ ? pinnedBgColor.dark
464
537
  : undefined,
465
538
  },
466
539
  // styling resize and pinning end
467
- display: "grid", children: [jsx(Fragment, { children: jsxs(Menu, { children: [jsx(MenuButton, { as: Box, display: "flex", alignItems: "center", justifyContent: "start", _hover: { backgroundColor: "gray.100" }, _dark: { _hover: { backgroundColor: "gray.700" } }, children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
468
- ? null
469
- : flexRender(header.column.columnDef.header, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && (jsx(UpDownIcon, {})), header.column.getIsSorted() === "asc" && (jsx(ChevronUpIcon, {})), header.column.getIsSorted() === "desc" && (jsx(ChevronDownIcon, {}))] })) })] }) }), jsx(Portal, { children: jsxs(MenuList, { children: [!header.column.getIsPinned() && (jsx(MenuItem, { icon: jsx(MdPushPin, {}), onClick: () => {
470
- header.column.pin("left");
471
- }, children: "Pin Column" })), header.column.getIsPinned() && (jsx(MenuItem, { icon: jsx(MdCancel, {}), onClick: () => {
472
- header.column.pin(false);
473
- }, children: "Cancel Pin" })), header.column.getCanSort() && (jsxs(Fragment, { children: [jsx(MenuItem, { icon: jsx(MdSort, {}), onClick: () => {
474
- header.column.toggleSorting();
475
- }, children: "Toggle Sorting" }), header.column.getIsSorted() && (jsx(MenuItem, { icon: jsx(IoMdClose, {}), onClick: () => {
476
- header.column.clearSorting();
477
- }, children: "Clear Sorting" }))] }))] }) })] }) }), header.column.getIsFiltered() && jsx(MdFilterListAlt, {}), canResize && (jsx(Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing() ? "gray.700" : "transparent", position: "absolute", right: "0", top: "0", height: "100%", width: "5px", userSelect: "none", style: { touchAction: "none" }, _hover: {
540
+ display: "grid", children: [jsxs(Menu, { children: [jsx(MenuButton, { as: Box, padding: table.getState().density, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", _hover: { backgroundColor: "gray.100" }, children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
541
+ ? null
542
+ : flexRender(header.column.columnDef.header, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && (
543
+ // <UpDownIcon />
544
+ jsx(Fragment, {})), header.column.getIsSorted() === "asc" && (jsx(ChevronUpIcon, {})), header.column.getIsSorted() === "desc" && (jsx(ChevronDownIcon, {}))] })) })] }) }), jsx(Portal, { children: jsxs(MenuList, { children: [!header.column.getIsPinned() && (jsx(MenuItem, { icon: jsx(MdPushPin, {}), onClick: () => {
545
+ header.column.pin("left");
546
+ }, children: "Pin Column" })), header.column.getIsPinned() && (jsx(MenuItem, { icon: jsx(MdCancel, {}), onClick: () => {
547
+ header.column.pin(false);
548
+ }, children: "Cancel Pin" })), header.column.getCanSort() && (jsxs(Fragment, { children: [jsx(MenuItem, { icon: jsx(MdSort, {}), onClick: () => {
549
+ header.column.toggleSorting();
550
+ }, children: "Toggle Sorting" }), header.column.getIsSorted() && (jsx(MenuItem, { icon: jsx(IoMdClose, {}), onClick: () => {
551
+ header.column.clearSorting();
552
+ }, children: "Clear Sorting" }))] }))] }) })] }), header.column.getIsFiltered() && jsx(MdFilterListAlt, {}), canResize && (jsx(Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing() ? "gray.700" : "transparent", position: "absolute", right: "0", top: "0", height: "100%", width: "5px", userSelect: "none", style: { touchAction: "none" }, _hover: {
478
553
  borderRightColor: header.column.getIsResizing()
479
554
  ? "gray.700"
480
555
  : "gray.400",
@@ -503,9 +578,9 @@ const TableSelector = () => {
503
578
 
504
579
  const TextCell = ({ label, noOfLines = [1], padding = "0rem", children, }) => {
505
580
  if (label) {
506
- return (jsx(Box, { padding: padding, children: jsx(Tooltip, { label: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", noOfLines: [5], children: label }), placement: "auto", children: jsx(Text, { as: "span", textOverflow: "ellipsis", noOfLines: noOfLines, children: children }) }) }));
581
+ return (jsx(Box, { padding: padding, children: jsx(Tooltip, { label: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", noOfLines: [5], children: label }), placement: "auto", children: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", noOfLines: noOfLines, children: children }) }) }));
507
582
  }
508
- return (jsx(Box, { padding: padding, children: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", noOfLines: noOfLines, children: children }) }));
583
+ return (jsx(Box, { padding: padding, children: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", noOfLines: noOfLines, children: children }) }));
509
584
  };
510
585
 
511
- export { DataTable, DataTableServer, EditFilterButton, EditOrderButton, EditSortingButton, EditViewButton, GlobalFilter, PageSizeControl, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, Table, TableBody, TableCardContainer, TableCards, TableFilter, TableFooter, TableHeader, TableOrderer, TablePagination, TableSelector, TableSorter, TableViewer, TextCell, useDataFromUrl, useDataTable };
586
+ export { DataTable, DataTableServer, DensityToggleButton, EditFilterButton, EditOrderButton, EditSortingButton, EditViewButton, GlobalFilter, PageSizeControl, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, Table, TableBody, TableCardContainer, TableCards, TableFilter, TableFooter, TableHeader, TableOrderer, TablePagination, TableSelector, TableSorter, TableViewer, TextCell, useDataFromUrl, useDataTable };
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import { ColumnDef, FilterFn } from "@tanstack/react-table";
3
- import { RankingInfo } from '@tanstack/match-sorter-utils';
4
- declare module '@tanstack/react-table' {
3
+ import { RankingInfo } from "@tanstack/match-sorter-utils";
4
+ declare module "@tanstack/react-table" {
5
5
  interface FilterFns {
6
6
  fuzzy: FilterFn<unknown>;
7
7
  }
@@ -0,0 +1,22 @@
1
+ import { OnChangeFn, Updater, RowData, TableFeature } from "@tanstack/react-table";
2
+ export type DensityState = "0.5rem" | "1rem" | "2rem";
3
+ export interface DensityTableState {
4
+ density: DensityState;
5
+ }
6
+ export interface DensityOptions {
7
+ enableDensity?: boolean;
8
+ onDensityChange?: OnChangeFn<DensityState>;
9
+ }
10
+ export interface DensityInstance {
11
+ setDensity: (updater: Updater<DensityState>) => void;
12
+ toggleDensity: (value?: DensityState) => void;
13
+ }
14
+ declare module "@tanstack/react-table" {
15
+ interface TableState extends DensityTableState {
16
+ }
17
+ interface TableOptionsResolved<TData extends RowData> extends DensityOptions {
18
+ }
19
+ interface Table<TData extends RowData> extends DensityInstance {
20
+ }
21
+ }
22
+ export declare const DensityFeature: TableFeature<any>;
@@ -0,0 +1 @@
1
+ export declare const SelectAllRowsToggle: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const DensityToggleButton: () => import("react/jsx-runtime").JSX.Element;
@@ -2,4 +2,4 @@ import { ReactNode } from "react";
2
2
  export interface TableProps {
3
3
  children: ReactNode;
4
4
  }
5
- export declare const Table: ({ children }: TableProps) => import("react/jsx-runtime").JSX.Element;
5
+ export declare const Table: ({ children, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1,7 @@
1
- export declare const TableBody: () => import("react/jsx-runtime").JSX.Element;
1
+ export interface TableBodyProps {
2
+ pinnedBgColor?: {
3
+ light: string;
4
+ dark: string;
5
+ };
6
+ }
7
+ export declare const TableBody: ({ pinnedBgColor, }: TableBodyProps) => import("react/jsx-runtime").JSX.Element;
@@ -1 +1,7 @@
1
- export declare const TableFooter: () => import("react/jsx-runtime").JSX.Element;
1
+ export interface TableFooterProps {
2
+ pinnedBgColor?: {
3
+ light: string;
4
+ dark: string;
5
+ };
6
+ }
7
+ export declare const TableFooter: ({ pinnedBgColor, }: TableFooterProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,8 @@
1
1
  export interface TableHeaderProps {
2
2
  canResize?: boolean;
3
+ pinnedBgColor?: {
4
+ light: string;
5
+ dark: string;
6
+ };
3
7
  }
4
- export declare const TableHeader: ({ canResize }: TableHeaderProps) => import("react/jsx-runtime").JSX.Element;
8
+ export declare const TableHeader: ({ canResize, pinnedBgColor, }: TableHeaderProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  export * from "./components/DataTable";
2
2
  export * from "./components/DataTableServer";
3
+ export * from "./components/DensityToggleButton";
3
4
  export * from "./components/EditFilterButton";
4
5
  export * from "./components/EditOrderButton";
5
6
  export * from "./components/EditSortingButton";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsol-oss/react-datatable5",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",