@redsift/table 12.4.0 → 12.5.0-muiv7

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,17 +1,1500 @@
1
1
  import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends } 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, forwardRef, useRef, 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, gridPaginatedVisibleSortedGridRowEntriesSelector, gridPaginatedVisibleSortedGridRowIdsSelector, 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, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite, ThemeProvider } from '@redsift/design-system';
6
+ import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, DataGridPro } from '@mui/x-data-grid-pro';
7
+ import { L as LicenseInfo, u as useControlledDatagridState, T as ThemeProvider$1, S as StyledDataGrid } from './useControlledDatagridState.js';
12
8
  import { mdiSync } from '@redsift/icons';
13
- import { n as normalizeRowSelectionModel, o as onServerSideSelectionStatusChange, g as getSelectionCount, i as isRowSelected, S as ServerSideControlledPagination, C as ControlledPagination } from './ServerSideControlledPagination.js';
14
- import { B as BaseButton, a as BaseCheckbox, c as BaseIconButton, b as BaseIcon } from './BaseIconButton.js';
9
+ import { d as defaultSxConfig, i as isPlainObject, s as styled, a as styleFunctionSx, c as clsx, g as generateUtilityClasses, b as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, e as generateUtilityClass, f as styled$1, u as useDefaultProps, h as composeClasses, r as rootShouldForwardProp, j as refType } from './Portal.js';
10
+ import { j as jsxRuntimeExports } from './jsx-runtime.js';
11
+ import { u as useTheme, m as memoTheme, c as createSimplePaletteValueFilter, a as useFormControl, b as formControlState, d as capitalize, i as isAdornedStart, e as isFilled, F as FormControlContext, h as useId, j as useSlot, k as Select, I as Input, l as FilledInput, O as OutlinedInput, o as onServerSideSelectionStatusChange, S as ServerSideControlledPagination, C as ControlledPagination } from './ControlledPagination.js';
12
+ import { T as Toolbar } from './Toolbar2.js';
13
+ import { B as BaseButton, a as BaseCheckbox, c as BasePopper, b as BaseIcon } from './BasePopper.js';
14
+ import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
15
+
16
+ const splitProps = props => {
17
+ const result = {
18
+ systemProps: {},
19
+ otherProps: {}
20
+ };
21
+ const config = props?.theme?.unstable_sxConfig ?? defaultSxConfig;
22
+ Object.keys(props).forEach(prop => {
23
+ if (config[prop]) {
24
+ result.systemProps[prop] = props[prop];
25
+ } else {
26
+ result.otherProps[prop] = props[prop];
27
+ }
28
+ });
29
+ return result;
30
+ };
31
+ function extendSxProp(props) {
32
+ const {
33
+ sx: inSx,
34
+ ...other
35
+ } = props;
36
+ const {
37
+ systemProps,
38
+ otherProps
39
+ } = splitProps(other);
40
+ let finalSx;
41
+ if (Array.isArray(inSx)) {
42
+ finalSx = [systemProps, ...inSx];
43
+ } else if (typeof inSx === 'function') {
44
+ finalSx = (...args) => {
45
+ const result = inSx(...args);
46
+ if (!isPlainObject(result)) {
47
+ return systemProps;
48
+ }
49
+ return {
50
+ ...systemProps,
51
+ ...result
52
+ };
53
+ };
54
+ } else {
55
+ finalSx = {
56
+ ...systemProps,
57
+ ...inSx
58
+ };
59
+ }
60
+ return {
61
+ ...otherProps,
62
+ sx: finalSx
63
+ };
64
+ }
65
+
66
+ function createBox(options = {}) {
67
+ const {
68
+ themeId,
69
+ defaultTheme,
70
+ defaultClassName = 'MuiBox-root',
71
+ generateClassName
72
+ } = options;
73
+ const BoxRoot = styled('div', {
74
+ shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
75
+ })(styleFunctionSx);
76
+ const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
77
+ const theme = useTheme(defaultTheme);
78
+ const {
79
+ className,
80
+ component = 'div',
81
+ ...other
82
+ } = extendSxProp(inProps);
83
+ return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, {
84
+ as: component,
85
+ ref: ref,
86
+ className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
87
+ theme: themeId ? theme[themeId] || theme : theme,
88
+ ...other
89
+ });
90
+ });
91
+ return Box;
92
+ }
93
+
94
+ function isMuiElement(element, muiNames) {
95
+ return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf(
96
+ // For server components `muiName` is avaialble in element.type._payload.value.muiName
97
+ // relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
98
+ // eslint-disable-next-line no-underscore-dangle
99
+ element.type.muiName ?? element.type?._payload?.value?.muiName) !== -1;
100
+ }
101
+
102
+ const boxClasses = generateUtilityClasses('MuiBox', ['root']);
103
+ var boxClasses$1 = boxClasses;
104
+
105
+ const defaultTheme = createTheme();
106
+ const Box = createBox({
107
+ themeId: THEME_ID,
108
+ defaultTheme,
109
+ defaultClassName: boxClasses$1.root,
110
+ generateClassName: ClassNameGenerator.generate
111
+ });
112
+ process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
113
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
114
+ // │ These PropTypes are generated from the TypeScript type definitions. │
115
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
116
+ // └─────────────────────────────────────────────────────────────────────┘
117
+ /**
118
+ * @ignore
119
+ */
120
+ children: PropTypes.node,
121
+ /**
122
+ * The component used for the root node.
123
+ * Either a string to use a HTML element or a component.
124
+ */
125
+ component: PropTypes.elementType,
126
+ /**
127
+ * The system prop that allows defining system overrides as well as additional CSS styles.
128
+ */
129
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
130
+ } : void 0;
131
+ var Box$1 = Box;
132
+
133
+ function getFormLabelUtilityClasses(slot) {
134
+ return generateUtilityClass('MuiFormLabel', slot);
135
+ }
136
+ const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
137
+ var formLabelClasses$1 = formLabelClasses;
138
+
139
+ const useUtilityClasses$4 = ownerState => {
140
+ const {
141
+ classes,
142
+ color,
143
+ focused,
144
+ disabled,
145
+ error,
146
+ filled,
147
+ required
148
+ } = ownerState;
149
+ const slots = {
150
+ root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
151
+ asterisk: ['asterisk', error && 'error']
152
+ };
153
+ return composeClasses(slots, getFormLabelUtilityClasses, classes);
154
+ };
155
+ const FormLabelRoot = styled$1('label', {
156
+ name: 'MuiFormLabel',
157
+ slot: 'Root',
158
+ overridesResolver: (props, styles) => {
159
+ const {
160
+ ownerState
161
+ } = props;
162
+ return [styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled];
163
+ }
164
+ })(memoTheme(({
165
+ theme
166
+ }) => ({
167
+ color: (theme.vars || theme).palette.text.secondary,
168
+ ...theme.typography.body1,
169
+ lineHeight: '1.4375em',
170
+ padding: 0,
171
+ position: 'relative',
172
+ variants: [...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
173
+ props: {
174
+ color
175
+ },
176
+ style: {
177
+ [`&.${formLabelClasses$1.focused}`]: {
178
+ color: (theme.vars || theme).palette[color].main
179
+ }
180
+ }
181
+ })), {
182
+ props: {},
183
+ style: {
184
+ [`&.${formLabelClasses$1.disabled}`]: {
185
+ color: (theme.vars || theme).palette.text.disabled
186
+ },
187
+ [`&.${formLabelClasses$1.error}`]: {
188
+ color: (theme.vars || theme).palette.error.main
189
+ }
190
+ }
191
+ }]
192
+ })));
193
+ const AsteriskComponent = styled$1('span', {
194
+ name: 'MuiFormLabel',
195
+ slot: 'Asterisk',
196
+ overridesResolver: (props, styles) => styles.asterisk
197
+ })(memoTheme(({
198
+ theme
199
+ }) => ({
200
+ [`&.${formLabelClasses$1.error}`]: {
201
+ color: (theme.vars || theme).palette.error.main
202
+ }
203
+ })));
204
+ const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
205
+ const props = useDefaultProps({
206
+ props: inProps,
207
+ name: 'MuiFormLabel'
208
+ });
209
+ const {
210
+ children,
211
+ className,
212
+ color,
213
+ component = 'label',
214
+ disabled,
215
+ error,
216
+ filled,
217
+ focused,
218
+ required,
219
+ ...other
220
+ } = props;
221
+ const muiFormControl = useFormControl();
222
+ const fcs = formControlState({
223
+ props,
224
+ muiFormControl,
225
+ states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
226
+ });
227
+ const ownerState = {
228
+ ...props,
229
+ color: fcs.color || 'primary',
230
+ component,
231
+ disabled: fcs.disabled,
232
+ error: fcs.error,
233
+ filled: fcs.filled,
234
+ focused: fcs.focused,
235
+ required: fcs.required
236
+ };
237
+ const classes = useUtilityClasses$4(ownerState);
238
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, {
239
+ as: component,
240
+ ownerState: ownerState,
241
+ className: clsx(classes.root, className),
242
+ ref: ref,
243
+ ...other,
244
+ children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
245
+ ownerState: ownerState,
246
+ "aria-hidden": true,
247
+ className: classes.asterisk,
248
+ children: ["\u2009", '*']
249
+ })]
250
+ });
251
+ });
252
+ process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
253
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
254
+ // │ These PropTypes are generated from the TypeScript type definitions. │
255
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
256
+ // └─────────────────────────────────────────────────────────────────────┘
257
+ /**
258
+ * The content of the component.
259
+ */
260
+ children: PropTypes.node,
261
+ /**
262
+ * Override or extend the styles applied to the component.
263
+ */
264
+ classes: PropTypes.object,
265
+ /**
266
+ * @ignore
267
+ */
268
+ className: PropTypes.string,
269
+ /**
270
+ * The color of the component.
271
+ * It supports both default and custom theme colors, which can be added as shown in the
272
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
273
+ */
274
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
275
+ /**
276
+ * The component used for the root node.
277
+ * Either a string to use a HTML element or a component.
278
+ */
279
+ component: PropTypes.elementType,
280
+ /**
281
+ * If `true`, the label should be displayed in a disabled state.
282
+ */
283
+ disabled: PropTypes.bool,
284
+ /**
285
+ * If `true`, the label is displayed in an error state.
286
+ */
287
+ error: PropTypes.bool,
288
+ /**
289
+ * If `true`, the label should use filled classes key.
290
+ */
291
+ filled: PropTypes.bool,
292
+ /**
293
+ * If `true`, the input of this label is focused (used by `FormGroup` components).
294
+ */
295
+ focused: PropTypes.bool,
296
+ /**
297
+ * If `true`, the label will indicate that the `input` is required.
298
+ */
299
+ required: PropTypes.bool,
300
+ /**
301
+ * The system prop that allows defining system overrides as well as additional CSS styles.
302
+ */
303
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
304
+ } : void 0;
305
+ var FormLabel$1 = FormLabel;
306
+
307
+ function getInputLabelUtilityClasses(slot) {
308
+ return generateUtilityClass('MuiInputLabel', slot);
309
+ }
310
+ generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
311
+
312
+ const useUtilityClasses$3 = ownerState => {
313
+ const {
314
+ classes,
315
+ formControl,
316
+ size,
317
+ shrink,
318
+ disableAnimation,
319
+ variant,
320
+ required
321
+ } = ownerState;
322
+ const slots = {
323
+ root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size && size !== 'normal' && `size${capitalize(size)}`, variant],
324
+ asterisk: [required && 'asterisk']
325
+ };
326
+ const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
327
+ return {
328
+ ...classes,
329
+ // forward the focused, disabled, etc. classes to the FormLabel
330
+ ...composedClasses
331
+ };
332
+ };
333
+ const InputLabelRoot = styled$1(FormLabel$1, {
334
+ shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
335
+ name: 'MuiInputLabel',
336
+ slot: 'Root',
337
+ overridesResolver: (props, styles) => {
338
+ const {
339
+ ownerState
340
+ } = props;
341
+ return [{
342
+ [`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
343
+ }, 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]];
344
+ }
345
+ })(memoTheme(({
346
+ theme
347
+ }) => ({
348
+ display: 'block',
349
+ transformOrigin: 'top left',
350
+ whiteSpace: 'nowrap',
351
+ overflow: 'hidden',
352
+ textOverflow: 'ellipsis',
353
+ maxWidth: '100%',
354
+ variants: [{
355
+ props: ({
356
+ ownerState
357
+ }) => ownerState.formControl,
358
+ style: {
359
+ position: 'absolute',
360
+ left: 0,
361
+ top: 0,
362
+ // slight alteration to spec spacing to match visual spec result
363
+ transform: 'translate(0, 20px) scale(1)'
364
+ }
365
+ }, {
366
+ props: {
367
+ size: 'small'
368
+ },
369
+ style: {
370
+ // Compensation for the `Input.inputSizeSmall` style.
371
+ transform: 'translate(0, 17px) scale(1)'
372
+ }
373
+ }, {
374
+ props: ({
375
+ ownerState
376
+ }) => ownerState.shrink,
377
+ style: {
378
+ transform: 'translate(0, -1.5px) scale(0.75)',
379
+ transformOrigin: 'top left',
380
+ maxWidth: '133%'
381
+ }
382
+ }, {
383
+ props: ({
384
+ ownerState
385
+ }) => !ownerState.disableAnimation,
386
+ style: {
387
+ transition: theme.transitions.create(['color', 'transform', 'max-width'], {
388
+ duration: theme.transitions.duration.shorter,
389
+ easing: theme.transitions.easing.easeOut
390
+ })
391
+ }
392
+ }, {
393
+ props: {
394
+ variant: 'filled'
395
+ },
396
+ style: {
397
+ // Chrome's autofill feature gives the input field a yellow background.
398
+ // Since the input field is behind the label in the HTML tree,
399
+ // the input field is drawn last and hides the label with an opaque background color.
400
+ // zIndex: 1 will raise the label above opaque background-colors of input.
401
+ zIndex: 1,
402
+ pointerEvents: 'none',
403
+ transform: 'translate(12px, 16px) scale(1)',
404
+ maxWidth: 'calc(100% - 24px)'
405
+ }
406
+ }, {
407
+ props: {
408
+ variant: 'filled',
409
+ size: 'small'
410
+ },
411
+ style: {
412
+ transform: 'translate(12px, 13px) scale(1)'
413
+ }
414
+ }, {
415
+ props: ({
416
+ variant,
417
+ ownerState
418
+ }) => variant === 'filled' && ownerState.shrink,
419
+ style: {
420
+ userSelect: 'none',
421
+ pointerEvents: 'auto',
422
+ transform: 'translate(12px, 7px) scale(0.75)',
423
+ maxWidth: 'calc(133% - 24px)'
424
+ }
425
+ }, {
426
+ props: ({
427
+ variant,
428
+ ownerState,
429
+ size
430
+ }) => variant === 'filled' && ownerState.shrink && size === 'small',
431
+ style: {
432
+ transform: 'translate(12px, 4px) scale(0.75)'
433
+ }
434
+ }, {
435
+ props: {
436
+ variant: 'outlined'
437
+ },
438
+ style: {
439
+ // see comment above on filled.zIndex
440
+ zIndex: 1,
441
+ pointerEvents: 'none',
442
+ transform: 'translate(14px, 16px) scale(1)',
443
+ maxWidth: 'calc(100% - 24px)'
444
+ }
445
+ }, {
446
+ props: {
447
+ variant: 'outlined',
448
+ size: 'small'
449
+ },
450
+ style: {
451
+ transform: 'translate(14px, 9px) scale(1)'
452
+ }
453
+ }, {
454
+ props: ({
455
+ variant,
456
+ ownerState
457
+ }) => variant === 'outlined' && ownerState.shrink,
458
+ style: {
459
+ userSelect: 'none',
460
+ pointerEvents: 'auto',
461
+ // Theoretically, we should have (8+5)*2/0.75 = 34px
462
+ // but it feels a better when it bleeds a bit on the left, so 32px.
463
+ maxWidth: 'calc(133% - 32px)',
464
+ transform: 'translate(14px, -9px) scale(0.75)'
465
+ }
466
+ }]
467
+ })));
468
+ const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
469
+ const props = useDefaultProps({
470
+ name: 'MuiInputLabel',
471
+ props: inProps
472
+ });
473
+ const {
474
+ disableAnimation = false,
475
+ margin,
476
+ shrink: shrinkProp,
477
+ variant,
478
+ className,
479
+ ...other
480
+ } = props;
481
+ const muiFormControl = useFormControl();
482
+ let shrink = shrinkProp;
483
+ if (typeof shrink === 'undefined' && muiFormControl) {
484
+ shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
485
+ }
486
+ const fcs = formControlState({
487
+ props,
488
+ muiFormControl,
489
+ states: ['size', 'variant', 'required', 'focused']
490
+ });
491
+ const ownerState = {
492
+ ...props,
493
+ disableAnimation,
494
+ formControl: muiFormControl,
495
+ shrink,
496
+ size: fcs.size,
497
+ variant: fcs.variant,
498
+ required: fcs.required,
499
+ focused: fcs.focused
500
+ };
501
+ const classes = useUtilityClasses$3(ownerState);
502
+ return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, {
503
+ "data-shrink": shrink,
504
+ ref: ref,
505
+ className: clsx(classes.root, className),
506
+ ...other,
507
+ ownerState: ownerState,
508
+ classes: classes
509
+ });
510
+ });
511
+ process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
512
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
513
+ // │ These PropTypes are generated from the TypeScript type definitions. │
514
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
515
+ // └─────────────────────────────────────────────────────────────────────┘
516
+ /**
517
+ * The content of the component.
518
+ */
519
+ children: PropTypes.node,
520
+ /**
521
+ * Override or extend the styles applied to the component.
522
+ */
523
+ classes: PropTypes.object,
524
+ /**
525
+ * @ignore
526
+ */
527
+ className: PropTypes.string,
528
+ /**
529
+ * The color of the component.
530
+ * It supports both default and custom theme colors, which can be added as shown in the
531
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
532
+ */
533
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
534
+ /**
535
+ * If `true`, the transition animation is disabled.
536
+ * @default false
537
+ */
538
+ disableAnimation: PropTypes.bool,
539
+ /**
540
+ * If `true`, the component is disabled.
541
+ */
542
+ disabled: PropTypes.bool,
543
+ /**
544
+ * If `true`, the label is displayed in an error state.
545
+ */
546
+ error: PropTypes.bool,
547
+ /**
548
+ * If `true`, the `input` of this label is focused.
549
+ */
550
+ focused: PropTypes.bool,
551
+ /**
552
+ * If `dense`, will adjust vertical spacing. This is normally obtained via context from
553
+ * FormControl.
554
+ */
555
+ margin: PropTypes.oneOf(['dense']),
556
+ /**
557
+ * if `true`, the label will indicate that the `input` is required.
558
+ */
559
+ required: PropTypes.bool,
560
+ /**
561
+ * If `true`, the label is shrunk.
562
+ */
563
+ shrink: PropTypes.bool,
564
+ /**
565
+ * The size of the component.
566
+ * @default 'normal'
567
+ */
568
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
569
+ /**
570
+ * The system prop that allows defining system overrides as well as additional CSS styles.
571
+ */
572
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
573
+ /**
574
+ * The variant to use.
575
+ */
576
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
577
+ } : void 0;
578
+ var InputLabel$1 = InputLabel;
579
+
580
+ function getFormControlUtilityClasses(slot) {
581
+ return generateUtilityClass('MuiFormControl', slot);
582
+ }
583
+ generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
584
+
585
+ const useUtilityClasses$2 = ownerState => {
586
+ const {
587
+ classes,
588
+ margin,
589
+ fullWidth
590
+ } = ownerState;
591
+ const slots = {
592
+ root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
593
+ };
594
+ return composeClasses(slots, getFormControlUtilityClasses, classes);
595
+ };
596
+ const FormControlRoot = styled$1('div', {
597
+ name: 'MuiFormControl',
598
+ slot: 'Root',
599
+ overridesResolver: (props, styles) => {
600
+ const {
601
+ ownerState
602
+ } = props;
603
+ return [styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth];
604
+ }
605
+ })({
606
+ display: 'inline-flex',
607
+ flexDirection: 'column',
608
+ position: 'relative',
609
+ // Reset fieldset default style.
610
+ minWidth: 0,
611
+ padding: 0,
612
+ margin: 0,
613
+ border: 0,
614
+ verticalAlign: 'top',
615
+ // Fix alignment issue on Safari.
616
+ variants: [{
617
+ props: {
618
+ margin: 'normal'
619
+ },
620
+ style: {
621
+ marginTop: 16,
622
+ marginBottom: 8
623
+ }
624
+ }, {
625
+ props: {
626
+ margin: 'dense'
627
+ },
628
+ style: {
629
+ marginTop: 8,
630
+ marginBottom: 4
631
+ }
632
+ }, {
633
+ props: {
634
+ fullWidth: true
635
+ },
636
+ style: {
637
+ width: '100%'
638
+ }
639
+ }]
640
+ });
641
+
642
+ /**
643
+ * Provides context such as filled/focused/error/required for form inputs.
644
+ * Relying on the context provides high flexibility and ensures that the state always stays
645
+ * consistent across the children of the `FormControl`.
646
+ * This context is used by the following components:
647
+ *
648
+ * - FormLabel
649
+ * - FormHelperText
650
+ * - Input
651
+ * - InputLabel
652
+ *
653
+ * You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
654
+ *
655
+ * ```jsx
656
+ * <FormControl>
657
+ * <InputLabel htmlFor="my-input">Email address</InputLabel>
658
+ * <Input id="my-input" aria-describedby="my-helper-text" />
659
+ * <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
660
+ * </FormControl>
661
+ * ```
662
+ *
663
+ * ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
664
+ * For instance, only one input can be focused at the same time, the state shouldn't be shared.
665
+ */
666
+ const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
667
+ const props = useDefaultProps({
668
+ props: inProps,
669
+ name: 'MuiFormControl'
670
+ });
671
+ const {
672
+ children,
673
+ className,
674
+ color = 'primary',
675
+ component = 'div',
676
+ disabled = false,
677
+ error = false,
678
+ focused: visuallyFocused,
679
+ fullWidth = false,
680
+ hiddenLabel = false,
681
+ margin = 'none',
682
+ required = false,
683
+ size = 'medium',
684
+ variant = 'outlined',
685
+ ...other
686
+ } = props;
687
+ const ownerState = {
688
+ ...props,
689
+ color,
690
+ component,
691
+ disabled,
692
+ error,
693
+ fullWidth,
694
+ hiddenLabel,
695
+ margin,
696
+ required,
697
+ size,
698
+ variant
699
+ };
700
+ const classes = useUtilityClasses$2(ownerState);
701
+ const [adornedStart, setAdornedStart] = React.useState(() => {
702
+ // We need to iterate through the children and find the Input in order
703
+ // to fully support server-side rendering.
704
+ let initialAdornedStart = false;
705
+ if (children) {
706
+ React.Children.forEach(children, child => {
707
+ if (!isMuiElement(child, ['Input', 'Select'])) {
708
+ return;
709
+ }
710
+ const input = isMuiElement(child, ['Select']) ? child.props.input : child;
711
+ if (input && isAdornedStart(input.props)) {
712
+ initialAdornedStart = true;
713
+ }
714
+ });
715
+ }
716
+ return initialAdornedStart;
717
+ });
718
+ const [filled, setFilled] = React.useState(() => {
719
+ // We need to iterate through the children and find the Input in order
720
+ // to fully support server-side rendering.
721
+ let initialFilled = false;
722
+ if (children) {
723
+ React.Children.forEach(children, child => {
724
+ if (!isMuiElement(child, ['Input', 'Select'])) {
725
+ return;
726
+ }
727
+ if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
728
+ initialFilled = true;
729
+ }
730
+ });
731
+ }
732
+ return initialFilled;
733
+ });
734
+ const [focusedState, setFocused] = React.useState(false);
735
+ if (disabled && focusedState) {
736
+ setFocused(false);
737
+ }
738
+ const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
739
+ let registerEffect;
740
+ const registeredInput = React.useRef(false);
741
+ if (process.env.NODE_ENV !== 'production') {
742
+ registerEffect = () => {
743
+ if (registeredInput.current) {
744
+ console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
745
+ }
746
+ registeredInput.current = true;
747
+ return () => {
748
+ registeredInput.current = false;
749
+ };
750
+ };
751
+ }
752
+ const onFilled = React.useCallback(() => {
753
+ setFilled(true);
754
+ }, []);
755
+ const onEmpty = React.useCallback(() => {
756
+ setFilled(false);
757
+ }, []);
758
+ const childContext = React.useMemo(() => {
759
+ return {
760
+ adornedStart,
761
+ setAdornedStart,
762
+ color,
763
+ disabled,
764
+ error,
765
+ filled,
766
+ focused,
767
+ fullWidth,
768
+ hiddenLabel,
769
+ size,
770
+ onBlur: () => {
771
+ setFocused(false);
772
+ },
773
+ onFocus: () => {
774
+ setFocused(true);
775
+ },
776
+ onEmpty,
777
+ onFilled,
778
+ registerEffect,
779
+ required,
780
+ variant
781
+ };
782
+ }, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, onEmpty, onFilled, required, size, variant]);
783
+ return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
784
+ value: childContext,
785
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, {
786
+ as: component,
787
+ ownerState: ownerState,
788
+ className: clsx(classes.root, className),
789
+ ref: ref,
790
+ ...other,
791
+ children: children
792
+ })
793
+ });
794
+ });
795
+ process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
796
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
797
+ // │ These PropTypes are generated from the TypeScript type definitions. │
798
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
799
+ // └─────────────────────────────────────────────────────────────────────┘
800
+ /**
801
+ * The content of the component.
802
+ */
803
+ children: PropTypes.node,
804
+ /**
805
+ * Override or extend the styles applied to the component.
806
+ */
807
+ classes: PropTypes.object,
808
+ /**
809
+ * @ignore
810
+ */
811
+ className: PropTypes.string,
812
+ /**
813
+ * The color of the component.
814
+ * It supports both default and custom theme colors, which can be added as shown in the
815
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
816
+ * @default 'primary'
817
+ */
818
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
819
+ /**
820
+ * The component used for the root node.
821
+ * Either a string to use a HTML element or a component.
822
+ */
823
+ component: PropTypes.elementType,
824
+ /**
825
+ * If `true`, the label, input and helper text should be displayed in a disabled state.
826
+ * @default false
827
+ */
828
+ disabled: PropTypes.bool,
829
+ /**
830
+ * If `true`, the label is displayed in an error state.
831
+ * @default false
832
+ */
833
+ error: PropTypes.bool,
834
+ /**
835
+ * If `true`, the component is displayed in focused state.
836
+ */
837
+ focused: PropTypes.bool,
838
+ /**
839
+ * If `true`, the component will take up the full width of its container.
840
+ * @default false
841
+ */
842
+ fullWidth: PropTypes.bool,
843
+ /**
844
+ * If `true`, the label is hidden.
845
+ * This is used to increase density for a `FilledInput`.
846
+ * Be sure to add `aria-label` to the `input` element.
847
+ * @default false
848
+ */
849
+ hiddenLabel: PropTypes.bool,
850
+ /**
851
+ * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
852
+ * @default 'none'
853
+ */
854
+ margin: PropTypes.oneOf(['dense', 'none', 'normal']),
855
+ /**
856
+ * If `true`, the label will indicate that the `input` is required.
857
+ * @default false
858
+ */
859
+ required: PropTypes.bool,
860
+ /**
861
+ * The size of the component.
862
+ * @default 'medium'
863
+ */
864
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
865
+ /**
866
+ * The system prop that allows defining system overrides as well as additional CSS styles.
867
+ */
868
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
869
+ /**
870
+ * The variant to use.
871
+ * @default 'outlined'
872
+ */
873
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
874
+ } : void 0;
875
+ var FormControl$1 = FormControl;
876
+
877
+ function getFormHelperTextUtilityClasses(slot) {
878
+ return generateUtilityClass('MuiFormHelperText', slot);
879
+ }
880
+ const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
881
+ var formHelperTextClasses$1 = formHelperTextClasses;
882
+
883
+ var _span;
884
+ const useUtilityClasses$1 = ownerState => {
885
+ const {
886
+ classes,
887
+ contained,
888
+ size,
889
+ disabled,
890
+ error,
891
+ filled,
892
+ focused,
893
+ required
894
+ } = ownerState;
895
+ const slots = {
896
+ root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
897
+ };
898
+ return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
899
+ };
900
+ const FormHelperTextRoot = styled$1('p', {
901
+ name: 'MuiFormHelperText',
902
+ slot: 'Root',
903
+ overridesResolver: (props, styles) => {
904
+ const {
905
+ ownerState
906
+ } = props;
907
+ return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
908
+ }
909
+ })(memoTheme(({
910
+ theme
911
+ }) => ({
912
+ color: (theme.vars || theme).palette.text.secondary,
913
+ ...theme.typography.caption,
914
+ textAlign: 'left',
915
+ marginTop: 3,
916
+ marginRight: 0,
917
+ marginBottom: 0,
918
+ marginLeft: 0,
919
+ [`&.${formHelperTextClasses$1.disabled}`]: {
920
+ color: (theme.vars || theme).palette.text.disabled
921
+ },
922
+ [`&.${formHelperTextClasses$1.error}`]: {
923
+ color: (theme.vars || theme).palette.error.main
924
+ },
925
+ variants: [{
926
+ props: {
927
+ size: 'small'
928
+ },
929
+ style: {
930
+ marginTop: 4
931
+ }
932
+ }, {
933
+ props: ({
934
+ ownerState
935
+ }) => ownerState.contained,
936
+ style: {
937
+ marginLeft: 14,
938
+ marginRight: 14
939
+ }
940
+ }]
941
+ })));
942
+ const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
943
+ const props = useDefaultProps({
944
+ props: inProps,
945
+ name: 'MuiFormHelperText'
946
+ });
947
+ const {
948
+ children,
949
+ className,
950
+ component = 'p',
951
+ disabled,
952
+ error,
953
+ filled,
954
+ focused,
955
+ margin,
956
+ required,
957
+ variant,
958
+ ...other
959
+ } = props;
960
+ const muiFormControl = useFormControl();
961
+ const fcs = formControlState({
962
+ props,
963
+ muiFormControl,
964
+ states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
965
+ });
966
+ const ownerState = {
967
+ ...props,
968
+ component,
969
+ contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
970
+ variant: fcs.variant,
971
+ size: fcs.size,
972
+ disabled: fcs.disabled,
973
+ error: fcs.error,
974
+ filled: fcs.filled,
975
+ focused: fcs.focused,
976
+ required: fcs.required
977
+ };
978
+
979
+ // This issue explains why this is required: https://github.com/mui/material-ui/issues/42184
980
+ delete ownerState.ownerState;
981
+ const classes = useUtilityClasses$1(ownerState);
982
+ return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, {
983
+ as: component,
984
+ className: clsx(classes.root, className),
985
+ ref: ref,
986
+ ...other,
987
+ ownerState: ownerState,
988
+ children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
989
+ _span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
990
+ className: "notranslate",
991
+ "aria-hidden": true,
992
+ children: "\u200B"
993
+ })) : children
994
+ });
995
+ });
996
+ process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
997
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
998
+ // │ These PropTypes are generated from the TypeScript type definitions. │
999
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
1000
+ // └─────────────────────────────────────────────────────────────────────┘
1001
+ /**
1002
+ * The content of the component.
1003
+ *
1004
+ * If `' '` is provided, the component reserves one line height for displaying a future message.
1005
+ */
1006
+ children: PropTypes.node,
1007
+ /**
1008
+ * Override or extend the styles applied to the component.
1009
+ */
1010
+ classes: PropTypes.object,
1011
+ /**
1012
+ * @ignore
1013
+ */
1014
+ className: PropTypes.string,
1015
+ /**
1016
+ * The component used for the root node.
1017
+ * Either a string to use a HTML element or a component.
1018
+ */
1019
+ component: PropTypes.elementType,
1020
+ /**
1021
+ * If `true`, the helper text should be displayed in a disabled state.
1022
+ */
1023
+ disabled: PropTypes.bool,
1024
+ /**
1025
+ * If `true`, helper text should be displayed in an error state.
1026
+ */
1027
+ error: PropTypes.bool,
1028
+ /**
1029
+ * If `true`, the helper text should use filled classes key.
1030
+ */
1031
+ filled: PropTypes.bool,
1032
+ /**
1033
+ * If `true`, the helper text should use focused classes key.
1034
+ */
1035
+ focused: PropTypes.bool,
1036
+ /**
1037
+ * If `dense`, will adjust vertical spacing. This is normally obtained via context from
1038
+ * FormControl.
1039
+ */
1040
+ margin: PropTypes.oneOf(['dense']),
1041
+ /**
1042
+ * If `true`, the helper text should use required classes key.
1043
+ */
1044
+ required: PropTypes.bool,
1045
+ /**
1046
+ * The system prop that allows defining system overrides as well as additional CSS styles.
1047
+ */
1048
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1049
+ /**
1050
+ * The variant to use.
1051
+ */
1052
+ variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
1053
+ } : void 0;
1054
+ var FormHelperText$1 = FormHelperText;
1055
+
1056
+ function getTextFieldUtilityClass(slot) {
1057
+ return generateUtilityClass('MuiTextField', slot);
1058
+ }
1059
+ generateUtilityClasses('MuiTextField', ['root']);
1060
+
1061
+ const variantComponent = {
1062
+ standard: Input,
1063
+ filled: FilledInput,
1064
+ outlined: OutlinedInput
1065
+ };
1066
+ const useUtilityClasses = ownerState => {
1067
+ const {
1068
+ classes
1069
+ } = ownerState;
1070
+ const slots = {
1071
+ root: ['root']
1072
+ };
1073
+ return composeClasses(slots, getTextFieldUtilityClass, classes);
1074
+ };
1075
+ const TextFieldRoot = styled$1(FormControl$1, {
1076
+ name: 'MuiTextField',
1077
+ slot: 'Root',
1078
+ overridesResolver: (props, styles) => styles.root
1079
+ })({});
1080
+
1081
+ /**
1082
+ * The `TextField` is a convenience wrapper for the most common cases (80%).
1083
+ * It cannot be all things to all people, otherwise the API would grow out of control.
1084
+ *
1085
+ * ## Advanced Configuration
1086
+ *
1087
+ * It's important to understand that the text field is a simple abstraction
1088
+ * on top of the following components:
1089
+ *
1090
+ * - [FormControl](/material-ui/api/form-control/)
1091
+ * - [InputLabel](/material-ui/api/input-label/)
1092
+ * - [FilledInput](/material-ui/api/filled-input/)
1093
+ * - [OutlinedInput](/material-ui/api/outlined-input/)
1094
+ * - [Input](/material-ui/api/input/)
1095
+ * - [FormHelperText](/material-ui/api/form-helper-text/)
1096
+ *
1097
+ * If you wish to alter the props applied to the `input` element, you can do so as follows:
1098
+ *
1099
+ * ```jsx
1100
+ * const inputProps = {
1101
+ * step: 300,
1102
+ * };
1103
+ *
1104
+ * return <TextField id="time" type="time" inputProps={inputProps} />;
1105
+ * ```
1106
+ *
1107
+ * For advanced cases, please look at the source of TextField by clicking on the
1108
+ * "Edit this page" button above. Consider either:
1109
+ *
1110
+ * - using the upper case props for passing values directly to the components
1111
+ * - using the underlying components directly as shown in the demos
1112
+ */
1113
+ const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
1114
+ const props = useDefaultProps({
1115
+ props: inProps,
1116
+ name: 'MuiTextField'
1117
+ });
1118
+ const {
1119
+ autoComplete,
1120
+ autoFocus = false,
1121
+ children,
1122
+ className,
1123
+ color = 'primary',
1124
+ defaultValue,
1125
+ disabled = false,
1126
+ error = false,
1127
+ FormHelperTextProps: FormHelperTextPropsProp,
1128
+ fullWidth = false,
1129
+ helperText,
1130
+ id: idOverride,
1131
+ InputLabelProps: InputLabelPropsProp,
1132
+ inputProps: inputPropsProp,
1133
+ InputProps: InputPropsProp,
1134
+ inputRef,
1135
+ label,
1136
+ maxRows,
1137
+ minRows,
1138
+ multiline = false,
1139
+ name,
1140
+ onBlur,
1141
+ onChange,
1142
+ onFocus,
1143
+ placeholder,
1144
+ required = false,
1145
+ rows,
1146
+ select = false,
1147
+ SelectProps: SelectPropsProp,
1148
+ slots = {},
1149
+ slotProps = {},
1150
+ type,
1151
+ value,
1152
+ variant = 'outlined',
1153
+ ...other
1154
+ } = props;
1155
+ const ownerState = {
1156
+ ...props,
1157
+ autoFocus,
1158
+ color,
1159
+ disabled,
1160
+ error,
1161
+ fullWidth,
1162
+ multiline,
1163
+ required,
1164
+ select,
1165
+ variant
1166
+ };
1167
+ const classes = useUtilityClasses(ownerState);
1168
+ if (process.env.NODE_ENV !== 'production') {
1169
+ if (select && !children) {
1170
+ console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
1171
+ }
1172
+ }
1173
+ const id = useId(idOverride);
1174
+ const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
1175
+ const inputLabelId = label && id ? `${id}-label` : undefined;
1176
+ const InputComponent = variantComponent[variant];
1177
+ const externalForwardedProps = {
1178
+ slots,
1179
+ slotProps: {
1180
+ input: InputPropsProp,
1181
+ inputLabel: InputLabelPropsProp,
1182
+ htmlInput: inputPropsProp,
1183
+ formHelperText: FormHelperTextPropsProp,
1184
+ select: SelectPropsProp,
1185
+ ...slotProps
1186
+ }
1187
+ };
1188
+ const inputAdditionalProps = {};
1189
+ const inputLabelSlotProps = externalForwardedProps.slotProps.inputLabel;
1190
+ if (variant === 'outlined') {
1191
+ if (inputLabelSlotProps && typeof inputLabelSlotProps.shrink !== 'undefined') {
1192
+ inputAdditionalProps.notched = inputLabelSlotProps.shrink;
1193
+ }
1194
+ inputAdditionalProps.label = label;
1195
+ }
1196
+ if (select) {
1197
+ // unset defaults from textbox inputs
1198
+ if (!SelectPropsProp || !SelectPropsProp.native) {
1199
+ inputAdditionalProps.id = undefined;
1200
+ }
1201
+ inputAdditionalProps['aria-describedby'] = undefined;
1202
+ }
1203
+ const [RootSlot, rootProps] = useSlot('root', {
1204
+ elementType: TextFieldRoot,
1205
+ shouldForwardComponentProp: true,
1206
+ externalForwardedProps: {
1207
+ ...externalForwardedProps,
1208
+ ...other
1209
+ },
1210
+ ownerState,
1211
+ className: clsx(classes.root, className),
1212
+ ref,
1213
+ additionalProps: {
1214
+ disabled,
1215
+ error,
1216
+ fullWidth,
1217
+ required,
1218
+ color,
1219
+ variant
1220
+ }
1221
+ });
1222
+ const [InputSlot, inputProps] = useSlot('input', {
1223
+ elementType: InputComponent,
1224
+ externalForwardedProps,
1225
+ additionalProps: inputAdditionalProps,
1226
+ ownerState
1227
+ });
1228
+ const [InputLabelSlot, inputLabelProps] = useSlot('inputLabel', {
1229
+ elementType: InputLabel$1,
1230
+ externalForwardedProps,
1231
+ ownerState
1232
+ });
1233
+ const [HtmlInputSlot, htmlInputProps] = useSlot('htmlInput', {
1234
+ elementType: 'input',
1235
+ externalForwardedProps,
1236
+ ownerState
1237
+ });
1238
+ const [FormHelperTextSlot, formHelperTextProps] = useSlot('formHelperText', {
1239
+ elementType: FormHelperText$1,
1240
+ externalForwardedProps,
1241
+ ownerState
1242
+ });
1243
+ const [SelectSlot, selectProps] = useSlot('select', {
1244
+ elementType: Select,
1245
+ externalForwardedProps,
1246
+ ownerState
1247
+ });
1248
+ const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputSlot, {
1249
+ "aria-describedby": helperTextId,
1250
+ autoComplete: autoComplete,
1251
+ autoFocus: autoFocus,
1252
+ defaultValue: defaultValue,
1253
+ fullWidth: fullWidth,
1254
+ multiline: multiline,
1255
+ name: name,
1256
+ rows: rows,
1257
+ maxRows: maxRows,
1258
+ minRows: minRows,
1259
+ type: type,
1260
+ value: value,
1261
+ id: id,
1262
+ inputRef: inputRef,
1263
+ onBlur: onBlur,
1264
+ onChange: onChange,
1265
+ onFocus: onFocus,
1266
+ placeholder: placeholder,
1267
+ inputProps: htmlInputProps,
1268
+ slots: {
1269
+ input: slots.htmlInput ? HtmlInputSlot : undefined
1270
+ },
1271
+ ...inputProps
1272
+ });
1273
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(RootSlot, {
1274
+ ...rootProps,
1275
+ children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelSlot, {
1276
+ htmlFor: id,
1277
+ id: inputLabelId,
1278
+ ...inputLabelProps,
1279
+ children: label
1280
+ }), select ? /*#__PURE__*/jsxRuntimeExports.jsx(SelectSlot, {
1281
+ "aria-describedby": helperTextId,
1282
+ id: id,
1283
+ labelId: inputLabelId,
1284
+ value: value,
1285
+ input: InputElement,
1286
+ ...selectProps,
1287
+ children: children
1288
+ }) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextSlot, {
1289
+ id: helperTextId,
1290
+ ...formHelperTextProps,
1291
+ children: helperText
1292
+ })]
1293
+ });
1294
+ });
1295
+ process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
1296
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
1297
+ // │ These PropTypes are generated from the TypeScript type definitions. │
1298
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
1299
+ // └─────────────────────────────────────────────────────────────────────┘
1300
+ /**
1301
+ * This prop helps users to fill forms faster, especially on mobile devices.
1302
+ * The name can be confusing, as it's more like an autofill.
1303
+ * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
1304
+ */
1305
+ autoComplete: PropTypes.string,
1306
+ /**
1307
+ * If `true`, the `input` element is focused during the first mount.
1308
+ * @default false
1309
+ */
1310
+ autoFocus: PropTypes.bool,
1311
+ /**
1312
+ * @ignore
1313
+ */
1314
+ children: PropTypes.node,
1315
+ /**
1316
+ * Override or extend the styles applied to the component.
1317
+ */
1318
+ classes: PropTypes.object,
1319
+ /**
1320
+ * @ignore
1321
+ */
1322
+ className: PropTypes.string,
1323
+ /**
1324
+ * The color of the component.
1325
+ * It supports both default and custom theme colors, which can be added as shown in the
1326
+ * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
1327
+ * @default 'primary'
1328
+ */
1329
+ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
1330
+ /**
1331
+ * The default value. Use when the component is not controlled.
1332
+ */
1333
+ defaultValue: PropTypes.any,
1334
+ /**
1335
+ * If `true`, the component is disabled.
1336
+ * @default false
1337
+ */
1338
+ disabled: PropTypes.bool,
1339
+ /**
1340
+ * If `true`, the label is displayed in an error state.
1341
+ * @default false
1342
+ */
1343
+ error: PropTypes.bool,
1344
+ /**
1345
+ * Props applied to the [`FormHelperText`](https://mui.com/material-ui/api/form-helper-text/) element.
1346
+ * @deprecated Use `slotProps.formHelperText` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1347
+ */
1348
+ FormHelperTextProps: PropTypes.object,
1349
+ /**
1350
+ * If `true`, the input will take up the full width of its container.
1351
+ * @default false
1352
+ */
1353
+ fullWidth: PropTypes.bool,
1354
+ /**
1355
+ * The helper text content.
1356
+ */
1357
+ helperText: PropTypes.node,
1358
+ /**
1359
+ * The id of the `input` element.
1360
+ * Use this prop to make `label` and `helperText` accessible for screen readers.
1361
+ */
1362
+ id: PropTypes.string,
1363
+ /**
1364
+ * Props applied to the [`InputLabel`](https://mui.com/material-ui/api/input-label/) element.
1365
+ * Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
1366
+ * @deprecated Use `slotProps.inputLabel` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1367
+ */
1368
+ InputLabelProps: PropTypes.object,
1369
+ /**
1370
+ * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
1371
+ * @deprecated Use `slotProps.htmlInput` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1372
+ */
1373
+ inputProps: PropTypes.object,
1374
+ /**
1375
+ * Props applied to the Input element.
1376
+ * It will be a [`FilledInput`](https://mui.com/material-ui/api/filled-input/),
1377
+ * [`OutlinedInput`](https://mui.com/material-ui/api/outlined-input/) or [`Input`](https://mui.com/material-ui/api/input/)
1378
+ * component depending on the `variant` prop value.
1379
+ * @deprecated Use `slotProps.input` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1380
+ */
1381
+ InputProps: PropTypes.object,
1382
+ /**
1383
+ * Pass a ref to the `input` element.
1384
+ */
1385
+ inputRef: refType,
1386
+ /**
1387
+ * The label content.
1388
+ */
1389
+ label: PropTypes.node,
1390
+ /**
1391
+ * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
1392
+ * @default 'none'
1393
+ */
1394
+ margin: PropTypes.oneOf(['dense', 'none', 'normal']),
1395
+ /**
1396
+ * Maximum number of rows to display when multiline option is set to true.
1397
+ */
1398
+ maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1399
+ /**
1400
+ * Minimum number of rows to display when multiline option is set to true.
1401
+ */
1402
+ minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1403
+ /**
1404
+ * If `true`, a `textarea` element is rendered instead of an input.
1405
+ * @default false
1406
+ */
1407
+ multiline: PropTypes.bool,
1408
+ /**
1409
+ * Name attribute of the `input` element.
1410
+ */
1411
+ name: PropTypes.string,
1412
+ /**
1413
+ * @ignore
1414
+ */
1415
+ onBlur: PropTypes.func,
1416
+ /**
1417
+ * Callback fired when the value is changed.
1418
+ *
1419
+ * @param {object} event The event source of the callback.
1420
+ * You can pull out the new value by accessing `event.target.value` (string).
1421
+ */
1422
+ onChange: PropTypes.func,
1423
+ /**
1424
+ * @ignore
1425
+ */
1426
+ onFocus: PropTypes.func,
1427
+ /**
1428
+ * The short hint displayed in the `input` before the user enters a value.
1429
+ */
1430
+ placeholder: PropTypes.string,
1431
+ /**
1432
+ * If `true`, the label is displayed as required and the `input` element is required.
1433
+ * @default false
1434
+ */
1435
+ required: PropTypes.bool,
1436
+ /**
1437
+ * Number of rows to display when multiline option is set to true.
1438
+ */
1439
+ rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1440
+ /**
1441
+ * Render a [`Select`](https://mui.com/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
1442
+ * If this option is set you must pass the options of the select as children.
1443
+ * @default false
1444
+ */
1445
+ select: PropTypes.bool,
1446
+ /**
1447
+ * Props applied to the [`Select`](https://mui.com/material-ui/api/select/) element.
1448
+ * @deprecated Use `slotProps.select` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1449
+ */
1450
+ SelectProps: PropTypes.object,
1451
+ /**
1452
+ * The size of the component.
1453
+ * @default 'medium'
1454
+ */
1455
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
1456
+ /**
1457
+ * The props used for each slot inside.
1458
+ * @default {}
1459
+ */
1460
+ slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
1461
+ formHelperText: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1462
+ htmlInput: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1463
+ input: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1464
+ inputLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1465
+ select: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
1466
+ }),
1467
+ /**
1468
+ * The components used for each slot inside.
1469
+ * @default {}
1470
+ */
1471
+ slots: PropTypes.shape({
1472
+ formHelperText: PropTypes.elementType,
1473
+ htmlInput: PropTypes.elementType,
1474
+ input: PropTypes.elementType,
1475
+ inputLabel: PropTypes.elementType,
1476
+ root: PropTypes.elementType,
1477
+ select: PropTypes.elementType
1478
+ }),
1479
+ /**
1480
+ * The system prop that allows defining system overrides as well as additional CSS styles.
1481
+ */
1482
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1483
+ /**
1484
+ * 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).
1485
+ */
1486
+ type: PropTypes /* @typescript-to-proptypes-ignore */.string,
1487
+ /**
1488
+ * The value of the `input` element, required for a controlled component.
1489
+ */
1490
+ value: PropTypes.any,
1491
+ /**
1492
+ * The variant to use.
1493
+ * @default 'outlined'
1494
+ */
1495
+ variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
1496
+ } : void 0;
1497
+ var TextField$1 = TextField;
15
1498
 
16
1499
  const SUBMIT_FILTER_STROKE_TIME = 500;
17
1500
  const InputNumberInterval = props => {
@@ -53,7 +1536,7 @@ const InputNumberInterval = props => {
53
1536
  const newLowerBound = event.target.value;
54
1537
  updateFilterValue(newLowerBound, filterValueState[1]);
55
1538
  };
56
- return /*#__PURE__*/React.createElement(Box, {
1539
+ return /*#__PURE__*/React.createElement(Box$1, {
57
1540
  sx: {
58
1541
  display: 'inline-flex',
59
1542
  flexDirection: 'row',
@@ -61,7 +1544,7 @@ const InputNumberInterval = props => {
61
1544
  height: 48,
62
1545
  pl: '20px'
63
1546
  }
64
- }, /*#__PURE__*/React.createElement(TextField, {
1547
+ }, /*#__PURE__*/React.createElement(TextField$1, {
65
1548
  name: "lower-bound-input",
66
1549
  placeholder: "From",
67
1550
  label: "From",
@@ -73,7 +1556,7 @@ const InputNumberInterval = props => {
73
1556
  sx: {
74
1557
  mr: 2
75
1558
  }
76
- }), /*#__PURE__*/React.createElement(TextField, {
1559
+ }), /*#__PURE__*/React.createElement(TextField$1, {
77
1560
  name: "upper-bound-input",
78
1561
  placeholder: "To",
79
1562
  label: "To",
@@ -700,7 +2183,8 @@ const VISIBILITY_MODEL_KEY = 'visibilityModel';
700
2183
  const PINNED_COLUMNS = 'pinnedColumns';
701
2184
  const DIMENSION_MODEL_KEY = 'dimension';
702
2185
  const FILTER_SEARCH_KEY = 'searchModel';
703
- const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS];
2186
+ const DENSITY_MODEL_KEY = 'densityModel';
2187
+ 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];
704
2188
  const buildStorageKey = _ref => {
705
2189
  let {
706
2190
  id,
@@ -739,6 +2223,10 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
739
2223
  id,
740
2224
  version,
741
2225
  category: DIMENSION_MODEL_KEY
2226
+ }), buildStorageKey({
2227
+ id,
2228
+ version,
2229
+ category: DENSITY_MODEL_KEY
742
2230
  })];
743
2231
  for (const keyToDelete of keysToDelete) {
744
2232
  try {
@@ -1156,16 +2644,11 @@ const isValueValid = (value, field, columns, operator) => {
1156
2644
  }
1157
2645
  const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
1158
2646
 
1159
- // Only date and rating fail with 500s, other set themselves as undefined
1160
- if (type !== 'date' && type !== 'rating') {
2647
+ // Only date fails with 500s, other set themselves as undefined
2648
+ if (type !== 'date') {
1161
2649
  return true;
1162
2650
  }
1163
2651
 
1164
- // just checking that rating is a number.
1165
- if (type === 'rating') {
1166
- return !isNaN(Number(value));
1167
- }
1168
-
1169
2652
  // format: YYYY-MM-DD
1170
2653
  // just verifying that the 3 values are numbers to avoid 500s,
1171
2654
  // If the value is invalid the form will appear as undefined
@@ -1291,7 +2774,17 @@ const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFil
1291
2774
  items: [],
1292
2775
  logicOperator: GridLogicOperator.And
1293
2776
  };
2777
+
2778
+ // Persist initialState-derived filters to localStorage so all three sources stay in sync
2779
+ const persistDefaultFilters = () => {
2780
+ const searchFromDefault = getSearchParamsFromFilterModel(defaultValue);
2781
+ const searchString = urlSearchParamsToString(searchFromDefault);
2782
+ if (searchString !== localStorageFilters) {
2783
+ setLocalStorageFilters(searchString);
2784
+ }
2785
+ };
1294
2786
  if (isNewVersion) {
2787
+ persistDefaultFilters();
1295
2788
  return defaultValue;
1296
2789
  }
1297
2790
  const filterModelFromSearch = getFilterModelFromString(search, columns);
@@ -1307,6 +2800,7 @@ const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFil
1307
2800
  if (filterModelFromLocalStorage !== 'invalid') {
1308
2801
  return filterModelFromLocalStorage;
1309
2802
  }
2803
+ persistDefaultFilters();
1310
2804
  return defaultValue;
1311
2805
  };
1312
2806
 
@@ -1344,7 +2838,17 @@ const getSearchParamsFromSorting = sorting => {
1344
2838
  const getSortModel = (search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion) => {
1345
2839
  var _initialState$sorting;
1346
2840
  const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$sorting = initialState.sorting) !== null && _initialState$sorting !== void 0 && _initialState$sorting.sortModel ? initialState.sorting.sortModel : [];
2841
+
2842
+ // Persist initialState-derived sorting to localStorage so all three sources stay in sync
2843
+ const persistDefaultSort = () => {
2844
+ const searchFromDefault = getSearchParamsFromSorting(defaultValue);
2845
+ const searchString = urlSearchParamsToString(searchFromDefault);
2846
+ if (searchString !== localStorageSorting) {
2847
+ setLocalStorageSorting(searchString);
2848
+ }
2849
+ };
1347
2850
  if (isNewVersion) {
2851
+ persistDefaultSort();
1348
2852
  return defaultValue;
1349
2853
  }
1350
2854
  const sorting = getSortingFromString(search, columns);
@@ -1360,6 +2864,7 @@ const getSortModel = (search, columns, localStorageSorting, setLocalStorageSorti
1360
2864
  if (sortModelFromLocalStorage !== 'invalid') {
1361
2865
  return sortModelFromLocalStorage;
1362
2866
  }
2867
+ persistDefaultSort();
1363
2868
  return defaultValue;
1364
2869
  };
1365
2870
 
@@ -1398,16 +2903,25 @@ const getSearchParamsFromPagination = pagination => {
1398
2903
  // - if we don't have that, use the localStorage and update the URL
1399
2904
  // - if we don't have that, return an empty PaginationModel
1400
2905
  const getPaginationModel = (search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion) => {
1401
- const defaultValue = initialState !== null && initialState !== void 0 && initialState.pagination ? _objectSpread2({
2906
+ var _initialState$paginat, _initialState$paginat2, _initialState$paginat3;
2907
+ // Extract pageSize from MUI's nested format: initialState.pagination.paginationModel.pageSize
2908
+ const initialPageSize = (_initialState$paginat = initialState === null || initialState === void 0 ? void 0 : (_initialState$paginat2 = initialState.pagination) === null || _initialState$paginat2 === void 0 ? void 0 : (_initialState$paginat3 = _initialState$paginat2.paginationModel) === null || _initialState$paginat3 === void 0 ? void 0 : _initialState$paginat3.pageSize) !== null && _initialState$paginat !== void 0 ? _initialState$paginat : 25;
2909
+ const defaultValue = {
1402
2910
  page: 0,
1403
- pageSize: 25,
1404
- direction: 'next'
1405
- }, initialState.pagination) : {
1406
- page: 0,
1407
- pageSize: 25,
2911
+ pageSize: initialPageSize,
1408
2912
  direction: 'next'
1409
2913
  };
2914
+
2915
+ // Persist initialState-derived pagination to localStorage so all three sources stay in sync
2916
+ const persistDefaultPagination = () => {
2917
+ const searchFromDefault = getSearchParamsFromPagination(defaultValue);
2918
+ const searchString = urlSearchParamsToString(searchFromDefault);
2919
+ if (searchString !== localStoragePagination) {
2920
+ setLocalStoragePagination(searchString);
2921
+ }
2922
+ };
1410
2923
  if (isNewVersion) {
2924
+ persistDefaultPagination();
1411
2925
  return defaultValue;
1412
2926
  }
1413
2927
  const pagination = getPaginationFromString(search);
@@ -1423,6 +2937,7 @@ const getPaginationModel = (search, localStoragePagination, setLocalStoragePagin
1423
2937
  if (paginationModelFromLocalStorage !== 'invalid') {
1424
2938
  return paginationModelFromLocalStorage;
1425
2939
  }
2940
+ persistDefaultPagination();
1426
2941
  return defaultValue;
1427
2942
  };
1428
2943
 
@@ -1494,7 +3009,15 @@ const getColumnsVisibility = (search, columns, localStorageColumnsVisibility, se
1494
3009
  }
1495
3010
  }
1496
3011
 
3012
+ // Persist initialState-derived column visibility to localStorage so all three sources stay in sync
3013
+ const persistDefaultVisibility = value => {
3014
+ const searchFromDefault = getSearchParamsFromColumnVisibility(value, columns);
3015
+ if (searchFromDefault.toString() !== localStorageColumnsVisibility) {
3016
+ setLocalStorageColumnsVisibility(searchFromDefault.toString());
3017
+ }
3018
+ };
1497
3019
  if (isNewVersion) {
3020
+ persistDefaultVisibility(defaultValue);
1498
3021
  return defaultValue;
1499
3022
  }
1500
3023
  const columnVisibility = getColumnVisibilityFromString(search, columns);
@@ -1510,8 +3033,10 @@ const getColumnsVisibility = (search, columns, localStorageColumnsVisibility, se
1510
3033
  return columnVisibilityFromLocalStorage;
1511
3034
  }
1512
3035
  if (initialState !== null && initialState !== void 0 && (_initialState$columns3 = initialState.columns) !== null && _initialState$columns3 !== void 0 && _initialState$columns3.columnVisibilityModel) {
3036
+ persistDefaultVisibility(initialState.columns.columnVisibilityModel);
1513
3037
  return initialState.columns.columnVisibilityModel;
1514
3038
  }
3039
+ persistDefaultVisibility(defaultValue);
1515
3040
  return defaultValue;
1516
3041
  };
1517
3042
  const getPinnedColumnsFromString = (notParsed, tableColumns) => {
@@ -1595,6 +3120,58 @@ const getSearchParamsFromTab = search => {
1595
3120
  }
1596
3121
  return searchParams;
1597
3122
  };
3123
+
3124
+ /** DENSITY */
3125
+
3126
+ const VALID_DENSITIES = ['compact', 'standard', 'comfortable'];
3127
+ const getDensityFromString = searchString => {
3128
+ if (!searchString) {
3129
+ return 'invalid';
3130
+ }
3131
+ const searchParams = new URLSearchParams(searchString);
3132
+ const value = searchParams.get('_density');
3133
+ if (value && VALID_DENSITIES.includes(value)) {
3134
+ return value;
3135
+ }
3136
+ return 'invalid';
3137
+ };
3138
+ const getSearchParamsFromDensity = density => {
3139
+ const searchParams = new URLSearchParams();
3140
+ searchParams.set('_density', density);
3141
+ return searchParams;
3142
+ };
3143
+ const getDensityModel = (search, localStorageDensity, setLocalStorageDensity, _initialState, isNewVersion) => {
3144
+ // Default to 'compact' when no density is provided via URL, localStorage, or initialState
3145
+ const defaultValue = 'compact';
3146
+
3147
+ // Persist initialState-derived density to localStorage so all three sources stay in sync
3148
+ const persistDefaultDensity = () => {
3149
+ const searchFromDefault = getSearchParamsFromDensity(defaultValue);
3150
+ const searchString = urlSearchParamsToString(searchFromDefault);
3151
+ if (searchString !== localStorageDensity) {
3152
+ setLocalStorageDensity(searchString);
3153
+ }
3154
+ };
3155
+ if (isNewVersion) {
3156
+ persistDefaultDensity();
3157
+ return defaultValue;
3158
+ }
3159
+ const density = getDensityFromString(search);
3160
+ if (density !== 'invalid') {
3161
+ const searchFromDensity = getSearchParamsFromDensity(density);
3162
+ const searchString = urlSearchParamsToString(searchFromDensity);
3163
+ if (searchString !== localStorageDensity) {
3164
+ setLocalStorageDensity(searchString);
3165
+ }
3166
+ return density;
3167
+ }
3168
+ const densityFromLocalStorage = getDensityFromString(localStorageDensity);
3169
+ if (densityFromLocalStorage !== 'invalid') {
3170
+ return densityFromLocalStorage;
3171
+ }
3172
+ persistDefaultDensity();
3173
+ return defaultValue;
3174
+ };
1598
3175
  const getFinalSearch = _ref => {
1599
3176
  let {
1600
3177
  search,
@@ -1604,6 +3181,7 @@ const getFinalSearch = _ref => {
1604
3181
  paginationModel,
1605
3182
  columnsVisibilityModel,
1606
3183
  pinnedColumnsModel,
3184
+ density,
1607
3185
  columns
1608
3186
  } = _ref;
1609
3187
  const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
@@ -1611,6 +3189,7 @@ const getFinalSearch = _ref => {
1611
3189
  const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
1612
3190
  const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
1613
3191
  const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
3192
+ const densitySearch = getSearchParamsFromDensity(density);
1614
3193
  const tabSearch = getSearchParamsFromTab(search);
1615
3194
  const searchParams = new URLSearchParams();
1616
3195
  for (const [key, value] of new URLSearchParams(search)) {
@@ -1625,7 +3204,7 @@ const getFinalSearch = _ref => {
1625
3204
  // Encode array as JSON string to preserve all values in one param
1626
3205
  searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
1627
3206
  }
1628
- return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch]);
3207
+ return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch]);
1629
3208
  };
1630
3209
  /** Return the state of the table given the URL and the local storage state */
1631
3210
  const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage) => {
@@ -1643,13 +3222,16 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
1643
3222
  localStorageColumnsVisibility,
1644
3223
  setLocalStorageColumnsVisibility,
1645
3224
  localStoragePinnedColumns,
1646
- setLocalStoragePinnedColumns
3225
+ setLocalStoragePinnedColumns,
3226
+ localStorageDensity,
3227
+ setLocalStorageDensity
1647
3228
  } = localStorage;
1648
3229
  const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
1649
3230
  const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
1650
3231
  const paginationModel = getPaginationModel(decodedSearch, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
1651
3232
  const columnVisibilityModel = getColumnsVisibility(decodedSearch, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
1652
3233
  const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
3234
+ const density = getDensityModel(decodedSearch, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion);
1653
3235
  const finalSearch = getFinalSearch({
1654
3236
  localStorageVersion,
1655
3237
  search: decodedSearch,
@@ -1658,6 +3240,7 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
1658
3240
  paginationModel,
1659
3241
  columnsVisibilityModel: columnVisibilityModel,
1660
3242
  pinnedColumnsModel,
3243
+ density,
1661
3244
  columns
1662
3245
  });
1663
3246
  const internalSearchString = urlSearchParamsToString(finalSearch);
@@ -1674,6 +3257,7 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
1674
3257
  paginationModel,
1675
3258
  columnVisibilityModel,
1676
3259
  pinnedColumnsModel,
3260
+ density,
1677
3261
  pendingSearch
1678
3262
  };
1679
3263
  };
@@ -1683,7 +3267,8 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
1683
3267
  sortModel,
1684
3268
  paginationModel,
1685
3269
  columnsModel: columnsVisibilityModel,
1686
- pinnedColumnsModel
3270
+ pinnedColumnsModel,
3271
+ density
1687
3272
  } = _ref2;
1688
3273
  // Convert from display format to internal format if needed
1689
3274
  const decodedSearch = getDecodedSearchFromUrl(search, columns);
@@ -1695,6 +3280,7 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
1695
3280
  paginationModel,
1696
3281
  columnsVisibilityModel,
1697
3282
  pinnedColumnsModel,
3283
+ density,
1698
3284
  columns
1699
3285
  });
1700
3286
  const internalSearchString = urlSearchParamsToString(newSearch);
@@ -1818,6 +3404,11 @@ const useTableStates = (id, version) => {
1818
3404
  version,
1819
3405
  category: DIMENSION_MODEL_KEY
1820
3406
  }));
3407
+ const [densityModel, setDensityModel] = useFetchState('', buildStorageKey({
3408
+ id,
3409
+ version,
3410
+ category: DENSITY_MODEL_KEY
3411
+ }));
1821
3412
  return {
1822
3413
  paginationModel,
1823
3414
  setPaginationModel,
@@ -1830,30 +3421,14 @@ const useTableStates = (id, version) => {
1830
3421
  pinnedColumns,
1831
3422
  setPinnedColumns,
1832
3423
  dimensionModel,
1833
- setDimensionModel
3424
+ setDimensionModel,
3425
+ densityModel,
3426
+ setDensityModel
1834
3427
  };
1835
3428
  };
1836
3429
 
1837
- /**
1838
- * Deep-equal comparison for plain objects / arrays.
1839
- * Used to stabilise parsed model references so that MUI v8 does not
1840
- * reset pagination on every render.
1841
- */
1842
- function isDeepEqual(a, b) {
1843
- if (a === b) return true;
1844
- if (a == null || b == null) return false;
1845
- if (typeof a !== typeof b) return false;
1846
- if (typeof a !== 'object') return false;
1847
- const aObj = a;
1848
- const bObj = b;
1849
- const aKeys = Object.keys(aObj);
1850
- const bKeys = Object.keys(bObj);
1851
- if (aKeys.length !== bKeys.length) return false;
1852
- return aKeys.every(key => isDeepEqual(aObj[key], bObj[key]));
1853
- }
1854
3430
  const useStatefulTable = props => {
1855
3431
  const {
1856
- // density = 'standard',
1857
3432
  apiRef,
1858
3433
  initialState,
1859
3434
  columns: propsColumns,
@@ -1887,7 +3462,9 @@ const useStatefulTable = props => {
1887
3462
  pinnedColumns,
1888
3463
  setPinnedColumns,
1889
3464
  dimensionModel,
1890
- setDimensionModel
3465
+ setDimensionModel,
3466
+ densityModel,
3467
+ setDensityModel
1891
3468
  } = useTableStates(id, localStorageVersion);
1892
3469
 
1893
3470
  // clearing up old version keys, triggering only on first render
@@ -1907,6 +3484,7 @@ const useStatefulTable = props => {
1907
3484
  paginationModel: paginationModelParsed,
1908
3485
  columnVisibilityModel: visibilityModel,
1909
3486
  pinnedColumnsModel,
3487
+ density: densityParsed,
1910
3488
  pendingSearch
1911
3489
  } = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, initialState, {
1912
3490
  localStorageFilters,
@@ -1918,7 +3496,9 @@ const useStatefulTable = props => {
1918
3496
  localStorageColumnsVisibility: visibilityModelLocalStorage,
1919
3497
  setLocalStorageColumnsVisibility: setVisibilityModelLocalStorage,
1920
3498
  localStoragePinnedColumns: pinnedColumns,
1921
- setLocalStoragePinnedColumns: setPinnedColumns
3499
+ setLocalStoragePinnedColumns: setPinnedColumns,
3500
+ localStorageDensity: densityModel,
3501
+ setLocalStorageDensity: setDensityModel
1922
3502
  });
1923
3503
 
1924
3504
  // Sync URL in an effect rather than during render to comply with React rules
@@ -1927,29 +3507,6 @@ const useStatefulTable = props => {
1927
3507
  historyReplace(pendingSearch);
1928
3508
  }
1929
3509
  }, [pendingSearch, historyReplace]);
1930
-
1931
- // Stabilise parsed model references to prevent MUI v8 from resetting
1932
- // pagination on every render due to new object identity.
1933
- const filterParsedRef = useRef(filterParsed);
1934
- if (!isDeepEqual(filterParsedRef.current, filterParsed)) {
1935
- filterParsedRef.current = filterParsed;
1936
- }
1937
- const sortModelParsedRef = useRef(sortModelParsed);
1938
- if (!isDeepEqual(sortModelParsedRef.current, sortModelParsed)) {
1939
- sortModelParsedRef.current = sortModelParsed;
1940
- }
1941
- const paginationModelParsedRef = useRef(paginationModelParsed);
1942
- if (!isDeepEqual(paginationModelParsedRef.current, paginationModelParsed)) {
1943
- paginationModelParsedRef.current = paginationModelParsed;
1944
- }
1945
- const visibilityModelRef = useRef(visibilityModel);
1946
- if (!isDeepEqual(visibilityModelRef.current, visibilityModel)) {
1947
- visibilityModelRef.current = visibilityModel;
1948
- }
1949
- const pinnedColumnsModelRef = useRef(pinnedColumnsModel);
1950
- if (!isDeepEqual(pinnedColumnsModelRef.current, pinnedColumnsModel)) {
1951
- pinnedColumnsModelRef.current = pinnedColumnsModel;
1952
- }
1953
3510
  const columns = useMemo(() => propsColumns.map(column => {
1954
3511
  return _objectSpread2(_objectSpread2({}, column), {}, {
1955
3512
  width: dimensionModel[column.field] || column.width || 100
@@ -1958,83 +3515,116 @@ const useStatefulTable = props => {
1958
3515
  if (apiRef.current) {
1959
3516
  /** Add resetPage method to apiRef. */
1960
3517
  apiRef.current.resetPage = () => {
1961
- var _apiRef$current;
1962
- (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPage(0);
3518
+ apiRef.current.setPage(0);
1963
3519
  };
1964
3520
  }
3521
+
3522
+ // Subscribe to density changes via stateChange event
3523
+ // (MUI v7 supports onDensityChange, but stateChange works and avoids a larger refactor)
3524
+ useEffect(() => {
3525
+ const api = apiRef.current;
3526
+ if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
3527
+ let prevDensity = densityParsed;
3528
+ const unsub = api.subscribeEvent('stateChange', () => {
3529
+ const currentDensity = api.state.density;
3530
+ if (currentDensity !== prevDensity) {
3531
+ prevDensity = currentDensity;
3532
+ updateUrl({
3533
+ filterModel: filterParsed,
3534
+ sortModel: sortModelParsed,
3535
+ paginationModel: paginationModelParsed,
3536
+ columnsModel: api.state.columns.columnVisibilityModel,
3537
+ pinnedColumnsModel: pinnedColumnsModel,
3538
+ density: currentDensity
3539
+ }, search, localStorageVersion, historyReplace, columns);
3540
+ }
3541
+ });
3542
+ return unsub;
3543
+ }, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, search, localStorageVersion, historyReplace, columns]);
1965
3544
  return {
1966
3545
  apiRef,
1967
3546
  columns,
3547
+ density: densityParsed,
3548
+ onDensityChange: newDensity => {
3549
+ updateUrl({
3550
+ filterModel: filterParsed,
3551
+ sortModel: sortModelParsed,
3552
+ paginationModel: paginationModelParsed,
3553
+ columnsModel: apiRef.current.state.columns.columnVisibilityModel,
3554
+ pinnedColumnsModel: pinnedColumnsModel,
3555
+ density: newDensity
3556
+ }, search, localStorageVersion, historyReplace, columns);
3557
+ },
1968
3558
  onFilterModelChange: (model, details) => {
1969
- var _apiRef$current$state, _apiRef$current3;
1970
3559
  const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
1971
3560
  items: model.items.map(item => {
1972
- var _apiRef$current2;
1973
- const column = (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.getColumn(item.field);
1974
- item.type = (column === null || column === void 0 ? void 0 : column.type) || 'string';
3561
+ const column = apiRef.current.getColumn(item.field);
3562
+ item.type = column.type || 'string';
1975
3563
  return item;
1976
3564
  }),
1977
3565
  quickFilterValues: model.quickFilterValues || []
1978
3566
  });
3567
+ propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
1979
3568
  updateUrl({
1980
3569
  filterModel: filterModel,
1981
3570
  sortModel: sortModelParsed,
1982
3571
  paginationModel: paginationModelParsed,
1983
- columnsModel: (_apiRef$current$state = (_apiRef$current3 = apiRef.current) === null || _apiRef$current3 === void 0 ? void 0 : _apiRef$current3.state.columns.columnVisibilityModel) !== null && _apiRef$current$state !== void 0 ? _apiRef$current$state : {},
1984
- pinnedColumnsModel: pinnedColumnsModel
3572
+ columnsModel: apiRef.current.state.columns.columnVisibilityModel,
3573
+ pinnedColumnsModel: pinnedColumnsModel,
3574
+ density: densityParsed
1985
3575
  }, search, localStorageVersion, historyReplace, columns);
1986
- propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
1987
3576
  },
1988
- filterModel: filterParsedRef.current,
3577
+ filterModel: filterParsed,
1989
3578
  onSortModelChange: (model, details) => {
1990
- var _apiRef$current$state2, _apiRef$current4;
3579
+ propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
1991
3580
  updateUrl({
1992
3581
  filterModel: filterParsed,
1993
3582
  sortModel: model,
1994
3583
  paginationModel: paginationModelParsed,
1995
- columnsModel: (_apiRef$current$state2 = (_apiRef$current4 = apiRef.current) === null || _apiRef$current4 === void 0 ? void 0 : _apiRef$current4.state.columns.columnVisibilityModel) !== null && _apiRef$current$state2 !== void 0 ? _apiRef$current$state2 : {},
1996
- pinnedColumnsModel: pinnedColumnsModel
3584
+ columnsModel: apiRef.current.state.columns.columnVisibilityModel,
3585
+ pinnedColumnsModel: pinnedColumnsModel,
3586
+ density: densityParsed
1997
3587
  }, search, localStorageVersion, historyReplace, columns);
1998
- propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
1999
3588
  },
2000
- sortModel: sortModelParsedRef.current,
3589
+ sortModel: sortModelParsed,
2001
3590
  onPinnedColumnsChange: (pinnedColumns, details) => {
2002
- var _apiRef$current$state3, _apiRef$current5;
3591
+ propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
2003
3592
  updateUrl({
2004
3593
  filterModel: filterParsed,
2005
3594
  sortModel: sortModelParsed,
2006
3595
  paginationModel: paginationModelParsed,
2007
- columnsModel: (_apiRef$current$state3 = (_apiRef$current5 = apiRef.current) === null || _apiRef$current5 === void 0 ? void 0 : _apiRef$current5.state.columns.columnVisibilityModel) !== null && _apiRef$current$state3 !== void 0 ? _apiRef$current$state3 : {},
2008
- pinnedColumnsModel: pinnedColumns
3596
+ columnsModel: apiRef.current.state.columns.columnVisibilityModel,
3597
+ pinnedColumnsModel: pinnedColumns,
3598
+ density: densityParsed
2009
3599
  }, search, localStorageVersion, historyReplace, columns);
2010
- propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
2011
3600
  },
2012
- pinnedColumns: pinnedColumnsModelRef.current,
2013
- paginationModel: paginationModelParsedRef.current,
3601
+ pinnedColumns: pinnedColumnsModel,
3602
+ paginationModel: paginationModelParsed,
2014
3603
  onPaginationModelChange: (model, details) => {
2015
- var _apiRef$current$state4, _apiRef$current6;
2016
3604
  const paginationModel = _objectSpread2(_objectSpread2({}, model), {}, {
2017
3605
  direction: paginationModelParsed.page < model.page ? 'next' : 'back'
2018
3606
  });
3607
+ propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
2019
3608
  updateUrl({
2020
3609
  filterModel: filterParsed,
2021
3610
  sortModel: sortModelParsed,
2022
3611
  paginationModel: paginationModel,
2023
- columnsModel: (_apiRef$current$state4 = (_apiRef$current6 = apiRef.current) === null || _apiRef$current6 === void 0 ? void 0 : _apiRef$current6.state.columns.columnVisibilityModel) !== null && _apiRef$current$state4 !== void 0 ? _apiRef$current$state4 : {},
2024
- pinnedColumnsModel: pinnedColumnsModel
3612
+ columnsModel: apiRef.current.state.columns.columnVisibilityModel,
3613
+ pinnedColumnsModel: pinnedColumnsModel,
3614
+ density: densityParsed
2025
3615
  }, search, localStorageVersion, historyReplace, columns);
2026
- propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
2027
3616
  },
2028
- columnVisibilityModel: visibilityModelRef.current,
3617
+ columnVisibilityModel: visibilityModel,
2029
3618
  onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
3619
+ propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
2030
3620
  updateUrl({
2031
3621
  filterModel: filterParsed,
2032
3622
  sortModel: sortModelParsed,
2033
3623
  paginationModel: paginationModelParsed,
2034
3624
  columnsModel: columnsVisibilityModel,
2035
- pinnedColumnsModel: pinnedColumnsModel
3625
+ pinnedColumnsModel: pinnedColumnsModel,
3626
+ density: densityParsed
2036
3627
  }, search, localStorageVersion, historyReplace, columns);
2037
- propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
2038
3628
  },
2039
3629
  onColumnWidthChange: (params, event, details) => {
2040
3630
  propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
@@ -2102,7 +3692,6 @@ const CLASSNAME = 'redsift-datagrid';
2102
3692
  */
2103
3693
 
2104
3694
  const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2105
- var _initialState$density, _forwardedProps$densi;
2106
3695
  const datagridRef = ref || useRef();
2107
3696
  const {
2108
3697
  apiRef: propsApiRef,
@@ -2143,9 +3732,10 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2143
3732
  rowCount
2144
3733
  } = props,
2145
3734
  forwardedProps = _objectWithoutProperties(props, _excluded);
2146
- const theme = useTheme(propsTheme);
3735
+ const theme = useTheme$1(propsTheme);
2147
3736
  const _apiRef = useGridApiRef();
2148
3737
  const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
3738
+ const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
2149
3739
  LicenseInfo.setLicenseKey(license);
2150
3740
  const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
2151
3741
  const {
@@ -2170,8 +3760,10 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2170
3760
  });
2171
3761
  const {
2172
3762
  columnVisibilityModel,
3763
+ density: controlledDensity,
2173
3764
  filterModel,
2174
3765
  onColumnVisibilityModelChange,
3766
+ onDensityChange,
2175
3767
  onFilterModelChange,
2176
3768
  onPaginationModelChange,
2177
3769
  onPinnedColumnsChange,
@@ -2194,18 +3786,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2194
3786
  localStorageVersion,
2195
3787
  previousLocalStorageVersions
2196
3788
  });
2197
- const [rowSelectionModel, setRowSelectionModel] = useState(() => normalizeRowSelectionModel(propsRowSelectionModel));
3789
+ const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
2198
3790
  useEffect(() => {
2199
- setRowSelectionModel(normalizeRowSelectionModel(propsRowSelectionModel));
3791
+ setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
2200
3792
  }, [propsRowSelectionModel]);
2201
3793
  const onRowSelectionModelChange = (selectionModel, details) => {
2202
- if (propsOnRowSelectionModelChange) {
2203
- propsOnRowSelectionModelChange(selectionModel, details);
2204
- } else {
2205
- setRowSelectionModel(selectionModel);
2206
- }
3794
+ setRowSelectionModel(selectionModel);
3795
+ propsOnRowSelectionModelChange === null || propsOnRowSelectionModelChange === void 0 ? void 0 : propsOnRowSelectionModelChange(selectionModel, details);
2207
3796
  };
2208
- const selectionStatus = useRef({
3797
+ const selectionStatusRef = useRef({
2209
3798
  type: 'none',
2210
3799
  numberOfSelectedRows: 0,
2211
3800
  numberOfSelectedRowsInPage: 0,
@@ -2220,34 +3809,31 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2220
3809
  // for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
2221
3810
  const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
2222
3811
 
2223
- // Track when the grid API is ready to ensure top pagination renders correctly
2224
- const [gridReady, setGridReady] = useState(false);
2225
-
2226
- // Force re-render when the grid API becomes ready (for top pagination)
2227
- useEffect(() => {
2228
- if (apiRef.current && !gridReady) {
2229
- setGridReady(true);
2230
- }
2231
- });
2232
-
2233
3812
  // in server-side pagination we want to update the selection status
2234
3813
  // every time we navigate between pages, resize our page or select something
2235
3814
  useEffect(() => {
2236
3815
  if (paginationMode == 'server') {
2237
- onServerSideSelectionStatusChange(rowSelectionModel, apiRef, selectionStatus, forceSelectionUpdate, isRowSelectable, paginationModel.page, paginationModel.pageSize);
3816
+ onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, paginationModel.page, paginationModel.pageSize);
2238
3817
  }
2239
- }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize]);
3818
+ }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize, rows]);
2240
3819
  if (!Array.isArray(rows)) {
2241
3820
  return null;
2242
3821
  }
2243
3822
 
2244
- // Recalculate selection status for client-side pagination when navigating pages.
2245
- // The ref is updated in onRowSelectionModelChange but that callback does not fire
2246
- // on page changes, so the status can become stale (e.g. showing "all rows on this
2247
- // page are selected" on a page where none are actually selected).
2248
- if (pagination && paginationMode !== 'server' && getSelectionCount(rowSelectionModel) > 0) {
3823
+ // Compute selection status synchronously during render for client-side pagination.
3824
+ // This value is passed directly to ToolbarWrapper and ControlledPagination, so slots
3825
+ // receive the fresh value in the same render cycle no extra re-render needed.
3826
+ // The ref is kept in sync for the onRowSelectionModelChange callback's deselect logic.
3827
+ let selectionStatus = selectionStatusRef.current;
3828
+ if (pagination && paginationMode !== 'server' && Array.isArray(rowSelectionModel) && rowSelectionModel.length > 0) {
2249
3829
  try {
2250
- const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref => {
3830
+ // Use manual page slicing with our React state's paginationModel instead of
3831
+ // gridPaginatedVisibleSortedGridRow*Selector(apiRef). In MUI v7, the apiRef's
3832
+ // internal pagination state can lag behind the React state after a page change,
3833
+ // causing the selection status to be one page behind.
3834
+ const pageStart = paginationModel.page * paginationModel.pageSize;
3835
+ const pageEnd = pageStart + paginationModel.pageSize;
3836
+ const selectableRowsInPage = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).slice(pageStart, pageEnd).filter(_ref => {
2251
3837
  let {
2252
3838
  model
2253
3839
  } = _ref;
@@ -2259,7 +3845,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2259
3845
  id
2260
3846
  } = _ref2;
2261
3847
  return id;
2262
- }) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
3848
+ }) : gridFilteredSortedRowIdsSelector(apiRef).slice(pageStart, pageEnd);
2263
3849
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
2264
3850
  const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref3 => {
2265
3851
  let {
@@ -2275,25 +3861,25 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2275
3861
  return id;
2276
3862
  }) : gridFilteredSortedRowIdsSelector(apiRef);
2277
3863
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
2278
- const numberOfSelectedRows = getSelectionCount(rowSelectionModel);
2279
- const selectedOnCurrentPage = selectableRowsInPage.filter(id => isRowSelected(rowSelectionModel, id));
3864
+ const numberOfSelectedRows = rowSelectionModel.length;
3865
+ const selectedOnCurrentPage = selectableRowsInPage.filter(id => rowSelectionModel.includes(id));
2280
3866
  if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
2281
- selectionStatus.current = {
3867
+ selectionStatus = {
2282
3868
  type: 'table',
2283
3869
  numberOfSelectedRows
2284
3870
  };
2285
3871
  } else if (selectedOnCurrentPage.length === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage > 0 && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
2286
- selectionStatus.current = {
3872
+ selectionStatus = {
2287
3873
  type: 'page',
2288
3874
  numberOfSelectedRows: selectedOnCurrentPage.length
2289
3875
  };
2290
3876
  } else if (numberOfSelectedRows > 0) {
2291
- selectionStatus.current = {
3877
+ selectionStatus = {
2292
3878
  type: 'other',
2293
3879
  numberOfSelectedRows
2294
3880
  };
2295
3881
  } else {
2296
- selectionStatus.current = {
3882
+ selectionStatus = {
2297
3883
  type: 'none',
2298
3884
  numberOfSelectedRows: 0
2299
3885
  };
@@ -2301,7 +3887,13 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2301
3887
  } catch {
2302
3888
  // apiRef may not be initialized on first render
2303
3889
  }
3890
+ } else if (pagination && paginationMode !== 'server') {
3891
+ selectionStatus = {
3892
+ type: 'none',
3893
+ numberOfSelectedRows: 0
3894
+ };
2304
3895
  }
3896
+ selectionStatusRef.current = selectionStatus;
2305
3897
  const muiTheme = useMemo(() => createTheme({
2306
3898
  palette: {
2307
3899
  mode: theme,
@@ -2324,33 +3916,14 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2324
3916
  ref: datagridRef,
2325
3917
  className: classNames(StatefulDataGrid.className, className),
2326
3918
  $height: height
2327
- }, pagination && ['top', 'both'].includes(paginationPlacement) && gridReady ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, {
2328
- displaySelection: true,
2329
- displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
2330
- displayPagination: ['top', 'both'].includes(paginationPlacement),
2331
- selectionStatus: selectionStatus.current,
2332
- paginationModel: paginationModel,
2333
- onPaginationModelChange: onPaginationModelChange,
2334
- pageSizeOptions: pageSizeOptions,
2335
- paginationProps: paginationProps,
2336
- rowCount: rowCount
2337
- }) : /*#__PURE__*/React__default.createElement(ControlledPagination, {
2338
- displaySelection: true,
2339
- displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
2340
- displayPagination: ['top', 'both'].includes(paginationPlacement),
2341
- selectionStatus: selectionStatus.current,
2342
- apiRef: apiRef,
2343
- isRowSelectable: isRowSelectable,
2344
- paginationModel: paginationModel,
2345
- onPaginationModelChange: onPaginationModelChange,
2346
- pageSizeOptions: pageSizeOptions,
2347
- paginationProps: paginationProps
2348
- }) : null, /*#__PURE__*/React__default.createElement(DataGridPremium, _extends({}, forwardedProps, {
3919
+ }, /*#__PURE__*/React__default.createElement(DataGridPro, _extends({}, forwardedProps, {
2349
3920
  apiRef: apiRef,
2350
3921
  columns: columns,
2351
3922
  columnVisibilityModel: columnVisibilityModel,
3923
+ density: controlledDensity,
2352
3924
  filterModel: filterModel,
2353
3925
  onColumnVisibilityModelChange: onColumnVisibilityModelChange,
3926
+ onDensityChange: onDensityChange,
2354
3927
  onFilterModelChange: onFilterModelChange,
2355
3928
  onPaginationModelChange: onPaginationModelChange,
2356
3929
  onPinnedColumnsChange: onPinnedColumnsChange,
@@ -2360,9 +3933,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2360
3933
  sortModel: sortModel,
2361
3934
  pageSizeOptions: pageSizeOptions,
2362
3935
  onColumnWidthChange: onColumnWidthChange,
2363
- initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
2364
- density: (_initialState$density = initialState === null || initialState === void 0 ? void 0 : initialState.density) !== null && _initialState$density !== void 0 ? _initialState$density : 'standard'
2365
- }),
3936
+ initialState: initialState,
2366
3937
  isRowSelectable: isRowSelectable,
2367
3938
  pagination: pagination,
2368
3939
  paginationMode: paginationMode,
@@ -2371,12 +3942,11 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2371
3942
  rowCount: rowCount,
2372
3943
  autoHeight: autoHeight,
2373
3944
  checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
2374
- showToolbar: !hideToolbar,
2375
- density: (_forwardedProps$densi = forwardedProps.density) !== null && _forwardedProps$densi !== void 0 ? _forwardedProps$densi : 'standard',
2376
3945
  slots: _objectSpread2(_objectSpread2({
2377
3946
  baseButton: BaseButton,
2378
3947
  baseCheckbox: BaseCheckbox,
2379
- baseIconButton: BaseIconButton,
3948
+ // baseTextField,
3949
+ basePopper: BasePopper,
2380
3950
  columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2381
3951
  displayName: "columnFilteredIcon"
2382
3952
  })),
@@ -2411,12 +3981,29 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2411
3981
  displayName: "openFilterButtonIcon"
2412
3982
  }))
2413
3983
  }, slots), {}, {
3984
+ toolbar: props => /*#__PURE__*/React__default.createElement(ToolbarWrapper, _extends({}, props, {
3985
+ hideToolbar: hideToolbar,
3986
+ RenderedToolbar: RenderedToolbar,
3987
+ filterModel: filterModel,
3988
+ onFilterModelChange: onFilterModelChange,
3989
+ pagination: pagination,
3990
+ paginationPlacement: paginationPlacement,
3991
+ selectionStatus: selectionStatus,
3992
+ apiRef: apiRef,
3993
+ isRowSelectable: isRowSelectable,
3994
+ paginationModel: paginationModel,
3995
+ onPaginationModelChange: onPaginationModelChange,
3996
+ pageSizeOptions: pageSizeOptions,
3997
+ paginationProps: paginationProps,
3998
+ paginationMode: paginationMode,
3999
+ rowCount: rowCount
4000
+ })),
2414
4001
  pagination: props => {
2415
4002
  return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
2416
4003
  displaySelection: false,
2417
4004
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
2418
4005
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
2419
- selectionStatus: selectionStatus.current,
4006
+ selectionStatus: selectionStatus,
2420
4007
  paginationModel: paginationModel,
2421
4008
  onPaginationModelChange: onPaginationModelChange,
2422
4009
  pageSizeOptions: pageSizeOptions,
@@ -2426,7 +4013,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2426
4013
  displaySelection: false,
2427
4014
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
2428
4015
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
2429
- selectionStatus: selectionStatus.current,
4016
+ selectionStatus: selectionStatus,
2430
4017
  apiRef: apiRef,
2431
4018
  isRowSelectable: isRowSelectable,
2432
4019
  paginationModel: paginationModel,
@@ -2440,7 +4027,9 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2440
4027
  rowSelectionModel: rowSelectionModel,
2441
4028
  onRowSelectionModelChange: (newSelectionModel, details) => {
2442
4029
  if (pagination && paginationMode != 'server') {
2443
- const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref5 => {
4030
+ const cbPageStart = paginationModel.page * paginationModel.pageSize;
4031
+ const cbPageEnd = cbPageStart + paginationModel.pageSize;
4032
+ const selectableRowsInPage = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).slice(cbPageStart, cbPageEnd).filter(_ref5 => {
2444
4033
  let {
2445
4034
  model
2446
4035
  } = _ref5;
@@ -2452,7 +4041,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2452
4041
  id
2453
4042
  } = _ref6;
2454
4043
  return id;
2455
- }) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
4044
+ }) : gridFilteredSortedRowIdsSelector(apiRef).slice(cbPageStart, cbPageEnd);
2456
4045
  const numberOfSelectableRowsInPage = selectableRowsInPage.length;
2457
4046
  const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref7 => {
2458
4047
  let {
@@ -2468,30 +4057,29 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2468
4057
  return id;
2469
4058
  }) : gridFilteredSortedRowIdsSelector(apiRef);
2470
4059
  const numberOfSelectableRowsInTable = selectableRowsInTable.length;
2471
- const numberOfSelectedRows = getSelectionCount(newSelectionModel);
2472
- if (selectionStatus.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatus.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatus.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
4060
+ const numberOfSelectedRows = newSelectionModel.length;
4061
+ if (selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatusRef.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
2473
4062
  setTimeout(() => {
2474
- var _apiRef$current;
2475
- (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.selectRows([], true, true);
4063
+ apiRef.current.selectRows([], true, true);
2476
4064
  }, 0);
2477
4065
  }
2478
4066
  if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
2479
- selectionStatus.current = {
4067
+ selectionStatusRef.current = {
2480
4068
  type: 'page',
2481
4069
  numberOfSelectedRows
2482
4070
  };
2483
4071
  } else if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
2484
- selectionStatus.current = {
4072
+ selectionStatusRef.current = {
2485
4073
  type: 'table',
2486
4074
  numberOfSelectedRows
2487
4075
  };
2488
4076
  } else if (numberOfSelectedRows > 0) {
2489
- selectionStatus.current = {
4077
+ selectionStatusRef.current = {
2490
4078
  type: 'other',
2491
4079
  numberOfSelectedRows
2492
4080
  };
2493
4081
  } else {
2494
- selectionStatus.current = {
4082
+ selectionStatusRef.current = {
2495
4083
  type: 'none',
2496
4084
  numberOfSelectedRows
2497
4085
  };
@@ -2514,5 +4102,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2514
4102
  StatefulDataGrid.className = CLASSNAME;
2515
4103
  StatefulDataGrid.displayName = COMPONENT_NAME;
2516
4104
 
2517
- export { areSearchStringsEqual 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, CATEGORIES as T, buildStorageKey as U, VISIBILITY_MODEL_KEY as V, clearPreviousVersionStorage as W, convertToDisplayFormat as X, convertFromDisplayFormat as Y, getDecodedSearchFromUrl as Z, buildQueryParamsString as _, DOES_NOT_EQUAL as a, decodeValue as a0, encodeValue as a1, urlSearchParamsToString as a2, numberOperatorEncoder as a3, numberOperatorDecoder as a4, isOperatorValueValid as a5, isValueValid as a6, getFilterModelFromString as a7, getSearchParamsFromFilterModel as a8, getSortingFromString as a9, getSearchParamsFromSorting as aa, getPaginationFromString as ab, getSearchParamsFromPagination as ac, getColumnVisibilityFromString as ad, getSearchParamsFromColumnVisibility as ae, getPinnedColumnsFromString as af, getSearchParamsFromPinnedColumns as ag, getSearchParamsFromTab as ah, getFinalSearch as ai, getModelsParsedOrUpdateLocalStorage as aj, updateUrl as ak, areFilterModelsEquivalent as al, StatefulDataGrid as am, 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 };
4105
+ export { convertFromDisplayFormat 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, CATEGORIES as X, buildStorageKey as Y, clearPreviousVersionStorage as Z, convertToDisplayFormat as _, DOES_NOT_EQUAL as a, getDecodedSearchFromUrl as a0, buildQueryParamsString as a1, areSearchStringsEqual as a2, decodeValue as a3, encodeValue as a4, urlSearchParamsToString as a5, numberOperatorEncoder as a6, numberOperatorDecoder as a7, isOperatorValueValid as a8, isValueValid as a9, getFilterModelFromString as aa, getSearchParamsFromFilterModel as ab, getSortingFromString as ac, getSearchParamsFromSorting as ad, getPaginationFromString as ae, getSearchParamsFromPagination as af, getColumnVisibilityFromString as ag, getSearchParamsFromColumnVisibility as ah, getPinnedColumnsFromString as ai, getSearchParamsFromPinnedColumns as aj, getSearchParamsFromTab as ak, getDensityFromString as al, getSearchParamsFromDensity as am, getFinalSearch as an, getModelsParsedOrUpdateLocalStorage as ao, updateUrl as ap, areFilterModelsEquivalent as aq, StatefulDataGrid as ar, 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 };
2518
4106
  //# sourceMappingURL=StatefulDataGrid2.js.map