@redsift/table 11.10.0-muiv7 → 11.11.0-muiv5

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,2002 +1,15 @@
1
- import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends } from './_rollupPluginBabelHelpers.js';
2
- import * as React from 'react';
1
+ import { _ as _objectSpread2, b as _objectWithoutProperties, a as _extends } from './_rollupPluginBabelHelpers.js';
3
2
  import React__default, { useCallback, useEffect, useMemo, forwardRef, useRef, useState } from 'react';
4
3
  import classNames from 'classnames';
5
- import { Icon, useTheme as useTheme$1, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite, ThemeProvider } from '@redsift/design-system';
6
- import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, DataGridPro, gridPaginatedVisibleSortedGridRowEntriesSelector, gridPaginatedVisibleSortedGridRowIdsSelector, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector } from '@mui/x-data-grid-pro';
7
- import { L as LicenseInfo, u as useControlledDatagridState, T as ThemeProvider$1, S as StyledDataGrid } from './useControlledDatagridState.js';
8
- import { mdiSync } from '@redsift/icons';
9
- import { d as defaultSxConfig, i as isPlainObject, s as styled, a as styleFunctionSx, c as clsx, g as generateUtilityClasses, b as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, e as generateUtilityClass, f as styled$1, u as useDefaultProps, h as composeClasses, r as rootShouldForwardProp, j as refType } from './Portal.js';
10
- import { j as jsxRuntimeExports } from './jsx-runtime.js';
11
- import { u as useTheme, m as memoTheme, c as createSimplePaletteValueFilter, a as useFormControl, f as formControlState, b as capitalize, i as isAdornedStart, d as isFilled, F as FormControlContext, e as useId, g as useSlot, h as Select, I as Input, j as FilledInput, O as OutlinedInput, o as onServerSideSelectionStatusChange, S as ServerSideControlledPagination, C as ControlledPagination } from './ControlledPagination.js';
4
+ import { useTheme, ThemeProvider, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite } from '@redsift/design-system';
5
+ import { GridLinkOperator, useGridApiRef, DataGridPro, gridPaginatedVisibleSortedGridRowEntriesSelector, gridPaginatedVisibleSortedGridRowIdsSelector, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector } from '@mui/x-data-grid-pro';
6
+ import { o as operatorList, M as LicenseInfo, N as useControlledDatagridState, T as ThemeProvider$1, O as StyledDataGrid, f as customColumnTypes } from './useControlledDatagridState.js';
7
+ import { g as createTheme } from './Portal.js';
12
8
  import { T as Toolbar } from './Toolbar2.js';
9
+ import { o as onServerSideSelectionStatusChange, S as ServerSideControlledPagination, C as ControlledPagination } from './ControlledPagination.js';
13
10
  import { B as BaseButton, a as BaseCheckbox, c as BasePopper, b as BaseIcon } from './BasePopper.js';
14
11
  import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
15
12
 
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;
1498
-
1499
- const SUBMIT_FILTER_STROKE_TIME = 500;
1500
- const InputNumberInterval = props => {
1501
- var _item$value;
1502
- const {
1503
- item,
1504
- applyValue,
1505
- focusElementRef = null
1506
- } = props;
1507
- const filterTimeout = React.useRef();
1508
- const [filterValueState, setFilterValueState] = React.useState((_item$value = item.value) !== null && _item$value !== void 0 ? _item$value : '');
1509
- const [applying, setIsApplying] = React.useState(false);
1510
- React.useEffect(() => {
1511
- return () => {
1512
- clearTimeout(filterTimeout.current);
1513
- };
1514
- }, []);
1515
- React.useEffect(() => {
1516
- var _item$value2;
1517
- const itemValue = (_item$value2 = item.value) !== null && _item$value2 !== void 0 ? _item$value2 : [undefined, undefined];
1518
- setFilterValueState(itemValue);
1519
- }, [item.value]);
1520
- const updateFilterValue = (lowerBound, upperBound) => {
1521
- clearTimeout(filterTimeout.current);
1522
- setFilterValueState([lowerBound, upperBound]);
1523
- setIsApplying(true);
1524
- filterTimeout.current = setTimeout(() => {
1525
- setIsApplying(false);
1526
- applyValue(_objectSpread2(_objectSpread2({}, item), {}, {
1527
- value: [lowerBound, upperBound]
1528
- }));
1529
- }, SUBMIT_FILTER_STROKE_TIME);
1530
- };
1531
- const handleUpperFilterChange = event => {
1532
- const newUpperBound = event.target.value;
1533
- updateFilterValue(filterValueState[0], newUpperBound);
1534
- };
1535
- const handleLowerFilterChange = event => {
1536
- const newLowerBound = event.target.value;
1537
- updateFilterValue(newLowerBound, filterValueState[1]);
1538
- };
1539
- return /*#__PURE__*/React.createElement(Box$1, {
1540
- sx: {
1541
- display: 'inline-flex',
1542
- flexDirection: 'row',
1543
- alignItems: 'end',
1544
- height: 48,
1545
- pl: '20px'
1546
- }
1547
- }, /*#__PURE__*/React.createElement(TextField$1, {
1548
- name: "lower-bound-input",
1549
- placeholder: "From",
1550
- label: "From",
1551
- variant: "standard",
1552
- value: Number(filterValueState[0]),
1553
- onChange: handleLowerFilterChange,
1554
- type: "number",
1555
- inputRef: focusElementRef,
1556
- sx: {
1557
- mr: 2
1558
- }
1559
- }), /*#__PURE__*/React.createElement(TextField$1, {
1560
- name: "upper-bound-input",
1561
- placeholder: "To",
1562
- label: "To",
1563
- variant: "standard",
1564
- value: Number(filterValueState[1]),
1565
- onChange: handleUpperFilterChange,
1566
- type: "number",
1567
- InputProps: applying ? {
1568
- endAdornment: /*#__PURE__*/React.createElement(Icon, {
1569
- icon: mdiSync
1570
- })
1571
- } : {}
1572
- }));
1573
- };
1574
-
1575
- const isBetweenOperator = {
1576
- label: 'is between',
1577
- value: 'isBetween',
1578
- getApplyFilterFn: filterItem => {
1579
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1580
- return null;
1581
- }
1582
- if (!Array.isArray(filterItem.value) || filterItem.value.length !== 2) {
1583
- return null;
1584
- }
1585
- if (filterItem.value[0] == null || filterItem.value[1] == null) {
1586
- return null;
1587
- }
1588
- if (typeof filterItem.value[0] !== 'number' || typeof filterItem.value[1] !== 'number') {
1589
- return null;
1590
- }
1591
- return value => {
1592
- return value !== null && value !== undefined && filterItem.value[0] <= value && value <= filterItem.value[1];
1593
- };
1594
- },
1595
- InputComponent: InputNumberInterval
1596
- };
1597
- const IS_BETWEEN = isBetweenOperator;
1598
-
1599
- const getGridNumericOperators = () => [...getGridNumericOperators$1(), IS_BETWEEN];
1600
-
1601
- const doesNotContain = {
1602
- label: 'does not contain',
1603
- value: 'doesNotContain',
1604
- getApplyFilterFn: filterItem => {
1605
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1606
- return null;
1607
- }
1608
- return value => {
1609
- if (filterItem.value.length === 0) {
1610
- return true;
1611
- }
1612
- if (String(value).indexOf(filterItem.value) !== -1) {
1613
- return false;
1614
- }
1615
- return true;
1616
- };
1617
- },
1618
- InputComponent: GridFilterInputValue
1619
- };
1620
- const DOES_NOT_CONTAIN = doesNotContain;
1621
-
1622
- const doesNotEqual = {
1623
- label: 'does not equal',
1624
- value: 'doesNotEqual',
1625
- getApplyFilterFn: filterItem => {
1626
- if (!filterItem.field || !filterItem.value || !filterItem.value) {
1627
- return null;
1628
- }
1629
- return value => {
1630
- if (filterItem.value.length === 0) {
1631
- return true;
1632
- }
1633
- if (String(value) === filterItem.value) {
1634
- return false;
1635
- }
1636
- return true;
1637
- };
1638
- },
1639
- InputComponent: GridFilterInputValue
1640
- };
1641
- const DOES_NOT_EQUAL = doesNotEqual;
1642
-
1643
- const doesNotHaveOperator = {
1644
- label: "doesn't have",
1645
- value: 'doesNotHave',
1646
- getApplyFilterFn: filterItem => {
1647
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1648
- return null;
1649
- }
1650
- return value => {
1651
- const cellValues = Array.isArray(value) ? value : [value];
1652
- return !cellValues.map(val => String(val)).includes(filterItem.value);
1653
- };
1654
- },
1655
- InputComponent: GridFilterInputValue
1656
- };
1657
- const DOES_NOT_HAVE = doesNotHaveOperator;
1658
- const DOES_NOT_HAVE_WITH_SELECT = _objectSpread2(_objectSpread2({}, DOES_NOT_HAVE), {}, {
1659
- InputComponent: GridFilterInputSingleSelect
1660
- });
1661
-
1662
- const hasOperator = {
1663
- label: 'has',
1664
- value: 'has',
1665
- getApplyFilterFn: filterItem => {
1666
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1667
- return null;
1668
- }
1669
- return value => {
1670
- const cellValues = Array.isArray(value) ? value : [value];
1671
- return cellValues.map(val => String(val)).includes(filterItem.value);
1672
- };
1673
- },
1674
- InputComponent: GridFilterInputValue
1675
- };
1676
- const HAS = hasOperator;
1677
- const HAS_WITH_SELECT = _objectSpread2(_objectSpread2({}, HAS), {}, {
1678
- InputComponent: GridFilterInputSingleSelect
1679
- });
1680
-
1681
- const hasOnlyOperator = {
1682
- label: 'has only',
1683
- value: 'hasOnly',
1684
- getApplyFilterFn: filterItem => {
1685
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1686
- return null;
1687
- }
1688
- return value => {
1689
- const cellValues = Array.isArray(value) ? value : [value];
1690
- return cellValues.length === 1 && String(cellValues[0]) === filterItem.value;
1691
- };
1692
- },
1693
- InputComponent: GridFilterInputValue
1694
- };
1695
- const HAS_ONLY = hasOnlyOperator;
1696
- const HAS_ONLY_WITH_SELECT = _objectSpread2(_objectSpread2({}, HAS_ONLY), {}, {
1697
- InputComponent: GridFilterInputSingleSelect
1698
- });
1699
-
1700
- const isOperator = {
1701
- label: 'is',
1702
- value: 'is',
1703
- getApplyFilterFn: filterItem => {
1704
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1705
- return null;
1706
- }
1707
- return value => {
1708
- if (Array.isArray(value)) {
1709
- return false;
1710
- }
1711
- return String(value) === filterItem.value;
1712
- };
1713
- },
1714
- InputComponent: GridFilterInputValue
1715
- };
1716
- const IS = isOperator;
1717
- const IS_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS), {}, {
1718
- InputComponent: GridFilterInputSingleSelect
1719
- });
1720
-
1721
- const isNotOperator = {
1722
- label: 'is not',
1723
- value: 'isNot',
1724
- getApplyFilterFn: filterItem => {
1725
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1726
- return null;
1727
- }
1728
- return value => {
1729
- if (Array.isArray(value)) {
1730
- return true;
1731
- }
1732
- return String(value) !== filterItem.value;
1733
- };
1734
- },
1735
- InputComponent: GridFilterInputValue
1736
- };
1737
- const IS_NOT = isNotOperator;
1738
- const IS_NOT_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_NOT), {}, {
1739
- InputComponent: GridFilterInputSingleSelect
1740
- });
1741
-
1742
- const containsAnyOfOperator = {
1743
- label: 'contains any of',
1744
- value: 'containsAnyOf',
1745
- getApplyFilterFn: filterItem => {
1746
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1747
- return null;
1748
- }
1749
- return value => {
1750
- if (filterItem.value.length === 0) {
1751
- return true;
1752
- }
1753
- const paramValues = Array.isArray(value) ? value : [value];
1754
- let match = false;
1755
- filterItem.value.forEach(filteredValue => {
1756
- paramValues.forEach(paramValue => {
1757
- if (String(paramValue).indexOf(filteredValue) !== -1) {
1758
- match = true;
1759
- }
1760
- });
1761
- });
1762
- return match;
1763
- };
1764
- },
1765
- InputComponent: GridFilterInputMultipleValue
1766
- };
1767
- const containsAnyOfCIOperator = {
1768
- label: 'contains any of (case insensitive)',
1769
- value: 'containsAnyOf',
1770
- getApplyFilterFn: filterItem => {
1771
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1772
- return null;
1773
- }
1774
- return value => {
1775
- if (filterItem.value.length === 0) {
1776
- return true;
1777
- }
1778
- const paramValues = Array.isArray(value) ? value : [value];
1779
- const paramValuesLower = paramValues.map(item => String(item).toLowerCase());
1780
- let match = false;
1781
- filterItem.value.forEach(filteredValue => {
1782
- if (paramValuesLower.indexOf(filteredValue.toLowerCase()) !== -1) {
1783
- match = true;
1784
- }
1785
- });
1786
- return match;
1787
- };
1788
- },
1789
- InputComponent: GridFilterInputMultipleValue
1790
- };
1791
- const CONTAINS_ANY_OF = containsAnyOfOperator;
1792
- const CONTAINS_ANY_OF_I = containsAnyOfCIOperator;
1793
-
1794
- const doesNotHaveAnyOf = {
1795
- label: "doesn't have any of",
1796
- value: 'doesNotHaveAnyOf',
1797
- getApplyFilterFn: filterItem => {
1798
- if (!filterItem.field || !filterItem.value || !Array.isArray(filterItem.value) || filterItem.value.length === 0) {
1799
- return null;
1800
- }
1801
- return value => {
1802
- const cellValues = Array.isArray(value) ? value : [value];
1803
-
1804
- // Return true only if none of the filter values are in the cell values
1805
- return filterItem.value.every(filterVal => !cellValues.map(val => String(val)).includes(filterVal));
1806
- };
1807
- },
1808
- InputComponent: GridFilterInputMultipleValue
1809
- };
1810
- const DOES_NOT_HAVE_ANY_OF = doesNotHaveAnyOf;
1811
- const DOES_NOT_HAVE_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, DOES_NOT_HAVE_ANY_OF), {}, {
1812
- InputComponent: GridFilterInputMultipleSingleSelect
1813
- });
1814
-
1815
- const endsWithAnyOfOperator = {
1816
- label: 'ends with any of',
1817
- value: 'endsWithAnyOf',
1818
- getApplyFilterFn: filterItem => {
1819
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1820
- return null;
1821
- }
1822
- return value => {
1823
- if (filterItem.value.length === 0) {
1824
- return true;
1825
- }
1826
- const paramValues = Array.isArray(value) ? value : [value];
1827
- let match = false;
1828
- filterItem.value.forEach(filteredValue => {
1829
- paramValues.forEach(paramValue => {
1830
- if (String(paramValue).endsWith(filteredValue)) {
1831
- match = true;
1832
- }
1833
- });
1834
- });
1835
- return match;
1836
- };
1837
- },
1838
- InputComponent: GridFilterInputMultipleValue
1839
- };
1840
- const ENDS_WITH_ANY_OF = endsWithAnyOfOperator;
1841
-
1842
- const isAnyOfOperator = {
1843
- label: 'is any of',
1844
- value: 'isAnyOf',
1845
- getApplyFilterFn: filterItem => {
1846
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1847
- return null;
1848
- }
1849
- return value => {
1850
- if (filterItem.value.length === 0) {
1851
- return true;
1852
- }
1853
- const paramValues = Array.isArray(value) ? value : [value];
1854
- for (const paramValue of paramValues) {
1855
- if (filterItem.value.includes(String(paramValue))) {
1856
- return true;
1857
- }
1858
- }
1859
- return false;
1860
- };
1861
- },
1862
- InputComponent: GridFilterInputMultipleValue
1863
- };
1864
- const IS_ANY_OF = isAnyOfOperator;
1865
- const IS_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_ANY_OF), {}, {
1866
- InputComponent: GridFilterInputMultipleSingleSelect
1867
- });
1868
-
1869
- const isAnyOfIOperator = {
1870
- label: 'is any of (case-insensitive)',
1871
- value: 'isAnyOfI',
1872
- getApplyFilterFn: filterItem => {
1873
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1874
- return null;
1875
- }
1876
- const lowerCaseFilterValues = filterItem.value.map(v => String(v).toLowerCase());
1877
- return value => {
1878
- if (filterItem.value.length === 0) {
1879
- return true;
1880
- }
1881
- const paramValues = Array.isArray(value) ? value : [value];
1882
- for (const paramValue of paramValues) {
1883
- if (lowerCaseFilterValues.includes(String(paramValue).toLowerCase())) {
1884
- return true;
1885
- }
1886
- }
1887
- return false;
1888
- };
1889
- },
1890
- InputComponent: GridFilterInputMultipleValue
1891
- };
1892
- const IS_ANY_OF_I = isAnyOfIOperator;
1893
- const IS_ANY_OF_I_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_ANY_OF_I), {}, {
1894
- InputComponent: GridFilterInputMultipleSingleSelect
1895
- });
1896
-
1897
- const hasAnyOfOperator = {
1898
- label: 'has any of',
1899
- value: 'hasAnyOf',
1900
- getApplyFilterFn: filterItem => {
1901
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1902
- return null;
1903
- }
1904
- return value => {
1905
- if (filterItem.value.length === 0) {
1906
- return true;
1907
- }
1908
- const cellValues = Array.isArray(value) ? value : [value];
1909
- const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
1910
- return filterItemValues.some(v => cellValues.map(val => String(val)).includes(v));
1911
- };
1912
- },
1913
- InputComponent: GridFilterInputMultipleValue
1914
- };
1915
- const HAS_ANY_OF = hasAnyOfOperator;
1916
- const HAS_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, HAS_ANY_OF), {}, {
1917
- InputComponent: GridFilterInputMultipleSingleSelect
1918
- });
1919
-
1920
- const isNotAnyOfOperator = {
1921
- label: 'is not any of',
1922
- value: 'isNotAnyOf',
1923
- getApplyFilterFn: filterItem => {
1924
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1925
- return null;
1926
- }
1927
- return value => {
1928
- if (filterItem.value.length === 0) {
1929
- return true;
1930
- }
1931
- const paramValues = Array.isArray(value) ? value : [value];
1932
- for (const paramValue of paramValues) {
1933
- if (filterItem.value.includes(String(paramValue))) {
1934
- return false;
1935
- }
1936
- }
1937
- return true;
1938
- };
1939
- },
1940
- InputComponent: GridFilterInputMultipleValue
1941
- };
1942
- const IS_NOT_ANY_OF = isNotAnyOfOperator;
1943
- const IS_NOT_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_NOT_ANY_OF), {}, {
1944
- InputComponent: GridFilterInputMultipleSingleSelect
1945
- });
1946
-
1947
- const startsWithAnyOfOperator = {
1948
- label: 'starts with any of',
1949
- value: 'startsWithAnyOf',
1950
- getApplyFilterFn: filterItem => {
1951
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1952
- return null;
1953
- }
1954
- return value => {
1955
- if (filterItem.value.length === 0) {
1956
- return true;
1957
- }
1958
- const paramValues = Array.isArray(value) ? value : [value];
1959
- let match = false;
1960
- filterItem.value.forEach(filteredValue => {
1961
- paramValues.forEach(paramValue => {
1962
- if (String(paramValue).startsWith(filteredValue)) {
1963
- match = true;
1964
- }
1965
- });
1966
- });
1967
- return match;
1968
- };
1969
- },
1970
- InputComponent: GridFilterInputMultipleValue
1971
- };
1972
- const STARTS_WITH_ANY_OF = startsWithAnyOfOperator;
1973
-
1974
- const getGridStringArrayOperators = () => [CONTAINS_ANY_OF, ENDS_WITH_ANY_OF, IS_ANY_OF, IS_ANY_OF_I, IS_NOT_ANY_OF, STARTS_WITH_ANY_OF];
1975
- const getGridStringArrayOperatorsWithSelect = () => [CONTAINS_ANY_OF, ENDS_WITH_ANY_OF, IS_ANY_OF_WITH_SELECT, IS_ANY_OF_I_WITH_SELECT, IS_NOT_WITH_SELECT, IS_WITH_SELECT, STARTS_WITH_ANY_OF];
1976
- const getGridStringArrayOperatorsWithSelectOnStringArrayColumns = () => [HAS_WITH_SELECT, HAS_ANY_OF_WITH_SELECT, HAS_ONLY_WITH_SELECT, DOES_NOT_HAVE_WITH_SELECT, DOES_NOT_HAVE_ANY_OF_WITH_SELECT];
1977
-
1978
- const getGridStringOperators = () => [...getGridStringOperators$1().filter(operator => !['isAnyOf'].includes(operator.value)), DOES_NOT_CONTAIN, DOES_NOT_EQUAL, ...getGridStringArrayOperators()];
1979
-
1980
- // istanbul ignore file
1981
- const operatorList = {
1982
- // Default types
1983
- string: getGridStringOperators$1(),
1984
- number: getGridNumericOperators$1(),
1985
- boolean: getGridBooleanOperators(),
1986
- date: getGridDateOperators(),
1987
- dateTime: getGridDateOperators(true),
1988
- singleSelect: getGridSingleSelectOperators(),
1989
- // Extended types
1990
- rsString: getGridStringOperators(),
1991
- rsNumber: getGridNumericOperators(),
1992
- rsSingleSelect: [CONTAINS_ANY_OF, ENDS_WITH_ANY_OF, IS_ANY_OF_WITH_SELECT, IS_NOT_WITH_SELECT, IS_WITH_SELECT, STARTS_WITH_ANY_OF],
1993
- rsSingleSelectWithShortOperatorList: [IS_WITH_SELECT, IS_NOT_WITH_SELECT, IS_ANY_OF_WITH_SELECT],
1994
- rsMultipleSelect: [HAS_WITH_SELECT, HAS_ANY_OF_WITH_SELECT, HAS_ONLY_WITH_SELECT, DOES_NOT_HAVE_WITH_SELECT, DOES_NOT_HAVE_ANY_OF_WITH_SELECT],
1995
- rsMultipleSelectWithShortOperatorList: [HAS_WITH_SELECT, DOES_NOT_HAVE_WITH_SELECT, HAS_ANY_OF_WITH_SELECT],
1996
- // Custom types
1997
- rsStringArray: getGridStringArrayOperators()
1998
- };
1999
-
2000
13
  const PAGINATION_MODEL_KEY = 'paginationModel';
2001
14
  const FILTER_MODEL_KEY = 'filterModel';
2002
15
  const SORT_MODEL_KEY = 'sortModel';
@@ -2054,63 +67,347 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
2054
67
  }
2055
68
  };
2056
69
 
2057
- // reference value: https://www.w3schools.com/tags/ref_urlencode.ASP
2058
- const DECODER = {
2059
- '%20': ' ',
2060
- '%26': '&',
2061
- '%3D': '=',
2062
- '%3F': '?',
2063
- '%5B': '[',
2064
- '%5D': ']',
2065
- '%2C': ',',
2066
- '%3C': '<',
2067
- '%3E': '>',
2068
- '%21': '!',
2069
- '%22': '"'
2070
- };
2071
- const ENCODER = {
2072
- ' ': '%20',
2073
- '&': '%26',
2074
- '=': '%3D',
2075
- '?': '%3F',
70
+ // Characters that need URL encoding in display format values
71
+ // These characters could cause CloudFront issues or parsing ambiguity
72
+ const CHARS_TO_ENCODE_IN_VALUES = {
73
+ ':': '%3A',
74
+ // Colon - reserved
75
+ ',': '%2C',
76
+ // Comma - used as list separator (only in list values)
77
+ '~': '%7E',
78
+ // Tilde - reserved
79
+ ';': '%3B',
80
+ // Semicolon - reserved
2076
81
  '[': '%5B',
82
+ // Square bracket - used in internal format
2077
83
  ']': '%5D',
2078
- ',': '%2C',
2079
- '<': '%3C',
2080
- '>': '%3E',
2081
- '!': '%21',
2082
- '"': '%22'
84
+ // Square bracket - used in internal format
85
+ '(': '%28',
86
+ // Parenthesis - reserved
87
+ ')': '%29' // Parenthesis - reserved
88
+ };
89
+
90
+ /**
91
+ * Encodes special characters in a value for display format URLs.
92
+ * This ensures values containing colons, commas, etc. don't break parsing.
93
+ */
94
+ const encodeDisplayValue = value => {
95
+ let encoded = value;
96
+ for (const [char, replacement] of Object.entries(CHARS_TO_ENCODE_IN_VALUES)) {
97
+ encoded = encoded.split(char).join(replacement);
98
+ }
99
+ return encoded;
100
+ };
101
+
102
+ /**
103
+ * Decodes URL-encoded characters in display format values back to their original form.
104
+ * Uses decodeURIComponent to handle all standard URL encoding.
105
+ */
106
+ const decodeDisplayValue = value => {
107
+ try {
108
+ return decodeURIComponent(value);
109
+ } catch {
110
+ // If decoding fails, return the original value
111
+ return value;
112
+ }
113
+ };
114
+
115
+ /**
116
+ * Encodes array values for display format URLs.
117
+ * Each value is URL-encoded and joined with commas.
118
+ */
119
+ const encodeDisplayArrayValue = values => {
120
+ return values.map(v => encodeDisplayValue(v)).join(',');
121
+ };
122
+
123
+ /**
124
+ * Decodes comma-separated display format array values.
125
+ * Handles URL-encoded commas within individual values.
126
+ */
127
+ const decodeDisplayArrayValue = value => {
128
+ if (value === '') {
129
+ return [];
130
+ }
131
+ // Split by unencoded commas only (not %2C)
132
+ // First, temporarily replace encoded commas, then split, then restore
133
+ const TEMP_COMMA_PLACEHOLDER = '\x00COMMA\x00';
134
+ const withPlaceholder = value.split('%2C').join(TEMP_COMMA_PLACEHOLDER);
135
+ const parts = withPlaceholder.split(',');
136
+ return parts.map(part => {
137
+ const withCommasRestored = part.split(TEMP_COMMA_PLACEHOLDER).join('%2C');
138
+ return decodeDisplayValue(withCommasRestored);
139
+ });
140
+ };
141
+
142
+ /**
143
+ * Converts internal bracket notation to display-friendly dot notation.
144
+ *
145
+ * Display format (CloudFront-safe, no brackets):
146
+ * - `field[operator]=value` → `field.operator=value` (value URL-encoded if needed)
147
+ * - `field[isAnyOf]=list[a,b,c]` → `field.isAnyOf=a,b,c` (comma-separated, values URL-encoded)
148
+ * - `_sortColumn=[field,desc]` → `_sortColumn=field.desc`
149
+ * - `_pagination=[0,25,next]` → `_pagination=0.25.next`
150
+ * - `_pinnedColumnsLeft=[a,b,c]` → `_pinnedColumnsLeft=a,b,c` (comma-separated)
151
+ * - `_columnVisibility=[a,b,c]` → `_columnVisibility=a,b,c` (comma-separated)
152
+ */
153
+ const convertToDisplayFormat = search => {
154
+ if (!search) return search;
155
+ const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
156
+ const params = cleanSearch.split('&');
157
+ const converted = params.map(param => {
158
+ // Handle _sortColumn=[field,direction]
159
+ if (param.startsWith('_sortColumn=')) {
160
+ const value = param.slice('_sortColumn='.length);
161
+ if (value.startsWith('[') && value.endsWith(']')) {
162
+ const inner = value.slice(1, -1);
163
+ if (inner === '') {
164
+ return '_sortColumn=';
165
+ }
166
+ const [field, direction] = inner.split(',');
167
+ return `_sortColumn=${field}.${direction}`;
168
+ }
169
+ return param;
170
+ }
171
+
172
+ // Handle _pagination=[page,pageSize,direction]
173
+ if (param.startsWith('_pagination=')) {
174
+ const value = param.slice('_pagination='.length);
175
+ if (value.startsWith('[') && value.endsWith(']')) {
176
+ const inner = value.slice(1, -1);
177
+ if (inner === '') {
178
+ return '_pagination=';
179
+ }
180
+ const [page, pageSize, direction] = inner.split(',');
181
+ return `_pagination=${page}.${pageSize}.${direction}`;
182
+ }
183
+ return param;
184
+ }
185
+
186
+ // Handle _pinnedColumnsLeft=[a,b,c] and _pinnedColumnsRight=[a,b,c]
187
+ if (param.startsWith('_pinnedColumnsLeft=') || param.startsWith('_pinnedColumnsRight=')) {
188
+ const eqIndex = param.indexOf('=');
189
+ const key = param.slice(0, eqIndex);
190
+ const value = param.slice(eqIndex + 1);
191
+ if (value.startsWith('[') && value.endsWith(']')) {
192
+ const inner = value.slice(1, -1);
193
+ return `${key}=${inner}`;
194
+ }
195
+ return param;
196
+ }
197
+
198
+ // Handle _columnVisibility=[a,b,c]
199
+ if (param.startsWith('_columnVisibility=')) {
200
+ const value = param.slice('_columnVisibility='.length);
201
+ if (value.startsWith('[') && value.endsWith(']')) {
202
+ const inner = value.slice(1, -1);
203
+ return `_columnVisibility=${inner}`;
204
+ }
205
+ return param;
206
+ }
207
+
208
+ // Handle _field[operator,type]=value or _field[operator,type]=list[a,b,c]
209
+ const bracketMatch = param.match(/^_([^[]+)\[([^\]]+)\]=(.*)$/);
210
+ if (bracketMatch) {
211
+ const [, field, operatorAndType, value] = bracketMatch;
212
+ const [operator] = operatorAndType.split(',');
213
+
214
+ // Convert list[a,b,c] to comma-separated with URL-encoded values
215
+ if (value.startsWith('list[') && value.endsWith(']')) {
216
+ const listContent = value.slice(5, -1);
217
+ if (listContent === '') {
218
+ return `${field}.${operator}=`;
219
+ }
220
+ const items = listContent.split(',');
221
+ return `${field}.${operator}=${encodeDisplayArrayValue(items)}`;
222
+ }
223
+ // URL-encode special characters in the value
224
+ return `${field}.${operator}=${encodeDisplayValue(value)}`;
225
+ }
226
+ return param;
227
+ });
228
+ return converted.join('&');
229
+ };
230
+
231
+ /**
232
+ * Converts display-friendly dot notation back to internal bracket notation.
233
+ *
234
+ * Internal format (server-side compatible):
235
+ * - `field.operator=value` → `_field[operator,type]=value`
236
+ * - `field.isAnyOf=a,b,c` → `_field[isAnyOf,type]=list[a,b,c]`
237
+ * - `_sortColumn=field.desc` → `_sortColumn=[field,desc]`
238
+ * - `_pagination=0.25.next` → `_pagination=[0,25,next]`
239
+ * - `_pinnedColumnsLeft=a,b,c` → `_pinnedColumnsLeft=[a,b,c]`
240
+ * - `_columnVisibility=a,b,c` → `_columnVisibility=[a,b,c]`
241
+ */
242
+ const convertFromDisplayFormat = (search, columns) => {
243
+ if (!search) return search;
244
+ const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
245
+ const params = cleanSearch.split('&');
246
+ const converted = params.map(param => {
247
+ // Handle _sortColumn=field.direction or _sortColumn=
248
+ if (param.startsWith('_sortColumn=')) {
249
+ const value = param.slice('_sortColumn='.length);
250
+ if (value === '') {
251
+ return '_sortColumn=[]';
252
+ }
253
+ // If it already has brackets, leave it alone
254
+ if (value.startsWith('[')) {
255
+ return param;
256
+ }
257
+ const dotIndex = value.indexOf('.');
258
+ if (dotIndex !== -1) {
259
+ const field = value.slice(0, dotIndex);
260
+ const direction = value.slice(dotIndex + 1);
261
+ return `_sortColumn=[${field},${direction}]`;
262
+ }
263
+ return param;
264
+ }
265
+
266
+ // Handle _pagination=page.pageSize.direction or _pagination=
267
+ if (param.startsWith('_pagination=')) {
268
+ const value = param.slice('_pagination='.length);
269
+ if (value === '') {
270
+ return '_pagination=[]';
271
+ }
272
+ // If it already has brackets, leave it alone
273
+ if (value.startsWith('[')) {
274
+ return param;
275
+ }
276
+ const parts = value.split('.');
277
+ if (parts.length === 3) {
278
+ return `_pagination=[${parts.join(',')}]`;
279
+ }
280
+ return param;
281
+ }
282
+
283
+ // Handle _pinnedColumnsLeft=a,b,c and _pinnedColumnsRight=a,b,c
284
+ if (param.startsWith('_pinnedColumnsLeft=') || param.startsWith('_pinnedColumnsRight=')) {
285
+ const eqIndex = param.indexOf('=');
286
+ const key = param.slice(0, eqIndex);
287
+ const value = param.slice(eqIndex + 1);
288
+ // If it already has brackets, leave it alone
289
+ if (value.startsWith('[')) {
290
+ return param;
291
+ }
292
+ return `${key}=[${value}]`;
293
+ }
294
+
295
+ // Handle _columnVisibility=a,b,c
296
+ if (param.startsWith('_columnVisibility=')) {
297
+ const value = param.slice('_columnVisibility='.length);
298
+ // If it already has brackets, leave it alone
299
+ if (value.startsWith('[')) {
300
+ return param;
301
+ }
302
+ return `_columnVisibility=[${value}]`;
303
+ }
304
+
305
+ // Handle field.operator=value (dot notation for filters)
306
+ const dotMatch = param.match(/^([^.]+)\.([a-zA-Z_]+)=(.*)$/);
307
+ if (dotMatch) {
308
+ const [, field, operator, rawValue] = dotMatch;
309
+
310
+ // Get column type for this field
311
+ const column = columns.find(c => c.field === field);
312
+ const columnType = (column === null || column === void 0 ? void 0 : column.type) || 'string';
313
+
314
+ // Check if this is a list operator
315
+ const listOps = ['containsAnyOf', 'doesNotContainAnyOf', 'endsWithAnyOf', 'doesNotEndWithAnyOf', 'hasAnyOf', 'doesNotHaveAnyOf', 'isAnyOf', 'isNotAnyOf', 'startsWithAnyOf', 'doesNotStartWithAnyOf'];
316
+ if (listOps.includes(operator)) {
317
+ const items = decodeDisplayArrayValue(rawValue);
318
+ return `_${field}[${operator},${columnType}]=list[${items.join(',')}]`;
319
+ }
320
+ // Decode URL-encoded special characters in the value
321
+ const decodedValue = decodeDisplayValue(rawValue);
322
+ return `_${field}[${operator},${columnType}]=${decodedValue}`;
323
+ }
324
+ return param;
325
+ });
326
+ return converted.join('&');
327
+ };
328
+
329
+ /**
330
+ * Detects if search string is in display format and converts it to internal format.
331
+ */
332
+ const getDecodedSearchFromUrl = (search, columns) => {
333
+ const searchWithoutLeadingQuestion = search.startsWith('?') ? search.slice(1) : search;
334
+
335
+ // Check if it's using display format:
336
+ // 1. Contains dot notation for filters like 'field.operator='
337
+ // 2. Has empty _sortColumn= (display format) instead of _sortColumn=[] (internal format)
338
+ // 3. Has _pinnedColumnsLeft=a,b without brackets
339
+ // 4. Has _sortColumn=field.desc format
340
+ // 5. Has _pagination=0.25.next format
341
+ const hasDotNotationFilter = /[a-zA-Z_]+\.[a-zA-Z_]+=/.test(searchWithoutLeadingQuestion);
342
+ const hasEmptySortColumn = /(_sortColumn)=(&|$)/.test(searchWithoutLeadingQuestion);
343
+ const hasSortDotNotation = /_sortColumn=[^&[]+\.[^&]+/.test(searchWithoutLeadingQuestion);
344
+ const hasPaginationDotNotation = /_pagination=[^&[]+\.[^&]+/.test(searchWithoutLeadingQuestion);
345
+ const hasPinnedWithoutBrackets = /(_pinnedColumnsLeft|_pinnedColumnsRight)=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
346
+ const hasVisibilityWithoutBrackets = /_columnVisibility=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
347
+ const hasBracketNotation = /\[.*\]=/.test(searchWithoutLeadingQuestion);
348
+ const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets) && !hasBracketNotation;
349
+ if (isDisplayFormat) {
350
+ return '?' + convertFromDisplayFormat(searchWithoutLeadingQuestion, columns);
351
+ }
352
+
353
+ // Already in internal bracket format or empty
354
+ return search;
355
+ };
356
+
357
+ /**
358
+ * Builds a display-format query string from internal format.
359
+ */
360
+ const buildQueryParamsString = search => {
361
+ const displaySearch = convertToDisplayFormat(search);
362
+ return displaySearch.startsWith('?') ? displaySearch : `?${displaySearch}`;
363
+ };
364
+
365
+ /**
366
+ * Compares two search strings for equality, ignoring parameter order.
367
+ * This prevents infinite update loops when the same parameters appear in different order.
368
+ */
369
+ const areSearchStringsEqual = (search1, search2) => {
370
+ const strippedSearch1 = search1.startsWith('?') ? search1.slice(1) : search1;
371
+ const strippedSearch2 = search2.startsWith('?') ? search2.slice(1) : search2;
372
+
373
+ // Quick check: if strings are identical, no need to parse
374
+ if (strippedSearch1 === strippedSearch2) {
375
+ return true;
376
+ }
377
+
378
+ // Parse and sort parameters for order-independent comparison
379
+ const params1 = strippedSearch1.split('&').filter(Boolean).sort();
380
+ const params2 = strippedSearch2.split('&').filter(Boolean).sort();
381
+ if (params1.length !== params2.length) {
382
+ return false;
383
+ }
384
+ return params1.every((param, index) => param === params2[index]);
2083
385
  };
2084
386
  const decodeValue = value => {
2085
387
  if (value === '') {
2086
- return '';
388
+ return undefined;
2087
389
  }
2088
- const re = new RegExp(Object.keys(DECODER).reduce((acc, curr) => `${acc},${curr}`), 'g');
2089
- // decodeValue for lists:
390
+
391
+ // Handle array values encoded as list[item1,item2,...]
2090
392
  if (value.startsWith('list[')) {
2091
- const arrayValues = value.split('[')[1].split(']')[0];
2092
- const arrayList = arrayValues.split(',').map(v => v.replace(re, encoded => DECODER[encoded])).filter(item => item);
2093
- return arrayList.length > 0 ? arrayList : [];
393
+ const arrayContent = value.slice(5, -1); // Remove 'list[' and ']'
394
+ if (arrayContent === '') {
395
+ return [];
396
+ }
397
+ return arrayContent.split(',').filter(item => item);
2094
398
  }
2095
- return value.replace(re, encoded => DECODER[encoded]);
399
+ return value;
2096
400
  };
2097
401
  const encodeValue = value => {
2098
- if (!value) {
402
+ if (value === undefined || value === null) {
2099
403
  return '';
2100
404
  }
2101
405
 
2102
- // Array encoding for value:
2103
- // we are representing it as list[encoded], where encoded is the list comma separated
406
+ // Handle array values - encode as list[item1,item2,...]
2104
407
  if (Array.isArray(value)) {
2105
- const encodedArray = value.map(entry => {
2106
- return String(entry).replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
2107
- }).join(',');
2108
- return `list[${encodedArray}]`;
408
+ return `list[${value.map(String).join(',')}]`;
2109
409
  }
2110
-
2111
- // we might also pass integers
2112
- const castedValue = String(value);
2113
- return castedValue.replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
410
+ return String(value);
2114
411
  };
2115
412
  const urlSearchParamsToString = searchParams => {
2116
413
  let searchString = '';
@@ -2135,49 +432,57 @@ const numberOperatorDecoder = {
2135
432
  lt: '<',
2136
433
  lte: '<='
2137
434
  };
2138
- const isOperatorValueValid = (field, operator, columns) => {
2139
- const column = columns.find(column => column.field === field);
435
+ const isOperatorValueValid = (columnField, operatorValue, columns) => {
436
+ const column = columns.find(column => column.field === columnField);
2140
437
  if (!column) {
2141
438
  return false;
2142
439
  }
2143
440
  const columnType = (column === null || column === void 0 ? void 0 : column.type) || 'string';
2144
- const operators = column.filterOperators || operatorList[columnType];
441
+ const operators = operatorList[columnType];
2145
442
  if (!operators) {
2146
443
  return false;
2147
444
  }
2148
- return !!operators.find(op => columnType === 'number' && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operator : op.value === operator);
445
+ if ('filterOperators' in operators) {
446
+ return !!operators.filterOperators.find(op => columnType === 'number' && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operatorValue : op['value'] === operatorValue);
447
+ }
448
+ return !!operators.find(op => ['number', 'rsNumber'].includes(columnType) && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operatorValue : op['value'] === operatorValue);
2149
449
  };
2150
450
  const listOperators = ['containsAnyOf', 'doesNotContainAnyOf', 'endsWithAnyOf', 'doesNotEndWithAnyOf', 'hasAnyOf', 'doesNotHaveAnyOf', 'isAnyOf', 'isNotAnyOf', 'startsWithAnyOf', 'doesNotStartWithAnyOf'];
2151
451
 
2152
452
  // Check if the value doesn't break
2153
- const isValueValid = (value, field, columns, operator) => {
453
+ const isValueValid = (value, columnField, columns, operatorValue) => {
2154
454
  var _column$type;
2155
455
  // every field accepts undefined as value for default
2156
456
  if (value === undefined || value === '') {
2157
457
  return true;
2158
458
  }
2159
459
 
2160
- // xxxAnyOf accepts as value only lists, and we are declaring them in the
460
+ // xxxAnyOf accepts as value only lists, and we are declearing them in the
2161
461
  // URL as `list=[...]`
2162
- if (listOperators.includes(operator)) {
462
+ if (listOperators.includes(operatorValue)) {
2163
463
  return Array.isArray(value) || value === '';
2164
464
  }
2165
465
 
2166
466
  // We are accepting arrays only if they are of the 'xxxAnyOf' type
2167
- if (Array.isArray(value) && !listOperators.includes(operator)) {
467
+ if (Array.isArray(value) && !listOperators.includes(operatorValue)) {
2168
468
  return false;
2169
469
  }
2170
- const column = columns.find(column => column.field === field);
470
+ const column = columns.find(column => column.field === columnField);
2171
471
  if (!column) {
2172
472
  return false;
2173
473
  }
2174
474
  const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
2175
475
 
2176
- // Only date fail with 500s, other set themselves as undefined
2177
- if (type !== 'date') {
476
+ // Only date and rating fail with 500s, other set themselves as undefined
477
+ if (type !== 'date' && type !== 'rating') {
2178
478
  return true;
2179
479
  }
2180
480
 
481
+ // just checking that rating is a number.
482
+ if (type === 'rating') {
483
+ return !isNaN(Number(value));
484
+ }
485
+
2181
486
  // format: YYYY-MM-DD
2182
487
  // just verifying that the 3 values are numbers to avoid 500s,
2183
488
  // If the value is invalid the form will appear as undefined
@@ -2200,7 +505,7 @@ const getFilterModelFromString = (searchString, columns) => {
2200
505
  if (!searchString) {
2201
506
  return 'invalid';
2202
507
  }
2203
- let logicOperator = GridLogicOperator.And;
508
+ let linkOperator = GridLinkOperator.And;
2204
509
  let quickFilterValues = [];
2205
510
  const searchParams = new URLSearchParams();
2206
511
  for (const [key, value] of new URLSearchParams(searchString)) {
@@ -2208,7 +513,7 @@ const getFilterModelFromString = (searchString, columns) => {
2208
513
  searchParams.set(key, value);
2209
514
  }
2210
515
  if (key === '_logicOperator') {
2211
- logicOperator = value === GridLogicOperator.And || value === GridLogicOperator.Or ? value : GridLogicOperator.And;
516
+ linkOperator = value;
2212
517
  }
2213
518
  if (key === '_quickFilterValues') {
2214
519
  try {
@@ -2227,7 +532,7 @@ const getFilterModelFromString = (searchString, columns) => {
2227
532
  if (isInvalid) {
2228
533
  return;
2229
534
  }
2230
- const field = key.split('[')[0].slice(1);
535
+ const field = key.split('[')[0].slice(1); // Slice to remove the _ at the beginning
2231
536
  if (!fields.includes(field)) {
2232
537
  return;
2233
538
  }
@@ -2244,6 +549,7 @@ const getFilterModelFromString = (searchString, columns) => {
2244
549
  return;
2245
550
  }
2246
551
  const operator = splitRight[0];
552
+ // if the operator is not part of the valid operators invalidate the URL
2247
553
  if (!isOperatorValueValid(field, operator, columns) || Array.isArray(operator)) {
2248
554
  isInvalid = true;
2249
555
  return;
@@ -2255,37 +561,41 @@ const getFilterModelFromString = (searchString, columns) => {
2255
561
  return;
2256
562
  }
2257
563
  items.push({
2258
- field,
2259
- operator: columnType === 'number' && Object.keys(numberOperatorDecoder).includes(operator) ? numberOperatorDecoder[operator] : operator,
564
+ columnField: field,
565
+ operatorValue: ['number', 'rsNumber'].includes(columnType) && Object.keys(numberOperatorDecoder).includes(operator) ? numberOperatorDecoder[operator] : operator,
2260
566
  id,
2261
567
  value: listOperators.includes(operator) && decodedValue === '' ? [] : decodedValue,
2262
568
  type
2263
569
  });
2264
570
  });
571
+
572
+ // If we found some condition that results in an invalid URL,
573
+ // return the empty filterModel (this will trigger the localStorage)
574
+ // and will pick up the last valid search
2265
575
  if (isInvalid) {
2266
576
  return 'invalid';
2267
577
  }
2268
578
  return {
2269
579
  items,
2270
- logicOperator,
580
+ linkOperator,
2271
581
  quickFilterValues
2272
582
  };
2273
583
  };
2274
584
  const getSearchParamsFromFilterModel = filterModel => {
2275
585
  var _filterModel$quickFil;
2276
586
  const searchParams = new URLSearchParams();
2277
- searchParams.set('_logicOperator', filterModel['logicOperator'] || '');
587
+ searchParams.set('_logicOperator', filterModel['linkOperator'] || '');
2278
588
  filterModel['items'].forEach(item => {
2279
589
  const {
2280
- field,
2281
- operator,
590
+ columnField,
591
+ operatorValue,
2282
592
  value,
2283
593
  type
2284
594
  } = item;
2285
- if (Object.keys(numberOperatorEncoder).includes(operator)) {
2286
- searchParams.set(`_${field}[${numberOperatorEncoder[operator]},${encodeValue(type)}]`, encodeValue(value));
595
+ if (Object.keys(numberOperatorEncoder).includes(operatorValue)) {
596
+ searchParams.set(`_${columnField}[${numberOperatorEncoder[operatorValue]},${encodeValue(type)}]`, encodeValue(value));
2287
597
  } else {
2288
- searchParams.set(`_${field}[${encodeValue(operator)},${encodeValue(type)}]`, encodeValue(value));
598
+ searchParams.set(`_${columnField}[${encodeValue(operatorValue)},${encodeValue(type)}]`, encodeValue(value));
2289
599
  }
2290
600
  });
2291
601
  if ((_filterModel$quickFil = filterModel.quickFilterValues) !== null && _filterModel$quickFil !== void 0 && _filterModel$quickFil.length) {
@@ -2301,7 +611,7 @@ const getSearchParamsFromFilterModel = filterModel => {
2301
611
  const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion) => {
2302
612
  const defaultValue = initialState && initialState.filter && initialState.filter.filterModel ? initialState.filter.filterModel : {
2303
613
  items: [],
2304
- logicOperator: GridLogicOperator.And
614
+ linkOperator: GridLinkOperator.And
2305
615
  };
2306
616
  if (isNewVersion) {
2307
617
  return defaultValue;
@@ -2440,38 +750,13 @@ const getPaginationModel = (search, localStoragePagination, setLocalStoragePagin
2440
750
 
2441
751
  /** COLUMN VISIBILITY */
2442
752
 
2443
- const getColumnVisibilityFromString = (searchString, columns) => {
2444
- if (!searchString) {
2445
- return 'invalid';
2446
- }
2447
- const searchParams = new URLSearchParams(searchString);
2448
- const value = searchParams.get('_columnVisibility');
2449
- if (value === '' || value === null || value === '[]') {
2450
- return 'invalid';
2451
- }
2452
- const parsedFields = value.slice(1, value.length - 1).split(',');
2453
- const fields = columns.map(column => column.field);
2454
- const visibility = {};
2455
- for (const field of fields) {
2456
- visibility[field] = false;
2457
- }
2458
- for (const parsedField of parsedFields) {
2459
- if (fields.includes(parsedField)) {
2460
- visibility[parsedField] = true;
2461
- }
2462
- }
2463
- if (Object.values(visibility).filter(v => v === true).length === 0) {
2464
- return 'invalid';
2465
- }
2466
- return visibility;
2467
- };
2468
753
  const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
2469
754
  const searchParams = new URLSearchParams();
2470
- const fields = columns.map(column => column.field);
755
+ const columnFields = columns.map(column => column.field);
2471
756
 
2472
757
  // if column visibility model is empty, show all columns
2473
758
  if (Object.keys(columnVisibility).length == 0) {
2474
- searchParams.set('_columnVisibility', `[${fields.join(',')}]`);
759
+ searchParams.set('_columnVisibility', `[${columnFields.join(',')}]`);
2475
760
  return searchParams;
2476
761
  }
2477
762
  const finalColumnVisibility = columns.filter(c => {
@@ -2482,10 +767,63 @@ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
2482
767
  [colName]: true
2483
768
  });
2484
769
  }, columnVisibility);
2485
- const visibleColumns = fields.filter(column => finalColumnVisibility[column] !== false);
770
+ const visibleColumns = Object.entries(finalColumnVisibility)
771
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
772
+ .filter(_ref => {
773
+ let [_, visible] = _ref;
774
+ return visible;
775
+ })
776
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
777
+ .map(_ref2 => {
778
+ let [column, _] = _ref2;
779
+ return encodeValue(column);
780
+ });
2486
781
  searchParams.set('_columnVisibility', `[${visibleColumns.join(',')}]`);
2487
782
  return searchParams;
2488
783
  };
784
+ const getColumnVisibilityFromString = (notParsed, tableColumns) => {
785
+ if (!notParsed || notParsed.length === 1 && notParsed[0] === '?') {
786
+ return 'invalid';
787
+ }
788
+ // remove the initial ? if present
789
+ const parsed = notParsed[0] === '?' ? notParsed.slice(1) : notParsed;
790
+ const visibility = {};
791
+ let exist = false;
792
+ let visibleColumnsCount = 0;
793
+ for (const item of parsed.split('&')) {
794
+ // if it's not column visibility field, skip
795
+ const fieldURL = item.split('=')[0];
796
+ if (fieldURL !== '_columnVisibility') {
797
+ continue;
798
+ }
799
+ // e.g. item = _columnVisibility[abc,def]
800
+ const left = item.split(']')[0];
801
+ if (left.split('[').length < 2) {
802
+ continue;
803
+ }
804
+ const encodedValues = item.split('[')[1].split(']')[0];
805
+ if (typeof encodedValues !== 'string') {
806
+ continue;
807
+ }
808
+ exist = true;
809
+ const columnFields = tableColumns.map(column => column.field);
810
+ // TODO: Add validation that , is present
811
+ const columns = encodedValues.split(',').map(value => decodeValue(value));
812
+
813
+ // for each column, check if it's visible and add it to visibility model
814
+ for (const column of columnFields) {
815
+ const isColumnVisible = columns.includes(column);
816
+ visibility[column] = isColumnVisible;
817
+ if (isColumnVisible) {
818
+ visibleColumnsCount += 1;
819
+ }
820
+ }
821
+ }
822
+ if (visibleColumnsCount === 0 && !exist) {
823
+ return 'invalid';
824
+ }
825
+ return visibility;
826
+ };
2489
827
 
2490
828
  // Rules:
2491
829
  // - if we have something in the URL, use that info
@@ -2546,8 +884,8 @@ const getPinnedColumnsFromString = (notParsed, tableColumns) => {
2546
884
  if (typeof encodedValues !== 'string') {
2547
885
  continue;
2548
886
  }
2549
- const fields = [...tableColumns.map(column => column.field), '__check__'];
2550
- const columns = encodedValues.split(',').map(value => decodeValue(value)).filter(val => typeof val === 'string' && fields.includes(val));
887
+ const columnFields = [...tableColumns.map(column => column.field), '__check__'];
888
+ const columns = encodedValues.split(',').map(value => decodeValue(value)).filter(val => typeof val === 'string' && columnFields.includes(val));
2551
889
  if (fieldURL === '_pinnedColumnsLeft') {
2552
890
  pinnedColumns['left'] = columns;
2553
891
  }
@@ -2555,9 +893,9 @@ const getPinnedColumnsFromString = (notParsed, tableColumns) => {
2555
893
  pinnedColumns['right'] = columns;
2556
894
  }
2557
895
  }
2558
- return pinnedColumns.left && pinnedColumns.left.length > 0 || pinnedColumns.right && pinnedColumns.right.length > 0 ? {
2559
- left: pinnedColumns.left || [],
2560
- right: pinnedColumns.right || []
896
+ return pinnedColumns['left'] || pinnedColumns['right'] ? {
897
+ left: pinnedColumns['left'] || [],
898
+ right: pinnedColumns['right'] || []
2561
899
  } : 'invalid';
2562
900
  };
2563
901
  const getSearchParamsFromPinnedColumns = pinnedColumns => {
@@ -2607,7 +945,7 @@ const getSearchParamsFromTab = search => {
2607
945
  }
2608
946
  return searchParams;
2609
947
  };
2610
- const getFinalSearch = _ref => {
948
+ const getFinalSearch = _ref3 => {
2611
949
  let {
2612
950
  search,
2613
951
  localStorageVersion,
@@ -2617,7 +955,7 @@ const getFinalSearch = _ref => {
2617
955
  columnsVisibilityModel,
2618
956
  pinnedColumnsModel,
2619
957
  columns
2620
- } = _ref;
958
+ } = _ref3;
2621
959
  const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
2622
960
  const sortModelSearch = getSearchParamsFromSorting(sortModel);
2623
961
  const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
@@ -2641,7 +979,9 @@ const getFinalSearch = _ref => {
2641
979
  };
2642
980
  /** Return the state of the table given the URL and the local storage state */
2643
981
  const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, historyReplace, initialState, localStorage) => {
2644
- const currentVersion = new URLSearchParams(search).get('v');
982
+ // Convert from display format (dot notation) to internal format (bracket notation) if needed
983
+ const decodedSearch = getDecodedSearchFromUrl(search, columns);
984
+ const currentVersion = new URLSearchParams(decodedSearch).get('v');
2645
985
  const isNewVersion = !currentVersion || Number(currentVersion) !== localStorageVersion;
2646
986
  const {
2647
987
  localStorageFilters,
@@ -2655,14 +995,14 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2655
995
  localStoragePinnedColumns,
2656
996
  setLocalStoragePinnedColumns
2657
997
  } = localStorage;
2658
- const filterModel = getFilterModel(search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
2659
- const sortModel = getSortModel(search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
2660
- const paginationModel = getPaginationModel(search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
2661
- const columnVisibilityModel = getColumnsVisibility(search, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
2662
- const pinnedColumnsModel = getPinnedColumns(search, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
998
+ const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
999
+ const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
1000
+ const paginationModel = getPaginationModel(decodedSearch, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
1001
+ const columnVisibilityModel = getColumnsVisibility(decodedSearch, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
1002
+ const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
2663
1003
  const finalSearch = getFinalSearch({
2664
1004
  localStorageVersion,
2665
- search,
1005
+ search: decodedSearch,
2666
1006
  filterModel,
2667
1007
  sortModel,
2668
1008
  paginationModel,
@@ -2670,9 +1010,15 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2670
1010
  pinnedColumnsModel,
2671
1011
  columns
2672
1012
  });
2673
- const searchString = urlSearchParamsToString(finalSearch);
2674
- if (searchString !== search) {
2675
- historyReplace(searchString);
1013
+ const internalSearchString = urlSearchParamsToString(finalSearch);
1014
+ // Convert to display format for the URL
1015
+ const displaySearchString = buildQueryParamsString(internalSearchString);
1016
+ const displaySearchWithoutQuestion = displaySearchString.startsWith('?') ? displaySearchString.slice(1) : displaySearchString;
1017
+
1018
+ // Compare with original search (without leading ?)
1019
+ const originalSearchWithoutQuestion = search.startsWith('?') ? search.slice(1) : search;
1020
+ if (!areSearchStringsEqual(displaySearchWithoutQuestion, originalSearchWithoutQuestion)) {
1021
+ historyReplace(displaySearchWithoutQuestion);
2676
1022
  }
2677
1023
  return {
2678
1024
  filterModel,
@@ -2682,16 +1028,18 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2682
1028
  pinnedColumnsModel
2683
1029
  };
2684
1030
  };
2685
- const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns) => {
1031
+ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
2686
1032
  let {
2687
1033
  filterModel,
2688
1034
  sortModel,
2689
1035
  paginationModel,
2690
1036
  columnsModel: columnsVisibilityModel,
2691
1037
  pinnedColumnsModel
2692
- } = _ref2;
1038
+ } = _ref4;
1039
+ // Convert from display format to internal format if needed
1040
+ const decodedSearch = getDecodedSearchFromUrl(search, columns);
2693
1041
  const newSearch = getFinalSearch({
2694
- search,
1042
+ search: decodedSearch,
2695
1043
  localStorageVersion,
2696
1044
  filterModel,
2697
1045
  sortModel,
@@ -2700,9 +1048,15 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
2700
1048
  pinnedColumnsModel,
2701
1049
  columns
2702
1050
  });
2703
- const searchString = urlSearchParamsToString(newSearch);
2704
- if (searchString !== search) {
2705
- historyReplace(searchString);
1051
+ const internalSearchString = urlSearchParamsToString(newSearch);
1052
+ // Convert to display format for the URL
1053
+ const displaySearchString = buildQueryParamsString(internalSearchString);
1054
+ const displaySearchWithoutQuestion = displaySearchString.startsWith('?') ? displaySearchString.slice(1) : displaySearchString;
1055
+
1056
+ // Compare with original search (without leading ?)
1057
+ const originalSearchWithoutQuestion = search.startsWith('?') ? search.slice(1) : search;
1058
+ if (!areSearchStringsEqual(displaySearchWithoutQuestion, originalSearchWithoutQuestion)) {
1059
+ historyReplace(displaySearchWithoutQuestion);
2706
1060
  }
2707
1061
  };
2708
1062
 
@@ -2710,17 +1064,17 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
2710
1064
  // do not use it for equivalence (e.g. with value `3` and undefined we
2711
1065
  // will get 0).
2712
1066
  const compareFilters = (firstFilter, secondFilter) => {
2713
- if (firstFilter.field < secondFilter.field) {
1067
+ if (firstFilter.columnField < secondFilter.columnField) {
2714
1068
  return -1;
2715
- } else if (firstFilter.field > secondFilter.field) {
1069
+ } else if (firstFilter.columnField > secondFilter.columnField) {
2716
1070
  return 1;
2717
1071
  }
2718
- if (firstFilter.operator === undefined || secondFilter.operator === undefined) {
1072
+ if (firstFilter.operatorValue === undefined || secondFilter.operatorValue === undefined) {
2719
1073
  return 0;
2720
1074
  }
2721
- if (firstFilter.operator < secondFilter.operator) {
1075
+ if (firstFilter.operatorValue < secondFilter.operatorValue) {
2722
1076
  return -1;
2723
- } else if (firstFilter.operator > secondFilter.operator) {
1077
+ } else if (firstFilter.operatorValue > secondFilter.operatorValue) {
2724
1078
  return 1;
2725
1079
  }
2726
1080
  if (firstFilter.value < secondFilter.value) {
@@ -2731,18 +1085,18 @@ const compareFilters = (firstFilter, secondFilter) => {
2731
1085
  return 0;
2732
1086
  };
2733
1087
  const areFiltersEquivalent = (firstFilter, secondFilter) => {
2734
- return firstFilter.field === secondFilter.field && firstFilter.operator === secondFilter.operator && firstFilter.value === secondFilter.value;
1088
+ return firstFilter.columnField === secondFilter.columnField && firstFilter.operatorValue === secondFilter.operatorValue && firstFilter.value === secondFilter.value;
2735
1089
  };
2736
1090
  const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2737
1091
  const {
2738
1092
  items,
2739
- logicOperator
1093
+ linkOperator
2740
1094
  } = filterModel;
2741
1095
  const {
2742
1096
  items: itemsToMatch,
2743
- logicOperator: logicOperatorToMatch
1097
+ linkOperator: linkOperatorToMatch
2744
1098
  } = filterModelToMatch;
2745
- if (logicOperator !== logicOperatorToMatch) {
1099
+ if (linkOperator !== linkOperatorToMatch) {
2746
1100
  return false;
2747
1101
  }
2748
1102
  if (items.length !== itemsToMatch.length) {
@@ -2755,7 +1109,7 @@ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2755
1109
  const filterToCompare = itemsToMatch[i];
2756
1110
 
2757
1111
  // compareFilters return 0 if and only if the filters have the same
2758
- // field, operator, and value
1112
+ // columnField, operatorValue, and value
2759
1113
  if (!areFiltersEquivalent(filter, filterToCompare)) {
2760
1114
  return false;
2761
1115
  }
@@ -2764,6 +1118,8 @@ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2764
1118
  };
2765
1119
 
2766
1120
  // Get and Set data from LocalStorage WITHOUT useState
1121
+
1122
+ // triggering a state update and consecutive re-render
2767
1123
  const useFetchState = (defaultValue, key) => {
2768
1124
  let stickyValue = null;
2769
1125
  try {
@@ -2771,7 +1127,16 @@ const useFetchState = (defaultValue, key) => {
2771
1127
  } catch (e) {
2772
1128
  console.error('StatefulDataGrid: error getting item from local storage: ', e);
2773
1129
  }
2774
- const parsedValue = stickyValue !== null && stickyValue !== undefined && stickyValue !== 'undefined' ? JSON.parse(stickyValue) : defaultValue;
1130
+ let parsedValue = stickyValue !== null && stickyValue !== undefined && stickyValue !== 'undefined' ? JSON.parse(stickyValue) : defaultValue;
1131
+
1132
+ // TODO: temporary workaround to avoid clashes when someone had sorting on the now-removed screenshot field (renamed to num_annotations)
1133
+ // Consider upgrading the Datagrid component library as the exception handling was added in this PR: https://github.com/mui-org/material-ui-x/pull/3224
1134
+ if (parsedValue instanceof Array) {
1135
+ const fields = (parsedValue || []).map(item => item.field);
1136
+ if (fields.includes('screenshot') || fields.includes('diffs')) {
1137
+ parsedValue = defaultValue;
1138
+ }
1139
+ }
2775
1140
  const updateValue = useCallback(value => {
2776
1141
  try {
2777
1142
  window.localStorage.setItem(key, JSON.stringify(value));
@@ -2782,8 +1147,6 @@ const useFetchState = (defaultValue, key) => {
2782
1147
  return [parsedValue, updateValue];
2783
1148
  };
2784
1149
 
2785
- // import useLocalStorage from './useLocalStorage';
2786
-
2787
1150
  const useTableStates = (id, version) => {
2788
1151
  const [paginationModel, setPaginationModel] = useFetchState('', buildStorageKey({
2789
1152
  id,
@@ -2840,7 +1203,8 @@ const useStatefulTable = props => {
2840
1203
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
2841
1204
  onColumnWidthChange: propsOnColumnWidthChange,
2842
1205
  onFilterModelChange: propsOnFilterModelChange,
2843
- onPaginationModelChange: propsOnPaginationModelChange,
1206
+ onPageChange: propsOnPageChange,
1207
+ onPageSizeChange: propsOnPageSizeChange,
2844
1208
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
2845
1209
  onSortModelChange: propsOnSortModelChange,
2846
1210
  useRouter,
@@ -2870,7 +1234,7 @@ const useStatefulTable = props => {
2870
1234
  setDimensionModel
2871
1235
  } = useTableStates(id, localStorageVersion);
2872
1236
 
2873
- // clearing up old version keys, triggering only on first render
1237
+ // clearing up old version keys
2874
1238
  useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
2875
1239
  const onColumnDimensionChange = useCallback(_ref => {
2876
1240
  let {
@@ -2915,7 +1279,7 @@ const useStatefulTable = props => {
2915
1279
  onFilterModelChange: (model, details) => {
2916
1280
  const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
2917
1281
  items: model.items.map(item => {
2918
- const column = apiRef.current.getColumn(item.field);
1282
+ const column = apiRef.current.getColumn(item.columnField);
2919
1283
  item.type = column.type || 'string';
2920
1284
  return item;
2921
1285
  }),
@@ -2953,16 +1317,34 @@ const useStatefulTable = props => {
2953
1317
  }, search, localStorageVersion, historyReplace, columns);
2954
1318
  },
2955
1319
  pinnedColumns: pinnedColumnsModel,
2956
- paginationModel: paginationModelParsed,
2957
- onPaginationModelChange: (model, details) => {
2958
- const paginationModel = _objectSpread2(_objectSpread2({}, model), {}, {
2959
- direction: paginationModelParsed.page < model.page ? 'next' : 'back'
2960
- });
2961
- propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
1320
+ page: paginationModelParsed.page,
1321
+ pageSize: paginationModelParsed.pageSize,
1322
+ onPageChange: (page, details) => {
1323
+ console.log('page change', page);
1324
+ const direction = paginationModelParsed.page < page ? 'next' : 'back';
1325
+ propsOnPageChange === null || propsOnPageChange === void 0 ? void 0 : propsOnPageChange(page, details);
2962
1326
  updateUrl({
2963
1327
  filterModel: filterParsed,
2964
1328
  sortModel: sortModelParsed,
2965
- paginationModel: paginationModel,
1329
+ paginationModel: {
1330
+ page,
1331
+ pageSize: paginationModelParsed.pageSize,
1332
+ direction
1333
+ },
1334
+ columnsModel: apiRef.current.state.columns.columnVisibilityModel,
1335
+ pinnedColumnsModel: pinnedColumnsModel
1336
+ }, search, localStorageVersion, historyReplace, columns);
1337
+ },
1338
+ onPageSizeChange: (pageSize, details) => {
1339
+ propsOnPageSizeChange === null || propsOnPageSizeChange === void 0 ? void 0 : propsOnPageSizeChange(pageSize, details);
1340
+ updateUrl({
1341
+ filterModel: filterParsed,
1342
+ sortModel: sortModelParsed,
1343
+ paginationModel: {
1344
+ page: paginationModelParsed.page,
1345
+ pageSize,
1346
+ direction: paginationModelParsed.direction
1347
+ },
2966
1348
  columnsModel: apiRef.current.state.columns.columnVisibilityModel,
2967
1349
  pinnedColumnsModel: pinnedColumnsModel
2968
1350
  }, search, localStorageVersion, historyReplace, columns);
@@ -2988,7 +1370,7 @@ const useStatefulTable = props => {
2988
1370
  };
2989
1371
  };
2990
1372
 
2991
- const _excluded = ["apiRef", "autoHeight", "className", "columns", "slots", "slotProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "paginationModel", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "rowSelectionModel", "onColumnWidthChange", "onPaginationModelChange", "onRowSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "pagination", "paginationPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount"];
1373
+ const _excluded = ["apiRef", "autoHeight", "className", "columns", "columnTypes", "components", "componentsProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "page", "pageSize", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "selectionModel", "onColumnWidthChange", "onPageChange", "onPageSizeChange", "onSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "pagination", "paginationPlacement", "paginationProps", "rows", "rowsPerPageOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount"];
2992
1374
  const COMPONENT_NAME = 'DataGrid';
2993
1375
  const CLASSNAME = 'redsift-datagrid';
2994
1376
  const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
@@ -2998,13 +1380,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2998
1380
  autoHeight,
2999
1381
  className,
3000
1382
  columns,
3001
- slots,
3002
- slotProps,
1383
+ columnTypes: propsColumnTypes,
1384
+ components,
1385
+ componentsProps,
3003
1386
  filterModel: propsFilterModel,
3004
1387
  columnVisibilityModel: propsColumnVisibilityModel,
3005
1388
  pinnedColumns: propsPinnedColumns,
3006
1389
  sortModel: propsSortModel,
3007
- paginationModel: propsPaginationModel,
1390
+ page: propsPage,
1391
+ pageSize: propsPageSize,
3008
1392
  height: propsHeight,
3009
1393
  hideToolbar,
3010
1394
  initialState,
@@ -3013,10 +1397,11 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3013
1397
  localStorageVersion,
3014
1398
  previousLocalStorageVersions,
3015
1399
  onFilterModelChange: propsOnFilterModelChange,
3016
- rowSelectionModel: propsRowSelectionModel,
1400
+ selectionModel: propsSelectionModel,
3017
1401
  onColumnWidthChange: propsOnColumnWidthChange,
3018
- onPaginationModelChange: propsOnPaginationModelChange,
3019
- onRowSelectionModelChange: propsOnRowSelectionModelChange,
1402
+ onPageChange: propsOnPageChange,
1403
+ onPageSizeChange: propsOnPageSizeChange,
1404
+ onSelectionModelChange: propsOnSelectionModelChange,
3020
1405
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
3021
1406
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
3022
1407
  onSortModelChange: propsOnSortModelChange,
@@ -3024,7 +1409,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3024
1409
  paginationPlacement = 'both',
3025
1410
  paginationProps,
3026
1411
  rows,
3027
- pageSizeOptions,
1412
+ rowsPerPageOptions,
3028
1413
  sx,
3029
1414
  theme: propsTheme,
3030
1415
  useRouter,
@@ -3032,41 +1417,46 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3032
1417
  rowCount
3033
1418
  } = props,
3034
1419
  forwardedProps = _objectWithoutProperties(props, _excluded);
3035
- const theme = useTheme$1(propsTheme);
1420
+ const theme = useTheme(propsTheme);
3036
1421
  const _apiRef = useGridApiRef();
3037
1422
  const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
3038
- const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
1423
+ const RenderedToolbar = components !== null && components !== void 0 && components.Toolbar ? components.Toolbar : Toolbar;
3039
1424
  LicenseInfo.setLicenseKey(license);
3040
1425
  const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
3041
1426
  const {
3042
1427
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
3043
1428
  onFilterModelChange: controlledOnFilterModelChange,
3044
- onPaginationModelChange: controlledOnPaginationModelChange,
1429
+ onPageChange: controlledOnPageChange,
1430
+ onPageSizeChange: controlledOnPageSizeChange,
3045
1431
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
3046
1432
  onSortModelChange: controlledOnSortModelChange
3047
1433
  } = useControlledDatagridState({
3048
1434
  initialState,
3049
- pageSizeOptions,
1435
+ rowsPerPageOptions,
3050
1436
  propsColumnVisibilityModel,
3051
1437
  propsFilterModel,
3052
1438
  propsOnColumnVisibilityModelChange,
3053
1439
  propsOnFilterModelChange,
3054
1440
  propsOnPinnedColumnsChange,
3055
1441
  propsOnSortModelChange,
3056
- propsPaginationModel,
1442
+ propsPage,
1443
+ propsPageSize,
3057
1444
  propsPinnedColumns,
3058
1445
  propsSortModel,
3059
- propsOnPaginationModelChange
1446
+ propsOnPageChange,
1447
+ propsOnPageSizeChange
3060
1448
  });
3061
1449
  const {
3062
1450
  columnVisibilityModel,
3063
1451
  filterModel,
3064
1452
  onColumnVisibilityModelChange,
3065
1453
  onFilterModelChange,
3066
- onPaginationModelChange,
1454
+ onPageChange,
1455
+ onPageSizeChange,
3067
1456
  onPinnedColumnsChange,
3068
1457
  onSortModelChange,
3069
- paginationModel,
1458
+ page,
1459
+ pageSize,
3070
1460
  pinnedColumns,
3071
1461
  sortModel,
3072
1462
  onColumnWidthChange
@@ -3077,46 +1467,40 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3077
1467
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
3078
1468
  onColumnWidthChange: propsOnColumnWidthChange,
3079
1469
  onFilterModelChange: controlledOnFilterModelChange,
3080
- onPaginationModelChange: controlledOnPaginationModelChange,
1470
+ onPageChange: controlledOnPageChange,
1471
+ onPageSizeChange: controlledOnPageSizeChange,
3081
1472
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
3082
1473
  onSortModelChange: controlledOnSortModelChange,
3083
1474
  useRouter: useRouter,
3084
1475
  localStorageVersion,
3085
1476
  previousLocalStorageVersions
3086
1477
  });
3087
- const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
1478
+ const [selectionModel, setSelectionModel] = useState(propsSelectionModel !== null && propsSelectionModel !== void 0 ? propsSelectionModel : []);
3088
1479
  useEffect(() => {
3089
- setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
3090
- }, [propsRowSelectionModel]);
3091
- const onRowSelectionModelChange = (selectionModel, details) => {
3092
- if (propsOnRowSelectionModelChange) {
3093
- propsOnRowSelectionModelChange(selectionModel, details);
1480
+ setSelectionModel(propsSelectionModel !== null && propsSelectionModel !== void 0 ? propsSelectionModel : []);
1481
+ }, [propsSelectionModel]);
1482
+ const onSelectionModelChange = (selectionModel, details) => {
1483
+ if (propsOnSelectionModelChange) {
1484
+ propsOnSelectionModelChange(selectionModel, details);
3094
1485
  } else {
3095
- setRowSelectionModel(selectionModel);
1486
+ setSelectionModel(selectionModel);
3096
1487
  }
3097
1488
  };
3098
1489
  const selectionStatus = useRef({
3099
1490
  type: 'none',
3100
1491
  numberOfSelectedRows: 0,
3101
1492
  numberOfSelectedRowsInPage: 0,
3102
- page: paginationModel.page,
3103
- pageSize: paginationModel.pageSize
1493
+ page,
1494
+ pageSize: pageSize
3104
1495
  });
3105
1496
 
3106
- // Version counter to force re-renders when selectionStatus ref changes
3107
- const [, forceSelectionUpdate] = useState(0);
3108
-
3109
- // The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
3110
- // for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
3111
- const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
3112
-
3113
1497
  // in server-side pagination we want to update the selection status
3114
1498
  // every time we navigate between pages, resize our page or select something
3115
1499
  useEffect(() => {
3116
1500
  if (paginationMode == 'server') {
3117
- onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatus, forceSelectionUpdate, isRowSelectable, paginationModel.page, paginationModel.pageSize);
1501
+ onServerSideSelectionStatusChange(Array.isArray(selectionModel) ? selectionModel : [selectionModel], apiRef, selectionStatus, isRowSelectable, page, pageSize);
3118
1502
  }
3119
- }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize]);
1503
+ }, [selectionModel, page, pageSize]);
3120
1504
  if (!Array.isArray(rows)) {
3121
1505
  return null;
3122
1506
  }
@@ -3149,13 +1533,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3149
1533
  filterModel: filterModel,
3150
1534
  onColumnVisibilityModelChange: onColumnVisibilityModelChange,
3151
1535
  onFilterModelChange: onFilterModelChange,
3152
- onPaginationModelChange: onPaginationModelChange,
1536
+ onPageChange: onPageChange,
1537
+ onPageSizeChange: onPageSizeChange,
3153
1538
  onPinnedColumnsChange: onPinnedColumnsChange,
3154
1539
  onSortModelChange: onSortModelChange,
3155
- paginationModel: paginationModel,
1540
+ page: page,
1541
+ pageSize: pageSize,
3156
1542
  pinnedColumns: pinnedColumns,
3157
1543
  sortModel: sortModel,
3158
- pageSizeOptions: pageSizeOptions,
1544
+ rowsPerPageOptions: rowsPerPageOptions,
3159
1545
  onColumnWidthChange: onColumnWidthChange,
3160
1546
  initialState: initialState,
3161
1547
  isRowSelectable: isRowSelectable,
@@ -3165,73 +1551,61 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3165
1551
  rows: rows,
3166
1552
  rowCount: rowCount,
3167
1553
  autoHeight: autoHeight,
3168
- checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
3169
- slots: _objectSpread2(_objectSpread2({
3170
- baseButton: BaseButton,
3171
- baseCheckbox: BaseCheckbox,
3172
- // baseTextField,
3173
- basePopper: BasePopper,
3174
- columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1554
+ checkboxSelectionVisibleOnly: Boolean(pagination),
1555
+ columnTypes: _objectSpread2(_objectSpread2({}, customColumnTypes), propsColumnTypes),
1556
+ components: _objectSpread2(_objectSpread2({
1557
+ BaseButton,
1558
+ BaseCheckbox,
1559
+ // BaseTextField,
1560
+ BasePopper,
1561
+ ColumnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3175
1562
  displayName: "ColumnFilteredIcon"
3176
1563
  })),
3177
- columnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1564
+ ColumnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3178
1565
  displayName: "ColumnSelectorIcon"
3179
1566
  })),
3180
- columnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1567
+ ColumnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3181
1568
  displayName: "ColumnSortedAscendingIcon"
3182
1569
  })),
3183
- columnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1570
+ ColumnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3184
1571
  displayName: "ColumnSortedDescendingIcon"
3185
1572
  })),
3186
- densityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1573
+ DensityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3187
1574
  displayName: "DensityCompactIcon"
3188
1575
  })),
3189
- densityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1576
+ DensityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3190
1577
  displayName: "DensityStandardIcon"
3191
1578
  })),
3192
- densityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1579
+ DensityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3193
1580
  displayName: "DensityComfortableIcon"
3194
1581
  })),
3195
- detailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1582
+ DetailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3196
1583
  displayName: "DetailPanelCollapseIcon"
3197
1584
  })),
3198
- detailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1585
+ DetailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3199
1586
  displayName: "DetailPanelExpandIcon"
3200
1587
  })),
3201
- exportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
1588
+ ExportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
3202
1589
  displayName: "ExportIcon"
3203
1590
  })),
3204
- openFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({
1591
+ OpenFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({
3205
1592
  displayName: "OpenFilterButtonIcon"
3206
1593
  }, props))
3207
- }, slots), {}, {
3208
- toolbar: props => /*#__PURE__*/React__default.createElement(ToolbarWrapper, _extends({}, props, {
3209
- hideToolbar: hideToolbar,
3210
- RenderedToolbar: RenderedToolbar,
3211
- filterModel: filterModel,
3212
- onFilterModelChange: onFilterModelChange,
3213
- pagination: pagination,
3214
- paginationPlacement: paginationPlacement,
3215
- selectionStatus: selectionStatus,
3216
- apiRef: apiRef,
3217
- isRowSelectable: isRowSelectable,
3218
- paginationModel: paginationModel,
3219
- onPaginationModelChange: onPaginationModelChange,
3220
- pageSizeOptions: pageSizeOptions,
3221
- paginationProps: paginationProps,
3222
- paginationMode: paginationMode,
3223
- rowCount: rowCount
3224
- })),
3225
- pagination: props => {
1594
+ }, components), {}, {
1595
+ Toolbar: ToolbarWrapper,
1596
+ Pagination: props => {
3226
1597
  return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
3227
1598
  displaySelection: false,
3228
1599
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3229
1600
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3230
1601
  selectionStatus: selectionStatus.current,
3231
- paginationModel: paginationModel,
3232
- onPaginationModelChange: onPaginationModelChange,
3233
- pageSizeOptions: pageSizeOptions,
1602
+ page: page,
1603
+ pageSize: pageSize,
1604
+ onPageChange: onPageChange,
1605
+ onPageSizeChange: onPageSizeChange,
1606
+ rowsPerPageOptions: rowsPerPageOptions,
3234
1607
  paginationProps: paginationProps,
1608
+ paginationMode: paginationMode,
3235
1609
  rowCount: rowCount
3236
1610
  })) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends({}, props, {
3237
1611
  displaySelection: false,
@@ -3240,16 +1614,39 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3240
1614
  selectionStatus: selectionStatus.current,
3241
1615
  apiRef: apiRef,
3242
1616
  isRowSelectable: isRowSelectable,
3243
- paginationModel: paginationModel,
3244
- onPaginationModelChange: onPaginationModelChange,
3245
- pageSizeOptions: pageSizeOptions,
3246
- paginationProps: paginationProps
1617
+ page: page,
1618
+ pageSize: pageSize,
1619
+ onPageChange: onPageChange,
1620
+ onPageSizeChange: onPageSizeChange,
1621
+ rowsPerPageOptions: rowsPerPageOptions,
1622
+ paginationProps: paginationProps,
1623
+ paginationMode: paginationMode
3247
1624
  })) : null;
3248
1625
  }
3249
1626
  }),
3250
- slotProps: _objectSpread2({}, slotProps),
3251
- rowSelectionModel: rowSelectionModel,
3252
- onRowSelectionModelChange: (newSelectionModel, details) => {
1627
+ componentsProps: _objectSpread2(_objectSpread2({}, componentsProps), {}, {
1628
+ toolbar: _objectSpread2({
1629
+ hideToolbar,
1630
+ RenderedToolbar,
1631
+ filterModel,
1632
+ onFilterModelChange,
1633
+ pagination,
1634
+ paginationPlacement,
1635
+ selectionStatus,
1636
+ apiRef,
1637
+ isRowSelectable,
1638
+ page,
1639
+ pageSize,
1640
+ onPageChange,
1641
+ onPageSizeChange,
1642
+ rowsPerPageOptions,
1643
+ paginationProps,
1644
+ paginationMode,
1645
+ rowCount
1646
+ }, componentsProps === null || componentsProps === void 0 ? void 0 : componentsProps.toolbar)
1647
+ }),
1648
+ selectionModel: selectionModel,
1649
+ onSelectionModelChange: (newSelectionModel, details) => {
3253
1650
  if (pagination && paginationMode != 'server') {
3254
1651
  const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref => {
3255
1652
  let {
@@ -3306,9 +1703,8 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3306
1703
  numberOfSelectedRows
3307
1704
  };
3308
1705
  }
3309
- forceSelectionUpdate(v => v + 1);
3310
1706
  }
3311
- onRowSelectionModelChange === null || onRowSelectionModelChange === void 0 ? void 0 : onRowSelectionModelChange(newSelectionModel, details);
1707
+ onSelectionModelChange === null || onSelectionModelChange === void 0 ? void 0 : onSelectionModelChange(newSelectionModel, details);
3312
1708
  },
3313
1709
  sx: _objectSpread2(_objectSpread2({}, sx), {}, {
3314
1710
  '.MuiDataGrid-columnHeaders': {
@@ -3324,5 +1720,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3324
1720
  StatefulDataGrid.className = CLASSNAME;
3325
1721
  StatefulDataGrid.displayName = COMPONENT_NAME;
3326
1722
 
3327
- export { getSearchParamsFromSorting as $, getGridStringArrayOperatorsWithSelectOnStringArrayColumns as A, SORT_MODEL_KEY as B, CONTAINS_ANY_OF as C, DOES_NOT_CONTAIN as D, ENDS_WITH_ANY_OF as E, FILTER_MODEL_KEY as F, PINNED_COLUMNS as G, HAS as H, IS_BETWEEN as I, DIMENSION_MODEL_KEY as J, FILTER_SEARCH_KEY as K, CATEGORIES as L, buildStorageKey as M, clearPreviousVersionStorage as N, decodeValue as O, PAGINATION_MODEL_KEY as P, encodeValue as Q, urlSearchParamsToString as R, STARTS_WITH_ANY_OF as S, numberOperatorEncoder as T, numberOperatorDecoder as U, VISIBILITY_MODEL_KEY as V, isOperatorValueValid as W, isValueValid as X, getFilterModelFromString as Y, getSearchParamsFromFilterModel as Z, getSortingFromString as _, DOES_NOT_EQUAL as a, getPaginationFromString as a0, getSearchParamsFromPagination as a1, getColumnVisibilityFromString as a2, getSearchParamsFromColumnVisibility as a3, getPinnedColumnsFromString as a4, getSearchParamsFromPinnedColumns as a5, getSearchParamsFromTab as a6, getFinalSearch as a7, getModelsParsedOrUpdateLocalStorage as a8, updateUrl as a9, areFilterModelsEquivalent as aa, StatefulDataGrid as ab, DOES_NOT_HAVE as b, DOES_NOT_HAVE_WITH_SELECT as c, HAS_WITH_SELECT as d, HAS_ONLY as e, HAS_ONLY_WITH_SELECT as f, getGridNumericOperators as g, IS as h, IS_WITH_SELECT as i, IS_NOT as j, IS_NOT_WITH_SELECT as k, getGridStringOperators as l, CONTAINS_ANY_OF_I as m, DOES_NOT_HAVE_ANY_OF as n, operatorList as o, DOES_NOT_HAVE_ANY_OF_WITH_SELECT as p, IS_ANY_OF as q, IS_ANY_OF_WITH_SELECT as r, IS_ANY_OF_I as s, IS_ANY_OF_I_WITH_SELECT as t, HAS_ANY_OF as u, HAS_ANY_OF_WITH_SELECT as v, IS_NOT_ANY_OF as w, IS_NOT_ANY_OF_WITH_SELECT as x, getGridStringArrayOperators as y, getGridStringArrayOperatorsWithSelect as z };
1723
+ export { getModelsParsedOrUpdateLocalStorage as A, updateUrl as B, CATEGORIES as C, DIMENSION_MODEL_KEY as D, areFilterModelsEquivalent as E, FILTER_MODEL_KEY as F, StatefulDataGrid as G, PAGINATION_MODEL_KEY as P, SORT_MODEL_KEY as S, VISIBILITY_MODEL_KEY as V, PINNED_COLUMNS as a, FILTER_SEARCH_KEY as b, buildStorageKey as c, clearPreviousVersionStorage as d, convertToDisplayFormat as e, convertFromDisplayFormat as f, getDecodedSearchFromUrl as g, buildQueryParamsString as h, areSearchStringsEqual as i, decodeValue as j, encodeValue as k, numberOperatorDecoder as l, getFilterModelFromString as m, numberOperatorEncoder as n, getSearchParamsFromFilterModel as o, getSortingFromString as p, getSearchParamsFromSorting as q, getPaginationFromString as r, getSearchParamsFromPagination as s, getSearchParamsFromColumnVisibility as t, urlSearchParamsToString as u, getColumnVisibilityFromString as v, getPinnedColumnsFromString as w, getSearchParamsFromPinnedColumns as x, getSearchParamsFromTab as y, getFinalSearch as z };
3328
1724
  //# sourceMappingURL=StatefulDataGrid2.js.map