@redsift/table 12.5.4 → 12.5.5-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,18 +1,1249 @@
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 } 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, S as ServerSideControlledPagination, C as ControlledPagination } 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';
13
+ import { T as Toolbar } from './Toolbar2.js';
14
+ import { B as BaseButton, a as BaseCheckbox, c as BasePopper, b as BaseIcon } from './BasePopper.js';
15
+ import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
16
+
17
+ 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}
18
+
19
+ const _excluded$6 = ["className", "component"];
20
+ function createBox(options = {}) {
21
+ const {
22
+ themeId,
23
+ defaultTheme,
24
+ defaultClassName = 'MuiBox-root',
25
+ generateClassName
26
+ } = options;
27
+ const BoxRoot = styled('div', {
28
+ shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
29
+ })(styleFunctionSx);
30
+ const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
31
+ const theme = useTheme(defaultTheme);
32
+ const _extendSxProp = extendSxProp(inProps),
33
+ {
34
+ className,
35
+ component = 'div'
36
+ } = _extendSxProp,
37
+ other = _objectWithoutPropertiesLoose(_extendSxProp, _excluded$6);
38
+ return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, _extends({
39
+ as: component,
40
+ ref: ref,
41
+ className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
42
+ theme: themeId ? theme[themeId] || theme : theme
43
+ }, other));
44
+ });
45
+ return Box;
46
+ }
47
+
48
+ function isMuiElement(element, muiNames) {
49
+ var _muiName, _element$type;
50
+ return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf( // For server components `muiName` is avaialble in element.type._payload.value.muiName
51
+ // relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
52
+ // eslint-disable-next-line no-underscore-dangle
53
+ (_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;
54
+ }
55
+
56
+ const boxClasses = generateUtilityClasses('MuiBox', ['root']);
57
+ var boxClasses$1 = boxClasses;
58
+
59
+ const defaultTheme = createTheme();
60
+ const Box = createBox({
61
+ themeId: THEME_ID,
62
+ defaultTheme,
63
+ defaultClassName: boxClasses$1.root,
64
+ generateClassName: ClassNameGenerator.generate
65
+ });
66
+ process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
67
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
68
+ // │ These PropTypes are generated from the TypeScript type definitions. │
69
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
70
+ // └─────────────────────────────────────────────────────────────────────┘
71
+ /**
72
+ * @ignore
73
+ */
74
+ children: PropTypes.node,
75
+ /**
76
+ * The component used for the root node.
77
+ * Either a string to use a HTML element or a component.
78
+ */
79
+ component: PropTypes.elementType,
80
+ /**
81
+ * The system prop that allows defining system overrides as well as additional CSS styles.
82
+ */
83
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
84
+ } : void 0;
85
+ var Box$1 = Box;
86
+
87
+ function getFormLabelUtilityClasses(slot) {
88
+ return generateUtilityClass('MuiFormLabel', slot);
89
+ }
90
+ const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
91
+ var formLabelClasses$1 = formLabelClasses;
92
+
93
+ const _excluded$5 = ["children", "className", "color", "component", "disabled", "error", "filled", "focused", "required"];
94
+ const useUtilityClasses$4 = ownerState => {
95
+ const {
96
+ classes,
97
+ color,
98
+ focused,
99
+ disabled,
100
+ error,
101
+ filled,
102
+ required
103
+ } = ownerState;
104
+ const slots = {
105
+ root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
106
+ asterisk: ['asterisk', error && 'error']
107
+ };
108
+ return composeClasses(slots, getFormLabelUtilityClasses, classes);
109
+ };
110
+ const FormLabelRoot = styled$1('label', {
111
+ name: 'MuiFormLabel',
112
+ slot: 'Root',
113
+ overridesResolver: ({
114
+ ownerState
115
+ }, styles) => {
116
+ return _extends$1({}, styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled);
117
+ }
118
+ })(({
119
+ theme,
120
+ ownerState
121
+ }) => _extends$1({
122
+ color: (theme.vars || theme).palette.text.secondary
123
+ }, theme.typography.body1, {
124
+ lineHeight: '1.4375em',
125
+ padding: 0,
126
+ position: 'relative',
127
+ [`&.${formLabelClasses$1.focused}`]: {
128
+ color: (theme.vars || theme).palette[ownerState.color].main
129
+ },
130
+ [`&.${formLabelClasses$1.disabled}`]: {
131
+ color: (theme.vars || theme).palette.text.disabled
132
+ },
133
+ [`&.${formLabelClasses$1.error}`]: {
134
+ color: (theme.vars || theme).palette.error.main
135
+ }
136
+ }));
137
+ const AsteriskComponent = styled$1('span', {
138
+ name: 'MuiFormLabel',
139
+ slot: 'Asterisk',
140
+ overridesResolver: (props, styles) => styles.asterisk
141
+ })(({
142
+ theme
143
+ }) => ({
144
+ [`&.${formLabelClasses$1.error}`]: {
145
+ color: (theme.vars || theme).palette.error.main
146
+ }
147
+ }));
148
+ const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
149
+ const props = useDefaultProps({
150
+ props: inProps,
151
+ name: 'MuiFormLabel'
152
+ });
153
+ const {
154
+ children,
155
+ className,
156
+ component = 'label'
157
+ } = props,
158
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$5);
159
+ const muiFormControl = useFormControl();
160
+ const fcs = formControlState({
161
+ props,
162
+ muiFormControl,
163
+ states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
164
+ });
165
+ const ownerState = _extends$1({}, props, {
166
+ color: fcs.color || 'primary',
167
+ component,
168
+ disabled: fcs.disabled,
169
+ error: fcs.error,
170
+ filled: fcs.filled,
171
+ focused: fcs.focused,
172
+ required: fcs.required
173
+ });
174
+ const classes = useUtilityClasses$4(ownerState);
175
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, _extends$1({
176
+ as: component,
177
+ ownerState: ownerState,
178
+ className: clsx$1(classes.root, className),
179
+ ref: ref
180
+ }, other, {
181
+ children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
182
+ ownerState: ownerState,
183
+ "aria-hidden": true,
184
+ className: classes.asterisk,
185
+ children: ["\u2009", '*']
186
+ })]
187
+ }));
188
+ });
189
+ process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
190
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
191
+ // │ These PropTypes are generated from the TypeScript type definitions. │
192
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
193
+ // └─────────────────────────────────────────────────────────────────────┘
194
+ /**
195
+ * The content of the component.
196
+ */
197
+ children: PropTypes.node,
198
+ /**
199
+ * Override or extend the styles applied to the component.
200
+ */
201
+ classes: PropTypes.object,
202
+ /**
203
+ * @ignore
204
+ */
205
+ className: PropTypes.string,
206
+ /**
207
+ * The color of the component.
208
+ * It supports both default and custom theme colors, which can be added as shown in the
209
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
210
+ */
211
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
212
+ /**
213
+ * The component used for the root node.
214
+ * Either a string to use a HTML element or a component.
215
+ */
216
+ component: PropTypes.elementType,
217
+ /**
218
+ * If `true`, the label should be displayed in a disabled state.
219
+ */
220
+ disabled: PropTypes.bool,
221
+ /**
222
+ * If `true`, the label is displayed in an error state.
223
+ */
224
+ error: PropTypes.bool,
225
+ /**
226
+ * If `true`, the label should use filled classes key.
227
+ */
228
+ filled: PropTypes.bool,
229
+ /**
230
+ * If `true`, the input of this label is focused (used by `FormGroup` components).
231
+ */
232
+ focused: PropTypes.bool,
233
+ /**
234
+ * If `true`, the label will indicate that the `input` is required.
235
+ */
236
+ required: PropTypes.bool,
237
+ /**
238
+ * The system prop that allows defining system overrides as well as additional CSS styles.
239
+ */
240
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
241
+ } : void 0;
242
+ var FormLabel$1 = FormLabel;
243
+
244
+ function getInputLabelUtilityClasses(slot) {
245
+ return generateUtilityClass('MuiInputLabel', slot);
246
+ }
247
+ generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
248
+
249
+ const _excluded$4 = ["disableAnimation", "margin", "shrink", "variant", "className"];
250
+ const useUtilityClasses$3 = ownerState => {
251
+ const {
252
+ classes,
253
+ formControl,
254
+ size,
255
+ shrink,
256
+ disableAnimation,
257
+ variant,
258
+ required
259
+ } = ownerState;
260
+ const slots = {
261
+ root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size && size !== 'normal' && `size${capitalize(size)}`, variant],
262
+ asterisk: [required && 'asterisk']
263
+ };
264
+ const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
265
+ return _extends$1({}, classes, composedClasses);
266
+ };
267
+ const InputLabelRoot = styled$1(FormLabel$1, {
268
+ shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
269
+ name: 'MuiInputLabel',
270
+ slot: 'Root',
271
+ overridesResolver: (props, styles) => {
272
+ const {
273
+ ownerState
274
+ } = props;
275
+ return [{
276
+ [`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
277
+ }, 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]];
278
+ }
279
+ })(({
280
+ theme,
281
+ ownerState
282
+ }) => _extends$1({
283
+ display: 'block',
284
+ transformOrigin: 'top left',
285
+ whiteSpace: 'nowrap',
286
+ overflow: 'hidden',
287
+ textOverflow: 'ellipsis',
288
+ maxWidth: '100%'
289
+ }, ownerState.formControl && {
290
+ position: 'absolute',
291
+ left: 0,
292
+ top: 0,
293
+ // slight alteration to spec spacing to match visual spec result
294
+ transform: 'translate(0, 20px) scale(1)'
295
+ }, ownerState.size === 'small' && {
296
+ // Compensation for the `Input.inputSizeSmall` style.
297
+ transform: 'translate(0, 17px) scale(1)'
298
+ }, ownerState.shrink && {
299
+ transform: 'translate(0, -1.5px) scale(0.75)',
300
+ transformOrigin: 'top left',
301
+ maxWidth: '133%'
302
+ }, !ownerState.disableAnimation && {
303
+ transition: theme.transitions.create(['color', 'transform', 'max-width'], {
304
+ duration: theme.transitions.duration.shorter,
305
+ easing: theme.transitions.easing.easeOut
306
+ })
307
+ }, ownerState.variant === 'filled' && _extends$1({
308
+ // Chrome's autofill feature gives the input field a yellow background.
309
+ // Since the input field is behind the label in the HTML tree,
310
+ // the input field is drawn last and hides the label with an opaque background color.
311
+ // zIndex: 1 will raise the label above opaque background-colors of input.
312
+ zIndex: 1,
313
+ pointerEvents: 'none',
314
+ transform: 'translate(12px, 16px) scale(1)',
315
+ maxWidth: 'calc(100% - 24px)'
316
+ }, ownerState.size === 'small' && {
317
+ transform: 'translate(12px, 13px) scale(1)'
318
+ }, ownerState.shrink && _extends$1({
319
+ userSelect: 'none',
320
+ pointerEvents: 'auto',
321
+ transform: 'translate(12px, 7px) scale(0.75)',
322
+ maxWidth: 'calc(133% - 24px)'
323
+ }, ownerState.size === 'small' && {
324
+ transform: 'translate(12px, 4px) scale(0.75)'
325
+ })), ownerState.variant === 'outlined' && _extends$1({
326
+ // see comment above on filled.zIndex
327
+ zIndex: 1,
328
+ pointerEvents: 'none',
329
+ transform: 'translate(14px, 16px) scale(1)',
330
+ maxWidth: 'calc(100% - 24px)'
331
+ }, ownerState.size === 'small' && {
332
+ transform: 'translate(14px, 9px) scale(1)'
333
+ }, ownerState.shrink && {
334
+ userSelect: 'none',
335
+ pointerEvents: 'auto',
336
+ // Theoretically, we should have (8+5)*2/0.75 = 34px
337
+ // but it feels a better when it bleeds a bit on the left, so 32px.
338
+ maxWidth: 'calc(133% - 32px)',
339
+ transform: 'translate(14px, -9px) scale(0.75)'
340
+ })));
341
+ const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
342
+ const props = useDefaultProps({
343
+ name: 'MuiInputLabel',
344
+ props: inProps
345
+ });
346
+ const {
347
+ disableAnimation = false,
348
+ shrink: shrinkProp,
349
+ className
350
+ } = props,
351
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$4);
352
+ const muiFormControl = useFormControl();
353
+ let shrink = shrinkProp;
354
+ if (typeof shrink === 'undefined' && muiFormControl) {
355
+ shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
356
+ }
357
+ const fcs = formControlState({
358
+ props,
359
+ muiFormControl,
360
+ states: ['size', 'variant', 'required', 'focused']
361
+ });
362
+ const ownerState = _extends$1({}, props, {
363
+ disableAnimation,
364
+ formControl: muiFormControl,
365
+ shrink,
366
+ size: fcs.size,
367
+ variant: fcs.variant,
368
+ required: fcs.required,
369
+ focused: fcs.focused
370
+ });
371
+ const classes = useUtilityClasses$3(ownerState);
372
+ return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, _extends$1({
373
+ "data-shrink": shrink,
374
+ ownerState: ownerState,
375
+ ref: ref,
376
+ className: clsx$1(classes.root, className)
377
+ }, other, {
378
+ classes: classes
379
+ }));
380
+ });
381
+ process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
382
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
383
+ // │ These PropTypes are generated from the TypeScript type definitions. │
384
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
385
+ // └─────────────────────────────────────────────────────────────────────┘
386
+ /**
387
+ * The content of the component.
388
+ */
389
+ children: PropTypes.node,
390
+ /**
391
+ * Override or extend the styles applied to the component.
392
+ */
393
+ classes: PropTypes.object,
394
+ /**
395
+ * @ignore
396
+ */
397
+ className: PropTypes.string,
398
+ /**
399
+ * The color of the component.
400
+ * It supports both default and custom theme colors, which can be added as shown in the
401
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
402
+ */
403
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
404
+ /**
405
+ * If `true`, the transition animation is disabled.
406
+ * @default false
407
+ */
408
+ disableAnimation: PropTypes.bool,
409
+ /**
410
+ * If `true`, the component is disabled.
411
+ */
412
+ disabled: PropTypes.bool,
413
+ /**
414
+ * If `true`, the label is displayed in an error state.
415
+ */
416
+ error: PropTypes.bool,
417
+ /**
418
+ * If `true`, the `input` of this label is focused.
419
+ */
420
+ focused: PropTypes.bool,
421
+ /**
422
+ * If `dense`, will adjust vertical spacing. This is normally obtained via context from
423
+ * FormControl.
424
+ */
425
+ margin: PropTypes.oneOf(['dense']),
426
+ /**
427
+ * if `true`, the label will indicate that the `input` is required.
428
+ */
429
+ required: PropTypes.bool,
430
+ /**
431
+ * If `true`, the label is shrunk.
432
+ */
433
+ shrink: PropTypes.bool,
434
+ /**
435
+ * The size of the component.
436
+ * @default 'normal'
437
+ */
438
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
439
+ /**
440
+ * The system prop that allows defining system overrides as well as additional CSS styles.
441
+ */
442
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
443
+ /**
444
+ * The variant to use.
445
+ */
446
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
447
+ } : void 0;
448
+ var InputLabel$1 = InputLabel;
449
+
450
+ function getFormControlUtilityClasses(slot) {
451
+ return generateUtilityClass('MuiFormControl', slot);
452
+ }
453
+ generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
454
+
455
+ const _excluded$3 = ["children", "className", "color", "component", "disabled", "error", "focused", "fullWidth", "hiddenLabel", "margin", "required", "size", "variant"];
456
+ const useUtilityClasses$2 = ownerState => {
457
+ const {
458
+ classes,
459
+ margin,
460
+ fullWidth
461
+ } = ownerState;
462
+ const slots = {
463
+ root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
464
+ };
465
+ return composeClasses(slots, getFormControlUtilityClasses, classes);
466
+ };
467
+ const FormControlRoot = styled$1('div', {
468
+ name: 'MuiFormControl',
469
+ slot: 'Root',
470
+ overridesResolver: ({
471
+ ownerState
472
+ }, styles) => {
473
+ return _extends$1({}, styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth);
474
+ }
475
+ })(({
476
+ ownerState
477
+ }) => _extends$1({
478
+ display: 'inline-flex',
479
+ flexDirection: 'column',
480
+ position: 'relative',
481
+ // Reset fieldset default style.
482
+ minWidth: 0,
483
+ padding: 0,
484
+ margin: 0,
485
+ border: 0,
486
+ verticalAlign: 'top'
487
+ }, ownerState.margin === 'normal' && {
488
+ marginTop: 16,
489
+ marginBottom: 8
490
+ }, ownerState.margin === 'dense' && {
491
+ marginTop: 8,
492
+ marginBottom: 4
493
+ }, ownerState.fullWidth && {
494
+ width: '100%'
495
+ }));
496
+
497
+ /**
498
+ * Provides context such as filled/focused/error/required for form inputs.
499
+ * Relying on the context provides high flexibility and ensures that the state always stays
500
+ * consistent across the children of the `FormControl`.
501
+ * This context is used by the following components:
502
+ *
503
+ * - FormLabel
504
+ * - FormHelperText
505
+ * - Input
506
+ * - InputLabel
507
+ *
508
+ * You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
509
+ *
510
+ * ```jsx
511
+ * <FormControl>
512
+ * <InputLabel htmlFor="my-input">Email address</InputLabel>
513
+ * <Input id="my-input" aria-describedby="my-helper-text" />
514
+ * <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
515
+ * </FormControl>
516
+ * ```
517
+ *
518
+ * ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
519
+ * For instance, only one input can be focused at the same time, the state shouldn't be shared.
520
+ */
521
+ const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
522
+ const props = useDefaultProps({
523
+ props: inProps,
524
+ name: 'MuiFormControl'
525
+ });
526
+ const {
527
+ children,
528
+ className,
529
+ color = 'primary',
530
+ component = 'div',
531
+ disabled = false,
532
+ error = false,
533
+ focused: visuallyFocused,
534
+ fullWidth = false,
535
+ hiddenLabel = false,
536
+ margin = 'none',
537
+ required = false,
538
+ size = 'medium',
539
+ variant = 'outlined'
540
+ } = props,
541
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$3);
542
+ const ownerState = _extends$1({}, props, {
543
+ color,
544
+ component,
545
+ disabled,
546
+ error,
547
+ fullWidth,
548
+ hiddenLabel,
549
+ margin,
550
+ required,
551
+ size,
552
+ variant
553
+ });
554
+ const classes = useUtilityClasses$2(ownerState);
555
+ const [adornedStart, setAdornedStart] = React.useState(() => {
556
+ // We need to iterate through the children and find the Input in order
557
+ // to fully support server-side rendering.
558
+ let initialAdornedStart = false;
559
+ if (children) {
560
+ React.Children.forEach(children, child => {
561
+ if (!isMuiElement(child, ['Input', 'Select'])) {
562
+ return;
563
+ }
564
+ const input = isMuiElement(child, ['Select']) ? child.props.input : child;
565
+ if (input && isAdornedStart(input.props)) {
566
+ initialAdornedStart = true;
567
+ }
568
+ });
569
+ }
570
+ return initialAdornedStart;
571
+ });
572
+ const [filled, setFilled] = React.useState(() => {
573
+ // We need to iterate through the children and find the Input in order
574
+ // to fully support server-side rendering.
575
+ let initialFilled = false;
576
+ if (children) {
577
+ React.Children.forEach(children, child => {
578
+ if (!isMuiElement(child, ['Input', 'Select'])) {
579
+ return;
580
+ }
581
+ if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
582
+ initialFilled = true;
583
+ }
584
+ });
585
+ }
586
+ return initialFilled;
587
+ });
588
+ const [focusedState, setFocused] = React.useState(false);
589
+ if (disabled && focusedState) {
590
+ setFocused(false);
591
+ }
592
+ const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
593
+ let registerEffect;
594
+ if (process.env.NODE_ENV !== 'production') {
595
+ // eslint-disable-next-line react-hooks/rules-of-hooks
596
+ const registeredInput = React.useRef(false);
597
+ registerEffect = () => {
598
+ if (registeredInput.current) {
599
+ console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
600
+ }
601
+ registeredInput.current = true;
602
+ return () => {
603
+ registeredInput.current = false;
604
+ };
605
+ };
606
+ }
607
+ const childContext = React.useMemo(() => {
608
+ return {
609
+ adornedStart,
610
+ setAdornedStart,
611
+ color,
612
+ disabled,
613
+ error,
614
+ filled,
615
+ focused,
616
+ fullWidth,
617
+ hiddenLabel,
618
+ size,
619
+ onBlur: () => {
620
+ setFocused(false);
621
+ },
622
+ onEmpty: () => {
623
+ setFilled(false);
624
+ },
625
+ onFilled: () => {
626
+ setFilled(true);
627
+ },
628
+ onFocus: () => {
629
+ setFocused(true);
630
+ },
631
+ registerEffect,
632
+ required,
633
+ variant
634
+ };
635
+ }, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, required, size, variant]);
636
+ return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
637
+ value: childContext,
638
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, _extends$1({
639
+ as: component,
640
+ ownerState: ownerState,
641
+ className: clsx$1(classes.root, className),
642
+ ref: ref
643
+ }, other, {
644
+ children: children
645
+ }))
646
+ });
647
+ });
648
+ process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
649
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
650
+ // │ These PropTypes are generated from the TypeScript type definitions. │
651
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
652
+ // └─────────────────────────────────────────────────────────────────────┘
653
+ /**
654
+ * The content of the component.
655
+ */
656
+ children: PropTypes.node,
657
+ /**
658
+ * Override or extend the styles applied to the component.
659
+ */
660
+ classes: PropTypes.object,
661
+ /**
662
+ * @ignore
663
+ */
664
+ className: PropTypes.string,
665
+ /**
666
+ * The color of the component.
667
+ * It supports both default and custom theme colors, which can be added as shown in the
668
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
669
+ * @default 'primary'
670
+ */
671
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
672
+ /**
673
+ * The component used for the root node.
674
+ * Either a string to use a HTML element or a component.
675
+ */
676
+ component: PropTypes.elementType,
677
+ /**
678
+ * If `true`, the label, input and helper text should be displayed in a disabled state.
679
+ * @default false
680
+ */
681
+ disabled: PropTypes.bool,
682
+ /**
683
+ * If `true`, the label is displayed in an error state.
684
+ * @default false
685
+ */
686
+ error: PropTypes.bool,
687
+ /**
688
+ * If `true`, the component is displayed in focused state.
689
+ */
690
+ focused: PropTypes.bool,
691
+ /**
692
+ * If `true`, the component will take up the full width of its container.
693
+ * @default false
694
+ */
695
+ fullWidth: PropTypes.bool,
696
+ /**
697
+ * If `true`, the label is hidden.
698
+ * This is used to increase density for a `FilledInput`.
699
+ * Be sure to add `aria-label` to the `input` element.
700
+ * @default false
701
+ */
702
+ hiddenLabel: PropTypes.bool,
703
+ /**
704
+ * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
705
+ * @default 'none'
706
+ */
707
+ margin: PropTypes.oneOf(['dense', 'none', 'normal']),
708
+ /**
709
+ * If `true`, the label will indicate that the `input` is required.
710
+ * @default false
711
+ */
712
+ required: PropTypes.bool,
713
+ /**
714
+ * The size of the component.
715
+ * @default 'medium'
716
+ */
717
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
718
+ /**
719
+ * The system prop that allows defining system overrides as well as additional CSS styles.
720
+ */
721
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
722
+ /**
723
+ * The variant to use.
724
+ * @default 'outlined'
725
+ */
726
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
727
+ } : void 0;
728
+ var FormControl$1 = FormControl;
729
+
730
+ function getFormHelperTextUtilityClasses(slot) {
731
+ return generateUtilityClass('MuiFormHelperText', slot);
732
+ }
733
+ const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
734
+ var formHelperTextClasses$1 = formHelperTextClasses;
735
+
736
+ var _span;
737
+ const _excluded$2 = ["children", "className", "component", "disabled", "error", "filled", "focused", "margin", "required", "variant"];
738
+ const useUtilityClasses$1 = ownerState => {
739
+ const {
740
+ classes,
741
+ contained,
742
+ size,
743
+ disabled,
744
+ error,
745
+ filled,
746
+ focused,
747
+ required
748
+ } = ownerState;
749
+ const slots = {
750
+ root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
751
+ };
752
+ return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
753
+ };
754
+ const FormHelperTextRoot = styled$1('p', {
755
+ name: 'MuiFormHelperText',
756
+ slot: 'Root',
757
+ overridesResolver: (props, styles) => {
758
+ const {
759
+ ownerState
760
+ } = props;
761
+ return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
762
+ }
763
+ })(({
764
+ theme,
765
+ ownerState
766
+ }) => _extends$1({
767
+ color: (theme.vars || theme).palette.text.secondary
768
+ }, theme.typography.caption, {
769
+ textAlign: 'left',
770
+ marginTop: 3,
771
+ marginRight: 0,
772
+ marginBottom: 0,
773
+ marginLeft: 0,
774
+ [`&.${formHelperTextClasses$1.disabled}`]: {
775
+ color: (theme.vars || theme).palette.text.disabled
776
+ },
777
+ [`&.${formHelperTextClasses$1.error}`]: {
778
+ color: (theme.vars || theme).palette.error.main
779
+ }
780
+ }, ownerState.size === 'small' && {
781
+ marginTop: 4
782
+ }, ownerState.contained && {
783
+ marginLeft: 14,
784
+ marginRight: 14
785
+ }));
786
+ const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
787
+ const props = useDefaultProps({
788
+ props: inProps,
789
+ name: 'MuiFormHelperText'
790
+ });
791
+ const {
792
+ children,
793
+ className,
794
+ component = 'p'
795
+ } = props,
796
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$2);
797
+ const muiFormControl = useFormControl();
798
+ const fcs = formControlState({
799
+ props,
800
+ muiFormControl,
801
+ states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
802
+ });
803
+ const ownerState = _extends$1({}, props, {
804
+ component,
805
+ contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
806
+ variant: fcs.variant,
807
+ size: fcs.size,
808
+ disabled: fcs.disabled,
809
+ error: fcs.error,
810
+ filled: fcs.filled,
811
+ focused: fcs.focused,
812
+ required: fcs.required
813
+ });
814
+ const classes = useUtilityClasses$1(ownerState);
815
+ return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, _extends$1({
816
+ as: component,
817
+ ownerState: ownerState,
818
+ className: clsx$1(classes.root, className),
819
+ ref: ref
820
+ }, other, {
821
+ children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
822
+ _span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
823
+ className: "notranslate",
824
+ children: "\u200B"
825
+ })) : children
826
+ }));
827
+ });
828
+ process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
829
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
830
+ // │ These PropTypes are generated from the TypeScript type definitions. │
831
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
832
+ // └─────────────────────────────────────────────────────────────────────┘
833
+ /**
834
+ * The content of the component.
835
+ *
836
+ * If `' '` is provided, the component reserves one line height for displaying a future message.
837
+ */
838
+ children: PropTypes.node,
839
+ /**
840
+ * Override or extend the styles applied to the component.
841
+ */
842
+ classes: PropTypes.object,
843
+ /**
844
+ * @ignore
845
+ */
846
+ className: PropTypes.string,
847
+ /**
848
+ * The component used for the root node.
849
+ * Either a string to use a HTML element or a component.
850
+ */
851
+ component: PropTypes.elementType,
852
+ /**
853
+ * If `true`, the helper text should be displayed in a disabled state.
854
+ */
855
+ disabled: PropTypes.bool,
856
+ /**
857
+ * If `true`, helper text should be displayed in an error state.
858
+ */
859
+ error: PropTypes.bool,
860
+ /**
861
+ * If `true`, the helper text should use filled classes key.
862
+ */
863
+ filled: PropTypes.bool,
864
+ /**
865
+ * If `true`, the helper text should use focused classes key.
866
+ */
867
+ focused: PropTypes.bool,
868
+ /**
869
+ * If `dense`, will adjust vertical spacing. This is normally obtained via context from
870
+ * FormControl.
871
+ */
872
+ margin: PropTypes.oneOf(['dense']),
873
+ /**
874
+ * If `true`, the helper text should use required classes key.
875
+ */
876
+ required: PropTypes.bool,
877
+ /**
878
+ * The system prop that allows defining system overrides as well as additional CSS styles.
879
+ */
880
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
881
+ /**
882
+ * The variant to use.
883
+ */
884
+ variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
885
+ } : void 0;
886
+ var FormHelperText$1 = FormHelperText;
887
+
888
+ function getTextFieldUtilityClass(slot) {
889
+ return generateUtilityClass('MuiTextField', slot);
890
+ }
891
+ generateUtilityClasses('MuiTextField', ['root']);
892
+
893
+ 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"];
894
+ const variantComponent = {
895
+ standard: Input,
896
+ filled: FilledInput,
897
+ outlined: OutlinedInput
898
+ };
899
+ const useUtilityClasses = ownerState => {
900
+ const {
901
+ classes
902
+ } = ownerState;
903
+ const slots = {
904
+ root: ['root']
905
+ };
906
+ return composeClasses(slots, getTextFieldUtilityClass, classes);
907
+ };
908
+ const TextFieldRoot = styled$1(FormControl$1, {
909
+ name: 'MuiTextField',
910
+ slot: 'Root',
911
+ overridesResolver: (props, styles) => styles.root
912
+ })({});
913
+
914
+ /**
915
+ * The `TextField` is a convenience wrapper for the most common cases (80%).
916
+ * It cannot be all things to all people, otherwise the API would grow out of control.
917
+ *
918
+ * ## Advanced Configuration
919
+ *
920
+ * It's important to understand that the text field is a simple abstraction
921
+ * on top of the following components:
922
+ *
923
+ * - [FormControl](/material-ui/api/form-control/)
924
+ * - [InputLabel](/material-ui/api/input-label/)
925
+ * - [FilledInput](/material-ui/api/filled-input/)
926
+ * - [OutlinedInput](/material-ui/api/outlined-input/)
927
+ * - [Input](/material-ui/api/input/)
928
+ * - [FormHelperText](/material-ui/api/form-helper-text/)
929
+ *
930
+ * If you wish to alter the props applied to the `input` element, you can do so as follows:
931
+ *
932
+ * ```jsx
933
+ * const inputProps = {
934
+ * step: 300,
935
+ * };
936
+ *
937
+ * return <TextField id="time" type="time" inputProps={inputProps} />;
938
+ * ```
939
+ *
940
+ * For advanced cases, please look at the source of TextField by clicking on the
941
+ * "Edit this page" button above. Consider either:
942
+ *
943
+ * - using the upper case props for passing values directly to the components
944
+ * - using the underlying components directly as shown in the demos
945
+ */
946
+ const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
947
+ const props = useDefaultProps({
948
+ props: inProps,
949
+ name: 'MuiTextField'
950
+ });
951
+ const {
952
+ autoComplete,
953
+ autoFocus = false,
954
+ children,
955
+ className,
956
+ color = 'primary',
957
+ defaultValue,
958
+ disabled = false,
959
+ error = false,
960
+ FormHelperTextProps,
961
+ fullWidth = false,
962
+ helperText,
963
+ id: idOverride,
964
+ InputLabelProps,
965
+ inputProps,
966
+ InputProps,
967
+ inputRef,
968
+ label,
969
+ maxRows,
970
+ minRows,
971
+ multiline = false,
972
+ name,
973
+ onBlur,
974
+ onChange,
975
+ onFocus,
976
+ placeholder,
977
+ required = false,
978
+ rows,
979
+ select = false,
980
+ SelectProps,
981
+ type,
982
+ value,
983
+ variant = 'outlined'
984
+ } = props,
985
+ other = _objectWithoutPropertiesLoose$1(props, _excluded$1);
986
+ const ownerState = _extends$1({}, props, {
987
+ autoFocus,
988
+ color,
989
+ disabled,
990
+ error,
991
+ fullWidth,
992
+ multiline,
993
+ required,
994
+ select,
995
+ variant
996
+ });
997
+ const classes = useUtilityClasses(ownerState);
998
+ if (process.env.NODE_ENV !== 'production') {
999
+ if (select && !children) {
1000
+ console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
1001
+ }
1002
+ }
1003
+ const InputMore = {};
1004
+ if (variant === 'outlined') {
1005
+ if (InputLabelProps && typeof InputLabelProps.shrink !== 'undefined') {
1006
+ InputMore.notched = InputLabelProps.shrink;
1007
+ }
1008
+ InputMore.label = label;
1009
+ }
1010
+ if (select) {
1011
+ // unset defaults from textbox inputs
1012
+ if (!SelectProps || !SelectProps.native) {
1013
+ InputMore.id = undefined;
1014
+ }
1015
+ InputMore['aria-describedby'] = undefined;
1016
+ }
1017
+ const id = useId(idOverride);
1018
+ const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
1019
+ const inputLabelId = label && id ? `${id}-label` : undefined;
1020
+ const InputComponent = variantComponent[variant];
1021
+ const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputComponent, _extends$1({
1022
+ "aria-describedby": helperTextId,
1023
+ autoComplete: autoComplete,
1024
+ autoFocus: autoFocus,
1025
+ defaultValue: defaultValue,
1026
+ fullWidth: fullWidth,
1027
+ multiline: multiline,
1028
+ name: name,
1029
+ rows: rows,
1030
+ maxRows: maxRows,
1031
+ minRows: minRows,
1032
+ type: type,
1033
+ value: value,
1034
+ id: id,
1035
+ inputRef: inputRef,
1036
+ onBlur: onBlur,
1037
+ onChange: onChange,
1038
+ onFocus: onFocus,
1039
+ placeholder: placeholder,
1040
+ inputProps: inputProps
1041
+ }, InputMore, InputProps));
1042
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(TextFieldRoot, _extends$1({
1043
+ className: clsx$1(classes.root, className),
1044
+ disabled: disabled,
1045
+ error: error,
1046
+ fullWidth: fullWidth,
1047
+ ref: ref,
1048
+ required: required,
1049
+ color: color,
1050
+ variant: variant,
1051
+ ownerState: ownerState
1052
+ }, other, {
1053
+ children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabel$1, _extends$1({
1054
+ htmlFor: id,
1055
+ id: inputLabelId
1056
+ }, InputLabelProps, {
1057
+ children: label
1058
+ })), select ? /*#__PURE__*/jsxRuntimeExports.jsx(Select, _extends$1({
1059
+ "aria-describedby": helperTextId,
1060
+ id: id,
1061
+ labelId: inputLabelId,
1062
+ value: value,
1063
+ input: InputElement
1064
+ }, SelectProps, {
1065
+ children: children
1066
+ })) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperText$1, _extends$1({
1067
+ id: helperTextId
1068
+ }, FormHelperTextProps, {
1069
+ children: helperText
1070
+ }))]
1071
+ }));
1072
+ });
1073
+ process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
1074
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
1075
+ // │ These PropTypes are generated from the TypeScript type definitions. │
1076
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
1077
+ // └─────────────────────────────────────────────────────────────────────┘
1078
+ /**
1079
+ * This prop helps users to fill forms faster, especially on mobile devices.
1080
+ * The name can be confusing, as it's more like an autofill.
1081
+ * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
1082
+ */
1083
+ autoComplete: PropTypes.string,
1084
+ /**
1085
+ * If `true`, the `input` element is focused during the first mount.
1086
+ * @default false
1087
+ */
1088
+ autoFocus: PropTypes.bool,
1089
+ /**
1090
+ * @ignore
1091
+ */
1092
+ children: PropTypes.node,
1093
+ /**
1094
+ * Override or extend the styles applied to the component.
1095
+ */
1096
+ classes: PropTypes.object,
1097
+ /**
1098
+ * @ignore
1099
+ */
1100
+ className: PropTypes.string,
1101
+ /**
1102
+ * The color of the component.
1103
+ * It supports both default and custom theme colors, which can be added as shown in the
1104
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
1105
+ * @default 'primary'
1106
+ */
1107
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
1108
+ /**
1109
+ * The default value. Use when the component is not controlled.
1110
+ */
1111
+ defaultValue: PropTypes.any,
1112
+ /**
1113
+ * If `true`, the component is disabled.
1114
+ * @default false
1115
+ */
1116
+ disabled: PropTypes.bool,
1117
+ /**
1118
+ * If `true`, the label is displayed in an error state.
1119
+ * @default false
1120
+ */
1121
+ error: PropTypes.bool,
1122
+ /**
1123
+ * Props applied to the [`FormHelperText`](/material-ui/api/form-helper-text/) element.
1124
+ */
1125
+ FormHelperTextProps: PropTypes.object,
1126
+ /**
1127
+ * If `true`, the input will take up the full width of its container.
1128
+ * @default false
1129
+ */
1130
+ fullWidth: PropTypes.bool,
1131
+ /**
1132
+ * The helper text content.
1133
+ */
1134
+ helperText: PropTypes.node,
1135
+ /**
1136
+ * The id of the `input` element.
1137
+ * Use this prop to make `label` and `helperText` accessible for screen readers.
1138
+ */
1139
+ id: PropTypes.string,
1140
+ /**
1141
+ * Props applied to the [`InputLabel`](/material-ui/api/input-label/) element.
1142
+ * Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
1143
+ */
1144
+ InputLabelProps: PropTypes.object,
1145
+ /**
1146
+ * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
1147
+ */
1148
+ inputProps: PropTypes.object,
1149
+ /**
1150
+ * Props applied to the Input element.
1151
+ * It will be a [`FilledInput`](/material-ui/api/filled-input/),
1152
+ * [`OutlinedInput`](/material-ui/api/outlined-input/) or [`Input`](/material-ui/api/input/)
1153
+ * component depending on the `variant` prop value.
1154
+ */
1155
+ InputProps: PropTypes.object,
1156
+ /**
1157
+ * Pass a ref to the `input` element.
1158
+ */
1159
+ inputRef: refType,
1160
+ /**
1161
+ * The label content.
1162
+ */
1163
+ label: PropTypes.node,
1164
+ /**
1165
+ * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
1166
+ * @default 'none'
1167
+ */
1168
+ margin: PropTypes.oneOf(['dense', 'none', 'normal']),
1169
+ /**
1170
+ * Maximum number of rows to display when multiline option is set to true.
1171
+ */
1172
+ maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1173
+ /**
1174
+ * Minimum number of rows to display when multiline option is set to true.
1175
+ */
1176
+ minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1177
+ /**
1178
+ * If `true`, a `textarea` element is rendered instead of an input.
1179
+ * @default false
1180
+ */
1181
+ multiline: PropTypes.bool,
1182
+ /**
1183
+ * Name attribute of the `input` element.
1184
+ */
1185
+ name: PropTypes.string,
1186
+ /**
1187
+ * @ignore
1188
+ */
1189
+ onBlur: PropTypes.func,
1190
+ /**
1191
+ * Callback fired when the value is changed.
1192
+ *
1193
+ * @param {object} event The event source of the callback.
1194
+ * You can pull out the new value by accessing `event.target.value` (string).
1195
+ */
1196
+ onChange: PropTypes.func,
1197
+ /**
1198
+ * @ignore
1199
+ */
1200
+ onFocus: PropTypes.func,
1201
+ /**
1202
+ * The short hint displayed in the `input` before the user enters a value.
1203
+ */
1204
+ placeholder: PropTypes.string,
1205
+ /**
1206
+ * If `true`, the label is displayed as required and the `input` element is required.
1207
+ * @default false
1208
+ */
1209
+ required: PropTypes.bool,
1210
+ /**
1211
+ * Number of rows to display when multiline option is set to true.
1212
+ */
1213
+ rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1214
+ /**
1215
+ * Render a [`Select`](/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
1216
+ * If this option is set you must pass the options of the select as children.
1217
+ * @default false
1218
+ */
1219
+ select: PropTypes.bool,
1220
+ /**
1221
+ * Props applied to the [`Select`](/material-ui/api/select/) element.
1222
+ */
1223
+ SelectProps: PropTypes.object,
1224
+ /**
1225
+ * The size of the component.
1226
+ */
1227
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
1228
+ /**
1229
+ * The system prop that allows defining system overrides as well as additional CSS styles.
1230
+ */
1231
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1232
+ /**
1233
+ * 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).
1234
+ */
1235
+ type: PropTypes /* @typescript-to-proptypes-ignore */.string,
1236
+ /**
1237
+ * The value of the `input` element, required for a controlled component.
1238
+ */
1239
+ value: PropTypes.any,
1240
+ /**
1241
+ * The variant to use.
1242
+ * @default 'outlined'
1243
+ */
1244
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
1245
+ } : void 0;
1246
+ var TextField$1 = TextField;
16
1247
 
17
1248
  const SUBMIT_FILTER_STROKE_TIME = 500;
18
1249
  const InputNumberInterval = props => {
@@ -54,7 +1285,7 @@ const InputNumberInterval = props => {
54
1285
  const newLowerBound = event.target.value;
55
1286
  updateFilterValue(newLowerBound, filterValueState[1]);
56
1287
  };
57
- return /*#__PURE__*/React.createElement(Box, {
1288
+ return /*#__PURE__*/React.createElement(Box$1, {
58
1289
  sx: {
59
1290
  display: 'inline-flex',
60
1291
  flexDirection: 'row',
@@ -62,7 +1293,7 @@ const InputNumberInterval = props => {
62
1293
  height: 48,
63
1294
  pl: '20px'
64
1295
  }
65
- }, /*#__PURE__*/React.createElement(TextField, {
1296
+ }, /*#__PURE__*/React.createElement(TextField$1, {
66
1297
  name: "lower-bound-input",
67
1298
  placeholder: "From",
68
1299
  label: "From",
@@ -74,7 +1305,7 @@ const InputNumberInterval = props => {
74
1305
  sx: {
75
1306
  mr: 2
76
1307
  }
77
- }), /*#__PURE__*/React.createElement(TextField, {
1308
+ }), /*#__PURE__*/React.createElement(TextField$1, {
78
1309
  name: "upper-bound-input",
79
1310
  placeholder: "To",
80
1311
  label: "To",
@@ -106,8 +1337,8 @@ const isBetweenOperator = {
106
1337
  if (typeof filterItem.value[0] !== 'number' || typeof filterItem.value[1] !== 'number') {
107
1338
  return null;
108
1339
  }
109
- return value => {
110
- return value !== null && value !== undefined && filterItem.value[0] <= value && value <= filterItem.value[1];
1340
+ return params => {
1341
+ return params.value !== null && params.value !== undefined && filterItem.value[0] <= params.value && params.value <= filterItem.value[1];
111
1342
  };
112
1343
  },
113
1344
  InputComponent: InputNumberInterval
@@ -123,14 +1354,14 @@ const doesNotContain = {
123
1354
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
124
1355
  return null;
125
1356
  }
126
- return value => {
1357
+ return params => {
127
1358
  if (filterItem.value.length === 0) {
128
1359
  return true;
129
1360
  }
130
- if (value == null) {
1361
+ if (params.value == null) {
131
1362
  return true;
132
1363
  }
133
- if (String(value).indexOf(filterItem.value) !== -1) {
1364
+ if (String(params.value).indexOf(filterItem.value) !== -1) {
134
1365
  return false;
135
1366
  }
136
1367
  return true;
@@ -147,11 +1378,11 @@ const doesNotEndWithOperator = {
147
1378
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
148
1379
  return null;
149
1380
  }
150
- return value => {
151
- if (value == null) {
1381
+ return params => {
1382
+ if (params.value == null) {
152
1383
  return true;
153
1384
  }
154
- return !String(value).endsWith(filterItem.value);
1385
+ return !String(params.value).endsWith(filterItem.value);
155
1386
  };
156
1387
  },
157
1388
  InputComponent: GridFilterInputValue
@@ -165,11 +1396,11 @@ const doesNotEqual = {
165
1396
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
166
1397
  return null;
167
1398
  }
168
- return value => {
169
- if (value == null) {
1399
+ return params => {
1400
+ if (params.value == null) {
170
1401
  return true;
171
1402
  }
172
- if (String(value) === filterItem.value) {
1403
+ if (String(params.value) === filterItem.value) {
173
1404
  return false;
174
1405
  }
175
1406
  return true;
@@ -186,11 +1417,11 @@ const doesNotHaveOperator = {
186
1417
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
187
1418
  return null;
188
1419
  }
189
- return value => {
190
- if (value == null) {
1420
+ return params => {
1421
+ if (params.value == null) {
191
1422
  return true;
192
1423
  }
193
- const cellValues = Array.isArray(value) ? value : [value];
1424
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
194
1425
  return !cellValues.map(value => String(value)).includes(filterItem.value);
195
1426
  };
196
1427
  },
@@ -208,11 +1439,11 @@ const doesNotStartWithOperator = {
208
1439
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
209
1440
  return null;
210
1441
  }
211
- return value => {
212
- if (value == null) {
1442
+ return params => {
1443
+ if (params.value == null) {
213
1444
  return true;
214
1445
  }
215
- return !String(value).startsWith(filterItem.value);
1446
+ return !String(params.value).startsWith(filterItem.value);
216
1447
  };
217
1448
  },
218
1449
  InputComponent: GridFilterInputValue
@@ -226,11 +1457,11 @@ const hasOperator = {
226
1457
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
227
1458
  return null;
228
1459
  }
229
- return value => {
230
- if (value == null) {
1460
+ return params => {
1461
+ if (params.value == null) {
231
1462
  return false;
232
1463
  }
233
- const cellValues = Array.isArray(value) ? value : [value];
1464
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
234
1465
  return cellValues.map(value => String(value)).includes(filterItem.value);
235
1466
  };
236
1467
  },
@@ -248,11 +1479,11 @@ const hasOnlyOperator = {
248
1479
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
249
1480
  return null;
250
1481
  }
251
- return value => {
252
- if (value == null) {
1482
+ return params => {
1483
+ if (params.value == null) {
253
1484
  return false;
254
1485
  }
255
- const cellValues = Array.isArray(value) ? value : [value];
1486
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
256
1487
  return cellValues.length === 1 && String(cellValues[0]) === filterItem.value;
257
1488
  };
258
1489
  },
@@ -270,14 +1501,14 @@ const isOperator = {
270
1501
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
271
1502
  return null;
272
1503
  }
273
- return value => {
274
- if (value == null) {
1504
+ return params => {
1505
+ if (params.value == null) {
275
1506
  return false;
276
1507
  }
277
- if (Array.isArray(value)) {
1508
+ if (Array.isArray(params.value)) {
278
1509
  return false;
279
1510
  }
280
- return String(value) === filterItem.value;
1511
+ return String(params.value) === filterItem.value;
281
1512
  };
282
1513
  },
283
1514
  InputComponent: GridFilterInputValue
@@ -294,14 +1525,14 @@ const isNotOperator = {
294
1525
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
295
1526
  return null;
296
1527
  }
297
- return value => {
298
- if (value == null) {
1528
+ return params => {
1529
+ if (params.value == null) {
299
1530
  return true;
300
1531
  }
301
- if (Array.isArray(value)) {
1532
+ if (Array.isArray(params.value)) {
302
1533
  return true;
303
1534
  }
304
- return String(value) !== filterItem.value;
1535
+ return String(params.value) !== filterItem.value;
305
1536
  };
306
1537
  },
307
1538
  InputComponent: GridFilterInputValue
@@ -318,14 +1549,14 @@ const containsAnyOfOperator = {
318
1549
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
319
1550
  return null;
320
1551
  }
321
- return value => {
1552
+ return params => {
322
1553
  if (filterItem.value.length === 0) {
323
1554
  return true;
324
1555
  }
325
- if (value == null) {
1556
+ if (params.value == null) {
326
1557
  return false;
327
1558
  }
328
- const paramValues = Array.isArray(value) ? value : [value];
1559
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
329
1560
  let match = false;
330
1561
  filterItem.value.forEach(filteredValue => {
331
1562
  paramValues.forEach(paramValue => {
@@ -348,14 +1579,14 @@ const doesNotContainAnyOfOperator = {
348
1579
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
349
1580
  return null;
350
1581
  }
351
- return value => {
1582
+ return params => {
352
1583
  if (filterItem.value.length === 0) {
353
1584
  return true;
354
1585
  }
355
- if (value == null) {
1586
+ if (params.value == null) {
356
1587
  return true;
357
1588
  }
358
- const paramValues = Array.isArray(value) ? value : [value];
1589
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
359
1590
  for (const filteredValue of filterItem.value) {
360
1591
  for (const paramValue of paramValues) {
361
1592
  if (String(paramValue).indexOf(filteredValue) !== -1) {
@@ -377,14 +1608,14 @@ const doesNotEndWithAnyOfOperator = {
377
1608
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
378
1609
  return null;
379
1610
  }
380
- return value => {
1611
+ return params => {
381
1612
  if (filterItem.value.length === 0) {
382
1613
  return true;
383
1614
  }
384
- if (value == null) {
1615
+ if (params.value == null) {
385
1616
  return true;
386
1617
  }
387
- const paramValues = Array.isArray(value) ? value : [value];
1618
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
388
1619
  for (const filteredValue of filterItem.value) {
389
1620
  for (const paramValue of paramValues) {
390
1621
  if (String(paramValue).endsWith(filteredValue)) {
@@ -406,11 +1637,11 @@ const doesNotHaveAnyOf = {
406
1637
  if (!filterItem.field || !filterItem.value || !Array.isArray(filterItem.value) || filterItem.value.length === 0) {
407
1638
  return null;
408
1639
  }
409
- return value => {
410
- if (value == null) {
1640
+ return params => {
1641
+ if (params.value == null) {
411
1642
  return true;
412
1643
  }
413
- const cellValues = Array.isArray(value) ? value : [value];
1644
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
414
1645
 
415
1646
  // Return true only if none of the filter values are in the cell values
416
1647
  return filterItem.value.every(filterVal => !cellValues.map(value => String(value)).includes(filterVal));
@@ -430,14 +1661,14 @@ const doesNotStartWithAnyOfOperator = {
430
1661
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
431
1662
  return null;
432
1663
  }
433
- return value => {
1664
+ return params => {
434
1665
  if (filterItem.value.length === 0) {
435
1666
  return true;
436
1667
  }
437
- if (value == null) {
1668
+ if (params.value == null) {
438
1669
  return true;
439
1670
  }
440
- const paramValues = Array.isArray(value) ? value : [value];
1671
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
441
1672
  for (const filteredValue of filterItem.value) {
442
1673
  for (const paramValue of paramValues) {
443
1674
  if (String(paramValue).startsWith(filteredValue)) {
@@ -459,14 +1690,14 @@ const endsWithAnyOfOperator = {
459
1690
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
460
1691
  return null;
461
1692
  }
462
- return value => {
1693
+ return params => {
463
1694
  if (filterItem.value.length === 0) {
464
1695
  return true;
465
1696
  }
466
- if (value == null) {
1697
+ if (params.value == null) {
467
1698
  return false;
468
1699
  }
469
- const paramValues = Array.isArray(value) ? value : [value];
1700
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
470
1701
  let match = false;
471
1702
  filterItem.value.forEach(filteredValue => {
472
1703
  paramValues.forEach(paramValue => {
@@ -489,14 +1720,14 @@ const hasAllOfOperator = {
489
1720
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
490
1721
  return null;
491
1722
  }
492
- return value => {
1723
+ return params => {
493
1724
  if (filterItem.value.length === 0) {
494
1725
  return true;
495
1726
  }
496
- if (value == null) {
1727
+ if (params.value == null) {
497
1728
  return false;
498
1729
  }
499
- const cellValues = Array.isArray(value) ? value : [value];
1730
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
500
1731
  const cellStrings = cellValues.map(value => String(value));
501
1732
  const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
502
1733
  return filterItemValues.every(v => cellStrings.includes(v));
@@ -516,14 +1747,14 @@ const hasAnyOfOperator = {
516
1747
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
517
1748
  return null;
518
1749
  }
519
- return value => {
1750
+ return params => {
520
1751
  if (filterItem.value.length === 0) {
521
1752
  return true;
522
1753
  }
523
- if (value == null) {
1754
+ if (params.value == null) {
524
1755
  return false;
525
1756
  }
526
- const cellValues = Array.isArray(value) ? value : [value];
1757
+ const cellValues = Array.isArray(params.value) ? params.value : [params.value];
527
1758
  const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
528
1759
  return filterItemValues.some(v => cellValues.map(value => String(value)).includes(v));
529
1760
  };
@@ -542,14 +1773,14 @@ const isAnyOfOperator = {
542
1773
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
543
1774
  return null;
544
1775
  }
545
- return value => {
1776
+ return params => {
546
1777
  if (filterItem.value.length === 0) {
547
1778
  return true;
548
1779
  }
549
- if (value == null) {
1780
+ if (params.value == null) {
550
1781
  return false;
551
1782
  }
552
- const paramValues = Array.isArray(value) ? value : [value];
1783
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
553
1784
  for (const paramValue of paramValues) {
554
1785
  if (filterItem.value.includes(String(paramValue))) {
555
1786
  return true;
@@ -572,14 +1803,14 @@ const isNotAnyOfOperator = {
572
1803
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
573
1804
  return null;
574
1805
  }
575
- return value => {
1806
+ return params => {
576
1807
  if (filterItem.value.length === 0) {
577
1808
  return true;
578
1809
  }
579
- if (value == null) {
1810
+ if (params.value == null) {
580
1811
  return true;
581
1812
  }
582
- const paramValues = Array.isArray(value) ? value : [value];
1813
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
583
1814
  for (const paramValue of paramValues) {
584
1815
  if (filterItem.value.includes(String(paramValue))) {
585
1816
  return false;
@@ -602,14 +1833,14 @@ const startsWithAnyOfOperator = {
602
1833
  if (!filterItem.field || !filterItem.value || !filterItem.operator) {
603
1834
  return null;
604
1835
  }
605
- return value => {
1836
+ return params => {
606
1837
  if (filterItem.value.length === 0) {
607
1838
  return true;
608
1839
  }
609
- if (value == null) {
1840
+ if (params.value == null) {
610
1841
  return false;
611
1842
  }
612
- const paramValues = Array.isArray(value) ? value : [value];
1843
+ const paramValues = Array.isArray(params.value) ? params.value : [params.value];
613
1844
  let match = false;
614
1845
  filterItem.value.forEach(filteredValue => {
615
1846
  paramValues.forEach(paramValue => {
@@ -636,15 +1867,15 @@ const isEmptyOperator = {
636
1867
  value: 'isEmpty',
637
1868
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
638
1869
  getApplyFilterFn: _filterItem => {
639
- return value => {
640
- if (value == null) {
1870
+ return params => {
1871
+ if (params.value == null) {
641
1872
  return true;
642
1873
  }
643
- if (Array.isArray(value)) {
644
- return value.length === 0;
1874
+ if (Array.isArray(params.value)) {
1875
+ return params.value.length === 0;
645
1876
  }
646
- if (typeof value === 'string') {
647
- return value.trim() === '';
1877
+ if (typeof params.value === 'string') {
1878
+ return params.value.trim() === '';
648
1879
  }
649
1880
  return false;
650
1881
  };
@@ -656,15 +1887,15 @@ const isNotEmptyOperator = {
656
1887
  value: 'isNotEmpty',
657
1888
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
658
1889
  getApplyFilterFn: _filterItem => {
659
- return value => {
660
- if (value == null) {
1890
+ return params => {
1891
+ if (params.value == null) {
661
1892
  return false;
662
1893
  }
663
- if (Array.isArray(value)) {
664
- return value.length > 0;
1894
+ if (Array.isArray(params.value)) {
1895
+ return params.value.length > 0;
665
1896
  }
666
- if (typeof value === 'string') {
667
- return value.trim() !== '';
1897
+ if (typeof params.value === 'string') {
1898
+ return params.value.trim() !== '';
668
1899
  }
669
1900
  return true;
670
1901
  };
@@ -703,20 +1934,14 @@ const DIMENSION_MODEL_KEY = 'dimension';
703
1934
  const FILTER_SEARCH_KEY = 'searchModel';
704
1935
  const DENSITY_MODEL_KEY = 'densityModel';
705
1936
  const COLUMN_ORDER_MODEL_KEY = 'columnOrderModel';
706
- const ROW_GROUPING_MODEL_KEY = 'rowGroupingModel';
707
- const AGGREGATION_MODEL_KEY = 'aggregationModel';
708
- /** Storage category key for the pivot column/row/value configuration. Consumer interop — use with `buildStorageKey`. */
709
- const PIVOT_MODEL_KEY = 'pivotModel';
710
- /** Storage category key for whether pivoting is active. Consumer interop — use with `buildStorageKey`. */
711
- const PIVOT_ACTIVE_KEY = 'pivotActive';
712
- const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS, DENSITY_MODEL_KEY, COLUMN_ORDER_MODEL_KEY, ROW_GROUPING_MODEL_KEY, AGGREGATION_MODEL_KEY, PIVOT_MODEL_KEY, PIVOT_ACTIVE_KEY];
1937
+ 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];
713
1938
  /**
714
1939
  * Build the localStorage key for a specific grid state category.
715
1940
  * Consumers can use this to read or clear individual state entries directly.
716
1941
  *
717
1942
  * @example
718
1943
  * ```ts
719
- * const key = buildStorageKey({ id: pathname, version: 2, category: PIVOT_ACTIVE_KEY });
1944
+ * const key = buildStorageKey({ id: pathname, version: 2, category: 'filterModel' });
720
1945
  * localStorage.removeItem(key);
721
1946
  * ```
722
1947
  */
@@ -766,22 +1991,6 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
766
1991
  id,
767
1992
  version,
768
1993
  category: COLUMN_ORDER_MODEL_KEY
769
- }), buildStorageKey({
770
- id,
771
- version,
772
- category: ROW_GROUPING_MODEL_KEY
773
- }), buildStorageKey({
774
- id,
775
- version,
776
- category: AGGREGATION_MODEL_KEY
777
- }), buildStorageKey({
778
- id,
779
- version,
780
- category: PIVOT_MODEL_KEY
781
- }), buildStorageKey({
782
- id,
783
- version,
784
- category: PIVOT_ACTIVE_KEY
785
1994
  })];
786
1995
  for (const keyToDelete of keysToDelete) {
787
1996
  try {
@@ -808,6 +2017,19 @@ const clearAllVersionStorage = (id, maxVersion) => {
808
2017
  * Fully reset a `StatefulDataGrid` — clear localStorage for the given versions
809
2018
  * and strip all grid-owned URL params (`_*` and `v=`), preserving any non-grid params.
810
2019
  *
2020
+ * The function reads `window.location.search` directly so the strip always
2021
+ * operates on the live URL. This matters because consumers typically call this
2022
+ * from a component whose captured `search` snapshot may be stale — for example
2023
+ * when the grid has just written its own keys to the URL via the router adapter
2024
+ * but the parent hasn't re-rendered yet. Falling back to the supplied `search`
2025
+ * is only used in non-browser environments (SSR, unit tests without jsdom).
2026
+ *
2027
+ * The write is performed via `historyReplace(newSearch, { authoritative: true })`.
2028
+ * Adapters with delta/coalescing logic (e.g. `createReactRouterV5Adapter`)
2029
+ * recognise the `authoritative` flag and bypass the delta computation, which
2030
+ * would otherwise drop keys that grew into the URL after the parent's last
2031
+ * captured snapshot. Adapters without delta logic simply ignore the flag.
2032
+ *
811
2033
  * Call from within a component where the router values are available:
812
2034
  * ```ts
813
2035
  * const { search, historyReplace } = useMyRouter();
@@ -822,7 +2044,8 @@ const resetStatefulDataGridState = _ref2 => {
822
2044
  historyReplace
823
2045
  } = _ref2;
824
2046
  clearPreviousVersionStorage(id, versions);
825
- const params = new URLSearchParams(search);
2047
+ const liveSearch = typeof window !== 'undefined' && window.location ? window.location.search : search;
2048
+ const params = new URLSearchParams(liveSearch);
826
2049
  const keysToDelete = [];
827
2050
  params.forEach((_value, key) => {
828
2051
  if (key.startsWith('_') || key === 'v') {
@@ -832,7 +2055,59 @@ const resetStatefulDataGridState = _ref2 => {
832
2055
  for (const key of keysToDelete) {
833
2056
  params.delete(key);
834
2057
  }
835
- historyReplace(params.toString());
2058
+ historyReplace(params.toString(), {
2059
+ authoritative: true
2060
+ });
2061
+ };
2062
+
2063
+ /**
2064
+ * Reset only the column-visibility state of a `StatefulDataGrid` back to its
2065
+ * default (all columns visible). Clears the persisted `visibilityModel`
2066
+ * localStorage entry for the given versions and strips the `_columnVisibility`
2067
+ * param from the live URL, leaving every other piece of grid state (filters,
2068
+ * sort, pagination, pinned columns, …) untouched.
2069
+ *
2070
+ * This is the visibility-scoped counterpart to `resetStatefulDataGridState`.
2071
+ * Reach for it at transition points where a stale visibility snapshot would
2072
+ * otherwise re-seed and keep base columns hidden. Because it leaves the other
2073
+ * params alone it will not clobber a filter the caller is writing in the same
2074
+ * transition.
2075
+ *
2076
+ * Like `resetStatefulDataGridState`, the URL strip reads `window.location.search`
2077
+ * directly so it operates on the live URL (the caller's captured snapshot may
2078
+ * be stale), and writes via `historyReplace(newSearch, { authoritative: true })`.
2079
+ *
2080
+ * This clears the *persisted* state only. The caller is responsible for
2081
+ * resetting the *live* grid in the same tick:
2082
+ * ```ts
2083
+ * resetColumnVisibility({ id: pathname, versions: [0, 1], search, historyReplace });
2084
+ * apiRef.current?.setColumnVisibilityModel?.({});
2085
+ * ```
2086
+ */
2087
+ const resetColumnVisibility = _ref3 => {
2088
+ let {
2089
+ id,
2090
+ versions,
2091
+ search,
2092
+ historyReplace
2093
+ } = _ref3;
2094
+ for (const version of versions) {
2095
+ try {
2096
+ window.localStorage.removeItem(buildStorageKey({
2097
+ id,
2098
+ version,
2099
+ category: VISIBILITY_MODEL_KEY
2100
+ }));
2101
+ } catch (e) {
2102
+ // Ignore — storage may be unavailable (SSR, Safari private mode).
2103
+ }
2104
+ }
2105
+ const liveSearch = typeof window !== 'undefined' && window.location ? window.location.search : search;
2106
+ const params = new URLSearchParams(liveSearch);
2107
+ params.delete('_columnVisibility');
2108
+ historyReplace(params.toString(), {
2109
+ authoritative: true
2110
+ });
836
2111
  };
837
2112
 
838
2113
  /** Maximum query string length (chars) before compression kicks in. */
@@ -846,7 +2121,7 @@ const COMPRESSED_PREFIX = '~';
846
2121
  * Params listed first are compressed first (least valuable to read in the URL).
847
2122
  * The filter aggregate step uses the special key `_filters_aggregate`.
848
2123
  */
849
- const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_aggregation', '_rowGrouping', '_quickFilterValues', '_pivot'];
2124
+ const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_quickFilterValues'];
850
2125
 
851
2126
  /** Params that are always short and should never be compressed. */
852
2127
  const NEVER_COMPRESS = new Set(['_sortColumn', '_pagination', '_density', '_logicOperator', 'v', 'tab']);
@@ -1087,13 +2362,6 @@ const convertToDisplayFormat = search => {
1087
2362
  const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
1088
2363
  const params = cleanSearch.split('&');
1089
2364
  const converted = params.map(param => {
1090
- const eqIndex = param.indexOf('=');
1091
- if (eqIndex !== -1) {
1092
- const value = param.slice(eqIndex + 1);
1093
- // Skip conversion for compressed values — already URL-safe
1094
- if (isCompressed(value)) return param;
1095
- }
1096
-
1097
2365
  // Handle _sortColumn=[field,direction]
1098
2366
  if (param.startsWith('_sortColumn=')) {
1099
2367
  const value = param.slice('_sortColumn='.length);
@@ -1134,7 +2402,8 @@ const convertToDisplayFormat = search => {
1134
2402
  return param;
1135
2403
  }
1136
2404
 
1137
- // Handle _columnVisibility=[a,b,c]
2405
+ // Handle _columnVisibility=[a,b,!c] → a,b,!c (single comma list; hidden fields
2406
+ // are `!`-prefixed. Only the brackets are structural; `!` and `,` are content.)
1138
2407
  if (param.startsWith('_columnVisibility=')) {
1139
2408
  const value = param.slice('_columnVisibility='.length);
1140
2409
  if (value.startsWith('[') && value.endsWith(']')) {
@@ -1147,6 +2416,7 @@ const convertToDisplayFormat = search => {
1147
2416
  // Handle _columnOrder=[a,b,c]
1148
2417
  if (param.startsWith('_columnOrder=')) {
1149
2418
  const value = param.slice('_columnOrder='.length);
2419
+ if (value.startsWith('~')) return param; // compressed — skip
1150
2420
  if (value.startsWith('[') && value.endsWith(']')) {
1151
2421
  const inner = value.slice(1, -1);
1152
2422
  return `_columnOrder=${inner}`;
@@ -1154,21 +2424,6 @@ const convertToDisplayFormat = search => {
1154
2424
  return param;
1155
2425
  }
1156
2426
 
1157
- // Handle _rowGrouping=[a,b,c]
1158
- if (param.startsWith('_rowGrouping=')) {
1159
- const value = param.slice('_rowGrouping='.length);
1160
- if (value.startsWith('[') && value.endsWith(']')) {
1161
- const inner = value.slice(1, -1);
1162
- return `_rowGrouping=${inner}`;
1163
- }
1164
- return param;
1165
- }
1166
-
1167
- // _aggregation and _pivot do not use bracket notation — pass through
1168
- if (param.startsWith('_aggregation=') || param.startsWith('_pivot=')) {
1169
- return param;
1170
- }
1171
-
1172
2427
  // Handle _field[operator,type]=value or _field[operator,type]=list[a,b,c]
1173
2428
  const bracketMatch = param.match(/^_([^[]+)\[([^\]]+)\]=(.*)$/);
1174
2429
  if (bracketMatch) {
@@ -1208,13 +2463,6 @@ const convertFromDisplayFormat = (search, columns) => {
1208
2463
  const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
1209
2464
  const params = cleanSearch.split('&');
1210
2465
  const converted = params.map(param => {
1211
- const eqIndex = param.indexOf('=');
1212
- if (eqIndex !== -1) {
1213
- const value = param.slice(eqIndex + 1);
1214
- // Skip conversion for compressed values — already URL-safe
1215
- if (isCompressed(value)) return param;
1216
- }
1217
-
1218
2466
  // Handle _sortColumn=field.direction or _sortColumn=
1219
2467
  if (param.startsWith('_sortColumn=')) {
1220
2468
  const value = param.slice('_sortColumn='.length);
@@ -1263,11 +2511,11 @@ const convertFromDisplayFormat = (search, columns) => {
1263
2511
  return `${key}=[${value}]`;
1264
2512
  }
1265
2513
 
1266
- // Handle _columnVisibility=a,b,c
2514
+ // Handle _columnVisibility display `a,b,!c` → internal `[a,b,!c]`.
1267
2515
  if (param.startsWith('_columnVisibility=')) {
1268
2516
  const value = param.slice('_columnVisibility='.length);
1269
2517
  // If it already has brackets, leave it alone
1270
- if (value.startsWith('[')) {
2518
+ if (value.startsWith('[') || value.startsWith('~')) {
1271
2519
  return param;
1272
2520
  }
1273
2521
  return `_columnVisibility=[${value}]`;
@@ -1276,26 +2524,13 @@ const convertFromDisplayFormat = (search, columns) => {
1276
2524
  // Handle _columnOrder=a,b,c
1277
2525
  if (param.startsWith('_columnOrder=')) {
1278
2526
  const value = param.slice('_columnOrder='.length);
1279
- if (value.startsWith('[')) {
2527
+ // If it already has brackets or is compressed, leave it alone
2528
+ if (value.startsWith('[') || value.startsWith('~')) {
1280
2529
  return param;
1281
2530
  }
1282
2531
  return `_columnOrder=[${value}]`;
1283
2532
  }
1284
2533
 
1285
- // Handle _rowGrouping=a,b,c
1286
- if (param.startsWith('_rowGrouping=')) {
1287
- const value = param.slice('_rowGrouping='.length);
1288
- if (value.startsWith('[')) {
1289
- return param;
1290
- }
1291
- return `_rowGrouping=[${value}]`;
1292
- }
1293
-
1294
- // _aggregation, _pivot, _filters — pass through (no bracket conversion needed)
1295
- if (param.startsWith('_aggregation=') || param.startsWith('_pivot=') || param.startsWith('_filters=')) {
1296
- return param;
1297
- }
1298
-
1299
2534
  // Handle field.operator=value (dot notation for filters)
1300
2535
  const dotMatch = param.match(/^([^.]+)\.([a-zA-Z_]+)=(.*)$/);
1301
2536
  if (dotMatch) {
@@ -1338,10 +2573,9 @@ const getDecodedSearchFromUrl = (search, columns) => {
1338
2573
  const hasPaginationDotNotation = /_pagination=[^&[]+\.[^&]+/.test(searchWithoutLeadingQuestion);
1339
2574
  const hasPinnedWithoutBrackets = /(_pinnedColumnsLeft|_pinnedColumnsRight)=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1340
2575
  const hasVisibilityWithoutBrackets = /_columnVisibility=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1341
- const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
1342
- const hasRowGroupingWithoutBrackets = /_rowGrouping=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
2576
+ const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[~]*(&|$)/.test(searchWithoutLeadingQuestion);
1343
2577
  const hasBracketNotation = /\[.*\]=/.test(searchWithoutLeadingQuestion);
1344
- const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets || hasRowGroupingWithoutBrackets) && !hasBracketNotation;
2578
+ const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets) && !hasBracketNotation;
1345
2579
  if (isDisplayFormat) {
1346
2580
  return '?' + convertFromDisplayFormat(searchWithoutLeadingQuestion, columns);
1347
2581
  }
@@ -1502,7 +2736,7 @@ const getFilterModelFromString = (searchString, columns) => {
1502
2736
  let quickFilterValues = [];
1503
2737
  const searchParams = new URLSearchParams();
1504
2738
  for (const [key, value] of new URLSearchParams(searchString)) {
1505
- if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_rowGrouping', '_aggregation', '_pivot', '_density', '_filters'].includes(key)) {
2739
+ if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_density', '_filters'].includes(key)) {
1506
2740
  searchParams.set(key, value);
1507
2741
  }
1508
2742
  if (key === '_logicOperator') {
@@ -1779,13 +3013,75 @@ const getColumnVisibilityFromString = (searchString, columns) => {
1779
3013
  if (value === '' || value === null || value === '[]') {
1780
3014
  return 'invalid';
1781
3015
  }
1782
- const parsedFields = value.slice(1, value.length - 1).split(',');
1783
3016
  const fields = columns.map(column => column.field);
3017
+
3018
+ // Back-compat READ-ONLY: the short-lived `v:[<visible>];h:[<hidden>]` form written
3019
+ // by 12.5.5-muiv8-alpha.5/alpha.6 (replaced by the URL-safe `!` form below — see
3020
+ // getSearchParamsFromColumnVisibility). Still parsed so any localStorage entry
3021
+ // persisted by those alphas keeps working; never written anymore. The two sets are
3022
+ // split on the fixed `];h:[` separator, so a `[` or `]` inside a field name does
3023
+ // not break parsing.
3024
+ if (value.startsWith('v:[') && value.endsWith(']') && value.includes('];h:[')) {
3025
+ const inner = value.slice('v:['.length, -1);
3026
+ const separatorIndex = inner.indexOf('];h:[');
3027
+ const visibleRaw = inner.slice(0, separatorIndex);
3028
+ const hiddenRaw = inner.slice(separatorIndex + '];h:['.length);
3029
+ const visibleFields = visibleRaw ? visibleRaw.split(',') : [];
3030
+ const hiddenFields = hiddenRaw ? hiddenRaw.split(',') : [];
3031
+ const visibility = {};
3032
+ // Static columns default to visible; only those explicitly hidden are false.
3033
+ // (A column added after the URL was written is absent from both lists and
3034
+ // correctly defaults to visible, matching MUI's behaviour.)
3035
+ for (const field of fields) {
3036
+ visibility[field] = !hiddenFields.includes(field);
3037
+ }
3038
+ // Dynamic keys that are not part of the static `columns` prop — preserve verbatim.
3039
+ for (const field of visibleFields) {
3040
+ if (!fields.includes(field)) {
3041
+ visibility[field] = true;
3042
+ }
3043
+ }
3044
+ for (const field of hiddenFields) {
3045
+ if (!fields.includes(field)) {
3046
+ visibility[field] = false;
3047
+ }
3048
+ }
3049
+ return visibility;
3050
+ }
3051
+
3052
+ // Bracketed token list: new `[a,b,!c]` (hidden fields `!`-prefixed) or legacy
3053
+ // `[a,b,c]` (visible-only). Split on the comma delimiter only, so `[`/`]` inside a
3054
+ // dynamic field name survive.
3055
+ const inner = value.slice(1, value.length - 1);
3056
+ const tokens = inner ? inner.split(',') : [];
3057
+
3058
+ // New form iff at least one `!`-prefixed (explicitly hidden) token is present.
3059
+ if (tokens.some(token => token.startsWith('!'))) {
3060
+ const hiddenFields = tokens.filter(token => token.startsWith('!')).map(token => token.slice(1));
3061
+ const visibility = {};
3062
+ // Static columns default to visible; only those explicitly hidden are false.
3063
+ for (const field of fields) {
3064
+ visibility[field] = !hiddenFields.includes(field);
3065
+ }
3066
+ // Dynamic keys not in the static `columns` prop — insert in TOKEN ORDER (do not
3067
+ // regroup visible/hidden) so the writer re-emits a byte-identical URL and the RR
3068
+ // v5 adapter's idempotency guard stops the URL-sync loop (ODM-3033).
3069
+ for (const token of tokens) {
3070
+ const hidden = token.startsWith('!');
3071
+ const field = hidden ? token.slice(1) : token;
3072
+ if (!fields.includes(field)) {
3073
+ visibility[field] = !hidden;
3074
+ }
3075
+ }
3076
+ return visibility;
3077
+ }
3078
+
3079
+ // Legacy visible-only form: `[<visible>]` (hidden encoded implicitly by absence).
1784
3080
  const visibility = {};
1785
3081
  for (const field of fields) {
1786
3082
  visibility[field] = false;
1787
3083
  }
1788
- for (const parsedField of parsedFields) {
3084
+ for (const parsedField of tokens) {
1789
3085
  if (fields.includes(parsedField)) {
1790
3086
  visibility[parsedField] = true;
1791
3087
  }
@@ -1812,8 +3108,24 @@ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
1812
3108
  [colName]: true
1813
3109
  });
1814
3110
  }, columnVisibility);
1815
- const visibleColumns = fields.filter(column => finalColumnVisibility[column] !== false);
1816
- searchParams.set('_columnVisibility', `[${visibleColumns.join(',')}]`);
3111
+
3112
+ // Serialise a single comma list over the static columns plus any extra keys present
3113
+ // in the model (dynamically-generated fields, preserved in model order). Hidden
3114
+ // fields are prefixed `!`; visible fields are bare. This URL-safe form round-trips
3115
+ // idempotently through `URLSearchParams.toString()` percent-encoding — the earlier
3116
+ // `v:[..];h:[..]` form did NOT (its `:`/`;` were percent-encoded and mis-parsed on
3117
+ // read-back, driving an unbounded `history.replace` loop, ODM-3033). `!` (not `~`,
3118
+ // the compression sentinel — compression.ts COMPRESSED_PREFIX) is used so a leading
3119
+ // hidden field can't be mistaken for a compressed value. The hidden set is still
3120
+ // explicit, so deselected dynamic columns survive reloads.
3121
+ const allFields = [...fields];
3122
+ for (const field of Object.keys(finalColumnVisibility)) {
3123
+ if (!allFields.includes(field)) {
3124
+ allFields.push(field);
3125
+ }
3126
+ }
3127
+ const tokens = allFields.map(column => finalColumnVisibility[column] === false ? `!${column}` : column);
3128
+ searchParams.set('_columnVisibility', `[${tokens.join(',')}]`);
1817
3129
  return searchParams;
1818
3130
  };
1819
3131
 
@@ -1968,7 +3280,8 @@ const getSearchParamsFromDensity = density => {
1968
3280
  return searchParams;
1969
3281
  };
1970
3282
  const getDensityModel = (search, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion) => {
1971
- // Default density: honour initialState.density if valid, otherwise fall back to 'compact'
3283
+ // MUI v6 GridInitialStatePro does not expose density on its type, but consumers
3284
+ // can still pass it through. Honour it when provided, otherwise fall back to 'compact'.
1972
3285
  const initialDensity = initialState === null || initialState === void 0 ? void 0 : initialState.density;
1973
3286
  const defaultValue = initialDensity && VALID_DENSITIES.includes(initialDensity) ? initialDensity : 'compact';
1974
3287
 
@@ -2021,6 +3334,29 @@ const getSearchParamsFromColumnOrder = columnOrder => {
2021
3334
  }
2022
3335
  return searchParams;
2023
3336
  };
3337
+
3338
+ /**
3339
+ * Builds the `v=<version>` search param the grid uses to detect stale URLs.
3340
+ *
3341
+ * Use this when constructing a deep link or share URL outside the grid (e.g. via
3342
+ * `getSearchParamsFromFilterModel` + `buildQueryParamsString`). The grid itself
3343
+ * always includes `v` in URLs it writes via `getFinalSearch`, but external helpers
3344
+ * do not — include this when you want a stale `localStorageVersion` bump to invalidate
3345
+ * the link. Omitting `v` is also safe: a missing `v` is treated as "current version"
3346
+ * and the URL state is applied as-is.
3347
+ *
3348
+ * @example
3349
+ * const params = new URLSearchParams([
3350
+ * ...getSearchParamsFromFilterModel(filterModel),
3351
+ * ...getSearchParamsFromVersion(1),
3352
+ * ]);
3353
+ * const url = `/my-grid${buildQueryParamsString(urlSearchParamsToString(params))}`;
3354
+ */
3355
+ const getSearchParamsFromVersion = version => {
3356
+ const searchParams = new URLSearchParams();
3357
+ searchParams.set('v', String(version));
3358
+ return searchParams;
3359
+ };
2024
3360
  const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion) => {
2025
3361
  var _initialState$columns4, _initialState$columns5;
2026
3362
  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);
@@ -2051,305 +3387,29 @@ const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorag
2051
3387
  persistDefault();
2052
3388
  return defaultValue;
2053
3389
  };
2054
-
2055
- /** ROW GROUPING */
2056
-
2057
- const getRowGroupingFromString = searchString => {
2058
- if (!searchString) return 'invalid';
2059
- const searchParams = new URLSearchParams(searchString);
2060
- const value = searchParams.get('_rowGrouping');
2061
- if (value === '' || value === null || value === '[]') return 'invalid';
2062
- const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
2063
- if (!inner) return 'invalid';
2064
- return inner.split(',').filter(Boolean);
2065
- };
2066
- const getSearchParamsFromRowGrouping = rowGrouping => {
2067
- const searchParams = new URLSearchParams();
2068
- if (rowGrouping.length > 0) {
2069
- searchParams.set('_rowGrouping', `[${rowGrouping.join(',')}]`);
2070
- }
2071
- return searchParams;
2072
- };
2073
- const getRowGroupingModel = (search, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion) => {
2074
- var _initialState$rowGrou, _initialState$rowGrou2;
2075
- const defaultValue = (_initialState$rowGrou = initialState === null || initialState === void 0 ? void 0 : (_initialState$rowGrou2 = initialState.rowGrouping) === null || _initialState$rowGrou2 === void 0 ? void 0 : _initialState$rowGrou2.model) !== null && _initialState$rowGrou !== void 0 ? _initialState$rowGrou : [];
2076
- const persistDefault = () => {
2077
- const searchFromDefault = getSearchParamsFromRowGrouping(defaultValue);
2078
- const searchString = urlSearchParamsToString(searchFromDefault);
2079
- if (searchString !== localStorageRowGrouping) {
2080
- setLocalStorageRowGrouping(searchString);
2081
- }
2082
- };
2083
- if (isNewVersion) {
2084
- persistDefault();
2085
- return defaultValue;
2086
- }
2087
- const fromUrl = getRowGroupingFromString(search);
2088
- if (fromUrl !== 'invalid') {
2089
- const searchFromModel = getSearchParamsFromRowGrouping(fromUrl);
2090
- const searchString = urlSearchParamsToString(searchFromModel);
2091
- if (searchString !== localStorageRowGrouping) {
2092
- setLocalStorageRowGrouping(searchString);
2093
- }
2094
- return fromUrl;
2095
- }
2096
- const fromLocalStorage = getRowGroupingFromString(localStorageRowGrouping);
2097
- if (fromLocalStorage !== 'invalid') {
2098
- return fromLocalStorage;
2099
- }
2100
- persistDefault();
2101
- return defaultValue;
2102
- };
2103
-
2104
- /** AGGREGATION */
2105
-
2106
- const getAggregationFromString = searchString => {
2107
- if (!searchString) return 'invalid';
2108
- const searchParams = new URLSearchParams(searchString);
2109
- const value = searchParams.get('_aggregation');
2110
- if (value === '' || value === null) return 'invalid';
2111
-
2112
- // Format: field1.sum,field2.avg or [field1.sum,field2.avg]
2113
- const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
2114
- if (!inner) return 'invalid';
2115
- const model = {};
2116
- for (const entry of inner.split(',')) {
2117
- const dotIndex = entry.lastIndexOf('.');
2118
- if (dotIndex <= 0) return 'invalid';
2119
- const field = entry.slice(0, dotIndex);
2120
- const aggFunc = entry.slice(dotIndex + 1);
2121
- if (!field || !aggFunc) return 'invalid';
2122
- model[field] = aggFunc;
2123
- }
2124
- return Object.keys(model).length > 0 ? model : 'invalid';
2125
- };
2126
- const getSearchParamsFromAggregation = aggregation => {
2127
- const searchParams = new URLSearchParams();
2128
- const entries = Object.entries(aggregation);
2129
- if (entries.length > 0) {
2130
- const value = entries.map(_ref => {
2131
- let [field, aggFunc] = _ref;
2132
- return `${field}.${aggFunc}`;
2133
- }).join(',');
2134
- searchParams.set('_aggregation', value);
2135
- }
2136
- return searchParams;
2137
- };
2138
- const getAggregationModel = (search, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion) => {
2139
- var _initialState$aggrega, _initialState$aggrega2;
2140
- const defaultValue = (_initialState$aggrega = initialState === null || initialState === void 0 ? void 0 : (_initialState$aggrega2 = initialState.aggregation) === null || _initialState$aggrega2 === void 0 ? void 0 : _initialState$aggrega2.model) !== null && _initialState$aggrega !== void 0 ? _initialState$aggrega : {};
2141
- const persistDefault = () => {
2142
- const searchFromDefault = getSearchParamsFromAggregation(defaultValue);
2143
- const searchString = urlSearchParamsToString(searchFromDefault);
2144
- if (searchString !== localStorageAggregation) {
2145
- setLocalStorageAggregation(searchString);
2146
- }
2147
- };
2148
- if (isNewVersion) {
2149
- persistDefault();
2150
- return defaultValue;
2151
- }
2152
- const fromUrl = getAggregationFromString(search);
2153
- if (fromUrl !== 'invalid') {
2154
- const searchFromModel = getSearchParamsFromAggregation(fromUrl);
2155
- const searchString = urlSearchParamsToString(searchFromModel);
2156
- if (searchString !== localStorageAggregation) {
2157
- setLocalStorageAggregation(searchString);
2158
- }
2159
- return fromUrl;
2160
- }
2161
- const fromLocalStorage = getAggregationFromString(localStorageAggregation);
2162
- if (fromLocalStorage !== 'invalid') {
2163
- return fromLocalStorage;
2164
- }
2165
- persistDefault();
2166
- return defaultValue;
2167
- };
2168
-
2169
- /** PIVOT */
2170
-
2171
- /** Convert MUI's GridPivotModel → our simplified PivotModel */
2172
- const fromGridPivotModel = model => ({
2173
- columns: model.columns.map(c => c.field),
2174
- rows: model.rows.map(r => r.field),
2175
- values: model.values.map(_ref2 => {
2176
- let {
2177
- field,
2178
- aggFunc
2179
- } = _ref2;
2180
- return {
2181
- field,
2182
- aggFunc
2183
- };
2184
- })
2185
- });
2186
-
2187
- /**
2188
- * Pivot format: `cols:f1,f2;rows:f3;vals:f4.sum,f5.avg`
2189
- */
2190
- const getPivotFromString = searchString => {
2191
- if (!searchString) return 'invalid';
2192
- const searchParams = new URLSearchParams(searchString);
2193
- const value = searchParams.get('_pivot');
2194
- if (value === '' || value === null) return 'invalid';
2195
- const model = {
2196
- columns: [],
2197
- rows: [],
2198
- values: []
2199
- };
2200
- for (const segment of value.split(';')) {
2201
- const colonIndex = segment.indexOf(':');
2202
- if (colonIndex <= 0) return 'invalid';
2203
- const key = segment.slice(0, colonIndex);
2204
- const content = segment.slice(colonIndex + 1);
2205
- if (key === 'cols') {
2206
- model.columns = content ? content.split(',').filter(Boolean) : [];
2207
- } else if (key === 'rows') {
2208
- model.rows = content ? content.split(',').filter(Boolean) : [];
2209
- } else if (key === 'vals') {
2210
- if (!content) continue;
2211
- for (const entry of content.split(',')) {
2212
- const dotIndex = entry.lastIndexOf('.');
2213
- if (dotIndex <= 0) return 'invalid';
2214
- model.values.push({
2215
- field: entry.slice(0, dotIndex),
2216
- aggFunc: entry.slice(dotIndex + 1)
2217
- });
2218
- }
2219
- }
2220
- }
2221
-
2222
- // At least one section must have content
2223
- if (model.columns.length === 0 && model.rows.length === 0 && model.values.length === 0) {
2224
- return 'invalid';
2225
- }
2226
- return model;
2227
- };
2228
- const getSearchParamsFromPivot = pivot => {
2229
- const searchParams = new URLSearchParams();
2230
- const hasContent = pivot.columns.length > 0 || pivot.rows.length > 0 || pivot.values.length > 0;
2231
- if (hasContent) {
2232
- const parts = [];
2233
- parts.push(`cols:${pivot.columns.join(',')}`);
2234
- parts.push(`rows:${pivot.rows.join(',')}`);
2235
- if (pivot.values.length > 0) {
2236
- parts.push(`vals:${pivot.values.map(v => `${v.field}.${v.aggFunc}`).join(',')}`);
2237
- }
2238
- searchParams.set('_pivot', parts.join(';'));
2239
- }
2240
- return searchParams;
2241
- };
2242
- const getPivotModel = (search, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion) => {
2243
- var _initialState$pivotin;
2244
- const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$pivotin = initialState.pivoting) !== null && _initialState$pivotin !== void 0 && _initialState$pivotin.model ? fromGridPivotModel(initialState.pivoting.model) : {
2245
- columns: [],
2246
- rows: [],
2247
- values: []
2248
- };
2249
- const persistDefault = () => {
2250
- const searchFromDefault = getSearchParamsFromPivot(defaultValue);
2251
- const searchString = urlSearchParamsToString(searchFromDefault);
2252
- if (searchString !== localStoragePivot) {
2253
- setLocalStoragePivot(searchString);
2254
- }
2255
- };
2256
- if (isNewVersion) {
2257
- persistDefault();
2258
- return defaultValue;
2259
- }
2260
- const fromUrl = getPivotFromString(search);
2261
- if (fromUrl !== 'invalid') {
2262
- const searchFromModel = getSearchParamsFromPivot(fromUrl);
2263
- const searchString = urlSearchParamsToString(searchFromModel);
2264
- if (searchString !== localStoragePivot) {
2265
- setLocalStoragePivot(searchString);
2266
- }
2267
- return fromUrl;
2268
- }
2269
- const fromLocalStorage = getPivotFromString(localStoragePivot);
2270
- if (fromLocalStorage !== 'invalid') {
2271
- return fromLocalStorage;
2272
- }
2273
- persistDefault();
2274
- return defaultValue;
2275
- };
2276
-
2277
- /** PIVOT ACTIVE */
2278
-
2279
- const getPivotActiveFromString = searchString => {
2280
- if (!searchString) return 'invalid';
2281
- const searchParams = new URLSearchParams(searchString);
2282
- const value = searchParams.get('_pivotActive');
2283
- if (value === 'true') return true;
2284
- if (value === 'false') return false;
2285
- return 'invalid';
2286
- };
2287
- const getSearchParamsFromPivotActive = active => {
2288
- const searchParams = new URLSearchParams();
2289
- searchParams.set('_pivotActive', String(active));
2290
- return searchParams;
2291
- };
2292
- const getPivotActive = (search, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion) => {
2293
- var _initialState$pivotin2, _initialState$pivotin3;
2294
- const defaultValue = (_initialState$pivotin2 = initialState === null || initialState === void 0 ? void 0 : (_initialState$pivotin3 = initialState.pivoting) === null || _initialState$pivotin3 === void 0 ? void 0 : _initialState$pivotin3.enabled) !== null && _initialState$pivotin2 !== void 0 ? _initialState$pivotin2 : false;
2295
- const persistDefault = () => {
2296
- const searchFromDefault = getSearchParamsFromPivotActive(defaultValue);
2297
- const searchString = urlSearchParamsToString(searchFromDefault);
2298
- if (searchString !== localStoragePivotActive) {
2299
- setLocalStoragePivotActive(searchString);
2300
- }
2301
- };
2302
- if (isNewVersion) {
2303
- persistDefault();
2304
- return defaultValue;
2305
- }
2306
- const fromUrl = getPivotActiveFromString(search);
2307
- if (fromUrl !== 'invalid') {
2308
- const searchFromModel = getSearchParamsFromPivotActive(fromUrl);
2309
- const searchString = urlSearchParamsToString(searchFromModel);
2310
- if (searchString !== localStoragePivotActive) {
2311
- setLocalStoragePivotActive(searchString);
2312
- }
2313
- return fromUrl;
2314
- }
2315
- const fromLocalStorage = getPivotActiveFromString(localStoragePivotActive);
2316
- if (fromLocalStorage !== 'invalid') {
2317
- return fromLocalStorage;
2318
- }
2319
- persistDefault();
2320
- return defaultValue;
2321
- };
2322
- const getFinalSearch = _ref3 => {
2323
- let {
2324
- search,
2325
- localStorageVersion,
2326
- filterModel,
2327
- sortModel,
2328
- paginationModel,
2329
- columnsVisibilityModel,
2330
- pinnedColumnsModel,
2331
- density,
2332
- columnOrderModel,
2333
- defaultColumnOrder,
2334
- rowGroupingModel,
2335
- aggregationModel,
2336
- pivotModel,
2337
- pivotActive,
2338
- columns
2339
- } = _ref3;
2340
- const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
2341
- const sortModelSearch = getSearchParamsFromSorting(sortModel);
2342
- const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
2343
- const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
2344
- const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
2345
- const densitySearch = getSearchParamsFromDensity(density);
2346
- // Only include _columnOrder in URL when it differs from the default
2347
- const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
2348
- const rowGroupingSearch = getSearchParamsFromRowGrouping(rowGroupingModel);
2349
- const aggregationSearch = getSearchParamsFromAggregation(aggregationModel);
2350
- const pivotSearch = getSearchParamsFromPivot(pivotModel);
2351
- const pivotActiveSearch = getSearchParamsFromPivotActive(pivotActive);
2352
- const tabSearch = getSearchParamsFromTab(search);
3390
+ const getFinalSearch = _ref => {
3391
+ let {
3392
+ search,
3393
+ localStorageVersion,
3394
+ filterModel,
3395
+ sortModel,
3396
+ paginationModel,
3397
+ columnsVisibilityModel,
3398
+ pinnedColumnsModel,
3399
+ density,
3400
+ columnOrderModel,
3401
+ defaultColumnOrder,
3402
+ columns
3403
+ } = _ref;
3404
+ const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
3405
+ const sortModelSearch = getSearchParamsFromSorting(sortModel);
3406
+ const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
3407
+ const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
3408
+ const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
3409
+ const densitySearch = getSearchParamsFromDensity(density);
3410
+ // Only include _columnOrder in URL when it differs from the default
3411
+ const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
3412
+ const tabSearch = getSearchParamsFromTab(search);
2353
3413
  const searchParams = new URLSearchParams();
2354
3414
  for (const [key, value] of new URLSearchParams(search)) {
2355
3415
  if (!key.startsWith('_')) {
@@ -2363,7 +3423,7 @@ const getFinalSearch = _ref3 => {
2363
3423
  // Encode array as JSON string to preserve all values in one param
2364
3424
  searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
2365
3425
  }
2366
- return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch, ...rowGroupingSearch, ...aggregationSearch, ...pivotSearch, ...pivotActiveSearch]);
3426
+ return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch]);
2367
3427
  };
2368
3428
  /** Return the state of the table given the URL and the local storage state */
2369
3429
  const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage) => {
@@ -2374,11 +3434,21 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2374
3434
  const decodedSearch = getDecodedSearchFromUrl(decompressedSearch, columns);
2375
3435
  const decodedParams = new URLSearchParams(decodedSearch);
2376
3436
  const currentVersion = decodedParams.get('v');
2377
- // Only treat as "new version reset" when the URL has params with a stale/missing version.
2378
- // An empty URL should fall through to the localStorage branch of each getter so persisted
2379
- // state is restored instead of being clobbered by defaults.
3437
+ // Only treat as "new version reset" when the URL carries params AND explicitly declares a
3438
+ // stale version (`v=` present but not matching `localStorageVersion`).
3439
+ //
3440
+ // Two cases that must NOT trigger a reset:
3441
+ // 1. Empty URL — fall through to the localStorage branch of each getter so persisted
3442
+ // preferences are restored instead of being clobbered by defaults.
3443
+ // 2. URL has params but no `v` — externally-constructed deep links / share links built
3444
+ // with `getSearchParamsFromFilterModel`, `buildQueryParamsString`, etc. do not include
3445
+ // `v` by default. Treating a missing `v` as "stale" silently discards the very state
3446
+ // the integrator just encoded into the URL (and wipes localStorage on the way out).
3447
+ // A missing `v` is interpreted as "current" so external URLs work out of the box.
3448
+ // URLs written by the grid itself (`getFinalSearch`) always include `v`, so a stale
3449
+ // bookmark from a previous `localStorageVersion` still resets correctly.
2380
3450
  const hasUrlState = Array.from(decodedParams.keys()).length > 0;
2381
- const isNewVersion = hasUrlState && (!currentVersion || Number(currentVersion) !== localStorageVersion);
3451
+ const isNewVersion = hasUrlState && currentVersion != null && Number(currentVersion) !== localStorageVersion;
2382
3452
  const {
2383
3453
  localStorageFilters,
2384
3454
  setLocalStorageFilters,
@@ -2393,15 +3463,7 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2393
3463
  localStorageDensity,
2394
3464
  setLocalStorageDensity,
2395
3465
  localStorageColumnOrder,
2396
- setLocalStorageColumnOrder,
2397
- localStorageRowGrouping,
2398
- setLocalStorageRowGrouping,
2399
- localStorageAggregation,
2400
- setLocalStorageAggregation,
2401
- localStoragePivot,
2402
- setLocalStoragePivot,
2403
- localStoragePivotActive,
2404
- setLocalStoragePivotActive
3466
+ setLocalStorageColumnOrder
2405
3467
  } = localStorage;
2406
3468
  const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
2407
3469
  const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
@@ -2410,10 +3472,6 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2410
3472
  const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
2411
3473
  const density = getDensityModel(decodedSearch, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion);
2412
3474
  const columnOrderModel = getColumnOrder(decodedSearch, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion);
2413
- const rowGroupingModel = getRowGroupingModel(decodedSearch, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion);
2414
- const aggregationModel = getAggregationModel(decodedSearch, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion);
2415
- const pivotModel = getPivotModel(decodedSearch, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion);
2416
- const pivotActive = getPivotActive(decodedSearch, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion);
2417
3475
  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);
2418
3476
  const finalSearch = getFinalSearch({
2419
3477
  localStorageVersion,
@@ -2426,10 +3484,6 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2426
3484
  density,
2427
3485
  columnOrderModel,
2428
3486
  defaultColumnOrder,
2429
- rowGroupingModel,
2430
- aggregationModel,
2431
- pivotModel,
2432
- pivotActive,
2433
3487
  columns
2434
3488
  });
2435
3489
  const internalSearchString = urlSearchParamsToString(finalSearch);
@@ -2450,14 +3504,10 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2450
3504
  pinnedColumnsModel,
2451
3505
  density,
2452
3506
  columnOrderModel,
2453
- rowGroupingModel,
2454
- aggregationModel,
2455
- pivotModel,
2456
- pivotActive,
2457
3507
  pendingSearch
2458
3508
  };
2459
3509
  };
2460
- const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
3510
+ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns) => {
2461
3511
  let {
2462
3512
  filterModel,
2463
3513
  sortModel,
@@ -2466,12 +3516,8 @@ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns)
2466
3516
  pinnedColumnsModel,
2467
3517
  density,
2468
3518
  columnOrderModel,
2469
- defaultColumnOrder,
2470
- rowGroupingModel,
2471
- aggregationModel,
2472
- pivotModel,
2473
- pivotActive
2474
- } = _ref4;
3519
+ defaultColumnOrder
3520
+ } = _ref2;
2475
3521
  // Convert from display format to internal format if needed
2476
3522
  const decodedSearch = getDecodedSearchFromUrl(search, columns);
2477
3523
  const newSearch = getFinalSearch({
@@ -2485,10 +3531,6 @@ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns)
2485
3531
  density,
2486
3532
  columnOrderModel,
2487
3533
  defaultColumnOrder,
2488
- rowGroupingModel,
2489
- aggregationModel,
2490
- pivotModel,
2491
- pivotActive,
2492
3534
  columns
2493
3535
  });
2494
3536
  const internalSearchString = urlSearchParamsToString(newSearch);
@@ -2676,26 +3718,6 @@ const useTableStates = (id, version) => {
2676
3718
  version,
2677
3719
  category: COLUMN_ORDER_MODEL_KEY
2678
3720
  }));
2679
- const [rowGroupingModel, setRowGroupingModel] = useFetchState('', buildStorageKey({
2680
- id,
2681
- version,
2682
- category: ROW_GROUPING_MODEL_KEY
2683
- }));
2684
- const [aggregationModel, setAggregationModel] = useFetchState('', buildStorageKey({
2685
- id,
2686
- version,
2687
- category: AGGREGATION_MODEL_KEY
2688
- }));
2689
- const [pivotModel, setPivotModel] = useFetchState('', buildStorageKey({
2690
- id,
2691
- version,
2692
- category: PIVOT_MODEL_KEY
2693
- }));
2694
- const [pivotActive, setPivotActive] = useFetchState('', buildStorageKey({
2695
- id,
2696
- version,
2697
- category: PIVOT_ACTIVE_KEY
2698
- }));
2699
3721
  return {
2700
3722
  paginationModel,
2701
3723
  setPaginationModel,
@@ -2712,55 +3734,10 @@ const useTableStates = (id, version) => {
2712
3734
  densityModel,
2713
3735
  setDensityModel,
2714
3736
  columnOrderModel,
2715
- setColumnOrderModel,
2716
- rowGroupingModel,
2717
- setRowGroupingModel,
2718
- aggregationModel,
2719
- setAggregationModel,
2720
- pivotModel,
2721
- setPivotModel,
2722
- pivotActive,
2723
- setPivotActive
3737
+ setColumnOrderModel
2724
3738
  };
2725
3739
  };
2726
3740
 
2727
- /** Convert our simplified PivotModel → MUI's GridPivotModel */
2728
- const toGridPivotModel = model => ({
2729
- columns: model.columns.map(field => ({
2730
- field
2731
- })),
2732
- rows: model.rows.map(field => ({
2733
- field
2734
- })),
2735
- values: model.values.map(_ref => {
2736
- let {
2737
- field,
2738
- aggFunc
2739
- } = _ref;
2740
- return {
2741
- field,
2742
- aggFunc
2743
- };
2744
- })
2745
- });
2746
-
2747
- /**
2748
- * Deep-equal comparison for plain objects / arrays.
2749
- * Used to stabilise parsed model references so that MUI v8 does not
2750
- * reset pagination on every render.
2751
- */
2752
- function isDeepEqual(a, b) {
2753
- if (a === b) return true;
2754
- if (a == null || b == null) return false;
2755
- if (typeof a !== typeof b) return false;
2756
- if (typeof a !== 'object') return false;
2757
- const aObj = a;
2758
- const bObj = b;
2759
- const aKeys = Object.keys(aObj);
2760
- const bKeys = Object.keys(bObj);
2761
- if (aKeys.length !== bKeys.length) return false;
2762
- return aKeys.every(key => isDeepEqual(aObj[key], bObj[key]));
2763
- }
2764
3741
  const useStatefulTable = props => {
2765
3742
  var _initialState$columns, _initialState$columns2;
2766
3743
  const {
@@ -2773,9 +3750,6 @@ const useStatefulTable = props => {
2773
3750
  onPaginationModelChange: propsOnPaginationModelChange,
2774
3751
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
2775
3752
  onSortModelChange: propsOnSortModelChange,
2776
- onRowGroupingModelChange: propsOnRowGroupingModelChange,
2777
- onAggregationModelChange: propsOnAggregationModelChange,
2778
- onPivotModelChange: propsOnPivotModelChange,
2779
3753
  useRouter,
2780
3754
  localStorageVersion = 1,
2781
3755
  previousLocalStorageVersions = []
@@ -2804,24 +3778,16 @@ const useStatefulTable = props => {
2804
3778
  densityModel,
2805
3779
  setDensityModel,
2806
3780
  columnOrderModel: localStorageColumnOrder,
2807
- setColumnOrderModel: setLocalStorageColumnOrder,
2808
- rowGroupingModel: localStorageRowGrouping,
2809
- setRowGroupingModel: setLocalStorageRowGrouping,
2810
- aggregationModel: localStorageAggregation,
2811
- setAggregationModel: setLocalStorageAggregation,
2812
- pivotModel: localStoragePivot,
2813
- setPivotModel: setLocalStoragePivot,
2814
- pivotActive: localStoragePivotActive,
2815
- setPivotActive: setLocalStoragePivotActive
3781
+ setColumnOrderModel: setLocalStorageColumnOrder
2816
3782
  } = useTableStates(id, localStorageVersion);
2817
3783
 
2818
3784
  // clearing up old version keys, triggering only on first render
2819
3785
  useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
2820
- const onColumnDimensionChange = useCallback(_ref2 => {
3786
+ const onColumnDimensionChange = useCallback(_ref => {
2821
3787
  let {
2822
3788
  newWidth,
2823
3789
  field
2824
- } = _ref2;
3790
+ } = _ref;
2825
3791
  setDimensionModel(_objectSpread2(_objectSpread2({}, dimensionModel), {}, {
2826
3792
  [field]: newWidth
2827
3793
  }));
@@ -2834,10 +3800,6 @@ const useStatefulTable = props => {
2834
3800
  pinnedColumnsModel,
2835
3801
  density: densityParsed,
2836
3802
  columnOrderModel: columnOrderParsed,
2837
- rowGroupingModel: rowGroupingParsed,
2838
- aggregationModel: aggregationParsed,
2839
- pivotModel: pivotParsed,
2840
- pivotActive: pivotActiveParsed,
2841
3803
  pendingSearch
2842
3804
  } = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, initialState, {
2843
3805
  localStorageFilters,
@@ -2853,15 +3815,7 @@ const useStatefulTable = props => {
2853
3815
  localStorageDensity: densityModel,
2854
3816
  setLocalStorageDensity: setDensityModel,
2855
3817
  localStorageColumnOrder,
2856
- setLocalStorageColumnOrder,
2857
- localStorageRowGrouping,
2858
- setLocalStorageRowGrouping,
2859
- localStorageAggregation,
2860
- setLocalStorageAggregation,
2861
- localStoragePivot,
2862
- setLocalStoragePivot,
2863
- localStoragePivotActive: localStoragePivotActive,
2864
- setLocalStoragePivotActive: setLocalStoragePivotActive
3818
+ setLocalStorageColumnOrder
2865
3819
  });
2866
3820
 
2867
3821
  // Sync URL in an effect rather than during render to comply with React rules
@@ -2870,45 +3824,6 @@ const useStatefulTable = props => {
2870
3824
  historyReplace(pendingSearch);
2871
3825
  }
2872
3826
  }, [pendingSearch, historyReplace]);
2873
-
2874
- // Stabilise parsed model references to prevent MUI v8 from resetting
2875
- // pagination on every render due to new object identity.
2876
- const filterParsedRef = useRef(filterParsed);
2877
- if (!isDeepEqual(filterParsedRef.current, filterParsed)) {
2878
- filterParsedRef.current = filterParsed;
2879
- }
2880
- const sortModelParsedRef = useRef(sortModelParsed);
2881
- if (!isDeepEqual(sortModelParsedRef.current, sortModelParsed)) {
2882
- sortModelParsedRef.current = sortModelParsed;
2883
- }
2884
- const paginationModelParsedRef = useRef(paginationModelParsed);
2885
- if (!isDeepEqual(paginationModelParsedRef.current, paginationModelParsed)) {
2886
- paginationModelParsedRef.current = paginationModelParsed;
2887
- }
2888
- const visibilityModelRef = useRef(visibilityModel);
2889
- if (!isDeepEqual(visibilityModelRef.current, visibilityModel)) {
2890
- visibilityModelRef.current = visibilityModel;
2891
- }
2892
- const pinnedColumnsModelRef = useRef(pinnedColumnsModel);
2893
- if (!isDeepEqual(pinnedColumnsModelRef.current, pinnedColumnsModel)) {
2894
- pinnedColumnsModelRef.current = pinnedColumnsModel;
2895
- }
2896
- const columnOrderParsedRef = useRef(columnOrderParsed);
2897
- if (!isDeepEqual(columnOrderParsedRef.current, columnOrderParsed)) {
2898
- columnOrderParsedRef.current = columnOrderParsed;
2899
- }
2900
- const rowGroupingParsedRef = useRef(rowGroupingParsed);
2901
- if (!isDeepEqual(rowGroupingParsedRef.current, rowGroupingParsed)) {
2902
- rowGroupingParsedRef.current = rowGroupingParsed;
2903
- }
2904
- const aggregationParsedRef = useRef(aggregationParsed);
2905
- if (!isDeepEqual(aggregationParsedRef.current, aggregationParsed)) {
2906
- aggregationParsedRef.current = aggregationParsed;
2907
- }
2908
- const pivotParsedRef = useRef(pivotParsed);
2909
- if (!isDeepEqual(pivotParsedRef.current, pivotParsed)) {
2910
- pivotParsedRef.current = pivotParsed;
2911
- }
2912
3827
  const columns = useMemo(() => propsColumns.map(column => {
2913
3828
  return _objectSpread2(_objectSpread2({}, column), {}, {
2914
3829
  width: dimensionModel[column.field] || column.width || 100
@@ -2917,61 +3832,56 @@ const useStatefulTable = props => {
2917
3832
  if (apiRef.current) {
2918
3833
  /** Add resetPage method to apiRef. */
2919
3834
  apiRef.current.resetPage = () => {
2920
- var _apiRef$current;
2921
- (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPage(0);
3835
+ apiRef.current.setPage(0);
2922
3836
  };
2923
3837
  }
2924
3838
  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);
2925
3839
 
3840
+ // Helper to build the current DataGridModel for updateUrl calls
3841
+ const buildModel = function () {
3842
+ var _apiRef$current$state, _apiRef$current;
3843
+ let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3844
+ return _objectSpread2({
3845
+ filterModel: filterParsed,
3846
+ sortModel: sortModelParsed,
3847
+ paginationModel: paginationModelParsed,
3848
+ 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 : {},
3849
+ pinnedColumnsModel: pinnedColumnsModel,
3850
+ density: densityParsed,
3851
+ columnOrderModel: columnOrderParsed,
3852
+ defaultColumnOrder
3853
+ }, overrides);
3854
+ };
3855
+
2926
3856
  // Subscribe to density changes via stateChange event (MUI v6 has no densityChange event)
2927
3857
  useEffect(() => {
2928
3858
  const api = apiRef.current;
2929
3859
  if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
2930
3860
  let prevDensity = densityParsed;
2931
3861
  const unsub = api.subscribeEvent('stateChange', () => {
2932
- const currentDensity = api.state.density;
3862
+ const currentDensity = api.state.density.value;
2933
3863
  if (currentDensity !== prevDensity) {
2934
3864
  prevDensity = currentDensity;
2935
- updateUrl({
2936
- filterModel: filterParsed,
2937
- sortModel: sortModelParsed,
2938
- paginationModel: paginationModelParsed,
3865
+ updateUrl(buildModel({
2939
3866
  columnsModel: api.state.columns.columnVisibilityModel,
2940
- pinnedColumnsModel: pinnedColumnsModel,
2941
- density: currentDensity,
2942
- columnOrderModel: columnOrderParsed,
2943
- defaultColumnOrder,
2944
- rowGroupingModel: rowGroupingParsed,
2945
- aggregationModel: aggregationParsed,
2946
- pivotModel: pivotParsed,
2947
- pivotActive: pivotActiveParsed
2948
- }, search, localStorageVersion, historyReplace, columns);
3867
+ density: currentDensity
3868
+ }), search, localStorageVersion, historyReplace, columns);
2949
3869
  }
2950
3870
  });
2951
3871
  return unsub;
2952
- }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
3872
+ }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, search, localStorageVersion, historyReplace, columns]);
2953
3873
 
2954
3874
  // Subscribe to column order changes via columnOrderChange (drag-drop) and columnIndexChange (programmatic setColumnIndex)
2955
3875
  useEffect(() => {
2956
3876
  const api = apiRef.current;
2957
3877
  if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
3878
+ const isDeepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
2958
3879
  const handleColumnOrderChange = () => {
2959
3880
  const orderedFields = api.state.columns.orderedFields;
2960
3881
  if (orderedFields && !isDeepEqual(orderedFields, columnOrderParsed)) {
2961
- updateUrl({
2962
- filterModel: filterParsed,
2963
- sortModel: sortModelParsed,
2964
- paginationModel: paginationModelParsed,
2965
- columnsModel: api.state.columns.columnVisibilityModel,
2966
- pinnedColumnsModel,
2967
- density: densityParsed,
2968
- columnOrderModel: orderedFields,
2969
- defaultColumnOrder,
2970
- rowGroupingModel: rowGroupingParsed,
2971
- aggregationModel: aggregationParsed,
2972
- pivotModel: pivotParsed,
2973
- pivotActive: pivotActiveParsed
2974
- }, search, localStorageVersion, historyReplace, columns);
3882
+ updateUrl(buildModel({
3883
+ columnOrderModel: orderedFields
3884
+ }), search, localStorageVersion, historyReplace, columns);
2975
3885
  }
2976
3886
  };
2977
3887
  const unsub1 = api.subscribeEvent('columnOrderChange', handleColumnOrderChange);
@@ -2980,120 +3890,69 @@ const useStatefulTable = props => {
2980
3890
  unsub1();
2981
3891
  unsub2();
2982
3892
  };
2983
- }, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
2984
-
2985
- // Helper to build the current DataGridModel for updateUrl calls
2986
- const buildModel = function () {
2987
- var _apiRef$current$state, _apiRef$current2;
2988
- let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2989
- return _objectSpread2({
2990
- filterModel: filterParsed,
2991
- sortModel: sortModelParsed,
2992
- paginationModel: paginationModelParsed,
2993
- 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 : {},
2994
- pinnedColumnsModel: pinnedColumnsModel,
2995
- density: densityParsed,
2996
- columnOrderModel: columnOrderParsed,
2997
- defaultColumnOrder,
2998
- rowGroupingModel: rowGroupingParsed,
2999
- aggregationModel: aggregationParsed,
3000
- pivotModel: pivotParsed,
3001
- pivotActive: pivotActiveParsed
3002
- }, overrides);
3003
- };
3004
-
3005
- // Stable GridPivotModel identity — only recompute when the simplified value changes.
3006
- // eslint-disable-next-line react-hooks/exhaustive-deps
3007
- const pivotModelMui = useMemo(() => toGridPivotModel(pivotParsed), [JSON.stringify(pivotParsed)]);
3893
+ }, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, search, localStorageVersion, historyReplace, columns]);
3008
3894
 
3009
3895
  // Track last emitted values for deep-equal guards to avoid feedback loops.
3010
- // Initialised from the current parsed values; updated only when we actually fire.
3011
3896
  const lastEmittedFilterRef = useRef(filterParsed);
3012
3897
  const lastEmittedSortRef = useRef(sortModelParsed);
3013
3898
  const lastEmittedPaginationRef = useRef(paginationModelParsed);
3014
- const lastEmittedPivotRef = useRef(pivotParsed);
3899
+ const isModelDeepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
3015
3900
  return {
3016
3901
  apiRef,
3017
3902
  columns,
3018
3903
  density: densityParsed,
3019
- columnOrderModel: columnOrderParsedRef.current,
3020
- rowGroupingModel: rowGroupingParsedRef.current,
3021
- aggregationModel: aggregationParsedRef.current,
3022
- pivotModel: pivotModelMui,
3023
- pivotActive: pivotActiveParsed,
3904
+ columnOrderModel: columnOrderParsed,
3024
3905
  onFilterModelChange: (model, details) => {
3025
3906
  const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
3026
3907
  items: model.items.map(item => {
3027
- var _apiRef$current3;
3028
- const column = (_apiRef$current3 = apiRef.current) === null || _apiRef$current3 === void 0 ? void 0 : _apiRef$current3.getColumn(item.field);
3029
- item.type = (column === null || column === void 0 ? void 0 : column.type) || 'string';
3908
+ const column = apiRef.current.getColumn(item.field);
3909
+ item.type = column.type || 'string';
3030
3910
  return item;
3031
3911
  }),
3032
3912
  quickFilterValues: model.quickFilterValues || []
3033
3913
  });
3034
- if (isDeepEqual(filterModel, lastEmittedFilterRef.current)) return;
3914
+ if (isModelDeepEqual(filterModel, lastEmittedFilterRef.current)) return;
3035
3915
  lastEmittedFilterRef.current = filterModel;
3916
+ propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
3036
3917
  updateUrl(buildModel({
3037
3918
  filterModel
3038
3919
  }), search, localStorageVersion, historyReplace, columns);
3039
- propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
3040
3920
  },
3041
- filterModel: filterParsedRef.current,
3921
+ filterModel: filterParsed,
3042
3922
  onSortModelChange: (model, details) => {
3043
- if (isDeepEqual(model, lastEmittedSortRef.current)) return;
3923
+ if (isModelDeepEqual(model, lastEmittedSortRef.current)) return;
3044
3924
  lastEmittedSortRef.current = model;
3925
+ propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
3045
3926
  updateUrl(buildModel({
3046
3927
  sortModel: model
3047
3928
  }), search, localStorageVersion, historyReplace, columns);
3048
- propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
3049
3929
  },
3050
- sortModel: sortModelParsedRef.current,
3930
+ sortModel: sortModelParsed,
3051
3931
  onPinnedColumnsChange: (pinnedColumns, details) => {
3052
- var _apiRef$current$state2, _apiRef$current4, _apiRef$current4$stat, _apiRef$current4$stat2;
3053
- // While pivot mode is active, MUI Premium emits synthetic pinned-column
3054
- // models (e.g. `__row_group_by_columns_group__` for the grouping column)
3055
- // that must not be persisted to the URL / localStorage. Read the live
3056
- // grid state from apiRef rather than the parsed URL value because the
3057
- // URL lags by a tick during pivot enable/disable transitions. Consumer
3058
- // callbacks are always forwarded so observers can still react.
3059
- 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;
3060
- if (!pivotActiveLive) {
3061
- updateUrl(buildModel({
3062
- pinnedColumnsModel: pinnedColumns
3063
- }), search, localStorageVersion, historyReplace, columns);
3064
- }
3065
3932
  propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
3933
+ updateUrl(buildModel({
3934
+ pinnedColumnsModel: pinnedColumns
3935
+ }), search, localStorageVersion, historyReplace, columns);
3066
3936
  },
3067
- pinnedColumns: pinnedColumnsModelRef.current,
3068
- paginationModel: paginationModelParsedRef.current,
3937
+ pinnedColumns: pinnedColumnsModel,
3938
+ paginationModel: paginationModelParsed,
3069
3939
  onPaginationModelChange: (model, details) => {
3070
3940
  const paginationModel = _objectSpread2(_objectSpread2({}, model), {}, {
3071
3941
  direction: paginationModelParsed.page < model.page ? 'next' : 'back'
3072
3942
  });
3073
- if (isDeepEqual(paginationModel, lastEmittedPaginationRef.current)) return;
3943
+ if (isModelDeepEqual(paginationModel, lastEmittedPaginationRef.current)) return;
3074
3944
  lastEmittedPaginationRef.current = paginationModel;
3945
+ propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
3075
3946
  updateUrl(buildModel({
3076
3947
  paginationModel
3077
3948
  }), search, localStorageVersion, historyReplace, columns);
3078
- propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
3079
3949
  },
3080
- columnVisibilityModel: visibilityModelRef.current,
3950
+ columnVisibilityModel: visibilityModel,
3081
3951
  onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
3082
- var _apiRef$current$state3, _apiRef$current5, _apiRef$current5$stat, _apiRef$current5$stat2;
3083
- // While pivot mode is active, MUI Premium emits synthetic visibility
3084
- // models that whitelist only the pivot value fields (hiding every base
3085
- // column). Persisting that to the URL would re-hide all base columns
3086
- // on the next load (see getColumnVisibilityFromString whitelist logic).
3087
- // Read the live grid state rather than the parsed URL value because the
3088
- // URL lags by a tick during pivot enable/disable transitions. Consumer
3089
- // callbacks are always forwarded.
3090
- 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;
3091
- if (!pivotActiveLive) {
3092
- updateUrl(buildModel({
3093
- columnsModel: columnsVisibilityModel
3094
- }), search, localStorageVersion, historyReplace, columns);
3095
- }
3096
3952
  propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
3953
+ updateUrl(buildModel({
3954
+ columnsModel: columnsVisibilityModel
3955
+ }), search, localStorageVersion, historyReplace, columns);
3097
3956
  },
3098
3957
  onColumnWidthChange: (params, event, details) => {
3099
3958
  propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
@@ -3101,38 +3960,11 @@ const useStatefulTable = props => {
3101
3960
  newWidth: params.width,
3102
3961
  field: params.colDef.field
3103
3962
  });
3104
- },
3105
- onRowGroupingModelChange: (model, details) => {
3106
- updateUrl(buildModel({
3107
- rowGroupingModel: model
3108
- }), search, localStorageVersion, historyReplace, columns);
3109
- propsOnRowGroupingModelChange === null || propsOnRowGroupingModelChange === void 0 ? void 0 : propsOnRowGroupingModelChange(model, details);
3110
- },
3111
- onAggregationModelChange: (model, details) => {
3112
- updateUrl(buildModel({
3113
- aggregationModel: model
3114
- }), search, localStorageVersion, historyReplace, columns);
3115
- propsOnAggregationModelChange === null || propsOnAggregationModelChange === void 0 ? void 0 : propsOnAggregationModelChange(model, details);
3116
- },
3117
- onPivotModelChange: model => {
3118
- const simplified = fromGridPivotModel(model);
3119
- if (isDeepEqual(simplified, lastEmittedPivotRef.current)) return;
3120
- lastEmittedPivotRef.current = simplified;
3121
- updateUrl(buildModel({
3122
- pivotModel: simplified
3123
- }), search, localStorageVersion, historyReplace, columns);
3124
- propsOnPivotModelChange === null || propsOnPivotModelChange === void 0 ? void 0 : propsOnPivotModelChange(model);
3125
- },
3126
- onPivotActiveChange: active => {
3127
- if (active === pivotActiveParsed) return;
3128
- updateUrl(buildModel({
3129
- pivotActive: active
3130
- }), search, localStorageVersion, historyReplace, columns);
3131
3963
  }
3132
3964
  };
3133
3965
  };
3134
3966
 
3135
- const _excluded = ["apiRef", "autoHeight", "className", "columns", "slots", "slotProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "paginationModel", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "rowSelectionModel", "onColumnWidthChange", "onPaginationModelChange", "onRowSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "onRowGroupingModelChange", "onAggregationModelChange", "onPivotModelChange", "pagination", "paginationPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount", "density", "dataSource", "filterMode", "sortingMode"];
3967
+ 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"];
3136
3968
  const COMPONENT_NAME = 'DataGrid';
3137
3969
  const CLASSNAME = 'redsift-datagrid';
3138
3970
 
@@ -3216,11 +4048,9 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3216
4048
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
3217
4049
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
3218
4050
  onSortModelChange: propsOnSortModelChange,
3219
- onRowGroupingModelChange: propsOnRowGroupingModelChange,
3220
- onAggregationModelChange: propsOnAggregationModelChange,
3221
- onPivotModelChange: propsOnPivotModelChange,
3222
4051
  pagination,
3223
4052
  paginationPlacement = 'both',
4053
+ selectionBannerPlacement = 'top',
3224
4054
  paginationProps,
3225
4055
  rows,
3226
4056
  pageSizeOptions,
@@ -3228,26 +4058,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3228
4058
  theme: propsTheme,
3229
4059
  useRouter,
3230
4060
  paginationMode = 'client',
3231
- rowCount,
3232
- density: _density,
3233
- dataSource,
3234
- filterMode: propsFilterMode,
3235
- sortingMode: propsSortingMode
4061
+ rowCount
3236
4062
  } = props,
3237
4063
  forwardedProps = _objectWithoutProperties(props, _excluded);
3238
- const theme = useTheme(propsTheme);
4064
+ const theme = useTheme$1(propsTheme);
3239
4065
  const _apiRef = useGridApiRef();
3240
4066
  const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
4067
+ const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
3241
4068
  LicenseInfo.setLicenseKey(license);
3242
4069
  const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
3243
-
3244
- // When dataSource is present, MUI manages filter/sort/pagination internally.
3245
- // We must not pass controlled models — only initialState (one-time) and
3246
- // write-only onChange handlers for URL/localStorage persistence.
3247
- const isDataSourceMode = Boolean(dataSource);
3248
- const effectivePaginationMode = isDataSourceMode ? 'server' : paginationMode;
3249
- const effectiveFilterMode = isDataSourceMode ? 'server' : propsFilterMode;
3250
- const effectiveSortingMode = isDataSourceMode ? 'server' : propsSortingMode;
3251
4070
  const {
3252
4071
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
3253
4072
  onFilterModelChange: controlledOnFilterModelChange,
@@ -3281,15 +4100,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3281
4100
  pinnedColumns,
3282
4101
  sortModel,
3283
4102
  onColumnWidthChange,
3284
- columnOrderModel,
3285
- rowGroupingModel,
3286
- aggregationModel,
3287
- pivotModel,
3288
- pivotActive,
3289
- onRowGroupingModelChange,
3290
- onAggregationModelChange,
3291
- onPivotModelChange,
3292
- onPivotActiveChange
4103
+ columnOrderModel
3293
4104
  } = useStatefulTable({
3294
4105
  apiRef: apiRef,
3295
4106
  initialState,
@@ -3300,68 +4111,13 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3300
4111
  onPaginationModelChange: controlledOnPaginationModelChange,
3301
4112
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
3302
4113
  onSortModelChange: controlledOnSortModelChange,
3303
- onRowGroupingModelChange: propsOnRowGroupingModelChange,
3304
- onAggregationModelChange: propsOnAggregationModelChange,
3305
- onPivotModelChange: propsOnPivotModelChange,
3306
4114
  useRouter: useRouter,
3307
4115
  localStorageVersion,
3308
4116
  previousLocalStorageVersions
3309
4117
  });
3310
-
3311
- // In dataSource mode, track pagination locally for the custom pagination slots
3312
- // (rendered outside DataGridPremium). MUI owns the actual pagination state internally.
3313
- const [dataSourcePaginationModel, setDataSourcePaginationModel] = useState(paginationModel);
3314
-
3315
- // The pagination model to use for display in pagination slots
3316
- const activePaginationModel = isDataSourceMode ? dataSourcePaginationModel : paginationModel;
3317
-
3318
- // Wrap onPaginationModelChange to also track state locally in dataSource mode
3319
- const wrappedOnPaginationModelChange = useCallback((model, details) => {
3320
- if (isDataSourceMode) {
3321
- setDataSourcePaginationModel(model);
3322
- }
3323
- onPaginationModelChange(model, details);
3324
- }, [isDataSourceMode, onPaginationModelChange]);
3325
-
3326
- // In dataSource mode, pagination changes from our custom pagination slots
3327
- // (rendered outside MUI's pagination state) route through apiRef so MUI's
3328
- // internal page state updates and dataSource.getRows() refetches with the
3329
- // new params. The `paginationModelChange` subscription below picks up the
3330
- // resulting state change and propagates it to URL/localStorage and local
3331
- // React state via wrappedOnPaginationModelChange.
3332
- const dataSourcePaginationChange = useCallback(model => {
3333
- var _apiRef$current;
3334
- (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPaginationModel(model);
3335
- }, [apiRef]);
3336
-
3337
- // In dataSource mode, subscribe to MUI's `paginationModelChange` event so
3338
- // URL state stays in sync with MUI's internal pagination regardless of how
3339
- // it changed (slot click, apiRef.setPaginationModel from consumer code,
3340
- // MUI internal updates, etc.). Relying on MUI's `onPaginationModelChange`
3341
- // prop callback alone is not sufficient: in pivot/GroupedData strategy mode
3342
- // and with `paginationModel` seeded via `initialState` (rather than as a
3343
- // controlled prop), the prop callback can be missed under certain
3344
- // re-render orderings. The event fires reliably whenever the internal
3345
- // state changes via `setState('setPaginationModel')`, see
3346
- // `useGridStateInitialization.setState` → `publishEvent(changeEvent, …)`.
3347
- // The deep-equal guard inside `useStatefulTable.onPaginationModelChange`
3348
- // dedupes any duplicate emits, so overlap with the prop callback is safe.
3349
- useEffect(() => {
3350
- if (!isDataSourceMode) return;
3351
- const api = apiRef.current;
3352
- if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
3353
- return api.subscribeEvent('paginationModelChange', model => {
3354
- wrappedOnPaginationModelChange({
3355
- page: model.page,
3356
- pageSize: model.pageSize
3357
- }, {
3358
- reason: 'paginationModelChange'
3359
- });
3360
- });
3361
- }, [isDataSourceMode, apiRef, wrappedOnPaginationModelChange]);
3362
- const [rowSelectionModel, setRowSelectionModel] = useState(() => normalizeRowSelectionModel(propsRowSelectionModel));
4118
+ const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3363
4119
  useEffect(() => {
3364
- setRowSelectionModel(normalizeRowSelectionModel(propsRowSelectionModel));
4120
+ setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3365
4121
  }, [propsRowSelectionModel]);
3366
4122
  const onRowSelectionModelChange = (selectionModel, details) => {
3367
4123
  setRowSelectionModel(selectionModel);
@@ -3375,41 +4131,25 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3375
4131
  pageSize: paginationModel.pageSize
3376
4132
  });
3377
4133
 
3378
- // Version counter to force re-renders when selectionStatus ref changes
3379
- const [, forceSelectionUpdate] = useState(0);
3380
-
3381
4134
  // The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
3382
4135
  // for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
3383
- const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(effectivePaginationMode != 'server');
3384
-
3385
- // Track when the grid API is ready to ensure top pagination renders correctly
3386
- const [gridReady, setGridReady] = useState(false);
3387
-
3388
- // Force re-render when the grid API becomes ready (for top pagination)
3389
- useEffect(() => {
3390
- if (apiRef.current && !gridReady) {
3391
- setGridReady(true);
3392
- }
3393
- });
4136
+ const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
3394
4137
 
3395
- // Sync persisted density via apiRef initialState only applies on mount,
3396
- // so this handles SPA back/forward navigation where controlledDensity changes after mount
3397
- useEffect(() => {
3398
- if (apiRef.current) {
3399
- apiRef.current.setDensity(controlledDensity);
3400
- }
3401
- }, [controlledDensity, apiRef]);
4138
+ // Banner and pager placements are independent. `belowToolbar` (for either) renders
4139
+ // in the toolbar-slot row, and only applies when pagination is on.
4140
+ const bannerAtTop = selectionBannerPlacement === 'top';
4141
+ const bannerAtBottom = selectionBannerPlacement === 'bottom';
4142
+ const bannerBelowToolbar = selectionBannerPlacement === 'belowToolbar' && Boolean(pagination);
4143
+ const pagerBelowToolbar = paginationPlacement === 'belowToolbar' && Boolean(pagination);
3402
4144
 
3403
4145
  // in server-side pagination we want to update the selection status
3404
4146
  // every time we navigate between pages, resize our page or select something
3405
4147
  useEffect(() => {
3406
- if (effectivePaginationMode == 'server') {
3407
- onServerSideSelectionStatusChange(rowSelectionModel, apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, activePaginationModel.page, activePaginationModel.pageSize);
4148
+ if (paginationMode == 'server') {
4149
+ onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatusRef, isRowSelectable, paginationModel.page, paginationModel.pageSize);
3408
4150
  }
3409
- }, [rowSelectionModel, activePaginationModel.page, activePaginationModel.pageSize, rows]);
3410
-
3411
- // In dataSource mode MUI provides rows internally; skip the guard.
3412
- if (!isDataSourceMode && !Array.isArray(rows)) {
4151
+ }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize, rows]);
4152
+ if (!Array.isArray(rows)) {
3413
4153
  return null;
3414
4154
  }
3415
4155
 
@@ -3418,15 +4158,9 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3418
4158
  // receive the fresh value in the same render cycle — no extra re-render needed.
3419
4159
  // The ref is kept in sync for the onRowSelectionModelChange callback's deselect logic.
3420
4160
  let selectionStatus = selectionStatusRef.current;
3421
- if (pagination && effectivePaginationMode !== 'server' && getSelectionCount(rowSelectionModel) > 0) {
4161
+ if (pagination && paginationMode !== 'server' && Array.isArray(rowSelectionModel) && rowSelectionModel.length > 0) {
3422
4162
  try {
3423
- // Use manual page slicing instead of gridPaginatedVisibleSorted* selectors.
3424
- // MUI's paginated selectors use apiRef internal state which may be stale when
3425
- // paginationModel prop changes — our React state is always up to date.
3426
- const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
3427
- const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
3428
- const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
3429
- const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref => {
4163
+ const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref => {
3430
4164
  let {
3431
4165
  model
3432
4166
  } = _ref;
@@ -3438,29 +4172,24 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3438
4172
  id
3439
4173
  } = _ref2;
3440
4174
  return id;
3441
- }) : pageEntries.map(_ref3 => {
3442
- let {
3443
- id
3444
- } = _ref3;
3445
- return id;
3446
- });
4175
+ }) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
3447
4176
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
3448
- const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref4 => {
4177
+ const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref3 => {
3449
4178
  let {
3450
4179
  model
3451
- } = _ref4;
4180
+ } = _ref3;
3452
4181
  return isRowSelectable({
3453
4182
  row: model
3454
4183
  });
3455
- }).map(_ref5 => {
4184
+ }).map(_ref4 => {
3456
4185
  let {
3457
4186
  id
3458
- } = _ref5;
4187
+ } = _ref4;
3459
4188
  return id;
3460
4189
  }) : gridFilteredSortedRowIdsSelector(apiRef);
3461
4190
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
3462
- const numberOfSelectedRows = getSelectionCount(rowSelectionModel);
3463
- const selectedOnCurrentPage = selectableRowsInPage.filter(id => isRowSelected(rowSelectionModel, id));
4191
+ const numberOfSelectedRows = rowSelectionModel.length;
4192
+ const selectedOnCurrentPage = selectableRowsInPage.filter(id => rowSelectionModel.includes(id));
3464
4193
  if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
3465
4194
  selectionStatus = {
3466
4195
  type: 'table',
@@ -3485,7 +4214,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3485
4214
  } catch {
3486
4215
  // apiRef may not be initialized on first render
3487
4216
  }
3488
- } else if (pagination && effectivePaginationMode !== 'server') {
4217
+ } else if (pagination && paginationMode !== 'server') {
3489
4218
  selectionStatus = {
3490
4219
  type: 'none',
3491
4220
  numberOfSelectedRows: 0
@@ -3514,227 +4243,158 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3514
4243
  ref: datagridRef,
3515
4244
  className: classNames(StatefulDataGrid.className, className),
3516
4245
  $height: height
3517
- }, pagination && ['top', 'both'].includes(paginationPlacement) && gridReady ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, {
3518
- displaySelection: true,
3519
- displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
3520
- displayPagination: ['top', 'both'].includes(paginationPlacement),
3521
- selectionStatus: selectionStatus,
3522
- paginationModel: activePaginationModel,
3523
- onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
3524
- pageSizeOptions: pageSizeOptions,
3525
- paginationProps: paginationProps,
3526
- rowCount: rowCount
3527
- }) : /*#__PURE__*/React__default.createElement(ControlledPagination, {
3528
- displaySelection: true,
3529
- displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
3530
- displayPagination: ['top', 'both'].includes(paginationPlacement),
3531
- selectionStatus: selectionStatus,
4246
+ }, /*#__PURE__*/React__default.createElement(DataGridPro, _extends$2({}, forwardedProps, {
3532
4247
  apiRef: apiRef,
3533
- isRowSelectable: isRowSelectable,
3534
- paginationModel: activePaginationModel,
3535
- onPaginationModelChange: onPaginationModelChange,
3536
- pageSizeOptions: pageSizeOptions,
3537
- paginationProps: paginationProps
3538
- }) : null, /*#__PURE__*/React__default.createElement(DataGridPremium, _extends({}, forwardedProps, {
3539
- apiRef: apiRef,
3540
- dataSource: dataSource,
3541
4248
  columns: columns,
4249
+ columnVisibilityModel: columnVisibilityModel,
4250
+ density: controlledDensity,
4251
+ filterModel: filterModel,
3542
4252
  onColumnVisibilityModelChange: onColumnVisibilityModelChange,
4253
+ onFilterModelChange: onFilterModelChange,
4254
+ onPaginationModelChange: onPaginationModelChange,
3543
4255
  onPinnedColumnsChange: onPinnedColumnsChange,
4256
+ onSortModelChange: onSortModelChange,
4257
+ paginationModel: paginationModel,
4258
+ pinnedColumns: pinnedColumns,
4259
+ sortModel: sortModel,
3544
4260
  pageSizeOptions: pageSizeOptions,
3545
4261
  onColumnWidthChange: onColumnWidthChange,
3546
- onRowGroupingModelChange: onRowGroupingModelChange,
3547
- onAggregationModelChange: onAggregationModelChange,
3548
- pivotModel: pivotModel,
3549
- onPivotModelChange: onPivotModelChange,
3550
- pivotActive: pivotActive,
3551
- onPivotActiveChange: onPivotActiveChange
3552
- // In dataSource mode: models are uncontrolled (MUI owns them),
3553
- // onChange handlers are write-only for URL/localStorage persistence,
3554
- // and initialState seeds MUI on mount from the persisted URL state.
3555
- // columnVisibilityModel / pinnedColumns / rowGroupingModel /
3556
- // aggregationModel are also uncontrolled here to avoid a controlled
3557
- // re-render race with consumer-side microtask-deferred history
3558
- // updates (otherwise user toggles flip back when MUI re-emits with
3559
- // the stale controlled value). Consumers needing programmatic
3560
- // changes should use the apiRef imperative API.
3561
- }, isDataSourceMode ? {
3562
- onFilterModelChange: onFilterModelChange,
3563
- onSortModelChange: onSortModelChange,
3564
- onPaginationModelChange: wrappedOnPaginationModelChange,
3565
4262
  initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
3566
- density: controlledDensity,
3567
- columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
3568
- orderedFields: columnOrderModel,
3569
- columnVisibilityModel
3570
- }),
3571
- pinnedColumns,
3572
- rowGrouping: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.rowGrouping), {}, {
3573
- model: rowGroupingModel
3574
- }),
3575
- aggregation: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.aggregation), {}, {
3576
- model: aggregationModel
3577
- }),
3578
- filter: {
3579
- filterModel
3580
- },
3581
- sorting: {
3582
- sortModel
3583
- },
3584
- pagination: {
3585
- paginationModel
3586
- },
3587
- pivoting: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.pivoting), {}, {
3588
- enabled: pivotActive
3589
- })
3590
- })
3591
- } : {
3592
- columnVisibilityModel,
3593
- pinnedColumns,
3594
- rowGroupingModel,
3595
- aggregationModel,
3596
- filterModel,
3597
- sortModel,
3598
- paginationModel,
3599
- onFilterModelChange: onFilterModelChange,
3600
- onSortModelChange: onSortModelChange,
3601
- onPaginationModelChange: wrappedOnPaginationModelChange,
3602
- initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
3603
- density: controlledDensity,
3604
4263
  columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
3605
4264
  orderedFields: columnOrderModel
3606
4265
  })
3607
- })
3608
- }, {
4266
+ }),
3609
4267
  isRowSelectable: isRowSelectable,
3610
4268
  pagination: pagination,
3611
- paginationMode: effectivePaginationMode,
3612
- filterMode: effectiveFilterMode,
3613
- sortingMode: effectiveSortingMode,
3614
- keepNonExistentRowsSelected: effectivePaginationMode == 'server',
3615
- rows: isDataSourceMode ? [] : rows,
4269
+ paginationMode: paginationMode,
4270
+ keepNonExistentRowsSelected: paginationMode == 'server',
4271
+ rows: rows,
3616
4272
  rowCount: rowCount,
3617
4273
  autoHeight: autoHeight,
3618
4274
  checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
3619
- disableRowSelectionExcludeModel: true,
3620
- showToolbar: !hideToolbar,
3621
4275
  slots: _objectSpread2(_objectSpread2({
3622
4276
  baseButton: BaseButton,
3623
4277
  baseCheckbox: BaseCheckbox,
3624
- baseIconButton: BaseIconButton,
3625
- columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3626
- displayName: "columnFilteredIcon"
4278
+ // baseTextField,
4279
+ basePopper: BasePopper,
4280
+ columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4281
+ displayName: "ColumnFilteredIcon"
3627
4282
  })),
3628
- columnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3629
- displayName: "columnSelectorIcon"
4283
+ columnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4284
+ displayName: "ColumnSelectorIcon"
3630
4285
  })),
3631
- columnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3632
- displayName: "columnSortedAscendingIcon"
4286
+ columnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4287
+ displayName: "ColumnSortedAscendingIcon"
3633
4288
  })),
3634
- columnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3635
- displayName: "columnSortedDescendingIcon"
4289
+ columnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4290
+ displayName: "ColumnSortedDescendingIcon"
3636
4291
  })),
3637
- densityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3638
- displayName: "densityCompactIcon"
4292
+ densityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4293
+ displayName: "DensityCompactIcon"
3639
4294
  })),
3640
- densityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3641
- displayName: "densityStandardIcon"
4295
+ densityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4296
+ displayName: "DensityStandardIcon"
3642
4297
  })),
3643
- densityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3644
- displayName: "densityComfortableIcon"
4298
+ densityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4299
+ displayName: "DensityComfortableIcon"
3645
4300
  })),
3646
- detailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3647
- displayName: "detailPanelCollapseIcon"
4301
+ detailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4302
+ displayName: "DetailPanelCollapseIcon"
3648
4303
  })),
3649
- detailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3650
- displayName: "detailPanelExpandIcon"
4304
+ detailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4305
+ displayName: "DetailPanelExpandIcon"
3651
4306
  })),
3652
- exportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3653
- displayName: "exportIcon"
4307
+ exportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({}, props, {
4308
+ displayName: "ExportIcon"
3654
4309
  })),
3655
- openFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3656
- displayName: "openFilterButtonIcon"
3657
- }))
4310
+ openFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$2({
4311
+ displayName: "OpenFilterButtonIcon"
4312
+ }, props))
3658
4313
  }, slots), {}, {
4314
+ toolbar: ToolbarWrapper,
3659
4315
  pagination: props => {
3660
- return pagination ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
3661
- displaySelection: false,
4316
+ return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends$2({}, props, {
4317
+ displaySelection: bannerAtBottom,
3662
4318
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3663
4319
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3664
4320
  selectionStatus: selectionStatus,
3665
- paginationModel: activePaginationModel
3666
- // In dataSource mode route through apiRef so MUI's internal pagination
3667
- // state stays in sync with the displayed model and dataSource.getRows()
3668
- // re-fetches with the new params. MUI then fires onPaginationModelChange
3669
- // via the prop, which updates URL/localStorage via useStatefulTable.
3670
- // Without this the bottom slot only updated local React state + URL,
3671
- // leaving MUI on its previous internal page (no refetch, stale display).
3672
- ,
3673
- onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : wrappedOnPaginationModelChange,
4321
+ paginationModel: paginationModel,
4322
+ onPaginationModelChange: onPaginationModelChange,
3674
4323
  pageSizeOptions: pageSizeOptions,
3675
4324
  paginationProps: paginationProps,
4325
+ paginationMode: paginationMode,
3676
4326
  rowCount: rowCount
3677
- })) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends({}, props, {
3678
- displaySelection: false,
4327
+ })) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends$2({}, props, {
4328
+ displaySelection: bannerAtBottom,
3679
4329
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3680
4330
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3681
4331
  selectionStatus: selectionStatus,
3682
4332
  apiRef: apiRef,
3683
4333
  isRowSelectable: isRowSelectable,
3684
- paginationModel: activePaginationModel,
3685
- onPaginationModelChange: wrappedOnPaginationModelChange,
4334
+ paginationModel: paginationModel,
4335
+ onPaginationModelChange: onPaginationModelChange,
3686
4336
  pageSizeOptions: pageSizeOptions,
3687
- paginationProps: paginationProps
4337
+ paginationProps: paginationProps,
4338
+ paginationMode: paginationMode
3688
4339
  })) : null;
3689
4340
  }
3690
4341
  }),
3691
- slotProps: _objectSpread2({}, slotProps),
4342
+ slotProps: _objectSpread2(_objectSpread2({}, slotProps), {}, {
4343
+ toolbar: _objectSpread2({
4344
+ hideToolbar,
4345
+ RenderedToolbar,
4346
+ filterModel,
4347
+ onFilterModelChange,
4348
+ pagination,
4349
+ displaySelection: bannerAtTop || bannerBelowToolbar,
4350
+ displayPagination: ['top', 'both'].includes(paginationPlacement) || pagerBelowToolbar,
4351
+ displayRowsPerPage: pagerBelowToolbar,
4352
+ selectionStatus,
4353
+ apiRef,
4354
+ isRowSelectable,
4355
+ paginationModel,
4356
+ onPaginationModelChange,
4357
+ pageSizeOptions,
4358
+ paginationProps,
4359
+ paginationMode,
4360
+ rowCount
4361
+ }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar)
4362
+ }),
3692
4363
  rowSelectionModel: rowSelectionModel,
3693
4364
  onRowSelectionModelChange: (newSelectionModel, details) => {
3694
- if (pagination && effectivePaginationMode != 'server') {
3695
- // Use manual page slicing instead of gridPaginatedVisibleSorted* selectors
3696
- // to avoid stale apiRef pagination state.
3697
- const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
3698
- const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
3699
- const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
3700
- const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref6 => {
4365
+ if (pagination && paginationMode != 'server') {
4366
+ const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref5 => {
3701
4367
  let {
3702
4368
  model
3703
- } = _ref6;
4369
+ } = _ref5;
3704
4370
  return isRowSelectable({
3705
4371
  row: model
3706
4372
  });
3707
- }).map(_ref7 => {
4373
+ }).map(_ref6 => {
3708
4374
  let {
3709
4375
  id
3710
- } = _ref7;
3711
- return id;
3712
- }) : pageEntries.map(_ref8 => {
3713
- let {
3714
- id
3715
- } = _ref8;
4376
+ } = _ref6;
3716
4377
  return id;
3717
- });
4378
+ }) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
3718
4379
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
3719
- const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref9 => {
4380
+ const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref7 => {
3720
4381
  let {
3721
4382
  model
3722
- } = _ref9;
4383
+ } = _ref7;
3723
4384
  return isRowSelectable({
3724
4385
  row: model
3725
4386
  });
3726
- }).map(_ref10 => {
4387
+ }).map(_ref8 => {
3727
4388
  let {
3728
4389
  id
3729
- } = _ref10;
4390
+ } = _ref8;
3730
4391
  return id;
3731
4392
  }) : gridFilteredSortedRowIdsSelector(apiRef);
3732
4393
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
3733
- const numberOfSelectedRows = getSelectionCount(newSelectionModel);
4394
+ const numberOfSelectedRows = newSelectionModel.length;
3734
4395
  if (selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatusRef.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
3735
4396
  setTimeout(() => {
3736
- var _apiRef$current2;
3737
- (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.selectRows([], true, true);
4397
+ apiRef.current.selectRows([], true, true);
3738
4398
  }, 0);
3739
4399
  }
3740
4400
  if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
@@ -3758,7 +4418,6 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3758
4418
  numberOfSelectedRows
3759
4419
  };
3760
4420
  }
3761
- forceSelectionUpdate(v => v + 1);
3762
4421
  }
3763
4422
  onRowSelectionModelChange === null || onRowSelectionModelChange === void 0 ? void 0 : onRowSelectionModelChange(newSelectionModel, details);
3764
4423
  },
@@ -3776,5 +4435,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3776
4435
  StatefulDataGrid.className = CLASSNAME;
3777
4436
  StatefulDataGrid.displayName = COMPONENT_NAME;
3778
4437
 
3779
- export { buildStorageKey as $, ARRAY_IS_EMPTY as A, IS as B, CONTAINS_ANY_OF as C, DOES_NOT_CONTAIN as D, ENDS_WITH_ANY_OF as E, IS_NOT as F, getGridStringOperators as G, HAS_WITH_SELECT as H, IS_ANY_OF as I, getGridStringArrayOperators as J, getGridStringArrayOperatorsWithSelect as K, getGridStringArrayOperatorsWithSelectOnStringArrayColumns as L, FILTER_MODEL_KEY as M, SORT_MODEL_KEY as N, PINNED_COLUMNS as O, PAGINATION_MODEL_KEY as P, DIMENSION_MODEL_KEY as Q, FILTER_SEARCH_KEY as R, STARTS_WITH_ANY_OF as S, DENSITY_MODEL_KEY as T, COLUMN_ORDER_MODEL_KEY as U, VISIBILITY_MODEL_KEY as V, ROW_GROUPING_MODEL_KEY as W, AGGREGATION_MODEL_KEY as X, PIVOT_MODEL_KEY as Y, PIVOT_ACTIVE_KEY as Z, CATEGORIES as _, DOES_NOT_EQUAL as a, clearPreviousVersionStorage as a0, clearAllVersionStorage as a1, resetStatefulDataGridState as a2, convertToDisplayFormat as a3, convertFromDisplayFormat as a4, getDecodedSearchFromUrl as a5, buildQueryParamsString as a6, areSearchStringsEqual as a7, decodeValue as a8, encodeValue as a9, getPivotFromString as aA, getSearchParamsFromPivot as aB, getPivotActiveFromString as aC, getSearchParamsFromPivotActive as aD, getFinalSearch as aE, getModelsParsedOrUpdateLocalStorage as aF, updateUrl as aG, areFilterModelsEquivalent as aH, StatefulDataGrid as aI, urlSearchParamsToString as aa, numberOperatorEncoder as ab, numberOperatorDecoder as ac, isOperatorValueValid as ad, isValueValid as ae, getFilterModelFromString as af, getSearchParamsFromFilterModel as ag, getSortingFromString as ah, getSearchParamsFromSorting as ai, getPaginationFromString as aj, getSearchParamsFromPagination as ak, getColumnVisibilityFromString as al, getSearchParamsFromColumnVisibility as am, getPinnedColumnsFromString as an, getSearchParamsFromPinnedColumns as ao, getSearchParamsFromTab as ap, getDensityFromString as aq, getSearchParamsFromDensity as ar, getDensityModel as as, getColumnOrderFromString as at, getSearchParamsFromColumnOrder as au, getRowGroupingFromString as av, getSearchParamsFromRowGrouping as aw, getAggregationFromString as ax, getSearchParamsFromAggregation as ay, fromGridPivotModel as az, DOES_NOT_START_WITH as b, DOES_NOT_END_WITH as c, IS_NOT_ANY_OF as d, DOES_NOT_CONTAIN_ANY_OF as e, DOES_NOT_START_WITH_ANY_OF as f, DOES_NOT_END_WITH_ANY_OF as g, IS_BETWEEN as h, IS_WITH_SELECT as i, IS_NOT_WITH_SELECT as j, IS_ANY_OF_WITH_SELECT as k, IS_NOT_ANY_OF_WITH_SELECT as l, ARRAY_IS_NOT_EMPTY as m, DOES_NOT_HAVE_WITH_SELECT as n, operatorList as o, HAS_ANY_OF_WITH_SELECT as p, HAS_ALL_OF_WITH_SELECT as q, DOES_NOT_HAVE_ANY_OF_WITH_SELECT as r, HAS_ONLY_WITH_SELECT as s, HAS as t, DOES_NOT_HAVE as u, HAS_ANY_OF as v, HAS_ALL_OF as w, DOES_NOT_HAVE_ANY_OF as x, HAS_ONLY as y, getGridNumericOperators as z };
4438
+ 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, getSearchParamsFromFilterModel as af, getSortingFromString as ag, getSearchParamsFromSorting as ah, getPaginationFromString as ai, getSearchParamsFromPagination as aj, getColumnVisibilityFromString as ak, getSearchParamsFromColumnVisibility as al, getPinnedColumnsFromString as am, getSearchParamsFromPinnedColumns as an, getSearchParamsFromTab as ao, getDensityFromString as ap, getSearchParamsFromDensity as aq, getColumnOrderFromString as ar, getSearchParamsFromColumnOrder as as, getSearchParamsFromVersion as at, getFinalSearch as au, getModelsParsedOrUpdateLocalStorage as av, updateUrl as aw, areFilterModelsEquivalent as ax, StatefulDataGrid as ay, 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 };
3780
4439
  //# sourceMappingURL=StatefulDataGrid2.js.map