@redsift/table 12.5.3-muiv7 → 12.5.3

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.
@@ -1,1501 +1,18 @@
1
1
  import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends } from './_rollupPluginBabelHelpers.js';
2
2
  import * as React from 'react';
3
3
  import React__default, { useCallback, useEffect, useRef, useMemo, forwardRef, useState } from 'react';
4
+ import { createTheme, ThemeProvider as ThemeProvider$1 } from '@mui/material/styles';
4
5
  import classNames from 'classnames';
5
- import { Icon, useTheme as useTheme$1, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite, ThemeProvider } from '@redsift/design-system';
6
- import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, DataGridPro } from '@mui/x-data-grid-pro';
7
- import { L as LicenseInfo, u as useControlledDatagridState, T as ThemeProvider$1, S as StyledDataGrid } from './useControlledDatagridState.js';
6
+ import { LicenseInfo } from '@mui/x-license';
7
+ import { Icon, useTheme, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite, ThemeProvider } from '@redsift/design-system';
8
+ import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, DataGridPremium } from '@mui/x-data-grid-premium';
9
+ import { u as useControlledDatagridState, S as StyledDataGrid } from './useControlledDatagridState.js';
10
+ import Box from '@mui/material/Box';
11
+ import TextField from '@mui/material/TextField';
8
12
  import { mdiSync } from '@redsift/icons';
9
- import { d as defaultSxConfig, i as isPlainObject, s as styled, a as styleFunctionSx, c as clsx, g as generateUtilityClasses, b as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, e as generateUtilityClass, f as styled$1, u as useDefaultProps, h as composeClasses, r as rootShouldForwardProp, j as refType } from './Portal.js';
10
- import { j as jsxRuntimeExports } from './jsx-runtime.js';
11
- import { u as useTheme, m as memoTheme, c as createSimplePaletteValueFilter, a as useFormControl, b as formControlState, d as capitalize, i as isAdornedStart, e as isFilled, F as FormControlContext, h as useId, j as useSlot, k as Select, I as Input, l as FilledInput, O as OutlinedInput, o as onServerSideSelectionStatusChange, S as ServerSideControlledPagination, C as ControlledPagination } from './ControlledPagination.js';
12
13
  import { decompressFromEncodedURIComponent, compressToEncodedURIComponent } from 'lz-string';
13
- import { T as Toolbar } from './Toolbar2.js';
14
- import { B as BaseButton, a as BaseCheckbox, c as BasePopper, b as BaseIcon } from './BasePopper.js';
15
- import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
16
-
17
- const splitProps = props => {
18
- const result = {
19
- systemProps: {},
20
- otherProps: {}
21
- };
22
- const config = props?.theme?.unstable_sxConfig ?? defaultSxConfig;
23
- Object.keys(props).forEach(prop => {
24
- if (config[prop]) {
25
- result.systemProps[prop] = props[prop];
26
- } else {
27
- result.otherProps[prop] = props[prop];
28
- }
29
- });
30
- return result;
31
- };
32
- function extendSxProp(props) {
33
- const {
34
- sx: inSx,
35
- ...other
36
- } = props;
37
- const {
38
- systemProps,
39
- otherProps
40
- } = splitProps(other);
41
- let finalSx;
42
- if (Array.isArray(inSx)) {
43
- finalSx = [systemProps, ...inSx];
44
- } else if (typeof inSx === 'function') {
45
- finalSx = (...args) => {
46
- const result = inSx(...args);
47
- if (!isPlainObject(result)) {
48
- return systemProps;
49
- }
50
- return {
51
- ...systemProps,
52
- ...result
53
- };
54
- };
55
- } else {
56
- finalSx = {
57
- ...systemProps,
58
- ...inSx
59
- };
60
- }
61
- return {
62
- ...otherProps,
63
- sx: finalSx
64
- };
65
- }
66
-
67
- function createBox(options = {}) {
68
- const {
69
- themeId,
70
- defaultTheme,
71
- defaultClassName = 'MuiBox-root',
72
- generateClassName
73
- } = options;
74
- const BoxRoot = styled('div', {
75
- shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
76
- })(styleFunctionSx);
77
- const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
78
- const theme = useTheme(defaultTheme);
79
- const {
80
- className,
81
- component = 'div',
82
- ...other
83
- } = extendSxProp(inProps);
84
- return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, {
85
- as: component,
86
- ref: ref,
87
- className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
88
- theme: themeId ? theme[themeId] || theme : theme,
89
- ...other
90
- });
91
- });
92
- return Box;
93
- }
94
-
95
- function isMuiElement(element, muiNames) {
96
- return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf(
97
- // For server components `muiName` is avaialble in element.type._payload.value.muiName
98
- // relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
99
- // eslint-disable-next-line no-underscore-dangle
100
- element.type.muiName ?? element.type?._payload?.value?.muiName) !== -1;
101
- }
102
-
103
- const boxClasses = generateUtilityClasses('MuiBox', ['root']);
104
- var boxClasses$1 = boxClasses;
105
-
106
- const defaultTheme = createTheme();
107
- const Box = createBox({
108
- themeId: THEME_ID,
109
- defaultTheme,
110
- defaultClassName: boxClasses$1.root,
111
- generateClassName: ClassNameGenerator.generate
112
- });
113
- process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
114
- // ┌────────────────────────────── Warning ──────────────────────────────┐
115
- // │ These PropTypes are generated from the TypeScript type definitions. │
116
- // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
117
- // └─────────────────────────────────────────────────────────────────────┘
118
- /**
119
- * @ignore
120
- */
121
- children: PropTypes.node,
122
- /**
123
- * The component used for the root node.
124
- * Either a string to use a HTML element or a component.
125
- */
126
- component: PropTypes.elementType,
127
- /**
128
- * The system prop that allows defining system overrides as well as additional CSS styles.
129
- */
130
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
131
- } : void 0;
132
- var Box$1 = Box;
133
-
134
- function getFormLabelUtilityClasses(slot) {
135
- return generateUtilityClass('MuiFormLabel', slot);
136
- }
137
- const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
138
- var formLabelClasses$1 = formLabelClasses;
139
-
140
- const useUtilityClasses$4 = ownerState => {
141
- const {
142
- classes,
143
- color,
144
- focused,
145
- disabled,
146
- error,
147
- filled,
148
- required
149
- } = ownerState;
150
- const slots = {
151
- root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
152
- asterisk: ['asterisk', error && 'error']
153
- };
154
- return composeClasses(slots, getFormLabelUtilityClasses, classes);
155
- };
156
- const FormLabelRoot = styled$1('label', {
157
- name: 'MuiFormLabel',
158
- slot: 'Root',
159
- overridesResolver: (props, styles) => {
160
- const {
161
- ownerState
162
- } = props;
163
- return [styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled];
164
- }
165
- })(memoTheme(({
166
- theme
167
- }) => ({
168
- color: (theme.vars || theme).palette.text.secondary,
169
- ...theme.typography.body1,
170
- lineHeight: '1.4375em',
171
- padding: 0,
172
- position: 'relative',
173
- variants: [...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
174
- props: {
175
- color
176
- },
177
- style: {
178
- [`&.${formLabelClasses$1.focused}`]: {
179
- color: (theme.vars || theme).palette[color].main
180
- }
181
- }
182
- })), {
183
- props: {},
184
- style: {
185
- [`&.${formLabelClasses$1.disabled}`]: {
186
- color: (theme.vars || theme).palette.text.disabled
187
- },
188
- [`&.${formLabelClasses$1.error}`]: {
189
- color: (theme.vars || theme).palette.error.main
190
- }
191
- }
192
- }]
193
- })));
194
- const AsteriskComponent = styled$1('span', {
195
- name: 'MuiFormLabel',
196
- slot: 'Asterisk',
197
- overridesResolver: (props, styles) => styles.asterisk
198
- })(memoTheme(({
199
- theme
200
- }) => ({
201
- [`&.${formLabelClasses$1.error}`]: {
202
- color: (theme.vars || theme).palette.error.main
203
- }
204
- })));
205
- const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
206
- const props = useDefaultProps({
207
- props: inProps,
208
- name: 'MuiFormLabel'
209
- });
210
- const {
211
- children,
212
- className,
213
- color,
214
- component = 'label',
215
- disabled,
216
- error,
217
- filled,
218
- focused,
219
- required,
220
- ...other
221
- } = props;
222
- const muiFormControl = useFormControl();
223
- const fcs = formControlState({
224
- props,
225
- muiFormControl,
226
- states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
227
- });
228
- const ownerState = {
229
- ...props,
230
- color: fcs.color || 'primary',
231
- component,
232
- disabled: fcs.disabled,
233
- error: fcs.error,
234
- filled: fcs.filled,
235
- focused: fcs.focused,
236
- required: fcs.required
237
- };
238
- const classes = useUtilityClasses$4(ownerState);
239
- return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, {
240
- as: component,
241
- ownerState: ownerState,
242
- className: clsx(classes.root, className),
243
- ref: ref,
244
- ...other,
245
- children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
246
- ownerState: ownerState,
247
- "aria-hidden": true,
248
- className: classes.asterisk,
249
- children: ["\u2009", '*']
250
- })]
251
- });
252
- });
253
- process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
254
- // ┌────────────────────────────── Warning ──────────────────────────────┐
255
- // │ These PropTypes are generated from the TypeScript type definitions. │
256
- // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
257
- // └─────────────────────────────────────────────────────────────────────┘
258
- /**
259
- * The content of the component.
260
- */
261
- children: PropTypes.node,
262
- /**
263
- * Override or extend the styles applied to the component.
264
- */
265
- classes: PropTypes.object,
266
- /**
267
- * @ignore
268
- */
269
- className: PropTypes.string,
270
- /**
271
- * The color of the component.
272
- * It supports both default and custom theme colors, which can be added as shown in the
273
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
274
- */
275
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
276
- /**
277
- * The component used for the root node.
278
- * Either a string to use a HTML element or a component.
279
- */
280
- component: PropTypes.elementType,
281
- /**
282
- * If `true`, the label should be displayed in a disabled state.
283
- */
284
- disabled: PropTypes.bool,
285
- /**
286
- * If `true`, the label is displayed in an error state.
287
- */
288
- error: PropTypes.bool,
289
- /**
290
- * If `true`, the label should use filled classes key.
291
- */
292
- filled: PropTypes.bool,
293
- /**
294
- * If `true`, the input of this label is focused (used by `FormGroup` components).
295
- */
296
- focused: PropTypes.bool,
297
- /**
298
- * If `true`, the label will indicate that the `input` is required.
299
- */
300
- required: PropTypes.bool,
301
- /**
302
- * The system prop that allows defining system overrides as well as additional CSS styles.
303
- */
304
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
305
- } : void 0;
306
- var FormLabel$1 = FormLabel;
307
-
308
- function getInputLabelUtilityClasses(slot) {
309
- return generateUtilityClass('MuiInputLabel', slot);
310
- }
311
- generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
312
-
313
- const useUtilityClasses$3 = ownerState => {
314
- const {
315
- classes,
316
- formControl,
317
- size,
318
- shrink,
319
- disableAnimation,
320
- variant,
321
- required
322
- } = ownerState;
323
- const slots = {
324
- root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size && size !== 'normal' && `size${capitalize(size)}`, variant],
325
- asterisk: [required && 'asterisk']
326
- };
327
- const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
328
- return {
329
- ...classes,
330
- // forward the focused, disabled, etc. classes to the FormLabel
331
- ...composedClasses
332
- };
333
- };
334
- const InputLabelRoot = styled$1(FormLabel$1, {
335
- shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
336
- name: 'MuiInputLabel',
337
- slot: 'Root',
338
- overridesResolver: (props, styles) => {
339
- const {
340
- ownerState
341
- } = props;
342
- return [{
343
- [`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
344
- }, styles.root, ownerState.formControl && styles.formControl, ownerState.size === 'small' && styles.sizeSmall, ownerState.shrink && styles.shrink, !ownerState.disableAnimation && styles.animated, ownerState.focused && styles.focused, styles[ownerState.variant]];
345
- }
346
- })(memoTheme(({
347
- theme
348
- }) => ({
349
- display: 'block',
350
- transformOrigin: 'top left',
351
- whiteSpace: 'nowrap',
352
- overflow: 'hidden',
353
- textOverflow: 'ellipsis',
354
- maxWidth: '100%',
355
- variants: [{
356
- props: ({
357
- ownerState
358
- }) => ownerState.formControl,
359
- style: {
360
- position: 'absolute',
361
- left: 0,
362
- top: 0,
363
- // slight alteration to spec spacing to match visual spec result
364
- transform: 'translate(0, 20px) scale(1)'
365
- }
366
- }, {
367
- props: {
368
- size: 'small'
369
- },
370
- style: {
371
- // Compensation for the `Input.inputSizeSmall` style.
372
- transform: 'translate(0, 17px) scale(1)'
373
- }
374
- }, {
375
- props: ({
376
- ownerState
377
- }) => ownerState.shrink,
378
- style: {
379
- transform: 'translate(0, -1.5px) scale(0.75)',
380
- transformOrigin: 'top left',
381
- maxWidth: '133%'
382
- }
383
- }, {
384
- props: ({
385
- ownerState
386
- }) => !ownerState.disableAnimation,
387
- style: {
388
- transition: theme.transitions.create(['color', 'transform', 'max-width'], {
389
- duration: theme.transitions.duration.shorter,
390
- easing: theme.transitions.easing.easeOut
391
- })
392
- }
393
- }, {
394
- props: {
395
- variant: 'filled'
396
- },
397
- style: {
398
- // Chrome's autofill feature gives the input field a yellow background.
399
- // Since the input field is behind the label in the HTML tree,
400
- // the input field is drawn last and hides the label with an opaque background color.
401
- // zIndex: 1 will raise the label above opaque background-colors of input.
402
- zIndex: 1,
403
- pointerEvents: 'none',
404
- transform: 'translate(12px, 16px) scale(1)',
405
- maxWidth: 'calc(100% - 24px)'
406
- }
407
- }, {
408
- props: {
409
- variant: 'filled',
410
- size: 'small'
411
- },
412
- style: {
413
- transform: 'translate(12px, 13px) scale(1)'
414
- }
415
- }, {
416
- props: ({
417
- variant,
418
- ownerState
419
- }) => variant === 'filled' && ownerState.shrink,
420
- style: {
421
- userSelect: 'none',
422
- pointerEvents: 'auto',
423
- transform: 'translate(12px, 7px) scale(0.75)',
424
- maxWidth: 'calc(133% - 24px)'
425
- }
426
- }, {
427
- props: ({
428
- variant,
429
- ownerState,
430
- size
431
- }) => variant === 'filled' && ownerState.shrink && size === 'small',
432
- style: {
433
- transform: 'translate(12px, 4px) scale(0.75)'
434
- }
435
- }, {
436
- props: {
437
- variant: 'outlined'
438
- },
439
- style: {
440
- // see comment above on filled.zIndex
441
- zIndex: 1,
442
- pointerEvents: 'none',
443
- transform: 'translate(14px, 16px) scale(1)',
444
- maxWidth: 'calc(100% - 24px)'
445
- }
446
- }, {
447
- props: {
448
- variant: 'outlined',
449
- size: 'small'
450
- },
451
- style: {
452
- transform: 'translate(14px, 9px) scale(1)'
453
- }
454
- }, {
455
- props: ({
456
- variant,
457
- ownerState
458
- }) => variant === 'outlined' && ownerState.shrink,
459
- style: {
460
- userSelect: 'none',
461
- pointerEvents: 'auto',
462
- // Theoretically, we should have (8+5)*2/0.75 = 34px
463
- // but it feels a better when it bleeds a bit on the left, so 32px.
464
- maxWidth: 'calc(133% - 32px)',
465
- transform: 'translate(14px, -9px) scale(0.75)'
466
- }
467
- }]
468
- })));
469
- const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
470
- const props = useDefaultProps({
471
- name: 'MuiInputLabel',
472
- props: inProps
473
- });
474
- const {
475
- disableAnimation = false,
476
- margin,
477
- shrink: shrinkProp,
478
- variant,
479
- className,
480
- ...other
481
- } = props;
482
- const muiFormControl = useFormControl();
483
- let shrink = shrinkProp;
484
- if (typeof shrink === 'undefined' && muiFormControl) {
485
- shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
486
- }
487
- const fcs = formControlState({
488
- props,
489
- muiFormControl,
490
- states: ['size', 'variant', 'required', 'focused']
491
- });
492
- const ownerState = {
493
- ...props,
494
- disableAnimation,
495
- formControl: muiFormControl,
496
- shrink,
497
- size: fcs.size,
498
- variant: fcs.variant,
499
- required: fcs.required,
500
- focused: fcs.focused
501
- };
502
- const classes = useUtilityClasses$3(ownerState);
503
- return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, {
504
- "data-shrink": shrink,
505
- ref: ref,
506
- className: clsx(classes.root, className),
507
- ...other,
508
- ownerState: ownerState,
509
- classes: classes
510
- });
511
- });
512
- process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
513
- // ┌────────────────────────────── Warning ──────────────────────────────┐
514
- // │ These PropTypes are generated from the TypeScript type definitions. │
515
- // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
516
- // └─────────────────────────────────────────────────────────────────────┘
517
- /**
518
- * The content of the component.
519
- */
520
- children: PropTypes.node,
521
- /**
522
- * Override or extend the styles applied to the component.
523
- */
524
- classes: PropTypes.object,
525
- /**
526
- * @ignore
527
- */
528
- className: PropTypes.string,
529
- /**
530
- * The color of the component.
531
- * It supports both default and custom theme colors, which can be added as shown in the
532
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
533
- */
534
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
535
- /**
536
- * If `true`, the transition animation is disabled.
537
- * @default false
538
- */
539
- disableAnimation: PropTypes.bool,
540
- /**
541
- * If `true`, the component is disabled.
542
- */
543
- disabled: PropTypes.bool,
544
- /**
545
- * If `true`, the label is displayed in an error state.
546
- */
547
- error: PropTypes.bool,
548
- /**
549
- * If `true`, the `input` of this label is focused.
550
- */
551
- focused: PropTypes.bool,
552
- /**
553
- * If `dense`, will adjust vertical spacing. This is normally obtained via context from
554
- * FormControl.
555
- */
556
- margin: PropTypes.oneOf(['dense']),
557
- /**
558
- * if `true`, the label will indicate that the `input` is required.
559
- */
560
- required: PropTypes.bool,
561
- /**
562
- * If `true`, the label is shrunk.
563
- */
564
- shrink: PropTypes.bool,
565
- /**
566
- * The size of the component.
567
- * @default 'normal'
568
- */
569
- size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
570
- /**
571
- * The system prop that allows defining system overrides as well as additional CSS styles.
572
- */
573
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
574
- /**
575
- * The variant to use.
576
- */
577
- variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
578
- } : void 0;
579
- var InputLabel$1 = InputLabel;
580
-
581
- function getFormControlUtilityClasses(slot) {
582
- return generateUtilityClass('MuiFormControl', slot);
583
- }
584
- generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
585
-
586
- const useUtilityClasses$2 = ownerState => {
587
- const {
588
- classes,
589
- margin,
590
- fullWidth
591
- } = ownerState;
592
- const slots = {
593
- root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
594
- };
595
- return composeClasses(slots, getFormControlUtilityClasses, classes);
596
- };
597
- const FormControlRoot = styled$1('div', {
598
- name: 'MuiFormControl',
599
- slot: 'Root',
600
- overridesResolver: (props, styles) => {
601
- const {
602
- ownerState
603
- } = props;
604
- return [styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth];
605
- }
606
- })({
607
- display: 'inline-flex',
608
- flexDirection: 'column',
609
- position: 'relative',
610
- // Reset fieldset default style.
611
- minWidth: 0,
612
- padding: 0,
613
- margin: 0,
614
- border: 0,
615
- verticalAlign: 'top',
616
- // Fix alignment issue on Safari.
617
- variants: [{
618
- props: {
619
- margin: 'normal'
620
- },
621
- style: {
622
- marginTop: 16,
623
- marginBottom: 8
624
- }
625
- }, {
626
- props: {
627
- margin: 'dense'
628
- },
629
- style: {
630
- marginTop: 8,
631
- marginBottom: 4
632
- }
633
- }, {
634
- props: {
635
- fullWidth: true
636
- },
637
- style: {
638
- width: '100%'
639
- }
640
- }]
641
- });
642
-
643
- /**
644
- * Provides context such as filled/focused/error/required for form inputs.
645
- * Relying on the context provides high flexibility and ensures that the state always stays
646
- * consistent across the children of the `FormControl`.
647
- * This context is used by the following components:
648
- *
649
- * - FormLabel
650
- * - FormHelperText
651
- * - Input
652
- * - InputLabel
653
- *
654
- * You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
655
- *
656
- * ```jsx
657
- * <FormControl>
658
- * <InputLabel htmlFor="my-input">Email address</InputLabel>
659
- * <Input id="my-input" aria-describedby="my-helper-text" />
660
- * <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
661
- * </FormControl>
662
- * ```
663
- *
664
- * ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
665
- * For instance, only one input can be focused at the same time, the state shouldn't be shared.
666
- */
667
- const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
668
- const props = useDefaultProps({
669
- props: inProps,
670
- name: 'MuiFormControl'
671
- });
672
- const {
673
- children,
674
- className,
675
- color = 'primary',
676
- component = 'div',
677
- disabled = false,
678
- error = false,
679
- focused: visuallyFocused,
680
- fullWidth = false,
681
- hiddenLabel = false,
682
- margin = 'none',
683
- required = false,
684
- size = 'medium',
685
- variant = 'outlined',
686
- ...other
687
- } = props;
688
- const ownerState = {
689
- ...props,
690
- color,
691
- component,
692
- disabled,
693
- error,
694
- fullWidth,
695
- hiddenLabel,
696
- margin,
697
- required,
698
- size,
699
- variant
700
- };
701
- const classes = useUtilityClasses$2(ownerState);
702
- const [adornedStart, setAdornedStart] = React.useState(() => {
703
- // We need to iterate through the children and find the Input in order
704
- // to fully support server-side rendering.
705
- let initialAdornedStart = false;
706
- if (children) {
707
- React.Children.forEach(children, child => {
708
- if (!isMuiElement(child, ['Input', 'Select'])) {
709
- return;
710
- }
711
- const input = isMuiElement(child, ['Select']) ? child.props.input : child;
712
- if (input && isAdornedStart(input.props)) {
713
- initialAdornedStart = true;
714
- }
715
- });
716
- }
717
- return initialAdornedStart;
718
- });
719
- const [filled, setFilled] = React.useState(() => {
720
- // We need to iterate through the children and find the Input in order
721
- // to fully support server-side rendering.
722
- let initialFilled = false;
723
- if (children) {
724
- React.Children.forEach(children, child => {
725
- if (!isMuiElement(child, ['Input', 'Select'])) {
726
- return;
727
- }
728
- if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
729
- initialFilled = true;
730
- }
731
- });
732
- }
733
- return initialFilled;
734
- });
735
- const [focusedState, setFocused] = React.useState(false);
736
- if (disabled && focusedState) {
737
- setFocused(false);
738
- }
739
- const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
740
- let registerEffect;
741
- const registeredInput = React.useRef(false);
742
- if (process.env.NODE_ENV !== 'production') {
743
- registerEffect = () => {
744
- if (registeredInput.current) {
745
- console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
746
- }
747
- registeredInput.current = true;
748
- return () => {
749
- registeredInput.current = false;
750
- };
751
- };
752
- }
753
- const onFilled = React.useCallback(() => {
754
- setFilled(true);
755
- }, []);
756
- const onEmpty = React.useCallback(() => {
757
- setFilled(false);
758
- }, []);
759
- const childContext = React.useMemo(() => {
760
- return {
761
- adornedStart,
762
- setAdornedStart,
763
- color,
764
- disabled,
765
- error,
766
- filled,
767
- focused,
768
- fullWidth,
769
- hiddenLabel,
770
- size,
771
- onBlur: () => {
772
- setFocused(false);
773
- },
774
- onFocus: () => {
775
- setFocused(true);
776
- },
777
- onEmpty,
778
- onFilled,
779
- registerEffect,
780
- required,
781
- variant
782
- };
783
- }, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, onEmpty, onFilled, required, size, variant]);
784
- return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
785
- value: childContext,
786
- children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, {
787
- as: component,
788
- ownerState: ownerState,
789
- className: clsx(classes.root, className),
790
- ref: ref,
791
- ...other,
792
- children: children
793
- })
794
- });
795
- });
796
- process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
797
- // ┌────────────────────────────── Warning ──────────────────────────────┐
798
- // │ These PropTypes are generated from the TypeScript type definitions. │
799
- // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
800
- // └─────────────────────────────────────────────────────────────────────┘
801
- /**
802
- * The content of the component.
803
- */
804
- children: PropTypes.node,
805
- /**
806
- * Override or extend the styles applied to the component.
807
- */
808
- classes: PropTypes.object,
809
- /**
810
- * @ignore
811
- */
812
- className: PropTypes.string,
813
- /**
814
- * The color of the component.
815
- * It supports both default and custom theme colors, which can be added as shown in the
816
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
817
- * @default 'primary'
818
- */
819
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
820
- /**
821
- * The component used for the root node.
822
- * Either a string to use a HTML element or a component.
823
- */
824
- component: PropTypes.elementType,
825
- /**
826
- * If `true`, the label, input and helper text should be displayed in a disabled state.
827
- * @default false
828
- */
829
- disabled: PropTypes.bool,
830
- /**
831
- * If `true`, the label is displayed in an error state.
832
- * @default false
833
- */
834
- error: PropTypes.bool,
835
- /**
836
- * If `true`, the component is displayed in focused state.
837
- */
838
- focused: PropTypes.bool,
839
- /**
840
- * If `true`, the component will take up the full width of its container.
841
- * @default false
842
- */
843
- fullWidth: PropTypes.bool,
844
- /**
845
- * If `true`, the label is hidden.
846
- * This is used to increase density for a `FilledInput`.
847
- * Be sure to add `aria-label` to the `input` element.
848
- * @default false
849
- */
850
- hiddenLabel: PropTypes.bool,
851
- /**
852
- * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
853
- * @default 'none'
854
- */
855
- margin: PropTypes.oneOf(['dense', 'none', 'normal']),
856
- /**
857
- * If `true`, the label will indicate that the `input` is required.
858
- * @default false
859
- */
860
- required: PropTypes.bool,
861
- /**
862
- * The size of the component.
863
- * @default 'medium'
864
- */
865
- size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
866
- /**
867
- * The system prop that allows defining system overrides as well as additional CSS styles.
868
- */
869
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
870
- /**
871
- * The variant to use.
872
- * @default 'outlined'
873
- */
874
- variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
875
- } : void 0;
876
- var FormControl$1 = FormControl;
877
-
878
- function getFormHelperTextUtilityClasses(slot) {
879
- return generateUtilityClass('MuiFormHelperText', slot);
880
- }
881
- const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
882
- var formHelperTextClasses$1 = formHelperTextClasses;
883
-
884
- var _span;
885
- const useUtilityClasses$1 = ownerState => {
886
- const {
887
- classes,
888
- contained,
889
- size,
890
- disabled,
891
- error,
892
- filled,
893
- focused,
894
- required
895
- } = ownerState;
896
- const slots = {
897
- root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
898
- };
899
- return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
900
- };
901
- const FormHelperTextRoot = styled$1('p', {
902
- name: 'MuiFormHelperText',
903
- slot: 'Root',
904
- overridesResolver: (props, styles) => {
905
- const {
906
- ownerState
907
- } = props;
908
- return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
909
- }
910
- })(memoTheme(({
911
- theme
912
- }) => ({
913
- color: (theme.vars || theme).palette.text.secondary,
914
- ...theme.typography.caption,
915
- textAlign: 'left',
916
- marginTop: 3,
917
- marginRight: 0,
918
- marginBottom: 0,
919
- marginLeft: 0,
920
- [`&.${formHelperTextClasses$1.disabled}`]: {
921
- color: (theme.vars || theme).palette.text.disabled
922
- },
923
- [`&.${formHelperTextClasses$1.error}`]: {
924
- color: (theme.vars || theme).palette.error.main
925
- },
926
- variants: [{
927
- props: {
928
- size: 'small'
929
- },
930
- style: {
931
- marginTop: 4
932
- }
933
- }, {
934
- props: ({
935
- ownerState
936
- }) => ownerState.contained,
937
- style: {
938
- marginLeft: 14,
939
- marginRight: 14
940
- }
941
- }]
942
- })));
943
- const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
944
- const props = useDefaultProps({
945
- props: inProps,
946
- name: 'MuiFormHelperText'
947
- });
948
- const {
949
- children,
950
- className,
951
- component = 'p',
952
- disabled,
953
- error,
954
- filled,
955
- focused,
956
- margin,
957
- required,
958
- variant,
959
- ...other
960
- } = props;
961
- const muiFormControl = useFormControl();
962
- const fcs = formControlState({
963
- props,
964
- muiFormControl,
965
- states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
966
- });
967
- const ownerState = {
968
- ...props,
969
- component,
970
- contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
971
- variant: fcs.variant,
972
- size: fcs.size,
973
- disabled: fcs.disabled,
974
- error: fcs.error,
975
- filled: fcs.filled,
976
- focused: fcs.focused,
977
- required: fcs.required
978
- };
979
-
980
- // This issue explains why this is required: https://github.com/mui/material-ui/issues/42184
981
- delete ownerState.ownerState;
982
- const classes = useUtilityClasses$1(ownerState);
983
- return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, {
984
- as: component,
985
- className: clsx(classes.root, className),
986
- ref: ref,
987
- ...other,
988
- ownerState: ownerState,
989
- children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
990
- _span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
991
- className: "notranslate",
992
- "aria-hidden": true,
993
- children: "\u200B"
994
- })) : children
995
- });
996
- });
997
- process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
998
- // ┌────────────────────────────── Warning ──────────────────────────────┐
999
- // │ These PropTypes are generated from the TypeScript type definitions. │
1000
- // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
1001
- // └─────────────────────────────────────────────────────────────────────┘
1002
- /**
1003
- * The content of the component.
1004
- *
1005
- * If `' '` is provided, the component reserves one line height for displaying a future message.
1006
- */
1007
- children: PropTypes.node,
1008
- /**
1009
- * Override or extend the styles applied to the component.
1010
- */
1011
- classes: PropTypes.object,
1012
- /**
1013
- * @ignore
1014
- */
1015
- className: PropTypes.string,
1016
- /**
1017
- * The component used for the root node.
1018
- * Either a string to use a HTML element or a component.
1019
- */
1020
- component: PropTypes.elementType,
1021
- /**
1022
- * If `true`, the helper text should be displayed in a disabled state.
1023
- */
1024
- disabled: PropTypes.bool,
1025
- /**
1026
- * If `true`, helper text should be displayed in an error state.
1027
- */
1028
- error: PropTypes.bool,
1029
- /**
1030
- * If `true`, the helper text should use filled classes key.
1031
- */
1032
- filled: PropTypes.bool,
1033
- /**
1034
- * If `true`, the helper text should use focused classes key.
1035
- */
1036
- focused: PropTypes.bool,
1037
- /**
1038
- * If `dense`, will adjust vertical spacing. This is normally obtained via context from
1039
- * FormControl.
1040
- */
1041
- margin: PropTypes.oneOf(['dense']),
1042
- /**
1043
- * If `true`, the helper text should use required classes key.
1044
- */
1045
- required: PropTypes.bool,
1046
- /**
1047
- * The system prop that allows defining system overrides as well as additional CSS styles.
1048
- */
1049
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1050
- /**
1051
- * The variant to use.
1052
- */
1053
- variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
1054
- } : void 0;
1055
- var FormHelperText$1 = FormHelperText;
1056
-
1057
- function getTextFieldUtilityClass(slot) {
1058
- return generateUtilityClass('MuiTextField', slot);
1059
- }
1060
- generateUtilityClasses('MuiTextField', ['root']);
1061
-
1062
- const variantComponent = {
1063
- standard: Input,
1064
- filled: FilledInput,
1065
- outlined: OutlinedInput
1066
- };
1067
- const useUtilityClasses = ownerState => {
1068
- const {
1069
- classes
1070
- } = ownerState;
1071
- const slots = {
1072
- root: ['root']
1073
- };
1074
- return composeClasses(slots, getTextFieldUtilityClass, classes);
1075
- };
1076
- const TextFieldRoot = styled$1(FormControl$1, {
1077
- name: 'MuiTextField',
1078
- slot: 'Root',
1079
- overridesResolver: (props, styles) => styles.root
1080
- })({});
1081
-
1082
- /**
1083
- * The `TextField` is a convenience wrapper for the most common cases (80%).
1084
- * It cannot be all things to all people, otherwise the API would grow out of control.
1085
- *
1086
- * ## Advanced Configuration
1087
- *
1088
- * It's important to understand that the text field is a simple abstraction
1089
- * on top of the following components:
1090
- *
1091
- * - [FormControl](/material-ui/api/form-control/)
1092
- * - [InputLabel](/material-ui/api/input-label/)
1093
- * - [FilledInput](/material-ui/api/filled-input/)
1094
- * - [OutlinedInput](/material-ui/api/outlined-input/)
1095
- * - [Input](/material-ui/api/input/)
1096
- * - [FormHelperText](/material-ui/api/form-helper-text/)
1097
- *
1098
- * If you wish to alter the props applied to the `input` element, you can do so as follows:
1099
- *
1100
- * ```jsx
1101
- * const inputProps = {
1102
- * step: 300,
1103
- * };
1104
- *
1105
- * return <TextField id="time" type="time" inputProps={inputProps} />;
1106
- * ```
1107
- *
1108
- * For advanced cases, please look at the source of TextField by clicking on the
1109
- * "Edit this page" button above. Consider either:
1110
- *
1111
- * - using the upper case props for passing values directly to the components
1112
- * - using the underlying components directly as shown in the demos
1113
- */
1114
- const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
1115
- const props = useDefaultProps({
1116
- props: inProps,
1117
- name: 'MuiTextField'
1118
- });
1119
- const {
1120
- autoComplete,
1121
- autoFocus = false,
1122
- children,
1123
- className,
1124
- color = 'primary',
1125
- defaultValue,
1126
- disabled = false,
1127
- error = false,
1128
- FormHelperTextProps: FormHelperTextPropsProp,
1129
- fullWidth = false,
1130
- helperText,
1131
- id: idOverride,
1132
- InputLabelProps: InputLabelPropsProp,
1133
- inputProps: inputPropsProp,
1134
- InputProps: InputPropsProp,
1135
- inputRef,
1136
- label,
1137
- maxRows,
1138
- minRows,
1139
- multiline = false,
1140
- name,
1141
- onBlur,
1142
- onChange,
1143
- onFocus,
1144
- placeholder,
1145
- required = false,
1146
- rows,
1147
- select = false,
1148
- SelectProps: SelectPropsProp,
1149
- slots = {},
1150
- slotProps = {},
1151
- type,
1152
- value,
1153
- variant = 'outlined',
1154
- ...other
1155
- } = props;
1156
- const ownerState = {
1157
- ...props,
1158
- autoFocus,
1159
- color,
1160
- disabled,
1161
- error,
1162
- fullWidth,
1163
- multiline,
1164
- required,
1165
- select,
1166
- variant
1167
- };
1168
- const classes = useUtilityClasses(ownerState);
1169
- if (process.env.NODE_ENV !== 'production') {
1170
- if (select && !children) {
1171
- console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
1172
- }
1173
- }
1174
- const id = useId(idOverride);
1175
- const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
1176
- const inputLabelId = label && id ? `${id}-label` : undefined;
1177
- const InputComponent = variantComponent[variant];
1178
- const externalForwardedProps = {
1179
- slots,
1180
- slotProps: {
1181
- input: InputPropsProp,
1182
- inputLabel: InputLabelPropsProp,
1183
- htmlInput: inputPropsProp,
1184
- formHelperText: FormHelperTextPropsProp,
1185
- select: SelectPropsProp,
1186
- ...slotProps
1187
- }
1188
- };
1189
- const inputAdditionalProps = {};
1190
- const inputLabelSlotProps = externalForwardedProps.slotProps.inputLabel;
1191
- if (variant === 'outlined') {
1192
- if (inputLabelSlotProps && typeof inputLabelSlotProps.shrink !== 'undefined') {
1193
- inputAdditionalProps.notched = inputLabelSlotProps.shrink;
1194
- }
1195
- inputAdditionalProps.label = label;
1196
- }
1197
- if (select) {
1198
- // unset defaults from textbox inputs
1199
- if (!SelectPropsProp || !SelectPropsProp.native) {
1200
- inputAdditionalProps.id = undefined;
1201
- }
1202
- inputAdditionalProps['aria-describedby'] = undefined;
1203
- }
1204
- const [RootSlot, rootProps] = useSlot('root', {
1205
- elementType: TextFieldRoot,
1206
- shouldForwardComponentProp: true,
1207
- externalForwardedProps: {
1208
- ...externalForwardedProps,
1209
- ...other
1210
- },
1211
- ownerState,
1212
- className: clsx(classes.root, className),
1213
- ref,
1214
- additionalProps: {
1215
- disabled,
1216
- error,
1217
- fullWidth,
1218
- required,
1219
- color,
1220
- variant
1221
- }
1222
- });
1223
- const [InputSlot, inputProps] = useSlot('input', {
1224
- elementType: InputComponent,
1225
- externalForwardedProps,
1226
- additionalProps: inputAdditionalProps,
1227
- ownerState
1228
- });
1229
- const [InputLabelSlot, inputLabelProps] = useSlot('inputLabel', {
1230
- elementType: InputLabel$1,
1231
- externalForwardedProps,
1232
- ownerState
1233
- });
1234
- const [HtmlInputSlot, htmlInputProps] = useSlot('htmlInput', {
1235
- elementType: 'input',
1236
- externalForwardedProps,
1237
- ownerState
1238
- });
1239
- const [FormHelperTextSlot, formHelperTextProps] = useSlot('formHelperText', {
1240
- elementType: FormHelperText$1,
1241
- externalForwardedProps,
1242
- ownerState
1243
- });
1244
- const [SelectSlot, selectProps] = useSlot('select', {
1245
- elementType: Select,
1246
- externalForwardedProps,
1247
- ownerState
1248
- });
1249
- const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputSlot, {
1250
- "aria-describedby": helperTextId,
1251
- autoComplete: autoComplete,
1252
- autoFocus: autoFocus,
1253
- defaultValue: defaultValue,
1254
- fullWidth: fullWidth,
1255
- multiline: multiline,
1256
- name: name,
1257
- rows: rows,
1258
- maxRows: maxRows,
1259
- minRows: minRows,
1260
- type: type,
1261
- value: value,
1262
- id: id,
1263
- inputRef: inputRef,
1264
- onBlur: onBlur,
1265
- onChange: onChange,
1266
- onFocus: onFocus,
1267
- placeholder: placeholder,
1268
- inputProps: htmlInputProps,
1269
- slots: {
1270
- input: slots.htmlInput ? HtmlInputSlot : undefined
1271
- },
1272
- ...inputProps
1273
- });
1274
- return /*#__PURE__*/jsxRuntimeExports.jsxs(RootSlot, {
1275
- ...rootProps,
1276
- children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelSlot, {
1277
- htmlFor: id,
1278
- id: inputLabelId,
1279
- ...inputLabelProps,
1280
- children: label
1281
- }), select ? /*#__PURE__*/jsxRuntimeExports.jsx(SelectSlot, {
1282
- "aria-describedby": helperTextId,
1283
- id: id,
1284
- labelId: inputLabelId,
1285
- value: value,
1286
- input: InputElement,
1287
- ...selectProps,
1288
- children: children
1289
- }) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextSlot, {
1290
- id: helperTextId,
1291
- ...formHelperTextProps,
1292
- children: helperText
1293
- })]
1294
- });
1295
- });
1296
- process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
1297
- // ┌────────────────────────────── Warning ──────────────────────────────┐
1298
- // │ These PropTypes are generated from the TypeScript type definitions. │
1299
- // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
1300
- // └─────────────────────────────────────────────────────────────────────┘
1301
- /**
1302
- * This prop helps users to fill forms faster, especially on mobile devices.
1303
- * The name can be confusing, as it's more like an autofill.
1304
- * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
1305
- */
1306
- autoComplete: PropTypes.string,
1307
- /**
1308
- * If `true`, the `input` element is focused during the first mount.
1309
- * @default false
1310
- */
1311
- autoFocus: PropTypes.bool,
1312
- /**
1313
- * @ignore
1314
- */
1315
- children: PropTypes.node,
1316
- /**
1317
- * Override or extend the styles applied to the component.
1318
- */
1319
- classes: PropTypes.object,
1320
- /**
1321
- * @ignore
1322
- */
1323
- className: PropTypes.string,
1324
- /**
1325
- * The color of the component.
1326
- * It supports both default and custom theme colors, which can be added as shown in the
1327
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
1328
- * @default 'primary'
1329
- */
1330
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
1331
- /**
1332
- * The default value. Use when the component is not controlled.
1333
- */
1334
- defaultValue: PropTypes.any,
1335
- /**
1336
- * If `true`, the component is disabled.
1337
- * @default false
1338
- */
1339
- disabled: PropTypes.bool,
1340
- /**
1341
- * If `true`, the label is displayed in an error state.
1342
- * @default false
1343
- */
1344
- error: PropTypes.bool,
1345
- /**
1346
- * Props applied to the [`FormHelperText`](https://mui.com/material-ui/api/form-helper-text/) element.
1347
- * @deprecated Use `slotProps.formHelperText` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1348
- */
1349
- FormHelperTextProps: PropTypes.object,
1350
- /**
1351
- * If `true`, the input will take up the full width of its container.
1352
- * @default false
1353
- */
1354
- fullWidth: PropTypes.bool,
1355
- /**
1356
- * The helper text content.
1357
- */
1358
- helperText: PropTypes.node,
1359
- /**
1360
- * The id of the `input` element.
1361
- * Use this prop to make `label` and `helperText` accessible for screen readers.
1362
- */
1363
- id: PropTypes.string,
1364
- /**
1365
- * Props applied to the [`InputLabel`](https://mui.com/material-ui/api/input-label/) element.
1366
- * Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
1367
- * @deprecated Use `slotProps.inputLabel` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1368
- */
1369
- InputLabelProps: PropTypes.object,
1370
- /**
1371
- * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
1372
- * @deprecated Use `slotProps.htmlInput` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1373
- */
1374
- inputProps: PropTypes.object,
1375
- /**
1376
- * Props applied to the Input element.
1377
- * It will be a [`FilledInput`](https://mui.com/material-ui/api/filled-input/),
1378
- * [`OutlinedInput`](https://mui.com/material-ui/api/outlined-input/) or [`Input`](https://mui.com/material-ui/api/input/)
1379
- * component depending on the `variant` prop value.
1380
- * @deprecated Use `slotProps.input` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1381
- */
1382
- InputProps: PropTypes.object,
1383
- /**
1384
- * Pass a ref to the `input` element.
1385
- */
1386
- inputRef: refType,
1387
- /**
1388
- * The label content.
1389
- */
1390
- label: PropTypes.node,
1391
- /**
1392
- * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
1393
- * @default 'none'
1394
- */
1395
- margin: PropTypes.oneOf(['dense', 'none', 'normal']),
1396
- /**
1397
- * Maximum number of rows to display when multiline option is set to true.
1398
- */
1399
- maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1400
- /**
1401
- * Minimum number of rows to display when multiline option is set to true.
1402
- */
1403
- minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1404
- /**
1405
- * If `true`, a `textarea` element is rendered instead of an input.
1406
- * @default false
1407
- */
1408
- multiline: PropTypes.bool,
1409
- /**
1410
- * Name attribute of the `input` element.
1411
- */
1412
- name: PropTypes.string,
1413
- /**
1414
- * @ignore
1415
- */
1416
- onBlur: PropTypes.func,
1417
- /**
1418
- * Callback fired when the value is changed.
1419
- *
1420
- * @param {object} event The event source of the callback.
1421
- * You can pull out the new value by accessing `event.target.value` (string).
1422
- */
1423
- onChange: PropTypes.func,
1424
- /**
1425
- * @ignore
1426
- */
1427
- onFocus: PropTypes.func,
1428
- /**
1429
- * The short hint displayed in the `input` before the user enters a value.
1430
- */
1431
- placeholder: PropTypes.string,
1432
- /**
1433
- * If `true`, the label is displayed as required and the `input` element is required.
1434
- * @default false
1435
- */
1436
- required: PropTypes.bool,
1437
- /**
1438
- * Number of rows to display when multiline option is set to true.
1439
- */
1440
- rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1441
- /**
1442
- * Render a [`Select`](https://mui.com/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
1443
- * If this option is set you must pass the options of the select as children.
1444
- * @default false
1445
- */
1446
- select: PropTypes.bool,
1447
- /**
1448
- * Props applied to the [`Select`](https://mui.com/material-ui/api/select/) element.
1449
- * @deprecated Use `slotProps.select` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1450
- */
1451
- SelectProps: PropTypes.object,
1452
- /**
1453
- * The size of the component.
1454
- * @default 'medium'
1455
- */
1456
- size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
1457
- /**
1458
- * The props used for each slot inside.
1459
- * @default {}
1460
- */
1461
- slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
1462
- formHelperText: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1463
- htmlInput: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1464
- input: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1465
- inputLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1466
- select: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
1467
- }),
1468
- /**
1469
- * The components used for each slot inside.
1470
- * @default {}
1471
- */
1472
- slots: PropTypes.shape({
1473
- formHelperText: PropTypes.elementType,
1474
- htmlInput: PropTypes.elementType,
1475
- input: PropTypes.elementType,
1476
- inputLabel: PropTypes.elementType,
1477
- root: PropTypes.elementType,
1478
- select: PropTypes.elementType
1479
- }),
1480
- /**
1481
- * The system prop that allows defining system overrides as well as additional CSS styles.
1482
- */
1483
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1484
- /**
1485
- * Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
1486
- */
1487
- type: PropTypes /* @typescript-to-proptypes-ignore */.string,
1488
- /**
1489
- * The value of the `input` element, required for a controlled component.
1490
- */
1491
- value: PropTypes.any,
1492
- /**
1493
- * The variant to use.
1494
- * @default 'outlined'
1495
- */
1496
- variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
1497
- } : void 0;
1498
- var TextField$1 = TextField;
14
+ import { n as normalizeRowSelectionModel, o as onServerSideSelectionStatusChange, g as getSelectionCount, i as isRowSelected, S as ServerSideControlledPagination, C as ControlledPagination } from './ServerSideControlledPagination.js';
15
+ import { B as BaseButton, a as BaseCheckbox, c as BaseIconButton, b as BaseIcon } from './BaseIconButton.js';
1499
16
 
1500
17
  const SUBMIT_FILTER_STROKE_TIME = 500;
1501
18
  const InputNumberInterval = props => {
@@ -1537,7 +54,7 @@ const InputNumberInterval = props => {
1537
54
  const newLowerBound = event.target.value;
1538
55
  updateFilterValue(newLowerBound, filterValueState[1]);
1539
56
  };
1540
- return /*#__PURE__*/React.createElement(Box$1, {
57
+ return /*#__PURE__*/React.createElement(Box, {
1541
58
  sx: {
1542
59
  display: 'inline-flex',
1543
60
  flexDirection: 'row',
@@ -1545,7 +62,7 @@ const InputNumberInterval = props => {
1545
62
  height: 48,
1546
63
  pl: '20px'
1547
64
  }
1548
- }, /*#__PURE__*/React.createElement(TextField$1, {
65
+ }, /*#__PURE__*/React.createElement(TextField, {
1549
66
  name: "lower-bound-input",
1550
67
  placeholder: "From",
1551
68
  label: "From",
@@ -1557,7 +74,7 @@ const InputNumberInterval = props => {
1557
74
  sx: {
1558
75
  mr: 2
1559
76
  }
1560
- }), /*#__PURE__*/React.createElement(TextField$1, {
77
+ }), /*#__PURE__*/React.createElement(TextField, {
1561
78
  name: "upper-bound-input",
1562
79
  placeholder: "To",
1563
80
  label: "To",
@@ -2186,14 +703,20 @@ const DIMENSION_MODEL_KEY = 'dimension';
2186
703
  const FILTER_SEARCH_KEY = 'searchModel';
2187
704
  const DENSITY_MODEL_KEY = 'densityModel';
2188
705
  const COLUMN_ORDER_MODEL_KEY = 'columnOrderModel';
2189
- const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS, DENSITY_MODEL_KEY, COLUMN_ORDER_MODEL_KEY];
706
+ const ROW_GROUPING_MODEL_KEY = 'rowGroupingModel';
707
+ const AGGREGATION_MODEL_KEY = 'aggregationModel';
708
+ /** Storage category key for the pivot column/row/value configuration. Consumer interop — use with `buildStorageKey`. */
709
+ const PIVOT_MODEL_KEY = 'pivotModel';
710
+ /** Storage category key for whether pivoting is active. Consumer interop — use with `buildStorageKey`. */
711
+ const PIVOT_ACTIVE_KEY = 'pivotActive';
712
+ const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS, DENSITY_MODEL_KEY, COLUMN_ORDER_MODEL_KEY, ROW_GROUPING_MODEL_KEY, AGGREGATION_MODEL_KEY, PIVOT_MODEL_KEY, PIVOT_ACTIVE_KEY];
2190
713
  /**
2191
714
  * Build the localStorage key for a specific grid state category.
2192
715
  * Consumers can use this to read or clear individual state entries directly.
2193
716
  *
2194
717
  * @example
2195
718
  * ```ts
2196
- * const key = buildStorageKey({ id: pathname, version: 2, category: SORT_MODEL_KEY });
719
+ * const key = buildStorageKey({ id: pathname, version: 2, category: PIVOT_ACTIVE_KEY });
2197
720
  * localStorage.removeItem(key);
2198
721
  * ```
2199
722
  */
@@ -2243,6 +766,22 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
2243
766
  id,
2244
767
  version,
2245
768
  category: COLUMN_ORDER_MODEL_KEY
769
+ }), buildStorageKey({
770
+ id,
771
+ version,
772
+ category: ROW_GROUPING_MODEL_KEY
773
+ }), buildStorageKey({
774
+ id,
775
+ version,
776
+ category: AGGREGATION_MODEL_KEY
777
+ }), buildStorageKey({
778
+ id,
779
+ version,
780
+ category: PIVOT_MODEL_KEY
781
+ }), buildStorageKey({
782
+ id,
783
+ version,
784
+ category: PIVOT_ACTIVE_KEY
2246
785
  })];
2247
786
  for (const keyToDelete of keysToDelete) {
2248
787
  try {
@@ -2307,7 +846,7 @@ const COMPRESSED_PREFIX = '~';
2307
846
  * Params listed first are compressed first (least valuable to read in the URL).
2308
847
  * The filter aggregate step uses the special key `_filters_aggregate`.
2309
848
  */
2310
- const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_quickFilterValues'];
849
+ const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_aggregation', '_rowGrouping', '_quickFilterValues', '_pivot'];
2311
850
 
2312
851
  /** Params that are always short and should never be compressed. */
2313
852
  const NEVER_COMPRESS = new Set(['_sortColumn', '_pagination', '_density', '_logicOperator', 'v', 'tab']);
@@ -2385,7 +924,7 @@ const tryAggregateFilters = (params, filterKeys) => {
2385
924
  * Filter params are those that start with `_` but are not well-known system params.
2386
925
  */
2387
926
  const getFilterParamKeys = params => {
2388
- const systemPrefixes = ['_sortColumn', '_pagination', '_density', '_logicOperator', '_quickFilterValues', '_columnVisibility', '_columnOrder', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters'];
927
+ const systemPrefixes = ['_sortColumn', '_pagination', '_density', '_logicOperator', '_quickFilterValues', '_columnVisibility', '_columnOrder', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_rowGrouping', '_aggregation', '_pivot', '_filters'];
2389
928
  const filterKeys = [];
2390
929
  for (const key of params.keys()) {
2391
930
  if (!key.startsWith('_')) continue;
@@ -2615,6 +1154,21 @@ const convertToDisplayFormat = search => {
2615
1154
  return param;
2616
1155
  }
2617
1156
 
1157
+ // Handle _rowGrouping=[a,b,c]
1158
+ if (param.startsWith('_rowGrouping=')) {
1159
+ const value = param.slice('_rowGrouping='.length);
1160
+ if (value.startsWith('[') && value.endsWith(']')) {
1161
+ const inner = value.slice(1, -1);
1162
+ return `_rowGrouping=${inner}`;
1163
+ }
1164
+ return param;
1165
+ }
1166
+
1167
+ // _aggregation and _pivot do not use bracket notation — pass through
1168
+ if (param.startsWith('_aggregation=') || param.startsWith('_pivot=')) {
1169
+ return param;
1170
+ }
1171
+
2618
1172
  // Handle _field[operator,type]=value or _field[operator,type]=list[a,b,c]
2619
1173
  const bracketMatch = param.match(/^_([^[]+)\[([^\]]+)\]=(.*)$/);
2620
1174
  if (bracketMatch) {
@@ -2728,8 +1282,17 @@ const convertFromDisplayFormat = (search, columns) => {
2728
1282
  return `_columnOrder=[${value}]`;
2729
1283
  }
2730
1284
 
2731
- // _filters — pass through (no bracket conversion needed)
2732
- if (param.startsWith('_filters=')) {
1285
+ // Handle _rowGrouping=a,b,c
1286
+ if (param.startsWith('_rowGrouping=')) {
1287
+ const value = param.slice('_rowGrouping='.length);
1288
+ if (value.startsWith('[')) {
1289
+ return param;
1290
+ }
1291
+ return `_rowGrouping=[${value}]`;
1292
+ }
1293
+
1294
+ // _aggregation, _pivot, _filters — pass through (no bracket conversion needed)
1295
+ if (param.startsWith('_aggregation=') || param.startsWith('_pivot=') || param.startsWith('_filters=')) {
2733
1296
  return param;
2734
1297
  }
2735
1298
 
@@ -2776,8 +1339,9 @@ const getDecodedSearchFromUrl = (search, columns) => {
2776
1339
  const hasPinnedWithoutBrackets = /(_pinnedColumnsLeft|_pinnedColumnsRight)=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
2777
1340
  const hasVisibilityWithoutBrackets = /_columnVisibility=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
2778
1341
  const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1342
+ const hasRowGroupingWithoutBrackets = /_rowGrouping=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
2779
1343
  const hasBracketNotation = /\[.*\]=/.test(searchWithoutLeadingQuestion);
2780
- const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets) && !hasBracketNotation;
1344
+ const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets || hasRowGroupingWithoutBrackets) && !hasBracketNotation;
2781
1345
  if (isDisplayFormat) {
2782
1346
  return '?' + convertFromDisplayFormat(searchWithoutLeadingQuestion, columns);
2783
1347
  }
@@ -2902,11 +1466,16 @@ const isValueValid = (value, field, columns, operator) => {
2902
1466
  }
2903
1467
  const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
2904
1468
 
2905
- // Only date fails with 500s, other set themselves as undefined
2906
- if (type !== 'date') {
1469
+ // Only date and rating fail with 500s, other set themselves as undefined
1470
+ if (type !== 'date' && type !== 'rating') {
2907
1471
  return true;
2908
1472
  }
2909
1473
 
1474
+ // just checking that rating is a number.
1475
+ if (type === 'rating') {
1476
+ return !isNaN(Number(value));
1477
+ }
1478
+
2910
1479
  // format: YYYY-MM-DD
2911
1480
  // just verifying that the 3 values are numbers to avoid 500s,
2912
1481
  // If the value is invalid the form will appear as undefined
@@ -2933,7 +1502,7 @@ const getFilterModelFromString = (searchString, columns) => {
2933
1502
  let quickFilterValues = [];
2934
1503
  const searchParams = new URLSearchParams();
2935
1504
  for (const [key, value] of new URLSearchParams(searchString)) {
2936
- if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_density', '_filters'].includes(key)) {
1505
+ if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_rowGrouping', '_aggregation', '_pivot', '_density', '_filters'].includes(key)) {
2937
1506
  searchParams.set(key, value);
2938
1507
  }
2939
1508
  if (key === '_logicOperator') {
@@ -3482,7 +2051,275 @@ const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorag
3482
2051
  persistDefault();
3483
2052
  return defaultValue;
3484
2053
  };
3485
- const getFinalSearch = _ref => {
2054
+
2055
+ /** ROW GROUPING */
2056
+
2057
+ const getRowGroupingFromString = searchString => {
2058
+ if (!searchString) return 'invalid';
2059
+ const searchParams = new URLSearchParams(searchString);
2060
+ const value = searchParams.get('_rowGrouping');
2061
+ if (value === '' || value === null || value === '[]') return 'invalid';
2062
+ const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
2063
+ if (!inner) return 'invalid';
2064
+ return inner.split(',').filter(Boolean);
2065
+ };
2066
+ const getSearchParamsFromRowGrouping = rowGrouping => {
2067
+ const searchParams = new URLSearchParams();
2068
+ if (rowGrouping.length > 0) {
2069
+ searchParams.set('_rowGrouping', `[${rowGrouping.join(',')}]`);
2070
+ }
2071
+ return searchParams;
2072
+ };
2073
+ const getRowGroupingModel = (search, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion) => {
2074
+ var _initialState$rowGrou, _initialState$rowGrou2;
2075
+ const defaultValue = (_initialState$rowGrou = initialState === null || initialState === void 0 ? void 0 : (_initialState$rowGrou2 = initialState.rowGrouping) === null || _initialState$rowGrou2 === void 0 ? void 0 : _initialState$rowGrou2.model) !== null && _initialState$rowGrou !== void 0 ? _initialState$rowGrou : [];
2076
+ const persistDefault = () => {
2077
+ const searchFromDefault = getSearchParamsFromRowGrouping(defaultValue);
2078
+ const searchString = urlSearchParamsToString(searchFromDefault);
2079
+ if (searchString !== localStorageRowGrouping) {
2080
+ setLocalStorageRowGrouping(searchString);
2081
+ }
2082
+ };
2083
+ if (isNewVersion) {
2084
+ persistDefault();
2085
+ return defaultValue;
2086
+ }
2087
+ const fromUrl = getRowGroupingFromString(search);
2088
+ if (fromUrl !== 'invalid') {
2089
+ const searchFromModel = getSearchParamsFromRowGrouping(fromUrl);
2090
+ const searchString = urlSearchParamsToString(searchFromModel);
2091
+ if (searchString !== localStorageRowGrouping) {
2092
+ setLocalStorageRowGrouping(searchString);
2093
+ }
2094
+ return fromUrl;
2095
+ }
2096
+ const fromLocalStorage = getRowGroupingFromString(localStorageRowGrouping);
2097
+ if (fromLocalStorage !== 'invalid') {
2098
+ return fromLocalStorage;
2099
+ }
2100
+ persistDefault();
2101
+ return defaultValue;
2102
+ };
2103
+
2104
+ /** AGGREGATION */
2105
+
2106
+ const getAggregationFromString = searchString => {
2107
+ if (!searchString) return 'invalid';
2108
+ const searchParams = new URLSearchParams(searchString);
2109
+ const value = searchParams.get('_aggregation');
2110
+ if (value === '' || value === null) return 'invalid';
2111
+
2112
+ // Format: field1.sum,field2.avg or [field1.sum,field2.avg]
2113
+ const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
2114
+ if (!inner) return 'invalid';
2115
+ const model = {};
2116
+ for (const entry of inner.split(',')) {
2117
+ const dotIndex = entry.lastIndexOf('.');
2118
+ if (dotIndex <= 0) return 'invalid';
2119
+ const field = entry.slice(0, dotIndex);
2120
+ const aggFunc = entry.slice(dotIndex + 1);
2121
+ if (!field || !aggFunc) return 'invalid';
2122
+ model[field] = aggFunc;
2123
+ }
2124
+ return Object.keys(model).length > 0 ? model : 'invalid';
2125
+ };
2126
+ const getSearchParamsFromAggregation = aggregation => {
2127
+ const searchParams = new URLSearchParams();
2128
+ const entries = Object.entries(aggregation);
2129
+ if (entries.length > 0) {
2130
+ const value = entries.map(_ref => {
2131
+ let [field, aggFunc] = _ref;
2132
+ return `${field}.${aggFunc}`;
2133
+ }).join(',');
2134
+ searchParams.set('_aggregation', value);
2135
+ }
2136
+ return searchParams;
2137
+ };
2138
+ const getAggregationModel = (search, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion) => {
2139
+ var _initialState$aggrega, _initialState$aggrega2;
2140
+ const defaultValue = (_initialState$aggrega = initialState === null || initialState === void 0 ? void 0 : (_initialState$aggrega2 = initialState.aggregation) === null || _initialState$aggrega2 === void 0 ? void 0 : _initialState$aggrega2.model) !== null && _initialState$aggrega !== void 0 ? _initialState$aggrega : {};
2141
+ const persistDefault = () => {
2142
+ const searchFromDefault = getSearchParamsFromAggregation(defaultValue);
2143
+ const searchString = urlSearchParamsToString(searchFromDefault);
2144
+ if (searchString !== localStorageAggregation) {
2145
+ setLocalStorageAggregation(searchString);
2146
+ }
2147
+ };
2148
+ if (isNewVersion) {
2149
+ persistDefault();
2150
+ return defaultValue;
2151
+ }
2152
+ const fromUrl = getAggregationFromString(search);
2153
+ if (fromUrl !== 'invalid') {
2154
+ const searchFromModel = getSearchParamsFromAggregation(fromUrl);
2155
+ const searchString = urlSearchParamsToString(searchFromModel);
2156
+ if (searchString !== localStorageAggregation) {
2157
+ setLocalStorageAggregation(searchString);
2158
+ }
2159
+ return fromUrl;
2160
+ }
2161
+ const fromLocalStorage = getAggregationFromString(localStorageAggregation);
2162
+ if (fromLocalStorage !== 'invalid') {
2163
+ return fromLocalStorage;
2164
+ }
2165
+ persistDefault();
2166
+ return defaultValue;
2167
+ };
2168
+
2169
+ /** PIVOT */
2170
+
2171
+ /** Convert MUI's GridPivotModel → our simplified PivotModel */
2172
+ const fromGridPivotModel = model => ({
2173
+ columns: model.columns.map(c => c.field),
2174
+ rows: model.rows.map(r => r.field),
2175
+ values: model.values.map(_ref2 => {
2176
+ let {
2177
+ field,
2178
+ aggFunc
2179
+ } = _ref2;
2180
+ return {
2181
+ field,
2182
+ aggFunc
2183
+ };
2184
+ })
2185
+ });
2186
+
2187
+ /**
2188
+ * Pivot format: `cols:f1,f2;rows:f3;vals:f4.sum,f5.avg`
2189
+ */
2190
+ const getPivotFromString = searchString => {
2191
+ if (!searchString) return 'invalid';
2192
+ const searchParams = new URLSearchParams(searchString);
2193
+ const value = searchParams.get('_pivot');
2194
+ if (value === '' || value === null) return 'invalid';
2195
+ const model = {
2196
+ columns: [],
2197
+ rows: [],
2198
+ values: []
2199
+ };
2200
+ for (const segment of value.split(';')) {
2201
+ const colonIndex = segment.indexOf(':');
2202
+ if (colonIndex <= 0) return 'invalid';
2203
+ const key = segment.slice(0, colonIndex);
2204
+ const content = segment.slice(colonIndex + 1);
2205
+ if (key === 'cols') {
2206
+ model.columns = content ? content.split(',').filter(Boolean) : [];
2207
+ } else if (key === 'rows') {
2208
+ model.rows = content ? content.split(',').filter(Boolean) : [];
2209
+ } else if (key === 'vals') {
2210
+ if (!content) continue;
2211
+ for (const entry of content.split(',')) {
2212
+ const dotIndex = entry.lastIndexOf('.');
2213
+ if (dotIndex <= 0) return 'invalid';
2214
+ model.values.push({
2215
+ field: entry.slice(0, dotIndex),
2216
+ aggFunc: entry.slice(dotIndex + 1)
2217
+ });
2218
+ }
2219
+ }
2220
+ }
2221
+
2222
+ // At least one section must have content
2223
+ if (model.columns.length === 0 && model.rows.length === 0 && model.values.length === 0) {
2224
+ return 'invalid';
2225
+ }
2226
+ return model;
2227
+ };
2228
+ const getSearchParamsFromPivot = pivot => {
2229
+ const searchParams = new URLSearchParams();
2230
+ const hasContent = pivot.columns.length > 0 || pivot.rows.length > 0 || pivot.values.length > 0;
2231
+ if (hasContent) {
2232
+ const parts = [];
2233
+ parts.push(`cols:${pivot.columns.join(',')}`);
2234
+ parts.push(`rows:${pivot.rows.join(',')}`);
2235
+ if (pivot.values.length > 0) {
2236
+ parts.push(`vals:${pivot.values.map(v => `${v.field}.${v.aggFunc}`).join(',')}`);
2237
+ }
2238
+ searchParams.set('_pivot', parts.join(';'));
2239
+ }
2240
+ return searchParams;
2241
+ };
2242
+ const getPivotModel = (search, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion) => {
2243
+ var _initialState$pivotin;
2244
+ const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$pivotin = initialState.pivoting) !== null && _initialState$pivotin !== void 0 && _initialState$pivotin.model ? fromGridPivotModel(initialState.pivoting.model) : {
2245
+ columns: [],
2246
+ rows: [],
2247
+ values: []
2248
+ };
2249
+ const persistDefault = () => {
2250
+ const searchFromDefault = getSearchParamsFromPivot(defaultValue);
2251
+ const searchString = urlSearchParamsToString(searchFromDefault);
2252
+ if (searchString !== localStoragePivot) {
2253
+ setLocalStoragePivot(searchString);
2254
+ }
2255
+ };
2256
+ if (isNewVersion) {
2257
+ persistDefault();
2258
+ return defaultValue;
2259
+ }
2260
+ const fromUrl = getPivotFromString(search);
2261
+ if (fromUrl !== 'invalid') {
2262
+ const searchFromModel = getSearchParamsFromPivot(fromUrl);
2263
+ const searchString = urlSearchParamsToString(searchFromModel);
2264
+ if (searchString !== localStoragePivot) {
2265
+ setLocalStoragePivot(searchString);
2266
+ }
2267
+ return fromUrl;
2268
+ }
2269
+ const fromLocalStorage = getPivotFromString(localStoragePivot);
2270
+ if (fromLocalStorage !== 'invalid') {
2271
+ return fromLocalStorage;
2272
+ }
2273
+ persistDefault();
2274
+ return defaultValue;
2275
+ };
2276
+
2277
+ /** PIVOT ACTIVE */
2278
+
2279
+ const getPivotActiveFromString = searchString => {
2280
+ if (!searchString) return 'invalid';
2281
+ const searchParams = new URLSearchParams(searchString);
2282
+ const value = searchParams.get('_pivotActive');
2283
+ if (value === 'true') return true;
2284
+ if (value === 'false') return false;
2285
+ return 'invalid';
2286
+ };
2287
+ const getSearchParamsFromPivotActive = active => {
2288
+ const searchParams = new URLSearchParams();
2289
+ searchParams.set('_pivotActive', String(active));
2290
+ return searchParams;
2291
+ };
2292
+ const getPivotActive = (search, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion) => {
2293
+ var _initialState$pivotin2, _initialState$pivotin3;
2294
+ const defaultValue = (_initialState$pivotin2 = initialState === null || initialState === void 0 ? void 0 : (_initialState$pivotin3 = initialState.pivoting) === null || _initialState$pivotin3 === void 0 ? void 0 : _initialState$pivotin3.enabled) !== null && _initialState$pivotin2 !== void 0 ? _initialState$pivotin2 : false;
2295
+ const persistDefault = () => {
2296
+ const searchFromDefault = getSearchParamsFromPivotActive(defaultValue);
2297
+ const searchString = urlSearchParamsToString(searchFromDefault);
2298
+ if (searchString !== localStoragePivotActive) {
2299
+ setLocalStoragePivotActive(searchString);
2300
+ }
2301
+ };
2302
+ if (isNewVersion) {
2303
+ persistDefault();
2304
+ return defaultValue;
2305
+ }
2306
+ const fromUrl = getPivotActiveFromString(search);
2307
+ if (fromUrl !== 'invalid') {
2308
+ const searchFromModel = getSearchParamsFromPivotActive(fromUrl);
2309
+ const searchString = urlSearchParamsToString(searchFromModel);
2310
+ if (searchString !== localStoragePivotActive) {
2311
+ setLocalStoragePivotActive(searchString);
2312
+ }
2313
+ return fromUrl;
2314
+ }
2315
+ const fromLocalStorage = getPivotActiveFromString(localStoragePivotActive);
2316
+ if (fromLocalStorage !== 'invalid') {
2317
+ return fromLocalStorage;
2318
+ }
2319
+ persistDefault();
2320
+ return defaultValue;
2321
+ };
2322
+ const getFinalSearch = _ref3 => {
3486
2323
  let {
3487
2324
  search,
3488
2325
  localStorageVersion,
@@ -3494,8 +2331,12 @@ const getFinalSearch = _ref => {
3494
2331
  density,
3495
2332
  columnOrderModel,
3496
2333
  defaultColumnOrder,
2334
+ rowGroupingModel,
2335
+ aggregationModel,
2336
+ pivotModel,
2337
+ pivotActive,
3497
2338
  columns
3498
- } = _ref;
2339
+ } = _ref3;
3499
2340
  const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
3500
2341
  const sortModelSearch = getSearchParamsFromSorting(sortModel);
3501
2342
  const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
@@ -3504,6 +2345,10 @@ const getFinalSearch = _ref => {
3504
2345
  const densitySearch = getSearchParamsFromDensity(density);
3505
2346
  // Only include _columnOrder in URL when it differs from the default
3506
2347
  const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
2348
+ const rowGroupingSearch = getSearchParamsFromRowGrouping(rowGroupingModel);
2349
+ const aggregationSearch = getSearchParamsFromAggregation(aggregationModel);
2350
+ const pivotSearch = getSearchParamsFromPivot(pivotModel);
2351
+ const pivotActiveSearch = getSearchParamsFromPivotActive(pivotActive);
3507
2352
  const tabSearch = getSearchParamsFromTab(search);
3508
2353
  const searchParams = new URLSearchParams();
3509
2354
  for (const [key, value] of new URLSearchParams(search)) {
@@ -3518,7 +2363,7 @@ const getFinalSearch = _ref => {
3518
2363
  // Encode array as JSON string to preserve all values in one param
3519
2364
  searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
3520
2365
  }
3521
- return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch]);
2366
+ return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch, ...rowGroupingSearch, ...aggregationSearch, ...pivotSearch, ...pivotActiveSearch]);
3522
2367
  };
3523
2368
  /** Return the state of the table given the URL and the local storage state */
3524
2369
  const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage) => {
@@ -3543,7 +2388,15 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
3543
2388
  localStorageDensity,
3544
2389
  setLocalStorageDensity,
3545
2390
  localStorageColumnOrder,
3546
- setLocalStorageColumnOrder
2391
+ setLocalStorageColumnOrder,
2392
+ localStorageRowGrouping,
2393
+ setLocalStorageRowGrouping,
2394
+ localStorageAggregation,
2395
+ setLocalStorageAggregation,
2396
+ localStoragePivot,
2397
+ setLocalStoragePivot,
2398
+ localStoragePivotActive,
2399
+ setLocalStoragePivotActive
3547
2400
  } = localStorage;
3548
2401
  const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
3549
2402
  const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
@@ -3552,6 +2405,10 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
3552
2405
  const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
3553
2406
  const density = getDensityModel(decodedSearch, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion);
3554
2407
  const columnOrderModel = getColumnOrder(decodedSearch, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion);
2408
+ const rowGroupingModel = getRowGroupingModel(decodedSearch, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion);
2409
+ const aggregationModel = getAggregationModel(decodedSearch, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion);
2410
+ const pivotModel = getPivotModel(decodedSearch, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion);
2411
+ const pivotActive = getPivotActive(decodedSearch, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion);
3555
2412
  const defaultColumnOrder = (_initialState$columns6 = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns7 = initialState.columns) === null || _initialState$columns7 === void 0 ? void 0 : _initialState$columns7.orderedFields) !== null && _initialState$columns6 !== void 0 ? _initialState$columns6 : columns.map(c => c.field);
3556
2413
  const finalSearch = getFinalSearch({
3557
2414
  localStorageVersion,
@@ -3564,6 +2421,10 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
3564
2421
  density,
3565
2422
  columnOrderModel,
3566
2423
  defaultColumnOrder,
2424
+ rowGroupingModel,
2425
+ aggregationModel,
2426
+ pivotModel,
2427
+ pivotActive,
3567
2428
  columns
3568
2429
  });
3569
2430
  const internalSearchString = urlSearchParamsToString(finalSearch);
@@ -3584,10 +2445,14 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
3584
2445
  pinnedColumnsModel,
3585
2446
  density,
3586
2447
  columnOrderModel,
2448
+ rowGroupingModel,
2449
+ aggregationModel,
2450
+ pivotModel,
2451
+ pivotActive,
3587
2452
  pendingSearch
3588
2453
  };
3589
2454
  };
3590
- const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns) => {
2455
+ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
3591
2456
  let {
3592
2457
  filterModel,
3593
2458
  sortModel,
@@ -3596,8 +2461,12 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
3596
2461
  pinnedColumnsModel,
3597
2462
  density,
3598
2463
  columnOrderModel,
3599
- defaultColumnOrder
3600
- } = _ref2;
2464
+ defaultColumnOrder,
2465
+ rowGroupingModel,
2466
+ aggregationModel,
2467
+ pivotModel,
2468
+ pivotActive
2469
+ } = _ref4;
3601
2470
  // Convert from display format to internal format if needed
3602
2471
  const decodedSearch = getDecodedSearchFromUrl(search, columns);
3603
2472
  const newSearch = getFinalSearch({
@@ -3611,6 +2480,10 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
3611
2480
  density,
3612
2481
  columnOrderModel,
3613
2482
  defaultColumnOrder,
2483
+ rowGroupingModel,
2484
+ aggregationModel,
2485
+ pivotModel,
2486
+ pivotActive,
3614
2487
  columns
3615
2488
  });
3616
2489
  const internalSearchString = urlSearchParamsToString(newSearch);
@@ -3798,6 +2671,26 @@ const useTableStates = (id, version) => {
3798
2671
  version,
3799
2672
  category: COLUMN_ORDER_MODEL_KEY
3800
2673
  }));
2674
+ const [rowGroupingModel, setRowGroupingModel] = useFetchState('', buildStorageKey({
2675
+ id,
2676
+ version,
2677
+ category: ROW_GROUPING_MODEL_KEY
2678
+ }));
2679
+ const [aggregationModel, setAggregationModel] = useFetchState('', buildStorageKey({
2680
+ id,
2681
+ version,
2682
+ category: AGGREGATION_MODEL_KEY
2683
+ }));
2684
+ const [pivotModel, setPivotModel] = useFetchState('', buildStorageKey({
2685
+ id,
2686
+ version,
2687
+ category: PIVOT_MODEL_KEY
2688
+ }));
2689
+ const [pivotActive, setPivotActive] = useFetchState('', buildStorageKey({
2690
+ id,
2691
+ version,
2692
+ category: PIVOT_ACTIVE_KEY
2693
+ }));
3801
2694
  return {
3802
2695
  paginationModel,
3803
2696
  setPaginationModel,
@@ -3814,13 +2707,41 @@ const useTableStates = (id, version) => {
3814
2707
  densityModel,
3815
2708
  setDensityModel,
3816
2709
  columnOrderModel,
3817
- setColumnOrderModel
2710
+ setColumnOrderModel,
2711
+ rowGroupingModel,
2712
+ setRowGroupingModel,
2713
+ aggregationModel,
2714
+ setAggregationModel,
2715
+ pivotModel,
2716
+ setPivotModel,
2717
+ pivotActive,
2718
+ setPivotActive
3818
2719
  };
3819
2720
  };
3820
2721
 
2722
+ /** Convert our simplified PivotModel → MUI's GridPivotModel */
2723
+ const toGridPivotModel = model => ({
2724
+ columns: model.columns.map(field => ({
2725
+ field
2726
+ })),
2727
+ rows: model.rows.map(field => ({
2728
+ field
2729
+ })),
2730
+ values: model.values.map(_ref => {
2731
+ let {
2732
+ field,
2733
+ aggFunc
2734
+ } = _ref;
2735
+ return {
2736
+ field,
2737
+ aggFunc
2738
+ };
2739
+ })
2740
+ });
2741
+
3821
2742
  /**
3822
2743
  * Deep-equal comparison for plain objects / arrays.
3823
- * Used to stabilise parsed model references so that MUI does not
2744
+ * Used to stabilise parsed model references so that MUI v8 does not
3824
2745
  * reset pagination on every render.
3825
2746
  */
3826
2747
  function isDeepEqual(a, b) {
@@ -3847,6 +2768,9 @@ const useStatefulTable = props => {
3847
2768
  onPaginationModelChange: propsOnPaginationModelChange,
3848
2769
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
3849
2770
  onSortModelChange: propsOnSortModelChange,
2771
+ onRowGroupingModelChange: propsOnRowGroupingModelChange,
2772
+ onAggregationModelChange: propsOnAggregationModelChange,
2773
+ onPivotModelChange: propsOnPivotModelChange,
3850
2774
  useRouter,
3851
2775
  localStorageVersion = 1,
3852
2776
  previousLocalStorageVersions = []
@@ -3875,16 +2799,24 @@ const useStatefulTable = props => {
3875
2799
  densityModel,
3876
2800
  setDensityModel,
3877
2801
  columnOrderModel: localStorageColumnOrder,
3878
- setColumnOrderModel: setLocalStorageColumnOrder
2802
+ setColumnOrderModel: setLocalStorageColumnOrder,
2803
+ rowGroupingModel: localStorageRowGrouping,
2804
+ setRowGroupingModel: setLocalStorageRowGrouping,
2805
+ aggregationModel: localStorageAggregation,
2806
+ setAggregationModel: setLocalStorageAggregation,
2807
+ pivotModel: localStoragePivot,
2808
+ setPivotModel: setLocalStoragePivot,
2809
+ pivotActive: localStoragePivotActive,
2810
+ setPivotActive: setLocalStoragePivotActive
3879
2811
  } = useTableStates(id, localStorageVersion);
3880
2812
 
3881
2813
  // clearing up old version keys, triggering only on first render
3882
2814
  useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
3883
- const onColumnDimensionChange = useCallback(_ref => {
2815
+ const onColumnDimensionChange = useCallback(_ref2 => {
3884
2816
  let {
3885
2817
  newWidth,
3886
2818
  field
3887
- } = _ref;
2819
+ } = _ref2;
3888
2820
  setDimensionModel(_objectSpread2(_objectSpread2({}, dimensionModel), {}, {
3889
2821
  [field]: newWidth
3890
2822
  }));
@@ -3897,6 +2829,10 @@ const useStatefulTable = props => {
3897
2829
  pinnedColumnsModel,
3898
2830
  density: densityParsed,
3899
2831
  columnOrderModel: columnOrderParsed,
2832
+ rowGroupingModel: rowGroupingParsed,
2833
+ aggregationModel: aggregationParsed,
2834
+ pivotModel: pivotParsed,
2835
+ pivotActive: pivotActiveParsed,
3900
2836
  pendingSearch
3901
2837
  } = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, initialState, {
3902
2838
  localStorageFilters,
@@ -3912,7 +2848,15 @@ const useStatefulTable = props => {
3912
2848
  localStorageDensity: densityModel,
3913
2849
  setLocalStorageDensity: setDensityModel,
3914
2850
  localStorageColumnOrder,
3915
- setLocalStorageColumnOrder
2851
+ setLocalStorageColumnOrder,
2852
+ localStorageRowGrouping,
2853
+ setLocalStorageRowGrouping,
2854
+ localStorageAggregation,
2855
+ setLocalStorageAggregation,
2856
+ localStoragePivot,
2857
+ setLocalStoragePivot,
2858
+ localStoragePivotActive: localStoragePivotActive,
2859
+ setLocalStoragePivotActive: setLocalStoragePivotActive
3916
2860
  });
3917
2861
 
3918
2862
  // Sync URL in an effect rather than during render to comply with React rules
@@ -3922,7 +2866,7 @@ const useStatefulTable = props => {
3922
2866
  }
3923
2867
  }, [pendingSearch, historyReplace]);
3924
2868
 
3925
- // Stabilise parsed model references to prevent MUI from resetting
2869
+ // Stabilise parsed model references to prevent MUI v8 from resetting
3926
2870
  // pagination on every render due to new object identity.
3927
2871
  const filterParsedRef = useRef(filterParsed);
3928
2872
  if (!isDeepEqual(filterParsedRef.current, filterParsed)) {
@@ -3948,6 +2892,18 @@ const useStatefulTable = props => {
3948
2892
  if (!isDeepEqual(columnOrderParsedRef.current, columnOrderParsed)) {
3949
2893
  columnOrderParsedRef.current = columnOrderParsed;
3950
2894
  }
2895
+ const rowGroupingParsedRef = useRef(rowGroupingParsed);
2896
+ if (!isDeepEqual(rowGroupingParsedRef.current, rowGroupingParsed)) {
2897
+ rowGroupingParsedRef.current = rowGroupingParsed;
2898
+ }
2899
+ const aggregationParsedRef = useRef(aggregationParsed);
2900
+ if (!isDeepEqual(aggregationParsedRef.current, aggregationParsed)) {
2901
+ aggregationParsedRef.current = aggregationParsed;
2902
+ }
2903
+ const pivotParsedRef = useRef(pivotParsed);
2904
+ if (!isDeepEqual(pivotParsedRef.current, pivotParsed)) {
2905
+ pivotParsedRef.current = pivotParsed;
2906
+ }
3951
2907
  const columns = useMemo(() => propsColumns.map(column => {
3952
2908
  return _objectSpread2(_objectSpread2({}, column), {}, {
3953
2909
  width: dimensionModel[column.field] || column.width || 100
@@ -3956,29 +2912,13 @@ const useStatefulTable = props => {
3956
2912
  if (apiRef.current) {
3957
2913
  /** Add resetPage method to apiRef. */
3958
2914
  apiRef.current.resetPage = () => {
3959
- apiRef.current.setPage(0);
2915
+ var _apiRef$current;
2916
+ (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPage(0);
3960
2917
  };
3961
2918
  }
3962
2919
  const defaultColumnOrder = (_initialState$columns = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns2 = initialState.columns) === null || _initialState$columns2 === void 0 ? void 0 : _initialState$columns2.orderedFields) !== null && _initialState$columns !== void 0 ? _initialState$columns : propsColumns.map(c => c.field);
3963
2920
 
3964
- // Helper to build the current DataGridModel for updateUrl calls
3965
- const buildModel = function () {
3966
- var _apiRef$current$state, _apiRef$current;
3967
- let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3968
- return _objectSpread2({
3969
- filterModel: filterParsed,
3970
- sortModel: sortModelParsed,
3971
- paginationModel: paginationModelParsed,
3972
- columnsModel: (_apiRef$current$state = (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.state.columns.columnVisibilityModel) !== null && _apiRef$current$state !== void 0 ? _apiRef$current$state : {},
3973
- pinnedColumnsModel: pinnedColumnsModel,
3974
- density: densityParsed,
3975
- columnOrderModel: columnOrderParsed,
3976
- defaultColumnOrder
3977
- }, overrides);
3978
- };
3979
-
3980
- // Subscribe to density changes via stateChange event
3981
- // (MUI v7 supports onDensityChange, but stateChange works and avoids a larger refactor)
2921
+ // Subscribe to density changes via stateChange event (MUI v6 has no densityChange event)
3982
2922
  useEffect(() => {
3983
2923
  const api = apiRef.current;
3984
2924
  if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
@@ -3987,14 +2927,24 @@ const useStatefulTable = props => {
3987
2927
  const currentDensity = api.state.density;
3988
2928
  if (currentDensity !== prevDensity) {
3989
2929
  prevDensity = currentDensity;
3990
- updateUrl(buildModel({
2930
+ updateUrl({
2931
+ filterModel: filterParsed,
2932
+ sortModel: sortModelParsed,
2933
+ paginationModel: paginationModelParsed,
3991
2934
  columnsModel: api.state.columns.columnVisibilityModel,
3992
- density: currentDensity
3993
- }), search, localStorageVersion, historyReplace, columns);
2935
+ pinnedColumnsModel: pinnedColumnsModel,
2936
+ density: currentDensity,
2937
+ columnOrderModel: columnOrderParsed,
2938
+ defaultColumnOrder,
2939
+ rowGroupingModel: rowGroupingParsed,
2940
+ aggregationModel: aggregationParsed,
2941
+ pivotModel: pivotParsed,
2942
+ pivotActive: pivotActiveParsed
2943
+ }, search, localStorageVersion, historyReplace, columns);
3994
2944
  }
3995
2945
  });
3996
2946
  return unsub;
3997
- }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, search, localStorageVersion, historyReplace, columns]);
2947
+ }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
3998
2948
 
3999
2949
  // Subscribe to column order changes via columnOrderChange (drag-drop) and columnIndexChange (programmatic setColumnIndex)
4000
2950
  useEffect(() => {
@@ -4003,9 +2953,20 @@ const useStatefulTable = props => {
4003
2953
  const handleColumnOrderChange = () => {
4004
2954
  const orderedFields = api.state.columns.orderedFields;
4005
2955
  if (orderedFields && !isDeepEqual(orderedFields, columnOrderParsed)) {
4006
- updateUrl(buildModel({
4007
- columnOrderModel: orderedFields
4008
- }), search, localStorageVersion, historyReplace, columns);
2956
+ updateUrl({
2957
+ filterModel: filterParsed,
2958
+ sortModel: sortModelParsed,
2959
+ paginationModel: paginationModelParsed,
2960
+ columnsModel: api.state.columns.columnVisibilityModel,
2961
+ pinnedColumnsModel,
2962
+ density: densityParsed,
2963
+ columnOrderModel: orderedFields,
2964
+ defaultColumnOrder,
2965
+ rowGroupingModel: rowGroupingParsed,
2966
+ aggregationModel: aggregationParsed,
2967
+ pivotModel: pivotParsed,
2968
+ pivotActive: pivotActiveParsed
2969
+ }, search, localStorageVersion, historyReplace, columns);
4009
2970
  }
4010
2971
  };
4011
2972
  const unsub1 = api.subscribeEvent('columnOrderChange', handleColumnOrderChange);
@@ -4014,28 +2975,53 @@ const useStatefulTable = props => {
4014
2975
  unsub1();
4015
2976
  unsub2();
4016
2977
  };
4017
- }, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, search, localStorageVersion, historyReplace, columns]);
2978
+ }, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
2979
+
2980
+ // Helper to build the current DataGridModel for updateUrl calls
2981
+ const buildModel = function () {
2982
+ var _apiRef$current$state, _apiRef$current2;
2983
+ let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2984
+ return _objectSpread2({
2985
+ filterModel: filterParsed,
2986
+ sortModel: sortModelParsed,
2987
+ paginationModel: paginationModelParsed,
2988
+ columnsModel: (_apiRef$current$state = (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.state.columns.columnVisibilityModel) !== null && _apiRef$current$state !== void 0 ? _apiRef$current$state : {},
2989
+ pinnedColumnsModel: pinnedColumnsModel,
2990
+ density: densityParsed,
2991
+ columnOrderModel: columnOrderParsed,
2992
+ defaultColumnOrder,
2993
+ rowGroupingModel: rowGroupingParsed,
2994
+ aggregationModel: aggregationParsed,
2995
+ pivotModel: pivotParsed,
2996
+ pivotActive: pivotActiveParsed
2997
+ }, overrides);
2998
+ };
2999
+
3000
+ // Stable GridPivotModel identity — only recompute when the simplified value changes.
3001
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3002
+ const pivotModelMui = useMemo(() => toGridPivotModel(pivotParsed), [JSON.stringify(pivotParsed)]);
4018
3003
 
4019
3004
  // Track last emitted values for deep-equal guards to avoid feedback loops.
4020
3005
  // Initialised from the current parsed values; updated only when we actually fire.
4021
3006
  const lastEmittedFilterRef = useRef(filterParsed);
4022
3007
  const lastEmittedSortRef = useRef(sortModelParsed);
4023
3008
  const lastEmittedPaginationRef = useRef(paginationModelParsed);
3009
+ const lastEmittedPivotRef = useRef(pivotParsed);
4024
3010
  return {
4025
3011
  apiRef,
4026
3012
  columns,
4027
3013
  density: densityParsed,
4028
- onDensityChange: newDensity => {
4029
- updateUrl(buildModel({
4030
- density: newDensity
4031
- }), search, localStorageVersion, historyReplace, columns);
4032
- },
4033
3014
  columnOrderModel: columnOrderParsedRef.current,
3015
+ rowGroupingModel: rowGroupingParsedRef.current,
3016
+ aggregationModel: aggregationParsedRef.current,
3017
+ pivotModel: pivotModelMui,
3018
+ pivotActive: pivotActiveParsed,
4034
3019
  onFilterModelChange: (model, details) => {
4035
3020
  const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
4036
3021
  items: model.items.map(item => {
4037
- const column = apiRef.current.getColumn(item.field);
4038
- item.type = column.type || 'string';
3022
+ var _apiRef$current3;
3023
+ const column = (_apiRef$current3 = apiRef.current) === null || _apiRef$current3 === void 0 ? void 0 : _apiRef$current3.getColumn(item.field);
3024
+ item.type = (column === null || column === void 0 ? void 0 : column.type) || 'string';
4039
3025
  return item;
4040
3026
  }),
4041
3027
  quickFilterValues: model.quickFilterValues || []
@@ -4058,10 +3044,10 @@ const useStatefulTable = props => {
4058
3044
  },
4059
3045
  sortModel: sortModelParsedRef.current,
4060
3046
  onPinnedColumnsChange: (pinnedColumns, details) => {
4061
- propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
4062
3047
  updateUrl(buildModel({
4063
3048
  pinnedColumnsModel: pinnedColumns
4064
3049
  }), search, localStorageVersion, historyReplace, columns);
3050
+ propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
4065
3051
  },
4066
3052
  pinnedColumns: pinnedColumnsModelRef.current,
4067
3053
  paginationModel: paginationModelParsedRef.current,
@@ -4078,10 +3064,10 @@ const useStatefulTable = props => {
4078
3064
  },
4079
3065
  columnVisibilityModel: visibilityModelRef.current,
4080
3066
  onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
4081
- propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
4082
3067
  updateUrl(buildModel({
4083
3068
  columnsModel: columnsVisibilityModel
4084
3069
  }), search, localStorageVersion, historyReplace, columns);
3070
+ propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
4085
3071
  },
4086
3072
  onColumnWidthChange: (params, event, details) => {
4087
3073
  propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
@@ -4089,11 +3075,38 @@ const useStatefulTable = props => {
4089
3075
  newWidth: params.width,
4090
3076
  field: params.colDef.field
4091
3077
  });
3078
+ },
3079
+ onRowGroupingModelChange: (model, details) => {
3080
+ updateUrl(buildModel({
3081
+ rowGroupingModel: model
3082
+ }), search, localStorageVersion, historyReplace, columns);
3083
+ propsOnRowGroupingModelChange === null || propsOnRowGroupingModelChange === void 0 ? void 0 : propsOnRowGroupingModelChange(model, details);
3084
+ },
3085
+ onAggregationModelChange: (model, details) => {
3086
+ updateUrl(buildModel({
3087
+ aggregationModel: model
3088
+ }), search, localStorageVersion, historyReplace, columns);
3089
+ propsOnAggregationModelChange === null || propsOnAggregationModelChange === void 0 ? void 0 : propsOnAggregationModelChange(model, details);
3090
+ },
3091
+ onPivotModelChange: model => {
3092
+ const simplified = fromGridPivotModel(model);
3093
+ if (isDeepEqual(simplified, lastEmittedPivotRef.current)) return;
3094
+ lastEmittedPivotRef.current = simplified;
3095
+ updateUrl(buildModel({
3096
+ pivotModel: simplified
3097
+ }), search, localStorageVersion, historyReplace, columns);
3098
+ propsOnPivotModelChange === null || propsOnPivotModelChange === void 0 ? void 0 : propsOnPivotModelChange(model);
3099
+ },
3100
+ onPivotActiveChange: active => {
3101
+ if (active === pivotActiveParsed) return;
3102
+ updateUrl(buildModel({
3103
+ pivotActive: active
3104
+ }), search, localStorageVersion, historyReplace, columns);
4092
3105
  }
4093
3106
  };
4094
3107
  };
4095
3108
 
4096
- const _excluded = ["apiRef", "autoHeight", "className", "columns", "slots", "slotProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "paginationModel", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "rowSelectionModel", "onColumnWidthChange", "onPaginationModelChange", "onRowSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "pagination", "paginationPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount"];
3109
+ const _excluded = ["apiRef", "autoHeight", "className", "columns", "slots", "slotProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "paginationModel", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "rowSelectionModel", "onColumnWidthChange", "onPaginationModelChange", "onRowSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "onRowGroupingModelChange", "onAggregationModelChange", "onPivotModelChange", "pagination", "paginationPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount", "density", "dataSource", "filterMode", "sortingMode"];
4097
3110
  const COMPONENT_NAME = 'DataGrid';
4098
3111
  const CLASSNAME = 'redsift-datagrid';
4099
3112
 
@@ -4177,6 +3190,9 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4177
3190
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
4178
3191
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
4179
3192
  onSortModelChange: propsOnSortModelChange,
3193
+ onRowGroupingModelChange: propsOnRowGroupingModelChange,
3194
+ onAggregationModelChange: propsOnAggregationModelChange,
3195
+ onPivotModelChange: propsOnPivotModelChange,
4180
3196
  pagination,
4181
3197
  paginationPlacement = 'both',
4182
3198
  paginationProps,
@@ -4186,15 +3202,26 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4186
3202
  theme: propsTheme,
4187
3203
  useRouter,
4188
3204
  paginationMode = 'client',
4189
- rowCount
3205
+ rowCount,
3206
+ density: _density,
3207
+ dataSource,
3208
+ filterMode: propsFilterMode,
3209
+ sortingMode: propsSortingMode
4190
3210
  } = props,
4191
3211
  forwardedProps = _objectWithoutProperties(props, _excluded);
4192
- const theme = useTheme$1(propsTheme);
3212
+ const theme = useTheme(propsTheme);
4193
3213
  const _apiRef = useGridApiRef();
4194
3214
  const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
4195
- const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
4196
3215
  LicenseInfo.setLicenseKey(license);
4197
3216
  const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
3217
+
3218
+ // When dataSource is present, MUI manages filter/sort/pagination internally.
3219
+ // We must not pass controlled models — only initialState (one-time) and
3220
+ // write-only onChange handlers for URL/localStorage persistence.
3221
+ const isDataSourceMode = Boolean(dataSource);
3222
+ const effectivePaginationMode = isDataSourceMode ? 'server' : paginationMode;
3223
+ const effectiveFilterMode = isDataSourceMode ? 'server' : propsFilterMode;
3224
+ const effectiveSortingMode = isDataSourceMode ? 'server' : propsSortingMode;
4198
3225
  const {
4199
3226
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
4200
3227
  onFilterModelChange: controlledOnFilterModelChange,
@@ -4220,7 +3247,6 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4220
3247
  density: controlledDensity,
4221
3248
  filterModel,
4222
3249
  onColumnVisibilityModelChange,
4223
- onDensityChange,
4224
3250
  onFilterModelChange,
4225
3251
  onPaginationModelChange,
4226
3252
  onPinnedColumnsChange,
@@ -4229,7 +3255,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4229
3255
  pinnedColumns,
4230
3256
  sortModel,
4231
3257
  onColumnWidthChange,
4232
- columnOrderModel
3258
+ columnOrderModel,
3259
+ rowGroupingModel,
3260
+ aggregationModel,
3261
+ pivotModel,
3262
+ pivotActive,
3263
+ onRowGroupingModelChange,
3264
+ onAggregationModelChange,
3265
+ onPivotModelChange,
3266
+ onPivotActiveChange
4233
3267
  } = useStatefulTable({
4234
3268
  apiRef: apiRef,
4235
3269
  initialState,
@@ -4240,13 +3274,39 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4240
3274
  onPaginationModelChange: controlledOnPaginationModelChange,
4241
3275
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
4242
3276
  onSortModelChange: controlledOnSortModelChange,
3277
+ onRowGroupingModelChange: propsOnRowGroupingModelChange,
3278
+ onAggregationModelChange: propsOnAggregationModelChange,
3279
+ onPivotModelChange: propsOnPivotModelChange,
4243
3280
  useRouter: useRouter,
4244
3281
  localStorageVersion,
4245
3282
  previousLocalStorageVersions
4246
3283
  });
4247
- const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3284
+
3285
+ // In dataSource mode, track pagination locally for the custom pagination slots
3286
+ // (rendered outside DataGridPremium). MUI owns the actual pagination state internally.
3287
+ const [dataSourcePaginationModel, setDataSourcePaginationModel] = useState(paginationModel);
3288
+
3289
+ // The pagination model to use for display in pagination slots
3290
+ const activePaginationModel = isDataSourceMode ? dataSourcePaginationModel : paginationModel;
3291
+
3292
+ // In dataSource mode, the top pagination (outside DataGridPremium) must go through
3293
+ // apiRef to change MUI's internal page. MUI then fires onPaginationModelChange
3294
+ // which updates URL and local state.
3295
+ const dataSourceTopPaginationChange = useCallback(model => {
3296
+ var _apiRef$current;
3297
+ (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPaginationModel(model);
3298
+ }, [apiRef]);
3299
+
3300
+ // Wrap onPaginationModelChange to also track state locally in dataSource mode
3301
+ const wrappedOnPaginationModelChange = useCallback((model, details) => {
3302
+ if (isDataSourceMode) {
3303
+ setDataSourcePaginationModel(model);
3304
+ }
3305
+ onPaginationModelChange(model, details);
3306
+ }, [isDataSourceMode, onPaginationModelChange]);
3307
+ const [rowSelectionModel, setRowSelectionModel] = useState(() => normalizeRowSelectionModel(propsRowSelectionModel));
4248
3308
  useEffect(() => {
4249
- setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3309
+ setRowSelectionModel(normalizeRowSelectionModel(propsRowSelectionModel));
4250
3310
  }, [propsRowSelectionModel]);
4251
3311
  const onRowSelectionModelChange = (selectionModel, details) => {
4252
3312
  setRowSelectionModel(selectionModel);
@@ -4265,16 +3325,36 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4265
3325
 
4266
3326
  // The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
4267
3327
  // for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
4268
- const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
3328
+ const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(effectivePaginationMode != 'server');
3329
+
3330
+ // Track when the grid API is ready to ensure top pagination renders correctly
3331
+ const [gridReady, setGridReady] = useState(false);
3332
+
3333
+ // Force re-render when the grid API becomes ready (for top pagination)
3334
+ useEffect(() => {
3335
+ if (apiRef.current && !gridReady) {
3336
+ setGridReady(true);
3337
+ }
3338
+ });
3339
+
3340
+ // Sync persisted density via apiRef — initialState only applies on mount,
3341
+ // so this handles SPA back/forward navigation where controlledDensity changes after mount
3342
+ useEffect(() => {
3343
+ if (apiRef.current) {
3344
+ apiRef.current.setDensity(controlledDensity);
3345
+ }
3346
+ }, [controlledDensity, apiRef]);
4269
3347
 
4270
3348
  // in server-side pagination we want to update the selection status
4271
3349
  // every time we navigate between pages, resize our page or select something
4272
3350
  useEffect(() => {
4273
- if (paginationMode == 'server') {
4274
- onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, paginationModel.page, paginationModel.pageSize);
3351
+ if (effectivePaginationMode == 'server') {
3352
+ onServerSideSelectionStatusChange(rowSelectionModel, apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, activePaginationModel.page, activePaginationModel.pageSize);
4275
3353
  }
4276
- }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize, rows]);
4277
- if (!Array.isArray(rows)) {
3354
+ }, [rowSelectionModel, activePaginationModel.page, activePaginationModel.pageSize, rows]);
3355
+
3356
+ // In dataSource mode MUI provides rows internally; skip the guard.
3357
+ if (!isDataSourceMode && !Array.isArray(rows)) {
4278
3358
  return null;
4279
3359
  }
4280
3360
 
@@ -4283,15 +3363,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4283
3363
  // receive the fresh value in the same render cycle — no extra re-render needed.
4284
3364
  // The ref is kept in sync for the onRowSelectionModelChange callback's deselect logic.
4285
3365
  let selectionStatus = selectionStatusRef.current;
4286
- if (pagination && paginationMode !== 'server' && Array.isArray(rowSelectionModel) && rowSelectionModel.length > 0) {
3366
+ if (pagination && effectivePaginationMode !== 'server' && getSelectionCount(rowSelectionModel) > 0) {
4287
3367
  try {
4288
- // Use manual page slicing with our React state's paginationModel instead of
4289
- // gridPaginatedVisibleSortedGridRow*Selector(apiRef). In MUI v7, the apiRef's
4290
- // internal pagination state can lag behind the React state after a page change,
4291
- // causing the selection status to be one page behind.
4292
- const pageStart = paginationModel.page * paginationModel.pageSize;
4293
- const pageEnd = pageStart + paginationModel.pageSize;
4294
- const selectableRowsInPage = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).slice(pageStart, pageEnd).filter(_ref => {
3368
+ // Use manual page slicing instead of gridPaginatedVisibleSorted* selectors.
3369
+ // MUI's paginated selectors use apiRef internal state which may be stale when
3370
+ // paginationModel prop changes our React state is always up to date.
3371
+ const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
3372
+ const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
3373
+ const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
3374
+ const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref => {
4295
3375
  let {
4296
3376
  model
4297
3377
  } = _ref;
@@ -4303,24 +3383,29 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4303
3383
  id
4304
3384
  } = _ref2;
4305
3385
  return id;
4306
- }) : gridFilteredSortedRowIdsSelector(apiRef).slice(pageStart, pageEnd);
3386
+ }) : pageEntries.map(_ref3 => {
3387
+ let {
3388
+ id
3389
+ } = _ref3;
3390
+ return id;
3391
+ });
4307
3392
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
4308
- const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref3 => {
3393
+ const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref4 => {
4309
3394
  let {
4310
3395
  model
4311
- } = _ref3;
3396
+ } = _ref4;
4312
3397
  return isRowSelectable({
4313
3398
  row: model
4314
3399
  });
4315
- }).map(_ref4 => {
3400
+ }).map(_ref5 => {
4316
3401
  let {
4317
3402
  id
4318
- } = _ref4;
3403
+ } = _ref5;
4319
3404
  return id;
4320
3405
  }) : gridFilteredSortedRowIdsSelector(apiRef);
4321
3406
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
4322
- const numberOfSelectedRows = rowSelectionModel.length;
4323
- const selectedOnCurrentPage = selectableRowsInPage.filter(id => rowSelectionModel.includes(id));
3407
+ const numberOfSelectedRows = getSelectionCount(rowSelectionModel);
3408
+ const selectedOnCurrentPage = selectableRowsInPage.filter(id => isRowSelected(rowSelectionModel, id));
4324
3409
  if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
4325
3410
  selectionStatus = {
4326
3411
  type: 'table',
@@ -4345,7 +3430,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4345
3430
  } catch {
4346
3431
  // apiRef may not be initialized on first render
4347
3432
  }
4348
- } else if (pagination && paginationMode !== 'server') {
3433
+ } else if (pagination && effectivePaginationMode !== 'server') {
4349
3434
  selectionStatus = {
4350
3435
  type: 'none',
4351
3436
  numberOfSelectedRows: 0
@@ -4374,41 +3459,100 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4374
3459
  ref: datagridRef,
4375
3460
  className: classNames(StatefulDataGrid.className, className),
4376
3461
  $height: height
4377
- }, /*#__PURE__*/React__default.createElement(DataGridPro, _extends({}, forwardedProps, {
3462
+ }, pagination && ['top', 'both'].includes(paginationPlacement) && gridReady ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, {
3463
+ displaySelection: true,
3464
+ displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
3465
+ displayPagination: ['top', 'both'].includes(paginationPlacement),
3466
+ selectionStatus: selectionStatus,
3467
+ paginationModel: activePaginationModel,
3468
+ onPaginationModelChange: isDataSourceMode ? dataSourceTopPaginationChange : onPaginationModelChange,
3469
+ pageSizeOptions: pageSizeOptions,
3470
+ paginationProps: paginationProps,
3471
+ rowCount: rowCount
3472
+ }) : /*#__PURE__*/React__default.createElement(ControlledPagination, {
3473
+ displaySelection: true,
3474
+ displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
3475
+ displayPagination: ['top', 'both'].includes(paginationPlacement),
3476
+ selectionStatus: selectionStatus,
3477
+ apiRef: apiRef,
3478
+ isRowSelectable: isRowSelectable,
3479
+ paginationModel: activePaginationModel,
3480
+ onPaginationModelChange: onPaginationModelChange,
3481
+ pageSizeOptions: pageSizeOptions,
3482
+ paginationProps: paginationProps
3483
+ }) : null, /*#__PURE__*/React__default.createElement(DataGridPremium, _extends({}, forwardedProps, {
4378
3484
  apiRef: apiRef,
3485
+ dataSource: dataSource,
4379
3486
  columns: columns,
4380
3487
  columnVisibilityModel: columnVisibilityModel,
4381
- density: controlledDensity,
4382
- filterModel: filterModel,
4383
3488
  onColumnVisibilityModelChange: onColumnVisibilityModelChange,
4384
- onDensityChange: onDensityChange,
4385
- onFilterModelChange: onFilterModelChange,
4386
- onPaginationModelChange: onPaginationModelChange,
4387
3489
  onPinnedColumnsChange: onPinnedColumnsChange,
4388
- onSortModelChange: onSortModelChange,
4389
- paginationModel: paginationModel,
4390
3490
  pinnedColumns: pinnedColumns,
4391
- sortModel: sortModel,
4392
3491
  pageSizeOptions: pageSizeOptions,
4393
3492
  onColumnWidthChange: onColumnWidthChange,
3493
+ rowGroupingModel: rowGroupingModel,
3494
+ onRowGroupingModelChange: onRowGroupingModelChange,
3495
+ aggregationModel: aggregationModel,
3496
+ onAggregationModelChange: onAggregationModelChange,
3497
+ pivotModel: pivotModel,
3498
+ onPivotModelChange: onPivotModelChange,
3499
+ pivotActive: pivotActive,
3500
+ onPivotActiveChange: onPivotActiveChange
3501
+ // In dataSource mode: models are uncontrolled (MUI owns them),
3502
+ // onChange handlers are write-only for URL/localStorage persistence,
3503
+ // and initialState seeds MUI on mount from the persisted URL state.
3504
+ }, isDataSourceMode ? {
3505
+ onFilterModelChange: onFilterModelChange,
3506
+ onSortModelChange: onSortModelChange,
3507
+ onPaginationModelChange: wrappedOnPaginationModelChange,
4394
3508
  initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
3509
+ density: controlledDensity,
4395
3510
  columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
4396
3511
  orderedFields: columnOrderModel
3512
+ }),
3513
+ filter: {
3514
+ filterModel
3515
+ },
3516
+ sorting: {
3517
+ sortModel
3518
+ },
3519
+ pagination: {
3520
+ paginationModel
3521
+ },
3522
+ pivoting: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.pivoting), {}, {
3523
+ enabled: pivotActive
4397
3524
  })
4398
- }),
3525
+ })
3526
+ } : {
3527
+ filterModel,
3528
+ sortModel,
3529
+ paginationModel,
3530
+ onFilterModelChange: onFilterModelChange,
3531
+ onSortModelChange: onSortModelChange,
3532
+ onPaginationModelChange: wrappedOnPaginationModelChange,
3533
+ initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
3534
+ density: controlledDensity,
3535
+ columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
3536
+ orderedFields: columnOrderModel
3537
+ })
3538
+ })
3539
+ }, {
4399
3540
  isRowSelectable: isRowSelectable,
4400
3541
  pagination: pagination,
4401
- paginationMode: paginationMode,
4402
- keepNonExistentRowsSelected: paginationMode == 'server',
4403
- rows: rows,
3542
+ paginationMode: effectivePaginationMode,
3543
+ filterMode: effectiveFilterMode,
3544
+ sortingMode: effectiveSortingMode,
3545
+ keepNonExistentRowsSelected: effectivePaginationMode == 'server',
3546
+ rows: isDataSourceMode ? [] : rows,
4404
3547
  rowCount: rowCount,
4405
3548
  autoHeight: autoHeight,
4406
3549
  checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
3550
+ disableRowSelectionExcludeModel: true,
3551
+ showToolbar: !hideToolbar,
4407
3552
  slots: _objectSpread2(_objectSpread2({
4408
3553
  baseButton: BaseButton,
4409
3554
  baseCheckbox: BaseCheckbox,
4410
- // baseTextField,
4411
- basePopper: BasePopper,
3555
+ baseIconButton: BaseIconButton,
4412
3556
  columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
4413
3557
  displayName: "columnFilteredIcon"
4414
3558
  })),
@@ -4443,31 +3587,14 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4443
3587
  displayName: "openFilterButtonIcon"
4444
3588
  }))
4445
3589
  }, slots), {}, {
4446
- toolbar: props => /*#__PURE__*/React__default.createElement(ToolbarWrapper, _extends({}, props, {
4447
- hideToolbar: hideToolbar,
4448
- RenderedToolbar: RenderedToolbar,
4449
- filterModel: filterModel,
4450
- onFilterModelChange: onFilterModelChange,
4451
- pagination: pagination,
4452
- paginationPlacement: paginationPlacement,
4453
- selectionStatus: selectionStatus,
4454
- apiRef: apiRef,
4455
- isRowSelectable: isRowSelectable,
4456
- paginationModel: paginationModel,
4457
- onPaginationModelChange: onPaginationModelChange,
4458
- pageSizeOptions: pageSizeOptions,
4459
- paginationProps: paginationProps,
4460
- paginationMode: paginationMode,
4461
- rowCount: rowCount
4462
- })),
4463
3590
  pagination: props => {
4464
- return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
3591
+ return pagination ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
4465
3592
  displaySelection: false,
4466
3593
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
4467
3594
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
4468
3595
  selectionStatus: selectionStatus,
4469
- paginationModel: paginationModel,
4470
- onPaginationModelChange: onPaginationModelChange,
3596
+ paginationModel: activePaginationModel,
3597
+ onPaginationModelChange: wrappedOnPaginationModelChange,
4471
3598
  pageSizeOptions: pageSizeOptions,
4472
3599
  paginationProps: paginationProps,
4473
3600
  rowCount: rowCount
@@ -4478,8 +3605,8 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4478
3605
  selectionStatus: selectionStatus,
4479
3606
  apiRef: apiRef,
4480
3607
  isRowSelectable: isRowSelectable,
4481
- paginationModel: paginationModel,
4482
- onPaginationModelChange: onPaginationModelChange,
3608
+ paginationModel: activePaginationModel,
3609
+ onPaginationModelChange: wrappedOnPaginationModelChange,
4483
3610
  pageSizeOptions: pageSizeOptions,
4484
3611
  paginationProps: paginationProps
4485
3612
  })) : null;
@@ -4488,41 +3615,50 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4488
3615
  slotProps: _objectSpread2({}, slotProps),
4489
3616
  rowSelectionModel: rowSelectionModel,
4490
3617
  onRowSelectionModelChange: (newSelectionModel, details) => {
4491
- if (pagination && paginationMode != 'server') {
4492
- const cbPageStart = paginationModel.page * paginationModel.pageSize;
4493
- const cbPageEnd = cbPageStart + paginationModel.pageSize;
4494
- const selectableRowsInPage = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).slice(cbPageStart, cbPageEnd).filter(_ref5 => {
3618
+ if (pagination && effectivePaginationMode != 'server') {
3619
+ // Use manual page slicing instead of gridPaginatedVisibleSorted* selectors
3620
+ // to avoid stale apiRef pagination state.
3621
+ const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
3622
+ const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
3623
+ const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
3624
+ const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref6 => {
4495
3625
  let {
4496
3626
  model
4497
- } = _ref5;
3627
+ } = _ref6;
4498
3628
  return isRowSelectable({
4499
3629
  row: model
4500
3630
  });
4501
- }).map(_ref6 => {
3631
+ }).map(_ref7 => {
4502
3632
  let {
4503
3633
  id
4504
- } = _ref6;
3634
+ } = _ref7;
4505
3635
  return id;
4506
- }) : gridFilteredSortedRowIdsSelector(apiRef).slice(cbPageStart, cbPageEnd);
3636
+ }) : pageEntries.map(_ref8 => {
3637
+ let {
3638
+ id
3639
+ } = _ref8;
3640
+ return id;
3641
+ });
4507
3642
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
4508
- const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref7 => {
3643
+ const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref9 => {
4509
3644
  let {
4510
3645
  model
4511
- } = _ref7;
3646
+ } = _ref9;
4512
3647
  return isRowSelectable({
4513
3648
  row: model
4514
3649
  });
4515
- }).map(_ref8 => {
3650
+ }).map(_ref10 => {
4516
3651
  let {
4517
3652
  id
4518
- } = _ref8;
3653
+ } = _ref10;
4519
3654
  return id;
4520
3655
  }) : gridFilteredSortedRowIdsSelector(apiRef);
4521
3656
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
4522
- const numberOfSelectedRows = newSelectionModel.length;
3657
+ const numberOfSelectedRows = getSelectionCount(newSelectionModel);
4523
3658
  if (selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatusRef.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
4524
3659
  setTimeout(() => {
4525
- apiRef.current.selectRows([], true, true);
3660
+ var _apiRef$current2;
3661
+ (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.selectRows([], true, true);
4526
3662
  }, 0);
4527
3663
  }
4528
3664
  if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
@@ -4564,5 +3700,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
4564
3700
  StatefulDataGrid.className = CLASSNAME;
4565
3701
  StatefulDataGrid.displayName = COMPONENT_NAME;
4566
3702
 
4567
- export { clearAllVersionStorage as $, ARRAY_IS_EMPTY as A, Box$1 as B, CONTAINS_ANY_OF as C, DOES_NOT_CONTAIN as D, ENDS_WITH_ANY_OF as E, IS as F, IS_NOT as G, HAS_WITH_SELECT as H, IS_ANY_OF as I, getGridStringOperators as J, getGridStringArrayOperators as K, getGridStringArrayOperatorsWithSelect as L, getGridStringArrayOperatorsWithSelectOnStringArrayColumns as M, FILTER_MODEL_KEY as N, SORT_MODEL_KEY as O, PAGINATION_MODEL_KEY as P, PINNED_COLUMNS as Q, DIMENSION_MODEL_KEY as R, STARTS_WITH_ANY_OF as S, TextField$1 as T, FILTER_SEARCH_KEY as U, VISIBILITY_MODEL_KEY as V, DENSITY_MODEL_KEY as W, COLUMN_ORDER_MODEL_KEY as X, CATEGORIES as Y, buildStorageKey as Z, clearPreviousVersionStorage as _, DOES_NOT_EQUAL as a, resetStatefulDataGridState as a0, convertToDisplayFormat as a1, convertFromDisplayFormat as a2, getDecodedSearchFromUrl as a3, buildQueryParamsString as a4, areSearchStringsEqual as a5, decodeValue as a6, encodeValue as a7, urlSearchParamsToString as a8, numberOperatorEncoder as a9, numberOperatorDecoder as aa, isOperatorValueValid as ab, isValueValid as ac, getFilterModelFromString as ad, getSearchParamsFromFilterModel as ae, getSortingFromString as af, getSearchParamsFromSorting as ag, getPaginationFromString as ah, getSearchParamsFromPagination as ai, getColumnVisibilityFromString as aj, getSearchParamsFromColumnVisibility as ak, getPinnedColumnsFromString as al, getSearchParamsFromPinnedColumns as am, getSearchParamsFromTab as an, getDensityFromString as ao, getSearchParamsFromDensity as ap, getDensityModel as aq, getColumnOrderFromString as ar, getSearchParamsFromColumnOrder as as, getFinalSearch as at, getModelsParsedOrUpdateLocalStorage as au, updateUrl as av, areFilterModelsEquivalent as aw, StatefulDataGrid as ax, DOES_NOT_START_WITH as b, DOES_NOT_END_WITH as c, IS_NOT_ANY_OF as d, DOES_NOT_CONTAIN_ANY_OF as e, DOES_NOT_START_WITH_ANY_OF as f, DOES_NOT_END_WITH_ANY_OF as g, IS_BETWEEN as h, IS_WITH_SELECT as i, IS_NOT_WITH_SELECT as j, IS_ANY_OF_WITH_SELECT as k, IS_NOT_ANY_OF_WITH_SELECT as l, ARRAY_IS_NOT_EMPTY as m, DOES_NOT_HAVE_WITH_SELECT as n, operatorList as o, HAS_ANY_OF_WITH_SELECT as p, HAS_ALL_OF_WITH_SELECT as q, DOES_NOT_HAVE_ANY_OF_WITH_SELECT as r, HAS_ONLY_WITH_SELECT as s, HAS as t, DOES_NOT_HAVE as u, HAS_ANY_OF as v, HAS_ALL_OF as w, DOES_NOT_HAVE_ANY_OF as x, HAS_ONLY as y, getGridNumericOperators as z };
3703
+ export { buildStorageKey as $, ARRAY_IS_EMPTY as A, IS as B, CONTAINS_ANY_OF as C, DOES_NOT_CONTAIN as D, ENDS_WITH_ANY_OF as E, IS_NOT as F, getGridStringOperators as G, HAS_WITH_SELECT as H, IS_ANY_OF as I, getGridStringArrayOperators as J, getGridStringArrayOperatorsWithSelect as K, getGridStringArrayOperatorsWithSelectOnStringArrayColumns as L, FILTER_MODEL_KEY as M, SORT_MODEL_KEY as N, PINNED_COLUMNS as O, PAGINATION_MODEL_KEY as P, DIMENSION_MODEL_KEY as Q, FILTER_SEARCH_KEY as R, STARTS_WITH_ANY_OF as S, DENSITY_MODEL_KEY as T, COLUMN_ORDER_MODEL_KEY as U, VISIBILITY_MODEL_KEY as V, ROW_GROUPING_MODEL_KEY as W, AGGREGATION_MODEL_KEY as X, PIVOT_MODEL_KEY as Y, PIVOT_ACTIVE_KEY as Z, CATEGORIES as _, DOES_NOT_EQUAL as a, clearPreviousVersionStorage as a0, clearAllVersionStorage as a1, resetStatefulDataGridState as a2, convertToDisplayFormat as a3, convertFromDisplayFormat as a4, getDecodedSearchFromUrl as a5, buildQueryParamsString as a6, areSearchStringsEqual as a7, decodeValue as a8, encodeValue as a9, getPivotFromString as aA, getSearchParamsFromPivot as aB, getPivotActiveFromString as aC, getSearchParamsFromPivotActive as aD, getFinalSearch as aE, getModelsParsedOrUpdateLocalStorage as aF, updateUrl as aG, areFilterModelsEquivalent as aH, StatefulDataGrid as aI, urlSearchParamsToString as aa, numberOperatorEncoder as ab, numberOperatorDecoder as ac, isOperatorValueValid as ad, isValueValid as ae, getFilterModelFromString as af, getSearchParamsFromFilterModel as ag, getSortingFromString as ah, getSearchParamsFromSorting as ai, getPaginationFromString as aj, getSearchParamsFromPagination as ak, getColumnVisibilityFromString as al, getSearchParamsFromColumnVisibility as am, getPinnedColumnsFromString as an, getSearchParamsFromPinnedColumns as ao, getSearchParamsFromTab as ap, getDensityFromString as aq, getSearchParamsFromDensity as ar, getDensityModel as as, getColumnOrderFromString as at, getSearchParamsFromColumnOrder as au, getRowGroupingFromString as av, getSearchParamsFromRowGrouping as aw, getAggregationFromString as ax, getSearchParamsFromAggregation as ay, fromGridPivotModel as az, DOES_NOT_START_WITH as b, DOES_NOT_END_WITH as c, IS_NOT_ANY_OF as d, DOES_NOT_CONTAIN_ANY_OF as e, DOES_NOT_START_WITH_ANY_OF as f, DOES_NOT_END_WITH_ANY_OF as g, IS_BETWEEN as h, IS_WITH_SELECT as i, IS_NOT_WITH_SELECT as j, IS_ANY_OF_WITH_SELECT as k, IS_NOT_ANY_OF_WITH_SELECT as l, ARRAY_IS_NOT_EMPTY as m, DOES_NOT_HAVE_WITH_SELECT as n, operatorList as o, HAS_ANY_OF_WITH_SELECT as p, HAS_ALL_OF_WITH_SELECT as q, DOES_NOT_HAVE_ANY_OF_WITH_SELECT as r, HAS_ONLY_WITH_SELECT as s, HAS as t, DOES_NOT_HAVE as u, HAS_ANY_OF as v, HAS_ALL_OF as w, DOES_NOT_HAVE_ANY_OF as x, HAS_ONLY as y, getGridNumericOperators as z };
4568
3704
  //# sourceMappingURL=StatefulDataGrid2.js.map