@mantine-vue/table 3.0.0 → 3.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.
@@ -0,0 +1,494 @@
1
+ import { type Component, type VNodeChild } from 'vue';
2
+ import type { HTMLPropsRef, MVT_Column, MVT_ColumnFiltersState, MVT_Node, MVT_PaginationState, MVT_RowData, MVT_SortingState, MVT_TableInstance } from '../types';
3
+ import type { TableTrProps } from '../mantine.types';
4
+ /**
5
+ * Stable identifier of a location inside the server-grouping hierarchy.
6
+ *
7
+ * - `'__root__'` — the root level (first group-by field, or the flat record
8
+ * list when `grouping` is empty).
9
+ * - `'country:BH'` — content under the root group `BH` of field `country`.
10
+ * - `'country:BH/salesperson:42'` — content nested one level deeper.
11
+ *
12
+ * Path ids are never derived from row indexes, so they stay stable across
13
+ * pagination, sorting, and reloads. Segment values are escaped, so group ids
14
+ * may safely contain `/` or `:`.
15
+ */
16
+ export type MVT_ServerGroupPathId = string;
17
+ export declare const MVT_SERVER_GROUPING_ROOT_PATH_ID: "__root__";
18
+ /**
19
+ * Normalized group node. This is the internal contract between a
20
+ * {@link MVT_ServerGroupingProvider} and the table — the original backend
21
+ * response shape is preserved in `original` and never dictated.
22
+ */
23
+ export interface MVT_ServerGroupNode<TGroup = unknown> {
24
+ id: string;
25
+ label: string;
26
+ value?: unknown;
27
+ count?: number;
28
+ original: TGroup;
29
+ meta?: Record<string, unknown>;
30
+ hasChildren?: boolean;
31
+ }
32
+ /** Normalized page of group nodes. */
33
+ export interface MVT_ServerGroupPage<TGroup = unknown> {
34
+ groups: MVT_ServerGroupNode<TGroup>[];
35
+ rowCount: number;
36
+ }
37
+ /** Normalized page of final records. */
38
+ export interface MVT_ServerRecordPage<TData> {
39
+ rows: TData[];
40
+ rowCount: number;
41
+ }
42
+ /**
43
+ * One resolved ancestor group on the path to the level being loaded. Preserves
44
+ * both the normalized node data and the `original` backend group object so a
45
+ * provider can construct any follow-up request (scope/domain/cursor/…).
46
+ */
47
+ export interface MVT_ServerGroupPathItem<TGroup = unknown> {
48
+ id: string;
49
+ field: string;
50
+ depth: number;
51
+ label: string;
52
+ value?: unknown;
53
+ original: TGroup;
54
+ meta?: Record<string, unknown>;
55
+ }
56
+ /**
57
+ * Pagination state for one group path. Extends the standard offset model with
58
+ * an opaque `cursor` slot for cursor-based backends — the provider decides
59
+ * whether `pageIndex * pageSize` or `cursor` drives the actual request.
60
+ */
61
+ export interface MVT_ServerPageState extends MVT_PaginationState {
62
+ cursor?: unknown;
63
+ }
64
+ export type MVT_ServerGroupingSortingMode = 'independent' | 'records-only' | 'shared';
65
+ export type MVT_ServerGroupingFilteringMode = 'independent' | 'records-only' | 'shared';
66
+ /** Common request context shared by group and record requests. */
67
+ export interface MVT_ServerGroupingBaseRequest<TGroup = unknown> {
68
+ /** All active group-by field identifiers (opaque strings, e.g. `'createdAt:month'`). */
69
+ grouping: string[];
70
+ /** Zero-based depth of the level being loaded. */
71
+ depth: number;
72
+ /** Stable path id of the level being loaded. */
73
+ pathId: MVT_ServerGroupPathId;
74
+ /** Every resolved ancestor group, outermost first. */
75
+ parentGroups: MVT_ServerGroupPathItem<TGroup>[];
76
+ /** The direct parent group (`parentGroups.at(-1)`), if any. */
77
+ parentGroup?: MVT_ServerGroupPathItem<TGroup>;
78
+ pagination: MVT_ServerPageState;
79
+ sorting: MVT_SortingState;
80
+ columnFilters: MVT_ColumnFiltersState;
81
+ globalFilter: unknown;
82
+ /** Aborted when the request becomes obsolete. Forward it to your HTTP client. */
83
+ signal: AbortSignal;
84
+ table: MVT_TableInstance<any>;
85
+ }
86
+ /** Request context for loading one page of child groups. */
87
+ export interface MVT_ServerGroupRequest<TGroup = unknown> extends MVT_ServerGroupingBaseRequest<TGroup> {
88
+ /** The group-by field identifier for the level being loaded (`grouping[depth]`). */
89
+ groupingField: string;
90
+ }
91
+ /** Request context for loading one page of final records. */
92
+ export type MVT_ServerRecordRequest<TGroup = unknown> = MVT_ServerGroupingBaseRequest<TGroup>;
93
+ /** Context given to the per-group adapter functions of a provider. */
94
+ export interface MVT_ServerGroupingContext<TGroup = unknown> {
95
+ field: string;
96
+ depth: number;
97
+ request: MVT_ServerGroupRequest<TGroup>;
98
+ }
99
+ /**
100
+ * A server-grouping provider loads and normalizes groups and records. It is
101
+ * the only integration point with your backend — REST, GraphQL, RPC,
102
+ * Elasticsearch aggregations, cursor APIs, … anything works, as
103
+ * long as the adapter functions can map the response into the normalized
104
+ * internal model. Use {@link createServerGroupingProvider} for less boilerplate.
105
+ */
106
+ export interface MVT_ServerGroupingProvider<TData extends MVT_RowData = MVT_RowData, TGroup = unknown, TGroupResponse = unknown, TRecordResponse = unknown> {
107
+ /** Stable id of a group within its own level (never a row index). */
108
+ getGroupId: (group: TGroup, context: MVT_ServerGroupingContext<TGroup>) => string;
109
+ getGroupLabel: (group: TGroup, context: MVT_ServerGroupingContext<TGroup>) => string;
110
+ /** Raw group value. Defaults to the group object itself. */
111
+ getGroupValue?: (group: TGroup, context: MVT_ServerGroupingContext<TGroup>) => unknown;
112
+ /** Optional record count shown next to the label. */
113
+ getGroupCount?: (group: TGroup, context: MVT_ServerGroupingContext<TGroup>) => number | undefined;
114
+ /** Optional metadata (aggregates, scopes, cursors, …). Defaults to `{}`. */
115
+ getGroupMeta?: (group: TGroup, context: MVT_ServerGroupingContext<TGroup>) => Record<string, unknown>;
116
+ /** Whether the group can be expanded. Defaults to `true`. */
117
+ hasGroupChildren?: (group: TGroup, context: MVT_ServerGroupingContext<TGroup>) => boolean;
118
+ loadGroups: (request: MVT_ServerGroupRequest<TGroup>) => Promise<TGroupResponse>;
119
+ getGroups: (response: TGroupResponse) => TGroup[];
120
+ getGroupRowCount: (response: TGroupResponse) => number;
121
+ loadRecords: (request: MVT_ServerRecordRequest<TGroup>) => Promise<TRecordResponse>;
122
+ getRecords: (response: TRecordResponse) => TData[];
123
+ getRecordRowCount: (response: TRecordResponse) => number;
124
+ /** Stable record row id. Falls back to the table's `getRowId`, then to a path-scoped index. */
125
+ getRowId?: (row: TData) => string;
126
+ /**
127
+ * Customize the cache key for a request. The returned parts are appended to
128
+ * the built-in key (path id, grouping, depth, pagination, sorting, filters).
129
+ */
130
+ getCacheKey?: (request: MVT_ServerGroupRequest<TGroup> | MVT_ServerRecordRequest<TGroup>) => unknown[];
131
+ }
132
+ /** Per-path request lifecycle state. */
133
+ export interface MVT_ServerGroupingRequestState {
134
+ isLoading: boolean;
135
+ isFetching: boolean;
136
+ error: unknown;
137
+ updatedAt?: number;
138
+ }
139
+ /** Loaded content + query state of one group path. */
140
+ export interface MVT_ServerGroupingPathState<TData extends MVT_RowData = MVT_RowData, TGroup = unknown> extends MVT_ServerGroupingRequestState {
141
+ pathId: MVT_ServerGroupPathId;
142
+ depth: number;
143
+ /** `'groups'` for intermediate levels, `'records'` for the final level. */
144
+ kind: 'groups' | 'records';
145
+ pagination: MVT_ServerPageState;
146
+ /** Per-path sorting override (see `sortingMode`). */
147
+ sorting?: MVT_SortingState;
148
+ /** Per-path column filters override (see `filteringMode`). */
149
+ columnFilters?: MVT_ColumnFiltersState;
150
+ /** Per-path global filter override (see `filteringMode`). */
151
+ globalFilter?: unknown;
152
+ rowCount: number;
153
+ groups?: MVT_ServerGroupNode<TGroup>[];
154
+ rows?: TData[];
155
+ }
156
+ export type MVT_ServerGroupingExpandedState = Record<MVT_ServerGroupPathId, boolean>;
157
+ /** Aggregated server-grouping state, returned by `table.getServerGroupingState()`. */
158
+ export interface MVT_ServerGroupingState<TData extends MVT_RowData = MVT_RowData, TGroup = unknown> {
159
+ enabled: boolean;
160
+ grouping: string[];
161
+ expanded: MVT_ServerGroupingExpandedState;
162
+ paths: Record<MVT_ServerGroupPathId, MVT_ServerGroupingPathState<TData, TGroup>>;
163
+ }
164
+ export interface MVT_ServerGroupingCacheOptions {
165
+ enabled?: boolean;
166
+ /** Milliseconds a cached page is served without refetching. @default 0 */
167
+ staleTime?: number;
168
+ /** Milliseconds before an unused cached page is garbage collected. @default 300_000 */
169
+ gcTime?: number;
170
+ /** Keep loaded content of collapsed groups. @default true */
171
+ keepCollapsedGroups?: boolean;
172
+ }
173
+ export interface MVT_ServerGroupingPaginationOptions {
174
+ enabled?: boolean;
175
+ /**
176
+ * Fixed page size applied to every group and record level. Nested levels
177
+ * cannot change their page size at runtime — nested pagination bars show
178
+ * only page navigation and row-count info.
179
+ *
180
+ * @default 10 (or `serverGrouping.initialPageSize`)
181
+ */
182
+ defaultPageSize?: number;
183
+ /**
184
+ * Render an inline pagination row for the root level inside the table body.
185
+ * Defaults to `false` because the root level is paginated by the regular
186
+ * bottom toolbar (`positionPagination`, `mantinePaginationProps`), exactly
187
+ * like an ungrouped server-side table; it defaults to `true` when the
188
+ * toolbar pagination is turned off.
189
+ */
190
+ showAtRoot?: boolean;
191
+ /** @default true */
192
+ showForGroups?: boolean;
193
+ /** @default true */
194
+ showForRecords?: boolean;
195
+ /** Extra Mantine props for the nested prev/next `ActionIcon`s (merged safely). */
196
+ mantineActionIconProps?: Record<string, any>;
197
+ }
198
+ /** Request context of `selection.loadAllMatchingRowIds`. */
199
+ export interface MVT_ServerGroupingSelectAllRequest {
200
+ grouping: string[];
201
+ sorting: MVT_SortingState;
202
+ columnFilters: MVT_ColumnFiltersState;
203
+ globalFilter: unknown;
204
+ table: MVT_TableInstance<any>;
205
+ }
206
+ /**
207
+ * "Select all matching records" state.
208
+ *
209
+ * Selecting a filtered dataset of millions of rows must never materialize row
210
+ * ids. Instead the selection flips to *exclude mode*: it means "everything
211
+ * matching the current query", and only the rows the user explicitly unchecks
212
+ * afterwards are tracked. Bulk actions then send the query + exclusions.
213
+ */
214
+ export interface MVT_ServerGroupingSelectAllState {
215
+ /** Whether "all matching records" is active (exclude mode). */
216
+ active: boolean;
217
+ /** Row ids explicitly deselected while exclude mode is active. */
218
+ excludedRowIds: string[];
219
+ }
220
+ /**
221
+ * What a bulk action should send to the server.
222
+ *
223
+ * - `'include'`: act on `rowIds` (the classic, explicit selection).
224
+ * - `'exclude'`: act on every record matching `grouping`/`sorting`/filters,
225
+ * except `excludedRowIds`. No id list is ever transferred.
226
+ */
227
+ export interface MVT_ServerGroupingSelectionPayload {
228
+ mode: 'exclude' | 'include';
229
+ rowIds: string[];
230
+ excludedRowIds: string[];
231
+ grouping: string[];
232
+ sorting: MVT_SortingState;
233
+ columnFilters: MVT_ColumnFiltersState;
234
+ globalFilter: unknown;
235
+ }
236
+ /** Header-checkbox / selection state of a server-grouped table. */
237
+ export interface MVT_ServerGroupingSelectionSummary {
238
+ /** Every selectable loaded record inside expanded groups is selected. */
239
+ isAll: boolean;
240
+ /** Some — but not all — are selected (indeterminate header checkbox). */
241
+ isSome: boolean;
242
+ /** How many loaded records are currently selectable. */
243
+ selectableCount: number;
244
+ /** How many of those are selected. */
245
+ selectedCount: number;
246
+ /** Explicitly selected row ids (empty in exclude mode). */
247
+ selectedRowIds: string[];
248
+ /** `'exclude'` while "all matching records" is active. */
249
+ mode: 'exclude' | 'include';
250
+ /** Convenience flag: `mode === 'exclude'`. */
251
+ isSelectAllMatching: boolean;
252
+ /** Rows unchecked after "select all matching records". */
253
+ excludedRowIds: string[];
254
+ }
255
+ export interface MVT_ServerGroupingSelectionOptions {
256
+ /**
257
+ * Deselect a group's records when it is collapsed.
258
+ *
259
+ * Defaults to `false`: collapsing is a view operation, so selections survive
260
+ * it (the toolbar alert keeps counting them, and unchecking the header
261
+ * checkbox clears everything). Set to `true` for a strictly
262
+ * "what you see is what is selected" behavior.
263
+ *
264
+ * @default false
265
+ */
266
+ clearOnCollapse?: boolean;
267
+ /**
268
+ * Show a built-in "select all matching records" action in the toolbar alert
269
+ * banner once every loaded record is selected.
270
+ */
271
+ enableSelectAllMatching?: boolean;
272
+ /**
273
+ * How "select all matching records" represents the selection.
274
+ *
275
+ * - `'query'` (default, recommended): flips to exclude mode — no request, no
276
+ * ids transferred, works with millions of rows. Send
277
+ * `table.getServerGroupingSelectionPayload()` to your bulk endpoint.
278
+ * - `'ids'`: materializes every matching row id through
279
+ * {@link MVT_ServerGroupingSelectionOptions.loadAllMatchingRowIds}. Only
280
+ * suitable for small, bounded datasets.
281
+ *
282
+ * @default 'query'
283
+ */
284
+ selectAllMode?: 'ids' | 'query';
285
+ /**
286
+ * Resolve every row id matching the current filters. Only used (and
287
+ * required) when `selectAllMode: 'ids'`.
288
+ */
289
+ loadAllMatchingRowIds?: (request: MVT_ServerGroupingSelectAllRequest) => Promise<string[]>;
290
+ }
291
+ /** A column offered by the built-in group-by toolbar control. */
292
+ export interface MVT_ServerGroupableColumn {
293
+ /** Grouping field id sent to the provider. */
294
+ id: string;
295
+ /** Display label (column header, or the raw id for custom descriptors). */
296
+ label: string;
297
+ }
298
+ /** Scoped argument of the group-by control slot / render callback. */
299
+ export interface MVT_ServerGroupingGroupByContext {
300
+ /** Active grouping fields, outermost first. */
301
+ grouping: string[];
302
+ /** Columns/fields the user may group by. */
303
+ groupableColumns: MVT_ServerGroupableColumn[];
304
+ addGroup: (field: string) => void;
305
+ removeGroup: (field: string) => void;
306
+ /** Move an active level up (`-1`) or down (`1`). */
307
+ moveGroup: (field: string, direction: -1 | 1) => void;
308
+ clearGrouping: () => void;
309
+ table: MVT_TableInstance<any>;
310
+ }
311
+ /**
312
+ * Built-in group-by toolbar control. Rendered in the top toolbar whenever
313
+ * server grouping is active and grouping is driven by the table's `grouping`
314
+ * state (with a static `serverGrouping.grouping` array the control is hidden
315
+ * unless `enabled: true` is forced, since it could not change anything).
316
+ */
317
+ export interface MVT_ServerGroupingGroupByOptions {
318
+ /** @default true */
319
+ enabled?: boolean;
320
+ /** Show the per-level reorder arrows. @default true */
321
+ allowReorder?: boolean;
322
+ /**
323
+ * Also offer "Group by" / "Ungroup by" / "Clear grouping" in each groupable
324
+ * column's action menu.
325
+ *
326
+ * @default true
327
+ */
328
+ showInColumnActions?: boolean;
329
+ /** Show the "clear grouping" action. @default true */
330
+ allowClearAll?: boolean;
331
+ /**
332
+ * Explicit whitelist of groupable field ids (may include custom descriptors
333
+ * like `'createdAt:month'`). When omitted, every `data` column whose
334
+ * `enableGrouping` is not `false` is offered.
335
+ */
336
+ columns?: string[];
337
+ /** Resolve the display label of a field. Defaults to the column header, or the raw id. */
338
+ getFieldLabel?: (field: string, table: MVT_TableInstance<any>) => string;
339
+ /**
340
+ * Replace the entire default control. A `#serverGroupByControl` slot takes
341
+ * precedence over this callback; both receive the same context.
342
+ */
343
+ renderControl?: (context: MVT_ServerGroupingGroupByContext) => MVT_Node;
344
+ /** Extra Mantine props for the "Group by" `Button` (merged safely). */
345
+ mantineButtonProps?: Record<string, any>;
346
+ /** Extra Mantine props for the `Menu` (merged safely). */
347
+ mantineMenuProps?: Record<string, any>;
348
+ /** Extra Mantine props for each active-level `Pill` (merged safely). */
349
+ mantinePillProps?: ((context: {
350
+ field: string;
351
+ index: number;
352
+ }) => Record<string, any>) | Record<string, any>;
353
+ }
354
+ /** Scoped argument of group-row render callbacks and slots. */
355
+ export interface MVT_ServerGroupRowContext<TGroup = unknown> {
356
+ group: MVT_ServerGroupNode<TGroup>;
357
+ field: string;
358
+ depth: number;
359
+ pathId: MVT_ServerGroupPathId;
360
+ parentGroups: MVT_ServerGroupPathItem<TGroup>[];
361
+ isExpanded: boolean;
362
+ table: MVT_TableInstance<any>;
363
+ }
364
+ /** Scoped argument of per-column aggregate cell rendering. */
365
+ export interface MVT_ServerGroupCellContext<TGroup = unknown> extends MVT_ServerGroupRowContext<TGroup> {
366
+ column: MVT_Column<any>;
367
+ value: unknown;
368
+ }
369
+ type MVT_ServerGroupingRenderCallback<TContext, TResult> = {
370
+ bivarianceHack(context: TContext): TResult;
371
+ }['bivarianceHack'];
372
+ /** Column-level options for resolving/rendering server aggregate values in group rows. */
373
+ export interface MVT_ColumnServerGroupingOptions<TGroup = unknown> {
374
+ /** Resolve this column's value for a group row (commonly from `group.meta`). */
375
+ getValue?: MVT_ServerGroupingRenderCallback<Omit<MVT_ServerGroupCellContext<TGroup>, 'value'>, unknown>;
376
+ /** Render the resolved value. Receives the full cell context including `value`. */
377
+ Cell?: Component | MVT_ServerGroupingRenderCallback<MVT_ServerGroupCellContext<TGroup>, VNodeChild>;
378
+ /** Show this column's aggregate cell in group rows. @default true when `getValue` is set */
379
+ visible?: boolean;
380
+ }
381
+ export interface MVT_ServerGroupingEventPayload<TGroup = unknown> {
382
+ pathId: MVT_ServerGroupPathId;
383
+ path: MVT_ServerGroupPathItem<TGroup>[];
384
+ }
385
+ export interface MVT_ServerGroupingOptions<TData extends MVT_RowData = MVT_RowData, TGroup = unknown, TGroupResponse = unknown, TRecordResponse = unknown> {
386
+ /** @default true when a provider is set */
387
+ enabled?: boolean;
388
+ /**
389
+ * Group-by field identifiers, outermost first. Treated as opaque strings —
390
+ * custom descriptors like `'createdAt:month'` are passed through to the
391
+ * provider untouched. When omitted, the table's regular `grouping` state is
392
+ * used, so `state.grouping` / `onGroupingChange` keep working.
393
+ */
394
+ grouping?: string[];
395
+ /**
396
+ * Initial grouping fields used when neither `serverGrouping.grouping` nor a
397
+ * controlled/initial table `grouping` state is provided. An empty or omitted
398
+ * value starts the table in normal (ungrouped) server-side mode — the user
399
+ * can still add levels from the group-by toolbar. Controlled grouping state
400
+ * always takes precedence.
401
+ */
402
+ defaultGrouping?: string[];
403
+ provider: MVT_ServerGroupingProvider<TData, TGroup, TGroupResponse, TRecordResponse>;
404
+ /** Initial page size for every level. @default 10 */
405
+ initialPageSize?: number;
406
+ pagination?: MVT_ServerGroupingPaginationOptions;
407
+ /** Built-in group-by toolbar control. Enabled by default. */
408
+ groupBy?: MVT_ServerGroupingGroupByOptions;
409
+ /** Row-selection behavior for grouped tables. */
410
+ selection?: MVT_ServerGroupingSelectionOptions;
411
+ cache?: MVT_ServerGroupingCacheOptions;
412
+ /** @default 'independent' */
413
+ sortingMode?: MVT_ServerGroupingSortingMode;
414
+ /** @default 'shared' */
415
+ filteringMode?: MVT_ServerGroupingFilteringMode;
416
+ /** Reset expansion when grouping fields change. @default true */
417
+ resetExpansionOnGroupingChange?: boolean;
418
+ renderGroupLabel?: (context: MVT_ServerGroupRowContext<TGroup>) => MVT_Node;
419
+ renderGroupCount?: (context: MVT_ServerGroupRowContext<TGroup>) => MVT_Node;
420
+ renderGroupError?: (context: {
421
+ error: unknown;
422
+ pathId: MVT_ServerGroupPathId;
423
+ retry: () => void;
424
+ table: MVT_TableInstance<any>;
425
+ }) => MVT_Node;
426
+ renderGroupEmpty?: (context: {
427
+ field?: string;
428
+ parentGroup?: MVT_ServerGroupPathItem<TGroup>;
429
+ pathId: MVT_ServerGroupPathId;
430
+ table: MVT_TableInstance<any>;
431
+ }) => MVT_Node;
432
+ renderGroupLoading?: (context: {
433
+ depth: number;
434
+ pathId: MVT_ServerGroupPathId;
435
+ table: MVT_TableInstance<any>;
436
+ }) => MVT_Node;
437
+ mantineGroupRowProps?: ((context: MVT_ServerGroupRowContext<TGroup>) => HTMLPropsRef<HTMLTableRowElement> & TableTrProps) | (HTMLPropsRef<HTMLTableRowElement> & TableTrProps);
438
+ onGroupExpand?: (payload: {
439
+ group: MVT_ServerGroupNode<TGroup>;
440
+ } & MVT_ServerGroupingEventPayload<TGroup>) => void;
441
+ onGroupCollapse?: (payload: {
442
+ group: MVT_ServerGroupNode<TGroup>;
443
+ } & MVT_ServerGroupingEventPayload<TGroup>) => void;
444
+ onGroupLoadStart?: (payload: {
445
+ request: MVT_ServerGroupRequest<TGroup> | MVT_ServerRecordRequest<TGroup>;
446
+ } & MVT_ServerGroupingEventPayload<TGroup>) => void;
447
+ onGroupLoadSuccess?: (payload: {
448
+ groups: MVT_ServerGroupNode<TGroup>[];
449
+ request: MVT_ServerGroupRequest<TGroup>;
450
+ response: TGroupResponse;
451
+ } & MVT_ServerGroupingEventPayload<TGroup>) => void;
452
+ onRecordLoadSuccess?: (payload: {
453
+ request: MVT_ServerRecordRequest<TGroup>;
454
+ response: TRecordResponse;
455
+ rows: TData[];
456
+ } & MVT_ServerGroupingEventPayload<TGroup>) => void;
457
+ onError?: (payload: {
458
+ error: unknown;
459
+ request: MVT_ServerGroupRequest<TGroup> | MVT_ServerRecordRequest<TGroup>;
460
+ } & MVT_ServerGroupingEventPayload<TGroup>) => void;
461
+ }
462
+ /** Server-grouping methods exposed on the table instance. */
463
+ export interface MVT_ServerGroupingTableApi<TData extends MVT_RowData = MVT_RowData> {
464
+ getServerGroupingState: () => MVT_ServerGroupingState<TData>;
465
+ getServerGroupingPathState: (pathId: MVT_ServerGroupPathId) => MVT_ServerGroupingPathState<TData> | undefined;
466
+ expandServerGroup: (pathId: MVT_ServerGroupPathId) => void;
467
+ collapseServerGroup: (pathId: MVT_ServerGroupPathId) => void;
468
+ toggleServerGroup: (pathId: MVT_ServerGroupPathId) => void;
469
+ reloadServerGrouping: () => void;
470
+ reloadServerGroupingPath: (pathId: MVT_ServerGroupPathId) => void;
471
+ invalidateServerGrouping: () => void;
472
+ invalidateServerGroupingPath: (pathId: MVT_ServerGroupPathId) => void;
473
+ resetServerGroupingState: () => void;
474
+ setServerGroupingExpanded: (updaterOrValue: ((prev: MVT_ServerGroupingExpandedState) => MVT_ServerGroupingExpandedState) | MVT_ServerGroupingExpandedState) => void;
475
+ setServerGroupingPagination: (pathId: MVT_ServerGroupPathId, pagination: ((prev: MVT_ServerPageState) => MVT_ServerPageState) | Partial<MVT_ServerPageState>) => void;
476
+ setServerGroupingSorting: (pathId: MVT_ServerGroupPathId, sorting: ((prev: MVT_SortingState) => MVT_SortingState) | MVT_SortingState) => void;
477
+ setServerGroupingColumnFilters: (pathId: MVT_ServerGroupPathId, columnFilters: ((prev: MVT_ColumnFiltersState) => MVT_ColumnFiltersState) | MVT_ColumnFiltersState) => void;
478
+ setServerGroupingGlobalFilter: (pathId: MVT_ServerGroupPathId, globalFilter: unknown) => void;
479
+ /** Header-checkbox / selection state over loaded records in expanded groups. */
480
+ getServerGroupingSelectionSummary: () => MVT_ServerGroupingSelectionSummary;
481
+ /** Select or deselect every loaded record inside expanded groups. */
482
+ toggleAllServerGroupingRecordsSelected: (value?: boolean) => void;
483
+ /**
484
+ * Select every record matching the current filters. With the default
485
+ * `selectAllMode: 'query'` this is synchronous and transfers nothing.
486
+ */
487
+ selectAllMatchingServerGroupingRecords: () => Promise<void>;
488
+ /** Raw "all matching" state (exclude mode + its exclusions). */
489
+ getServerGroupingSelectAllState: () => MVT_ServerGroupingSelectAllState;
490
+ setServerGroupingSelectAllState: (updaterOrValue: ((prev: MVT_ServerGroupingSelectAllState) => MVT_ServerGroupingSelectAllState) | MVT_ServerGroupingSelectAllState) => void;
491
+ /** Everything a bulk action needs to send to the server. */
492
+ getServerGroupingSelectionPayload: () => MVT_ServerGroupingSelectionPayload;
493
+ }
494
+ export {};
@@ -0,0 +1,31 @@
1
+ import { type MVT_ServerGroupPathId } from './serverGrouping.types';
2
+ /**
3
+ * Escape a path segment part so group ids may safely contain the reserved
4
+ * characters `/` and `:` (and `%`, used for escaping).
5
+ */
6
+ export declare const escapeServerGroupPathPart: (part: string) => string;
7
+ export declare const unescapeServerGroupPathPart: (part: string) => string;
8
+ /**
9
+ * Build the stable path id of a group's content, e.g.
10
+ * `createServerGroupPathId('__root__', 'country', 'BH')` → `'country:BH'` and
11
+ * `createServerGroupPathId('country:BH', 'salesperson', '42')` →
12
+ * `'country:BH/salesperson:42'`. Never derived from row indexes.
13
+ */
14
+ export declare const createServerGroupPathId: (parentPathId: MVT_ServerGroupPathId, field: string, groupId: string) => MVT_ServerGroupPathId;
15
+ export interface MVT_ServerGroupPathSegment {
16
+ field: string;
17
+ groupId: string;
18
+ }
19
+ /** Parse a path id back into its `{ field, groupId }` segments. Root → `[]`. */
20
+ export declare const parseServerGroupPathId: (pathId: MVT_ServerGroupPathId) => MVT_ServerGroupPathSegment[];
21
+ /** Depth of the content addressed by a path id (root → 0). */
22
+ export declare const getServerGroupPathDepth: (pathId: MVT_ServerGroupPathId) => number;
23
+ /** Whether `pathId` equals `ancestorPathId` or is nested anywhere below it. */
24
+ export declare const isServerGroupPathOrDescendant: (pathId: MVT_ServerGroupPathId, ancestorPathId: MVT_ServerGroupPathId) => boolean;
25
+ /**
26
+ * Serialize cache key parts deterministically (object key order does not
27
+ * affect the result).
28
+ */
29
+ export declare const serializeServerGroupingCacheKey: (parts: unknown[]) => string;
30
+ /** Whether an error was caused by request cancellation (never shown as an error). */
31
+ export declare const isAbortError: (error: unknown) => boolean;
@@ -0,0 +1,65 @@
1
+ import type { MVT_Row, MVT_RowData, MVT_TableInstance } from '../types';
2
+ import type { MVT_ServerGroupingSelectionPayload, MVT_ServerGroupingSelectionSummary } from './serverGrouping.types';
3
+ import type { MVT_ServerGroupingManager } from './useMVT_ServerGrouping';
4
+ /** Any MVT table instance — selection helpers never depend on the row type. */
5
+ type AnyTable = MVT_TableInstance<any>;
6
+ /** The server-grouping engine of a table, when server grouping is active. */
7
+ export declare const getServerGroupingManager: (table: AnyTable) => MVT_ServerGroupingManager<MVT_RowData> | undefined;
8
+ /**
9
+ * Record rows that the user may currently select: loaded records inside
10
+ * expanded groups only (never group rows, never collapsed or unloaded
11
+ * groups), filtered by `enableRowSelection`.
12
+ */
13
+ export declare const getServerGroupingSelectableRows: (table: AnyTable) => MVT_Row<MVT_RowData>[];
14
+ /** Whether one record row is selected, honoring exclude mode. */
15
+ export declare const isServerGroupingRecordSelected: (table: AnyTable, row: MVT_Row<MVT_RowData>) => boolean;
16
+ /**
17
+ * Header-checkbox state for a server-grouped table.
18
+ *
19
+ * In *include* mode `isAll` means "every selectable loaded record is
20
+ * selected". In *exclude* mode ("all matching records") the selection is a
21
+ * query, so the checkbox is checked, and turns indeterminate as soon as the
22
+ * user unchecks individual rows.
23
+ */
24
+ export declare const getServerGroupingSelectionSummary: (table: AnyTable) => MVT_ServerGroupingSelectionSummary;
25
+ /**
26
+ * Everything a bulk action needs to send to the server.
27
+ *
28
+ * In exclude mode this is the query plus the user's deselections — no row ids
29
+ * are transferred, so it scales to millions of matching records.
30
+ */
31
+ export declare const getServerGroupingSelectionPayload: (table: AnyTable) => MVT_ServerGroupingSelectionPayload;
32
+ /**
33
+ * Header-checkbox toggle.
34
+ *
35
+ * - **Checking** selects every loaded record inside expanded groups. Records in
36
+ * collapsed or unloaded groups are never implicitly selected.
37
+ * - **Unchecking** clears the *entire* selection — including records whose
38
+ * group was collapsed since, and everything added by "select all matching
39
+ * records". Removing only the on-screen ids would leave invisible records
40
+ * selected while the header checkbox reads unchecked.
41
+ */
42
+ export declare const toggleAllServerGroupingRecordsSelected: (table: AnyTable, value?: boolean) => void;
43
+ /** Deselect the given record ids (used by `selection.clearOnCollapse`). */
44
+ export declare const deselectServerGroupingRecords: (table: AnyTable, rowIds: string[]) => void;
45
+ /**
46
+ * Toggle a single server-grouping record.
47
+ *
48
+ * Provider rows live outside the table's row model (`data` is empty), so
49
+ * `row.toggleSelected()` — which resolves the row through `table.getRow()` —
50
+ * would throw. Selection state is mutated directly instead.
51
+ *
52
+ * Supports shift-click range selection across the loaded records currently on
53
+ * screen, matching the behavior of a regular MVT table.
54
+ */
55
+ export declare const toggleServerGroupingRecordSelected: (table: AnyTable, row: MVT_Row<MVT_RowData>, value: boolean, options?: {
56
+ batch?: boolean;
57
+ lastSelectedRowId?: null | string;
58
+ }) => void;
59
+ /**
60
+ * Opt-in "select all matching records" action: asks the consumer-provided
61
+ * `serverGrouping.selection.loadAllMatchingRowIds` for every row id matching
62
+ * the current filters (across all groups and pages) and selects them.
63
+ */
64
+ export declare const selectAllMatchingServerGroupingRecords: (table: AnyTable) => Promise<void>;
65
+ export {};
@@ -0,0 +1,50 @@
1
+ import type { MVT_ColumnFiltersState, MVT_Row, MVT_RowData, MVT_SortingState, MVT_TableInstance, MVT_Updater } from '../types';
2
+ import { type MVT_ServerGroupNode, type MVT_ServerGroupPathId, type MVT_ServerGroupPathItem, type MVT_ServerGroupingExpandedState, type MVT_ServerGroupingOptions, type MVT_ServerGroupingPathState, type MVT_ServerGroupingSelectAllState, type MVT_ServerGroupingState, type MVT_ServerPageState } from './serverGrouping.types';
3
+ /**
4
+ * Internal server-grouping engine. Owns per-path query state (pagination,
5
+ * sorting, filters, loading, errors), lazy loading, request cancellation,
6
+ * stale-response protection, the optional cache, and expansion state.
7
+ *
8
+ * Created by `useMVT_TableInstance` when `serverGrouping.provider` is set; the
9
+ * public surface is exposed through the `table.*ServerGrouping*` instance
10
+ * methods and the `<MantineVueTable>` built-in rendering.
11
+ */
12
+ export interface MVT_ServerGroupingManager<TData extends MVT_RowData = MVT_RowData> {
13
+ options: MVT_ServerGroupingOptions<TData, any, any, any>;
14
+ getGroupingFields: () => string[];
15
+ getExpanded: () => MVT_ServerGroupingExpandedState;
16
+ setExpanded: (updater: MVT_Updater<MVT_ServerGroupingExpandedState>) => void;
17
+ /** "All matching records" (exclude-mode) selection state. */
18
+ getSelectAll: () => MVT_ServerGroupingSelectAllState;
19
+ setSelectAll: (updater: MVT_Updater<MVT_ServerGroupingSelectAllState>) => void;
20
+ isExpanded: (pathId: MVT_ServerGroupPathId) => boolean;
21
+ getState: () => MVT_ServerGroupingState<TData>;
22
+ getPathState: (pathId: MVT_ServerGroupPathId) => MVT_ServerGroupingPathState<TData> | undefined;
23
+ /** Table rows of one loaded record page (created once, cached per page). */
24
+ getRecordRows: (pathId: MVT_ServerGroupPathId) => MVT_Row<TData>[];
25
+ /** All loaded record rows inside currently expanded groups. */
26
+ getVisibleRecordRows: () => MVT_Row<TData>[];
27
+ getNode: (pathId: MVT_ServerGroupPathId) => MVT_ServerGroupNode | undefined;
28
+ getParentItems: (pathId: MVT_ServerGroupPathId) => MVT_ServerGroupPathItem[];
29
+ expand: (pathId: MVT_ServerGroupPathId) => void;
30
+ collapse: (pathId: MVT_ServerGroupPathId) => void;
31
+ toggle: (pathId: MVT_ServerGroupPathId) => void;
32
+ ensureLoaded: (pathId: MVT_ServerGroupPathId) => void;
33
+ reload: (pathId?: MVT_ServerGroupPathId) => void;
34
+ invalidate: (pathId?: MVT_ServerGroupPathId) => void;
35
+ retry: (pathId: MVT_ServerGroupPathId) => void;
36
+ reset: () => void;
37
+ setPagination: (pathId: MVT_ServerGroupPathId, updater: ((prev: MVT_ServerPageState) => MVT_ServerPageState) | Partial<MVT_ServerPageState>) => void;
38
+ setSorting: (pathId: MVT_ServerGroupPathId, updater: MVT_Updater<MVT_SortingState>) => void;
39
+ setColumnFilters: (pathId: MVT_ServerGroupPathId, updater: MVT_Updater<MVT_ColumnFiltersState>) => void;
40
+ setGlobalFilter: (pathId: MVT_ServerGroupPathId, value: unknown) => void;
41
+ }
42
+ export declare const createMVT_ServerGroupingManager: <TData extends MVT_RowData>(table: MVT_TableInstance<TData>,
43
+ /**
44
+ * Reader for the user-controlled `state.serverGroupingExpanded` slice.
45
+ * Injected by `useMVT_TableInstance` to avoid reading back the merged state
46
+ * object (which would recurse); defaults to reading `table.options.state`.
47
+ */
48
+ controlledExpandedReader?: () => MVT_ServerGroupingExpandedState | undefined,
49
+ /** Same, for the controlled `state.serverGroupingSelectAll` slice. */
50
+ controlledSelectAllReader?: () => MVT_ServerGroupingSelectAllState | undefined) => MVT_ServerGroupingManager<TData> | undefined;