@redsift/table 12.5.5 → 12.5.6-muiv6

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,20 +1,1248 @@
1
- import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends } from './_rollupPluginBabelHelpers.js';
1
+ import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends$2 } from './_rollupPluginBabelHelpers.js';
2
2
  import * as React from 'react';
3
- import React__default, { useCallback, useEffect, useRef, useMemo, forwardRef, useState } from 'react';
4
- import { createTheme, ThemeProvider as ThemeProvider$1 } from '@mui/material/styles';
3
+ import React__default, { useCallback, useEffect, useMemo, useRef, forwardRef, useState } from 'react';
5
4
  import classNames from 'classnames';
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';
5
+ import { Icon, useTheme as useTheme$1, ThemeProvider, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite } from '@redsift/design-system';
6
+ import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, gridPaginatedVisibleSortedGridRowEntriesSelector, gridPaginatedVisibleSortedGridRowIdsSelector, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, DataGridPro } from '@mui/x-data-grid-pro';
7
+ import { L as LicenseInfo, u as useControlledDatagridState, T as ThemeProvider$1, S as StyledDataGrid, B as BottomPagination, b as baseGridSlots } from './useControlledDatagridState.js';
12
8
  import { mdiSync } from '@redsift/icons';
9
+ import { s as styled, a as styleFunctionSx, e as extendSxProp, _ as _objectWithoutPropertiesLoose, b as _extends, g as generateUtilityClasses, c as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, d as generateUtilityClass, f as styled$1, h as _extends$1, u as useDefaultProps, i as _objectWithoutPropertiesLoose$1, j as capitalize, k as composeClasses, r as rootShouldForwardProp, l as refType } from './Portal.js';
10
+ import { u as useTheme, a as useFormControl, b as formControlState, c as clsx$1, i as isAdornedStart, d as isFilled, F as FormControlContext, e as useId, h as Select, I as Input, j as FilledInput, O as OutlinedInput, o as onServerSideSelectionStatusChange } from './ControlledPagination.js';
11
+ import { j as jsxRuntimeExports } from './jsx-runtime.js';
13
12
  import { decompressFromEncodedURIComponent, compressToEncodedURIComponent } from 'lz-string';
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';
16
- import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
17
13
  import { T as Toolbar } from './Toolbar2.js';
14
+ import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
15
+
16
+ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
17
+
18
+ const _excluded$6 = ["className", "component"];
19
+ function createBox(options = {}) {
20
+ const {
21
+ themeId,
22
+ defaultTheme,
23
+ defaultClassName = 'MuiBox-root',
24
+ generateClassName
25
+ } = options;
26
+ const BoxRoot = styled('div', {
27
+ shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
28
+ })(styleFunctionSx);
29
+ const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
30
+ const theme = useTheme(defaultTheme);
31
+ const _extendSxProp = extendSxProp(inProps),
32
+ {
33
+ className,
34
+ component = 'div'
35
+ } = _extendSxProp,
36
+ other = _objectWithoutPropertiesLoose(_extendSxProp, _excluded$6);
37
+ return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, _extends({
38
+ as: component,
39
+ ref: ref,
40
+ className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
41
+ theme: themeId ? theme[themeId] || theme : theme
42
+ }, other));
43
+ });
44
+ return Box;
45
+ }
46
+
47
+ function isMuiElement(element, muiNames) {
48
+ var _muiName, _element$type;
49
+ return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf( // For server components `muiName` is avaialble in element.type._payload.value.muiName
50
+ // relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
51
+ // eslint-disable-next-line no-underscore-dangle
52
+ (_muiName = element.type.muiName) != null ? _muiName : (_element$type = element.type) == null || (_element$type = _element$type._payload) == null || (_element$type = _element$type.value) == null ? void 0 : _element$type.muiName) !== -1;
53
+ }
54
+
55
+ const boxClasses = generateUtilityClasses('MuiBox', ['root']);
56
+ var boxClasses$1 = boxClasses;
57
+
58
+ const defaultTheme = createTheme();
59
+ const Box = createBox({
60
+ themeId: THEME_ID,
61
+ defaultTheme,
62
+ defaultClassName: boxClasses$1.root,
63
+ generateClassName: ClassNameGenerator.generate
64
+ });
65
+ process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
66
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
67
+ // │ These PropTypes are generated from the TypeScript type definitions. │
68
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
69
+ // └─────────────────────────────────────────────────────────────────────┘
70
+ /**
71
+ * @ignore
72
+ */
73
+ children: PropTypes.node,
74
+ /**
75
+ * The component used for the root node.
76
+ * Either a string to use a HTML element or a component.
77
+ */
78
+ component: PropTypes.elementType,
79
+ /**
80
+ * The system prop that allows defining system overrides as well as additional CSS styles.
81
+ */
82
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
83
+ } : void 0;
84
+ var Box$1 = Box;
85
+
86
+ function getFormLabelUtilityClasses(slot) {
87
+ return generateUtilityClass('MuiFormLabel', slot);
88
+ }
89
+ const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
90
+ var formLabelClasses$1 = formLabelClasses;
91
+
92
+ const _excluded$5 = ["children", "className", "color", "component", "disabled", "error", "filled", "focused", "required"];
93
+ const useUtilityClasses$4 = ownerState => {
94
+ const {
95
+ classes,
96
+ color,
97
+ focused,
98
+ disabled,
99
+ error,
100
+ filled,
101
+ required
102
+ } = ownerState;
103
+ const slots = {
104
+ root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
105
+ asterisk: ['asterisk', error && 'error']
106
+ };
107
+ return composeClasses(slots, getFormLabelUtilityClasses, classes);
108
+ };
109
+ const FormLabelRoot = styled$1('label', {
110
+ name: 'MuiFormLabel',
111
+ slot: 'Root',
112
+ overridesResolver: ({
113
+ ownerState
114
+ }, styles) => {
115
+ return _extends$1({}, styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled);
116
+ }
117
+ })(({
118
+ theme,
119
+ ownerState
120
+ }) => _extends$1({
121
+ color: (theme.vars || theme).palette.text.secondary
122
+ }, theme.typography.body1, {
123
+ lineHeight: '1.4375em',
124
+ padding: 0,
125
+ position: 'relative',
126
+ [`&.${formLabelClasses$1.focused}`]: {
127
+ color: (theme.vars || theme).palette[ownerState.color].main
128
+ },
129
+ [`&.${formLabelClasses$1.disabled}`]: {
130
+ color: (theme.vars || theme).palette.text.disabled
131
+ },
132
+ [`&.${formLabelClasses$1.error}`]: {
133
+ color: (theme.vars || theme).palette.error.main
134
+ }
135
+ }));
136
+ const AsteriskComponent = styled$1('span', {
137
+ name: 'MuiFormLabel',
138
+ slot: 'Asterisk',
139
+ overridesResolver: (props, styles) => styles.asterisk
140
+ })(({
141
+ theme
142
+ }) => ({
143
+ [`&.${formLabelClasses$1.error}`]: {
144
+ color: (theme.vars || theme).palette.error.main
145
+ }
146
+ }));
147
+ const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
148
+ const props = useDefaultProps({
149
+ props: inProps,
150
+ name: 'MuiFormLabel'
151
+ });
152
+ const {
153
+ children,
154
+ className,
155
+ component = 'label'
156
+ } = props,
157
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$5);
158
+ const muiFormControl = useFormControl();
159
+ const fcs = formControlState({
160
+ props,
161
+ muiFormControl,
162
+ states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
163
+ });
164
+ const ownerState = _extends$1({}, props, {
165
+ color: fcs.color || 'primary',
166
+ component,
167
+ disabled: fcs.disabled,
168
+ error: fcs.error,
169
+ filled: fcs.filled,
170
+ focused: fcs.focused,
171
+ required: fcs.required
172
+ });
173
+ const classes = useUtilityClasses$4(ownerState);
174
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, _extends$1({
175
+ as: component,
176
+ ownerState: ownerState,
177
+ className: clsx$1(classes.root, className),
178
+ ref: ref
179
+ }, other, {
180
+ children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
181
+ ownerState: ownerState,
182
+ "aria-hidden": true,
183
+ className: classes.asterisk,
184
+ children: ["\u2009", '*']
185
+ })]
186
+ }));
187
+ });
188
+ process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
189
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
190
+ // │ These PropTypes are generated from the TypeScript type definitions. │
191
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
192
+ // └─────────────────────────────────────────────────────────────────────┘
193
+ /**
194
+ * The content of the component.
195
+ */
196
+ children: PropTypes.node,
197
+ /**
198
+ * Override or extend the styles applied to the component.
199
+ */
200
+ classes: PropTypes.object,
201
+ /**
202
+ * @ignore
203
+ */
204
+ className: PropTypes.string,
205
+ /**
206
+ * The color of the component.
207
+ * It supports both default and custom theme colors, which can be added as shown in the
208
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
209
+ */
210
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
211
+ /**
212
+ * The component used for the root node.
213
+ * Either a string to use a HTML element or a component.
214
+ */
215
+ component: PropTypes.elementType,
216
+ /**
217
+ * If `true`, the label should be displayed in a disabled state.
218
+ */
219
+ disabled: PropTypes.bool,
220
+ /**
221
+ * If `true`, the label is displayed in an error state.
222
+ */
223
+ error: PropTypes.bool,
224
+ /**
225
+ * If `true`, the label should use filled classes key.
226
+ */
227
+ filled: PropTypes.bool,
228
+ /**
229
+ * If `true`, the input of this label is focused (used by `FormGroup` components).
230
+ */
231
+ focused: PropTypes.bool,
232
+ /**
233
+ * If `true`, the label will indicate that the `input` is required.
234
+ */
235
+ required: PropTypes.bool,
236
+ /**
237
+ * The system prop that allows defining system overrides as well as additional CSS styles.
238
+ */
239
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
240
+ } : void 0;
241
+ var FormLabel$1 = FormLabel;
242
+
243
+ function getInputLabelUtilityClasses(slot) {
244
+ return generateUtilityClass('MuiInputLabel', slot);
245
+ }
246
+ generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
247
+
248
+ const _excluded$4 = ["disableAnimation", "margin", "shrink", "variant", "className"];
249
+ const useUtilityClasses$3 = ownerState => {
250
+ const {
251
+ classes,
252
+ formControl,
253
+ size,
254
+ shrink,
255
+ disableAnimation,
256
+ variant,
257
+ required
258
+ } = ownerState;
259
+ const slots = {
260
+ root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size && size !== 'normal' && `size${capitalize(size)}`, variant],
261
+ asterisk: [required && 'asterisk']
262
+ };
263
+ const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
264
+ return _extends$1({}, classes, composedClasses);
265
+ };
266
+ const InputLabelRoot = styled$1(FormLabel$1, {
267
+ shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
268
+ name: 'MuiInputLabel',
269
+ slot: 'Root',
270
+ overridesResolver: (props, styles) => {
271
+ const {
272
+ ownerState
273
+ } = props;
274
+ return [{
275
+ [`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
276
+ }, 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]];
277
+ }
278
+ })(({
279
+ theme,
280
+ ownerState
281
+ }) => _extends$1({
282
+ display: 'block',
283
+ transformOrigin: 'top left',
284
+ whiteSpace: 'nowrap',
285
+ overflow: 'hidden',
286
+ textOverflow: 'ellipsis',
287
+ maxWidth: '100%'
288
+ }, ownerState.formControl && {
289
+ position: 'absolute',
290
+ left: 0,
291
+ top: 0,
292
+ // slight alteration to spec spacing to match visual spec result
293
+ transform: 'translate(0, 20px) scale(1)'
294
+ }, ownerState.size === 'small' && {
295
+ // Compensation for the `Input.inputSizeSmall` style.
296
+ transform: 'translate(0, 17px) scale(1)'
297
+ }, ownerState.shrink && {
298
+ transform: 'translate(0, -1.5px) scale(0.75)',
299
+ transformOrigin: 'top left',
300
+ maxWidth: '133%'
301
+ }, !ownerState.disableAnimation && {
302
+ transition: theme.transitions.create(['color', 'transform', 'max-width'], {
303
+ duration: theme.transitions.duration.shorter,
304
+ easing: theme.transitions.easing.easeOut
305
+ })
306
+ }, ownerState.variant === 'filled' && _extends$1({
307
+ // Chrome's autofill feature gives the input field a yellow background.
308
+ // Since the input field is behind the label in the HTML tree,
309
+ // the input field is drawn last and hides the label with an opaque background color.
310
+ // zIndex: 1 will raise the label above opaque background-colors of input.
311
+ zIndex: 1,
312
+ pointerEvents: 'none',
313
+ transform: 'translate(12px, 16px) scale(1)',
314
+ maxWidth: 'calc(100% - 24px)'
315
+ }, ownerState.size === 'small' && {
316
+ transform: 'translate(12px, 13px) scale(1)'
317
+ }, ownerState.shrink && _extends$1({
318
+ userSelect: 'none',
319
+ pointerEvents: 'auto',
320
+ transform: 'translate(12px, 7px) scale(0.75)',
321
+ maxWidth: 'calc(133% - 24px)'
322
+ }, ownerState.size === 'small' && {
323
+ transform: 'translate(12px, 4px) scale(0.75)'
324
+ })), ownerState.variant === 'outlined' && _extends$1({
325
+ // see comment above on filled.zIndex
326
+ zIndex: 1,
327
+ pointerEvents: 'none',
328
+ transform: 'translate(14px, 16px) scale(1)',
329
+ maxWidth: 'calc(100% - 24px)'
330
+ }, ownerState.size === 'small' && {
331
+ transform: 'translate(14px, 9px) scale(1)'
332
+ }, ownerState.shrink && {
333
+ userSelect: 'none',
334
+ pointerEvents: 'auto',
335
+ // Theoretically, we should have (8+5)*2/0.75 = 34px
336
+ // but it feels a better when it bleeds a bit on the left, so 32px.
337
+ maxWidth: 'calc(133% - 32px)',
338
+ transform: 'translate(14px, -9px) scale(0.75)'
339
+ })));
340
+ const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
341
+ const props = useDefaultProps({
342
+ name: 'MuiInputLabel',
343
+ props: inProps
344
+ });
345
+ const {
346
+ disableAnimation = false,
347
+ shrink: shrinkProp,
348
+ className
349
+ } = props,
350
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$4);
351
+ const muiFormControl = useFormControl();
352
+ let shrink = shrinkProp;
353
+ if (typeof shrink === 'undefined' && muiFormControl) {
354
+ shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
355
+ }
356
+ const fcs = formControlState({
357
+ props,
358
+ muiFormControl,
359
+ states: ['size', 'variant', 'required', 'focused']
360
+ });
361
+ const ownerState = _extends$1({}, props, {
362
+ disableAnimation,
363
+ formControl: muiFormControl,
364
+ shrink,
365
+ size: fcs.size,
366
+ variant: fcs.variant,
367
+ required: fcs.required,
368
+ focused: fcs.focused
369
+ });
370
+ const classes = useUtilityClasses$3(ownerState);
371
+ return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, _extends$1({
372
+ "data-shrink": shrink,
373
+ ownerState: ownerState,
374
+ ref: ref,
375
+ className: clsx$1(classes.root, className)
376
+ }, other, {
377
+ classes: classes
378
+ }));
379
+ });
380
+ process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
381
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
382
+ // │ These PropTypes are generated from the TypeScript type definitions. │
383
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
384
+ // └─────────────────────────────────────────────────────────────────────┘
385
+ /**
386
+ * The content of the component.
387
+ */
388
+ children: PropTypes.node,
389
+ /**
390
+ * Override or extend the styles applied to the component.
391
+ */
392
+ classes: PropTypes.object,
393
+ /**
394
+ * @ignore
395
+ */
396
+ className: PropTypes.string,
397
+ /**
398
+ * The color of the component.
399
+ * It supports both default and custom theme colors, which can be added as shown in the
400
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
401
+ */
402
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
403
+ /**
404
+ * If `true`, the transition animation is disabled.
405
+ * @default false
406
+ */
407
+ disableAnimation: PropTypes.bool,
408
+ /**
409
+ * If `true`, the component is disabled.
410
+ */
411
+ disabled: PropTypes.bool,
412
+ /**
413
+ * If `true`, the label is displayed in an error state.
414
+ */
415
+ error: PropTypes.bool,
416
+ /**
417
+ * If `true`, the `input` of this label is focused.
418
+ */
419
+ focused: PropTypes.bool,
420
+ /**
421
+ * If `dense`, will adjust vertical spacing. This is normally obtained via context from
422
+ * FormControl.
423
+ */
424
+ margin: PropTypes.oneOf(['dense']),
425
+ /**
426
+ * if `true`, the label will indicate that the `input` is required.
427
+ */
428
+ required: PropTypes.bool,
429
+ /**
430
+ * If `true`, the label is shrunk.
431
+ */
432
+ shrink: PropTypes.bool,
433
+ /**
434
+ * The size of the component.
435
+ * @default 'normal'
436
+ */
437
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
438
+ /**
439
+ * The system prop that allows defining system overrides as well as additional CSS styles.
440
+ */
441
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
442
+ /**
443
+ * The variant to use.
444
+ */
445
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
446
+ } : void 0;
447
+ var InputLabel$1 = InputLabel;
448
+
449
+ function getFormControlUtilityClasses(slot) {
450
+ return generateUtilityClass('MuiFormControl', slot);
451
+ }
452
+ generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
453
+
454
+ const _excluded$3 = ["children", "className", "color", "component", "disabled", "error", "focused", "fullWidth", "hiddenLabel", "margin", "required", "size", "variant"];
455
+ const useUtilityClasses$2 = ownerState => {
456
+ const {
457
+ classes,
458
+ margin,
459
+ fullWidth
460
+ } = ownerState;
461
+ const slots = {
462
+ root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
463
+ };
464
+ return composeClasses(slots, getFormControlUtilityClasses, classes);
465
+ };
466
+ const FormControlRoot = styled$1('div', {
467
+ name: 'MuiFormControl',
468
+ slot: 'Root',
469
+ overridesResolver: ({
470
+ ownerState
471
+ }, styles) => {
472
+ return _extends$1({}, styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth);
473
+ }
474
+ })(({
475
+ ownerState
476
+ }) => _extends$1({
477
+ display: 'inline-flex',
478
+ flexDirection: 'column',
479
+ position: 'relative',
480
+ // Reset fieldset default style.
481
+ minWidth: 0,
482
+ padding: 0,
483
+ margin: 0,
484
+ border: 0,
485
+ verticalAlign: 'top'
486
+ }, ownerState.margin === 'normal' && {
487
+ marginTop: 16,
488
+ marginBottom: 8
489
+ }, ownerState.margin === 'dense' && {
490
+ marginTop: 8,
491
+ marginBottom: 4
492
+ }, ownerState.fullWidth && {
493
+ width: '100%'
494
+ }));
495
+
496
+ /**
497
+ * Provides context such as filled/focused/error/required for form inputs.
498
+ * Relying on the context provides high flexibility and ensures that the state always stays
499
+ * consistent across the children of the `FormControl`.
500
+ * This context is used by the following components:
501
+ *
502
+ * - FormLabel
503
+ * - FormHelperText
504
+ * - Input
505
+ * - InputLabel
506
+ *
507
+ * You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
508
+ *
509
+ * ```jsx
510
+ * <FormControl>
511
+ * <InputLabel htmlFor="my-input">Email address</InputLabel>
512
+ * <Input id="my-input" aria-describedby="my-helper-text" />
513
+ * <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
514
+ * </FormControl>
515
+ * ```
516
+ *
517
+ * ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
518
+ * For instance, only one input can be focused at the same time, the state shouldn't be shared.
519
+ */
520
+ const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
521
+ const props = useDefaultProps({
522
+ props: inProps,
523
+ name: 'MuiFormControl'
524
+ });
525
+ const {
526
+ children,
527
+ className,
528
+ color = 'primary',
529
+ component = 'div',
530
+ disabled = false,
531
+ error = false,
532
+ focused: visuallyFocused,
533
+ fullWidth = false,
534
+ hiddenLabel = false,
535
+ margin = 'none',
536
+ required = false,
537
+ size = 'medium',
538
+ variant = 'outlined'
539
+ } = props,
540
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$3);
541
+ const ownerState = _extends$1({}, props, {
542
+ color,
543
+ component,
544
+ disabled,
545
+ error,
546
+ fullWidth,
547
+ hiddenLabel,
548
+ margin,
549
+ required,
550
+ size,
551
+ variant
552
+ });
553
+ const classes = useUtilityClasses$2(ownerState);
554
+ const [adornedStart, setAdornedStart] = React.useState(() => {
555
+ // We need to iterate through the children and find the Input in order
556
+ // to fully support server-side rendering.
557
+ let initialAdornedStart = false;
558
+ if (children) {
559
+ React.Children.forEach(children, child => {
560
+ if (!isMuiElement(child, ['Input', 'Select'])) {
561
+ return;
562
+ }
563
+ const input = isMuiElement(child, ['Select']) ? child.props.input : child;
564
+ if (input && isAdornedStart(input.props)) {
565
+ initialAdornedStart = true;
566
+ }
567
+ });
568
+ }
569
+ return initialAdornedStart;
570
+ });
571
+ const [filled, setFilled] = React.useState(() => {
572
+ // We need to iterate through the children and find the Input in order
573
+ // to fully support server-side rendering.
574
+ let initialFilled = false;
575
+ if (children) {
576
+ React.Children.forEach(children, child => {
577
+ if (!isMuiElement(child, ['Input', 'Select'])) {
578
+ return;
579
+ }
580
+ if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
581
+ initialFilled = true;
582
+ }
583
+ });
584
+ }
585
+ return initialFilled;
586
+ });
587
+ const [focusedState, setFocused] = React.useState(false);
588
+ if (disabled && focusedState) {
589
+ setFocused(false);
590
+ }
591
+ const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
592
+ let registerEffect;
593
+ if (process.env.NODE_ENV !== 'production') {
594
+ // eslint-disable-next-line react-hooks/rules-of-hooks
595
+ const registeredInput = React.useRef(false);
596
+ registerEffect = () => {
597
+ if (registeredInput.current) {
598
+ console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
599
+ }
600
+ registeredInput.current = true;
601
+ return () => {
602
+ registeredInput.current = false;
603
+ };
604
+ };
605
+ }
606
+ const childContext = React.useMemo(() => {
607
+ return {
608
+ adornedStart,
609
+ setAdornedStart,
610
+ color,
611
+ disabled,
612
+ error,
613
+ filled,
614
+ focused,
615
+ fullWidth,
616
+ hiddenLabel,
617
+ size,
618
+ onBlur: () => {
619
+ setFocused(false);
620
+ },
621
+ onEmpty: () => {
622
+ setFilled(false);
623
+ },
624
+ onFilled: () => {
625
+ setFilled(true);
626
+ },
627
+ onFocus: () => {
628
+ setFocused(true);
629
+ },
630
+ registerEffect,
631
+ required,
632
+ variant
633
+ };
634
+ }, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, required, size, variant]);
635
+ return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
636
+ value: childContext,
637
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, _extends$1({
638
+ as: component,
639
+ ownerState: ownerState,
640
+ className: clsx$1(classes.root, className),
641
+ ref: ref
642
+ }, other, {
643
+ children: children
644
+ }))
645
+ });
646
+ });
647
+ process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
648
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
649
+ // │ These PropTypes are generated from the TypeScript type definitions. │
650
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
651
+ // └─────────────────────────────────────────────────────────────────────┘
652
+ /**
653
+ * The content of the component.
654
+ */
655
+ children: PropTypes.node,
656
+ /**
657
+ * Override or extend the styles applied to the component.
658
+ */
659
+ classes: PropTypes.object,
660
+ /**
661
+ * @ignore
662
+ */
663
+ className: PropTypes.string,
664
+ /**
665
+ * The color of the component.
666
+ * It supports both default and custom theme colors, which can be added as shown in the
667
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
668
+ * @default 'primary'
669
+ */
670
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
671
+ /**
672
+ * The component used for the root node.
673
+ * Either a string to use a HTML element or a component.
674
+ */
675
+ component: PropTypes.elementType,
676
+ /**
677
+ * If `true`, the label, input and helper text should be displayed in a disabled state.
678
+ * @default false
679
+ */
680
+ disabled: PropTypes.bool,
681
+ /**
682
+ * If `true`, the label is displayed in an error state.
683
+ * @default false
684
+ */
685
+ error: PropTypes.bool,
686
+ /**
687
+ * If `true`, the component is displayed in focused state.
688
+ */
689
+ focused: PropTypes.bool,
690
+ /**
691
+ * If `true`, the component will take up the full width of its container.
692
+ * @default false
693
+ */
694
+ fullWidth: PropTypes.bool,
695
+ /**
696
+ * If `true`, the label is hidden.
697
+ * This is used to increase density for a `FilledInput`.
698
+ * Be sure to add `aria-label` to the `input` element.
699
+ * @default false
700
+ */
701
+ hiddenLabel: PropTypes.bool,
702
+ /**
703
+ * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
704
+ * @default 'none'
705
+ */
706
+ margin: PropTypes.oneOf(['dense', 'none', 'normal']),
707
+ /**
708
+ * If `true`, the label will indicate that the `input` is required.
709
+ * @default false
710
+ */
711
+ required: PropTypes.bool,
712
+ /**
713
+ * The size of the component.
714
+ * @default 'medium'
715
+ */
716
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
717
+ /**
718
+ * The system prop that allows defining system overrides as well as additional CSS styles.
719
+ */
720
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
721
+ /**
722
+ * The variant to use.
723
+ * @default 'outlined'
724
+ */
725
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
726
+ } : void 0;
727
+ var FormControl$1 = FormControl;
728
+
729
+ function getFormHelperTextUtilityClasses(slot) {
730
+ return generateUtilityClass('MuiFormHelperText', slot);
731
+ }
732
+ const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
733
+ var formHelperTextClasses$1 = formHelperTextClasses;
734
+
735
+ var _span;
736
+ const _excluded$2 = ["children", "className", "component", "disabled", "error", "filled", "focused", "margin", "required", "variant"];
737
+ const useUtilityClasses$1 = ownerState => {
738
+ const {
739
+ classes,
740
+ contained,
741
+ size,
742
+ disabled,
743
+ error,
744
+ filled,
745
+ focused,
746
+ required
747
+ } = ownerState;
748
+ const slots = {
749
+ root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
750
+ };
751
+ return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
752
+ };
753
+ const FormHelperTextRoot = styled$1('p', {
754
+ name: 'MuiFormHelperText',
755
+ slot: 'Root',
756
+ overridesResolver: (props, styles) => {
757
+ const {
758
+ ownerState
759
+ } = props;
760
+ return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
761
+ }
762
+ })(({
763
+ theme,
764
+ ownerState
765
+ }) => _extends$1({
766
+ color: (theme.vars || theme).palette.text.secondary
767
+ }, theme.typography.caption, {
768
+ textAlign: 'left',
769
+ marginTop: 3,
770
+ marginRight: 0,
771
+ marginBottom: 0,
772
+ marginLeft: 0,
773
+ [`&.${formHelperTextClasses$1.disabled}`]: {
774
+ color: (theme.vars || theme).palette.text.disabled
775
+ },
776
+ [`&.${formHelperTextClasses$1.error}`]: {
777
+ color: (theme.vars || theme).palette.error.main
778
+ }
779
+ }, ownerState.size === 'small' && {
780
+ marginTop: 4
781
+ }, ownerState.contained && {
782
+ marginLeft: 14,
783
+ marginRight: 14
784
+ }));
785
+ const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
786
+ const props = useDefaultProps({
787
+ props: inProps,
788
+ name: 'MuiFormHelperText'
789
+ });
790
+ const {
791
+ children,
792
+ className,
793
+ component = 'p'
794
+ } = props,
795
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$2);
796
+ const muiFormControl = useFormControl();
797
+ const fcs = formControlState({
798
+ props,
799
+ muiFormControl,
800
+ states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
801
+ });
802
+ const ownerState = _extends$1({}, props, {
803
+ component,
804
+ contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
805
+ variant: fcs.variant,
806
+ size: fcs.size,
807
+ disabled: fcs.disabled,
808
+ error: fcs.error,
809
+ filled: fcs.filled,
810
+ focused: fcs.focused,
811
+ required: fcs.required
812
+ });
813
+ const classes = useUtilityClasses$1(ownerState);
814
+ return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, _extends$1({
815
+ as: component,
816
+ ownerState: ownerState,
817
+ className: clsx$1(classes.root, className),
818
+ ref: ref
819
+ }, other, {
820
+ children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
821
+ _span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
822
+ className: "notranslate",
823
+ children: "\u200B"
824
+ })) : children
825
+ }));
826
+ });
827
+ process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
828
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
829
+ // │ These PropTypes are generated from the TypeScript type definitions. │
830
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
831
+ // └─────────────────────────────────────────────────────────────────────┘
832
+ /**
833
+ * The content of the component.
834
+ *
835
+ * If `' '` is provided, the component reserves one line height for displaying a future message.
836
+ */
837
+ children: PropTypes.node,
838
+ /**
839
+ * Override or extend the styles applied to the component.
840
+ */
841
+ classes: PropTypes.object,
842
+ /**
843
+ * @ignore
844
+ */
845
+ className: PropTypes.string,
846
+ /**
847
+ * The component used for the root node.
848
+ * Either a string to use a HTML element or a component.
849
+ */
850
+ component: PropTypes.elementType,
851
+ /**
852
+ * If `true`, the helper text should be displayed in a disabled state.
853
+ */
854
+ disabled: PropTypes.bool,
855
+ /**
856
+ * If `true`, helper text should be displayed in an error state.
857
+ */
858
+ error: PropTypes.bool,
859
+ /**
860
+ * If `true`, the helper text should use filled classes key.
861
+ */
862
+ filled: PropTypes.bool,
863
+ /**
864
+ * If `true`, the helper text should use focused classes key.
865
+ */
866
+ focused: PropTypes.bool,
867
+ /**
868
+ * If `dense`, will adjust vertical spacing. This is normally obtained via context from
869
+ * FormControl.
870
+ */
871
+ margin: PropTypes.oneOf(['dense']),
872
+ /**
873
+ * If `true`, the helper text should use required classes key.
874
+ */
875
+ required: PropTypes.bool,
876
+ /**
877
+ * The system prop that allows defining system overrides as well as additional CSS styles.
878
+ */
879
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
880
+ /**
881
+ * The variant to use.
882
+ */
883
+ variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
884
+ } : void 0;
885
+ var FormHelperText$1 = FormHelperText;
886
+
887
+ function getTextFieldUtilityClass(slot) {
888
+ return generateUtilityClass('MuiTextField', slot);
889
+ }
890
+ generateUtilityClasses('MuiTextField', ['root']);
891
+
892
+ const _excluded$1 = ["autoComplete", "autoFocus", "children", "className", "color", "defaultValue", "disabled", "error", "FormHelperTextProps", "fullWidth", "helperText", "id", "InputLabelProps", "inputProps", "InputProps", "inputRef", "label", "maxRows", "minRows", "multiline", "name", "onBlur", "onChange", "onFocus", "placeholder", "required", "rows", "select", "SelectProps", "type", "value", "variant"];
893
+ const variantComponent = {
894
+ standard: Input,
895
+ filled: FilledInput,
896
+ outlined: OutlinedInput
897
+ };
898
+ const useUtilityClasses = ownerState => {
899
+ const {
900
+ classes
901
+ } = ownerState;
902
+ const slots = {
903
+ root: ['root']
904
+ };
905
+ return composeClasses(slots, getTextFieldUtilityClass, classes);
906
+ };
907
+ const TextFieldRoot = styled$1(FormControl$1, {
908
+ name: 'MuiTextField',
909
+ slot: 'Root',
910
+ overridesResolver: (props, styles) => styles.root
911
+ })({});
912
+
913
+ /**
914
+ * The `TextField` is a convenience wrapper for the most common cases (80%).
915
+ * It cannot be all things to all people, otherwise the API would grow out of control.
916
+ *
917
+ * ## Advanced Configuration
918
+ *
919
+ * It's important to understand that the text field is a simple abstraction
920
+ * on top of the following components:
921
+ *
922
+ * - [FormControl](/material-ui/api/form-control/)
923
+ * - [InputLabel](/material-ui/api/input-label/)
924
+ * - [FilledInput](/material-ui/api/filled-input/)
925
+ * - [OutlinedInput](/material-ui/api/outlined-input/)
926
+ * - [Input](/material-ui/api/input/)
927
+ * - [FormHelperText](/material-ui/api/form-helper-text/)
928
+ *
929
+ * If you wish to alter the props applied to the `input` element, you can do so as follows:
930
+ *
931
+ * ```jsx
932
+ * const inputProps = {
933
+ * step: 300,
934
+ * };
935
+ *
936
+ * return <TextField id="time" type="time" inputProps={inputProps} />;
937
+ * ```
938
+ *
939
+ * For advanced cases, please look at the source of TextField by clicking on the
940
+ * "Edit this page" button above. Consider either:
941
+ *
942
+ * - using the upper case props for passing values directly to the components
943
+ * - using the underlying components directly as shown in the demos
944
+ */
945
+ const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
946
+ const props = useDefaultProps({
947
+ props: inProps,
948
+ name: 'MuiTextField'
949
+ });
950
+ const {
951
+ autoComplete,
952
+ autoFocus = false,
953
+ children,
954
+ className,
955
+ color = 'primary',
956
+ defaultValue,
957
+ disabled = false,
958
+ error = false,
959
+ FormHelperTextProps,
960
+ fullWidth = false,
961
+ helperText,
962
+ id: idOverride,
963
+ InputLabelProps,
964
+ inputProps,
965
+ InputProps,
966
+ inputRef,
967
+ label,
968
+ maxRows,
969
+ minRows,
970
+ multiline = false,
971
+ name,
972
+ onBlur,
973
+ onChange,
974
+ onFocus,
975
+ placeholder,
976
+ required = false,
977
+ rows,
978
+ select = false,
979
+ SelectProps,
980
+ type,
981
+ value,
982
+ variant = 'outlined'
983
+ } = props,
984
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$1);
985
+ const ownerState = _extends$1({}, props, {
986
+ autoFocus,
987
+ color,
988
+ disabled,
989
+ error,
990
+ fullWidth,
991
+ multiline,
992
+ required,
993
+ select,
994
+ variant
995
+ });
996
+ const classes = useUtilityClasses(ownerState);
997
+ if (process.env.NODE_ENV !== 'production') {
998
+ if (select && !children) {
999
+ console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
1000
+ }
1001
+ }
1002
+ const InputMore = {};
1003
+ if (variant === 'outlined') {
1004
+ if (InputLabelProps && typeof InputLabelProps.shrink !== 'undefined') {
1005
+ InputMore.notched = InputLabelProps.shrink;
1006
+ }
1007
+ InputMore.label = label;
1008
+ }
1009
+ if (select) {
1010
+ // unset defaults from textbox inputs
1011
+ if (!SelectProps || !SelectProps.native) {
1012
+ InputMore.id = undefined;
1013
+ }
1014
+ InputMore['aria-describedby'] = undefined;
1015
+ }
1016
+ const id = useId(idOverride);
1017
+ const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
1018
+ const inputLabelId = label && id ? `${id}-label` : undefined;
1019
+ const InputComponent = variantComponent[variant];
1020
+ const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputComponent, _extends$1({
1021
+ "aria-describedby": helperTextId,
1022
+ autoComplete: autoComplete,
1023
+ autoFocus: autoFocus,
1024
+ defaultValue: defaultValue,
1025
+ fullWidth: fullWidth,
1026
+ multiline: multiline,
1027
+ name: name,
1028
+ rows: rows,
1029
+ maxRows: maxRows,
1030
+ minRows: minRows,
1031
+ type: type,
1032
+ value: value,
1033
+ id: id,
1034
+ inputRef: inputRef,
1035
+ onBlur: onBlur,
1036
+ onChange: onChange,
1037
+ onFocus: onFocus,
1038
+ placeholder: placeholder,
1039
+ inputProps: inputProps
1040
+ }, InputMore, InputProps));
1041
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(TextFieldRoot, _extends$1({
1042
+ className: clsx$1(classes.root, className),
1043
+ disabled: disabled,
1044
+ error: error,
1045
+ fullWidth: fullWidth,
1046
+ ref: ref,
1047
+ required: required,
1048
+ color: color,
1049
+ variant: variant,
1050
+ ownerState: ownerState
1051
+ }, other, {
1052
+ children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabel$1, _extends$1({
1053
+ htmlFor: id,
1054
+ id: inputLabelId
1055
+ }, InputLabelProps, {
1056
+ children: label
1057
+ })), select ? /*#__PURE__*/jsxRuntimeExports.jsx(Select, _extends$1({
1058
+ "aria-describedby": helperTextId,
1059
+ id: id,
1060
+ labelId: inputLabelId,
1061
+ value: value,
1062
+ input: InputElement
1063
+ }, SelectProps, {
1064
+ children: children
1065
+ })) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperText$1, _extends$1({
1066
+ id: helperTextId
1067
+ }, FormHelperTextProps, {
1068
+ children: helperText
1069
+ }))]
1070
+ }));
1071
+ });
1072
+ process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
1073
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
1074
+ // │ These PropTypes are generated from the TypeScript type definitions. │
1075
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
1076
+ // └─────────────────────────────────────────────────────────────────────┘
1077
+ /**
1078
+ * This prop helps users to fill forms faster, especially on mobile devices.
1079
+ * The name can be confusing, as it's more like an autofill.
1080
+ * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
1081
+ */
1082
+ autoComplete: PropTypes.string,
1083
+ /**
1084
+ * If `true`, the `input` element is focused during the first mount.
1085
+ * @default false
1086
+ */
1087
+ autoFocus: PropTypes.bool,
1088
+ /**
1089
+ * @ignore
1090
+ */
1091
+ children: PropTypes.node,
1092
+ /**
1093
+ * Override or extend the styles applied to the component.
1094
+ */
1095
+ classes: PropTypes.object,
1096
+ /**
1097
+ * @ignore
1098
+ */
1099
+ className: PropTypes.string,
1100
+ /**
1101
+ * The color of the component.
1102
+ * It supports both default and custom theme colors, which can be added as shown in the
1103
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
1104
+ * @default 'primary'
1105
+ */
1106
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
1107
+ /**
1108
+ * The default value. Use when the component is not controlled.
1109
+ */
1110
+ defaultValue: PropTypes.any,
1111
+ /**
1112
+ * If `true`, the component is disabled.
1113
+ * @default false
1114
+ */
1115
+ disabled: PropTypes.bool,
1116
+ /**
1117
+ * If `true`, the label is displayed in an error state.
1118
+ * @default false
1119
+ */
1120
+ error: PropTypes.bool,
1121
+ /**
1122
+ * Props applied to the [`FormHelperText`](/material-ui/api/form-helper-text/) element.
1123
+ */
1124
+ FormHelperTextProps: PropTypes.object,
1125
+ /**
1126
+ * If `true`, the input will take up the full width of its container.
1127
+ * @default false
1128
+ */
1129
+ fullWidth: PropTypes.bool,
1130
+ /**
1131
+ * The helper text content.
1132
+ */
1133
+ helperText: PropTypes.node,
1134
+ /**
1135
+ * The id of the `input` element.
1136
+ * Use this prop to make `label` and `helperText` accessible for screen readers.
1137
+ */
1138
+ id: PropTypes.string,
1139
+ /**
1140
+ * Props applied to the [`InputLabel`](/material-ui/api/input-label/) element.
1141
+ * Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
1142
+ */
1143
+ InputLabelProps: PropTypes.object,
1144
+ /**
1145
+ * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
1146
+ */
1147
+ inputProps: PropTypes.object,
1148
+ /**
1149
+ * Props applied to the Input element.
1150
+ * It will be a [`FilledInput`](/material-ui/api/filled-input/),
1151
+ * [`OutlinedInput`](/material-ui/api/outlined-input/) or [`Input`](/material-ui/api/input/)
1152
+ * component depending on the `variant` prop value.
1153
+ */
1154
+ InputProps: PropTypes.object,
1155
+ /**
1156
+ * Pass a ref to the `input` element.
1157
+ */
1158
+ inputRef: refType,
1159
+ /**
1160
+ * The label content.
1161
+ */
1162
+ label: PropTypes.node,
1163
+ /**
1164
+ * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
1165
+ * @default 'none'
1166
+ */
1167
+ margin: PropTypes.oneOf(['dense', 'none', 'normal']),
1168
+ /**
1169
+ * Maximum number of rows to display when multiline option is set to true.
1170
+ */
1171
+ maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1172
+ /**
1173
+ * Minimum number of rows to display when multiline option is set to true.
1174
+ */
1175
+ minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1176
+ /**
1177
+ * If `true`, a `textarea` element is rendered instead of an input.
1178
+ * @default false
1179
+ */
1180
+ multiline: PropTypes.bool,
1181
+ /**
1182
+ * Name attribute of the `input` element.
1183
+ */
1184
+ name: PropTypes.string,
1185
+ /**
1186
+ * @ignore
1187
+ */
1188
+ onBlur: PropTypes.func,
1189
+ /**
1190
+ * Callback fired when the value is changed.
1191
+ *
1192
+ * @param {object} event The event source of the callback.
1193
+ * You can pull out the new value by accessing `event.target.value` (string).
1194
+ */
1195
+ onChange: PropTypes.func,
1196
+ /**
1197
+ * @ignore
1198
+ */
1199
+ onFocus: PropTypes.func,
1200
+ /**
1201
+ * The short hint displayed in the `input` before the user enters a value.
1202
+ */
1203
+ placeholder: PropTypes.string,
1204
+ /**
1205
+ * If `true`, the label is displayed as required and the `input` element is required.
1206
+ * @default false
1207
+ */
1208
+ required: PropTypes.bool,
1209
+ /**
1210
+ * Number of rows to display when multiline option is set to true.
1211
+ */
1212
+ rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1213
+ /**
1214
+ * Render a [`Select`](/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
1215
+ * If this option is set you must pass the options of the select as children.
1216
+ * @default false
1217
+ */
1218
+ select: PropTypes.bool,
1219
+ /**
1220
+ * Props applied to the [`Select`](/material-ui/api/select/) element.
1221
+ */
1222
+ SelectProps: PropTypes.object,
1223
+ /**
1224
+ * The size of the component.
1225
+ */
1226
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
1227
+ /**
1228
+ * The system prop that allows defining system overrides as well as additional CSS styles.
1229
+ */
1230
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1231
+ /**
1232
+ * 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).
1233
+ */
1234
+ type: PropTypes /* @typescript-to-proptypes-ignore */.string,
1235
+ /**
1236
+ * The value of the `input` element, required for a controlled component.
1237
+ */
1238
+ value: PropTypes.any,
1239
+ /**
1240
+ * The variant to use.
1241
+ * @default 'outlined'
1242
+ */
1243
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
1244
+ } : void 0;
1245
+ var TextField$1 = TextField;
18
1246
 
19
1247
  const SUBMIT_FILTER_STROKE_TIME = 500;
20
1248
  const InputNumberInterval = props => {
@@ -56,7 +1284,7 @@ const InputNumberInterval = props => {
56
1284
  const newLowerBound = event.target.value;
57
1285
  updateFilterValue(newLowerBound, filterValueState[1]);
58
1286
  };
59
- return /*#__PURE__*/React.createElement(Box, {
1287
+ return /*#__PURE__*/React.createElement(Box$1, {
60
1288
  sx: {
61
1289
  display: 'inline-flex',
62
1290
  flexDirection: 'row',
@@ -64,7 +1292,7 @@ const InputNumberInterval = props => {
64
1292
  height: 48,
65
1293
  pl: '20px'
66
1294
  }
67
- }, /*#__PURE__*/React.createElement(TextField, {
1295
+ }, /*#__PURE__*/React.createElement(TextField$1, {
68
1296
  name: "lower-bound-input",
69
1297
  placeholder: "From",
70
1298
  label: "From",
@@ -76,7 +1304,7 @@ const InputNumberInterval = props => {
76
1304
  sx: {
77
1305
  mr: 2
78
1306
  }
79
- }), /*#__PURE__*/React.createElement(TextField, {
1307
+ }), /*#__PURE__*/React.createElement(TextField$1, {
80
1308
  name: "upper-bound-input",
81
1309
  placeholder: "To",
82
1310
  label: "To",
@@ -108,8 +1336,8 @@ const isBetweenOperator = {
108
1336
  if (typeof filterItem.value[0] !== 'number' || typeof filterItem.value[1] !== 'number') {
109
1337
  return null;
110
1338
  }
111
- return value => {
112
- return value !== null && value !== undefined && filterItem.value[0] <= value && value <= filterItem.value[1];
1339
+ return params => {
1340
+ return params.value !== null && params.value !== undefined && filterItem.value[0] <= params.value && params.value <= filterItem.value[1];
113
1341
  };
114
1342
  },
115
1343
  InputComponent: InputNumberInterval
@@ -125,14 +1353,14 @@ const doesNotContain = {
125
1353
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
126
1354
  return null;
127
1355
  }
128
- return value => {
1356
+ return params => {
129
1357
  if (filterItem.value.length === 0) {
130
1358
  return true;
131
1359
  }
132
- if (value == null) {
1360
+ if (params.value == null) {
133
1361
  return true;
134
1362
  }
135
- if (String(value).indexOf(filterItem.value) !== -1) {
1363
+ if (String(params.value).indexOf(filterItem.value) !== -1) {
136
1364
  return false;
137
1365
  }
138
1366
  return true;
@@ -149,11 +1377,11 @@ const doesNotEndWithOperator = {
149
1377
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
150
1378
  return null;
151
1379
  }
152
- return value => {
153
- if (value == null) {
1380
+ return params => {
1381
+ if (params.value == null) {
154
1382
  return true;
155
1383
  }
156
- return !String(value).endsWith(filterItem.value);
1384
+ return !String(params.value).endsWith(filterItem.value);
157
1385
  };
158
1386
  },
159
1387
  InputComponent: GridFilterInputValue
@@ -167,11 +1395,11 @@ const doesNotEqual = {
167
1395
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
168
1396
  return null;
169
1397
  }
170
- return value => {
171
- if (value == null) {
1398
+ return params => {
1399
+ if (params.value == null) {
172
1400
  return true;
173
1401
  }
174
- if (String(value) === filterItem.value) {
1402
+ if (String(params.value) === filterItem.value) {
175
1403
  return false;
176
1404
  }
177
1405
  return true;
@@ -188,11 +1416,11 @@ const doesNotHaveOperator = {
188
1416
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
189
1417
  return null;
190
1418
  }
191
- return value => {
192
- if (value == null) {
1419
+ return params => {
1420
+ if (params.value == null) {
193
1421
  return true;
194
1422
  }
195
- const cellValues = Array.isArray(value) ? value : [value];
1423
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
196
1424
  return !cellValues.map(value => String(value)).includes(filterItem.value);
197
1425
  };
198
1426
  },
@@ -210,11 +1438,11 @@ const doesNotStartWithOperator = {
210
1438
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
211
1439
  return null;
212
1440
  }
213
- return value => {
214
- if (value == null) {
1441
+ return params => {
1442
+ if (params.value == null) {
215
1443
  return true;
216
1444
  }
217
- return !String(value).startsWith(filterItem.value);
1445
+ return !String(params.value).startsWith(filterItem.value);
218
1446
  };
219
1447
  },
220
1448
  InputComponent: GridFilterInputValue
@@ -228,11 +1456,11 @@ const hasOperator = {
228
1456
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
229
1457
  return null;
230
1458
  }
231
- return value => {
232
- if (value == null) {
1459
+ return params => {
1460
+ if (params.value == null) {
233
1461
  return false;
234
1462
  }
235
- const cellValues = Array.isArray(value) ? value : [value];
1463
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
236
1464
  return cellValues.map(value => String(value)).includes(filterItem.value);
237
1465
  };
238
1466
  },
@@ -250,11 +1478,11 @@ const hasOnlyOperator = {
250
1478
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
251
1479
  return null;
252
1480
  }
253
- return value => {
254
- if (value == null) {
1481
+ return params => {
1482
+ if (params.value == null) {
255
1483
  return false;
256
1484
  }
257
- const cellValues = Array.isArray(value) ? value : [value];
1485
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
258
1486
  return cellValues.length === 1 && String(cellValues[0]) === filterItem.value;
259
1487
  };
260
1488
  },
@@ -272,14 +1500,14 @@ const isOperator = {
272
1500
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
273
1501
  return null;
274
1502
  }
275
- return value => {
276
- if (value == null) {
1503
+ return params => {
1504
+ if (params.value == null) {
277
1505
  return false;
278
1506
  }
279
- if (Array.isArray(value)) {
1507
+ if (Array.isArray(params.value)) {
280
1508
  return false;
281
1509
  }
282
- return String(value) === filterItem.value;
1510
+ return String(params.value) === filterItem.value;
283
1511
  };
284
1512
  },
285
1513
  InputComponent: GridFilterInputValue
@@ -296,14 +1524,14 @@ const isNotOperator = {
296
1524
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
297
1525
  return null;
298
1526
  }
299
- return value => {
300
- if (value == null) {
1527
+ return params => {
1528
+ if (params.value == null) {
301
1529
  return true;
302
1530
  }
303
- if (Array.isArray(value)) {
1531
+ if (Array.isArray(params.value)) {
304
1532
  return true;
305
1533
  }
306
- return String(value) !== filterItem.value;
1534
+ return String(params.value) !== filterItem.value;
307
1535
  };
308
1536
  },
309
1537
  InputComponent: GridFilterInputValue
@@ -320,14 +1548,14 @@ const containsAnyOfOperator = {
320
1548
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
321
1549
  return null;
322
1550
  }
323
- return value => {
1551
+ return params => {
324
1552
  if (filterItem.value.length === 0) {
325
1553
  return true;
326
1554
  }
327
- if (value == null) {
1555
+ if (params.value == null) {
328
1556
  return false;
329
1557
  }
330
- const paramValues = Array.isArray(value) ? value : [value];
1558
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
331
1559
  let match = false;
332
1560
  filterItem.value.forEach(filteredValue => {
333
1561
  paramValues.forEach(paramValue => {
@@ -350,14 +1578,14 @@ const doesNotContainAnyOfOperator = {
350
1578
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
351
1579
  return null;
352
1580
  }
353
- return value => {
1581
+ return params => {
354
1582
  if (filterItem.value.length === 0) {
355
1583
  return true;
356
1584
  }
357
- if (value == null) {
1585
+ if (params.value == null) {
358
1586
  return true;
359
1587
  }
360
- const paramValues = Array.isArray(value) ? value : [value];
1588
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
361
1589
  for (const filteredValue of filterItem.value) {
362
1590
  for (const paramValue of paramValues) {
363
1591
  if (String(paramValue).indexOf(filteredValue) !== -1) {
@@ -379,14 +1607,14 @@ const doesNotEndWithAnyOfOperator = {
379
1607
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
380
1608
  return null;
381
1609
  }
382
- return value => {
1610
+ return params => {
383
1611
  if (filterItem.value.length === 0) {
384
1612
  return true;
385
1613
  }
386
- if (value == null) {
1614
+ if (params.value == null) {
387
1615
  return true;
388
1616
  }
389
- const paramValues = Array.isArray(value) ? value : [value];
1617
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
390
1618
  for (const filteredValue of filterItem.value) {
391
1619
  for (const paramValue of paramValues) {
392
1620
  if (String(paramValue).endsWith(filteredValue)) {
@@ -408,11 +1636,11 @@ const doesNotHaveAnyOf = {
408
1636
  if (!filterItem.field || !filterItem.value || !Array.isArray(filterItem.value) || filterItem.value.length === 0) {
409
1637
  return null;
410
1638
  }
411
- return value => {
412
- if (value == null) {
1639
+ return params => {
1640
+ if (params.value == null) {
413
1641
  return true;
414
1642
  }
415
- const cellValues = Array.isArray(value) ? value : [value];
1643
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
416
1644
 
417
1645
  // Return true only if none of the filter values are in the cell values
418
1646
  return filterItem.value.every(filterVal => !cellValues.map(value => String(value)).includes(filterVal));
@@ -432,14 +1660,14 @@ const doesNotStartWithAnyOfOperator = {
432
1660
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
433
1661
  return null;
434
1662
  }
435
- return value => {
1663
+ return params => {
436
1664
  if (filterItem.value.length === 0) {
437
1665
  return true;
438
1666
  }
439
- if (value == null) {
1667
+ if (params.value == null) {
440
1668
  return true;
441
1669
  }
442
- const paramValues = Array.isArray(value) ? value : [value];
1670
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
443
1671
  for (const filteredValue of filterItem.value) {
444
1672
  for (const paramValue of paramValues) {
445
1673
  if (String(paramValue).startsWith(filteredValue)) {
@@ -461,14 +1689,14 @@ const endsWithAnyOfOperator = {
461
1689
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
462
1690
  return null;
463
1691
  }
464
- return value => {
1692
+ return params => {
465
1693
  if (filterItem.value.length === 0) {
466
1694
  return true;
467
1695
  }
468
- if (value == null) {
1696
+ if (params.value == null) {
469
1697
  return false;
470
1698
  }
471
- const paramValues = Array.isArray(value) ? value : [value];
1699
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
472
1700
  let match = false;
473
1701
  filterItem.value.forEach(filteredValue => {
474
1702
  paramValues.forEach(paramValue => {
@@ -491,14 +1719,14 @@ const hasAllOfOperator = {
491
1719
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
492
1720
  return null;
493
1721
  }
494
- return value => {
1722
+ return params => {
495
1723
  if (filterItem.value.length === 0) {
496
1724
  return true;
497
1725
  }
498
- if (value == null) {
1726
+ if (params.value == null) {
499
1727
  return false;
500
1728
  }
501
- const cellValues = Array.isArray(value) ? value : [value];
1729
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
502
1730
  const cellStrings = cellValues.map(value => String(value));
503
1731
  const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
504
1732
  return filterItemValues.every(v => cellStrings.includes(v));
@@ -518,14 +1746,14 @@ const hasAnyOfOperator = {
518
1746
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
519
1747
  return null;
520
1748
  }
521
- return value => {
1749
+ return params => {
522
1750
  if (filterItem.value.length === 0) {
523
1751
  return true;
524
1752
  }
525
- if (value == null) {
1753
+ if (params.value == null) {
526
1754
  return false;
527
1755
  }
528
- const cellValues = Array.isArray(value) ? value : [value];
1756
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
529
1757
  const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
530
1758
  return filterItemValues.some(v => cellValues.map(value => String(value)).includes(v));
531
1759
  };
@@ -544,14 +1772,14 @@ const isAnyOfOperator = {
544
1772
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
545
1773
  return null;
546
1774
  }
547
- return value => {
1775
+ return params => {
548
1776
  if (filterItem.value.length === 0) {
549
1777
  return true;
550
1778
  }
551
- if (value == null) {
1779
+ if (params.value == null) {
552
1780
  return false;
553
1781
  }
554
- const paramValues = Array.isArray(value) ? value : [value];
1782
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
555
1783
  for (const paramValue of paramValues) {
556
1784
  if (filterItem.value.includes(String(paramValue))) {
557
1785
  return true;
@@ -574,14 +1802,14 @@ const isNotAnyOfOperator = {
574
1802
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
575
1803
  return null;
576
1804
  }
577
- return value => {
1805
+ return params => {
578
1806
  if (filterItem.value.length === 0) {
579
1807
  return true;
580
1808
  }
581
- if (value == null) {
1809
+ if (params.value == null) {
582
1810
  return true;
583
1811
  }
584
- const paramValues = Array.isArray(value) ? value : [value];
1812
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
585
1813
  for (const paramValue of paramValues) {
586
1814
  if (filterItem.value.includes(String(paramValue))) {
587
1815
  return false;
@@ -604,14 +1832,14 @@ const startsWithAnyOfOperator = {
604
1832
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
605
1833
  return null;
606
1834
  }
607
- return value => {
1835
+ return params => {
608
1836
  if (filterItem.value.length === 0) {
609
1837
  return true;
610
1838
  }
611
- if (value == null) {
1839
+ if (params.value == null) {
612
1840
  return false;
613
1841
  }
614
- const paramValues = Array.isArray(value) ? value : [value];
1842
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
615
1843
  let match = false;
616
1844
  filterItem.value.forEach(filteredValue => {
617
1845
  paramValues.forEach(paramValue => {
@@ -638,15 +1866,15 @@ const isEmptyOperator = {
638
1866
  value: 'isEmpty',
639
1867
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
640
1868
  getApplyFilterFn: _filterItem => {
641
- return value => {
642
- if (value == null) {
1869
+ return params => {
1870
+ if (params.value == null) {
643
1871
  return true;
644
1872
  }
645
- if (Array.isArray(value)) {
646
- return value.length === 0;
1873
+ if (Array.isArray(params.value)) {
1874
+ return params.value.length === 0;
647
1875
  }
648
- if (typeof value === 'string') {
649
- return value.trim() === '';
1876
+ if (typeof params.value === 'string') {
1877
+ return params.value.trim() === '';
650
1878
  }
651
1879
  return false;
652
1880
  };
@@ -658,15 +1886,15 @@ const isNotEmptyOperator = {
658
1886
  value: 'isNotEmpty',
659
1887
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
660
1888
  getApplyFilterFn: _filterItem => {
661
- return value => {
662
- if (value == null) {
1889
+ return params => {
1890
+ if (params.value == null) {
663
1891
  return false;
664
1892
  }
665
- if (Array.isArray(value)) {
666
- return value.length > 0;
1893
+ if (Array.isArray(params.value)) {
1894
+ return params.value.length > 0;
667
1895
  }
668
- if (typeof value === 'string') {
669
- return value.trim() !== '';
1896
+ if (typeof params.value === 'string') {
1897
+ return params.value.trim() !== '';
670
1898
  }
671
1899
  return true;
672
1900
  };
@@ -705,20 +1933,14 @@ const DIMENSION_MODEL_KEY = 'dimension';
705
1933
  const FILTER_SEARCH_KEY = 'searchModel';
706
1934
  const DENSITY_MODEL_KEY = 'densityModel';
707
1935
  const COLUMN_ORDER_MODEL_KEY = 'columnOrderModel';
708
- const ROW_GROUPING_MODEL_KEY = 'rowGroupingModel';
709
- const AGGREGATION_MODEL_KEY = 'aggregationModel';
710
- /** Storage category key for the pivot column/row/value configuration. Consumer interop — use with `buildStorageKey`. */
711
- const PIVOT_MODEL_KEY = 'pivotModel';
712
- /** Storage category key for whether pivoting is active. Consumer interop — use with `buildStorageKey`. */
713
- const PIVOT_ACTIVE_KEY = 'pivotActive';
714
- 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];
1936
+ 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];
715
1937
  /**
716
1938
  * Build the localStorage key for a specific grid state category.
717
1939
  * Consumers can use this to read or clear individual state entries directly.
718
1940
  *
719
1941
  * @example
720
1942
  * ```ts
721
- * const key = buildStorageKey({ id: pathname, version: 2, category: PIVOT_ACTIVE_KEY });
1943
+ * const key = buildStorageKey({ id: pathname, version: 2, category: 'filterModel' });
722
1944
  * localStorage.removeItem(key);
723
1945
  * ```
724
1946
  */
@@ -768,22 +1990,6 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
768
1990
  id,
769
1991
  version,
770
1992
  category: COLUMN_ORDER_MODEL_KEY
771
- }), buildStorageKey({
772
- id,
773
- version,
774
- category: ROW_GROUPING_MODEL_KEY
775
- }), buildStorageKey({
776
- id,
777
- version,
778
- category: AGGREGATION_MODEL_KEY
779
- }), buildStorageKey({
780
- id,
781
- version,
782
- category: PIVOT_MODEL_KEY
783
- }), buildStorageKey({
784
- id,
785
- version,
786
- category: PIVOT_ACTIVE_KEY
787
1993
  })];
788
1994
  for (const keyToDelete of keysToDelete) {
789
1995
  try {
@@ -858,14 +2064,13 @@ const resetStatefulDataGridState = _ref2 => {
858
2064
  * default (all columns visible). Clears the persisted `visibilityModel`
859
2065
  * localStorage entry for the given versions and strips the `_columnVisibility`
860
2066
  * param from the live URL, leaving every other piece of grid state (filters,
861
- * sort, pivot, pagination, pinned columns, …) untouched.
2067
+ * sort, pagination, pinned columns, …) untouched.
862
2068
  *
863
2069
  * This is the visibility-scoped counterpart to `resetStatefulDataGridState`.
864
- * Reach for it at transition points for example drilling down from pivot
865
- * mode to a flat record view where a stale pivot-era visibility snapshot
866
- * would otherwise re-seed and keep base columns hidden. Because it leaves the
867
- * other params alone it will not clobber a filter the caller is writing in the
868
- * same transition.
2070
+ * Reach for it at transition points where a stale visibility snapshot would
2071
+ * otherwise re-seed and keep base columns hidden. Because it leaves the other
2072
+ * params alone it will not clobber a filter the caller is writing in the same
2073
+ * transition.
869
2074
  *
870
2075
  * Like `resetStatefulDataGridState`, the URL strip reads `window.location.search`
871
2076
  * directly so it operates on the live URL (the caller's captured snapshot may
@@ -915,7 +2120,7 @@ const COMPRESSED_PREFIX = '~';
915
2120
  * Params listed first are compressed first (least valuable to read in the URL).
916
2121
  * The filter aggregate step uses the special key `_filters_aggregate`.
917
2122
  */
918
- const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_aggregation', '_rowGrouping', '_quickFilterValues', '_pivot'];
2123
+ const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_quickFilterValues'];
919
2124
 
920
2125
  /** Params that are always short and should never be compressed. */
921
2126
  const NEVER_COMPRESS = new Set(['_sortColumn', '_pagination', '_density', '_logicOperator', 'v', 'tab']);
@@ -1156,13 +2361,6 @@ const convertToDisplayFormat = search => {
1156
2361
  const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
1157
2362
  const params = cleanSearch.split('&');
1158
2363
  const converted = params.map(param => {
1159
- const eqIndex = param.indexOf('=');
1160
- if (eqIndex !== -1) {
1161
- const value = param.slice(eqIndex + 1);
1162
- // Skip conversion for compressed values — already URL-safe
1163
- if (isCompressed(value)) return param;
1164
- }
1165
-
1166
2364
  // Handle _sortColumn=[field,direction]
1167
2365
  if (param.startsWith('_sortColumn=')) {
1168
2366
  const value = param.slice('_sortColumn='.length);
@@ -1217,6 +2415,7 @@ const convertToDisplayFormat = search => {
1217
2415
  // Handle _columnOrder=[a,b,c]
1218
2416
  if (param.startsWith('_columnOrder=')) {
1219
2417
  const value = param.slice('_columnOrder='.length);
2418
+ if (value.startsWith('~')) return param; // compressed — skip
1220
2419
  if (value.startsWith('[') && value.endsWith(']')) {
1221
2420
  const inner = value.slice(1, -1);
1222
2421
  return `_columnOrder=${inner}`;
@@ -1224,21 +2423,6 @@ const convertToDisplayFormat = search => {
1224
2423
  return param;
1225
2424
  }
1226
2425
 
1227
- // Handle _rowGrouping=[a,b,c]
1228
- if (param.startsWith('_rowGrouping=')) {
1229
- const value = param.slice('_rowGrouping='.length);
1230
- if (value.startsWith('[') && value.endsWith(']')) {
1231
- const inner = value.slice(1, -1);
1232
- return `_rowGrouping=${inner}`;
1233
- }
1234
- return param;
1235
- }
1236
-
1237
- // _aggregation and _pivot do not use bracket notation — pass through
1238
- if (param.startsWith('_aggregation=') || param.startsWith('_pivot=')) {
1239
- return param;
1240
- }
1241
-
1242
2426
  // Handle _field[operator,type]=value or _field[operator,type]=list[a,b,c]
1243
2427
  const bracketMatch = param.match(/^_([^[]+)\[([^\]]+)\]=(.*)$/);
1244
2428
  if (bracketMatch) {
@@ -1278,13 +2462,6 @@ const convertFromDisplayFormat = (search, columns) => {
1278
2462
  const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
1279
2463
  const params = cleanSearch.split('&');
1280
2464
  const converted = params.map(param => {
1281
- const eqIndex = param.indexOf('=');
1282
- if (eqIndex !== -1) {
1283
- const value = param.slice(eqIndex + 1);
1284
- // Skip conversion for compressed values — already URL-safe
1285
- if (isCompressed(value)) return param;
1286
- }
1287
-
1288
2465
  // Handle _sortColumn=field.direction or _sortColumn=
1289
2466
  if (param.startsWith('_sortColumn=')) {
1290
2467
  const value = param.slice('_sortColumn='.length);
@@ -1336,8 +2513,8 @@ const convertFromDisplayFormat = (search, columns) => {
1336
2513
  // Handle _columnVisibility display `a,b,!c` → internal `[a,b,!c]`.
1337
2514
  if (param.startsWith('_columnVisibility=')) {
1338
2515
  const value = param.slice('_columnVisibility='.length);
1339
- // Already internal (bracketed) leave it alone.
1340
- if (value.startsWith('[')) {
2516
+ // If it already has brackets, leave it alone
2517
+ if (value.startsWith('[') || value.startsWith('~')) {
1341
2518
  return param;
1342
2519
  }
1343
2520
  return `_columnVisibility=[${value}]`;
@@ -1346,26 +2523,13 @@ const convertFromDisplayFormat = (search, columns) => {
1346
2523
  // Handle _columnOrder=a,b,c
1347
2524
  if (param.startsWith('_columnOrder=')) {
1348
2525
  const value = param.slice('_columnOrder='.length);
1349
- if (value.startsWith('[')) {
2526
+ // If it already has brackets or is compressed, leave it alone
2527
+ if (value.startsWith('[') || value.startsWith('~')) {
1350
2528
  return param;
1351
2529
  }
1352
2530
  return `_columnOrder=[${value}]`;
1353
2531
  }
1354
2532
 
1355
- // Handle _rowGrouping=a,b,c
1356
- if (param.startsWith('_rowGrouping=')) {
1357
- const value = param.slice('_rowGrouping='.length);
1358
- if (value.startsWith('[')) {
1359
- return param;
1360
- }
1361
- return `_rowGrouping=[${value}]`;
1362
- }
1363
-
1364
- // _aggregation, _pivot, _filters — pass through (no bracket conversion needed)
1365
- if (param.startsWith('_aggregation=') || param.startsWith('_pivot=') || param.startsWith('_filters=')) {
1366
- return param;
1367
- }
1368
-
1369
2533
  // Handle field.operator=value (dot notation for filters)
1370
2534
  const dotMatch = param.match(/^([^.]+)\.([a-zA-Z_]+)=(.*)$/);
1371
2535
  if (dotMatch) {
@@ -1408,10 +2572,9 @@ const getDecodedSearchFromUrl = (search, columns) => {
1408
2572
  const hasPaginationDotNotation = /_pagination=[^&[]+\.[^&]+/.test(searchWithoutLeadingQuestion);
1409
2573
  const hasPinnedWithoutBrackets = /(_pinnedColumnsLeft|_pinnedColumnsRight)=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1410
2574
  const hasVisibilityWithoutBrackets = /_columnVisibility=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1411
- const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1412
- const hasRowGroupingWithoutBrackets = /_rowGrouping=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
2575
+ const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[~]*(&|$)/.test(searchWithoutLeadingQuestion);
1413
2576
  const hasBracketNotation = /\[.*\]=/.test(searchWithoutLeadingQuestion);
1414
- const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets || hasRowGroupingWithoutBrackets) && !hasBracketNotation;
2577
+ const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets) && !hasBracketNotation;
1415
2578
  if (isDisplayFormat) {
1416
2579
  return '?' + convertFromDisplayFormat(searchWithoutLeadingQuestion, columns);
1417
2580
  }
@@ -1536,8 +2699,9 @@ const isValueValid = (value, field, columns, operator) => {
1536
2699
  }
1537
2700
  const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
1538
2701
 
1539
- // Only date and rating fail with 500s, other set themselves as undefined
1540
- if (type !== 'date' && type !== 'rating') {
2702
+ // Only date, dateTime and rating need value validation; other types either
2703
+ // accept any string or reset themselves to undefined.
2704
+ if (type !== 'date' && type !== 'dateTime' && type !== 'rating') {
1541
2705
  return true;
1542
2706
  }
1543
2707
 
@@ -1546,16 +2710,18 @@ const isValueValid = (value, field, columns, operator) => {
1546
2710
  return !isNaN(Number(value));
1547
2711
  }
1548
2712
 
1549
- // format: YYYY-MM-DD
1550
- // just verifying that the 3 values are numbers to avoid 500s,
1551
- // If the value is invalid the form will appear as undefined
2713
+ // format: YYYY-MM-DD — strict, so corrupt/locale/ISO strings (e.g. a
2714
+ // stringified Date, or an ISO value with a `T` suffix) are rejected rather
2715
+ // than reaching a server consumer. Canonical values come from
2716
+ // `normalizeDateValue`.
1552
2717
  if (type === 'date') {
1553
- const dateSplitted = value.split('-');
1554
- if (dateSplitted.length !== 3) {
1555
- return false;
1556
- }
1557
- const [YYYY, MM, DD] = dateSplitted;
1558
- return !isNaN(parseInt(YYYY)) && !isNaN(parseInt(MM)) && !isNaN(parseInt(DD));
2718
+ return /^\d{4}-\d{2}-\d{2}$/.test(value);
2719
+ }
2720
+
2721
+ // format: YYYY-MM-DDTHH:mm:ss — local wall-clock, matching the datetime-local
2722
+ // input (see `normalizeDateValue`).
2723
+ if (type === 'dateTime') {
2724
+ return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(value);
1559
2725
  }
1560
2726
  return false;
1561
2727
  };
@@ -1570,15 +2736,22 @@ const getFilterModelFromString = (searchString, columns) => {
1570
2736
  }
1571
2737
  let logicOperator = GridLogicOperator.And;
1572
2738
  let quickFilterValues = [];
2739
+ // Whether the URL carries explicit filter metadata (`_logicOperator` /
2740
+ // `_quickFilterValues`). Distinguishes an explicit empty filter (which the
2741
+ // grid serialises with `_logicOperator`) from a URL that has no filter params
2742
+ // at all, so the latter can fall through to localStorage. (ODM-3149)
2743
+ let hasFilterMeta = false;
1573
2744
  const searchParams = new URLSearchParams();
1574
2745
  for (const [key, value] of new URLSearchParams(searchString)) {
1575
- if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_rowGrouping', '_aggregation', '_pivot', '_density', '_filters'].includes(key)) {
2746
+ if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_density', '_filters'].includes(key)) {
1576
2747
  searchParams.set(key, value);
1577
2748
  }
1578
2749
  if (key === '_logicOperator') {
2750
+ hasFilterMeta = true;
1579
2751
  logicOperator = value === GridLogicOperator.And || value === GridLogicOperator.Or ? value : GridLogicOperator.And;
1580
2752
  }
1581
2753
  if (key === '_quickFilterValues') {
2754
+ hasFilterMeta = true;
1582
2755
  try {
1583
2756
  quickFilterValues = JSON.parse(decodeURIComponent(value));
1584
2757
  } catch {
@@ -1633,12 +2806,64 @@ const getFilterModelFromString = (searchString, columns) => {
1633
2806
  if (isInvalid) {
1634
2807
  return 'invalid';
1635
2808
  }
2809
+
2810
+ // The URL carries no filter signal at all — no logic operator, no quick filter,
2811
+ // and no valid filter items (e.g. a bare `?period=30` written by another URL
2812
+ // owner before the grid mounts). This is NOT an explicit empty filter, so
2813
+ // return 'invalid' to let the caller fall through to localStorage instead of
2814
+ // returning an empty model that would overwrite the user's persisted filters
2815
+ // (and clobber localStorage on the way out). (ODM-3149)
2816
+ if (items.length === 0 && !hasFilterMeta) {
2817
+ return 'invalid';
2818
+ }
1636
2819
  return {
1637
2820
  items,
1638
2821
  logicOperator,
1639
2822
  quickFilterValues
1640
2823
  };
1641
2824
  };
2825
+
2826
+ /**
2827
+ * Normalises a `date` / `dateTime` filter value to a canonical, URL-safe string
2828
+ * before it is serialised into the URL.
2829
+ *
2830
+ * MUI's `GridFilterInputDate` commits filter values as JS `Date` objects. The
2831
+ * generic `encodeValue` would stringify those via `String(value)`, producing a
2832
+ * locale string (e.g. `"Thu Jun 25 2026 02:00:00 GMT+0200 (…)"`) that cannot
2833
+ * survive the URL round-trip and is rejected by `isValueValid`, silently erasing
2834
+ * the filter value (DS-90). We instead mirror MUI's own
2835
+ * `convertFilterItemValueToInputValue` so the canonical string matches what the
2836
+ * date input renders and round-trips losslessly:
2837
+ * - `date` → `YYYY-MM-DD` (UTC, timezone-stable)
2838
+ * - `dateTime` → `YYYY-MM-DDTHH:mm:ss` (local wall-clock, matching the
2839
+ * datetime-local input)
2840
+ * Non-date types, empty values, arrays of dates (e.g. `isBetween`) and
2841
+ * unparseable values are handled so the existing string / number / list / rating
2842
+ * paths are untouched and invalid values still fall through to `isValueValid`.
2843
+ */
2844
+ const normalizeDateValue = (value, type) => {
2845
+ if (type !== 'date' && type !== 'dateTime') {
2846
+ return value;
2847
+ }
2848
+ if (value === undefined || value === null || value === '') {
2849
+ return value;
2850
+ }
2851
+ if (Array.isArray(value)) {
2852
+ return value.map(entry => normalizeDateValue(entry, type));
2853
+ }
2854
+ const date = value instanceof Date ? value : new Date(value);
2855
+ if (isNaN(date.getTime())) {
2856
+ return value;
2857
+ }
2858
+ if (type === 'date') {
2859
+ return date.toISOString().substring(0, 10);
2860
+ }
2861
+ // dateTime: mirror MUI's datetime-local conversion (subtract the timezone
2862
+ // offset so the serialised wall-clock time matches the rendered input value).
2863
+ const local = new Date(date.getTime());
2864
+ local.setMinutes(local.getMinutes() - local.getTimezoneOffset());
2865
+ return local.toISOString().substring(0, 19);
2866
+ };
1642
2867
  const getSearchParamsFromFilterModel = filterModel => {
1643
2868
  var _filterModel$quickFil;
1644
2869
  const searchParams = new URLSearchParams();
@@ -1650,10 +2875,11 @@ const getSearchParamsFromFilterModel = filterModel => {
1650
2875
  value,
1651
2876
  type
1652
2877
  } = item;
2878
+ const normalizedValue = normalizeDateValue(value, type);
1653
2879
  if (Object.keys(numberOperatorEncoder).includes(operator)) {
1654
- searchParams.set(`_${field}[${numberOperatorEncoder[operator]},${encodeValue(type)}]`, encodeValue(value));
2880
+ searchParams.set(`_${field}[${numberOperatorEncoder[operator]},${encodeValue(type)}]`, encodeValue(normalizedValue));
1655
2881
  } else {
1656
- searchParams.set(`_${field}[${encodeValue(operator)},${encodeValue(type)}]`, encodeValue(value));
2882
+ searchParams.set(`_${field}[${encodeValue(operator)},${encodeValue(type)}]`, encodeValue(normalizedValue));
1657
2883
  }
1658
2884
  });
1659
2885
  if ((_filterModel$quickFil = filterModel.quickFilterValues) !== null && _filterModel$quickFil !== void 0 && _filterModel$quickFil.length) {
@@ -1709,7 +2935,19 @@ const getSortingFromString = (searchString, columns) => {
1709
2935
  }
1710
2936
  const searchParams = new URLSearchParams(searchString);
1711
2937
  const value = searchParams.get('_sortColumn');
1712
- if (value === '' || value === null || value === '[]') {
2938
+
2939
+ // `_sortColumn` absent entirely → the URL is not expressing sort state (e.g. it
2940
+ // only carries a foreign param such as `?period=30` written by another URL
2941
+ // owner before the grid mounts). Return 'invalid' so the caller falls through
2942
+ // to localStorage instead of returning an empty model that would clobber the
2943
+ // user's persisted sort. (ODM-3149)
2944
+ if (value === null) {
2945
+ return 'invalid';
2946
+ }
2947
+
2948
+ // Explicit empty sort (`_sortColumn=` / `_sortColumn=[]`, written when the user
2949
+ // clears sorting) → respect it.
2950
+ if (value === '' || value === '[]') {
1713
2951
  return [];
1714
2952
  }
1715
2953
  const fields = columns.map(column => column.field);
@@ -1855,8 +3093,8 @@ const getColumnVisibilityFromString = (searchString, columns) => {
1855
3093
  // by 12.5.5-muiv8-alpha.5/alpha.6 (replaced by the URL-safe `!` form below — see
1856
3094
  // getSearchParamsFromColumnVisibility). Still parsed so any localStorage entry
1857
3095
  // persisted by those alphas keeps working; never written anymore. The two sets are
1858
- // split on the fixed `];h:[` separator, so a `[` or `]` inside a pivot field name
1859
- // (e.g. `["gmail"]>->email_volume`) does not break parsing.
3096
+ // split on the fixed `];h:[` separator, so a `[` or `]` inside a field name does
3097
+ // not break parsing.
1860
3098
  if (value.startsWith('v:[') && value.endsWith(']') && value.includes('];h:[')) {
1861
3099
  const inner = value.slice('v:['.length, -1);
1862
3100
  const separatorIndex = inner.indexOf('];h:[');
@@ -1946,14 +3184,14 @@ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
1946
3184
  }, columnVisibility);
1947
3185
 
1948
3186
  // Serialise a single comma list over the static columns plus any extra keys present
1949
- // in the model (dynamically-generated pivot fields, preserved in model order).
1950
- // Hidden fields are prefixed `!`; visible fields are bare. This URL-safe form
1951
- // round-trips idempotently through `URLSearchParams.toString()` percent-encoding —
1952
- // the earlier `v:[..];h:[..]` form did NOT (its `:`/`;` were percent-encoded and
1953
- // mis-parsed on read-back, driving an unbounded `history.replace` loop, ODM-3033).
1954
- // `!` (not `~`, which is the compression sentinel — compression.ts COMPRESSED_PREFIX)
1955
- // is used so a leading hidden field can't be mistaken for a compressed value.
1956
- // The hidden set is still explicit, so deselected dynamic columns survive reloads.
3187
+ // in the model (dynamically-generated fields, preserved in model order). Hidden
3188
+ // fields are prefixed `!`; visible fields are bare. This URL-safe form round-trips
3189
+ // idempotently through `URLSearchParams.toString()` percent-encoding — the earlier
3190
+ // `v:[..];h:[..]` form did NOT (its `:`/`;` were percent-encoded and mis-parsed on
3191
+ // read-back, driving an unbounded `history.replace` loop, ODM-3033). `!` (not `~`,
3192
+ // the compression sentinel — compression.ts COMPRESSED_PREFIX) is used so a leading
3193
+ // hidden field can't be mistaken for a compressed value. The hidden set is still
3194
+ // explicit, so deselected dynamic columns survive reloads.
1957
3195
  const allFields = [...fields];
1958
3196
  for (const field of Object.keys(finalColumnVisibility)) {
1959
3197
  if (!allFields.includes(field)) {
@@ -2116,7 +3354,8 @@ const getSearchParamsFromDensity = density => {
2116
3354
  return searchParams;
2117
3355
  };
2118
3356
  const getDensityModel = (search, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion) => {
2119
- // Default density: honour initialState.density if valid, otherwise fall back to 'compact'
3357
+ // MUI v6 GridInitialStatePro does not expose density on its type, but consumers
3358
+ // can still pass it through. Honour it when provided, otherwise fall back to 'compact'.
2120
3359
  const initialDensity = initialState === null || initialState === void 0 ? void 0 : initialState.density;
2121
3360
  const defaultValue = initialDensity && VALID_DENSITIES.includes(initialDensity) ? initialDensity : 'compact';
2122
3361
 
@@ -2169,6 +3408,29 @@ const getSearchParamsFromColumnOrder = columnOrder => {
2169
3408
  }
2170
3409
  return searchParams;
2171
3410
  };
3411
+
3412
+ /**
3413
+ * Builds the `v=<version>` search param the grid uses to detect stale URLs.
3414
+ *
3415
+ * Use this when constructing a deep link or share URL outside the grid (e.g. via
3416
+ * `getSearchParamsFromFilterModel` + `buildQueryParamsString`). The grid itself
3417
+ * always includes `v` in URLs it writes via `getFinalSearch`, but external helpers
3418
+ * do not — include this when you want a stale `localStorageVersion` bump to invalidate
3419
+ * the link. Omitting `v` is also safe: a missing `v` is treated as "current version"
3420
+ * and the URL state is applied as-is.
3421
+ *
3422
+ * @example
3423
+ * const params = new URLSearchParams([
3424
+ * ...getSearchParamsFromFilterModel(filterModel),
3425
+ * ...getSearchParamsFromVersion(1),
3426
+ * ]);
3427
+ * const url = `/my-grid${buildQueryParamsString(urlSearchParamsToString(params))}`;
3428
+ */
3429
+ const getSearchParamsFromVersion = version => {
3430
+ const searchParams = new URLSearchParams();
3431
+ searchParams.set('v', String(version));
3432
+ return searchParams;
3433
+ };
2172
3434
  const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion) => {
2173
3435
  var _initialState$columns4, _initialState$columns5;
2174
3436
  const defaultValue = (_initialState$columns4 = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns5 = initialState.columns) === null || _initialState$columns5 === void 0 ? void 0 : _initialState$columns5.orderedFields) !== null && _initialState$columns4 !== void 0 ? _initialState$columns4 : columns.map(c => c.field);
@@ -2199,342 +3461,43 @@ const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorag
2199
3461
  persistDefault();
2200
3462
  return defaultValue;
2201
3463
  };
2202
-
2203
- /** ROW GROUPING */
2204
-
2205
- const getRowGroupingFromString = searchString => {
2206
- if (!searchString) return 'invalid';
2207
- const searchParams = new URLSearchParams(searchString);
2208
- const value = searchParams.get('_rowGrouping');
2209
- if (value === '' || value === null || value === '[]') return 'invalid';
2210
- const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
2211
- if (!inner) return 'invalid';
2212
- return inner.split(',').filter(Boolean);
2213
- };
2214
- const getSearchParamsFromRowGrouping = rowGrouping => {
2215
- const searchParams = new URLSearchParams();
2216
- if (rowGrouping.length > 0) {
2217
- searchParams.set('_rowGrouping', `[${rowGrouping.join(',')}]`);
2218
- }
2219
- return searchParams;
2220
- };
2221
- const getRowGroupingModel = (search, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion) => {
2222
- var _initialState$rowGrou, _initialState$rowGrou2;
2223
- 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 : [];
2224
- const persistDefault = () => {
2225
- const searchFromDefault = getSearchParamsFromRowGrouping(defaultValue);
2226
- const searchString = urlSearchParamsToString(searchFromDefault);
2227
- if (searchString !== localStorageRowGrouping) {
2228
- setLocalStorageRowGrouping(searchString);
2229
- }
2230
- };
2231
- if (isNewVersion) {
2232
- persistDefault();
2233
- return defaultValue;
2234
- }
2235
- const fromUrl = getRowGroupingFromString(search);
2236
- if (fromUrl !== 'invalid') {
2237
- const searchFromModel = getSearchParamsFromRowGrouping(fromUrl);
2238
- const searchString = urlSearchParamsToString(searchFromModel);
2239
- if (searchString !== localStorageRowGrouping) {
2240
- setLocalStorageRowGrouping(searchString);
2241
- }
2242
- return fromUrl;
2243
- }
2244
- const fromLocalStorage = getRowGroupingFromString(localStorageRowGrouping);
2245
- if (fromLocalStorage !== 'invalid') {
2246
- return fromLocalStorage;
2247
- }
2248
- persistDefault();
2249
- return defaultValue;
2250
- };
2251
-
2252
- /** AGGREGATION */
2253
-
2254
- const getAggregationFromString = searchString => {
2255
- if (!searchString) return 'invalid';
2256
- const searchParams = new URLSearchParams(searchString);
2257
- const value = searchParams.get('_aggregation');
2258
- if (value === '' || value === null) return 'invalid';
2259
-
2260
- // Format: field1.sum,field2.avg or [field1.sum,field2.avg]
2261
- const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
2262
- if (!inner) return 'invalid';
2263
- const model = {};
2264
- for (const entry of inner.split(',')) {
2265
- const dotIndex = entry.lastIndexOf('.');
2266
- if (dotIndex <= 0) return 'invalid';
2267
- const field = entry.slice(0, dotIndex);
2268
- const aggFunc = entry.slice(dotIndex + 1);
2269
- if (!field || !aggFunc) return 'invalid';
2270
- model[field] = aggFunc;
2271
- }
2272
- return Object.keys(model).length > 0 ? model : 'invalid';
2273
- };
2274
- const getSearchParamsFromAggregation = aggregation => {
2275
- const searchParams = new URLSearchParams();
2276
- const entries = Object.entries(aggregation);
2277
- if (entries.length > 0) {
2278
- const value = entries.map(_ref => {
2279
- let [field, aggFunc] = _ref;
2280
- return `${field}.${aggFunc}`;
2281
- }).join(',');
2282
- searchParams.set('_aggregation', value);
2283
- }
2284
- return searchParams;
2285
- };
2286
- const getAggregationModel = (search, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion) => {
2287
- var _initialState$aggrega, _initialState$aggrega2;
2288
- 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 : {};
2289
- const persistDefault = () => {
2290
- const searchFromDefault = getSearchParamsFromAggregation(defaultValue);
2291
- const searchString = urlSearchParamsToString(searchFromDefault);
2292
- if (searchString !== localStorageAggregation) {
2293
- setLocalStorageAggregation(searchString);
2294
- }
2295
- };
2296
- if (isNewVersion) {
2297
- persistDefault();
2298
- return defaultValue;
2299
- }
2300
- const fromUrl = getAggregationFromString(search);
2301
- if (fromUrl !== 'invalid') {
2302
- const searchFromModel = getSearchParamsFromAggregation(fromUrl);
2303
- const searchString = urlSearchParamsToString(searchFromModel);
2304
- if (searchString !== localStorageAggregation) {
2305
- setLocalStorageAggregation(searchString);
2306
- }
2307
- return fromUrl;
2308
- }
2309
- const fromLocalStorage = getAggregationFromString(localStorageAggregation);
2310
- if (fromLocalStorage !== 'invalid') {
2311
- return fromLocalStorage;
2312
- }
2313
- persistDefault();
2314
- return defaultValue;
2315
- };
2316
-
2317
- /** PIVOT */
2318
-
2319
- /** Convert MUI's GridPivotModel → our simplified PivotModel */
2320
- const fromGridPivotModel = model => ({
2321
- columns: model.columns.map(c => c.field),
2322
- rows: model.rows.map(r => r.field),
2323
- values: model.values.map(_ref2 => {
2324
- let {
2325
- field,
2326
- aggFunc
2327
- } = _ref2;
2328
- return {
2329
- field,
2330
- aggFunc
2331
- };
2332
- })
2333
- });
2334
-
2335
- /**
2336
- * Pivot format: `cols:f1,f2;rows:f3;vals:f4.sum,f5.avg`
2337
- */
2338
- const getPivotFromString = searchString => {
2339
- if (!searchString) return 'invalid';
2340
- const searchParams = new URLSearchParams(searchString);
2341
- const value = searchParams.get('_pivot');
2342
- if (value === '' || value === null) return 'invalid';
2343
- const model = {
2344
- columns: [],
2345
- rows: [],
2346
- values: []
2347
- };
2348
- for (const segment of value.split(';')) {
2349
- const colonIndex = segment.indexOf(':');
2350
- if (colonIndex <= 0) return 'invalid';
2351
- const key = segment.slice(0, colonIndex);
2352
- const content = segment.slice(colonIndex + 1);
2353
- if (key === 'cols') {
2354
- model.columns = content ? content.split(',').filter(Boolean) : [];
2355
- } else if (key === 'rows') {
2356
- model.rows = content ? content.split(',').filter(Boolean) : [];
2357
- } else if (key === 'vals') {
2358
- if (!content) continue;
2359
- for (const entry of content.split(',')) {
2360
- const dotIndex = entry.lastIndexOf('.');
2361
- if (dotIndex <= 0) return 'invalid';
2362
- model.values.push({
2363
- field: entry.slice(0, dotIndex),
2364
- aggFunc: entry.slice(dotIndex + 1)
2365
- });
2366
- }
2367
- }
2368
- }
2369
-
2370
- // At least one section must have content
2371
- if (model.columns.length === 0 && model.rows.length === 0 && model.values.length === 0) {
2372
- return 'invalid';
2373
- }
2374
- return model;
2375
- };
2376
- const getSearchParamsFromPivot = pivot => {
2377
- const searchParams = new URLSearchParams();
2378
- const hasContent = pivot.columns.length > 0 || pivot.rows.length > 0 || pivot.values.length > 0;
2379
- if (hasContent) {
2380
- const parts = [];
2381
- parts.push(`cols:${pivot.columns.join(',')}`);
2382
- parts.push(`rows:${pivot.rows.join(',')}`);
2383
- if (pivot.values.length > 0) {
2384
- parts.push(`vals:${pivot.values.map(v => `${v.field}.${v.aggFunc}`).join(',')}`);
2385
- }
2386
- searchParams.set('_pivot', parts.join(';'));
2387
- }
2388
- return searchParams;
2389
- };
2390
- const getPivotModel = (search, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion) => {
2391
- var _initialState$pivotin;
2392
- const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$pivotin = initialState.pivoting) !== null && _initialState$pivotin !== void 0 && _initialState$pivotin.model ? fromGridPivotModel(initialState.pivoting.model) : {
2393
- columns: [],
2394
- rows: [],
2395
- values: []
2396
- };
2397
- const persistDefault = () => {
2398
- const searchFromDefault = getSearchParamsFromPivot(defaultValue);
2399
- const searchString = urlSearchParamsToString(searchFromDefault);
2400
- if (searchString !== localStoragePivot) {
2401
- setLocalStoragePivot(searchString);
2402
- }
2403
- };
2404
- if (isNewVersion) {
2405
- persistDefault();
2406
- return defaultValue;
2407
- }
2408
- const fromUrl = getPivotFromString(search);
2409
- if (fromUrl !== 'invalid') {
2410
- const searchFromModel = getSearchParamsFromPivot(fromUrl);
2411
- const searchString = urlSearchParamsToString(searchFromModel);
2412
- if (searchString !== localStoragePivot) {
2413
- setLocalStoragePivot(searchString);
2414
- }
2415
- return fromUrl;
2416
- }
2417
- const fromLocalStorage = getPivotFromString(localStoragePivot);
2418
- if (fromLocalStorage !== 'invalid') {
2419
- return fromLocalStorage;
2420
- }
2421
- persistDefault();
2422
- return defaultValue;
2423
- };
2424
-
2425
- /** PIVOT ACTIVE */
2426
-
2427
- const getPivotActiveFromString = searchString => {
2428
- if (!searchString) return 'invalid';
2429
- const searchParams = new URLSearchParams(searchString);
2430
- const value = searchParams.get('_pivotActive');
2431
- if (value === 'true') return true;
2432
- if (value === 'false') return false;
2433
- return 'invalid';
2434
- };
2435
- const getSearchParamsFromPivotActive = active => {
2436
- const searchParams = new URLSearchParams();
2437
- searchParams.set('_pivotActive', String(active));
2438
- return searchParams;
2439
- };
2440
-
2441
- /**
2442
- * Builds the `v=<version>` search param the grid uses to detect stale URLs.
2443
- *
2444
- * Use this when constructing a deep link or share URL outside the grid (e.g. via
2445
- * `getSearchParamsFromFilterModel` + `buildQueryParamsString`). The grid itself
2446
- * always includes `v` in URLs it writes via `getFinalSearch`, but external helpers
2447
- * do not — include this when you want a stale `localStorageVersion` bump to invalidate
2448
- * the link. Omitting `v` is also safe: a missing `v` is treated as "current version"
2449
- * and the URL state is applied as-is.
2450
- *
2451
- * @example
2452
- * const params = new URLSearchParams([
2453
- * ...getSearchParamsFromFilterModel(filterModel),
2454
- * ...getSearchParamsFromVersion(1),
2455
- * ]);
2456
- * const url = `/my-grid${buildQueryParamsString(urlSearchParamsToString(params))}`;
2457
- */
2458
- const getSearchParamsFromVersion = version => {
2459
- const searchParams = new URLSearchParams();
2460
- searchParams.set('v', String(version));
2461
- return searchParams;
2462
- };
2463
- const getPivotActive = (search, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion) => {
2464
- var _initialState$pivotin2, _initialState$pivotin3;
2465
- 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;
2466
- const persistDefault = () => {
2467
- const searchFromDefault = getSearchParamsFromPivotActive(defaultValue);
2468
- const searchString = urlSearchParamsToString(searchFromDefault);
2469
- if (searchString !== localStoragePivotActive) {
2470
- setLocalStoragePivotActive(searchString);
2471
- }
2472
- };
2473
- if (isNewVersion) {
2474
- persistDefault();
2475
- return defaultValue;
2476
- }
2477
- const fromUrl = getPivotActiveFromString(search);
2478
- if (fromUrl !== 'invalid') {
2479
- const searchFromModel = getSearchParamsFromPivotActive(fromUrl);
2480
- const searchString = urlSearchParamsToString(searchFromModel);
2481
- if (searchString !== localStoragePivotActive) {
2482
- setLocalStoragePivotActive(searchString);
2483
- }
2484
- return fromUrl;
2485
- }
2486
- const fromLocalStorage = getPivotActiveFromString(localStoragePivotActive);
2487
- if (fromLocalStorage !== 'invalid') {
2488
- return fromLocalStorage;
2489
- }
2490
- persistDefault();
2491
- return defaultValue;
2492
- };
2493
- const getFinalSearch = _ref3 => {
2494
- let {
2495
- search,
2496
- localStorageVersion,
2497
- filterModel,
2498
- sortModel,
2499
- paginationModel,
2500
- columnsVisibilityModel,
2501
- pinnedColumnsModel,
2502
- density,
2503
- columnOrderModel,
2504
- defaultColumnOrder,
2505
- rowGroupingModel,
2506
- aggregationModel,
2507
- pivotModel,
2508
- pivotActive,
2509
- columns
2510
- } = _ref3;
2511
- const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
2512
- const sortModelSearch = getSearchParamsFromSorting(sortModel);
2513
- const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
2514
- const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
2515
- const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
2516
- const densitySearch = getSearchParamsFromDensity(density);
2517
- // Only include _columnOrder in URL when it differs from the default
2518
- const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
2519
- const rowGroupingSearch = getSearchParamsFromRowGrouping(rowGroupingModel);
2520
- const aggregationSearch = getSearchParamsFromAggregation(aggregationModel);
2521
- const pivotSearch = getSearchParamsFromPivot(pivotModel);
2522
- const pivotActiveSearch = getSearchParamsFromPivotActive(pivotActive);
2523
- const tabSearch = getSearchParamsFromTab(search);
2524
- const searchParams = new URLSearchParams();
2525
- for (const [key, value] of new URLSearchParams(search)) {
2526
- if (!key.startsWith('_')) {
2527
- searchParams.set(key, value);
2528
- }
2529
- }
2530
- searchParams.set('v', `${localStorageVersion}`);
3464
+ const getFinalSearch = _ref => {
3465
+ let {
3466
+ search,
3467
+ localStorageVersion,
3468
+ filterModel,
3469
+ sortModel,
3470
+ paginationModel,
3471
+ columnsVisibilityModel,
3472
+ pinnedColumnsModel,
3473
+ density,
3474
+ columnOrderModel,
3475
+ defaultColumnOrder,
3476
+ columns
3477
+ } = _ref;
3478
+ const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
3479
+ const sortModelSearch = getSearchParamsFromSorting(sortModel);
3480
+ const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
3481
+ const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
3482
+ const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
3483
+ const densitySearch = getSearchParamsFromDensity(density);
3484
+ // Only include _columnOrder in URL when it differs from the default
3485
+ const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
3486
+ const tabSearch = getSearchParamsFromTab(search);
3487
+ const searchParams = new URLSearchParams();
3488
+ for (const [key, value] of new URLSearchParams(search)) {
3489
+ if (!key.startsWith('_')) {
3490
+ searchParams.set(key, value);
3491
+ }
3492
+ }
3493
+ searchParams.set('v', `${localStorageVersion}`);
2531
3494
 
2532
3495
  // Add quickFilterValues explicitly if present in filterModel
2533
3496
  if (filterModel.quickFilterValues && filterModel.quickFilterValues.length > 0) {
2534
3497
  // Encode array as JSON string to preserve all values in one param
2535
3498
  searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
2536
3499
  }
2537
- return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch, ...rowGroupingSearch, ...aggregationSearch, ...pivotSearch, ...pivotActiveSearch]);
3500
+ return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch]);
2538
3501
  };
2539
3502
  /** Return the state of the table given the URL and the local storage state */
2540
3503
  const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage) => {
@@ -2574,15 +3537,7 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2574
3537
  localStorageDensity,
2575
3538
  setLocalStorageDensity,
2576
3539
  localStorageColumnOrder,
2577
- setLocalStorageColumnOrder,
2578
- localStorageRowGrouping,
2579
- setLocalStorageRowGrouping,
2580
- localStorageAggregation,
2581
- setLocalStorageAggregation,
2582
- localStoragePivot,
2583
- setLocalStoragePivot,
2584
- localStoragePivotActive,
2585
- setLocalStoragePivotActive
3540
+ setLocalStorageColumnOrder
2586
3541
  } = localStorage;
2587
3542
  const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
2588
3543
  const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
@@ -2591,10 +3546,6 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2591
3546
  const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
2592
3547
  const density = getDensityModel(decodedSearch, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion);
2593
3548
  const columnOrderModel = getColumnOrder(decodedSearch, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion);
2594
- const rowGroupingModel = getRowGroupingModel(decodedSearch, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion);
2595
- const aggregationModel = getAggregationModel(decodedSearch, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion);
2596
- const pivotModel = getPivotModel(decodedSearch, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion);
2597
- const pivotActive = getPivotActive(decodedSearch, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion);
2598
3549
  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);
2599
3550
  const finalSearch = getFinalSearch({
2600
3551
  localStorageVersion,
@@ -2607,10 +3558,6 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2607
3558
  density,
2608
3559
  columnOrderModel,
2609
3560
  defaultColumnOrder,
2610
- rowGroupingModel,
2611
- aggregationModel,
2612
- pivotModel,
2613
- pivotActive,
2614
3561
  columns
2615
3562
  });
2616
3563
  const internalSearchString = urlSearchParamsToString(finalSearch);
@@ -2631,14 +3578,10 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2631
3578
  pinnedColumnsModel,
2632
3579
  density,
2633
3580
  columnOrderModel,
2634
- rowGroupingModel,
2635
- aggregationModel,
2636
- pivotModel,
2637
- pivotActive,
2638
3581
  pendingSearch
2639
3582
  };
2640
3583
  };
2641
- const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
3584
+ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns) => {
2642
3585
  let {
2643
3586
  filterModel,
2644
3587
  sortModel,
@@ -2647,12 +3590,8 @@ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns)
2647
3590
  pinnedColumnsModel,
2648
3591
  density,
2649
3592
  columnOrderModel,
2650
- defaultColumnOrder,
2651
- rowGroupingModel,
2652
- aggregationModel,
2653
- pivotModel,
2654
- pivotActive
2655
- } = _ref4;
3593
+ defaultColumnOrder
3594
+ } = _ref2;
2656
3595
  // Convert from display format to internal format if needed
2657
3596
  const decodedSearch = getDecodedSearchFromUrl(search, columns);
2658
3597
  const newSearch = getFinalSearch({
@@ -2666,10 +3605,6 @@ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns)
2666
3605
  density,
2667
3606
  columnOrderModel,
2668
3607
  defaultColumnOrder,
2669
- rowGroupingModel,
2670
- aggregationModel,
2671
- pivotModel,
2672
- pivotActive,
2673
3608
  columns
2674
3609
  });
2675
3610
  const internalSearchString = urlSearchParamsToString(newSearch);
@@ -2748,7 +3683,12 @@ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2748
3683
  * Also handles the `_filters` aggregate param: expands it back into individual filter params.
2749
3684
  */
2750
3685
  const decompressSearchParams = search => {
2751
- if (!search || !search.includes('~')) return search;
3686
+ // The `~` compression sentinel is form-encoded to `%7E` by URLSearchParams
3687
+ // (which the React Router adapter uses when it writes the URL), so a literal-`~`
3688
+ // check alone would skip decompression of every adapter-written compressed
3689
+ // value — leaving the payload compressed and unreadable. Detect both forms; the
3690
+ // URLSearchParams parse below decodes `%7E` back to `~` for `decompressValue`. (ODM-2833)
3691
+ if (!search || !search.includes('~') && !/%7[eE]/.test(search)) return search;
2752
3692
  const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
2753
3693
  const params = new URLSearchParams(cleanSearch);
2754
3694
  const result = new URLSearchParams();
@@ -2857,26 +3797,6 @@ const useTableStates = (id, version) => {
2857
3797
  version,
2858
3798
  category: COLUMN_ORDER_MODEL_KEY
2859
3799
  }));
2860
- const [rowGroupingModel, setRowGroupingModel] = useFetchState('', buildStorageKey({
2861
- id,
2862
- version,
2863
- category: ROW_GROUPING_MODEL_KEY
2864
- }));
2865
- const [aggregationModel, setAggregationModel] = useFetchState('', buildStorageKey({
2866
- id,
2867
- version,
2868
- category: AGGREGATION_MODEL_KEY
2869
- }));
2870
- const [pivotModel, setPivotModel] = useFetchState('', buildStorageKey({
2871
- id,
2872
- version,
2873
- category: PIVOT_MODEL_KEY
2874
- }));
2875
- const [pivotActive, setPivotActive] = useFetchState('', buildStorageKey({
2876
- id,
2877
- version,
2878
- category: PIVOT_ACTIVE_KEY
2879
- }));
2880
3800
  return {
2881
3801
  paginationModel,
2882
3802
  setPaginationModel,
@@ -2893,55 +3813,10 @@ const useTableStates = (id, version) => {
2893
3813
  densityModel,
2894
3814
  setDensityModel,
2895
3815
  columnOrderModel,
2896
- setColumnOrderModel,
2897
- rowGroupingModel,
2898
- setRowGroupingModel,
2899
- aggregationModel,
2900
- setAggregationModel,
2901
- pivotModel,
2902
- setPivotModel,
2903
- pivotActive,
2904
- setPivotActive
3816
+ setColumnOrderModel
2905
3817
  };
2906
3818
  };
2907
3819
 
2908
- /** Convert our simplified PivotModel → MUI's GridPivotModel */
2909
- const toGridPivotModel = model => ({
2910
- columns: model.columns.map(field => ({
2911
- field
2912
- })),
2913
- rows: model.rows.map(field => ({
2914
- field
2915
- })),
2916
- values: model.values.map(_ref => {
2917
- let {
2918
- field,
2919
- aggFunc
2920
- } = _ref;
2921
- return {
2922
- field,
2923
- aggFunc
2924
- };
2925
- })
2926
- });
2927
-
2928
- /**
2929
- * Deep-equal comparison for plain objects / arrays.
2930
- * Used to stabilise parsed model references so that MUI v8 does not
2931
- * reset pagination on every render.
2932
- */
2933
- function isDeepEqual(a, b) {
2934
- if (a === b) return true;
2935
- if (a == null || b == null) return false;
2936
- if (typeof a !== typeof b) return false;
2937
- if (typeof a !== 'object') return false;
2938
- const aObj = a;
2939
- const bObj = b;
2940
- const aKeys = Object.keys(aObj);
2941
- const bKeys = Object.keys(bObj);
2942
- if (aKeys.length !== bKeys.length) return false;
2943
- return aKeys.every(key => isDeepEqual(aObj[key], bObj[key]));
2944
- }
2945
3820
  const useStatefulTable = props => {
2946
3821
  var _initialState$columns, _initialState$columns2;
2947
3822
  const {
@@ -2954,9 +3829,6 @@ const useStatefulTable = props => {
2954
3829
  onPaginationModelChange: propsOnPaginationModelChange,
2955
3830
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
2956
3831
  onSortModelChange: propsOnSortModelChange,
2957
- onRowGroupingModelChange: propsOnRowGroupingModelChange,
2958
- onAggregationModelChange: propsOnAggregationModelChange,
2959
- onPivotModelChange: propsOnPivotModelChange,
2960
3832
  useRouter,
2961
3833
  localStorageVersion = 1,
2962
3834
  previousLocalStorageVersions = []
@@ -2985,24 +3857,16 @@ const useStatefulTable = props => {
2985
3857
  densityModel,
2986
3858
  setDensityModel,
2987
3859
  columnOrderModel: localStorageColumnOrder,
2988
- setColumnOrderModel: setLocalStorageColumnOrder,
2989
- rowGroupingModel: localStorageRowGrouping,
2990
- setRowGroupingModel: setLocalStorageRowGrouping,
2991
- aggregationModel: localStorageAggregation,
2992
- setAggregationModel: setLocalStorageAggregation,
2993
- pivotModel: localStoragePivot,
2994
- setPivotModel: setLocalStoragePivot,
2995
- pivotActive: localStoragePivotActive,
2996
- setPivotActive: setLocalStoragePivotActive
3860
+ setColumnOrderModel: setLocalStorageColumnOrder
2997
3861
  } = useTableStates(id, localStorageVersion);
2998
3862
 
2999
3863
  // clearing up old version keys, triggering only on first render
3000
3864
  useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
3001
- const onColumnDimensionChange = useCallback(_ref2 => {
3865
+ const onColumnDimensionChange = useCallback(_ref => {
3002
3866
  let {
3003
3867
  newWidth,
3004
3868
  field
3005
- } = _ref2;
3869
+ } = _ref;
3006
3870
  setDimensionModel(_objectSpread2(_objectSpread2({}, dimensionModel), {}, {
3007
3871
  [field]: newWidth
3008
3872
  }));
@@ -3015,10 +3879,6 @@ const useStatefulTable = props => {
3015
3879
  pinnedColumnsModel,
3016
3880
  density: densityParsed,
3017
3881
  columnOrderModel: columnOrderParsed,
3018
- rowGroupingModel: rowGroupingParsed,
3019
- aggregationModel: aggregationParsed,
3020
- pivotModel: pivotParsed,
3021
- pivotActive: pivotActiveParsed,
3022
3882
  pendingSearch
3023
3883
  } = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, initialState, {
3024
3884
  localStorageFilters,
@@ -3034,15 +3894,7 @@ const useStatefulTable = props => {
3034
3894
  localStorageDensity: densityModel,
3035
3895
  setLocalStorageDensity: setDensityModel,
3036
3896
  localStorageColumnOrder,
3037
- setLocalStorageColumnOrder,
3038
- localStorageRowGrouping,
3039
- setLocalStorageRowGrouping,
3040
- localStorageAggregation,
3041
- setLocalStorageAggregation,
3042
- localStoragePivot,
3043
- setLocalStoragePivot,
3044
- localStoragePivotActive: localStoragePivotActive,
3045
- setLocalStoragePivotActive: setLocalStoragePivotActive
3897
+ setLocalStorageColumnOrder
3046
3898
  });
3047
3899
 
3048
3900
  // Sync URL in an effect rather than during render to comply with React rules
@@ -3051,45 +3903,6 @@ const useStatefulTable = props => {
3051
3903
  historyReplace(pendingSearch);
3052
3904
  }
3053
3905
  }, [pendingSearch, historyReplace]);
3054
-
3055
- // Stabilise parsed model references to prevent MUI v8 from resetting
3056
- // pagination on every render due to new object identity.
3057
- const filterParsedRef = useRef(filterParsed);
3058
- if (!isDeepEqual(filterParsedRef.current, filterParsed)) {
3059
- filterParsedRef.current = filterParsed;
3060
- }
3061
- const sortModelParsedRef = useRef(sortModelParsed);
3062
- if (!isDeepEqual(sortModelParsedRef.current, sortModelParsed)) {
3063
- sortModelParsedRef.current = sortModelParsed;
3064
- }
3065
- const paginationModelParsedRef = useRef(paginationModelParsed);
3066
- if (!isDeepEqual(paginationModelParsedRef.current, paginationModelParsed)) {
3067
- paginationModelParsedRef.current = paginationModelParsed;
3068
- }
3069
- const visibilityModelRef = useRef(visibilityModel);
3070
- if (!isDeepEqual(visibilityModelRef.current, visibilityModel)) {
3071
- visibilityModelRef.current = visibilityModel;
3072
- }
3073
- const pinnedColumnsModelRef = useRef(pinnedColumnsModel);
3074
- if (!isDeepEqual(pinnedColumnsModelRef.current, pinnedColumnsModel)) {
3075
- pinnedColumnsModelRef.current = pinnedColumnsModel;
3076
- }
3077
- const columnOrderParsedRef = useRef(columnOrderParsed);
3078
- if (!isDeepEqual(columnOrderParsedRef.current, columnOrderParsed)) {
3079
- columnOrderParsedRef.current = columnOrderParsed;
3080
- }
3081
- const rowGroupingParsedRef = useRef(rowGroupingParsed);
3082
- if (!isDeepEqual(rowGroupingParsedRef.current, rowGroupingParsed)) {
3083
- rowGroupingParsedRef.current = rowGroupingParsed;
3084
- }
3085
- const aggregationParsedRef = useRef(aggregationParsed);
3086
- if (!isDeepEqual(aggregationParsedRef.current, aggregationParsed)) {
3087
- aggregationParsedRef.current = aggregationParsed;
3088
- }
3089
- const pivotParsedRef = useRef(pivotParsed);
3090
- if (!isDeepEqual(pivotParsedRef.current, pivotParsed)) {
3091
- pivotParsedRef.current = pivotParsed;
3092
- }
3093
3906
  const columns = useMemo(() => propsColumns.map(column => {
3094
3907
  return _objectSpread2(_objectSpread2({}, column), {}, {
3095
3908
  width: dimensionModel[column.field] || column.width || 100
@@ -3098,61 +3911,56 @@ const useStatefulTable = props => {
3098
3911
  if (apiRef.current) {
3099
3912
  /** Add resetPage method to apiRef. */
3100
3913
  apiRef.current.resetPage = () => {
3101
- var _apiRef$current;
3102
- (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPage(0);
3914
+ apiRef.current.setPage(0);
3103
3915
  };
3104
3916
  }
3105
3917
  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);
3106
3918
 
3919
+ // Helper to build the current DataGridModel for updateUrl calls
3920
+ const buildModel = function () {
3921
+ var _apiRef$current$state, _apiRef$current;
3922
+ let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3923
+ return _objectSpread2({
3924
+ filterModel: filterParsed,
3925
+ sortModel: sortModelParsed,
3926
+ paginationModel: paginationModelParsed,
3927
+ 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 : {},
3928
+ pinnedColumnsModel: pinnedColumnsModel,
3929
+ density: densityParsed,
3930
+ columnOrderModel: columnOrderParsed,
3931
+ defaultColumnOrder
3932
+ }, overrides);
3933
+ };
3934
+
3107
3935
  // Subscribe to density changes via stateChange event (MUI v6 has no densityChange event)
3108
3936
  useEffect(() => {
3109
3937
  const api = apiRef.current;
3110
3938
  if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
3111
3939
  let prevDensity = densityParsed;
3112
3940
  const unsub = api.subscribeEvent('stateChange', () => {
3113
- const currentDensity = api.state.density;
3941
+ const currentDensity = api.state.density.value;
3114
3942
  if (currentDensity !== prevDensity) {
3115
3943
  prevDensity = currentDensity;
3116
- updateUrl({
3117
- filterModel: filterParsed,
3118
- sortModel: sortModelParsed,
3119
- paginationModel: paginationModelParsed,
3944
+ updateUrl(buildModel({
3120
3945
  columnsModel: api.state.columns.columnVisibilityModel,
3121
- pinnedColumnsModel: pinnedColumnsModel,
3122
- density: currentDensity,
3123
- columnOrderModel: columnOrderParsed,
3124
- defaultColumnOrder,
3125
- rowGroupingModel: rowGroupingParsed,
3126
- aggregationModel: aggregationParsed,
3127
- pivotModel: pivotParsed,
3128
- pivotActive: pivotActiveParsed
3129
- }, search, localStorageVersion, historyReplace, columns);
3946
+ density: currentDensity
3947
+ }), search, localStorageVersion, historyReplace, columns);
3130
3948
  }
3131
3949
  });
3132
3950
  return unsub;
3133
- }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
3951
+ }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, search, localStorageVersion, historyReplace, columns]);
3134
3952
 
3135
3953
  // Subscribe to column order changes via columnOrderChange (drag-drop) and columnIndexChange (programmatic setColumnIndex)
3136
3954
  useEffect(() => {
3137
3955
  const api = apiRef.current;
3138
3956
  if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
3957
+ const isDeepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
3139
3958
  const handleColumnOrderChange = () => {
3140
3959
  const orderedFields = api.state.columns.orderedFields;
3141
3960
  if (orderedFields && !isDeepEqual(orderedFields, columnOrderParsed)) {
3142
- updateUrl({
3143
- filterModel: filterParsed,
3144
- sortModel: sortModelParsed,
3145
- paginationModel: paginationModelParsed,
3146
- columnsModel: api.state.columns.columnVisibilityModel,
3147
- pinnedColumnsModel,
3148
- density: densityParsed,
3149
- columnOrderModel: orderedFields,
3150
- defaultColumnOrder,
3151
- rowGroupingModel: rowGroupingParsed,
3152
- aggregationModel: aggregationParsed,
3153
- pivotModel: pivotParsed,
3154
- pivotActive: pivotActiveParsed
3155
- }, search, localStorageVersion, historyReplace, columns);
3961
+ updateUrl(buildModel({
3962
+ columnOrderModel: orderedFields
3963
+ }), search, localStorageVersion, historyReplace, columns);
3156
3964
  }
3157
3965
  };
3158
3966
  const unsub1 = api.subscribeEvent('columnOrderChange', handleColumnOrderChange);
@@ -3161,120 +3969,69 @@ const useStatefulTable = props => {
3161
3969
  unsub1();
3162
3970
  unsub2();
3163
3971
  };
3164
- }, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
3165
-
3166
- // Helper to build the current DataGridModel for updateUrl calls
3167
- const buildModel = function () {
3168
- var _apiRef$current$state, _apiRef$current2;
3169
- let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3170
- return _objectSpread2({
3171
- filterModel: filterParsed,
3172
- sortModel: sortModelParsed,
3173
- paginationModel: paginationModelParsed,
3174
- 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 : {},
3175
- pinnedColumnsModel: pinnedColumnsModel,
3176
- density: densityParsed,
3177
- columnOrderModel: columnOrderParsed,
3178
- defaultColumnOrder,
3179
- rowGroupingModel: rowGroupingParsed,
3180
- aggregationModel: aggregationParsed,
3181
- pivotModel: pivotParsed,
3182
- pivotActive: pivotActiveParsed
3183
- }, overrides);
3184
- };
3185
-
3186
- // Stable GridPivotModel identity — only recompute when the simplified value changes.
3187
- // eslint-disable-next-line react-hooks/exhaustive-deps
3188
- const pivotModelMui = useMemo(() => toGridPivotModel(pivotParsed), [JSON.stringify(pivotParsed)]);
3972
+ }, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, search, localStorageVersion, historyReplace, columns]);
3189
3973
 
3190
3974
  // Track last emitted values for deep-equal guards to avoid feedback loops.
3191
- // Initialised from the current parsed values; updated only when we actually fire.
3192
3975
  const lastEmittedFilterRef = useRef(filterParsed);
3193
3976
  const lastEmittedSortRef = useRef(sortModelParsed);
3194
3977
  const lastEmittedPaginationRef = useRef(paginationModelParsed);
3195
- const lastEmittedPivotRef = useRef(pivotParsed);
3978
+ const isModelDeepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
3196
3979
  return {
3197
3980
  apiRef,
3198
3981
  columns,
3199
3982
  density: densityParsed,
3200
- columnOrderModel: columnOrderParsedRef.current,
3201
- rowGroupingModel: rowGroupingParsedRef.current,
3202
- aggregationModel: aggregationParsedRef.current,
3203
- pivotModel: pivotModelMui,
3204
- pivotActive: pivotActiveParsed,
3983
+ columnOrderModel: columnOrderParsed,
3205
3984
  onFilterModelChange: (model, details) => {
3206
3985
  const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
3207
3986
  items: model.items.map(item => {
3208
- var _apiRef$current3;
3209
- const column = (_apiRef$current3 = apiRef.current) === null || _apiRef$current3 === void 0 ? void 0 : _apiRef$current3.getColumn(item.field);
3210
- item.type = (column === null || column === void 0 ? void 0 : column.type) || 'string';
3987
+ const column = apiRef.current.getColumn(item.field);
3988
+ item.type = column.type || 'string';
3211
3989
  return item;
3212
3990
  }),
3213
3991
  quickFilterValues: model.quickFilterValues || []
3214
3992
  });
3215
- if (isDeepEqual(filterModel, lastEmittedFilterRef.current)) return;
3993
+ if (isModelDeepEqual(filterModel, lastEmittedFilterRef.current)) return;
3216
3994
  lastEmittedFilterRef.current = filterModel;
3995
+ propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
3217
3996
  updateUrl(buildModel({
3218
3997
  filterModel
3219
3998
  }), search, localStorageVersion, historyReplace, columns);
3220
- propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
3221
3999
  },
3222
- filterModel: filterParsedRef.current,
4000
+ filterModel: filterParsed,
3223
4001
  onSortModelChange: (model, details) => {
3224
- if (isDeepEqual(model, lastEmittedSortRef.current)) return;
4002
+ if (isModelDeepEqual(model, lastEmittedSortRef.current)) return;
3225
4003
  lastEmittedSortRef.current = model;
4004
+ propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
3226
4005
  updateUrl(buildModel({
3227
4006
  sortModel: model
3228
4007
  }), search, localStorageVersion, historyReplace, columns);
3229
- propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
3230
4008
  },
3231
- sortModel: sortModelParsedRef.current,
4009
+ sortModel: sortModelParsed,
3232
4010
  onPinnedColumnsChange: (pinnedColumns, details) => {
3233
- var _apiRef$current$state2, _apiRef$current4, _apiRef$current4$stat, _apiRef$current4$stat2;
3234
- // While pivot mode is active, MUI Premium emits synthetic pinned-column
3235
- // models (e.g. `__row_group_by_columns_group__` for the grouping column)
3236
- // that must not be persisted to the URL / localStorage. Read the live
3237
- // grid state from apiRef rather than the parsed URL value because the
3238
- // URL lags by a tick during pivot enable/disable transitions. Consumer
3239
- // callbacks are always forwarded so observers can still react.
3240
- const pivotActiveLive = (_apiRef$current$state2 = (_apiRef$current4 = apiRef.current) === null || _apiRef$current4 === void 0 ? void 0 : (_apiRef$current4$stat = _apiRef$current4.state) === null || _apiRef$current4$stat === void 0 ? void 0 : (_apiRef$current4$stat2 = _apiRef$current4$stat.pivoting) === null || _apiRef$current4$stat2 === void 0 ? void 0 : _apiRef$current4$stat2.active) !== null && _apiRef$current$state2 !== void 0 ? _apiRef$current$state2 : pivotActiveParsed;
3241
- if (!pivotActiveLive) {
3242
- updateUrl(buildModel({
3243
- pinnedColumnsModel: pinnedColumns
3244
- }), search, localStorageVersion, historyReplace, columns);
3245
- }
3246
4011
  propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
4012
+ updateUrl(buildModel({
4013
+ pinnedColumnsModel: pinnedColumns
4014
+ }), search, localStorageVersion, historyReplace, columns);
3247
4015
  },
3248
- pinnedColumns: pinnedColumnsModelRef.current,
3249
- paginationModel: paginationModelParsedRef.current,
4016
+ pinnedColumns: pinnedColumnsModel,
4017
+ paginationModel: paginationModelParsed,
3250
4018
  onPaginationModelChange: (model, details) => {
3251
4019
  const paginationModel = _objectSpread2(_objectSpread2({}, model), {}, {
3252
4020
  direction: paginationModelParsed.page < model.page ? 'next' : 'back'
3253
4021
  });
3254
- if (isDeepEqual(paginationModel, lastEmittedPaginationRef.current)) return;
4022
+ if (isModelDeepEqual(paginationModel, lastEmittedPaginationRef.current)) return;
3255
4023
  lastEmittedPaginationRef.current = paginationModel;
4024
+ propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
3256
4025
  updateUrl(buildModel({
3257
4026
  paginationModel
3258
4027
  }), search, localStorageVersion, historyReplace, columns);
3259
- propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
3260
4028
  },
3261
- columnVisibilityModel: visibilityModelRef.current,
4029
+ columnVisibilityModel: visibilityModel,
3262
4030
  onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
3263
- var _apiRef$current$state3, _apiRef$current5, _apiRef$current5$stat, _apiRef$current5$stat2;
3264
- // While pivot mode is active, MUI Premium emits synthetic visibility
3265
- // models that whitelist only the pivot value fields (hiding every base
3266
- // column). Persisting that to the URL would re-hide all base columns
3267
- // on the next load (see getColumnVisibilityFromString whitelist logic).
3268
- // Read the live grid state rather than the parsed URL value because the
3269
- // URL lags by a tick during pivot enable/disable transitions. Consumer
3270
- // callbacks are always forwarded.
3271
- const pivotActiveLive = (_apiRef$current$state3 = (_apiRef$current5 = apiRef.current) === null || _apiRef$current5 === void 0 ? void 0 : (_apiRef$current5$stat = _apiRef$current5.state) === null || _apiRef$current5$stat === void 0 ? void 0 : (_apiRef$current5$stat2 = _apiRef$current5$stat.pivoting) === null || _apiRef$current5$stat2 === void 0 ? void 0 : _apiRef$current5$stat2.active) !== null && _apiRef$current$state3 !== void 0 ? _apiRef$current$state3 : pivotActiveParsed;
3272
- if (!pivotActiveLive) {
3273
- updateUrl(buildModel({
3274
- columnsModel: columnsVisibilityModel
3275
- }), search, localStorageVersion, historyReplace, columns);
3276
- }
3277
4031
  propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
4032
+ updateUrl(buildModel({
4033
+ columnsModel: columnsVisibilityModel
4034
+ }), search, localStorageVersion, historyReplace, columns);
3278
4035
  },
3279
4036
  onColumnWidthChange: (params, event, details) => {
3280
4037
  propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
@@ -3282,38 +4039,11 @@ const useStatefulTable = props => {
3282
4039
  newWidth: params.width,
3283
4040
  field: params.colDef.field
3284
4041
  });
3285
- },
3286
- onRowGroupingModelChange: (model, details) => {
3287
- updateUrl(buildModel({
3288
- rowGroupingModel: model
3289
- }), search, localStorageVersion, historyReplace, columns);
3290
- propsOnRowGroupingModelChange === null || propsOnRowGroupingModelChange === void 0 ? void 0 : propsOnRowGroupingModelChange(model, details);
3291
- },
3292
- onAggregationModelChange: (model, details) => {
3293
- updateUrl(buildModel({
3294
- aggregationModel: model
3295
- }), search, localStorageVersion, historyReplace, columns);
3296
- propsOnAggregationModelChange === null || propsOnAggregationModelChange === void 0 ? void 0 : propsOnAggregationModelChange(model, details);
3297
- },
3298
- onPivotModelChange: model => {
3299
- const simplified = fromGridPivotModel(model);
3300
- if (isDeepEqual(simplified, lastEmittedPivotRef.current)) return;
3301
- lastEmittedPivotRef.current = simplified;
3302
- updateUrl(buildModel({
3303
- pivotModel: simplified
3304
- }), search, localStorageVersion, historyReplace, columns);
3305
- propsOnPivotModelChange === null || propsOnPivotModelChange === void 0 ? void 0 : propsOnPivotModelChange(model);
3306
- },
3307
- onPivotActiveChange: active => {
3308
- if (active === pivotActiveParsed) return;
3309
- updateUrl(buildModel({
3310
- pivotActive: active
3311
- }), search, localStorageVersion, historyReplace, columns);
3312
4042
  }
3313
4043
  };
3314
4044
  };
3315
4045
 
3316
- 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", "selectionBannerPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount", "density", "dataSource", "filterMode", "sortingMode"];
4046
+ 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", "selectionBannerPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount"];
3317
4047
  const COMPONENT_NAME = 'DataGrid';
3318
4048
  const CLASSNAME = 'redsift-datagrid';
3319
4049
 
@@ -3397,9 +4127,6 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3397
4127
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
3398
4128
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
3399
4129
  onSortModelChange: propsOnSortModelChange,
3400
- onRowGroupingModelChange: propsOnRowGroupingModelChange,
3401
- onAggregationModelChange: propsOnAggregationModelChange,
3402
- onPivotModelChange: propsOnPivotModelChange,
3403
4130
  pagination,
3404
4131
  paginationPlacement = 'both',
3405
4132
  selectionBannerPlacement = 'top',
@@ -3410,26 +4137,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3410
4137
  theme: propsTheme,
3411
4138
  useRouter,
3412
4139
  paginationMode = 'client',
3413
- rowCount,
3414
- density: _density,
3415
- dataSource,
3416
- filterMode: propsFilterMode,
3417
- sortingMode: propsSortingMode
4140
+ rowCount
3418
4141
  } = props,
3419
4142
  forwardedProps = _objectWithoutProperties(props, _excluded);
3420
- const theme = useTheme(propsTheme);
4143
+ const theme = useTheme$1(propsTheme);
3421
4144
  const _apiRef = useGridApiRef();
3422
4145
  const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
4146
+ const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
3423
4147
  LicenseInfo.setLicenseKey(license);
3424
4148
  const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
3425
-
3426
- // When dataSource is present, MUI manages filter/sort/pagination internally.
3427
- // We must not pass controlled models — only initialState (one-time) and
3428
- // write-only onChange handlers for URL/localStorage persistence.
3429
- const isDataSourceMode = Boolean(dataSource);
3430
- const effectivePaginationMode = isDataSourceMode ? 'server' : paginationMode;
3431
- const effectiveFilterMode = isDataSourceMode ? 'server' : propsFilterMode;
3432
- const effectiveSortingMode = isDataSourceMode ? 'server' : propsSortingMode;
3433
4149
  const {
3434
4150
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
3435
4151
  onFilterModelChange: controlledOnFilterModelChange,
@@ -3463,15 +4179,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3463
4179
  pinnedColumns,
3464
4180
  sortModel,
3465
4181
  onColumnWidthChange,
3466
- columnOrderModel,
3467
- rowGroupingModel,
3468
- aggregationModel,
3469
- pivotModel,
3470
- pivotActive,
3471
- onRowGroupingModelChange,
3472
- onAggregationModelChange,
3473
- onPivotModelChange,
3474
- onPivotActiveChange
4182
+ columnOrderModel
3475
4183
  } = useStatefulTable({
3476
4184
  apiRef: apiRef,
3477
4185
  initialState,
@@ -3482,68 +4190,44 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3482
4190
  onPaginationModelChange: controlledOnPaginationModelChange,
3483
4191
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
3484
4192
  onSortModelChange: controlledOnSortModelChange,
3485
- onRowGroupingModelChange: propsOnRowGroupingModelChange,
3486
- onAggregationModelChange: propsOnAggregationModelChange,
3487
- onPivotModelChange: propsOnPivotModelChange,
3488
4193
  useRouter: useRouter,
3489
4194
  localStorageVersion,
3490
4195
  previousLocalStorageVersions
3491
4196
  });
3492
4197
 
3493
- // In dataSource mode, track pagination locally for the custom pagination slots
3494
- // (rendered outside DataGridPremium). MUI owns the actual pagination state internally.
3495
- const [dataSourcePaginationModel, setDataSourcePaginationModel] = useState(paginationModel);
3496
-
3497
- // The pagination model to use for display in pagination slots
3498
- const activePaginationModel = isDataSourceMode ? dataSourcePaginationModel : paginationModel;
3499
-
3500
- // Wrap onPaginationModelChange to also track state locally in dataSource mode
3501
- const wrappedOnPaginationModelChange = useCallback((model, details) => {
3502
- if (isDataSourceMode) {
3503
- setDataSourcePaginationModel(model);
3504
- }
3505
- onPaginationModelChange(model, details);
3506
- }, [isDataSourceMode, onPaginationModelChange]);
3507
-
3508
- // In dataSource mode, pagination changes from our custom pagination slots
3509
- // (rendered outside MUI's pagination state) route through apiRef so MUI's
3510
- // internal page state updates and dataSource.getRows() refetches with the
3511
- // new params. The `paginationModelChange` subscription below picks up the
3512
- // resulting state change and propagates it to URL/localStorage and local
3513
- // React state via wrappedOnPaginationModelChange.
3514
- const dataSourcePaginationChange = useCallback(model => {
3515
- var _apiRef$current;
3516
- (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPaginationModel(model);
3517
- }, [apiRef]);
3518
-
3519
- // In dataSource mode, subscribe to MUI's `paginationModelChange` event so
3520
- // URL state stays in sync with MUI's internal pagination regardless of how
3521
- // it changed (slot click, apiRef.setPaginationModel from consumer code,
3522
- // MUI internal updates, etc.). Relying on MUI's `onPaginationModelChange`
3523
- // prop callback alone is not sufficient: in pivot/GroupedData strategy mode
3524
- // and with `paginationModel` seeded via `initialState` (rather than as a
3525
- // controlled prop), the prop callback can be missed under certain
3526
- // re-render orderings. The event fires reliably whenever the internal
3527
- // state changes via `setState('setPaginationModel')`, see
3528
- // `useGridStateInitialization.setState` → `publishEvent(changeEvent, …)`.
3529
- // The deep-equal guard inside `useStatefulTable.onPaginationModelChange`
3530
- // dedupes any duplicate emits, so overlap with the prop callback is safe.
3531
- useEffect(() => {
3532
- if (!isDataSourceMode) return;
3533
- const api = apiRef.current;
3534
- if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
3535
- return api.subscribeEvent('paginationModelChange', model => {
3536
- wrappedOnPaginationModelChange({
3537
- page: model.page,
3538
- pageSize: model.pageSize
3539
- }, {
3540
- reason: 'paginationModelChange'
3541
- });
4198
+ // Pre-sort the columns handed to the grid to match the persisted column order.
4199
+ // MUI rebuilds `orderedFields` from the columns-prop array order whenever that
4200
+ // prop's reference changes (createColumnsState with keepOnlyColumnsToUpsert),
4201
+ // discarding any drag-drop reorder that was only seeded once via
4202
+ // initialState.columns.orderedFields. Consumers routinely pass a fresh
4203
+ // `columns` reference (e.g. a columns memo recomputing on a cell-renderer
4204
+ // dependency), so without this the user's reordering silently reverts to
4205
+ // definition order mid-session and the reverted order then gets persisted
4206
+ // over the real one. Sorting here makes that reconciliation a no-op.
4207
+ const orderedColumns = useMemo(() => {
4208
+ if (!columnOrderModel || columnOrderModel.length === 0) return columns;
4209
+ const rank = new Map(columnOrderModel.map((field, index) => [field, index]));
4210
+ // Fields absent from the persisted order (newly added columns) keep their
4211
+ // original relative position, appended after the ranked ones — matching
4212
+ // MUI's own "append unknown fields to the end" behaviour.
4213
+ return columns.map((column, index) => ({
4214
+ column,
4215
+ index
4216
+ })).sort((a, b) => {
4217
+ var _rank$get, _rank$get2;
4218
+ const rankA = (_rank$get = rank.get(a.column.field)) !== null && _rank$get !== void 0 ? _rank$get : Number.MAX_SAFE_INTEGER;
4219
+ const rankB = (_rank$get2 = rank.get(b.column.field)) !== null && _rank$get2 !== void 0 ? _rank$get2 : Number.MAX_SAFE_INTEGER;
4220
+ return rankA === rankB ? a.index - b.index : rankA - rankB;
4221
+ }).map(_ref => {
4222
+ let {
4223
+ column
4224
+ } = _ref;
4225
+ return column;
3542
4226
  });
3543
- }, [isDataSourceMode, apiRef, wrappedOnPaginationModelChange]);
3544
- const [rowSelectionModel, setRowSelectionModel] = useState(() => normalizeRowSelectionModel(propsRowSelectionModel));
4227
+ }, [columns, columnOrderModel]);
4228
+ const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3545
4229
  useEffect(() => {
3546
- setRowSelectionModel(normalizeRowSelectionModel(propsRowSelectionModel));
4230
+ setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3547
4231
  }, [propsRowSelectionModel]);
3548
4232
  const onRowSelectionModelChange = (selectionModel, details) => {
3549
4233
  setRowSelectionModel(selectionModel);
@@ -3557,49 +4241,25 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3557
4241
  pageSize: paginationModel.pageSize
3558
4242
  });
3559
4243
 
3560
- // Version counter to force re-renders when selectionStatus ref changes
3561
- const [, forceSelectionUpdate] = useState(0);
3562
-
3563
4244
  // The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
3564
4245
  // for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
3565
- const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(effectivePaginationMode != 'server');
4246
+ const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
3566
4247
 
3567
4248
  // Banner and pager placements are independent. `belowToolbar` (for either) renders
3568
- // in a row inside the toolbar slot, and only applies when pagination is on.
4249
+ // in the toolbar-slot row, and only applies when pagination is on.
3569
4250
  const bannerAtTop = selectionBannerPlacement === 'top';
3570
4251
  const bannerAtBottom = selectionBannerPlacement === 'bottom';
3571
4252
  const bannerBelowToolbar = selectionBannerPlacement === 'belowToolbar' && Boolean(pagination);
3572
4253
  const pagerBelowToolbar = paginationPlacement === 'belowToolbar' && Boolean(pagination);
3573
- const belowToolbarActive = bannerBelowToolbar || pagerBelowToolbar;
3574
-
3575
- // Track when the grid API is ready to ensure top pagination renders correctly
3576
- const [gridReady, setGridReady] = useState(false);
3577
-
3578
- // Force re-render when the grid API becomes ready (for top pagination)
3579
- useEffect(() => {
3580
- if (apiRef.current && !gridReady) {
3581
- setGridReady(true);
3582
- }
3583
- });
3584
-
3585
- // Sync persisted density via apiRef — initialState only applies on mount,
3586
- // so this handles SPA back/forward navigation where controlledDensity changes after mount
3587
- useEffect(() => {
3588
- if (apiRef.current) {
3589
- apiRef.current.setDensity(controlledDensity);
3590
- }
3591
- }, [controlledDensity, apiRef]);
3592
4254
 
3593
4255
  // in server-side pagination we want to update the selection status
3594
4256
  // every time we navigate between pages, resize our page or select something
3595
4257
  useEffect(() => {
3596
- if (effectivePaginationMode == 'server') {
3597
- onServerSideSelectionStatusChange(rowSelectionModel, apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, activePaginationModel.page, activePaginationModel.pageSize);
4258
+ if (paginationMode == 'server') {
4259
+ onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatusRef, isRowSelectable, paginationModel.page, paginationModel.pageSize);
3598
4260
  }
3599
- }, [rowSelectionModel, activePaginationModel.page, activePaginationModel.pageSize, rows]);
3600
-
3601
- // In dataSource mode MUI provides rows internally; skip the guard.
3602
- if (!isDataSourceMode && !Array.isArray(rows)) {
4261
+ }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize, rows]);
4262
+ if (!Array.isArray(rows)) {
3603
4263
  return null;
3604
4264
  }
3605
4265
 
@@ -3608,34 +4268,23 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3608
4268
  // receive the fresh value in the same render cycle — no extra re-render needed.
3609
4269
  // The ref is kept in sync for the onRowSelectionModelChange callback's deselect logic.
3610
4270
  let selectionStatus = selectionStatusRef.current;
3611
- if (pagination && effectivePaginationMode !== 'server' && getSelectionCount(rowSelectionModel) > 0) {
4271
+ if (pagination && paginationMode !== 'server' && Array.isArray(rowSelectionModel) && rowSelectionModel.length > 0) {
3612
4272
  try {
3613
- // Use manual page slicing instead of gridPaginatedVisibleSorted* selectors.
3614
- // MUI's paginated selectors use apiRef internal state which may be stale when
3615
- // paginationModel prop changes — our React state is always up to date.
3616
- const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
3617
- const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
3618
- const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
3619
- const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref => {
4273
+ const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref2 => {
3620
4274
  let {
3621
4275
  model
3622
- } = _ref;
4276
+ } = _ref2;
3623
4277
  return isRowSelectable({
3624
4278
  row: model
3625
4279
  });
3626
- }).map(_ref2 => {
3627
- let {
3628
- id
3629
- } = _ref2;
3630
- return id;
3631
- }) : pageEntries.map(_ref3 => {
4280
+ }).map(_ref3 => {
3632
4281
  let {
3633
4282
  id
3634
4283
  } = _ref3;
3635
4284
  return id;
3636
- });
4285
+ }) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
3637
4286
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
3638
- const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref4 => {
4287
+ const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref4 => {
3639
4288
  let {
3640
4289
  model
3641
4290
  } = _ref4;
@@ -3649,8 +4298,8 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3649
4298
  return id;
3650
4299
  }) : gridFilteredSortedRowIdsSelector(apiRef);
3651
4300
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
3652
- const numberOfSelectedRows = getSelectionCount(rowSelectionModel);
3653
- const selectedOnCurrentPage = selectableRowsInPage.filter(id => isRowSelected(rowSelectionModel, id));
4301
+ const numberOfSelectedRows = rowSelectionModel.length;
4302
+ const selectedOnCurrentPage = selectableRowsInPage.filter(id => rowSelectionModel.includes(id));
3654
4303
  if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
3655
4304
  selectionStatus = {
3656
4305
  type: 'table',
@@ -3675,7 +4324,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3675
4324
  } catch {
3676
4325
  // apiRef may not be initialized on first render
3677
4326
  }
3678
- } else if (pagination && effectivePaginationMode !== 'server') {
4327
+ } else if (pagination && paginationMode !== 'server') {
3679
4328
  selectionStatus = {
3680
4329
  type: 'none',
3681
4330
  numberOfSelectedRows: 0
@@ -3704,256 +4353,117 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3704
4353
  ref: datagridRef,
3705
4354
  className: classNames(StatefulDataGrid.className, className),
3706
4355
  $height: height
3707
- }, pagination && gridReady && (bannerAtTop || ['top', 'both'].includes(paginationPlacement)) ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, {
3708
- displaySelection: bannerAtTop,
3709
- displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
3710
- displayPagination: ['top', 'both'].includes(paginationPlacement),
3711
- selectionStatus: selectionStatus,
3712
- paginationModel: activePaginationModel,
3713
- onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
3714
- pageSizeOptions: pageSizeOptions,
3715
- paginationProps: paginationProps,
3716
- rowCount: rowCount
3717
- }) : /*#__PURE__*/React__default.createElement(ControlledPagination, {
3718
- displaySelection: bannerAtTop,
3719
- displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
3720
- displayPagination: ['top', 'both'].includes(paginationPlacement),
3721
- selectionStatus: selectionStatus,
3722
- apiRef: apiRef,
3723
- isRowSelectable: isRowSelectable,
3724
- paginationModel: activePaginationModel,
3725
- onPaginationModelChange: onPaginationModelChange,
3726
- pageSizeOptions: pageSizeOptions,
3727
- paginationProps: paginationProps
3728
- }) : null, /*#__PURE__*/React__default.createElement(DataGridPremium, _extends({}, forwardedProps, {
4356
+ }, /*#__PURE__*/React__default.createElement(DataGridPro, _extends$2({}, forwardedProps, {
3729
4357
  apiRef: apiRef,
3730
- dataSource: dataSource,
3731
- columns: columns,
4358
+ columns: orderedColumns,
4359
+ columnVisibilityModel: columnVisibilityModel,
4360
+ density: controlledDensity,
4361
+ filterModel: filterModel,
3732
4362
  onColumnVisibilityModelChange: onColumnVisibilityModelChange,
4363
+ onFilterModelChange: onFilterModelChange,
4364
+ onPaginationModelChange: onPaginationModelChange,
3733
4365
  onPinnedColumnsChange: onPinnedColumnsChange,
4366
+ onSortModelChange: onSortModelChange,
4367
+ paginationModel: paginationModel,
4368
+ pinnedColumns: pinnedColumns,
4369
+ sortModel: sortModel,
3734
4370
  pageSizeOptions: pageSizeOptions,
3735
4371
  onColumnWidthChange: onColumnWidthChange,
3736
- onRowGroupingModelChange: onRowGroupingModelChange,
3737
- onAggregationModelChange: onAggregationModelChange,
3738
- onPivotModelChange: onPivotModelChange,
3739
- pivotActive: pivotActive,
3740
- onPivotActiveChange: onPivotActiveChange
3741
- // In dataSource mode: models are uncontrolled (MUI owns them),
3742
- // onChange handlers are write-only for URL/localStorage persistence,
3743
- // and initialState seeds MUI on mount from the persisted URL state.
3744
- // columnVisibilityModel / pinnedColumns / rowGroupingModel /
3745
- // aggregationModel / pivotModel are also uncontrolled here to
3746
- // avoid a controlled re-render race with consumer-side
3747
- // microtask-deferred history updates (otherwise user toggles
3748
- // flip back when MUI re-emits with the stale controlled value).
3749
- // pivotModel specifically also carries `hidden`/`sort` field
3750
- // metadata that our simplified URL representation strips — so
3751
- // controlling it would prevent users from unchecking fields in
3752
- // the pivot panel (the controlled prop would immediately re-add
3753
- // them). Consumers needing programmatic changes should use the
3754
- // apiRef imperative API.
3755
- }, isDataSourceMode ? {
3756
- onFilterModelChange: onFilterModelChange,
3757
- onSortModelChange: onSortModelChange,
3758
- onPaginationModelChange: wrappedOnPaginationModelChange,
3759
- initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
3760
- density: controlledDensity,
3761
- columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
3762
- orderedFields: columnOrderModel,
3763
- columnVisibilityModel
3764
- }),
3765
- pinnedColumns,
3766
- rowGrouping: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.rowGrouping), {}, {
3767
- model: rowGroupingModel
3768
- }),
3769
- aggregation: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.aggregation), {}, {
3770
- model: aggregationModel
3771
- }),
3772
- filter: {
3773
- filterModel
3774
- },
3775
- sorting: {
3776
- sortModel
3777
- },
3778
- pagination: {
3779
- paginationModel
3780
- },
3781
- pivoting: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.pivoting), {}, {
3782
- model: pivotModel,
3783
- enabled: pivotActive
3784
- })
3785
- })
3786
- } : {
3787
- columnVisibilityModel,
3788
- pinnedColumns,
3789
- rowGroupingModel,
3790
- aggregationModel,
3791
- filterModel,
3792
- sortModel,
3793
- paginationModel,
3794
- pivotModel,
3795
- onFilterModelChange: onFilterModelChange,
3796
- onSortModelChange: onSortModelChange,
3797
- onPaginationModelChange: wrappedOnPaginationModelChange,
3798
4372
  initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
3799
- density: controlledDensity,
3800
4373
  columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
3801
4374
  orderedFields: columnOrderModel
3802
4375
  })
3803
- })
3804
- }, {
4376
+ }),
3805
4377
  isRowSelectable: isRowSelectable,
3806
4378
  pagination: pagination,
3807
- paginationMode: effectivePaginationMode,
3808
- filterMode: effectiveFilterMode,
3809
- sortingMode: effectiveSortingMode,
3810
- keepNonExistentRowsSelected: effectivePaginationMode == 'server',
3811
- rows: isDataSourceMode ? [] : rows,
4379
+ paginationMode: paginationMode,
4380
+ keepNonExistentRowsSelected: paginationMode == 'server',
4381
+ rows: rows,
3812
4382
  rowCount: rowCount,
3813
4383
  autoHeight: autoHeight,
3814
4384
  checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
3815
- disableRowSelectionExcludeModel: true,
3816
- showToolbar: !hideToolbar || belowToolbarActive,
3817
- slots: _objectSpread2(_objectSpread2(_objectSpread2({
3818
- baseButton: BaseButton,
3819
- baseCheckbox: BaseCheckbox,
3820
- baseIconButton: BaseIconButton,
3821
- columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3822
- displayName: "columnFilteredIcon"
3823
- })),
3824
- columnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3825
- displayName: "columnSelectorIcon"
3826
- })),
3827
- columnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3828
- displayName: "columnSortedAscendingIcon"
3829
- })),
3830
- columnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3831
- displayName: "columnSortedDescendingIcon"
3832
- })),
3833
- densityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3834
- displayName: "densityCompactIcon"
3835
- })),
3836
- densityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3837
- displayName: "densityStandardIcon"
3838
- })),
3839
- densityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3840
- displayName: "densityComfortableIcon"
3841
- })),
3842
- detailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3843
- displayName: "detailPanelCollapseIcon"
3844
- })),
3845
- detailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3846
- displayName: "detailPanelExpandIcon"
3847
- })),
3848
- exportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3849
- displayName: "exportIcon"
3850
- })),
3851
- openFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3852
- displayName: "openFilterButtonIcon"
3853
- }))
3854
- }, slots), belowToolbarActive ? {
3855
- toolbar: toolbarProps => {
3856
- var _ref6;
3857
- return /*#__PURE__*/React__default.createElement(ToolbarWrapper, _extends({}, toolbarProps, {
3858
- RenderedToolbar: (_ref6 = slots === null || slots === void 0 ? void 0 : slots.toolbar) !== null && _ref6 !== void 0 ? _ref6 : Toolbar,
3859
- hideToolbar: hideToolbar,
3860
- filterModel: filterModel,
3861
- onFilterModelChange: onFilterModelChange,
3862
- pagination: pagination,
3863
- paginationMode: effectivePaginationMode,
3864
- displaySelection: bannerBelowToolbar,
3865
- displayPagination: pagerBelowToolbar,
3866
- displayRowsPerPage: pagerBelowToolbar,
3867
- selectionStatus: selectionStatus,
3868
- apiRef: apiRef,
3869
- isRowSelectable: isRowSelectable,
3870
- paginationModel: activePaginationModel,
3871
- onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
3872
- pageSizeOptions: pageSizeOptions,
3873
- paginationProps: paginationProps,
3874
- rowCount: rowCount
3875
- }));
3876
- }
3877
- } : {}), {}, {
3878
- pagination: props => {
3879
- return pagination ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
3880
- displaySelection: bannerAtBottom,
3881
- displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3882
- displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3883
- selectionStatus: selectionStatus,
3884
- paginationModel: activePaginationModel
3885
- // In dataSource mode route through apiRef so MUI's internal pagination
3886
- // state stays in sync with the displayed model and dataSource.getRows()
3887
- // re-fetches with the new params. MUI then fires onPaginationModelChange
3888
- // via the prop, which updates URL/localStorage via useStatefulTable.
3889
- // Without this the bottom slot only updated local React state + URL,
3890
- // leaving MUI on its previous internal page (no refetch, stale display).
3891
- ,
3892
- onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : wrappedOnPaginationModelChange,
3893
- pageSizeOptions: pageSizeOptions,
3894
- paginationProps: paginationProps,
3895
- rowCount: rowCount
3896
- })) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends({}, props, {
3897
- displaySelection: bannerAtBottom,
3898
- displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3899
- displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3900
- selectionStatus: selectionStatus,
3901
- apiRef: apiRef,
3902
- isRowSelectable: isRowSelectable,
3903
- paginationModel: activePaginationModel,
3904
- onPaginationModelChange: wrappedOnPaginationModelChange,
3905
- pageSizeOptions: pageSizeOptions,
3906
- paginationProps: paginationProps
3907
- })) : null;
3908
- }
4385
+ slots: _objectSpread2(_objectSpread2(_objectSpread2({}, baseGridSlots), slots), {}, {
4386
+ // The toolbar is already a stable module-level component (ToolbarWrapper) with its
4387
+ // per-render data injected via `slotProps.toolbar` below. `BottomPagination` is
4388
+ // likewise stable; a fresh inline function here would remount the slot's subtree
4389
+ // every render.
4390
+ toolbar: ToolbarWrapper,
4391
+ pagination: BottomPagination
4392
+ }),
4393
+ slotProps: _objectSpread2(_objectSpread2({}, slotProps), {}, {
4394
+ toolbar: _objectSpread2({
4395
+ hideToolbar,
4396
+ RenderedToolbar,
4397
+ filterModel,
4398
+ onFilterModelChange,
4399
+ pagination,
4400
+ displaySelection: bannerAtTop || bannerBelowToolbar,
4401
+ displayPagination: ['top', 'both'].includes(paginationPlacement) || pagerBelowToolbar,
4402
+ displayRowsPerPage: pagerBelowToolbar,
4403
+ selectionStatus,
4404
+ apiRef,
4405
+ isRowSelectable,
4406
+ paginationModel,
4407
+ onPaginationModelChange,
4408
+ pageSizeOptions,
4409
+ paginationProps,
4410
+ paginationMode,
4411
+ rowCount
4412
+ }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar),
4413
+ // Per-render data for the stable `BottomPagination` slot. Consumer slot props are
4414
+ // spread first; the DS layout data wins. Cast at the MUI boundary because these are
4415
+ // ToolbarWrapper props, not the MUI slot prop types.
4416
+ pagination: _objectSpread2(_objectSpread2({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.pagination), {}, {
4417
+ pagination,
4418
+ paginationMode,
4419
+ displaySelection: bannerAtBottom,
4420
+ displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
4421
+ displayPagination: ['bottom', 'both'].includes(paginationPlacement),
4422
+ selectionStatus,
4423
+ paginationModel,
4424
+ onPaginationModelChange,
4425
+ apiRef,
4426
+ isRowSelectable,
4427
+ pageSizeOptions,
4428
+ paginationProps,
4429
+ rowCount
4430
+ })
3909
4431
  }),
3910
- slotProps: _objectSpread2({}, slotProps),
3911
4432
  rowSelectionModel: rowSelectionModel,
3912
4433
  onRowSelectionModelChange: (newSelectionModel, details) => {
3913
- if (pagination && effectivePaginationMode != 'server') {
3914
- // Use manual page slicing instead of gridPaginatedVisibleSorted* selectors
3915
- // to avoid stale apiRef pagination state.
3916
- const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
3917
- const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
3918
- const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
3919
- const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref7 => {
4434
+ if (pagination && paginationMode != 'server') {
4435
+ const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref6 => {
3920
4436
  let {
3921
4437
  model
3922
- } = _ref7;
4438
+ } = _ref6;
3923
4439
  return isRowSelectable({
3924
4440
  row: model
3925
4441
  });
3926
- }).map(_ref8 => {
3927
- let {
3928
- id
3929
- } = _ref8;
3930
- return id;
3931
- }) : pageEntries.map(_ref9 => {
4442
+ }).map(_ref7 => {
3932
4443
  let {
3933
4444
  id
3934
- } = _ref9;
4445
+ } = _ref7;
3935
4446
  return id;
3936
- });
4447
+ }) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
3937
4448
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
3938
- const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref10 => {
4449
+ const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref8 => {
3939
4450
  let {
3940
4451
  model
3941
- } = _ref10;
4452
+ } = _ref8;
3942
4453
  return isRowSelectable({
3943
4454
  row: model
3944
4455
  });
3945
- }).map(_ref11 => {
4456
+ }).map(_ref9 => {
3946
4457
  let {
3947
4458
  id
3948
- } = _ref11;
4459
+ } = _ref9;
3949
4460
  return id;
3950
4461
  }) : gridFilteredSortedRowIdsSelector(apiRef);
3951
4462
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
3952
- const numberOfSelectedRows = getSelectionCount(newSelectionModel);
4463
+ const numberOfSelectedRows = newSelectionModel.length;
3953
4464
  if (selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatusRef.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
3954
4465
  setTimeout(() => {
3955
- var _apiRef$current2;
3956
- (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.selectRows([], true, true);
4466
+ apiRef.current.selectRows([], true, true);
3957
4467
  }, 0);
3958
4468
  }
3959
4469
  if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
@@ -3977,7 +4487,6 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3977
4487
  numberOfSelectedRows
3978
4488
  };
3979
4489
  }
3980
- forceSelectionUpdate(v => v + 1);
3981
4490
  }
3982
4491
  onRowSelectionModelChange === null || onRowSelectionModelChange === void 0 ? void 0 : onRowSelectionModelChange(newSelectionModel, details);
3983
4492
  },
@@ -3995,5 +4504,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3995
4504
  StatefulDataGrid.className = CLASSNAME;
3996
4505
  StatefulDataGrid.displayName = COMPONENT_NAME;
3997
4506
 
3998
- 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, resetColumnVisibility as a3, convertToDisplayFormat as a4, convertFromDisplayFormat as a5, getDecodedSearchFromUrl as a6, buildQueryParamsString as a7, areSearchStringsEqual as a8, decodeValue as a9, fromGridPivotModel as aA, getPivotFromString as aB, getSearchParamsFromPivot as aC, getPivotActiveFromString as aD, getSearchParamsFromPivotActive as aE, getSearchParamsFromVersion as aF, getFinalSearch as aG, getModelsParsedOrUpdateLocalStorage as aH, updateUrl as aI, areFilterModelsEquivalent as aJ, StatefulDataGrid as aK, encodeValue as aa, urlSearchParamsToString as ab, numberOperatorEncoder as ac, numberOperatorDecoder as ad, isOperatorValueValid as ae, isValueValid as af, getFilterModelFromString as ag, getSearchParamsFromFilterModel as ah, getSortingFromString as ai, getSearchParamsFromSorting as aj, getPaginationFromString as ak, getSearchParamsFromPagination as al, getColumnVisibilityFromString as am, getSearchParamsFromColumnVisibility as an, getPinnedColumnsFromString as ao, getSearchParamsFromPinnedColumns as ap, getSearchParamsFromTab as aq, getDensityFromString as ar, getSearchParamsFromDensity as as, getDensityModel as at, getColumnOrderFromString as au, getSearchParamsFromColumnOrder as av, getRowGroupingFromString as aw, getSearchParamsFromRowGrouping as ax, getAggregationFromString as ay, getSearchParamsFromAggregation 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 };
4507
+ 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, resetColumnVisibility as a1, convertToDisplayFormat as a2, convertFromDisplayFormat as a3, getDecodedSearchFromUrl as a4, buildQueryParamsString as a5, areSearchStringsEqual as a6, decodeValue as a7, encodeValue as a8, urlSearchParamsToString as a9, numberOperatorEncoder as aa, numberOperatorDecoder as ab, isOperatorValueValid as ac, isValueValid as ad, getFilterModelFromString as ae, normalizeDateValue 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, getColumnOrderFromString as as, getSearchParamsFromColumnOrder as at, getSearchParamsFromVersion as au, getFinalSearch as av, getModelsParsedOrUpdateLocalStorage as aw, updateUrl as ax, areFilterModelsEquivalent as ay, StatefulDataGrid 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 };
3999
4508
  //# sourceMappingURL=StatefulDataGrid2.js.map