@datum-cloud/datum-ui 0.3.0-alpha.3670fb2 → 0.3.0-alpha.4702cdb
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/app-navigation/index.mjs +12 -0
- package/dist/app-navigation-CCvjPijd.mjs +416 -0
- package/dist/autocomplete/index.mjs +1 -1
- package/dist/{autocomplete-B9bCkXtz.mjs → autocomplete-DcKO7pj5.mjs} +1 -1
- package/dist/avatar-stack/index.mjs +2 -2
- package/dist/{avatar-stack-Bh-tLz0X.mjs → avatar-stack-B21McFeb.mjs} +1 -1
- package/dist/{calendar-date-picker-mlbzp3xR.mjs → calendar-date-picker-Bw6Mrr-P.mjs} +2 -1
- package/dist/components/base/index.d.ts +1 -0
- package/dist/components/base/index.d.ts.map +1 -1
- package/dist/components/base/sidebar/index.d.ts +2 -0
- package/dist/components/base/sidebar/index.d.ts.map +1 -0
- package/dist/components/{features → base}/sidebar/sidebar.d.ts +1 -1
- package/dist/components/base/sidebar/sidebar.d.ts.map +1 -0
- package/dist/components/base/skeleton/index.d.ts +1 -1
- package/dist/components/base/skeleton/index.d.ts.map +1 -1
- package/dist/components/base/skeleton/skeleton.d.ts +22 -0
- package/dist/components/base/skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/base/typography/typography.d.ts +2 -2
- package/dist/components/features/app-navigation/app-navigation.d.ts +14 -0
- package/dist/components/features/app-navigation/app-navigation.d.ts.map +1 -0
- package/dist/components/features/app-navigation/index.d.ts +4 -0
- package/dist/components/features/app-navigation/index.d.ts.map +1 -0
- package/dist/components/features/{sidebar/nav-main.d.ts → app-navigation/nav-menu.d.ts} +3 -3
- package/dist/components/features/app-navigation/nav-menu.d.ts.map +1 -0
- package/dist/components/features/calendar-date-picker/calendar-date-picker.d.ts +2 -1
- package/dist/components/features/calendar-date-picker/calendar-date-picker.d.ts.map +1 -1
- package/dist/components/features/data-table/components/active-filters.d.ts +1 -1
- package/dist/components/features/data-table/components/active-filters.d.ts.map +1 -1
- package/dist/components/features/data-table/components/content.d.ts.map +1 -1
- package/dist/components/features/data-table/components/loading.d.ts.map +1 -1
- package/dist/components/features/data-table/components/search.d.ts +1 -1
- package/dist/components/features/data-table/components/search.d.ts.map +1 -1
- package/dist/components/features/data-table/core/client-provider.d.ts +5 -7
- package/dist/components/features/data-table/core/client-provider.d.ts.map +1 -1
- package/dist/components/features/data-table/core/data-table-context.d.ts +23 -0
- package/dist/components/features/data-table/core/data-table-context.d.ts.map +1 -1
- package/dist/components/features/data-table/core/filter-engine.d.ts +5 -0
- package/dist/components/features/data-table/core/filter-engine.d.ts.map +1 -1
- package/dist/components/features/data-table/core/server-provider.d.ts +4 -7
- package/dist/components/features/data-table/core/server-provider.d.ts.map +1 -1
- package/dist/components/features/data-table/core/store.d.ts.map +1 -1
- package/dist/components/features/data-table/data-table.d.ts +1 -1
- package/dist/components/features/data-table/filters/checkbox-filter.d.ts +1 -1
- package/dist/components/features/data-table/filters/checkbox-filter.d.ts.map +1 -1
- package/dist/components/features/data-table/filters/date-picker-filter.d.ts +1 -1
- package/dist/components/features/data-table/filters/date-picker-filter.d.ts.map +1 -1
- package/dist/components/features/data-table/filters/select-filter.d.ts +1 -1
- package/dist/components/features/data-table/filters/select-filter.d.ts.map +1 -1
- package/dist/components/features/data-table/hooks/index.d.ts +1 -1
- package/dist/components/features/data-table/hooks/index.d.ts.map +1 -1
- package/dist/components/features/data-table/hooks/use-data-table-client.d.ts +11 -10
- package/dist/components/features/data-table/hooks/use-data-table-client.d.ts.map +1 -1
- package/dist/components/features/data-table/hooks/use-data-table-server.d.ts +12 -17
- package/dist/components/features/data-table/hooks/use-data-table-server.d.ts.map +1 -1
- package/dist/components/features/data-table/hooks/use-selectors.d.ts +4 -33
- package/dist/components/features/data-table/hooks/use-selectors.d.ts.map +1 -1
- package/dist/components/features/data-table/index.d.ts +2 -4
- package/dist/components/features/data-table/index.d.ts.map +1 -1
- package/dist/components/features/data-table/types.d.ts +28 -33
- package/dist/components/features/data-table/types.d.ts.map +1 -1
- package/dist/components/features/index.d.ts +1 -1
- package/dist/components/features/index.d.ts.map +1 -1
- package/dist/data-table/index.mjs +481 -388
- package/dist/date-picker/index.mjs +2 -2
- package/dist/dropdown/index.mjs +1 -1
- package/dist/dropzone/index.mjs +1 -1
- package/dist/empty-content/index.mjs +1 -1
- package/dist/form/index.mjs +3 -3
- package/dist/grid/index.mjs +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/index.mjs +34 -32
- package/dist/input-number/index.mjs +1 -1
- package/dist/input-with-addons/index.mjs +1 -1
- package/dist/loader-overlay/index.mjs +1 -1
- package/dist/map/index.mjs +1 -1
- package/dist/{map-ClJD-qxm.mjs → map-2RG9pYZR.mjs} +1 -1
- package/dist/more-actions/index.mjs +2 -2
- package/dist/{more-actions-DbC8dyed.mjs → more-actions-BODYgG1C.mjs} +2 -2
- package/dist/page-title/index.mjs +1 -1
- package/dist/sidebar/index.mjs +4 -5
- package/dist/{sidebar-C4NqSr4r.mjs → sidebar-BW76ss_f.mjs} +6 -415
- package/dist/skeleton/index.mjs +2 -1
- package/dist/skeleton-DZ31pU4B.mjs +28 -0
- package/dist/stepper/index.mjs +1 -1
- package/dist/styles/root.css +3 -0
- package/dist/switch/index.mjs +1 -1
- package/dist/table/index.mjs +1 -1
- package/dist/tabs/index.mjs +1 -1
- package/dist/tag-input/index.mjs +1 -1
- package/dist/task-queue/index.mjs +3 -3
- package/dist/{task-queue-dropdown-fo3TX58Q.mjs → task-queue-dropdown-DtS0IKci.mjs} +3 -3
- package/dist/textarea/index.mjs +1 -1
- package/dist/theme/index.mjs +1 -1
- package/dist/toast/index.mjs +1 -1
- package/dist/tooltip/index.mjs +1 -1
- package/dist/typography/index.mjs +1 -1
- package/dist/{use-copy-to-clipboard-C7xqNxBX.mjs → use-copy-to-clipboard-C9cT2Qb-.mjs} +1 -1
- package/dist/{use-stepper-CB1injte.mjs → use-stepper-DJd8o9dV.mjs} +8 -8
- package/dist/visually-hidden/index.mjs +1 -1
- package/package.json +83 -77
- package/dist/components/features/data-table/hooks/use-data-table-context.d.ts +0 -2
- package/dist/components/features/data-table/hooks/use-data-table-context.d.ts.map +0 -1
- package/dist/components/features/sidebar/app-sidebar.d.ts +0 -14
- package/dist/components/features/sidebar/app-sidebar.d.ts.map +0 -1
- package/dist/components/features/sidebar/index.d.ts +0 -4
- package/dist/components/features/sidebar/index.d.ts.map +0 -1
- package/dist/components/features/sidebar/nav-main.d.ts.map +0 -1
- package/dist/components/features/sidebar/sidebar.d.ts.map +0 -1
- /package/dist/{col-RfO7d6AR.mjs → col-DCneNxQj.mjs} +0 -0
- /package/dist/{dropdown-Cs7Xr8w7.mjs → dropdown-Dgm_b6Mm.mjs} +0 -0
- /package/dist/{dropzone-BT5fEDEF.mjs → dropzone-DR6O9OdU.mjs} +0 -0
- /package/dist/{empty-content-iDu3NUqG.mjs → empty-content-Dm7_5jO9.mjs} +0 -0
- /package/dist/{input-number-D9ydFith.mjs → input-number-D1HCcTXO.mjs} +0 -0
- /package/dist/{input-with-addons-CdgiUQce.mjs → input-with-addons-DN9LGwUU.mjs} +0 -0
- /package/dist/{loader-overlay-D83QeQNj.mjs → loader-overlay-CpA0zV8D.mjs} +0 -0
- /package/dist/{map-leaflet-imports-CdzvEnzY.mjs → map-leaflet-imports-CgEyVRnp.mjs} +0 -0
- /package/dist/{page-title-SGchAF6Y.mjs → page-title-D62FV6vD.mjs} +0 -0
- /package/dist/{skeleton-Cs6Q5GQc.mjs → skeleton-CkE23wsL.mjs} +0 -0
- /package/dist/{stepper-BG9DIzN5.mjs → stepper-CZeks9Ex.mjs} +0 -0
- /package/dist/{switch-B2VVauH6.mjs → switch-Cn9IM2gC.mjs} +0 -0
- /package/dist/{table-Dc3HfbM4.mjs → table-Dpzh0VPK.mjs} +0 -0
- /package/dist/{tabs-Ccb4uqbe.mjs → tabs-OYVCDOif.mjs} +0 -0
- /package/dist/{tag-input-BfHaKoMF.mjs → tag-input-DorFQ9bA.mjs} +0 -0
- /package/dist/{textarea-X4OjkqLJ.mjs → textarea-KZUKGHlO.mjs} +0 -0
- /package/dist/{theme.provider-Nun_O9-O.mjs → theme.provider-BG3cS9xe.mjs} +0 -0
- /package/dist/{to-api-format-zI26rEBI.mjs → to-api-format-CzPt5UAX.mjs} +0 -0
- /package/dist/{tooltip-DZFG1iMs.mjs → tooltip-U3XxlW4l.mjs} +0 -0
- /package/dist/{typography-T7WgvO77.mjs → typography-DdrxIJMd.mjs} +0 -0
- /package/dist/{use-debounce-Ctljs3MB.mjs → use-debounce-Dc95PFRX.mjs} +0 -0
- /package/dist/{use-toast-DN-fZBzJ.mjs → use-toast-DBmysDS6.mjs} +0 -0
- /package/dist/{visuallyhidden-CgkVhApW.mjs → visuallyhidden-CfBnXfvh.mjs} +0 -0
|
@@ -12,11 +12,12 @@ import { t as Label } from "../label-_ste_Re3.mjs";
|
|
|
12
12
|
import { i as DropdownMenuItem, l as DropdownMenuTrigger, r as DropdownMenuContent, t as DropdownMenu } from "../dropdown-menu-DAFyO-qD.mjs";
|
|
13
13
|
import { i as PopoverTrigger, r as PopoverContent, t as Popover } from "../popover-Ds9624qY.mjs";
|
|
14
14
|
import { i as SelectItem, l as SelectTrigger, n as SelectContent, t as Select, u as SelectValue } from "../select-CwVIFWFO.mjs";
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
import { t as
|
|
15
|
+
import "../skeleton-CkE23wsL.mjs";
|
|
16
|
+
import { t as Skeleton } from "../skeleton-DZ31pU4B.mjs";
|
|
17
|
+
import { c as TableRow, i as TableCell, n as TableBody, o as TableHead, s as TableHeader, t as Table } from "../table-Dpzh0VPK.mjs";
|
|
18
|
+
import { t as CalendarDatePicker } from "../calendar-date-picker-Bw6Mrr-P.mjs";
|
|
18
19
|
import { ArrowDown, ArrowUp, ArrowUpDown, Check, ChevronDown, ChevronLeft, ChevronRight, MoreHorizontal, X } from "lucide-react";
|
|
19
|
-
import { createContext, memo, use, useCallback, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
20
|
+
import { createContext, memo, use, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
20
21
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
21
22
|
import { parseAsInteger, parseAsString, useQueryStates } from "nuqs";
|
|
22
23
|
import { flexRender, getCoreRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
|
@@ -157,6 +158,16 @@ function withSelectionColumn(columns, options = {}) {
|
|
|
157
158
|
|
|
158
159
|
//#endregion
|
|
159
160
|
//#region src/components/features/data-table/core/filter-engine.ts
|
|
161
|
+
/**
|
|
162
|
+
* Resolve a dot-path on an object (e.g. "status.registrationApproval").
|
|
163
|
+
* Falls back to a flat key lookup when the path has no dots.
|
|
164
|
+
*/
|
|
165
|
+
function resolvePath(obj, path) {
|
|
166
|
+
if (obj == null) return void 0;
|
|
167
|
+
const record = obj;
|
|
168
|
+
if (!path.includes(".")) return record[path];
|
|
169
|
+
return path.split(".").reduce((acc, key) => acc != null ? acc[key] : void 0, record);
|
|
170
|
+
}
|
|
160
171
|
const FILTER_STRATEGIES = {
|
|
161
172
|
"checkbox": (cellValue, filterValue) => {
|
|
162
173
|
if (filterValue == null) return true;
|
|
@@ -200,14 +211,13 @@ function applyFilters(data, filters, search, registeredFilters, customFilterFns,
|
|
|
200
211
|
console.warn(`[DataTable] No filter strategy registered for column "${column}". Filter ignored.`);
|
|
201
212
|
continue;
|
|
202
213
|
}
|
|
203
|
-
|
|
204
|
-
if (!fn(cellValue, value)) return false;
|
|
214
|
+
if (!fn(resolvePath(row, column), value)) return false;
|
|
205
215
|
}
|
|
206
216
|
if (hasSearch) {
|
|
207
217
|
const query = search.toLowerCase();
|
|
208
218
|
if (searchConfig.searchFn) return searchConfig.searchFn(row, search);
|
|
209
219
|
if (searchConfig.searchableColumns && searchConfig.searchableColumns.length > 0) return searchConfig.searchableColumns.some((col) => {
|
|
210
|
-
const cellValue = row
|
|
220
|
+
const cellValue = resolvePath(row, col);
|
|
211
221
|
return cellValue != null && String(cellValue).toLowerCase().includes(query);
|
|
212
222
|
});
|
|
213
223
|
return Object.values(row).some((val) => {
|
|
@@ -240,10 +250,12 @@ function createDataTableStore(options) {
|
|
|
240
250
|
rowSelection: {},
|
|
241
251
|
pageIndex: 0,
|
|
242
252
|
pageSize: options.pageSize ?? DEFAULT_PAGE_SIZE,
|
|
253
|
+
columnCount: options.columnCount ?? 0,
|
|
243
254
|
mode: options.mode,
|
|
244
|
-
isLoading: false,
|
|
255
|
+
isLoading: options.isLoading ?? false,
|
|
245
256
|
error: null,
|
|
246
|
-
inlineContents: []
|
|
257
|
+
inlineContents: [],
|
|
258
|
+
_version: 0
|
|
247
259
|
};
|
|
248
260
|
if (options.defaultFilters && Object.keys(options.defaultFilters).length > 0) state = {
|
|
249
261
|
...state,
|
|
@@ -253,7 +265,10 @@ function createDataTableStore(options) {
|
|
|
253
265
|
for (const listener of listeners) listener();
|
|
254
266
|
}
|
|
255
267
|
function setState(next) {
|
|
256
|
-
state =
|
|
268
|
+
state = {
|
|
269
|
+
...next,
|
|
270
|
+
_version: state._version + 1
|
|
271
|
+
};
|
|
257
272
|
notify();
|
|
258
273
|
}
|
|
259
274
|
return {
|
|
@@ -281,7 +296,6 @@ function createDataTableStore(options) {
|
|
|
281
296
|
filteredData: data
|
|
282
297
|
});
|
|
283
298
|
},
|
|
284
|
-
setTable: (_t) => {},
|
|
285
299
|
setSorting: (sorting) => {
|
|
286
300
|
setState({
|
|
287
301
|
...state,
|
|
@@ -442,16 +456,34 @@ function createDataTableStore(options) {
|
|
|
442
456
|
//#region src/components/features/data-table/core/data-table-context.tsx
|
|
443
457
|
const DataTableStoreContext = createContext(null);
|
|
444
458
|
const TableInstanceContext = createContext(null);
|
|
459
|
+
/**
|
|
460
|
+
* Monotonic counter that increments on every store mutation.
|
|
461
|
+
* Table-dependent hooks consume this context to force re-renders
|
|
462
|
+
* through React's {children} composition boundary, since the
|
|
463
|
+
* mutable table singleton (stable ref) cannot trigger context updates.
|
|
464
|
+
*/
|
|
465
|
+
const DataTableRenderKeyContext = createContext(0);
|
|
466
|
+
/**
|
|
467
|
+
* Forces a re-render when the store changes. Used by table-dependent hooks.
|
|
468
|
+
* Uses useContext (not use()) because use() does not reliably register
|
|
469
|
+
* context subscriptions in SSR/hydration scenarios (React Router SSR),
|
|
470
|
+
* preventing re-renders when the context value changes.
|
|
471
|
+
*/
|
|
472
|
+
function useRenderKey() {
|
|
473
|
+
return useContext(DataTableRenderKeyContext);
|
|
474
|
+
}
|
|
445
475
|
const DataTableContext = createContext(null);
|
|
446
476
|
function useDataTableStore() {
|
|
447
477
|
const store = use(DataTableStoreContext);
|
|
448
478
|
if (!store) throw new Error("useDataTableStore must be used within a <DataTable.Client> or <DataTable.Server> provider");
|
|
449
479
|
return store;
|
|
450
480
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
481
|
+
/**
|
|
482
|
+
* Returns the table instance or null if not yet available.
|
|
483
|
+
* Used by hooks that need to handle the null-table window during SSR.
|
|
484
|
+
*/
|
|
485
|
+
function useTableInstanceOrNull() {
|
|
486
|
+
return use(TableInstanceContext);
|
|
455
487
|
}
|
|
456
488
|
|
|
457
489
|
//#endregion
|
|
@@ -482,7 +514,7 @@ function useSliceSelector(selector) {
|
|
|
482
514
|
cachedRef.current = next;
|
|
483
515
|
return next;
|
|
484
516
|
}, [store, selector]);
|
|
485
|
-
return useSyncExternalStore(store.subscribe, getSnapshot);
|
|
517
|
+
return useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
|
|
486
518
|
}
|
|
487
519
|
function useDataTableFilters() {
|
|
488
520
|
const store = useDataTableStore();
|
|
@@ -511,49 +543,64 @@ function useDataTableSorting() {
|
|
|
511
543
|
}), [store]));
|
|
512
544
|
}
|
|
513
545
|
function useDataTableSelection() {
|
|
546
|
+
useRenderKey();
|
|
514
547
|
const store = useDataTableStore();
|
|
515
|
-
const table =
|
|
516
|
-
return
|
|
517
|
-
rowSelection:
|
|
548
|
+
const table = useTableInstanceOrNull();
|
|
549
|
+
return {
|
|
550
|
+
rowSelection: store.getSnapshot().rowSelection,
|
|
518
551
|
setRowSelection: store.setRowSelection,
|
|
519
|
-
selectedRows: table.getFilteredSelectedRowModel().rows.map((r) => r.original)
|
|
520
|
-
}
|
|
552
|
+
selectedRows: table ? table.getFilteredSelectedRowModel().rows.map((r) => r.original) : []
|
|
553
|
+
};
|
|
521
554
|
}
|
|
522
555
|
function useDataTablePagination() {
|
|
556
|
+
useRenderKey();
|
|
523
557
|
const store = useDataTableStore();
|
|
524
|
-
const table =
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
558
|
+
const table = useTableInstanceOrNull();
|
|
559
|
+
const state = store.getSnapshot();
|
|
560
|
+
if (!table) return {
|
|
561
|
+
canNextPage: false,
|
|
562
|
+
canPrevPage: false,
|
|
563
|
+
nextPage: () => {},
|
|
564
|
+
prevPage: () => {},
|
|
565
|
+
pageIndex: state.pageIndex,
|
|
566
|
+
pageCount: 0,
|
|
567
|
+
setPageIndex: store.setPageIndex,
|
|
568
|
+
pageSize: state.pageSize,
|
|
569
|
+
setPageSize: store.setPageSize,
|
|
570
|
+
totalRows: 0
|
|
571
|
+
};
|
|
572
|
+
return {
|
|
528
573
|
canNextPage: table.getCanNextPage(),
|
|
529
574
|
canPrevPage: table.getCanPreviousPage(),
|
|
530
|
-
nextPage,
|
|
531
|
-
prevPage,
|
|
575
|
+
nextPage: () => table.nextPage(),
|
|
576
|
+
prevPage: () => table.previousPage(),
|
|
532
577
|
pageIndex: state.pageIndex,
|
|
533
578
|
pageCount: table.getPageCount(),
|
|
534
579
|
setPageIndex: store.setPageIndex,
|
|
535
580
|
pageSize: state.pageSize,
|
|
536
581
|
setPageSize: store.setPageSize,
|
|
537
582
|
totalRows: state.filteredData.length
|
|
538
|
-
}
|
|
539
|
-
store,
|
|
540
|
-
table,
|
|
541
|
-
nextPage,
|
|
542
|
-
prevPage
|
|
543
|
-
]));
|
|
583
|
+
};
|
|
544
584
|
}
|
|
545
585
|
function useDataTableRows() {
|
|
546
|
-
|
|
547
|
-
|
|
586
|
+
useRenderKey();
|
|
587
|
+
const table = useTableInstanceOrNull();
|
|
588
|
+
if (!table) return {
|
|
589
|
+
rows: [],
|
|
590
|
+
headerGroups: [],
|
|
591
|
+
totalColumns: 0
|
|
592
|
+
};
|
|
593
|
+
return {
|
|
548
594
|
rows: table.getRowModel().rows,
|
|
549
595
|
headerGroups: table.getHeaderGroups(),
|
|
550
596
|
totalColumns: table.getAllColumns().length
|
|
551
|
-
}
|
|
597
|
+
};
|
|
552
598
|
}
|
|
553
599
|
function useDataTableLoading() {
|
|
554
600
|
return useSliceSelector(useCallback((state) => ({
|
|
555
601
|
isLoading: state.isLoading,
|
|
556
|
-
error: state.error
|
|
602
|
+
error: state.error,
|
|
603
|
+
columnCount: state.columnCount
|
|
557
604
|
}), []));
|
|
558
605
|
}
|
|
559
606
|
function useDataTableInlineContents() {
|
|
@@ -564,49 +611,12 @@ function useDataTableInlineContents() {
|
|
|
564
611
|
unregisterInlineContent: store.unregisterInlineContent
|
|
565
612
|
}), [store]));
|
|
566
613
|
}
|
|
567
|
-
function useDataTableContext() {
|
|
568
|
-
const store = useDataTableStore();
|
|
569
|
-
const table = useTableInstance();
|
|
570
|
-
const state = useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
571
|
-
return {
|
|
572
|
-
table,
|
|
573
|
-
mode: state.mode,
|
|
574
|
-
sorting: state.sorting,
|
|
575
|
-
filters: state.filters,
|
|
576
|
-
search: state.search,
|
|
577
|
-
rowSelection: state.rowSelection,
|
|
578
|
-
isLoading: state.isLoading,
|
|
579
|
-
setSorting: store.setSorting,
|
|
580
|
-
setFilter: store.setFilter,
|
|
581
|
-
clearFilter: store.clearFilter,
|
|
582
|
-
clearAllFilters: store.clearAllFilters,
|
|
583
|
-
setSearch: store.setSearch,
|
|
584
|
-
clearSearch: store.clearSearch,
|
|
585
|
-
setRowSelection: store.setRowSelection,
|
|
586
|
-
pagination: {
|
|
587
|
-
canNextPage: table.getCanNextPage(),
|
|
588
|
-
canPrevPage: table.getCanPreviousPage(),
|
|
589
|
-
nextPage: () => table.nextPage(),
|
|
590
|
-
prevPage: () => table.previousPage(),
|
|
591
|
-
pageIndex: state.pageIndex,
|
|
592
|
-
pageCount: table.getPageCount(),
|
|
593
|
-
setPageIndex: store.setPageIndex,
|
|
594
|
-
pageSize: state.pageSize,
|
|
595
|
-
setPageSize: store.setPageSize
|
|
596
|
-
},
|
|
597
|
-
inlineContents: state.inlineContents,
|
|
598
|
-
registerInlineContent: store.registerInlineContent,
|
|
599
|
-
unregisterInlineContent: store.unregisterInlineContent
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
614
|
|
|
603
615
|
//#endregion
|
|
604
616
|
//#region src/components/features/data-table/components/active-filters.tsx
|
|
605
|
-
function formatValue(column, value,
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
if (result !== void 0) return result;
|
|
609
|
-
}
|
|
617
|
+
function formatValue(column, value, formatters) {
|
|
618
|
+
const fn = formatters?.[column];
|
|
619
|
+
if (fn) return fn(value);
|
|
610
620
|
return String(value);
|
|
611
621
|
}
|
|
612
622
|
function FilterGroup({ label, children, className }) {
|
|
@@ -621,14 +631,15 @@ function FilterGroup({ label, children, className }) {
|
|
|
621
631
|
});
|
|
622
632
|
}
|
|
623
633
|
const EMPTY_LABELS = {};
|
|
624
|
-
function ActiveFiltersInner({ label = "Selected Filters", filterLabels = EMPTY_LABELS, formatFilterValue:
|
|
634
|
+
function ActiveFiltersInner({ label = "Selected Filters", excludeFilters, filterLabels = EMPTY_LABELS, formatFilterValue: formatters, clearAll = "icon", clearAllLabel = "Clear all", className, groupClassName, badgeClassName }) {
|
|
625
635
|
const { filters, setFilter, clearFilter, clearAllFilters } = useDataTableFilters();
|
|
626
636
|
const { search, clearSearch } = useDataTableSearch();
|
|
627
|
-
const
|
|
628
|
-
const
|
|
637
|
+
const excludeSet = useMemo(() => new Set(excludeFilters ?? []), [excludeFilters]);
|
|
638
|
+
const activeFilterEntries = Object.entries(filters).filter(([key, value]) => !excludeSet.has(key) && value != null && value !== "" && !(Array.isArray(value) && value.length === 0));
|
|
639
|
+
const showSearch = search.length > 0 && !excludeSet.has("search");
|
|
629
640
|
const hasFilters = activeFilterEntries.length > 0;
|
|
630
|
-
if (!
|
|
631
|
-
const totalGroups = activeFilterEntries.length + (
|
|
641
|
+
if (!showSearch && !hasFilters) return null;
|
|
642
|
+
const totalGroups = activeFilterEntries.length + (showSearch ? 1 : 0);
|
|
632
643
|
const removeArrayItem = (column, items, item) => {
|
|
633
644
|
const remaining = items.filter((v) => v !== item);
|
|
634
645
|
if (remaining.length > 0) setFilter(column, remaining);
|
|
@@ -636,7 +647,7 @@ function ActiveFiltersInner({ label = "Selected Filters", filterLabels = EMPTY_L
|
|
|
636
647
|
};
|
|
637
648
|
const handleClearAll = () => {
|
|
638
649
|
clearAllFilters();
|
|
639
|
-
if (
|
|
650
|
+
if (search.length > 0) clearSearch();
|
|
640
651
|
};
|
|
641
652
|
const badgeCn = cn("flex items-center gap-1.5 px-2 py-0.5 text-xs", badgeClassName);
|
|
642
653
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -649,7 +660,7 @@ function ActiveFiltersInner({ label = "Selected Filters", filterLabels = EMPTY_L
|
|
|
649
660
|
"data-slot": "dt-active-filters-label",
|
|
650
661
|
children: label
|
|
651
662
|
}),
|
|
652
|
-
|
|
663
|
+
showSearch && /* @__PURE__ */ jsx(FilterGroup, {
|
|
653
664
|
label: "Search",
|
|
654
665
|
className: groupClassName,
|
|
655
666
|
children: /* @__PURE__ */ jsxs(Badge, {
|
|
@@ -678,10 +689,10 @@ function ActiveFiltersInner({ label = "Selected Filters", filterLabels = EMPTY_L
|
|
|
678
689
|
type: "muted",
|
|
679
690
|
theme: "solid",
|
|
680
691
|
className: badgeCn,
|
|
681
|
-
children: [/* @__PURE__ */ jsx("span", { children: formatValue(column, item,
|
|
692
|
+
children: [/* @__PURE__ */ jsx("span", { children: formatValue(column, item, formatters) }), /* @__PURE__ */ jsx(Button, {
|
|
682
693
|
theme: "borderless",
|
|
683
694
|
size: "small",
|
|
684
|
-
"aria-label": `Remove ${formatValue(column, item,
|
|
695
|
+
"aria-label": `Remove ${formatValue(column, item, formatters)} from ${groupLabel}`,
|
|
685
696
|
className: "h-auto p-0 text-muted-foreground hover:text-foreground",
|
|
686
697
|
onClick: () => removeArrayItem(column, value, item),
|
|
687
698
|
children: /* @__PURE__ */ jsx(X, {
|
|
@@ -698,7 +709,7 @@ function ActiveFiltersInner({ label = "Selected Filters", filterLabels = EMPTY_L
|
|
|
698
709
|
type: "muted",
|
|
699
710
|
theme: "solid",
|
|
700
711
|
className: badgeCn,
|
|
701
|
-
children: [/* @__PURE__ */ jsx("span", { children: formatValue(column, value,
|
|
712
|
+
children: [/* @__PURE__ */ jsx("span", { children: formatValue(column, value, formatters) }), /* @__PURE__ */ jsx(Button, {
|
|
702
713
|
theme: "borderless",
|
|
703
714
|
size: "small",
|
|
704
715
|
"aria-label": `Clear ${groupLabel} filter`,
|
|
@@ -804,9 +815,12 @@ function renderInlineContentRow(entry, colSpan, rows) {
|
|
|
804
815
|
}
|
|
805
816
|
function DataTableContent({ emptyMessage, className, tableClassName, headerClassName, headerRowClassName, headerCellClassName, bodyClassName, rowClassName, cellClassName }) {
|
|
806
817
|
const { rows, headerGroups, totalColumns } = useDataTableRows();
|
|
818
|
+
const { isLoading, columnCount } = useDataTableLoading();
|
|
819
|
+
const { pageSize } = useDataTablePagination();
|
|
807
820
|
const { inlineContents } = useDataTableInlineContents();
|
|
808
821
|
const openInlineContents = useMemo(() => inlineContents.filter((e) => e.open), [inlineContents]);
|
|
809
822
|
const colSpan = totalColumns;
|
|
823
|
+
const skeletonColumns = totalColumns || columnCount || DEFAULT_LOADING_ROWS;
|
|
810
824
|
return /* @__PURE__ */ jsx("div", {
|
|
811
825
|
className: cn("datum-ui-data-table", className),
|
|
812
826
|
"data-slot": "dt",
|
|
@@ -843,7 +857,13 @@ function DataTableContent({ emptyMessage, className, tableClassName, headerClass
|
|
|
843
857
|
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
844
858
|
}, cell.id))
|
|
845
859
|
}, row.id);
|
|
846
|
-
}) : /* @__PURE__ */ jsx(TableRow, {
|
|
860
|
+
}) : isLoading ? Array.from({ length: pageSize }, (_, i) => /* @__PURE__ */ jsx(TableRow, {
|
|
861
|
+
"data-slot": "dt-skeleton-row",
|
|
862
|
+
children: Array.from({ length: skeletonColumns }, (_, j) => /* @__PURE__ */ jsx(TableCell, {
|
|
863
|
+
"data-slot": "dt-skeleton-cell",
|
|
864
|
+
children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" })
|
|
865
|
+
}, j))
|
|
866
|
+
}, i)) : /* @__PURE__ */ jsx(TableRow, {
|
|
847
867
|
"data-slot": "dt-row",
|
|
848
868
|
children: /* @__PURE__ */ jsx(TableCell, {
|
|
849
869
|
colSpan,
|
|
@@ -914,19 +934,8 @@ function DataTableLoading({ rows = DEFAULT_LOADING_ROWS, columns = 4, className
|
|
|
914
934
|
return /* @__PURE__ */ jsx("div", {
|
|
915
935
|
className,
|
|
916
936
|
"data-slot": "dt-loading",
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
920
|
-
className: "border-b",
|
|
921
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
922
|
-
className: "flex gap-4 p-4",
|
|
923
|
-
children: Array.from({ length: columns }, (_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-4 flex-1" }, i))
|
|
924
|
-
})
|
|
925
|
-
}), Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ jsx("div", {
|
|
926
|
-
className: "flex gap-4 border-b p-4 last:border-b-0",
|
|
927
|
-
children: Array.from({ length: columns }, (_, colIndex) => /* @__PURE__ */ jsx(Skeleton, { className: "h-4 flex-1" }, colIndex))
|
|
928
|
-
}, rowIndex))]
|
|
929
|
-
})
|
|
937
|
+
style: { overflowX: "auto" },
|
|
938
|
+
children: /* @__PURE__ */ jsxs(Table, { children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, { children: Array.from({ length: columns }, (_, i) => /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" }) }, i)) }) }), /* @__PURE__ */ jsx(TableBody, { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ jsx(TableRow, { children: Array.from({ length: columns }, (_, colIndex) => /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }) }, colIndex)) }, rowIndex)) })] })
|
|
930
939
|
});
|
|
931
940
|
}
|
|
932
941
|
|
|
@@ -1025,9 +1034,9 @@ function DataTablePagination({ pageSizes = DEFAULT_PAGE_SIZES, className }) {
|
|
|
1025
1034
|
return /* @__PURE__ */ jsx(Button, {
|
|
1026
1035
|
theme: isActive ? "solid" : "outline",
|
|
1027
1036
|
size: "small",
|
|
1028
|
-
className: cn("h-8 min-w-8 px-2", isActive && "font-semibold"),
|
|
1037
|
+
className: cn("h-8 min-w-8 px-2", isActive && "pointer-events-none font-semibold"),
|
|
1029
1038
|
onClick: () => setPageIndex(page - 1),
|
|
1030
|
-
disabled: isActive,
|
|
1039
|
+
"aria-disabled": isActive || void 0,
|
|
1031
1040
|
"aria-label": `Page ${page}`,
|
|
1032
1041
|
"aria-current": isActive ? "page" : void 0,
|
|
1033
1042
|
children: page
|
|
@@ -1091,7 +1100,7 @@ function DataTableRowActions({ row, actions, isLoading = false, className }) {
|
|
|
1091
1100
|
|
|
1092
1101
|
//#endregion
|
|
1093
1102
|
//#region src/components/features/data-table/components/search.tsx
|
|
1094
|
-
function DataTableSearch({ placeholder = "Search...", debounceMs = DEFAULT_DEBOUNCE_MS, className }) {
|
|
1103
|
+
function DataTableSearch({ placeholder = "Search...", debounceMs = DEFAULT_DEBOUNCE_MS, className, disabled }) {
|
|
1095
1104
|
const { search, setSearch } = useDataTableSearch();
|
|
1096
1105
|
const [inputValue, setInputValue] = useState(search);
|
|
1097
1106
|
useEffect(() => {
|
|
@@ -1113,18 +1122,105 @@ function DataTableSearch({ placeholder = "Search...", debounceMs = DEFAULT_DEBOU
|
|
|
1113
1122
|
value: inputValue,
|
|
1114
1123
|
onChange: (e) => setInputValue(e.target.value),
|
|
1115
1124
|
className,
|
|
1125
|
+
disabled,
|
|
1116
1126
|
"aria-label": placeholder,
|
|
1117
1127
|
"data-slot": "dt-search"
|
|
1118
1128
|
});
|
|
1119
1129
|
}
|
|
1120
1130
|
|
|
1131
|
+
//#endregion
|
|
1132
|
+
//#region src/components/features/data-table/hooks/use-data-table-client.ts
|
|
1133
|
+
/**
|
|
1134
|
+
* Creates a TanStack Table instance from an existing store.
|
|
1135
|
+
* Does NOT create the store or sync data — the caller is responsible for that.
|
|
1136
|
+
*/
|
|
1137
|
+
function useClientTable(store, options) {
|
|
1138
|
+
const { columns, getRowId, enableRowSelection = false, stateAdapter } = options;
|
|
1139
|
+
const resolvedColumns = useMemo(() => enableRowSelection ? withSelectionColumn(columns, typeof enableRowSelection === "object" ? enableRowSelection : {}) : columns, [columns, enableRowSelection]);
|
|
1140
|
+
const { filteredData, sorting, rowSelection, pageIndex, pageSize: storePageSize, filters, search } = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
1141
|
+
const table = useReactTable({
|
|
1142
|
+
data: filteredData,
|
|
1143
|
+
columns: resolvedColumns,
|
|
1144
|
+
state: {
|
|
1145
|
+
sorting,
|
|
1146
|
+
rowSelection,
|
|
1147
|
+
pagination: {
|
|
1148
|
+
pageIndex,
|
|
1149
|
+
pageSize: storePageSize
|
|
1150
|
+
}
|
|
1151
|
+
},
|
|
1152
|
+
onSortingChange: (updater) => {
|
|
1153
|
+
const next = typeof updater === "function" ? updater(sorting) : updater;
|
|
1154
|
+
store.setSorting(next);
|
|
1155
|
+
},
|
|
1156
|
+
onRowSelectionChange: (updater) => {
|
|
1157
|
+
const next = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
1158
|
+
store.setRowSelection(next);
|
|
1159
|
+
},
|
|
1160
|
+
onPaginationChange: (updater) => {
|
|
1161
|
+
const next = typeof updater === "function" ? updater({
|
|
1162
|
+
pageIndex,
|
|
1163
|
+
pageSize: storePageSize
|
|
1164
|
+
}) : updater;
|
|
1165
|
+
store.setPagination(next.pageIndex, next.pageSize);
|
|
1166
|
+
},
|
|
1167
|
+
getCoreRowModel: getCoreRowModel(),
|
|
1168
|
+
getSortedRowModel: getSortedRowModel(),
|
|
1169
|
+
getPaginationRowModel: getPaginationRowModel(),
|
|
1170
|
+
getRowId,
|
|
1171
|
+
enableRowSelection: !!enableRowSelection
|
|
1172
|
+
});
|
|
1173
|
+
const hydratedRef = useRef(false);
|
|
1174
|
+
useEffect(() => {
|
|
1175
|
+
if (stateAdapter && !hydratedRef.current) {
|
|
1176
|
+
hydratedRef.current = true;
|
|
1177
|
+
const persisted = stateAdapter.read();
|
|
1178
|
+
if (persisted.sorting && persisted.sorting.length > 0) store.setSorting(persisted.sorting);
|
|
1179
|
+
if (persisted.filters) {
|
|
1180
|
+
for (const [key, value] of Object.entries(persisted.filters)) if (value != null) store.setFilter(key, value);
|
|
1181
|
+
}
|
|
1182
|
+
if (persisted.search) store.setSearch(persisted.search);
|
|
1183
|
+
if (persisted.pageIndex != null && persisted.pageIndex > 0) store.setPageIndex(persisted.pageIndex);
|
|
1184
|
+
if (persisted.pageSize != null) store.setPageSize(persisted.pageSize);
|
|
1185
|
+
}
|
|
1186
|
+
}, []);
|
|
1187
|
+
const isFirstWrite = useRef(true);
|
|
1188
|
+
useEffect(() => {
|
|
1189
|
+
if (!stateAdapter) return;
|
|
1190
|
+
if (isFirstWrite.current) {
|
|
1191
|
+
isFirstWrite.current = false;
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
stateAdapter.write({
|
|
1195
|
+
sorting,
|
|
1196
|
+
filters,
|
|
1197
|
+
search,
|
|
1198
|
+
pageIndex,
|
|
1199
|
+
pageSize: storePageSize
|
|
1200
|
+
});
|
|
1201
|
+
}, [
|
|
1202
|
+
sorting,
|
|
1203
|
+
filters,
|
|
1204
|
+
search,
|
|
1205
|
+
pageIndex,
|
|
1206
|
+
storePageSize,
|
|
1207
|
+
stateAdapter
|
|
1208
|
+
]);
|
|
1209
|
+
return { table };
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1121
1212
|
//#endregion
|
|
1122
1213
|
//#region src/components/features/data-table/core/client-provider.tsx
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1214
|
+
/**
|
|
1215
|
+
* Inner component that calls useClientTable.
|
|
1216
|
+
* Only rendered after hydration (gated by tableReady).
|
|
1217
|
+
*/
|
|
1218
|
+
function ClientProviderInner({ store, className, children, ...options }) {
|
|
1219
|
+
const { table } = useClientTable(store, options);
|
|
1220
|
+
return /* @__PURE__ */ jsx(TableInstanceContext, {
|
|
1221
|
+
value: table,
|
|
1222
|
+
children: /* @__PURE__ */ jsx(DataTableRenderKeyContext, {
|
|
1223
|
+
value: store.getSnapshot()._version,
|
|
1128
1224
|
children: /* @__PURE__ */ jsx("div", {
|
|
1129
1225
|
className,
|
|
1130
1226
|
children
|
|
@@ -1132,57 +1228,290 @@ function ClientProvider({ store, table, className, children }) {
|
|
|
1132
1228
|
})
|
|
1133
1229
|
});
|
|
1134
1230
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1231
|
+
function ClientProvider(props) {
|
|
1232
|
+
const { data, columns, loading, pageSize, getRowId, enableRowSelection, defaultSort, defaultFilters, searchableColumns, searchFn, filterFns, stateAdapter, className, children } = props;
|
|
1233
|
+
const store = useMemo(() => createDataTableStore({
|
|
1234
|
+
data,
|
|
1235
|
+
mode: "client",
|
|
1236
|
+
isLoading: true,
|
|
1237
|
+
defaultSort,
|
|
1238
|
+
defaultFilters,
|
|
1239
|
+
pageSize,
|
|
1240
|
+
columnCount: columns.length,
|
|
1241
|
+
searchableColumns,
|
|
1242
|
+
searchFn,
|
|
1243
|
+
filterFns
|
|
1244
|
+
}), []);
|
|
1245
|
+
const isInitialRender = useRef(true);
|
|
1246
|
+
useEffect(() => {
|
|
1247
|
+
if (isInitialRender.current) {
|
|
1248
|
+
isInitialRender.current = false;
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
store.setData(data);
|
|
1252
|
+
}, [data, store]);
|
|
1253
|
+
const [tableReady, setTableReady] = useState(false);
|
|
1254
|
+
useEffect(() => setTableReady(true), []);
|
|
1255
|
+
useEffect(() => {
|
|
1256
|
+
if (!tableReady) return;
|
|
1257
|
+
store.setLoading(loading ?? false);
|
|
1258
|
+
}, [
|
|
1259
|
+
loading,
|
|
1260
|
+
tableReady,
|
|
1261
|
+
store
|
|
1262
|
+
]);
|
|
1139
1263
|
return /* @__PURE__ */ jsx(DataTableStoreContext, {
|
|
1140
1264
|
value: store,
|
|
1141
|
-
children: /* @__PURE__ */ jsx(
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1265
|
+
children: tableReady ? /* @__PURE__ */ jsx(ClientProviderInner, {
|
|
1266
|
+
store,
|
|
1267
|
+
columns,
|
|
1268
|
+
getRowId,
|
|
1269
|
+
enableRowSelection,
|
|
1270
|
+
stateAdapter,
|
|
1271
|
+
className,
|
|
1272
|
+
children
|
|
1273
|
+
}) : /* @__PURE__ */ jsx(TableInstanceContext, {
|
|
1274
|
+
value: null,
|
|
1275
|
+
children: /* @__PURE__ */ jsx(DataTableRenderKeyContext, {
|
|
1276
|
+
value: 0,
|
|
1277
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1278
|
+
className,
|
|
1279
|
+
children
|
|
1280
|
+
})
|
|
1146
1281
|
})
|
|
1147
1282
|
})
|
|
1148
1283
|
});
|
|
1149
1284
|
}
|
|
1150
1285
|
|
|
1151
1286
|
//#endregion
|
|
1152
|
-
//#region src/components/features/data-table/
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1287
|
+
//#region src/components/features/data-table/hooks/use-data-table-server.ts
|
|
1288
|
+
/**
|
|
1289
|
+
* Creates a TanStack Table instance from an existing store.
|
|
1290
|
+
* Handles fetch-on-query-change, cursor pagination, and state adapter sync.
|
|
1291
|
+
* Does NOT create the store — the caller is responsible for that.
|
|
1292
|
+
*/
|
|
1293
|
+
function useServerTable(store, options) {
|
|
1294
|
+
const { columns, fetchFn, transform, getRowId, enableRowSelection = false, stateAdapter } = options;
|
|
1295
|
+
const fetchRef = useRef(fetchFn);
|
|
1296
|
+
const transformRef = useRef(transform);
|
|
1157
1297
|
useEffect(() => {
|
|
1158
|
-
|
|
1159
|
-
|
|
1298
|
+
fetchRef.current = fetchFn;
|
|
1299
|
+
}, [fetchFn]);
|
|
1300
|
+
useEffect(() => {
|
|
1301
|
+
transformRef.current = transform;
|
|
1302
|
+
}, [transform]);
|
|
1303
|
+
const cursorMapRef = useRef(/* @__PURE__ */ new Map());
|
|
1304
|
+
const hasNextPageRef = useRef(false);
|
|
1305
|
+
const { sorting, filters, search, rowSelection, pageSize, pageIndex } = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
1306
|
+
const prevQueryRef = useRef({
|
|
1307
|
+
sorting,
|
|
1308
|
+
filters,
|
|
1309
|
+
search,
|
|
1310
|
+
pageSize
|
|
1311
|
+
});
|
|
1312
|
+
useEffect(() => {
|
|
1313
|
+
const prev = prevQueryRef.current;
|
|
1314
|
+
if (prev.sorting !== sorting || prev.filters !== filters || prev.search !== search || prev.pageSize !== pageSize) {
|
|
1315
|
+
cursorMapRef.current = /* @__PURE__ */ new Map();
|
|
1316
|
+
hasNextPageRef.current = false;
|
|
1317
|
+
if (pageIndex !== 0) {
|
|
1318
|
+
prevQueryRef.current = {
|
|
1319
|
+
sorting,
|
|
1320
|
+
filters,
|
|
1321
|
+
search,
|
|
1322
|
+
pageSize
|
|
1323
|
+
};
|
|
1324
|
+
store.setPageIndex(0);
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
prevQueryRef.current = {
|
|
1329
|
+
sorting,
|
|
1330
|
+
filters,
|
|
1331
|
+
search,
|
|
1332
|
+
pageSize
|
|
1333
|
+
};
|
|
1334
|
+
let cancelled = false;
|
|
1335
|
+
store.setLoading(true);
|
|
1336
|
+
const cursor = cursorMapRef.current.get(pageIndex);
|
|
1337
|
+
fetchRef.current({
|
|
1338
|
+
sorting,
|
|
1339
|
+
filters,
|
|
1340
|
+
search,
|
|
1341
|
+
cursor,
|
|
1342
|
+
limit: pageSize
|
|
1343
|
+
}).then((response) => {
|
|
1344
|
+
if (cancelled) return;
|
|
1345
|
+
const result = transformRef.current(response);
|
|
1346
|
+
store.setServerData(result.data);
|
|
1347
|
+
store.setError(null);
|
|
1348
|
+
if (result.cursor) cursorMapRef.current.set(pageIndex + 1, result.cursor);
|
|
1349
|
+
hasNextPageRef.current = result.hasNextPage;
|
|
1350
|
+
}).catch((error) => {
|
|
1351
|
+
if (cancelled) return;
|
|
1352
|
+
store.setServerData([]);
|
|
1353
|
+
store.setError(error instanceof Error ? error : new Error(String(error)));
|
|
1354
|
+
hasNextPageRef.current = false;
|
|
1355
|
+
}).finally(() => {
|
|
1356
|
+
if (!cancelled) store.setLoading(false);
|
|
1357
|
+
});
|
|
1358
|
+
return () => {
|
|
1359
|
+
cancelled = true;
|
|
1360
|
+
};
|
|
1160
1361
|
}, [
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1362
|
+
sorting,
|
|
1363
|
+
filters,
|
|
1364
|
+
search,
|
|
1365
|
+
pageSize,
|
|
1366
|
+
pageIndex,
|
|
1367
|
+
store
|
|
1164
1368
|
]);
|
|
1165
|
-
const
|
|
1166
|
-
const
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1369
|
+
const resolvedColumns = useMemo(() => enableRowSelection ? withSelectionColumn(columns, typeof enableRowSelection === "object" ? enableRowSelection : {}) : columns, [columns, enableRowSelection]);
|
|
1370
|
+
const table = useReactTable({
|
|
1371
|
+
data: store.getSnapshot().data,
|
|
1372
|
+
columns: resolvedColumns,
|
|
1373
|
+
state: {
|
|
1374
|
+
sorting,
|
|
1375
|
+
rowSelection,
|
|
1376
|
+
pagination: {
|
|
1377
|
+
pageIndex,
|
|
1378
|
+
pageSize
|
|
1379
|
+
}
|
|
1380
|
+
},
|
|
1381
|
+
manualPagination: true,
|
|
1382
|
+
manualSorting: true,
|
|
1383
|
+
manualFiltering: true,
|
|
1384
|
+
pageCount: hasNextPageRef.current ? pageIndex + 2 : pageIndex + 1,
|
|
1385
|
+
getCoreRowModel: getCoreRowModel(),
|
|
1386
|
+
getRowId,
|
|
1387
|
+
enableRowSelection: !!enableRowSelection,
|
|
1388
|
+
onSortingChange: (updater) => {
|
|
1389
|
+
const next = typeof updater === "function" ? updater(sorting) : updater;
|
|
1390
|
+
store.setSorting(next);
|
|
1391
|
+
},
|
|
1392
|
+
onRowSelectionChange: (updater) => {
|
|
1393
|
+
const next = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
1394
|
+
store.setRowSelection(next);
|
|
1395
|
+
},
|
|
1396
|
+
onPaginationChange: (updater) => {
|
|
1397
|
+
const next = typeof updater === "function" ? updater({
|
|
1398
|
+
pageIndex,
|
|
1399
|
+
pageSize
|
|
1400
|
+
}) : updater;
|
|
1401
|
+
store.setPagination(next.pageIndex, next.pageSize);
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
useEffect(() => {
|
|
1405
|
+
if (stateAdapter) stateAdapter.write({
|
|
1406
|
+
sorting,
|
|
1407
|
+
filters,
|
|
1408
|
+
search,
|
|
1409
|
+
pageSize
|
|
1410
|
+
});
|
|
1411
|
+
}, [
|
|
1412
|
+
sorting,
|
|
1413
|
+
filters,
|
|
1414
|
+
search,
|
|
1415
|
+
pageSize,
|
|
1416
|
+
stateAdapter
|
|
1417
|
+
]);
|
|
1418
|
+
return { table };
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
//#endregion
|
|
1422
|
+
//#region src/components/features/data-table/core/server-provider.tsx
|
|
1423
|
+
/**
|
|
1424
|
+
* Inner component that calls useServerTable.
|
|
1425
|
+
* Only rendered after hydration (gated by tableReady).
|
|
1426
|
+
*/
|
|
1427
|
+
function ServerProviderInner({ store, className, children, ...options }) {
|
|
1428
|
+
const { table } = useServerTable(store, options);
|
|
1429
|
+
return /* @__PURE__ */ jsx(TableInstanceContext, {
|
|
1430
|
+
value: table,
|
|
1431
|
+
children: /* @__PURE__ */ jsx(DataTableRenderKeyContext, {
|
|
1432
|
+
value: store.getSnapshot()._version,
|
|
1433
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1434
|
+
className,
|
|
1435
|
+
children
|
|
1436
|
+
})
|
|
1437
|
+
})
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
function ServerProvider(props) {
|
|
1441
|
+
const { columns, fetchFn, transform, limit = 20, getRowId, enableRowSelection, defaultSort, defaultFilters, stateAdapter, className, children } = props;
|
|
1442
|
+
const store = useMemo(() => createDataTableStore({
|
|
1443
|
+
data: [],
|
|
1444
|
+
mode: "server",
|
|
1445
|
+
isLoading: true,
|
|
1446
|
+
defaultSort,
|
|
1447
|
+
defaultFilters,
|
|
1448
|
+
pageSize: limit,
|
|
1449
|
+
columnCount: columns.length
|
|
1450
|
+
}), []);
|
|
1451
|
+
const [tableReady, setTableReady] = useState(false);
|
|
1452
|
+
useEffect(() => setTableReady(true), []);
|
|
1453
|
+
return /* @__PURE__ */ jsx(DataTableStoreContext, {
|
|
1454
|
+
value: store,
|
|
1455
|
+
children: tableReady ? /* @__PURE__ */ jsx(ServerProviderInner, {
|
|
1456
|
+
store,
|
|
1457
|
+
columns,
|
|
1458
|
+
fetchFn,
|
|
1459
|
+
transform,
|
|
1460
|
+
limit,
|
|
1461
|
+
getRowId,
|
|
1462
|
+
enableRowSelection,
|
|
1463
|
+
stateAdapter,
|
|
1464
|
+
className,
|
|
1465
|
+
children
|
|
1466
|
+
}) : /* @__PURE__ */ jsx(TableInstanceContext, {
|
|
1467
|
+
value: null,
|
|
1468
|
+
children: /* @__PURE__ */ jsx(DataTableRenderKeyContext, {
|
|
1469
|
+
value: 0,
|
|
1470
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1471
|
+
className,
|
|
1472
|
+
children
|
|
1473
|
+
})
|
|
1474
|
+
})
|
|
1475
|
+
})
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
//#endregion
|
|
1480
|
+
//#region src/components/features/data-table/filters/checkbox-filter.tsx
|
|
1481
|
+
const MAX_VISIBLE_BADGES = 2;
|
|
1482
|
+
function CheckboxFilter({ column, label, options, className, checkboxPopoverClassName, disabled }) {
|
|
1483
|
+
const { filters, setFilter, clearFilter, registerFilter, unregisterFilter } = useDataTableFilters();
|
|
1484
|
+
const [open, setOpen] = useState(false);
|
|
1485
|
+
useEffect(() => {
|
|
1486
|
+
registerFilter(column, "checkbox");
|
|
1487
|
+
return () => unregisterFilter(column);
|
|
1488
|
+
}, [
|
|
1489
|
+
column,
|
|
1490
|
+
registerFilter,
|
|
1491
|
+
unregisterFilter
|
|
1492
|
+
]);
|
|
1493
|
+
const selectedValues = filters[column] ?? [];
|
|
1494
|
+
const updateValues = (newValues) => {
|
|
1495
|
+
if (newValues.length > 0) setFilter(column, newValues);
|
|
1496
|
+
else clearFilter(column);
|
|
1497
|
+
};
|
|
1498
|
+
const handleToggle = (optionValue, checked) => {
|
|
1499
|
+
updateValues(checked ? [...selectedValues, optionValue] : selectedValues.filter((v) => v !== optionValue));
|
|
1500
|
+
};
|
|
1501
|
+
const removeValue = (optionValue) => {
|
|
1502
|
+
updateValues(selectedValues.filter((v) => v !== optionValue));
|
|
1503
|
+
};
|
|
1504
|
+
const visibleBadges = selectedValues.slice(0, MAX_VISIBLE_BADGES);
|
|
1505
|
+
const remainingCount = selectedValues.length - MAX_VISIBLE_BADGES;
|
|
1506
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
1507
|
+
open,
|
|
1508
|
+
onOpenChange: setOpen,
|
|
1181
1509
|
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
1182
1510
|
asChild: true,
|
|
1183
1511
|
children: /* @__PURE__ */ jsxs(Button, {
|
|
1184
1512
|
theme: "outline",
|
|
1185
|
-
|
|
1513
|
+
disabled,
|
|
1514
|
+
className: cn("h-10 justify-between gap-1", className),
|
|
1186
1515
|
"data-slot": "dt-filter",
|
|
1187
1516
|
"data-testid": "dt-filter-trigger",
|
|
1188
1517
|
children: [selectedValues.length > 0 ? /* @__PURE__ */ jsxs("div", {
|
|
@@ -1261,7 +1590,7 @@ function CheckboxFilter({ column, label, options, className, checkboxPopoverClas
|
|
|
1261
1590
|
|
|
1262
1591
|
//#endregion
|
|
1263
1592
|
//#region src/components/features/data-table/filters/date-picker-filter.tsx
|
|
1264
|
-
function DatePickerFilter({ column, label, className, datePickerPopoverClassName, disableFuture, disablePast, minDate, maxDate }) {
|
|
1593
|
+
function DatePickerFilter({ column, label, className, datePickerPopoverClassName, disableFuture, disablePast, minDate, maxDate, disabled }) {
|
|
1265
1594
|
const { filters, setFilter, clearFilter, registerFilter, unregisterFilter } = useDataTableFilters();
|
|
1266
1595
|
const rawValue = filters[column];
|
|
1267
1596
|
useEffect(() => {
|
|
@@ -1286,8 +1615,9 @@ function DatePickerFilter({ column, label, className, datePickerPopoverClassName
|
|
|
1286
1615
|
numberOfMonths: 1,
|
|
1287
1616
|
closeOnSelect: true,
|
|
1288
1617
|
placeholder: label,
|
|
1289
|
-
triggerClassName: className,
|
|
1618
|
+
triggerClassName: cn("h-10", className),
|
|
1290
1619
|
variant: "outline",
|
|
1620
|
+
disabled,
|
|
1291
1621
|
disableFuture,
|
|
1292
1622
|
disablePast,
|
|
1293
1623
|
minDate,
|
|
@@ -1303,7 +1633,7 @@ function DatePickerFilter({ column, label, className, datePickerPopoverClassName
|
|
|
1303
1633
|
|
|
1304
1634
|
//#endregion
|
|
1305
1635
|
//#region src/components/features/data-table/filters/select-filter.tsx
|
|
1306
|
-
function SelectFilter({ column, label, options, placeholder, searchable = true, className, selectPopoverClassName }) {
|
|
1636
|
+
function SelectFilter({ column, label, options, placeholder, searchable = true, className, selectPopoverClassName, disabled }) {
|
|
1307
1637
|
const { filters, setFilter, clearFilter, registerFilter, unregisterFilter } = useDataTableFilters();
|
|
1308
1638
|
const [open, setOpen] = useState(false);
|
|
1309
1639
|
const value = filters[column];
|
|
@@ -1325,7 +1655,8 @@ function SelectFilter({ column, label, options, placeholder, searchable = true,
|
|
|
1325
1655
|
theme: "outline",
|
|
1326
1656
|
role: "combobox",
|
|
1327
1657
|
"aria-expanded": open,
|
|
1328
|
-
|
|
1658
|
+
disabled,
|
|
1659
|
+
className: cn("h-10 justify-between", className),
|
|
1329
1660
|
"data-slot": "dt-filter",
|
|
1330
1661
|
"data-testid": "dt-filter-trigger",
|
|
1331
1662
|
children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -1388,242 +1719,4 @@ const DataTable = {
|
|
|
1388
1719
|
};
|
|
1389
1720
|
|
|
1390
1721
|
//#endregion
|
|
1391
|
-
|
|
1392
|
-
function useDataTableClient(options) {
|
|
1393
|
-
const { data, columns, pageSize, getRowId, enableRowSelection = false, defaultSort, defaultFilters, searchableColumns, searchFn, filterFns, stateAdapter } = options;
|
|
1394
|
-
const store = useMemo(() => createDataTableStore({
|
|
1395
|
-
data,
|
|
1396
|
-
mode: "client",
|
|
1397
|
-
defaultSort,
|
|
1398
|
-
defaultFilters,
|
|
1399
|
-
pageSize,
|
|
1400
|
-
searchableColumns,
|
|
1401
|
-
searchFn,
|
|
1402
|
-
filterFns
|
|
1403
|
-
}), []);
|
|
1404
|
-
const isInitialRender = useRef(true);
|
|
1405
|
-
useEffect(() => {
|
|
1406
|
-
if (isInitialRender.current) {
|
|
1407
|
-
isInitialRender.current = false;
|
|
1408
|
-
return;
|
|
1409
|
-
}
|
|
1410
|
-
store.setData(data);
|
|
1411
|
-
}, [data, store]);
|
|
1412
|
-
const resolvedColumns = useMemo(() => enableRowSelection ? withSelectionColumn(columns, typeof enableRowSelection === "object" ? enableRowSelection : {}) : columns, [columns, enableRowSelection]);
|
|
1413
|
-
const { filteredData, sorting, rowSelection, pageIndex, pageSize: storePageSize, filters, search } = useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
1414
|
-
const table = useReactTable({
|
|
1415
|
-
data: filteredData,
|
|
1416
|
-
columns: resolvedColumns,
|
|
1417
|
-
state: {
|
|
1418
|
-
sorting,
|
|
1419
|
-
rowSelection,
|
|
1420
|
-
pagination: {
|
|
1421
|
-
pageIndex,
|
|
1422
|
-
pageSize: storePageSize
|
|
1423
|
-
}
|
|
1424
|
-
},
|
|
1425
|
-
onSortingChange: (updater) => {
|
|
1426
|
-
const next = typeof updater === "function" ? updater(sorting) : updater;
|
|
1427
|
-
store.setSorting(next);
|
|
1428
|
-
},
|
|
1429
|
-
onRowSelectionChange: (updater) => {
|
|
1430
|
-
const next = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
1431
|
-
store.setRowSelection(next);
|
|
1432
|
-
},
|
|
1433
|
-
onPaginationChange: (updater) => {
|
|
1434
|
-
const next = typeof updater === "function" ? updater({
|
|
1435
|
-
pageIndex,
|
|
1436
|
-
pageSize: storePageSize
|
|
1437
|
-
}) : updater;
|
|
1438
|
-
store.setPagination(next.pageIndex, next.pageSize);
|
|
1439
|
-
},
|
|
1440
|
-
getCoreRowModel: getCoreRowModel(),
|
|
1441
|
-
getSortedRowModel: getSortedRowModel(),
|
|
1442
|
-
getPaginationRowModel: getPaginationRowModel(),
|
|
1443
|
-
getRowId,
|
|
1444
|
-
enableRowSelection: !!enableRowSelection
|
|
1445
|
-
});
|
|
1446
|
-
const hydratedRef = useRef(false);
|
|
1447
|
-
useEffect(() => {
|
|
1448
|
-
if (stateAdapter && !hydratedRef.current) {
|
|
1449
|
-
hydratedRef.current = true;
|
|
1450
|
-
const persisted = stateAdapter.read();
|
|
1451
|
-
if (persisted.sorting && persisted.sorting.length > 0) store.setSorting(persisted.sorting);
|
|
1452
|
-
if (persisted.filters) {
|
|
1453
|
-
for (const [key, value] of Object.entries(persisted.filters)) if (value != null) store.setFilter(key, value);
|
|
1454
|
-
}
|
|
1455
|
-
if (persisted.search) store.setSearch(persisted.search);
|
|
1456
|
-
if (persisted.pageIndex != null && persisted.pageIndex > 0) store.setPageIndex(persisted.pageIndex);
|
|
1457
|
-
if (persisted.pageSize != null) store.setPageSize(persisted.pageSize);
|
|
1458
|
-
}
|
|
1459
|
-
}, []);
|
|
1460
|
-
const isFirstWrite = useRef(true);
|
|
1461
|
-
useEffect(() => {
|
|
1462
|
-
if (!stateAdapter) return;
|
|
1463
|
-
if (isFirstWrite.current) {
|
|
1464
|
-
isFirstWrite.current = false;
|
|
1465
|
-
return;
|
|
1466
|
-
}
|
|
1467
|
-
stateAdapter.write({
|
|
1468
|
-
sorting,
|
|
1469
|
-
filters,
|
|
1470
|
-
search,
|
|
1471
|
-
pageIndex,
|
|
1472
|
-
pageSize: storePageSize
|
|
1473
|
-
});
|
|
1474
|
-
}, [
|
|
1475
|
-
sorting,
|
|
1476
|
-
filters,
|
|
1477
|
-
search,
|
|
1478
|
-
pageIndex,
|
|
1479
|
-
storePageSize,
|
|
1480
|
-
stateAdapter
|
|
1481
|
-
]);
|
|
1482
|
-
return {
|
|
1483
|
-
store,
|
|
1484
|
-
table
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
//#endregion
|
|
1489
|
-
//#region src/components/features/data-table/hooks/use-data-table-server.ts
|
|
1490
|
-
function useDataTableServer(options) {
|
|
1491
|
-
const { columns, fetchFn, transform, limit = 20, getRowId, enableRowSelection = false, defaultSort, defaultFilters, stateAdapter } = options;
|
|
1492
|
-
const fetchRef = useRef(fetchFn);
|
|
1493
|
-
const transformRef = useRef(transform);
|
|
1494
|
-
useEffect(() => {
|
|
1495
|
-
fetchRef.current = fetchFn;
|
|
1496
|
-
}, [fetchFn]);
|
|
1497
|
-
useEffect(() => {
|
|
1498
|
-
transformRef.current = transform;
|
|
1499
|
-
}, [transform]);
|
|
1500
|
-
const cursorMapRef = useRef(/* @__PURE__ */ new Map());
|
|
1501
|
-
const hasNextPageRef = useRef(false);
|
|
1502
|
-
const store = useMemo(() => createDataTableStore({
|
|
1503
|
-
data: [],
|
|
1504
|
-
mode: "server",
|
|
1505
|
-
defaultSort,
|
|
1506
|
-
defaultFilters,
|
|
1507
|
-
pageSize: limit
|
|
1508
|
-
}), []);
|
|
1509
|
-
const { sorting, filters, search, rowSelection, pageSize, pageIndex } = useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
1510
|
-
const prevQueryRef = useRef({
|
|
1511
|
-
sorting,
|
|
1512
|
-
filters,
|
|
1513
|
-
search,
|
|
1514
|
-
pageSize
|
|
1515
|
-
});
|
|
1516
|
-
useEffect(() => {
|
|
1517
|
-
const prev = prevQueryRef.current;
|
|
1518
|
-
if (prev.sorting !== sorting || prev.filters !== filters || prev.search !== search || prev.pageSize !== pageSize) {
|
|
1519
|
-
cursorMapRef.current = /* @__PURE__ */ new Map();
|
|
1520
|
-
hasNextPageRef.current = false;
|
|
1521
|
-
if (pageIndex !== 0) {
|
|
1522
|
-
prevQueryRef.current = {
|
|
1523
|
-
sorting,
|
|
1524
|
-
filters,
|
|
1525
|
-
search,
|
|
1526
|
-
pageSize
|
|
1527
|
-
};
|
|
1528
|
-
store.setPageIndex(0);
|
|
1529
|
-
return;
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
prevQueryRef.current = {
|
|
1533
|
-
sorting,
|
|
1534
|
-
filters,
|
|
1535
|
-
search,
|
|
1536
|
-
pageSize
|
|
1537
|
-
};
|
|
1538
|
-
let cancelled = false;
|
|
1539
|
-
store.setLoading(true);
|
|
1540
|
-
const cursor = cursorMapRef.current.get(pageIndex);
|
|
1541
|
-
fetchRef.current({
|
|
1542
|
-
sorting,
|
|
1543
|
-
filters,
|
|
1544
|
-
search,
|
|
1545
|
-
cursor,
|
|
1546
|
-
limit: pageSize
|
|
1547
|
-
}).then((response) => {
|
|
1548
|
-
if (cancelled) return;
|
|
1549
|
-
const result = transformRef.current(response);
|
|
1550
|
-
store.setServerData(result.data);
|
|
1551
|
-
store.setError(null);
|
|
1552
|
-
if (result.nextCursor) cursorMapRef.current.set(pageIndex + 1, result.nextCursor);
|
|
1553
|
-
hasNextPageRef.current = result.hasNextPage;
|
|
1554
|
-
}).catch((error) => {
|
|
1555
|
-
if (cancelled) return;
|
|
1556
|
-
store.setServerData([]);
|
|
1557
|
-
store.setError(error instanceof Error ? error : new Error(String(error)));
|
|
1558
|
-
hasNextPageRef.current = false;
|
|
1559
|
-
}).finally(() => {
|
|
1560
|
-
if (!cancelled) store.setLoading(false);
|
|
1561
|
-
});
|
|
1562
|
-
return () => {
|
|
1563
|
-
cancelled = true;
|
|
1564
|
-
};
|
|
1565
|
-
}, [
|
|
1566
|
-
sorting,
|
|
1567
|
-
filters,
|
|
1568
|
-
search,
|
|
1569
|
-
pageSize,
|
|
1570
|
-
pageIndex,
|
|
1571
|
-
store
|
|
1572
|
-
]);
|
|
1573
|
-
const resolvedColumns = useMemo(() => enableRowSelection ? withSelectionColumn(columns, typeof enableRowSelection === "object" ? enableRowSelection : {}) : columns, [columns, enableRowSelection]);
|
|
1574
|
-
const table = useReactTable({
|
|
1575
|
-
data: store.getSnapshot().data,
|
|
1576
|
-
columns: resolvedColumns,
|
|
1577
|
-
state: {
|
|
1578
|
-
sorting,
|
|
1579
|
-
rowSelection,
|
|
1580
|
-
pagination: {
|
|
1581
|
-
pageIndex,
|
|
1582
|
-
pageSize
|
|
1583
|
-
}
|
|
1584
|
-
},
|
|
1585
|
-
manualPagination: true,
|
|
1586
|
-
manualSorting: true,
|
|
1587
|
-
manualFiltering: true,
|
|
1588
|
-
pageCount: hasNextPageRef.current ? pageIndex + 2 : pageIndex + 1,
|
|
1589
|
-
getCoreRowModel: getCoreRowModel(),
|
|
1590
|
-
getRowId,
|
|
1591
|
-
enableRowSelection: !!enableRowSelection,
|
|
1592
|
-
onSortingChange: (updater) => {
|
|
1593
|
-
const next = typeof updater === "function" ? updater(sorting) : updater;
|
|
1594
|
-
store.setSorting(next);
|
|
1595
|
-
},
|
|
1596
|
-
onRowSelectionChange: (updater) => {
|
|
1597
|
-
const next = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
1598
|
-
store.setRowSelection(next);
|
|
1599
|
-
},
|
|
1600
|
-
onPaginationChange: (updater) => {
|
|
1601
|
-
const next = typeof updater === "function" ? updater({
|
|
1602
|
-
pageIndex,
|
|
1603
|
-
pageSize
|
|
1604
|
-
}) : updater;
|
|
1605
|
-
store.setPagination(next.pageIndex, next.pageSize);
|
|
1606
|
-
}
|
|
1607
|
-
});
|
|
1608
|
-
useEffect(() => {
|
|
1609
|
-
if (stateAdapter) stateAdapter.write({
|
|
1610
|
-
sorting,
|
|
1611
|
-
filters,
|
|
1612
|
-
search,
|
|
1613
|
-
pageSize
|
|
1614
|
-
});
|
|
1615
|
-
}, [
|
|
1616
|
-
sorting,
|
|
1617
|
-
filters,
|
|
1618
|
-
search,
|
|
1619
|
-
pageSize,
|
|
1620
|
-
stateAdapter
|
|
1621
|
-
]);
|
|
1622
|
-
return {
|
|
1623
|
-
store,
|
|
1624
|
-
table
|
|
1625
|
-
};
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
//#endregion
|
|
1629
|
-
export { DEFAULT_DEBOUNCE_MS, DEFAULT_LOADING_ROWS, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZES, DataTable, createDataTableStore, createSelectionColumn, useDataTableClient, useDataTableContext, useDataTableFilters, useDataTableInlineContents, useDataTableLoading, useDataTablePagination, useDataTableRows, useDataTableSearch, useDataTableSelection, useDataTableServer, useDataTableSorting, useNuqsAdapter };
|
|
1722
|
+
export { DEFAULT_DEBOUNCE_MS, DEFAULT_LOADING_ROWS, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZES, DataTable, createDataTableStore, createSelectionColumn, useDataTableFilters, useDataTableInlineContents, useDataTableLoading, useDataTablePagination, useDataTableRows, useDataTableSearch, useDataTableSelection, useDataTableSorting, useNuqsAdapter };
|