@verifiedinc-public/shared-ui-elements 11.0.3-beta.1 → 11.1.1

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.
Files changed (46) hide show
  1. package/dist/components/DataTable/DataTable.context.d.ts +102 -0
  2. package/dist/components/DataTable/DataTable.context.mjs +1 -0
  3. package/dist/components/DataTable/DataTable.d.ts +8 -0
  4. package/dist/components/DataTable/DataTable.export.d.ts +37 -0
  5. package/dist/components/DataTable/DataTable.export.mjs +8 -0
  6. package/dist/components/DataTable/DataTable.filters.d.ts +51 -0
  7. package/dist/components/DataTable/DataTable.filters.mjs +1 -0
  8. package/dist/components/DataTable/DataTable.hooks.d.ts +43 -0
  9. package/dist/components/DataTable/DataTable.hooks.mjs +1 -0
  10. package/dist/components/DataTable/DataTable.mjs +1 -0
  11. package/dist/components/DataTable/DataTable.types.d.ts +525 -0
  12. package/dist/components/DataTable/DataTable.utils.d.ts +39 -0
  13. package/dist/components/DataTable/DataTable.utils.mjs +1 -0
  14. package/dist/components/DataTable/DataTableBody.d.ts +7 -0
  15. package/dist/components/DataTable/DataTableBody.mjs +1 -0
  16. package/dist/components/DataTable/DataTableColumnMenu.d.ts +22 -0
  17. package/dist/components/DataTable/DataTableColumnMenu.mjs +1 -0
  18. package/dist/components/DataTable/DataTableExportMenu.d.ts +16 -0
  19. package/dist/components/DataTable/DataTableExportMenu.mjs +1 -0
  20. package/dist/components/DataTable/DataTableFilterPanel.d.ts +36 -0
  21. package/dist/components/DataTable/DataTableFilterPanel.mjs +1 -0
  22. package/dist/components/DataTable/DataTableFooter.d.ts +6 -0
  23. package/dist/components/DataTable/DataTableFooter.mjs +1 -0
  24. package/dist/components/DataTable/DataTableHead.d.ts +8 -0
  25. package/dist/components/DataTable/DataTableHead.mjs +1 -0
  26. package/dist/components/DataTable/DataTableHeaderCell.d.ts +16 -0
  27. package/dist/components/DataTable/DataTableHeaderCell.mjs +1 -0
  28. package/dist/components/DataTable/DataTableManageColumnsPanel.d.ts +30 -0
  29. package/dist/components/DataTable/DataTableManageColumnsPanel.mjs +1 -0
  30. package/dist/components/DataTable/DataTablePanels.d.ts +6 -0
  31. package/dist/components/DataTable/DataTablePanels.mjs +1 -0
  32. package/dist/components/DataTable/DataTableToolbar.d.ts +7 -0
  33. package/dist/components/DataTable/DataTableToolbar.mjs +1 -0
  34. package/dist/components/DataTable/index.d.ts +5 -0
  35. package/dist/components/chart/BillableEventsTable/BillableEventsTable.mjs +1 -1
  36. package/dist/components/chart/BillableEventsTable/BillableEventsTable.types.d.ts +0 -23
  37. package/dist/components/chart/BillableEventsTable/BrandDetailsPanel.d.ts +1 -2
  38. package/dist/components/chart/BillableEventsTable/BrandDetailsPanel.mjs +1 -1
  39. package/dist/components/chart/BillableEventsTable/exportBillableEventsToCsv.d.ts +2 -4
  40. package/dist/components/chart/BillableEventsTable/exportBillableEventsToCsv.mjs +3 -3
  41. package/dist/components/index.d.ts +1 -0
  42. package/dist/components/index.mjs +1 -1
  43. package/dist/hooks/useBidirectionalScroll.d.ts +8 -1
  44. package/dist/hooks/useBidirectionalScroll.mjs +1 -1
  45. package/dist/index.mjs +1 -1
  46. package/package.json +2 -1
@@ -0,0 +1,525 @@
1
+ import { ComponentType, CSSProperties, ReactNode, Ref } from 'react';
2
+ import { SvgIconProps, SxProps, Theme } from '@mui/material';
3
+ import { Cell, ColumnDef, ColumnPinningState, PaginationState, Row, SortingState, VisibilityState } from '@tanstack/react-table';
4
+ import { VirtualItem } from '@tanstack/react-virtual';
5
+ /**
6
+ * Generic record shape — the table works with arrays of objects whose
7
+ * shape is unknown ahead of time.
8
+ */
9
+ export type DataTableData = Record<string, unknown>;
10
+ /** Operators available in the column filter panel (MUI DataGrid parity). */
11
+ export type DataTableFilterOperator = 'contains' | 'doesNotContain' | 'equals' | 'doesNotEqual' | 'startsWith' | 'endsWith' | 'isEmpty' | 'isNotEmpty' | 'isAnyOf';
12
+ /**
13
+ * Low-level value shape used internally by `dataTableFilterFn` — consumed
14
+ * from `DataTableFilterRow` when pre-filtering client-side.
15
+ */
16
+ export interface DataTableFilterValue {
17
+ operator: DataTableFilterOperator;
18
+ /**
19
+ * A single string for most operators; a `string[]` for the multi-value
20
+ * operators (`contains`, `isAnyOf`) — `contains` accepts either.
21
+ */
22
+ value?: string | string[];
23
+ }
24
+ /** Whether all filter rows must match (AND) or any one suffices (OR). */
25
+ export type DataTableFilterLogicOperator = 'and' | 'or';
26
+ /**
27
+ * One row in the filter panel. Each row targets a specific column with an
28
+ * operator and optional value. `id` is a unique key within the current
29
+ * filter state (not the column id) so multiple rows can target the same
30
+ * column.
31
+ */
32
+ export interface DataTableFilterRow {
33
+ id: string;
34
+ columnId: string;
35
+ operator: DataTableFilterOperator;
36
+ /**
37
+ * `string` for most operators; `string[]` for the multi-value operators
38
+ * (`contains`, `isAnyOf`) — `contains` accepts either. Multiple values
39
+ * OR within the row (the cell value matches any of them).
40
+ */
41
+ value?: string | string[];
42
+ }
43
+ /**
44
+ * The full filter state passed to / returned from the table. With
45
+ * `manualFiltering`, translate these into the server query in
46
+ * `onFiltersChange`; client-side filtering is applied automatically
47
+ * otherwise.
48
+ */
49
+ export interface DataTableActiveFilters {
50
+ rows: DataTableFilterRow[];
51
+ logicOperator: DataTableFilterLogicOperator;
52
+ }
53
+ /**
54
+ * Optional per-column display hints, supplied via the TanStack
55
+ * `ColumnDef.meta` field.
56
+ */
57
+ export interface DataTableColumnMeta {
58
+ align?: 'left' | 'right' | 'center';
59
+ /**
60
+ * Column width — any CSS width value: a number for px (e.g. 140) or a
61
+ * string for percentage fill (e.g. '40%'). Applied to the header cell,
62
+ * which sizes the whole column.
63
+ *
64
+ * With `enableColumnResizing`, a numeric (px) width behaves like a
65
+ * drag-resize: the table grows to the sum of the column widths and
66
+ * scrolls horizontally rather than shrinking the other columns to fit,
67
+ * so a large width never reflows its neighbors. Percentage widths still
68
+ * split the available space.
69
+ */
70
+ width?: number | string;
71
+ /**
72
+ * Options suggested by the filter panel's value input for this column.
73
+ * When omitted, suggestions are derived from the column's distinct
74
+ * values in `data` — with `manualFiltering`, `data` only holds the
75
+ * current page, so supply the full set here.
76
+ */
77
+ filterOptions?: string[];
78
+ /**
79
+ * Hides the hover kebab (column menu) on this column even when the table
80
+ * has `enableColumnMenu`. Use for utility columns with nothing to act on
81
+ * (e.g. an expand/select column) so they don't show a menu offering only
82
+ * the global "Manage columns" action.
83
+ */
84
+ disableColumnMenu?: boolean;
85
+ }
86
+ /**
87
+ * Replacement component for one of the table's built-in MUI icons. Slots
88
+ * receive the same props as the icon they replace (`fontSize`, `sx`, ...) so
89
+ * MUI icons drop in directly; custom components are free to ignore them.
90
+ */
91
+ export type DataTableIconComponent = ComponentType<SvgIconProps>;
92
+ /**
93
+ * Custom icon mapping — each slot replaces the MUI icon the table renders
94
+ * there by default. Unset slots keep the MUI default.
95
+ */
96
+ export interface DataTableIcons {
97
+ /**
98
+ * Sort direction arrow on sortable headers. Defaults to the MUI
99
+ * TableSortLabel arrow.
100
+ */
101
+ sort?: DataTableIconComponent;
102
+ /** Column menu "Sort by ASC" item. Defaults to ArrowUpward. */
103
+ sortAsc?: DataTableIconComponent;
104
+ /** Column menu "Sort by DESC" item. Defaults to ArrowDownward. */
105
+ sortDesc?: DataTableIconComponent;
106
+ /** Column menu "Pin to left" item. Defaults to a left-tilted PushPin. */
107
+ pinLeft?: DataTableIconComponent;
108
+ /** Column menu "Pin to right" item. Defaults to a right-tilted PushPin. */
109
+ pinRight?: DataTableIconComponent;
110
+ /** Column menu "Unpin" item. Defaults to PushPinOutlined. */
111
+ unpin?: DataTableIconComponent;
112
+ /**
113
+ * Kebab button on header hover that opens the column menu. Defaults to
114
+ * MoreVert.
115
+ */
116
+ columnMenu?: DataTableIconComponent;
117
+ /**
118
+ * Column menu "Filter" item and the active-filter indicator on filtered
119
+ * headers. Defaults to FilterAlt.
120
+ */
121
+ filter?: DataTableIconComponent;
122
+ /** Toolbar "Filters" button. Defaults to FilterList. */
123
+ openFilterPanel?: DataTableIconComponent;
124
+ /**
125
+ * Toolbar "Manage columns" button and the column menu "Manage columns"
126
+ * item. Defaults to ViewColumn.
127
+ */
128
+ manageColumns?: DataTableIconComponent;
129
+ /** Toolbar "Export" button. Defaults to FileDownloadOutlined. */
130
+ export?: DataTableIconComponent;
131
+ /** Export menu "Print" item. Defaults to Print. */
132
+ print?: DataTableIconComponent;
133
+ /** Export menu "Download as CSV" item. Defaults to DescriptionOutlined. */
134
+ downloadCsv?: DataTableIconComponent;
135
+ /** Export menu "Download as Excel" item. Defaults to GridOnOutlined. */
136
+ downloadExcel?: DataTableIconComponent;
137
+ /** Column menu "Hide column" item. Defaults to VisibilityOff. */
138
+ hideColumn?: DataTableIconComponent;
139
+ /**
140
+ * Search adornments — the toolbar quick search and the manage columns
141
+ * panel input. Defaults to Search.
142
+ */
143
+ search?: DataTableIconComponent;
144
+ /**
145
+ * Clear buttons — clear search and remove a filter panel row. Defaults
146
+ * to Close.
147
+ */
148
+ close?: DataTableIconComponent;
149
+ /** Filter panel "Add filter" button. Defaults to Add. */
150
+ addFilter?: DataTableIconComponent;
151
+ /** Filter panel "Remove all" button. Defaults to DeleteOutline. */
152
+ removeAllFilters?: DataTableIconComponent;
153
+ /** Pagination first-page button. Defaults to FirstPage. */
154
+ paginationFirst?: DataTableIconComponent;
155
+ /** Pagination previous-page button. Defaults to KeyboardArrowLeft. */
156
+ paginationPrevious?: DataTableIconComponent;
157
+ /** Pagination next-page button. Defaults to KeyboardArrowRight. */
158
+ paginationNext?: DataTableIconComponent;
159
+ /** Pagination last-page button. Defaults to LastPage. */
160
+ paginationLast?: DataTableIconComponent;
161
+ }
162
+ /**
163
+ * Props for one body `<TableCell>` matching the default cells: the meta
164
+ * alignment plus, for pinned columns, the sticky offset and background
165
+ * styles (and the fixed-layout overflow clipping).
166
+ */
167
+ export interface DataTableCellProps {
168
+ align?: DataTableColumnMeta['align'];
169
+ style?: CSSProperties;
170
+ sx?: SxProps<Theme>;
171
+ }
172
+ /**
173
+ * Context handed to the custom row renderer. The default row markup is
174
+ * available through `renderDefaultRow` so custom renderers can decorate it
175
+ * (e.g. append an expandable detail row) instead of rebuilding it.
176
+ */
177
+ export interface DataTableRowContext<TData> {
178
+ /** TanStack row — `row.original` holds the raw data object. */
179
+ row: Row<TData>;
180
+ /** Virtual item for this row (index, measured size, offsets). */
181
+ virtualRow: VirtualItem;
182
+ /**
183
+ * Spread onto the first `<TableRow>` of a custom row so the virtualizer
184
+ * can measure its rendered height. Sibling rows rendered after it (e.g.
185
+ * a divider row or an expandable detail row) are measured and observed
186
+ * as part of the same row group — expanding a Collapse panel resizes
187
+ * the virtual row instead of snapping the scroll.
188
+ */
189
+ rowProps: {
190
+ 'data-index': number;
191
+ ref: Ref<HTMLTableRowElement>;
192
+ };
193
+ /**
194
+ * Spread onto each `<TableCell>` of a custom row (built from
195
+ * `row.getVisibleCells()`) to match the default cells — column meta
196
+ * alignment plus, with `enableColumnPinning`, the sticky styles that
197
+ * keep pinned cells in place while the table scrolls horizontally.
198
+ */
199
+ getCellProps: (cell: Cell<TData, unknown>) => DataTableCellProps;
200
+ /** Renders the default `<TableRow>` for this row. */
201
+ renderDefaultRow: () => ReactNode;
202
+ }
203
+ /**
204
+ * Configuration for bidirectional infinite scroll (see
205
+ * `DataTableProps.bidirectionalScroll`). The flags describe a paged,
206
+ * reverse-chronological feed: "newer" pages sit above the loaded window,
207
+ * "older" pages below it.
208
+ */
209
+ export interface DataTableBidirectionalScroll {
210
+ /** Whether more rows exist above the loaded window. */
211
+ hasNewer?: boolean;
212
+ /** Whether more rows exist below the loaded window. */
213
+ hasOlder?: boolean;
214
+ /**
215
+ * Whether a newer-page fetch is in flight — shows the sticky indicator
216
+ * below the header and holds the scroll position when the rows land.
217
+ */
218
+ isLoadingNewer?: boolean;
219
+ /**
220
+ * Whether an older-page fetch is in flight — shows the sticky indicator
221
+ * at the bottom edge.
222
+ */
223
+ isLoadingOlder?: boolean;
224
+ /**
225
+ * Called when the user scrolls to the top edge — fetch the next newer
226
+ * page and prepend its rows to `data`.
227
+ */
228
+ onLoadNewer: () => void;
229
+ /**
230
+ * Called when the user scrolls to the bottom edge — fetch the next older
231
+ * page and append its rows to `data`.
232
+ */
233
+ onLoadOlder: () => void;
234
+ /**
235
+ * When this value changes, the scroll position resets to the top and the
236
+ * edge triggers re-arm. Derive it from the active filters (e.g. a
237
+ * serialised filter string) so a filter change starts a fresh feed.
238
+ */
239
+ resetKey?: string | number;
240
+ /** Label inside the top indicator. Defaults to 'Loading newer rows'. */
241
+ loadingNewerLabel?: string;
242
+ /** Label inside the bottom indicator. Defaults to 'Loading older rows'. */
243
+ loadingOlderLabel?: string;
244
+ }
245
+ export interface DataTableProps<TData extends DataTableData> {
246
+ data: TData[];
247
+ /**
248
+ * TanStack column definitions. When omitted, columns are inferred from
249
+ * the keys of the first data row with sensible header/cell defaults
250
+ * (inferred columns are all sortable).
251
+ *
252
+ * Sorting is opt-in: declare sortable columns with
253
+ * `enableSorting: true` on their defs — columns are plain labels
254
+ * otherwise.
255
+ *
256
+ * Supports TanStack group defs (`{ header: 'Group', columns: [...] }`)
257
+ * for a grouped header: group labels render centered above their
258
+ * sub-columns while ungrouped columns span all header rows.
259
+ */
260
+ columns?: Array<ColumnDef<TData, unknown>>;
261
+ /** Stable row identity; falls back to the row index. */
262
+ getRowId?: (row: TData, index: number) => string;
263
+ /**
264
+ * Custom row renderer; falls back to the default row markup. Custom rows
265
+ * build their own cells, so column visibility (Hide column / Manage
266
+ * columns) only affects them when they render from
267
+ * `row.getVisibleCells()` instead of hardcoding cells. Spread
268
+ * `getCellProps(cell)` onto each cell to keep the default alignment and
269
+ * pinned-column stickiness.
270
+ */
271
+ renderRow?: (context: DataTableRowContext<TData>) => ReactNode;
272
+ /** Initial sorting state, e.g. `[{ id: 'email', desc: false }]`. */
273
+ initialSorting?: SortingState;
274
+ /**
275
+ * Controlled sorting state (pair with `onSortingChange`). Takes
276
+ * precedence over `initialSorting`. When omitted, sorting state is
277
+ * internal.
278
+ */
279
+ sorting?: SortingState;
280
+ /**
281
+ * Called with the next sorting state when a header is clicked. With
282
+ * `manualSorting`, fetch the re-sorted rows from the server in response
283
+ * (and usually reset the page to 0).
284
+ */
285
+ onSortingChange?: (sorting: SortingState) => void;
286
+ /**
287
+ * Server-side sorting: rows in `data` are assumed to already be sorted —
288
+ * header clicks only update the sorting state, nothing is sorted
289
+ * client-side.
290
+ */
291
+ manualSorting?: boolean;
292
+ /** Rows per page when the table mounts. Defaults to 25. */
293
+ initialPageSize?: number;
294
+ /** Options for the rows-per-page select. Defaults to [10, 25, 50, 100]. */
295
+ pageSizeOptions?: number[];
296
+ /**
297
+ * Controlled pagination state (pair with `onPaginationChange`). Use when
298
+ * the consumer needs to drive the page externally — e.g. reset to the
299
+ * first page when filters change. Takes precedence over
300
+ * `initialPageSize`. When omitted, pagination state is internal.
301
+ */
302
+ pagination?: PaginationState;
303
+ /**
304
+ * Called with the next pagination state whenever the page or page size
305
+ * changes. With `manualPagination`, fetch the new page from the server
306
+ * in response (e.g. by keying a React Query on this state).
307
+ */
308
+ onPaginationChange?: (pagination: PaginationState) => void;
309
+ /**
310
+ * Server-side pagination: rows in `data` are treated as the current
311
+ * page (no client-side slicing) and `rowCount` drives the pager.
312
+ */
313
+ manualPagination?: boolean;
314
+ /**
315
+ * Total row count on the server. Required with `manualPagination` so
316
+ * the pager knows how many pages exist.
317
+ */
318
+ rowCount?: number;
319
+ /**
320
+ * Disables sorting for the whole table — headers render as plain labels
321
+ * and rows keep the order of `data`, even for columns declaring
322
+ * `enableSorting: true`.
323
+ */
324
+ disableSorting?: boolean;
325
+ /** Hides the pagination footer and renders all rows (still virtualized). */
326
+ disablePagination?: boolean;
327
+ /**
328
+ * Bidirectional infinite scroll for streaming feeds (e.g. logs):
329
+ * scrolling to the bottom edge calls `onLoadOlder`, scrolling back to
330
+ * the top edge calls `onLoadNewer`, and sticky in-flight indicators pin
331
+ * to the edges while a page loads. The scroll position is preserved when
332
+ * newer rows are prepended, so the viewport doesn't jump.
333
+ *
334
+ * The consumer owns the pages: merge the fetched rows into `data` and
335
+ * flip the `has*` / `isLoading*` flags (e.g. from a React Query infinite
336
+ * query). Pair with `disablePagination` (the scroll edges replace the
337
+ * pager) and `getRowId` (prepended rows shift the indexes, which are the
338
+ * default row identity); rows are assumed to arrive in feed order, so
339
+ * sorting is usually disabled or manual.
340
+ */
341
+ bidirectionalScroll?: DataTableBidirectionalScroll;
342
+ /**
343
+ * Adds drag handles (vertical separator lines) on the header cell edges
344
+ * to resize columns; double-clicking a handle restores the column's
345
+ * pre-drag width. Drags start from the column's rendered width, and the
346
+ * other columns are frozen at theirs — resizing changes the table width
347
+ * (adding horizontal scroll as needed) instead of reflowing the
348
+ * neighboring columns. Per-column opt-out via `enableResizing: false`
349
+ * on the def. Widths are enforced exactly with `tableLayout: 'fixed'`;
350
+ * with the default 'auto', content can keep a column from shrinking
351
+ * below its natural width.
352
+ */
353
+ enableColumnResizing?: boolean;
354
+ /**
355
+ * Shows a kebab menu on each column header (revealed on hover, like the
356
+ * MUI DataGrid) with per-column actions: Sort by ASC/DESC for sortable
357
+ * columns, Pin to left / Pin to right / Unpin with
358
+ * `enableColumnPinning`, Filter for filterable columns, and Hide column
359
+ * / Manage columns for column visibility.
360
+ *
361
+ * Every accessor column is filterable through the operator-based filter
362
+ * panel by default — opt a column out with `enableColumnFilter: false`
363
+ * on its def. Hide the kebab on a specific column (e.g. a utility
364
+ * expand/select column) with `meta.disableColumnMenu`.
365
+ */
366
+ enableColumnMenu?: boolean;
367
+ /**
368
+ * Adds Pin to left / Pin to right / Unpin actions to the column menu.
369
+ * Pinned columns reorder to that edge and stay sticky while the table
370
+ * scrolls horizontally; their offsets are measured from the rendered
371
+ * header cells, so they hold under both table layouts. Per-column
372
+ * opt-out via `enablePinning: false` on the def. Custom `renderRow`
373
+ * rows build their own cells — spread `getCellProps(cell)` onto them
374
+ * to get the sticky styles.
375
+ *
376
+ * The table only scrolls horizontally once it is wider than its
377
+ * container — pair with a `minWidth` beyond the container width (or
378
+ * exact column widths on every column with `tableLayout: 'fixed'`),
379
+ * otherwise there is nothing for pinned columns to stick over.
380
+ */
381
+ enableColumnPinning?: boolean;
382
+ /**
383
+ * Shows a toolbar row above the table with Manage columns and Filters
384
+ * buttons plus a search button that expands into a quick-search input on
385
+ * the right, like the MUI DataGrid toolbar. The filter button carries a
386
+ * badge with the active filter count. While the toolbar is shown, the
387
+ * filter / manage columns panels open anchored to their toolbar button —
388
+ * including when triggered from a column menu — instead of at the column
389
+ * that opened them.
390
+ */
391
+ showToolbar?: boolean;
392
+ /**
393
+ * Adds an Export button to the toolbar (requires `showToolbar`) with
394
+ * Print, Download as CSV and Download as Excel actions. Exports always
395
+ * reflect the displayed table: the filtered + sorted rows across every
396
+ * page and the visible accessor columns in display order (display-only
397
+ * columns are skipped). With grouped columns the export starts with a
398
+ * group header row, like the rendered header. With `manualPagination`
399
+ * only the loaded page is exported.
400
+ */
401
+ enableExport?: boolean;
402
+ /**
403
+ * Base filename (no extension) for the exported files; also the printed
404
+ * document title. Defaults to 'data'.
405
+ */
406
+ exportFilename?: string;
407
+ /**
408
+ * Initial filter state. Rows are applied as AND by default; switch to OR
409
+ * via `logicOperator: 'or'`.
410
+ *
411
+ * @example
412
+ * initialFilters={{ rows: [{ id: 'f1', columnId: 'role', operator: 'equals', value: 'admin' }], logicOperator: 'and' }}
413
+ */
414
+ initialFilters?: DataTableActiveFilters;
415
+ /**
416
+ * Controlled filter state (pair with `onFiltersChange`). Takes
417
+ * precedence over `initialFilters`. When omitted, filter state is
418
+ * internal.
419
+ */
420
+ filters?: DataTableActiveFilters;
421
+ /**
422
+ * Called with the next filter state when the filter panel changes. With
423
+ * `manualFiltering`, fetch the matching rows from the server in response
424
+ * (and usually reset the page to 0).
425
+ */
426
+ onFiltersChange?: (filters: DataTableActiveFilters) => void;
427
+ /**
428
+ * Server-side filtering: rows in `data` are assumed to already match the
429
+ * active filters and search query — the filter panel and the toolbar
430
+ * search input only update their state, nothing is filtered client-side.
431
+ */
432
+ manualFiltering?: boolean;
433
+ /** Initial quick-search query for the toolbar search input. */
434
+ initialSearch?: string;
435
+ /**
436
+ * Controlled quick-search query (pair with `onSearchChange`). Takes
437
+ * precedence over `initialSearch`. When omitted, search state is
438
+ * internal.
439
+ */
440
+ search?: string;
441
+ /**
442
+ * Called with the next query as the user types in the toolbar search
443
+ * input. With `manualFiltering`, fetch the matching rows from the server
444
+ * in response (and usually reset the page to 0).
445
+ */
446
+ onSearchChange?: (search: string) => void;
447
+ /**
448
+ * Initial column visibility, keyed by column id — `{ role: false }`
449
+ * mounts the table with the role column hidden. Also what the manage
450
+ * columns panel's Reset restores. Per-column opt-out from hiding via
451
+ * `enableHiding: false` on the def.
452
+ */
453
+ initialColumnVisibility?: VisibilityState;
454
+ /**
455
+ * Controlled column visibility state (pair with
456
+ * `onColumnVisibilityChange`) — e.g. to persist hidden columns per user.
457
+ * Takes precedence over `initialColumnVisibility`. When omitted,
458
+ * visibility state is internal.
459
+ */
460
+ columnVisibility?: VisibilityState;
461
+ /**
462
+ * Called with the next visibility state whenever a column is hidden or
463
+ * shown (column menu, manage columns panel).
464
+ */
465
+ onColumnVisibilityChange?: (columnVisibility: VisibilityState) => void;
466
+ /**
467
+ * Initial pinned columns, e.g. `{ left: ['email'], right: [] }` —
468
+ * requires `enableColumnPinning`.
469
+ */
470
+ initialColumnPinning?: ColumnPinningState;
471
+ /**
472
+ * Controlled pinning state (pair with `onColumnPinningChange`) — e.g.
473
+ * to persist pinned columns per user. Takes precedence over
474
+ * `initialColumnPinning`. When omitted, pinning state is internal.
475
+ */
476
+ columnPinning?: ColumnPinningState;
477
+ /**
478
+ * Called with the next pinning state whenever a column is pinned or
479
+ * unpinned from the column menu.
480
+ */
481
+ onColumnPinningChange?: (columnPinning: ColumnPinningState) => void;
482
+ /**
483
+ * Content rendered on the left side of the footer, opposite the
484
+ * pagination controls (e.g. a summary, bulk actions or an export button).
485
+ * Rendered even when pagination is disabled.
486
+ */
487
+ footerLeft?: ReactNode;
488
+ /** Estimated row height in px used by the virtualizer. Defaults to 53. */
489
+ estimateRowHeight?: number;
490
+ /**
491
+ * Min width of the table itself (any CSS width value). When it exceeds
492
+ * the container width, the table scrolls horizontally — which is what
493
+ * gives pinned columns something to stick over. Defaults to 650.
494
+ */
495
+ minWidth?: number | string;
496
+ /** Max height of the scroll container. Defaults to 800. */
497
+ maxHeight?: number | string;
498
+ /**
499
+ * Table layout algorithm. With the default 'auto', column widths are
500
+ * hints and content can stretch a column. Use 'fixed' to enforce the
501
+ * exact px/percentage widths set via column meta — content that cannot
502
+ * fit (e.g. long unbreakable strings) is clipped with an ellipsis
503
+ * instead of leaking over the neighboring cells.
504
+ */
505
+ tableLayout?: 'auto' | 'fixed';
506
+ /**
507
+ * Custom icon mapping — replaces the MUI icons the table renders by
508
+ * default (toolbar buttons, column menu items, filter panel actions,
509
+ * pagination arrows). Unset slots keep the MUI default.
510
+ *
511
+ * @example
512
+ * icons={{ search: MagnifyingGlass, columnMenu: DotsThree }}
513
+ */
514
+ icons?: DataTableIcons;
515
+ /** Message displayed when `data` is empty. */
516
+ emptyMessage?: string;
517
+ isLoading?: boolean;
518
+ /**
519
+ * Custom loading state renderer, shown while `isLoading` is true and
520
+ * there are no rows. Rendered inside the table body, so it must return
521
+ * one or more `<TableRow>`s (e.g. skeleton rows). Receives the column
522
+ * count for `colSpan`. Falls back to a default loading row.
523
+ */
524
+ renderLoading?: (columnCount: number) => ReactNode;
525
+ }
@@ -0,0 +1,39 @@
1
+ import { Column, ColumnDef } from '@tanstack/react-table';
2
+ import { DataTableColumnMeta, DataTableData } from './DataTable.types';
3
+ /**
4
+ * Marks tbody rows that don't belong to any virtual row group (the
5
+ * virtualizer padding rows, the bidirectional-scroll edge indicators) so
6
+ * group measurement and observation stop walking when they reach one.
7
+ */
8
+ export declare const VIRTUAL_BOUNDARY_ATTRIBUTE = "data-virtual-boundary";
9
+ /**
10
+ * Measures a logical row group. A single virtual row renders as several
11
+ * sibling `<tr>`s — the data row (which carries `data-index` and the
12
+ * measure ref) plus the divider row and any detail row a custom renderRow
13
+ * appends — so measuring only the first `<tr>` (the virtualizer default)
14
+ * undersizes every row, making the scrollbar jitter while scrolling, and
15
+ * ignores expanded detail panels entirely, snapping the scroll when their
16
+ * row leaves the render window. Sums the whole group up to the next
17
+ * measured row or a boundary row instead.
18
+ */
19
+ export declare function measureRowGroup(element: Element): number;
20
+ /** Turns an object key into a readable header label, e.g. `createdAt` → `Created At`. */
21
+ export declare function formatColumnLabel(key: string): string;
22
+ /** Default cell formatting for values of unknown shape. */
23
+ export declare function formatCellValue(value: unknown): string;
24
+ /** Builds default column definitions from the keys of the first data row. */
25
+ export declare function inferColumns<TData extends DataTableData>(data: TData[]): Array<ColumnDef<TData, unknown>>;
26
+ export declare function getColumnMeta(meta: unknown): DataTableColumnMeta | undefined;
27
+ /**
28
+ * Plain-text label for a column, used where the header def can't be
29
+ * rendered (aria-labels, the filter panel column select, the manage
30
+ * columns list). Function/element headers fall back to a label derived
31
+ * from the column id.
32
+ */
33
+ export declare function getColumnLabel<TData>(column: Column<TData, unknown>): string;
34
+ /**
35
+ * Copies numeric meta widths onto the TanStack `size` (recursing into group
36
+ * defs) so drag-resizing starts from the rendered width instead of jumping
37
+ * to TanStack's 150px default on the first drag.
38
+ */
39
+ export declare function applyMetaWidthsToSizes<TData extends DataTableData>(defs: Array<ColumnDef<TData, unknown>>): Array<ColumnDef<TData, unknown>>;
@@ -0,0 +1 @@
1
+ "use strict";const o="data-virtual-boundary";function l(e){let n=e.offsetHeight,t=e.nextElementSibling;for(;t&&!t.hasAttribute("data-index")&&!t.hasAttribute(o);)n+=t.offsetHeight,t=t.nextElementSibling;return n}function a(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_-]+/g," ").trim().replace(/\b\w/g,n=>n.toUpperCase())}function i(e){return e==null||e===""?"\u2014":e instanceof Date?e.toLocaleString():typeof e=="object"?JSON.stringify(e):String(e)}function s(e){const[n]=e;return n?Object.keys(n).map(t=>({id:t,accessorFn:r=>r[t],header:a(t),cell:r=>i(r.getValue()),enableSorting:!0})):[]}function c(e){return e}function f(e){const{header:n}=e.columnDef;return typeof n=="string"&&n.length>0?n:a(e.id)}function u(e){return e.map(n=>{const t=n.meta,r={...n};return typeof t?.width=="number"&&r.size===void 0&&(r.size=t.width),"columns"in r&&Array.isArray(r.columns)&&(r.columns=u(r.columns)),r})}export{o as VIRTUAL_BOUNDARY_ATTRIBUTE,u as applyMetaWidthsToSizes,i as formatCellValue,a as formatColumnLabel,f as getColumnLabel,c as getColumnMeta,s as inferColumns,l as measureRowGroup};
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * Table body: the loading / empty states, the bidirectional-scroll edge
4
+ * indicators, the virtualizer padding rows and the virtualized data rows
5
+ * (default markup or the consumer's `renderRow`).
6
+ */
7
+ export declare function DataTableBody(): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use strict";import D,{useRef as S,useEffect as I}from"react";import{flexRender as O}from"@tanstack/react-table";import{TableBody as P,TableRow as l,TableCell as i,Typography as T,Stack as j,CircularProgress as N}from"@mui/material";import{useDataTableContext as U}from"./DataTable.context.mjs";import{VIRTUAL_BOUNDARY_ATTRIBUTE as R}from"./DataTable.utils.mjs";import{jsxs as x,jsx as e,Fragment as V}from"react/jsx-runtime";const f={[R]:""};function L({edge:s,top:n=0,columnCount:u,label:g}){return e(l,{...f,sx:{position:"sticky",...s==="top"?{top:n}:{bottom:0},zIndex:2,pointerEvents:"none"},children:e(i,{colSpan:u,sx:{textAlign:"center",py:.75,bgcolor:"grey.100",...s==="top"?{borderBottom:"1px solid"}:{borderTop:"1px solid"},borderColor:"divider"},children:x(j,{direction:"row",alignItems:"center",justifyContent:"center",spacing:1,children:[e(N,{size:12}),e(T,{variant:"caption",color:"text.secondary",children:g})]})})})}function _(){const{rows:s,columnCount:n,isLoading:u,renderLoading:g,emptyMessage:E,bidirectionalScroll:a,headerHeight:A,renderRow:v,getCellProps:y,virtualizer:p}=U(),d=p.getVirtualItems(),m=S(new Set),b=S(null),z=()=>(!b.current&&typeof ResizeObserver<"u"&&(b.current=new ResizeObserver(t=>{for(const o of t){let r=o.target.previousElementSibling;for(;r&&!r.hasAttribute("data-index");)r=r.previousElementSibling;r!=null&&r.isConnected&&p.measureElement(r)}})),b.current);I(()=>()=>{var t;return(t=b.current)==null?void 0:t.disconnect()},[]);const B=t=>{if(p.measureElement(t),!t)return;const o=z();if(!o)return;for(const c of m.current)c.isConnected||(o.unobserve(c),m.current.delete(c));let r=t.nextElementSibling;for(;r&&!r.hasAttribute("data-index")&&!r.hasAttribute(R);)m.current.has(r)||(o.observe(r),m.current.add(r)),r=r.nextElementSibling},w=d.length>0?d[0].start:0,C=d.length>0?p.getTotalSize()-d[d.length-1].end:0;return x(P,{children:[u&&s.length===0&&(g?g(n):e(l,{children:e(i,{colSpan:n,sx:{textAlign:"center",py:2},children:e(T,{color:"text.secondary",children:"Loading..."})})})),!u&&s.length===0&&e(l,{children:e(i,{colSpan:n,children:E})}),a?.isLoadingNewer&&e(L,{edge:"top",top:A,columnCount:n,label:a.loadingNewerLabel??"Loading newer rows"}),w>0&&e(l,{...f,children:e(i,{colSpan:n,sx:{p:0,border:"none"},style:{height:w}})}),d.map(t=>{const o=s[t.index],r={"data-index":t.index,ref:B},c=()=>x(V,{children:[e(l,{hover:!0,...r,sx:{"& > td":{borderBottom:"unset"}},children:o.getVisibleCells().map(h=>e(i,{...y(h),children:O(h.column.columnDef.cell,h.getContext())},h.id))}),e(l,{children:e(i,{colSpan:n,sx:{py:0}})})]});return e(D.Fragment,{children:v?v({row:o,virtualRow:t,rowProps:r,getCellProps:y,renderDefaultRow:c}):c()},o.id)}),C>0&&e(l,{...f,children:e(i,{colSpan:n,sx:{p:0,border:"none"},style:{height:C}})}),a?.isLoadingOlder&&e(L,{edge:"bottom",columnCount:n,label:a.loadingOlderLabel??"Loading older rows"})]})}export{_ as DataTableBody};
@@ -0,0 +1,22 @@
1
+ import { Column } from '@tanstack/react-table';
2
+ import { DataTableData, DataTableIcons } from './DataTable.types';
3
+ interface DataTableColumnMenuProps<TData extends DataTableData> {
4
+ column: Column<TData, unknown>;
5
+ anchorEl: HTMLElement;
6
+ /** Custom icon slots for the menu items; unset slots keep the MUI default. */
7
+ icons?: DataTableIcons;
8
+ /** Blocks the sort actions while a page is being fetched (manualSorting). */
9
+ isLoading: boolean;
10
+ onClose: () => void;
11
+ /** Swaps this menu for the filter panel, preselecting this column. */
12
+ onOpenFilter: () => void;
13
+ /** Swaps this menu for the manage columns panel. */
14
+ onOpenManageColumns: () => void;
15
+ }
16
+ /**
17
+ * Per-column actions menu opened from the kebab button on a header cell,
18
+ * mirroring the MUI DataGrid column menu. Sections render only when the
19
+ * column supports them (e.g. sort items only for sortable columns).
20
+ */
21
+ export declare function DataTableColumnMenu<TData extends DataTableData>({ column, anchorEl, icons, isLoading, onClose, onOpenFilter, onOpenManageColumns, }: Readonly<DataTableColumnMenuProps<TData>>): import("react").JSX.Element;
22
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";import{Menu as L,MenuItem as l,ListItemIcon as r,ListItemText as t,Divider as f}from"@mui/material";import{ViewColumn as v,ArrowUpward as E,ArrowDownward as U,PushPinOutlined as V,FilterAlt as j,VisibilityOff as H,PushPin as u}from"@mui/icons-material";import{jsxs as e,jsx as n}from"react/jsx-runtime";function T(i){return n(u,{...i,sx:{transform:"rotate(30deg)"}})}function R(i){return n(u,{...i,sx:{transform:"rotate(-30deg)"}})}function K({column:i,anchorEl:S,icons:p={},isLoading:s,onClose:c,onOpenFilter:z,onOpenManageColumns:b}){const{sortAsc:k=E,sortDesc:P=U,pinLeft:w=T,pinRight:x=R,unpin:O=V,filter:A=j,hideColumn:D=H,manageColumns:I=v}=p,o=i.getCanSort(),M=i.getIsSorted(),a=i.getCanPin(),h=i.getIsPinned(),d=i.getCanFilter(),y=i.getCanHide(),C=g=>{i.toggleSorting(g),c()},F=()=>{i.clearSorting(),c()},m=g=>{i.pin(g),c()};return e(L,{open:!0,anchorEl:S,onClose:c,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},children:[o&&e(l,{disabled:s,onClick:()=>C(!1),children:[n(r,{children:n(k,{fontSize:"small"})}),n(t,{children:"Sort by ASC"})]}),o&&e(l,{disabled:s,onClick:()=>C(!0),children:[n(r,{children:n(P,{fontSize:"small"})}),n(t,{children:"Sort by DESC"})]}),o&&M&&e(l,{disabled:s,onClick:F,children:[n(r,{}),n(t,{children:"Unsort"})]}),o&&a&&n(f,{}),a&&h!=="left"&&e(l,{onClick:()=>m("left"),children:[n(r,{children:n(w,{fontSize:"small"})}),n(t,{children:"Pin to left"})]}),a&&h!=="right"&&e(l,{onClick:()=>m("right"),children:[n(r,{children:n(x,{fontSize:"small"})}),n(t,{children:"Pin to right"})]}),a&&h!==!1&&e(l,{onClick:()=>m(!1),children:[n(r,{children:n(O,{fontSize:"small"})}),n(t,{children:"Unpin"})]}),(o||a)&&d&&n(f,{}),d&&e(l,{onClick:z,children:[n(r,{children:n(A,{fontSize:"small"})}),n(t,{children:"Filter"})]}),(o||a||d)&&n(f,{}),y&&e(l,{onClick:()=>{i.toggleVisibility(!1),c()},children:[n(r,{children:n(D,{fontSize:"small"})}),n(t,{children:"Hide column"})]}),e(l,{onClick:b,children:[n(r,{children:n(I,{fontSize:"small"})}),n(t,{children:"Manage columns"})]})]})}export{K as DataTableColumnMenu};
@@ -0,0 +1,16 @@
1
+ import { Table } from '@tanstack/react-table';
2
+ import { DataTableData, DataTableIcons } from './DataTable.types';
3
+ interface DataTableExportMenuProps<TData extends DataTableData> {
4
+ table: Table<TData>;
5
+ /** Base filename (no extension); also the printed document title. */
6
+ filename: string;
7
+ icons: DataTableIcons;
8
+ }
9
+ /**
10
+ * Toolbar Export button opening a menu with Print / Download as CSV /
11
+ * Download as Excel actions, like the MUI DataGrid toolbar. Every action
12
+ * exports the displayed table: the filtered + sorted rows across every
13
+ * page and the visible accessor columns in display order.
14
+ */
15
+ export declare function DataTableExportMenu<TData extends DataTableData>({ table, filename, icons, }: Readonly<DataTableExportMenuProps<TData>>): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";import{useState as f}from"react";import{Tooltip as T,IconButton as D,Menu as b,MenuItem as t,ListItemIcon as r,ListItemText as i}from"@mui/material";import{GridOnOutlined as C,FileDownloadOutlined as E,Print as w,DescriptionOutlined as S}from"@mui/icons-material";import{getDataTableExportModel as z,printDataTable as I,exportDataTableToCsv as k,exportDataTableToExcel as M}from"./DataTable.export.mjs";import{jsxs as e,Fragment as O,jsx as l}from"react/jsx-runtime";function g({table:c,filename:d,icons:m}){const{export:p=E,print:h=w,downloadCsv:u=S,downloadExcel:x=C}=m,[s,a]=f(null),n=o=>{o(z(c),d),a(null)};return e(O,{children:[l(T,{title:"Export",placement:"bottom",arrow:!0,children:l(D,{size:"small","aria-label":"Export",onClick:o=>a(o.currentTarget),children:l(p,{fontSize:"small"})})}),e(b,{anchorEl:s,open:!!s,onClose:()=>a(null),children:[e(t,{onClick:()=>n(I),children:[l(r,{children:l(h,{fontSize:"small"})}),l(i,{children:"Print"})]}),e(t,{onClick:()=>n(k),children:[l(r,{children:l(u,{fontSize:"small"})}),l(i,{children:"Download as CSV"})]}),e(t,{onClick:()=>n(M),children:[l(r,{children:l(x,{fontSize:"small"})}),l(i,{children:"Download as Excel"})]})]})]})}export{g as DataTableExportMenu};