@verifiedinc-public/shared-ui-elements 11.0.3-beta.0 → 11.1.0

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 +511 -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,511 @@
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
+ width?: number | string;
65
+ /**
66
+ * Options suggested by the filter panel's value input for this column.
67
+ * When omitted, suggestions are derived from the column's distinct
68
+ * values in `data` — with `manualFiltering`, `data` only holds the
69
+ * current page, so supply the full set here.
70
+ */
71
+ filterOptions?: string[];
72
+ }
73
+ /**
74
+ * Replacement component for one of the table's built-in MUI icons. Slots
75
+ * receive the same props as the icon they replace (`fontSize`, `sx`, ...) so
76
+ * MUI icons drop in directly; custom components are free to ignore them.
77
+ */
78
+ export type DataTableIconComponent = ComponentType<SvgIconProps>;
79
+ /**
80
+ * Custom icon mapping — each slot replaces the MUI icon the table renders
81
+ * there by default. Unset slots keep the MUI default.
82
+ */
83
+ export interface DataTableIcons {
84
+ /**
85
+ * Sort direction arrow on sortable headers. Defaults to the MUI
86
+ * TableSortLabel arrow.
87
+ */
88
+ sort?: DataTableIconComponent;
89
+ /** Column menu "Sort by ASC" item. Defaults to ArrowUpward. */
90
+ sortAsc?: DataTableIconComponent;
91
+ /** Column menu "Sort by DESC" item. Defaults to ArrowDownward. */
92
+ sortDesc?: DataTableIconComponent;
93
+ /** Column menu "Pin to left" item. Defaults to a left-tilted PushPin. */
94
+ pinLeft?: DataTableIconComponent;
95
+ /** Column menu "Pin to right" item. Defaults to a right-tilted PushPin. */
96
+ pinRight?: DataTableIconComponent;
97
+ /** Column menu "Unpin" item. Defaults to PushPinOutlined. */
98
+ unpin?: DataTableIconComponent;
99
+ /**
100
+ * Kebab button on header hover that opens the column menu. Defaults to
101
+ * MoreVert.
102
+ */
103
+ columnMenu?: DataTableIconComponent;
104
+ /**
105
+ * Column menu "Filter" item and the active-filter indicator on filtered
106
+ * headers. Defaults to FilterAlt.
107
+ */
108
+ filter?: DataTableIconComponent;
109
+ /** Toolbar "Filters" button. Defaults to FilterList. */
110
+ openFilterPanel?: DataTableIconComponent;
111
+ /**
112
+ * Toolbar "Manage columns" button and the column menu "Manage columns"
113
+ * item. Defaults to ViewColumn.
114
+ */
115
+ manageColumns?: DataTableIconComponent;
116
+ /** Toolbar "Export" button. Defaults to FileDownloadOutlined. */
117
+ export?: DataTableIconComponent;
118
+ /** Export menu "Print" item. Defaults to Print. */
119
+ print?: DataTableIconComponent;
120
+ /** Export menu "Download as CSV" item. Defaults to DescriptionOutlined. */
121
+ downloadCsv?: DataTableIconComponent;
122
+ /** Export menu "Download as Excel" item. Defaults to GridOnOutlined. */
123
+ downloadExcel?: DataTableIconComponent;
124
+ /** Column menu "Hide column" item. Defaults to VisibilityOff. */
125
+ hideColumn?: DataTableIconComponent;
126
+ /**
127
+ * Search adornments — the toolbar quick search and the manage columns
128
+ * panel input. Defaults to Search.
129
+ */
130
+ search?: DataTableIconComponent;
131
+ /**
132
+ * Clear buttons — clear search and remove a filter panel row. Defaults
133
+ * to Close.
134
+ */
135
+ close?: DataTableIconComponent;
136
+ /** Filter panel "Add filter" button. Defaults to Add. */
137
+ addFilter?: DataTableIconComponent;
138
+ /** Filter panel "Remove all" button. Defaults to DeleteOutline. */
139
+ removeAllFilters?: DataTableIconComponent;
140
+ /** Pagination first-page button. Defaults to FirstPage. */
141
+ paginationFirst?: DataTableIconComponent;
142
+ /** Pagination previous-page button. Defaults to KeyboardArrowLeft. */
143
+ paginationPrevious?: DataTableIconComponent;
144
+ /** Pagination next-page button. Defaults to KeyboardArrowRight. */
145
+ paginationNext?: DataTableIconComponent;
146
+ /** Pagination last-page button. Defaults to LastPage. */
147
+ paginationLast?: DataTableIconComponent;
148
+ }
149
+ /**
150
+ * Props for one body `<TableCell>` matching the default cells: the meta
151
+ * alignment plus, for pinned columns, the sticky offset and background
152
+ * styles (and the fixed-layout overflow clipping).
153
+ */
154
+ export interface DataTableCellProps {
155
+ align?: DataTableColumnMeta['align'];
156
+ style?: CSSProperties;
157
+ sx?: SxProps<Theme>;
158
+ }
159
+ /**
160
+ * Context handed to the custom row renderer. The default row markup is
161
+ * available through `renderDefaultRow` so custom renderers can decorate it
162
+ * (e.g. append an expandable detail row) instead of rebuilding it.
163
+ */
164
+ export interface DataTableRowContext<TData> {
165
+ /** TanStack row — `row.original` holds the raw data object. */
166
+ row: Row<TData>;
167
+ /** Virtual item for this row (index, measured size, offsets). */
168
+ virtualRow: VirtualItem;
169
+ /**
170
+ * Spread onto the first `<TableRow>` of a custom row so the virtualizer
171
+ * can measure its rendered height. Sibling rows rendered after it (e.g.
172
+ * a divider row or an expandable detail row) are measured and observed
173
+ * as part of the same row group — expanding a Collapse panel resizes
174
+ * the virtual row instead of snapping the scroll.
175
+ */
176
+ rowProps: {
177
+ 'data-index': number;
178
+ ref: Ref<HTMLTableRowElement>;
179
+ };
180
+ /**
181
+ * Spread onto each `<TableCell>` of a custom row (built from
182
+ * `row.getVisibleCells()`) to match the default cells — column meta
183
+ * alignment plus, with `enableColumnPinning`, the sticky styles that
184
+ * keep pinned cells in place while the table scrolls horizontally.
185
+ */
186
+ getCellProps: (cell: Cell<TData, unknown>) => DataTableCellProps;
187
+ /** Renders the default `<TableRow>` for this row. */
188
+ renderDefaultRow: () => ReactNode;
189
+ }
190
+ /**
191
+ * Configuration for bidirectional infinite scroll (see
192
+ * `DataTableProps.bidirectionalScroll`). The flags describe a paged,
193
+ * reverse-chronological feed: "newer" pages sit above the loaded window,
194
+ * "older" pages below it.
195
+ */
196
+ export interface DataTableBidirectionalScroll {
197
+ /** Whether more rows exist above the loaded window. */
198
+ hasNewer?: boolean;
199
+ /** Whether more rows exist below the loaded window. */
200
+ hasOlder?: boolean;
201
+ /**
202
+ * Whether a newer-page fetch is in flight — shows the sticky indicator
203
+ * below the header and holds the scroll position when the rows land.
204
+ */
205
+ isLoadingNewer?: boolean;
206
+ /**
207
+ * Whether an older-page fetch is in flight — shows the sticky indicator
208
+ * at the bottom edge.
209
+ */
210
+ isLoadingOlder?: boolean;
211
+ /**
212
+ * Called when the user scrolls to the top edge — fetch the next newer
213
+ * page and prepend its rows to `data`.
214
+ */
215
+ onLoadNewer: () => void;
216
+ /**
217
+ * Called when the user scrolls to the bottom edge — fetch the next older
218
+ * page and append its rows to `data`.
219
+ */
220
+ onLoadOlder: () => void;
221
+ /**
222
+ * When this value changes, the scroll position resets to the top and the
223
+ * edge triggers re-arm. Derive it from the active filters (e.g. a
224
+ * serialised filter string) so a filter change starts a fresh feed.
225
+ */
226
+ resetKey?: string | number;
227
+ /** Label inside the top indicator. Defaults to 'Loading newer rows'. */
228
+ loadingNewerLabel?: string;
229
+ /** Label inside the bottom indicator. Defaults to 'Loading older rows'. */
230
+ loadingOlderLabel?: string;
231
+ }
232
+ export interface DataTableProps<TData extends DataTableData> {
233
+ data: TData[];
234
+ /**
235
+ * TanStack column definitions. When omitted, columns are inferred from
236
+ * the keys of the first data row with sensible header/cell defaults
237
+ * (inferred columns are all sortable).
238
+ *
239
+ * Sorting is opt-in: declare sortable columns with
240
+ * `enableSorting: true` on their defs — columns are plain labels
241
+ * otherwise.
242
+ *
243
+ * Supports TanStack group defs (`{ header: 'Group', columns: [...] }`)
244
+ * for a grouped header: group labels render centered above their
245
+ * sub-columns while ungrouped columns span all header rows.
246
+ */
247
+ columns?: Array<ColumnDef<TData, unknown>>;
248
+ /** Stable row identity; falls back to the row index. */
249
+ getRowId?: (row: TData, index: number) => string;
250
+ /**
251
+ * Custom row renderer; falls back to the default row markup. Custom rows
252
+ * build their own cells, so column visibility (Hide column / Manage
253
+ * columns) only affects them when they render from
254
+ * `row.getVisibleCells()` instead of hardcoding cells. Spread
255
+ * `getCellProps(cell)` onto each cell to keep the default alignment and
256
+ * pinned-column stickiness.
257
+ */
258
+ renderRow?: (context: DataTableRowContext<TData>) => ReactNode;
259
+ /** Initial sorting state, e.g. `[{ id: 'email', desc: false }]`. */
260
+ initialSorting?: SortingState;
261
+ /**
262
+ * Controlled sorting state (pair with `onSortingChange`). Takes
263
+ * precedence over `initialSorting`. When omitted, sorting state is
264
+ * internal.
265
+ */
266
+ sorting?: SortingState;
267
+ /**
268
+ * Called with the next sorting state when a header is clicked. With
269
+ * `manualSorting`, fetch the re-sorted rows from the server in response
270
+ * (and usually reset the page to 0).
271
+ */
272
+ onSortingChange?: (sorting: SortingState) => void;
273
+ /**
274
+ * Server-side sorting: rows in `data` are assumed to already be sorted —
275
+ * header clicks only update the sorting state, nothing is sorted
276
+ * client-side.
277
+ */
278
+ manualSorting?: boolean;
279
+ /** Rows per page when the table mounts. Defaults to 25. */
280
+ initialPageSize?: number;
281
+ /** Options for the rows-per-page select. Defaults to [10, 25, 50, 100]. */
282
+ pageSizeOptions?: number[];
283
+ /**
284
+ * Controlled pagination state (pair with `onPaginationChange`). Use when
285
+ * the consumer needs to drive the page externally — e.g. reset to the
286
+ * first page when filters change. Takes precedence over
287
+ * `initialPageSize`. When omitted, pagination state is internal.
288
+ */
289
+ pagination?: PaginationState;
290
+ /**
291
+ * Called with the next pagination state whenever the page or page size
292
+ * changes. With `manualPagination`, fetch the new page from the server
293
+ * in response (e.g. by keying a React Query on this state).
294
+ */
295
+ onPaginationChange?: (pagination: PaginationState) => void;
296
+ /**
297
+ * Server-side pagination: rows in `data` are treated as the current
298
+ * page (no client-side slicing) and `rowCount` drives the pager.
299
+ */
300
+ manualPagination?: boolean;
301
+ /**
302
+ * Total row count on the server. Required with `manualPagination` so
303
+ * the pager knows how many pages exist.
304
+ */
305
+ rowCount?: number;
306
+ /**
307
+ * Disables sorting for the whole table — headers render as plain labels
308
+ * and rows keep the order of `data`, even for columns declaring
309
+ * `enableSorting: true`.
310
+ */
311
+ disableSorting?: boolean;
312
+ /** Hides the pagination footer and renders all rows (still virtualized). */
313
+ disablePagination?: boolean;
314
+ /**
315
+ * Bidirectional infinite scroll for streaming feeds (e.g. logs):
316
+ * scrolling to the bottom edge calls `onLoadOlder`, scrolling back to
317
+ * the top edge calls `onLoadNewer`, and sticky in-flight indicators pin
318
+ * to the edges while a page loads. The scroll position is preserved when
319
+ * newer rows are prepended, so the viewport doesn't jump.
320
+ *
321
+ * The consumer owns the pages: merge the fetched rows into `data` and
322
+ * flip the `has*` / `isLoading*` flags (e.g. from a React Query infinite
323
+ * query). Pair with `disablePagination` (the scroll edges replace the
324
+ * pager) and `getRowId` (prepended rows shift the indexes, which are the
325
+ * default row identity); rows are assumed to arrive in feed order, so
326
+ * sorting is usually disabled or manual.
327
+ */
328
+ bidirectionalScroll?: DataTableBidirectionalScroll;
329
+ /**
330
+ * Adds drag handles (vertical separator lines) on the header cell edges
331
+ * to resize columns; double-clicking a handle restores the column's
332
+ * pre-drag width. Drags start from the column's rendered width, and the
333
+ * other columns are frozen at theirs — resizing changes the table width
334
+ * (adding horizontal scroll as needed) instead of reflowing the
335
+ * neighboring columns. Per-column opt-out via `enableResizing: false`
336
+ * on the def. Widths are enforced exactly with `tableLayout: 'fixed'`;
337
+ * with the default 'auto', content can keep a column from shrinking
338
+ * below its natural width.
339
+ */
340
+ enableColumnResizing?: boolean;
341
+ /**
342
+ * Shows a kebab menu on each column header (revealed on hover, like the
343
+ * MUI DataGrid) with per-column actions: Sort by ASC/DESC for sortable
344
+ * columns, Pin to left / Pin to right / Unpin with
345
+ * `enableColumnPinning`, Filter for filterable columns, and Hide column
346
+ * / Manage columns for column visibility.
347
+ *
348
+ * Every accessor column is filterable through the operator-based filter
349
+ * panel by default — opt a column out with `enableColumnFilter: false`
350
+ * on its def.
351
+ */
352
+ enableColumnMenu?: boolean;
353
+ /**
354
+ * Adds Pin to left / Pin to right / Unpin actions to the column menu.
355
+ * Pinned columns reorder to that edge and stay sticky while the table
356
+ * scrolls horizontally; their offsets are measured from the rendered
357
+ * header cells, so they hold under both table layouts. Per-column
358
+ * opt-out via `enablePinning: false` on the def. Custom `renderRow`
359
+ * rows build their own cells — spread `getCellProps(cell)` onto them
360
+ * to get the sticky styles.
361
+ *
362
+ * The table only scrolls horizontally once it is wider than its
363
+ * container — pair with a `minWidth` beyond the container width (or
364
+ * exact column widths on every column with `tableLayout: 'fixed'`),
365
+ * otherwise there is nothing for pinned columns to stick over.
366
+ */
367
+ enableColumnPinning?: boolean;
368
+ /**
369
+ * Shows a toolbar row above the table with Manage columns and Filters
370
+ * buttons plus a search button that expands into a quick-search input on
371
+ * the right, like the MUI DataGrid toolbar. The filter button carries a
372
+ * badge with the active filter count. While the toolbar is shown, the
373
+ * filter / manage columns panels open anchored to their toolbar button —
374
+ * including when triggered from a column menu — instead of at the column
375
+ * that opened them.
376
+ */
377
+ showToolbar?: boolean;
378
+ /**
379
+ * Adds an Export button to the toolbar (requires `showToolbar`) with
380
+ * Print, Download as CSV and Download as Excel actions. Exports always
381
+ * reflect the displayed table: the filtered + sorted rows across every
382
+ * page and the visible accessor columns in display order (display-only
383
+ * columns are skipped). With grouped columns the export starts with a
384
+ * group header row, like the rendered header. With `manualPagination`
385
+ * only the loaded page is exported.
386
+ */
387
+ enableExport?: boolean;
388
+ /**
389
+ * Base filename (no extension) for the exported files; also the printed
390
+ * document title. Defaults to 'data'.
391
+ */
392
+ exportFilename?: string;
393
+ /**
394
+ * Initial filter state. Rows are applied as AND by default; switch to OR
395
+ * via `logicOperator: 'or'`.
396
+ *
397
+ * @example
398
+ * initialFilters={{ rows: [{ id: 'f1', columnId: 'role', operator: 'equals', value: 'admin' }], logicOperator: 'and' }}
399
+ */
400
+ initialFilters?: DataTableActiveFilters;
401
+ /**
402
+ * Controlled filter state (pair with `onFiltersChange`). Takes
403
+ * precedence over `initialFilters`. When omitted, filter state is
404
+ * internal.
405
+ */
406
+ filters?: DataTableActiveFilters;
407
+ /**
408
+ * Called with the next filter state when the filter panel changes. With
409
+ * `manualFiltering`, fetch the matching rows from the server in response
410
+ * (and usually reset the page to 0).
411
+ */
412
+ onFiltersChange?: (filters: DataTableActiveFilters) => void;
413
+ /**
414
+ * Server-side filtering: rows in `data` are assumed to already match the
415
+ * active filters and search query — the filter panel and the toolbar
416
+ * search input only update their state, nothing is filtered client-side.
417
+ */
418
+ manualFiltering?: boolean;
419
+ /** Initial quick-search query for the toolbar search input. */
420
+ initialSearch?: string;
421
+ /**
422
+ * Controlled quick-search query (pair with `onSearchChange`). Takes
423
+ * precedence over `initialSearch`. When omitted, search state is
424
+ * internal.
425
+ */
426
+ search?: string;
427
+ /**
428
+ * Called with the next query as the user types in the toolbar search
429
+ * input. With `manualFiltering`, fetch the matching rows from the server
430
+ * in response (and usually reset the page to 0).
431
+ */
432
+ onSearchChange?: (search: string) => void;
433
+ /**
434
+ * Initial column visibility, keyed by column id — `{ role: false }`
435
+ * mounts the table with the role column hidden. Also what the manage
436
+ * columns panel's Reset restores. Per-column opt-out from hiding via
437
+ * `enableHiding: false` on the def.
438
+ */
439
+ initialColumnVisibility?: VisibilityState;
440
+ /**
441
+ * Controlled column visibility state (pair with
442
+ * `onColumnVisibilityChange`) — e.g. to persist hidden columns per user.
443
+ * Takes precedence over `initialColumnVisibility`. When omitted,
444
+ * visibility state is internal.
445
+ */
446
+ columnVisibility?: VisibilityState;
447
+ /**
448
+ * Called with the next visibility state whenever a column is hidden or
449
+ * shown (column menu, manage columns panel).
450
+ */
451
+ onColumnVisibilityChange?: (columnVisibility: VisibilityState) => void;
452
+ /**
453
+ * Initial pinned columns, e.g. `{ left: ['email'], right: [] }` —
454
+ * requires `enableColumnPinning`.
455
+ */
456
+ initialColumnPinning?: ColumnPinningState;
457
+ /**
458
+ * Controlled pinning state (pair with `onColumnPinningChange`) — e.g.
459
+ * to persist pinned columns per user. Takes precedence over
460
+ * `initialColumnPinning`. When omitted, pinning state is internal.
461
+ */
462
+ columnPinning?: ColumnPinningState;
463
+ /**
464
+ * Called with the next pinning state whenever a column is pinned or
465
+ * unpinned from the column menu.
466
+ */
467
+ onColumnPinningChange?: (columnPinning: ColumnPinningState) => void;
468
+ /**
469
+ * Content rendered on the left side of the footer, opposite the
470
+ * pagination controls (e.g. a summary, bulk actions or an export button).
471
+ * Rendered even when pagination is disabled.
472
+ */
473
+ footerLeft?: ReactNode;
474
+ /** Estimated row height in px used by the virtualizer. Defaults to 53. */
475
+ estimateRowHeight?: number;
476
+ /**
477
+ * Min width of the table itself (any CSS width value). When it exceeds
478
+ * the container width, the table scrolls horizontally — which is what
479
+ * gives pinned columns something to stick over. Defaults to 650.
480
+ */
481
+ minWidth?: number | string;
482
+ /** Max height of the scroll container. Defaults to 800. */
483
+ maxHeight?: number | string;
484
+ /**
485
+ * Table layout algorithm. With the default 'auto', column widths are
486
+ * hints and content can stretch a column. Use 'fixed' to enforce the
487
+ * exact px/percentage widths set via column meta — content that cannot
488
+ * fit (e.g. long unbreakable strings) is clipped with an ellipsis
489
+ * instead of leaking over the neighboring cells.
490
+ */
491
+ tableLayout?: 'auto' | 'fixed';
492
+ /**
493
+ * Custom icon mapping — replaces the MUI icons the table renders by
494
+ * default (toolbar buttons, column menu items, filter panel actions,
495
+ * pagination arrows). Unset slots keep the MUI default.
496
+ *
497
+ * @example
498
+ * icons={{ search: MagnifyingGlass, columnMenu: DotsThree }}
499
+ */
500
+ icons?: DataTableIcons;
501
+ /** Message displayed when `data` is empty. */
502
+ emptyMessage?: string;
503
+ isLoading?: boolean;
504
+ /**
505
+ * Custom loading state renderer, shown while `isLoading` is true and
506
+ * there are no rows. Rendered inside the table body, so it must return
507
+ * one or more `<TableRow>`s (e.g. skeleton rows). Receives the column
508
+ * count for `colSpan`. Falls back to a default loading row.
509
+ */
510
+ renderLoading?: (columnCount: number) => ReactNode;
511
+ }
@@ -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};
@@ -0,0 +1,36 @@
1
+ import { Table } from '@tanstack/react-table';
2
+ import { DataTableActiveFilters, DataTableData, DataTableIcons } from './DataTable.types';
3
+ interface DataTableFilterPanelProps<TData extends DataTableData> {
4
+ table: Table<TData>;
5
+ /**
6
+ * Unfiltered rows — the value input derives its suggestions from each
7
+ * column's distinct values here. (With manualFiltering this is just the
8
+ * current page; `meta.filterOptions` supplies the full set instead.)
9
+ */
10
+ data?: TData[];
11
+ /** Column preselected when opening from a column menu with no active filters. */
12
+ initialColumnId: string;
13
+ anchorPosition: {
14
+ top: number;
15
+ left: number;
16
+ };
17
+ /**
18
+ * Which top corner of the panel pins to `anchorPosition` — 'right' when
19
+ * opening from the table toolbar so the panel grows leftward over the
20
+ * table. Defaults to 'left'.
21
+ */
22
+ transformHorizontal?: 'left' | 'right';
23
+ /** Custom icon slots for the panel actions; unset slots keep the MUI default. */
24
+ icons?: DataTableIcons;
25
+ /** Current filter state — the panel syncs from this on mount. */
26
+ filters: DataTableActiveFilters;
27
+ onFiltersChange: (filters: DataTableActiveFilters) => void;
28
+ onClose: () => void;
29
+ }
30
+ /**
31
+ * Multi-row filter panel — each row targets a Column / Operator / Value
32
+ * triplet; rows combine with AND or OR (switched from the connector
33
+ * dropdown on rows 2+). Matches the MUI DataGrid Premium filter panel.
34
+ */
35
+ export declare function DataTableFilterPanel<TData extends DataTableData>({ table, data, initialColumnId, anchorPosition, transformHorizontal, icons, filters, onFiltersChange, onClose, }: Readonly<DataTableFilterPanelProps<TData>>): import("react").JSX.Element;
36
+ export {};