@redsift/table 11.10.0-muiv6 → 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,1791 +1,15 @@
1
- import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends$1 } 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, ThemeProvider, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite } from '@redsift/design-system';
6
- import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, 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 { _ as _objectWithoutPropertiesLoose, a as _extends, d as defaultSxConfig, i as isPlainObject, s as styled, b as styleFunctionSx, u as useTheme, c as clsx, e as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, g as generateUtilityClasses, f as generateUtilityClass, h as styled$1, j as useThemeProps, k as capitalize, l as composeClasses, r as rootShouldForwardProp, m as refType } from './Portal.js';
10
- import { j as jsxRuntimeExports } from './jsx-runtime.js';
11
- import { u as useFormControl, f as formControlState, i as isAdornedStart, a as isFilled, F as FormControlContext, b as useId, c as Select, I as Input, d 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
- function isMuiElement(element, muiNames) {
17
- return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf(element.type.muiName) !== -1;
18
- }
19
-
20
- const _excluded$7 = ["sx"];
21
- const splitProps = props => {
22
- var _props$theme$unstable, _props$theme;
23
- const result = {
24
- systemProps: {},
25
- otherProps: {}
26
- };
27
- const config = (_props$theme$unstable = props == null ? void 0 : (_props$theme = props.theme) == null ? void 0 : _props$theme.unstable_sxConfig) != null ? _props$theme$unstable : defaultSxConfig;
28
- Object.keys(props).forEach(prop => {
29
- if (config[prop]) {
30
- result.systemProps[prop] = props[prop];
31
- } else {
32
- result.otherProps[prop] = props[prop];
33
- }
34
- });
35
- return result;
36
- };
37
- function extendSxProp(props) {
38
- const {
39
- sx: inSx
40
- } = props,
41
- other = _objectWithoutPropertiesLoose(props, _excluded$7);
42
- const {
43
- systemProps,
44
- otherProps
45
- } = splitProps(other);
46
- let finalSx;
47
- if (Array.isArray(inSx)) {
48
- finalSx = [systemProps, ...inSx];
49
- } else if (typeof inSx === 'function') {
50
- finalSx = (...args) => {
51
- const result = inSx(...args);
52
- if (!isPlainObject(result)) {
53
- return systemProps;
54
- }
55
- return _extends({}, systemProps, result);
56
- };
57
- } else {
58
- finalSx = _extends({}, systemProps, inSx);
59
- }
60
- return _extends({}, otherProps, {
61
- sx: finalSx
62
- });
63
- }
64
-
65
- const _excluded$6 = ["className", "component"];
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 _extendSxProp = extendSxProp(inProps),
79
- {
80
- className,
81
- component = 'div'
82
- } = _extendSxProp,
83
- other = _objectWithoutPropertiesLoose(_extendSxProp, _excluded$6);
84
- return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, _extends({
85
- as: component,
86
- ref: ref,
87
- className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
88
- theme: themeId ? theme[themeId] || theme : theme
89
- }, other));
90
- });
91
- return Box;
92
- }
93
-
94
- const defaultTheme = createTheme();
95
- const Box = createBox({
96
- themeId: THEME_ID,
97
- defaultTheme,
98
- defaultClassName: 'MuiBox-root',
99
- generateClassName: ClassNameGenerator.generate
100
- });
101
- process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
102
- // ----------------------------- Warning --------------------------------
103
- // | These PropTypes are generated from the TypeScript type definitions |
104
- // | To update them edit the d.ts file and run "yarn proptypes" |
105
- // ----------------------------------------------------------------------
106
- /**
107
- * @ignore
108
- */
109
- children: PropTypes.node,
110
- /**
111
- * The component used for the root node.
112
- * Either a string to use a HTML element or a component.
113
- */
114
- component: PropTypes.elementType,
115
- /**
116
- * The system prop that allows defining system overrides as well as additional CSS styles.
117
- */
118
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
119
- } : void 0;
120
- var Box$1 = Box;
121
-
122
- function getFormLabelUtilityClasses(slot) {
123
- return generateUtilityClass('MuiFormLabel', slot);
124
- }
125
- const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
126
- var formLabelClasses$1 = formLabelClasses;
127
-
128
- const _excluded$5 = ["children", "className", "color", "component", "disabled", "error", "filled", "focused", "required"];
129
- const useUtilityClasses$4 = ownerState => {
130
- const {
131
- classes,
132
- color,
133
- focused,
134
- disabled,
135
- error,
136
- filled,
137
- required
138
- } = ownerState;
139
- const slots = {
140
- root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
141
- asterisk: ['asterisk', error && 'error']
142
- };
143
- return composeClasses(slots, getFormLabelUtilityClasses, classes);
144
- };
145
- const FormLabelRoot = styled$1('label', {
146
- name: 'MuiFormLabel',
147
- slot: 'Root',
148
- overridesResolver: ({
149
- ownerState
150
- }, styles) => {
151
- return _extends({}, styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled);
152
- }
153
- })(({
154
- theme,
155
- ownerState
156
- }) => _extends({
157
- color: (theme.vars || theme).palette.text.secondary
158
- }, theme.typography.body1, {
159
- lineHeight: '1.4375em',
160
- padding: 0,
161
- position: 'relative',
162
- [`&.${formLabelClasses$1.focused}`]: {
163
- color: (theme.vars || theme).palette[ownerState.color].main
164
- },
165
- [`&.${formLabelClasses$1.disabled}`]: {
166
- color: (theme.vars || theme).palette.text.disabled
167
- },
168
- [`&.${formLabelClasses$1.error}`]: {
169
- color: (theme.vars || theme).palette.error.main
170
- }
171
- }));
172
- const AsteriskComponent = styled$1('span', {
173
- name: 'MuiFormLabel',
174
- slot: 'Asterisk',
175
- overridesResolver: (props, styles) => styles.asterisk
176
- })(({
177
- theme
178
- }) => ({
179
- [`&.${formLabelClasses$1.error}`]: {
180
- color: (theme.vars || theme).palette.error.main
181
- }
182
- }));
183
- const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
184
- const props = useThemeProps({
185
- props: inProps,
186
- name: 'MuiFormLabel'
187
- });
188
- const {
189
- children,
190
- className,
191
- component = 'label'
192
- } = props,
193
- other = _objectWithoutPropertiesLoose(props, _excluded$5);
194
- const muiFormControl = useFormControl();
195
- const fcs = formControlState({
196
- props,
197
- muiFormControl,
198
- states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
199
- });
200
- const ownerState = _extends({}, props, {
201
- color: fcs.color || 'primary',
202
- component,
203
- disabled: fcs.disabled,
204
- error: fcs.error,
205
- filled: fcs.filled,
206
- focused: fcs.focused,
207
- required: fcs.required
208
- });
209
- const classes = useUtilityClasses$4(ownerState);
210
- return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, _extends({
211
- as: component,
212
- ownerState: ownerState,
213
- className: clsx(classes.root, className),
214
- ref: ref
215
- }, other, {
216
- children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
217
- ownerState: ownerState,
218
- "aria-hidden": true,
219
- className: classes.asterisk,
220
- children: ["\u2009", '*']
221
- })]
222
- }));
223
- });
224
- process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
225
- // ----------------------------- Warning --------------------------------
226
- // | These PropTypes are generated from the TypeScript type definitions |
227
- // | To update them edit the d.ts file and run "yarn proptypes" |
228
- // ----------------------------------------------------------------------
229
- /**
230
- * The content of the component.
231
- */
232
- children: PropTypes.node,
233
- /**
234
- * Override or extend the styles applied to the component.
235
- */
236
- classes: PropTypes.object,
237
- /**
238
- * @ignore
239
- */
240
- className: PropTypes.string,
241
- /**
242
- * The color of the component.
243
- * It supports both default and custom theme colors, which can be added as shown in the
244
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#adding-new-colors).
245
- */
246
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
247
- /**
248
- * The component used for the root node.
249
- * Either a string to use a HTML element or a component.
250
- */
251
- component: PropTypes.elementType,
252
- /**
253
- * If `true`, the label should be displayed in a disabled state.
254
- */
255
- disabled: PropTypes.bool,
256
- /**
257
- * If `true`, the label is displayed in an error state.
258
- */
259
- error: PropTypes.bool,
260
- /**
261
- * If `true`, the label should use filled classes key.
262
- */
263
- filled: PropTypes.bool,
264
- /**
265
- * If `true`, the input of this label is focused (used by `FormGroup` components).
266
- */
267
- focused: PropTypes.bool,
268
- /**
269
- * If `true`, the label will indicate that the `input` is required.
270
- */
271
- required: PropTypes.bool,
272
- /**
273
- * The system prop that allows defining system overrides as well as additional CSS styles.
274
- */
275
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
276
- } : void 0;
277
- var FormLabel$1 = FormLabel;
278
-
279
- function getInputLabelUtilityClasses(slot) {
280
- return generateUtilityClass('MuiInputLabel', slot);
281
- }
282
- generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
283
-
284
- const _excluded$4 = ["disableAnimation", "margin", "shrink", "variant", "className"];
285
- const useUtilityClasses$3 = ownerState => {
286
- const {
287
- classes,
288
- formControl,
289
- size,
290
- shrink,
291
- disableAnimation,
292
- variant,
293
- required
294
- } = ownerState;
295
- const slots = {
296
- root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size === 'small' && 'sizeSmall', variant],
297
- asterisk: [required && 'asterisk']
298
- };
299
- const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
300
- return _extends({}, classes, composedClasses);
301
- };
302
- const InputLabelRoot = styled$1(FormLabel$1, {
303
- shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
304
- name: 'MuiInputLabel',
305
- slot: 'Root',
306
- overridesResolver: (props, styles) => {
307
- const {
308
- ownerState
309
- } = props;
310
- return [{
311
- [`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
312
- }, styles.root, ownerState.formControl && styles.formControl, ownerState.size === 'small' && styles.sizeSmall, ownerState.shrink && styles.shrink, !ownerState.disableAnimation && styles.animated, styles[ownerState.variant]];
313
- }
314
- })(({
315
- theme,
316
- ownerState
317
- }) => _extends({
318
- display: 'block',
319
- transformOrigin: 'top left',
320
- whiteSpace: 'nowrap',
321
- overflow: 'hidden',
322
- textOverflow: 'ellipsis',
323
- maxWidth: '100%'
324
- }, ownerState.formControl && {
325
- position: 'absolute',
326
- left: 0,
327
- top: 0,
328
- // slight alteration to spec spacing to match visual spec result
329
- transform: 'translate(0, 20px) scale(1)'
330
- }, ownerState.size === 'small' && {
331
- // Compensation for the `Input.inputSizeSmall` style.
332
- transform: 'translate(0, 17px) scale(1)'
333
- }, ownerState.shrink && {
334
- transform: 'translate(0, -1.5px) scale(0.75)',
335
- transformOrigin: 'top left',
336
- maxWidth: '133%'
337
- }, !ownerState.disableAnimation && {
338
- transition: theme.transitions.create(['color', 'transform', 'max-width'], {
339
- duration: theme.transitions.duration.shorter,
340
- easing: theme.transitions.easing.easeOut
341
- })
342
- }, ownerState.variant === 'filled' && _extends({
343
- // Chrome's autofill feature gives the input field a yellow background.
344
- // Since the input field is behind the label in the HTML tree,
345
- // the input field is drawn last and hides the label with an opaque background color.
346
- // zIndex: 1 will raise the label above opaque background-colors of input.
347
- zIndex: 1,
348
- pointerEvents: 'none',
349
- transform: 'translate(12px, 16px) scale(1)',
350
- maxWidth: 'calc(100% - 24px)'
351
- }, ownerState.size === 'small' && {
352
- transform: 'translate(12px, 13px) scale(1)'
353
- }, ownerState.shrink && _extends({
354
- userSelect: 'none',
355
- pointerEvents: 'auto',
356
- transform: 'translate(12px, 7px) scale(0.75)',
357
- maxWidth: 'calc(133% - 24px)'
358
- }, ownerState.size === 'small' && {
359
- transform: 'translate(12px, 4px) scale(0.75)'
360
- })), ownerState.variant === 'outlined' && _extends({
361
- // see comment above on filled.zIndex
362
- zIndex: 1,
363
- pointerEvents: 'none',
364
- transform: 'translate(14px, 16px) scale(1)',
365
- maxWidth: 'calc(100% - 24px)'
366
- }, ownerState.size === 'small' && {
367
- transform: 'translate(14px, 9px) scale(1)'
368
- }, ownerState.shrink && {
369
- userSelect: 'none',
370
- pointerEvents: 'auto',
371
- // Theoretically, we should have (8+5)*2/0.75 = 34px
372
- // but it feels a better when it bleeds a bit on the left, so 32px.
373
- maxWidth: 'calc(133% - 32px)',
374
- transform: 'translate(14px, -9px) scale(0.75)'
375
- })));
376
- const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
377
- const props = useThemeProps({
378
- name: 'MuiInputLabel',
379
- props: inProps
380
- });
381
- const {
382
- disableAnimation = false,
383
- shrink: shrinkProp,
384
- className
385
- } = props,
386
- other = _objectWithoutPropertiesLoose(props, _excluded$4);
387
- const muiFormControl = useFormControl();
388
- let shrink = shrinkProp;
389
- if (typeof shrink === 'undefined' && muiFormControl) {
390
- shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
391
- }
392
- const fcs = formControlState({
393
- props,
394
- muiFormControl,
395
- states: ['size', 'variant', 'required']
396
- });
397
- const ownerState = _extends({}, props, {
398
- disableAnimation,
399
- formControl: muiFormControl,
400
- shrink,
401
- size: fcs.size,
402
- variant: fcs.variant,
403
- required: fcs.required
404
- });
405
- const classes = useUtilityClasses$3(ownerState);
406
- return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, _extends({
407
- "data-shrink": shrink,
408
- ownerState: ownerState,
409
- ref: ref,
410
- className: clsx(classes.root, className)
411
- }, other, {
412
- classes: classes
413
- }));
414
- });
415
- process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
416
- // ----------------------------- Warning --------------------------------
417
- // | These PropTypes are generated from the TypeScript type definitions |
418
- // | To update them edit the d.ts file and run "yarn proptypes" |
419
- // ----------------------------------------------------------------------
420
- /**
421
- * The content of the component.
422
- */
423
- children: PropTypes.node,
424
- /**
425
- * Override or extend the styles applied to the component.
426
- */
427
- classes: PropTypes.object,
428
- /**
429
- * @ignore
430
- */
431
- className: PropTypes.string,
432
- /**
433
- * The color of the component.
434
- * It supports both default and custom theme colors, which can be added as shown in the
435
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#adding-new-colors).
436
- */
437
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
438
- /**
439
- * If `true`, the transition animation is disabled.
440
- * @default false
441
- */
442
- disableAnimation: PropTypes.bool,
443
- /**
444
- * If `true`, the component is disabled.
445
- */
446
- disabled: PropTypes.bool,
447
- /**
448
- * If `true`, the label is displayed in an error state.
449
- */
450
- error: PropTypes.bool,
451
- /**
452
- * If `true`, the `input` of this label is focused.
453
- */
454
- focused: PropTypes.bool,
455
- /**
456
- * If `dense`, will adjust vertical spacing. This is normally obtained via context from
457
- * FormControl.
458
- */
459
- margin: PropTypes.oneOf(['dense']),
460
- /**
461
- * if `true`, the label will indicate that the `input` is required.
462
- */
463
- required: PropTypes.bool,
464
- /**
465
- * If `true`, the label is shrunk.
466
- */
467
- shrink: PropTypes.bool,
468
- /**
469
- * The size of the component.
470
- * @default 'normal'
471
- */
472
- size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
473
- /**
474
- * The system prop that allows defining system overrides as well as additional CSS styles.
475
- */
476
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
477
- /**
478
- * The variant to use.
479
- */
480
- variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
481
- } : void 0;
482
- var InputLabel$1 = InputLabel;
483
-
484
- function getFormControlUtilityClasses(slot) {
485
- return generateUtilityClass('MuiFormControl', slot);
486
- }
487
- generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
488
-
489
- const _excluded$3 = ["children", "className", "color", "component", "disabled", "error", "focused", "fullWidth", "hiddenLabel", "margin", "required", "size", "variant"];
490
- const useUtilityClasses$2 = ownerState => {
491
- const {
492
- classes,
493
- margin,
494
- fullWidth
495
- } = ownerState;
496
- const slots = {
497
- root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
498
- };
499
- return composeClasses(slots, getFormControlUtilityClasses, classes);
500
- };
501
- const FormControlRoot = styled$1('div', {
502
- name: 'MuiFormControl',
503
- slot: 'Root',
504
- overridesResolver: ({
505
- ownerState
506
- }, styles) => {
507
- return _extends({}, styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth);
508
- }
509
- })(({
510
- ownerState
511
- }) => _extends({
512
- display: 'inline-flex',
513
- flexDirection: 'column',
514
- position: 'relative',
515
- // Reset fieldset default style.
516
- minWidth: 0,
517
- padding: 0,
518
- margin: 0,
519
- border: 0,
520
- verticalAlign: 'top'
521
- }, ownerState.margin === 'normal' && {
522
- marginTop: 16,
523
- marginBottom: 8
524
- }, ownerState.margin === 'dense' && {
525
- marginTop: 8,
526
- marginBottom: 4
527
- }, ownerState.fullWidth && {
528
- width: '100%'
529
- }));
530
-
531
- /**
532
- * Provides context such as filled/focused/error/required for form inputs.
533
- * Relying on the context provides high flexibility and ensures that the state always stays
534
- * consistent across the children of the `FormControl`.
535
- * This context is used by the following components:
536
- *
537
- * - FormLabel
538
- * - FormHelperText
539
- * - Input
540
- * - InputLabel
541
- *
542
- * You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
543
- *
544
- * ```jsx
545
- * <FormControl>
546
- * <InputLabel htmlFor="my-input">Email address</InputLabel>
547
- * <Input id="my-input" aria-describedby="my-helper-text" />
548
- * <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
549
- * </FormControl>
550
- * ```
551
- *
552
- * ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
553
- * For instance, only one input can be focused at the same time, the state shouldn't be shared.
554
- */
555
- const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
556
- const props = useThemeProps({
557
- props: inProps,
558
- name: 'MuiFormControl'
559
- });
560
- const {
561
- children,
562
- className,
563
- color = 'primary',
564
- component = 'div',
565
- disabled = false,
566
- error = false,
567
- focused: visuallyFocused,
568
- fullWidth = false,
569
- hiddenLabel = false,
570
- margin = 'none',
571
- required = false,
572
- size = 'medium',
573
- variant = 'outlined'
574
- } = props,
575
- other = _objectWithoutPropertiesLoose(props, _excluded$3);
576
- const ownerState = _extends({}, props, {
577
- color,
578
- component,
579
- disabled,
580
- error,
581
- fullWidth,
582
- hiddenLabel,
583
- margin,
584
- required,
585
- size,
586
- variant
587
- });
588
- const classes = useUtilityClasses$2(ownerState);
589
- const [adornedStart, setAdornedStart] = React.useState(() => {
590
- // We need to iterate through the children and find the Input in order
591
- // to fully support server-side rendering.
592
- let initialAdornedStart = false;
593
- if (children) {
594
- React.Children.forEach(children, child => {
595
- if (!isMuiElement(child, ['Input', 'Select'])) {
596
- return;
597
- }
598
- const input = isMuiElement(child, ['Select']) ? child.props.input : child;
599
- if (input && isAdornedStart(input.props)) {
600
- initialAdornedStart = true;
601
- }
602
- });
603
- }
604
- return initialAdornedStart;
605
- });
606
- const [filled, setFilled] = React.useState(() => {
607
- // We need to iterate through the children and find the Input in order
608
- // to fully support server-side rendering.
609
- let initialFilled = false;
610
- if (children) {
611
- React.Children.forEach(children, child => {
612
- if (!isMuiElement(child, ['Input', 'Select'])) {
613
- return;
614
- }
615
- if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
616
- initialFilled = true;
617
- }
618
- });
619
- }
620
- return initialFilled;
621
- });
622
- const [focusedState, setFocused] = React.useState(false);
623
- if (disabled && focusedState) {
624
- setFocused(false);
625
- }
626
- const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
627
- let registerEffect;
628
- if (process.env.NODE_ENV !== 'production') {
629
- // eslint-disable-next-line react-hooks/rules-of-hooks
630
- const registeredInput = React.useRef(false);
631
- registerEffect = () => {
632
- if (registeredInput.current) {
633
- console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
634
- }
635
- registeredInput.current = true;
636
- return () => {
637
- registeredInput.current = false;
638
- };
639
- };
640
- }
641
- const childContext = React.useMemo(() => {
642
- return {
643
- adornedStart,
644
- setAdornedStart,
645
- color,
646
- disabled,
647
- error,
648
- filled,
649
- focused,
650
- fullWidth,
651
- hiddenLabel,
652
- size,
653
- onBlur: () => {
654
- setFocused(false);
655
- },
656
- onEmpty: () => {
657
- setFilled(false);
658
- },
659
- onFilled: () => {
660
- setFilled(true);
661
- },
662
- onFocus: () => {
663
- setFocused(true);
664
- },
665
- registerEffect,
666
- required,
667
- variant
668
- };
669
- }, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, required, size, variant]);
670
- return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
671
- value: childContext,
672
- children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, _extends({
673
- as: component,
674
- ownerState: ownerState,
675
- className: clsx(classes.root, className),
676
- ref: ref
677
- }, other, {
678
- children: children
679
- }))
680
- });
681
- });
682
- process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
683
- // ----------------------------- Warning --------------------------------
684
- // | These PropTypes are generated from the TypeScript type definitions |
685
- // | To update them edit the d.ts file and run "yarn proptypes" |
686
- // ----------------------------------------------------------------------
687
- /**
688
- * The content of the component.
689
- */
690
- children: PropTypes.node,
691
- /**
692
- * Override or extend the styles applied to the component.
693
- */
694
- classes: PropTypes.object,
695
- /**
696
- * @ignore
697
- */
698
- className: PropTypes.string,
699
- /**
700
- * The color of the component.
701
- * It supports both default and custom theme colors, which can be added as shown in the
702
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#adding-new-colors).
703
- * @default 'primary'
704
- */
705
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
706
- /**
707
- * The component used for the root node.
708
- * Either a string to use a HTML element or a component.
709
- */
710
- component: PropTypes.elementType,
711
- /**
712
- * If `true`, the label, input and helper text should be displayed in a disabled state.
713
- * @default false
714
- */
715
- disabled: PropTypes.bool,
716
- /**
717
- * If `true`, the label is displayed in an error state.
718
- * @default false
719
- */
720
- error: PropTypes.bool,
721
- /**
722
- * If `true`, the component is displayed in focused state.
723
- */
724
- focused: PropTypes.bool,
725
- /**
726
- * If `true`, the component will take up the full width of its container.
727
- * @default false
728
- */
729
- fullWidth: PropTypes.bool,
730
- /**
731
- * If `true`, the label is hidden.
732
- * This is used to increase density for a `FilledInput`.
733
- * Be sure to add `aria-label` to the `input` element.
734
- * @default false
735
- */
736
- hiddenLabel: PropTypes.bool,
737
- /**
738
- * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
739
- * @default 'none'
740
- */
741
- margin: PropTypes.oneOf(['dense', 'none', 'normal']),
742
- /**
743
- * If `true`, the label will indicate that the `input` is required.
744
- * @default false
745
- */
746
- required: PropTypes.bool,
747
- /**
748
- * The size of the component.
749
- * @default 'medium'
750
- */
751
- size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
752
- /**
753
- * The system prop that allows defining system overrides as well as additional CSS styles.
754
- */
755
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
756
- /**
757
- * The variant to use.
758
- * @default 'outlined'
759
- */
760
- variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
761
- } : void 0;
762
- var FormControl$1 = FormControl;
763
-
764
- function getFormHelperTextUtilityClasses(slot) {
765
- return generateUtilityClass('MuiFormHelperText', slot);
766
- }
767
- const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
768
- var formHelperTextClasses$1 = formHelperTextClasses;
769
-
770
- var _span;
771
- const _excluded$2 = ["children", "className", "component", "disabled", "error", "filled", "focused", "margin", "required", "variant"];
772
- const useUtilityClasses$1 = ownerState => {
773
- const {
774
- classes,
775
- contained,
776
- size,
777
- disabled,
778
- error,
779
- filled,
780
- focused,
781
- required
782
- } = ownerState;
783
- const slots = {
784
- root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
785
- };
786
- return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
787
- };
788
- const FormHelperTextRoot = styled$1('p', {
789
- name: 'MuiFormHelperText',
790
- slot: 'Root',
791
- overridesResolver: (props, styles) => {
792
- const {
793
- ownerState
794
- } = props;
795
- return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
796
- }
797
- })(({
798
- theme,
799
- ownerState
800
- }) => _extends({
801
- color: (theme.vars || theme).palette.text.secondary
802
- }, theme.typography.caption, {
803
- textAlign: 'left',
804
- marginTop: 3,
805
- marginRight: 0,
806
- marginBottom: 0,
807
- marginLeft: 0,
808
- [`&.${formHelperTextClasses$1.disabled}`]: {
809
- color: (theme.vars || theme).palette.text.disabled
810
- },
811
- [`&.${formHelperTextClasses$1.error}`]: {
812
- color: (theme.vars || theme).palette.error.main
813
- }
814
- }, ownerState.size === 'small' && {
815
- marginTop: 4
816
- }, ownerState.contained && {
817
- marginLeft: 14,
818
- marginRight: 14
819
- }));
820
- const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
821
- const props = useThemeProps({
822
- props: inProps,
823
- name: 'MuiFormHelperText'
824
- });
825
- const {
826
- children,
827
- className,
828
- component = 'p'
829
- } = props,
830
- other = _objectWithoutPropertiesLoose(props, _excluded$2);
831
- const muiFormControl = useFormControl();
832
- const fcs = formControlState({
833
- props,
834
- muiFormControl,
835
- states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
836
- });
837
- const ownerState = _extends({}, props, {
838
- component,
839
- contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
840
- variant: fcs.variant,
841
- size: fcs.size,
842
- disabled: fcs.disabled,
843
- error: fcs.error,
844
- filled: fcs.filled,
845
- focused: fcs.focused,
846
- required: fcs.required
847
- });
848
- const classes = useUtilityClasses$1(ownerState);
849
- return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, _extends({
850
- as: component,
851
- ownerState: ownerState,
852
- className: clsx(classes.root, className),
853
- ref: ref
854
- }, other, {
855
- children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
856
- _span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
857
- className: "notranslate",
858
- children: "\u200B"
859
- })) : children
860
- }));
861
- });
862
- process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
863
- // ----------------------------- Warning --------------------------------
864
- // | These PropTypes are generated from the TypeScript type definitions |
865
- // | To update them edit the d.ts file and run "yarn proptypes" |
866
- // ----------------------------------------------------------------------
867
- /**
868
- * The content of the component.
869
- *
870
- * If `' '` is provided, the component reserves one line height for displaying a future message.
871
- */
872
- children: PropTypes.node,
873
- /**
874
- * Override or extend the styles applied to the component.
875
- */
876
- classes: PropTypes.object,
877
- /**
878
- * @ignore
879
- */
880
- className: PropTypes.string,
881
- /**
882
- * The component used for the root node.
883
- * Either a string to use a HTML element or a component.
884
- */
885
- component: PropTypes.elementType,
886
- /**
887
- * If `true`, the helper text should be displayed in a disabled state.
888
- */
889
- disabled: PropTypes.bool,
890
- /**
891
- * If `true`, helper text should be displayed in an error state.
892
- */
893
- error: PropTypes.bool,
894
- /**
895
- * If `true`, the helper text should use filled classes key.
896
- */
897
- filled: PropTypes.bool,
898
- /**
899
- * If `true`, the helper text should use focused classes key.
900
- */
901
- focused: PropTypes.bool,
902
- /**
903
- * If `dense`, will adjust vertical spacing. This is normally obtained via context from
904
- * FormControl.
905
- */
906
- margin: PropTypes.oneOf(['dense']),
907
- /**
908
- * If `true`, the helper text should use required classes key.
909
- */
910
- required: PropTypes.bool,
911
- /**
912
- * The system prop that allows defining system overrides as well as additional CSS styles.
913
- */
914
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
915
- /**
916
- * The variant to use.
917
- */
918
- variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
919
- } : void 0;
920
- var FormHelperText$1 = FormHelperText;
921
-
922
- function getTextFieldUtilityClass(slot) {
923
- return generateUtilityClass('MuiTextField', slot);
924
- }
925
- generateUtilityClasses('MuiTextField', ['root']);
926
-
927
- const _excluded$1 = ["autoComplete", "autoFocus", "children", "className", "color", "defaultValue", "disabled", "error", "FormHelperTextProps", "fullWidth", "helperText", "id", "InputLabelProps", "inputProps", "InputProps", "inputRef", "label", "maxRows", "minRows", "multiline", "name", "onBlur", "onChange", "onClick", "onFocus", "placeholder", "required", "rows", "select", "SelectProps", "type", "value", "variant"];
928
- const variantComponent = {
929
- standard: Input,
930
- filled: FilledInput,
931
- outlined: OutlinedInput
932
- };
933
- const useUtilityClasses = ownerState => {
934
- const {
935
- classes
936
- } = ownerState;
937
- const slots = {
938
- root: ['root']
939
- };
940
- return composeClasses(slots, getTextFieldUtilityClass, classes);
941
- };
942
- const TextFieldRoot = styled$1(FormControl$1, {
943
- name: 'MuiTextField',
944
- slot: 'Root',
945
- overridesResolver: (props, styles) => styles.root
946
- })({});
947
-
948
- /**
949
- * The `TextField` is a convenience wrapper for the most common cases (80%).
950
- * It cannot be all things to all people, otherwise the API would grow out of control.
951
- *
952
- * ## Advanced Configuration
953
- *
954
- * It's important to understand that the text field is a simple abstraction
955
- * on top of the following components:
956
- *
957
- * - [FormControl](/material-ui/api/form-control/)
958
- * - [InputLabel](/material-ui/api/input-label/)
959
- * - [FilledInput](/material-ui/api/filled-input/)
960
- * - [OutlinedInput](/material-ui/api/outlined-input/)
961
- * - [Input](/material-ui/api/input/)
962
- * - [FormHelperText](/material-ui/api/form-helper-text/)
963
- *
964
- * If you wish to alter the props applied to the `input` element, you can do so as follows:
965
- *
966
- * ```jsx
967
- * const inputProps = {
968
- * step: 300,
969
- * };
970
- *
971
- * return <TextField id="time" type="time" inputProps={inputProps} />;
972
- * ```
973
- *
974
- * For advanced cases, please look at the source of TextField by clicking on the
975
- * "Edit this page" button above. Consider either:
976
- *
977
- * - using the upper case props for passing values directly to the components
978
- * - using the underlying components directly as shown in the demos
979
- */
980
- const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
981
- const props = useThemeProps({
982
- props: inProps,
983
- name: 'MuiTextField'
984
- });
985
- const {
986
- autoComplete,
987
- autoFocus = false,
988
- children,
989
- className,
990
- color = 'primary',
991
- defaultValue,
992
- disabled = false,
993
- error = false,
994
- FormHelperTextProps,
995
- fullWidth = false,
996
- helperText,
997
- id: idOverride,
998
- InputLabelProps,
999
- inputProps,
1000
- InputProps,
1001
- inputRef,
1002
- label,
1003
- maxRows,
1004
- minRows,
1005
- multiline = false,
1006
- name,
1007
- onBlur,
1008
- onChange,
1009
- onClick,
1010
- onFocus,
1011
- placeholder,
1012
- required = false,
1013
- rows,
1014
- select = false,
1015
- SelectProps,
1016
- type,
1017
- value,
1018
- variant = 'outlined'
1019
- } = props,
1020
- other = _objectWithoutPropertiesLoose(props, _excluded$1);
1021
- const ownerState = _extends({}, props, {
1022
- autoFocus,
1023
- color,
1024
- disabled,
1025
- error,
1026
- fullWidth,
1027
- multiline,
1028
- required,
1029
- select,
1030
- variant
1031
- });
1032
- const classes = useUtilityClasses(ownerState);
1033
- if (process.env.NODE_ENV !== 'production') {
1034
- if (select && !children) {
1035
- console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
1036
- }
1037
- }
1038
- const InputMore = {};
1039
- if (variant === 'outlined') {
1040
- if (InputLabelProps && typeof InputLabelProps.shrink !== 'undefined') {
1041
- InputMore.notched = InputLabelProps.shrink;
1042
- }
1043
- InputMore.label = label;
1044
- }
1045
- if (select) {
1046
- // unset defaults from textbox inputs
1047
- if (!SelectProps || !SelectProps.native) {
1048
- InputMore.id = undefined;
1049
- }
1050
- InputMore['aria-describedby'] = undefined;
1051
- }
1052
- const id = useId(idOverride);
1053
- const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
1054
- const inputLabelId = label && id ? `${id}-label` : undefined;
1055
- const InputComponent = variantComponent[variant];
1056
- const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputComponent, _extends({
1057
- "aria-describedby": helperTextId,
1058
- autoComplete: autoComplete,
1059
- autoFocus: autoFocus,
1060
- defaultValue: defaultValue,
1061
- fullWidth: fullWidth,
1062
- multiline: multiline,
1063
- name: name,
1064
- rows: rows,
1065
- maxRows: maxRows,
1066
- minRows: minRows,
1067
- type: type,
1068
- value: value,
1069
- id: id,
1070
- inputRef: inputRef,
1071
- onBlur: onBlur,
1072
- onChange: onChange,
1073
- onFocus: onFocus,
1074
- onClick: onClick,
1075
- placeholder: placeholder,
1076
- inputProps: inputProps
1077
- }, InputMore, InputProps));
1078
- return /*#__PURE__*/jsxRuntimeExports.jsxs(TextFieldRoot, _extends({
1079
- className: clsx(classes.root, className),
1080
- disabled: disabled,
1081
- error: error,
1082
- fullWidth: fullWidth,
1083
- ref: ref,
1084
- required: required,
1085
- color: color,
1086
- variant: variant,
1087
- ownerState: ownerState
1088
- }, other, {
1089
- children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabel$1, _extends({
1090
- htmlFor: id,
1091
- id: inputLabelId
1092
- }, InputLabelProps, {
1093
- children: label
1094
- })), select ? /*#__PURE__*/jsxRuntimeExports.jsx(Select, _extends({
1095
- "aria-describedby": helperTextId,
1096
- id: id,
1097
- labelId: inputLabelId,
1098
- value: value,
1099
- input: InputElement
1100
- }, SelectProps, {
1101
- children: children
1102
- })) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperText$1, _extends({
1103
- id: helperTextId
1104
- }, FormHelperTextProps, {
1105
- children: helperText
1106
- }))]
1107
- }));
1108
- });
1109
- process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
1110
- // ----------------------------- Warning --------------------------------
1111
- // | These PropTypes are generated from the TypeScript type definitions |
1112
- // | To update them edit the d.ts file and run "yarn proptypes" |
1113
- // ----------------------------------------------------------------------
1114
- /**
1115
- * This prop helps users to fill forms faster, especially on mobile devices.
1116
- * The name can be confusing, as it's more like an autofill.
1117
- * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
1118
- */
1119
- autoComplete: PropTypes.string,
1120
- /**
1121
- * If `true`, the `input` element is focused during the first mount.
1122
- * @default false
1123
- */
1124
- autoFocus: PropTypes.bool,
1125
- /**
1126
- * @ignore
1127
- */
1128
- children: PropTypes.node,
1129
- /**
1130
- * Override or extend the styles applied to the component.
1131
- */
1132
- classes: PropTypes.object,
1133
- /**
1134
- * @ignore
1135
- */
1136
- className: PropTypes.string,
1137
- /**
1138
- * The color of the component.
1139
- * It supports both default and custom theme colors, which can be added as shown in the
1140
- * [palette customization guide](https://mui.com/material-ui/customization/palette/#adding-new-colors).
1141
- * @default 'primary'
1142
- */
1143
- color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
1144
- /**
1145
- * The default value. Use when the component is not controlled.
1146
- */
1147
- defaultValue: PropTypes.any,
1148
- /**
1149
- * If `true`, the component is disabled.
1150
- * @default false
1151
- */
1152
- disabled: PropTypes.bool,
1153
- /**
1154
- * If `true`, the label is displayed in an error state.
1155
- * @default false
1156
- */
1157
- error: PropTypes.bool,
1158
- /**
1159
- * Props applied to the [`FormHelperText`](/material-ui/api/form-helper-text/) element.
1160
- */
1161
- FormHelperTextProps: PropTypes.object,
1162
- /**
1163
- * If `true`, the input will take up the full width of its container.
1164
- * @default false
1165
- */
1166
- fullWidth: PropTypes.bool,
1167
- /**
1168
- * The helper text content.
1169
- */
1170
- helperText: PropTypes.node,
1171
- /**
1172
- * The id of the `input` element.
1173
- * Use this prop to make `label` and `helperText` accessible for screen readers.
1174
- */
1175
- id: PropTypes.string,
1176
- /**
1177
- * Props applied to the [`InputLabel`](/material-ui/api/input-label/) element.
1178
- * Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
1179
- */
1180
- InputLabelProps: PropTypes.object,
1181
- /**
1182
- * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
1183
- */
1184
- inputProps: PropTypes.object,
1185
- /**
1186
- * Props applied to the Input element.
1187
- * It will be a [`FilledInput`](/material-ui/api/filled-input/),
1188
- * [`OutlinedInput`](/material-ui/api/outlined-input/) or [`Input`](/material-ui/api/input/)
1189
- * component depending on the `variant` prop value.
1190
- */
1191
- InputProps: PropTypes.object,
1192
- /**
1193
- * Pass a ref to the `input` element.
1194
- */
1195
- inputRef: refType,
1196
- /**
1197
- * The label content.
1198
- */
1199
- label: PropTypes.node,
1200
- /**
1201
- * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
1202
- * @default 'none'
1203
- */
1204
- margin: PropTypes.oneOf(['dense', 'none', 'normal']),
1205
- /**
1206
- * Maximum number of rows to display when multiline option is set to true.
1207
- */
1208
- maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1209
- /**
1210
- * Minimum number of rows to display when multiline option is set to true.
1211
- */
1212
- minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1213
- /**
1214
- * If `true`, a `textarea` element is rendered instead of an input.
1215
- * @default false
1216
- */
1217
- multiline: PropTypes.bool,
1218
- /**
1219
- * Name attribute of the `input` element.
1220
- */
1221
- name: PropTypes.string,
1222
- /**
1223
- * @ignore
1224
- */
1225
- onBlur: PropTypes.func,
1226
- /**
1227
- * Callback fired when the value is changed.
1228
- *
1229
- * @param {object} event The event source of the callback.
1230
- * You can pull out the new value by accessing `event.target.value` (string).
1231
- */
1232
- onChange: PropTypes.func,
1233
- /**
1234
- * @ignore
1235
- */
1236
- onClick: PropTypes.func,
1237
- /**
1238
- * @ignore
1239
- */
1240
- onFocus: PropTypes.func,
1241
- /**
1242
- * The short hint displayed in the `input` before the user enters a value.
1243
- */
1244
- placeholder: PropTypes.string,
1245
- /**
1246
- * If `true`, the label is displayed as required and the `input` element is required.
1247
- * @default false
1248
- */
1249
- required: PropTypes.bool,
1250
- /**
1251
- * Number of rows to display when multiline option is set to true.
1252
- */
1253
- rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
1254
- /**
1255
- * Render a [`Select`](/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
1256
- * If this option is set you must pass the options of the select as children.
1257
- * @default false
1258
- */
1259
- select: PropTypes.bool,
1260
- /**
1261
- * Props applied to the [`Select`](/material-ui/api/select/) element.
1262
- */
1263
- SelectProps: PropTypes.object,
1264
- /**
1265
- * The size of the component.
1266
- */
1267
- size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
1268
- /**
1269
- * The system prop that allows defining system overrides as well as additional CSS styles.
1270
- */
1271
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1272
- /**
1273
- * 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).
1274
- */
1275
- type: PropTypes /* @typescript-to-proptypes-ignore */.string,
1276
- /**
1277
- * The value of the `input` element, required for a controlled component.
1278
- */
1279
- value: PropTypes.any,
1280
- /**
1281
- * The variant to use.
1282
- * @default 'outlined'
1283
- */
1284
- variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
1285
- } : void 0;
1286
- var TextField$1 = TextField;
1287
-
1288
- const SUBMIT_FILTER_STROKE_TIME = 500;
1289
- const InputNumberInterval = props => {
1290
- var _item$value;
1291
- const {
1292
- item,
1293
- applyValue,
1294
- focusElementRef = null
1295
- } = props;
1296
- const filterTimeout = React.useRef();
1297
- const [filterValueState, setFilterValueState] = React.useState((_item$value = item.value) !== null && _item$value !== void 0 ? _item$value : '');
1298
- const [applying, setIsApplying] = React.useState(false);
1299
- React.useEffect(() => {
1300
- return () => {
1301
- clearTimeout(filterTimeout.current);
1302
- };
1303
- }, []);
1304
- React.useEffect(() => {
1305
- var _item$value2;
1306
- const itemValue = (_item$value2 = item.value) !== null && _item$value2 !== void 0 ? _item$value2 : [undefined, undefined];
1307
- setFilterValueState(itemValue);
1308
- }, [item.value]);
1309
- const updateFilterValue = (lowerBound, upperBound) => {
1310
- clearTimeout(filterTimeout.current);
1311
- setFilterValueState([lowerBound, upperBound]);
1312
- setIsApplying(true);
1313
- filterTimeout.current = setTimeout(() => {
1314
- setIsApplying(false);
1315
- applyValue(_objectSpread2(_objectSpread2({}, item), {}, {
1316
- value: [lowerBound, upperBound]
1317
- }));
1318
- }, SUBMIT_FILTER_STROKE_TIME);
1319
- };
1320
- const handleUpperFilterChange = event => {
1321
- const newUpperBound = event.target.value;
1322
- updateFilterValue(filterValueState[0], newUpperBound);
1323
- };
1324
- const handleLowerFilterChange = event => {
1325
- const newLowerBound = event.target.value;
1326
- updateFilterValue(newLowerBound, filterValueState[1]);
1327
- };
1328
- return /*#__PURE__*/React.createElement(Box$1, {
1329
- sx: {
1330
- display: 'inline-flex',
1331
- flexDirection: 'row',
1332
- alignItems: 'end',
1333
- height: 48,
1334
- pl: '20px'
1335
- }
1336
- }, /*#__PURE__*/React.createElement(TextField$1, {
1337
- name: "lower-bound-input",
1338
- placeholder: "From",
1339
- label: "From",
1340
- variant: "standard",
1341
- value: Number(filterValueState[0]),
1342
- onChange: handleLowerFilterChange,
1343
- type: "number",
1344
- inputRef: focusElementRef,
1345
- sx: {
1346
- mr: 2
1347
- }
1348
- }), /*#__PURE__*/React.createElement(TextField$1, {
1349
- name: "upper-bound-input",
1350
- placeholder: "To",
1351
- label: "To",
1352
- variant: "standard",
1353
- value: Number(filterValueState[1]),
1354
- onChange: handleUpperFilterChange,
1355
- type: "number",
1356
- InputProps: applying ? {
1357
- endAdornment: /*#__PURE__*/React.createElement(Icon, {
1358
- icon: mdiSync
1359
- })
1360
- } : {}
1361
- }));
1362
- };
1363
-
1364
- const isBetweenOperator = {
1365
- label: 'is between',
1366
- value: 'isBetween',
1367
- getApplyFilterFn: filterItem => {
1368
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1369
- return null;
1370
- }
1371
- if (!Array.isArray(filterItem.value) || filterItem.value.length !== 2) {
1372
- return null;
1373
- }
1374
- if (filterItem.value[0] == null || filterItem.value[1] == null) {
1375
- return null;
1376
- }
1377
- if (typeof filterItem.value[0] !== 'number' || typeof filterItem.value[1] !== 'number') {
1378
- return null;
1379
- }
1380
- return params => {
1381
- return params.value !== null && params.value !== undefined && filterItem.value[0] <= params.value && params.value <= filterItem.value[1];
1382
- };
1383
- },
1384
- InputComponent: InputNumberInterval
1385
- };
1386
- const IS_BETWEEN = isBetweenOperator;
1387
-
1388
- const getGridNumericOperators = () => [...getGridNumericOperators$1(), IS_BETWEEN];
1389
-
1390
- const doesNotContain = {
1391
- label: 'does not contain',
1392
- value: 'doesNotContain',
1393
- getApplyFilterFn: filterItem => {
1394
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1395
- return null;
1396
- }
1397
- return params => {
1398
- if (filterItem.value.length === 0) {
1399
- return true;
1400
- }
1401
- if (String(params.value).indexOf(filterItem.value) !== -1) {
1402
- return false;
1403
- }
1404
- return true;
1405
- };
1406
- },
1407
- InputComponent: GridFilterInputValue
1408
- };
1409
- const DOES_NOT_CONTAIN = doesNotContain;
1410
-
1411
- const doesNotEqual = {
1412
- label: 'does not equal',
1413
- value: 'doesNotEqual',
1414
- getApplyFilterFn: filterItem => {
1415
- if (!filterItem.field || !filterItem.value || !filterItem.value) {
1416
- return null;
1417
- }
1418
- return params => {
1419
- if (filterItem.value.length === 0) {
1420
- return true;
1421
- }
1422
- if (String(params.value) === filterItem.value) {
1423
- return false;
1424
- }
1425
- return true;
1426
- };
1427
- },
1428
- InputComponent: GridFilterInputValue
1429
- };
1430
- const DOES_NOT_EQUAL = doesNotEqual;
1431
-
1432
- const doesNotHaveOperator = {
1433
- label: "doesn't have",
1434
- value: 'doesNotHave',
1435
- getApplyFilterFn: filterItem => {
1436
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1437
- return null;
1438
- }
1439
- return params => {
1440
- const cellValues = Array.isArray(params.value) ? params.value : [params.value];
1441
- return !cellValues.map(value => String(value)).includes(filterItem.value);
1442
- };
1443
- },
1444
- InputComponent: GridFilterInputValue
1445
- };
1446
- const DOES_NOT_HAVE = doesNotHaveOperator;
1447
- const DOES_NOT_HAVE_WITH_SELECT = _objectSpread2(_objectSpread2({}, DOES_NOT_HAVE), {}, {
1448
- InputComponent: GridFilterInputSingleSelect
1449
- });
1450
-
1451
- const hasOperator = {
1452
- label: 'has',
1453
- value: 'has',
1454
- getApplyFilterFn: filterItem => {
1455
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1456
- return null;
1457
- }
1458
- return params => {
1459
- const cellValues = Array.isArray(params.value) ? params.value : [params.value];
1460
- return cellValues.map(value => String(value)).includes(filterItem.value);
1461
- };
1462
- },
1463
- InputComponent: GridFilterInputValue
1464
- };
1465
- const HAS = hasOperator;
1466
- const HAS_WITH_SELECT = _objectSpread2(_objectSpread2({}, HAS), {}, {
1467
- InputComponent: GridFilterInputSingleSelect
1468
- });
1469
-
1470
- const hasOnlyOperator = {
1471
- label: 'has only',
1472
- value: 'hasOnly',
1473
- getApplyFilterFn: filterItem => {
1474
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1475
- return null;
1476
- }
1477
- return params => {
1478
- const cellValues = Array.isArray(params.value) ? params.value : [params.value];
1479
- return cellValues.length === 1 && String(cellValues[0]) === filterItem.value;
1480
- };
1481
- },
1482
- InputComponent: GridFilterInputValue
1483
- };
1484
- const HAS_ONLY = hasOnlyOperator;
1485
- const HAS_ONLY_WITH_SELECT = _objectSpread2(_objectSpread2({}, HAS_ONLY), {}, {
1486
- InputComponent: GridFilterInputSingleSelect
1487
- });
1488
-
1489
- const isOperator = {
1490
- label: 'is',
1491
- value: 'is',
1492
- getApplyFilterFn: filterItem => {
1493
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1494
- return null;
1495
- }
1496
- return params => {
1497
- if (Array.isArray(params.value)) {
1498
- return false;
1499
- }
1500
- return String(params.value) === filterItem.value;
1501
- };
1502
- },
1503
- InputComponent: GridFilterInputValue
1504
- };
1505
- const IS = isOperator;
1506
- const IS_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS), {}, {
1507
- InputComponent: GridFilterInputSingleSelect
1508
- });
1509
-
1510
- const isNotOperator = {
1511
- label: 'is not',
1512
- value: 'isNot',
1513
- getApplyFilterFn: filterItem => {
1514
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1515
- return null;
1516
- }
1517
- return params => {
1518
- if (Array.isArray(params.value)) {
1519
- return true;
1520
- }
1521
- return String(params.value) !== filterItem.value;
1522
- };
1523
- },
1524
- InputComponent: GridFilterInputValue
1525
- };
1526
- const IS_NOT = isNotOperator;
1527
- const IS_NOT_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_NOT), {}, {
1528
- InputComponent: GridFilterInputSingleSelect
1529
- });
1530
-
1531
- const containsAnyOfOperator = {
1532
- label: 'contains any of',
1533
- value: 'containsAnyOf',
1534
- getApplyFilterFn: filterItem => {
1535
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1536
- return null;
1537
- }
1538
- return params => {
1539
- if (filterItem.value.length === 0) {
1540
- return true;
1541
- }
1542
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1543
- let match = false;
1544
- filterItem.value.forEach(filteredValue => {
1545
- paramValues.forEach(paramValue => {
1546
- if (String(paramValue).indexOf(filteredValue) !== -1) {
1547
- match = true;
1548
- }
1549
- });
1550
- });
1551
- return match;
1552
- };
1553
- },
1554
- InputComponent: GridFilterInputMultipleValue
1555
- };
1556
- const containsAnyOfCIOperator = {
1557
- label: 'contains any of (case insensitive)',
1558
- value: 'containsAnyOf',
1559
- getApplyFilterFn: filterItem => {
1560
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1561
- return null;
1562
- }
1563
- return params => {
1564
- if (filterItem.value.length === 0) {
1565
- return true;
1566
- }
1567
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1568
- const paramValuesLower = paramValues.map(item => String(item).toLowerCase());
1569
- let match = false;
1570
- filterItem.value.forEach(filteredValue => {
1571
- if (paramValuesLower.indexOf(filteredValue.toLowerCase()) !== -1) {
1572
- match = true;
1573
- }
1574
- });
1575
- return match;
1576
- };
1577
- },
1578
- InputComponent: GridFilterInputMultipleValue
1579
- };
1580
- const CONTAINS_ANY_OF = containsAnyOfOperator;
1581
- const CONTAINS_ANY_OF_I = containsAnyOfCIOperator;
1582
-
1583
- const doesNotHaveAnyOf = {
1584
- label: "doesn't have any of",
1585
- value: 'doesNotHaveAnyOf',
1586
- getApplyFilterFn: filterItem => {
1587
- if (!filterItem.field || !filterItem.value || !Array.isArray(filterItem.value) || filterItem.value.length === 0) {
1588
- return null;
1589
- }
1590
- return params => {
1591
- const cellValues = Array.isArray(params.value) ? params.value : [params.value];
1592
-
1593
- // Return true only if none of the filter values are in the cell values
1594
- return filterItem.value.every(filterVal => !cellValues.map(value => String(value)).includes(filterVal));
1595
- };
1596
- },
1597
- InputComponent: GridFilterInputMultipleValue
1598
- };
1599
- const DOES_NOT_HAVE_ANY_OF = doesNotHaveAnyOf;
1600
- const DOES_NOT_HAVE_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, DOES_NOT_HAVE_ANY_OF), {}, {
1601
- InputComponent: GridFilterInputMultipleSingleSelect
1602
- });
1603
-
1604
- const endsWithAnyOfOperator = {
1605
- label: 'ends with any of',
1606
- value: 'endsWithAnyOf',
1607
- getApplyFilterFn: filterItem => {
1608
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1609
- return null;
1610
- }
1611
- return params => {
1612
- if (filterItem.value.length === 0) {
1613
- return true;
1614
- }
1615
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1616
- let match = false;
1617
- filterItem.value.forEach(filteredValue => {
1618
- paramValues.forEach(paramValue => {
1619
- if (String(paramValue).endsWith(filteredValue)) {
1620
- match = true;
1621
- }
1622
- });
1623
- });
1624
- return match;
1625
- };
1626
- },
1627
- InputComponent: GridFilterInputMultipleValue
1628
- };
1629
- const ENDS_WITH_ANY_OF = endsWithAnyOfOperator;
1630
-
1631
- const isAnyOfOperator = {
1632
- label: 'is any of',
1633
- value: 'isAnyOf',
1634
- getApplyFilterFn: filterItem => {
1635
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1636
- return null;
1637
- }
1638
- return params => {
1639
- if (filterItem.value.length === 0) {
1640
- return true;
1641
- }
1642
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1643
- for (const paramValue of paramValues) {
1644
- if (filterItem.value.includes(String(paramValue))) {
1645
- return true;
1646
- }
1647
- }
1648
- return false;
1649
- };
1650
- },
1651
- InputComponent: GridFilterInputMultipleValue
1652
- };
1653
- const IS_ANY_OF = isAnyOfOperator;
1654
- const IS_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_ANY_OF), {}, {
1655
- InputComponent: GridFilterInputMultipleSingleSelect
1656
- });
1657
-
1658
- const isAnyOfIOperator = {
1659
- label: 'is any of (case-insensitive)',
1660
- value: 'isAnyOfI',
1661
- getApplyFilterFn: filterItem => {
1662
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1663
- return null;
1664
- }
1665
- const lowerCaseFilterValues = filterItem.value.map(v => String(v).toLowerCase());
1666
- return params => {
1667
- if (filterItem.value.length === 0) {
1668
- return true;
1669
- }
1670
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1671
- for (const paramValue of paramValues) {
1672
- if (lowerCaseFilterValues.includes(String(paramValue).toLowerCase())) {
1673
- return true;
1674
- }
1675
- }
1676
- return false;
1677
- };
1678
- },
1679
- InputComponent: GridFilterInputMultipleValue
1680
- };
1681
- const IS_ANY_OF_I = isAnyOfIOperator;
1682
- const IS_ANY_OF_I_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_ANY_OF_I), {}, {
1683
- InputComponent: GridFilterInputMultipleSingleSelect
1684
- });
1685
-
1686
- const hasAnyOfOperator = {
1687
- label: 'has any of',
1688
- value: 'hasAnyOf',
1689
- getApplyFilterFn: filterItem => {
1690
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1691
- return null;
1692
- }
1693
- return params => {
1694
- if (filterItem.value.length === 0) {
1695
- return true;
1696
- }
1697
- const cellValues = Array.isArray(params.value) ? params.value : [params.value];
1698
- const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
1699
- return filterItemValues.some(v => cellValues.map(value => String(value)).includes(v));
1700
- };
1701
- },
1702
- InputComponent: GridFilterInputMultipleValue
1703
- };
1704
- const HAS_ANY_OF = hasAnyOfOperator;
1705
- const HAS_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, HAS_ANY_OF), {}, {
1706
- InputComponent: GridFilterInputMultipleSingleSelect
1707
- });
1708
-
1709
- const isNotAnyOfOperator = {
1710
- label: 'is not any of',
1711
- value: 'isNotAnyOf',
1712
- getApplyFilterFn: filterItem => {
1713
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1714
- return null;
1715
- }
1716
- return params => {
1717
- if (filterItem.value.length === 0) {
1718
- return true;
1719
- }
1720
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1721
- for (const paramValue of paramValues) {
1722
- if (filterItem.value.includes(String(paramValue))) {
1723
- return false;
1724
- }
1725
- }
1726
- return true;
1727
- };
1728
- },
1729
- InputComponent: GridFilterInputMultipleValue
1730
- };
1731
- const IS_NOT_ANY_OF = isNotAnyOfOperator;
1732
- const IS_NOT_ANY_OF_WITH_SELECT = _objectSpread2(_objectSpread2({}, IS_NOT_ANY_OF), {}, {
1733
- InputComponent: GridFilterInputMultipleSingleSelect
1734
- });
1735
-
1736
- const startsWithAnyOfOperator = {
1737
- label: 'starts with any of',
1738
- value: 'startsWithAnyOf',
1739
- getApplyFilterFn: filterItem => {
1740
- if (!filterItem.field || !filterItem.value || !filterItem.operator) {
1741
- return null;
1742
- }
1743
- return params => {
1744
- if (filterItem.value.length === 0) {
1745
- return true;
1746
- }
1747
- const paramValues = Array.isArray(params.value) ? params.value : [params.value];
1748
- let match = false;
1749
- filterItem.value.forEach(filteredValue => {
1750
- paramValues.forEach(paramValue => {
1751
- if (String(paramValue).startsWith(filteredValue)) {
1752
- match = true;
1753
- }
1754
- });
1755
- });
1756
- return match;
1757
- };
1758
- },
1759
- InputComponent: GridFilterInputMultipleValue
1760
- };
1761
- const STARTS_WITH_ANY_OF = startsWithAnyOfOperator;
1762
-
1763
- const getGridStringArrayOperators = () => [CONTAINS_ANY_OF, ENDS_WITH_ANY_OF, IS_ANY_OF, IS_ANY_OF_I, IS_NOT_ANY_OF, STARTS_WITH_ANY_OF];
1764
- 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];
1765
- 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];
1766
-
1767
- const getGridStringOperators = () => [...getGridStringOperators$1().filter(operator => !['isAnyOf'].includes(operator.value)), DOES_NOT_CONTAIN, DOES_NOT_EQUAL, ...getGridStringArrayOperators()];
1768
-
1769
- // istanbul ignore file
1770
- const operatorList = {
1771
- // Default types
1772
- string: getGridStringOperators$1(),
1773
- number: getGridNumericOperators$1(),
1774
- boolean: getGridBooleanOperators(),
1775
- date: getGridDateOperators(),
1776
- dateTime: getGridDateOperators(true),
1777
- singleSelect: getGridSingleSelectOperators(),
1778
- // Extended types
1779
- rsString: getGridStringOperators(),
1780
- rsNumber: getGridNumericOperators(),
1781
- rsSingleSelect: [CONTAINS_ANY_OF, ENDS_WITH_ANY_OF, IS_ANY_OF_WITH_SELECT, IS_NOT_WITH_SELECT, IS_WITH_SELECT, STARTS_WITH_ANY_OF],
1782
- rsSingleSelectWithShortOperatorList: [IS_WITH_SELECT, IS_NOT_WITH_SELECT, IS_ANY_OF_WITH_SELECT],
1783
- 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],
1784
- rsMultipleSelectWithShortOperatorList: [HAS_WITH_SELECT, DOES_NOT_HAVE_WITH_SELECT, HAS_ANY_OF_WITH_SELECT],
1785
- // Custom types
1786
- rsStringArray: getGridStringArrayOperators()
1787
- };
1788
-
1789
13
  const PAGINATION_MODEL_KEY = 'paginationModel';
1790
14
  const FILTER_MODEL_KEY = 'filterModel';
1791
15
  const SORT_MODEL_KEY = 'sortModel';
@@ -1843,63 +67,347 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
1843
67
  }
1844
68
  };
1845
69
 
1846
- // reference value: https://www.w3schools.com/tags/ref_urlencode.ASP
1847
- const DECODER = {
1848
- '%20': ' ',
1849
- '%26': '&',
1850
- '%3D': '=',
1851
- '%3F': '?',
1852
- '%5B': '[',
1853
- '%5D': ']',
1854
- '%2C': ',',
1855
- '%3C': '<',
1856
- '%3E': '>',
1857
- '%21': '!',
1858
- '%22': '"'
1859
- };
1860
- const ENCODER = {
1861
- ' ': '%20',
1862
- '&': '%26',
1863
- '=': '%3D',
1864
- '?': '%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
1865
81
  '[': '%5B',
82
+ // Square bracket - used in internal format
1866
83
  ']': '%5D',
1867
- ',': '%2C',
1868
- '<': '%3C',
1869
- '>': '%3E',
1870
- '!': '%21',
1871
- '"': '%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]);
1872
385
  };
1873
386
  const decodeValue = value => {
1874
387
  if (value === '') {
1875
- return '';
388
+ return undefined;
1876
389
  }
1877
- const re = new RegExp(Object.keys(DECODER).reduce((acc, curr) => `${acc},${curr}`), 'g');
1878
- // decodeValue for lists:
390
+
391
+ // Handle array values encoded as list[item1,item2,...]
1879
392
  if (value.startsWith('list[')) {
1880
- const arrayValues = value.split('[')[1].split(']')[0];
1881
- const arrayList = arrayValues.split(',').map(v => v.replace(re, encoded => DECODER[encoded])).filter(item => item);
1882
- 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);
1883
398
  }
1884
- return value.replace(re, encoded => DECODER[encoded]);
399
+ return value;
1885
400
  };
1886
401
  const encodeValue = value => {
1887
- if (!value) {
402
+ if (value === undefined || value === null) {
1888
403
  return '';
1889
404
  }
1890
405
 
1891
- // Array encoding for value:
1892
- // we are representing it as list[encoded], where encoded is the list comma separated
406
+ // Handle array values - encode as list[item1,item2,...]
1893
407
  if (Array.isArray(value)) {
1894
- const encodedArray = value.map(entry => {
1895
- return String(entry).replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
1896
- }).join(',');
1897
- return `list[${encodedArray}]`;
408
+ return `list[${value.map(String).join(',')}]`;
1898
409
  }
1899
-
1900
- // we might also pass integers
1901
- const castedValue = String(value);
1902
- return castedValue.replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
410
+ return String(value);
1903
411
  };
1904
412
  const urlSearchParamsToString = searchParams => {
1905
413
  let searchString = '';
@@ -1924,39 +432,42 @@ const numberOperatorDecoder = {
1924
432
  lt: '<',
1925
433
  lte: '<='
1926
434
  };
1927
- const isOperatorValueValid = (field, operator, columns) => {
1928
- const column = columns.find(column => column.field === field);
435
+ const isOperatorValueValid = (columnField, operatorValue, columns) => {
436
+ const column = columns.find(column => column.field === columnField);
1929
437
  if (!column) {
1930
438
  return false;
1931
439
  }
1932
440
  const columnType = (column === null || column === void 0 ? void 0 : column.type) || 'string';
1933
- const operators = column.filterOperators || operatorList[columnType];
441
+ const operators = operatorList[columnType];
1934
442
  if (!operators) {
1935
443
  return false;
1936
444
  }
1937
- 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);
1938
449
  };
1939
450
  const listOperators = ['containsAnyOf', 'doesNotContainAnyOf', 'endsWithAnyOf', 'doesNotEndWithAnyOf', 'hasAnyOf', 'doesNotHaveAnyOf', 'isAnyOf', 'isNotAnyOf', 'startsWithAnyOf', 'doesNotStartWithAnyOf'];
1940
451
 
1941
452
  // Check if the value doesn't break
1942
- const isValueValid = (value, field, columns, operator) => {
453
+ const isValueValid = (value, columnField, columns, operatorValue) => {
1943
454
  var _column$type;
1944
455
  // every field accepts undefined as value for default
1945
456
  if (value === undefined || value === '') {
1946
457
  return true;
1947
458
  }
1948
459
 
1949
- // 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
1950
461
  // URL as `list=[...]`
1951
- if (listOperators.includes(operator)) {
462
+ if (listOperators.includes(operatorValue)) {
1952
463
  return Array.isArray(value) || value === '';
1953
464
  }
1954
465
 
1955
466
  // We are accepting arrays only if they are of the 'xxxAnyOf' type
1956
- if (Array.isArray(value) && !listOperators.includes(operator)) {
467
+ if (Array.isArray(value) && !listOperators.includes(operatorValue)) {
1957
468
  return false;
1958
469
  }
1959
- const column = columns.find(column => column.field === field);
470
+ const column = columns.find(column => column.field === columnField);
1960
471
  if (!column) {
1961
472
  return false;
1962
473
  }
@@ -1994,7 +505,7 @@ const getFilterModelFromString = (searchString, columns) => {
1994
505
  if (!searchString) {
1995
506
  return 'invalid';
1996
507
  }
1997
- let logicOperator = GridLogicOperator.And;
508
+ let linkOperator = GridLinkOperator.And;
1998
509
  let quickFilterValues = [];
1999
510
  const searchParams = new URLSearchParams();
2000
511
  for (const [key, value] of new URLSearchParams(searchString)) {
@@ -2002,7 +513,7 @@ const getFilterModelFromString = (searchString, columns) => {
2002
513
  searchParams.set(key, value);
2003
514
  }
2004
515
  if (key === '_logicOperator') {
2005
- logicOperator = value === GridLogicOperator.And || value === GridLogicOperator.Or ? value : GridLogicOperator.And;
516
+ linkOperator = value;
2006
517
  }
2007
518
  if (key === '_quickFilterValues') {
2008
519
  try {
@@ -2021,7 +532,7 @@ const getFilterModelFromString = (searchString, columns) => {
2021
532
  if (isInvalid) {
2022
533
  return;
2023
534
  }
2024
- const field = key.split('[')[0].slice(1);
535
+ const field = key.split('[')[0].slice(1); // Slice to remove the _ at the beginning
2025
536
  if (!fields.includes(field)) {
2026
537
  return;
2027
538
  }
@@ -2038,6 +549,7 @@ const getFilterModelFromString = (searchString, columns) => {
2038
549
  return;
2039
550
  }
2040
551
  const operator = splitRight[0];
552
+ // if the operator is not part of the valid operators invalidate the URL
2041
553
  if (!isOperatorValueValid(field, operator, columns) || Array.isArray(operator)) {
2042
554
  isInvalid = true;
2043
555
  return;
@@ -2049,37 +561,41 @@ const getFilterModelFromString = (searchString, columns) => {
2049
561
  return;
2050
562
  }
2051
563
  items.push({
2052
- field,
2053
- 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,
2054
566
  id,
2055
567
  value: listOperators.includes(operator) && decodedValue === '' ? [] : decodedValue,
2056
568
  type
2057
569
  });
2058
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
2059
575
  if (isInvalid) {
2060
576
  return 'invalid';
2061
577
  }
2062
578
  return {
2063
579
  items,
2064
- logicOperator,
580
+ linkOperator,
2065
581
  quickFilterValues
2066
582
  };
2067
583
  };
2068
584
  const getSearchParamsFromFilterModel = filterModel => {
2069
585
  var _filterModel$quickFil;
2070
586
  const searchParams = new URLSearchParams();
2071
- searchParams.set('_logicOperator', filterModel['logicOperator'] || '');
587
+ searchParams.set('_logicOperator', filterModel['linkOperator'] || '');
2072
588
  filterModel['items'].forEach(item => {
2073
589
  const {
2074
- field,
2075
- operator,
590
+ columnField,
591
+ operatorValue,
2076
592
  value,
2077
593
  type
2078
594
  } = item;
2079
- if (Object.keys(numberOperatorEncoder).includes(operator)) {
2080
- 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));
2081
597
  } else {
2082
- searchParams.set(`_${field}[${encodeValue(operator)},${encodeValue(type)}]`, encodeValue(value));
598
+ searchParams.set(`_${columnField}[${encodeValue(operatorValue)},${encodeValue(type)}]`, encodeValue(value));
2083
599
  }
2084
600
  });
2085
601
  if ((_filterModel$quickFil = filterModel.quickFilterValues) !== null && _filterModel$quickFil !== void 0 && _filterModel$quickFil.length) {
@@ -2095,7 +611,7 @@ const getSearchParamsFromFilterModel = filterModel => {
2095
611
  const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion) => {
2096
612
  const defaultValue = initialState && initialState.filter && initialState.filter.filterModel ? initialState.filter.filterModel : {
2097
613
  items: [],
2098
- logicOperator: GridLogicOperator.And
614
+ linkOperator: GridLinkOperator.And
2099
615
  };
2100
616
  if (isNewVersion) {
2101
617
  return defaultValue;
@@ -2234,38 +750,13 @@ const getPaginationModel = (search, localStoragePagination, setLocalStoragePagin
2234
750
 
2235
751
  /** COLUMN VISIBILITY */
2236
752
 
2237
- const getColumnVisibilityFromString = (searchString, columns) => {
2238
- if (!searchString) {
2239
- return 'invalid';
2240
- }
2241
- const searchParams = new URLSearchParams(searchString);
2242
- const value = searchParams.get('_columnVisibility');
2243
- if (value === '' || value === null || value === '[]') {
2244
- return 'invalid';
2245
- }
2246
- const parsedFields = value.slice(1, value.length - 1).split(',');
2247
- const fields = columns.map(column => column.field);
2248
- const visibility = {};
2249
- for (const field of fields) {
2250
- visibility[field] = false;
2251
- }
2252
- for (const parsedField of parsedFields) {
2253
- if (fields.includes(parsedField)) {
2254
- visibility[parsedField] = true;
2255
- }
2256
- }
2257
- if (Object.values(visibility).filter(v => v === true).length === 0) {
2258
- return 'invalid';
2259
- }
2260
- return visibility;
2261
- };
2262
753
  const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
2263
754
  const searchParams = new URLSearchParams();
2264
- const fields = columns.map(column => column.field);
755
+ const columnFields = columns.map(column => column.field);
2265
756
 
2266
757
  // if column visibility model is empty, show all columns
2267
758
  if (Object.keys(columnVisibility).length == 0) {
2268
- searchParams.set('_columnVisibility', `[${fields.join(',')}]`);
759
+ searchParams.set('_columnVisibility', `[${columnFields.join(',')}]`);
2269
760
  return searchParams;
2270
761
  }
2271
762
  const finalColumnVisibility = columns.filter(c => {
@@ -2276,10 +767,63 @@ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
2276
767
  [colName]: true
2277
768
  });
2278
769
  }, columnVisibility);
2279
- 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
+ });
2280
781
  searchParams.set('_columnVisibility', `[${visibleColumns.join(',')}]`);
2281
782
  return searchParams;
2282
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
+ };
2283
827
 
2284
828
  // Rules:
2285
829
  // - if we have something in the URL, use that info
@@ -2340,8 +884,8 @@ const getPinnedColumnsFromString = (notParsed, tableColumns) => {
2340
884
  if (typeof encodedValues !== 'string') {
2341
885
  continue;
2342
886
  }
2343
- const fields = [...tableColumns.map(column => column.field), '__check__'];
2344
- 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));
2345
889
  if (fieldURL === '_pinnedColumnsLeft') {
2346
890
  pinnedColumns['left'] = columns;
2347
891
  }
@@ -2349,9 +893,9 @@ const getPinnedColumnsFromString = (notParsed, tableColumns) => {
2349
893
  pinnedColumns['right'] = columns;
2350
894
  }
2351
895
  }
2352
- return pinnedColumns.left && pinnedColumns.left.length > 0 || pinnedColumns.right && pinnedColumns.right.length > 0 ? {
2353
- left: pinnedColumns.left || [],
2354
- right: pinnedColumns.right || []
896
+ return pinnedColumns['left'] || pinnedColumns['right'] ? {
897
+ left: pinnedColumns['left'] || [],
898
+ right: pinnedColumns['right'] || []
2355
899
  } : 'invalid';
2356
900
  };
2357
901
  const getSearchParamsFromPinnedColumns = pinnedColumns => {
@@ -2401,7 +945,7 @@ const getSearchParamsFromTab = search => {
2401
945
  }
2402
946
  return searchParams;
2403
947
  };
2404
- const getFinalSearch = _ref => {
948
+ const getFinalSearch = _ref3 => {
2405
949
  let {
2406
950
  search,
2407
951
  localStorageVersion,
@@ -2411,7 +955,7 @@ const getFinalSearch = _ref => {
2411
955
  columnsVisibilityModel,
2412
956
  pinnedColumnsModel,
2413
957
  columns
2414
- } = _ref;
958
+ } = _ref3;
2415
959
  const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
2416
960
  const sortModelSearch = getSearchParamsFromSorting(sortModel);
2417
961
  const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
@@ -2435,7 +979,9 @@ const getFinalSearch = _ref => {
2435
979
  };
2436
980
  /** Return the state of the table given the URL and the local storage state */
2437
981
  const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, historyReplace, initialState, localStorage) => {
2438
- 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');
2439
985
  const isNewVersion = !currentVersion || Number(currentVersion) !== localStorageVersion;
2440
986
  const {
2441
987
  localStorageFilters,
@@ -2449,14 +995,14 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2449
995
  localStoragePinnedColumns,
2450
996
  setLocalStoragePinnedColumns
2451
997
  } = localStorage;
2452
- const filterModel = getFilterModel(search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
2453
- const sortModel = getSortModel(search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
2454
- const paginationModel = getPaginationModel(search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
2455
- const columnVisibilityModel = getColumnsVisibility(search, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
2456
- 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);
2457
1003
  const finalSearch = getFinalSearch({
2458
1004
  localStorageVersion,
2459
- search,
1005
+ search: decodedSearch,
2460
1006
  filterModel,
2461
1007
  sortModel,
2462
1008
  paginationModel,
@@ -2464,9 +1010,15 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2464
1010
  pinnedColumnsModel,
2465
1011
  columns
2466
1012
  });
2467
- const searchString = urlSearchParamsToString(finalSearch);
2468
- if (searchString !== search) {
2469
- 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);
2470
1022
  }
2471
1023
  return {
2472
1024
  filterModel,
@@ -2476,16 +1028,18 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
2476
1028
  pinnedColumnsModel
2477
1029
  };
2478
1030
  };
2479
- const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns) => {
1031
+ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
2480
1032
  let {
2481
1033
  filterModel,
2482
1034
  sortModel,
2483
1035
  paginationModel,
2484
1036
  columnsModel: columnsVisibilityModel,
2485
1037
  pinnedColumnsModel
2486
- } = _ref2;
1038
+ } = _ref4;
1039
+ // Convert from display format to internal format if needed
1040
+ const decodedSearch = getDecodedSearchFromUrl(search, columns);
2487
1041
  const newSearch = getFinalSearch({
2488
- search,
1042
+ search: decodedSearch,
2489
1043
  localStorageVersion,
2490
1044
  filterModel,
2491
1045
  sortModel,
@@ -2494,9 +1048,15 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
2494
1048
  pinnedColumnsModel,
2495
1049
  columns
2496
1050
  });
2497
- const searchString = urlSearchParamsToString(newSearch);
2498
- if (searchString !== search) {
2499
- 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);
2500
1060
  }
2501
1061
  };
2502
1062
 
@@ -2504,17 +1064,17 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
2504
1064
  // do not use it for equivalence (e.g. with value `3` and undefined we
2505
1065
  // will get 0).
2506
1066
  const compareFilters = (firstFilter, secondFilter) => {
2507
- if (firstFilter.field < secondFilter.field) {
1067
+ if (firstFilter.columnField < secondFilter.columnField) {
2508
1068
  return -1;
2509
- } else if (firstFilter.field > secondFilter.field) {
1069
+ } else if (firstFilter.columnField > secondFilter.columnField) {
2510
1070
  return 1;
2511
1071
  }
2512
- if (firstFilter.operator === undefined || secondFilter.operator === undefined) {
1072
+ if (firstFilter.operatorValue === undefined || secondFilter.operatorValue === undefined) {
2513
1073
  return 0;
2514
1074
  }
2515
- if (firstFilter.operator < secondFilter.operator) {
1075
+ if (firstFilter.operatorValue < secondFilter.operatorValue) {
2516
1076
  return -1;
2517
- } else if (firstFilter.operator > secondFilter.operator) {
1077
+ } else if (firstFilter.operatorValue > secondFilter.operatorValue) {
2518
1078
  return 1;
2519
1079
  }
2520
1080
  if (firstFilter.value < secondFilter.value) {
@@ -2525,18 +1085,18 @@ const compareFilters = (firstFilter, secondFilter) => {
2525
1085
  return 0;
2526
1086
  };
2527
1087
  const areFiltersEquivalent = (firstFilter, secondFilter) => {
2528
- 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;
2529
1089
  };
2530
1090
  const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2531
1091
  const {
2532
1092
  items,
2533
- logicOperator
1093
+ linkOperator
2534
1094
  } = filterModel;
2535
1095
  const {
2536
1096
  items: itemsToMatch,
2537
- logicOperator: logicOperatorToMatch
1097
+ linkOperator: linkOperatorToMatch
2538
1098
  } = filterModelToMatch;
2539
- if (logicOperator !== logicOperatorToMatch) {
1099
+ if (linkOperator !== linkOperatorToMatch) {
2540
1100
  return false;
2541
1101
  }
2542
1102
  if (items.length !== itemsToMatch.length) {
@@ -2549,7 +1109,7 @@ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2549
1109
  const filterToCompare = itemsToMatch[i];
2550
1110
 
2551
1111
  // compareFilters return 0 if and only if the filters have the same
2552
- // field, operator, and value
1112
+ // columnField, operatorValue, and value
2553
1113
  if (!areFiltersEquivalent(filter, filterToCompare)) {
2554
1114
  return false;
2555
1115
  }
@@ -2558,6 +1118,8 @@ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
2558
1118
  };
2559
1119
 
2560
1120
  // Get and Set data from LocalStorage WITHOUT useState
1121
+
1122
+ // triggering a state update and consecutive re-render
2561
1123
  const useFetchState = (defaultValue, key) => {
2562
1124
  let stickyValue = null;
2563
1125
  try {
@@ -2565,7 +1127,16 @@ const useFetchState = (defaultValue, key) => {
2565
1127
  } catch (e) {
2566
1128
  console.error('StatefulDataGrid: error getting item from local storage: ', e);
2567
1129
  }
2568
- 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
+ }
2569
1140
  const updateValue = useCallback(value => {
2570
1141
  try {
2571
1142
  window.localStorage.setItem(key, JSON.stringify(value));
@@ -2576,8 +1147,6 @@ const useFetchState = (defaultValue, key) => {
2576
1147
  return [parsedValue, updateValue];
2577
1148
  };
2578
1149
 
2579
- // import useLocalStorage from './useLocalStorage';
2580
-
2581
1150
  const useTableStates = (id, version) => {
2582
1151
  const [paginationModel, setPaginationModel] = useFetchState('', buildStorageKey({
2583
1152
  id,
@@ -2634,7 +1203,8 @@ const useStatefulTable = props => {
2634
1203
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
2635
1204
  onColumnWidthChange: propsOnColumnWidthChange,
2636
1205
  onFilterModelChange: propsOnFilterModelChange,
2637
- onPaginationModelChange: propsOnPaginationModelChange,
1206
+ onPageChange: propsOnPageChange,
1207
+ onPageSizeChange: propsOnPageSizeChange,
2638
1208
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
2639
1209
  onSortModelChange: propsOnSortModelChange,
2640
1210
  useRouter,
@@ -2664,7 +1234,7 @@ const useStatefulTable = props => {
2664
1234
  setDimensionModel
2665
1235
  } = useTableStates(id, localStorageVersion);
2666
1236
 
2667
- // clearing up old version keys, triggering only on first render
1237
+ // clearing up old version keys
2668
1238
  useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
2669
1239
  const onColumnDimensionChange = useCallback(_ref => {
2670
1240
  let {
@@ -2709,7 +1279,7 @@ const useStatefulTable = props => {
2709
1279
  onFilterModelChange: (model, details) => {
2710
1280
  const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
2711
1281
  items: model.items.map(item => {
2712
- const column = apiRef.current.getColumn(item.field);
1282
+ const column = apiRef.current.getColumn(item.columnField);
2713
1283
  item.type = column.type || 'string';
2714
1284
  return item;
2715
1285
  }),
@@ -2747,16 +1317,34 @@ const useStatefulTable = props => {
2747
1317
  }, search, localStorageVersion, historyReplace, columns);
2748
1318
  },
2749
1319
  pinnedColumns: pinnedColumnsModel,
2750
- paginationModel: paginationModelParsed,
2751
- onPaginationModelChange: (model, details) => {
2752
- const paginationModel = _objectSpread2(_objectSpread2({}, model), {}, {
2753
- direction: paginationModelParsed.page < model.page ? 'next' : 'back'
2754
- });
2755
- 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);
1326
+ updateUrl({
1327
+ filterModel: filterParsed,
1328
+ sortModel: sortModelParsed,
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);
2756
1340
  updateUrl({
2757
1341
  filterModel: filterParsed,
2758
1342
  sortModel: sortModelParsed,
2759
- paginationModel: paginationModel,
1343
+ paginationModel: {
1344
+ page: paginationModelParsed.page,
1345
+ pageSize,
1346
+ direction: paginationModelParsed.direction
1347
+ },
2760
1348
  columnsModel: apiRef.current.state.columns.columnVisibilityModel,
2761
1349
  pinnedColumnsModel: pinnedColumnsModel
2762
1350
  }, search, localStorageVersion, historyReplace, columns);
@@ -2782,7 +1370,7 @@ const useStatefulTable = props => {
2782
1370
  };
2783
1371
  };
2784
1372
 
2785
- 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"];
2786
1374
  const COMPONENT_NAME = 'DataGrid';
2787
1375
  const CLASSNAME = 'redsift-datagrid';
2788
1376
  const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
@@ -2792,13 +1380,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2792
1380
  autoHeight,
2793
1381
  className,
2794
1382
  columns,
2795
- slots,
2796
- slotProps,
1383
+ columnTypes: propsColumnTypes,
1384
+ components,
1385
+ componentsProps,
2797
1386
  filterModel: propsFilterModel,
2798
1387
  columnVisibilityModel: propsColumnVisibilityModel,
2799
1388
  pinnedColumns: propsPinnedColumns,
2800
1389
  sortModel: propsSortModel,
2801
- paginationModel: propsPaginationModel,
1390
+ page: propsPage,
1391
+ pageSize: propsPageSize,
2802
1392
  height: propsHeight,
2803
1393
  hideToolbar,
2804
1394
  initialState,
@@ -2807,10 +1397,11 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2807
1397
  localStorageVersion,
2808
1398
  previousLocalStorageVersions,
2809
1399
  onFilterModelChange: propsOnFilterModelChange,
2810
- rowSelectionModel: propsRowSelectionModel,
1400
+ selectionModel: propsSelectionModel,
2811
1401
  onColumnWidthChange: propsOnColumnWidthChange,
2812
- onPaginationModelChange: propsOnPaginationModelChange,
2813
- onRowSelectionModelChange: propsOnRowSelectionModelChange,
1402
+ onPageChange: propsOnPageChange,
1403
+ onPageSizeChange: propsOnPageSizeChange,
1404
+ onSelectionModelChange: propsOnSelectionModelChange,
2814
1405
  onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
2815
1406
  onPinnedColumnsChange: propsOnPinnedColumnsChange,
2816
1407
  onSortModelChange: propsOnSortModelChange,
@@ -2818,7 +1409,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2818
1409
  paginationPlacement = 'both',
2819
1410
  paginationProps,
2820
1411
  rows,
2821
- pageSizeOptions,
1412
+ rowsPerPageOptions,
2822
1413
  sx,
2823
1414
  theme: propsTheme,
2824
1415
  useRouter,
@@ -2826,41 +1417,46 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2826
1417
  rowCount
2827
1418
  } = props,
2828
1419
  forwardedProps = _objectWithoutProperties(props, _excluded);
2829
- const theme = useTheme$1(propsTheme);
1420
+ const theme = useTheme(propsTheme);
2830
1421
  const _apiRef = useGridApiRef();
2831
1422
  const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
2832
- 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;
2833
1424
  LicenseInfo.setLicenseKey(license);
2834
1425
  const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
2835
1426
  const {
2836
1427
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
2837
1428
  onFilterModelChange: controlledOnFilterModelChange,
2838
- onPaginationModelChange: controlledOnPaginationModelChange,
1429
+ onPageChange: controlledOnPageChange,
1430
+ onPageSizeChange: controlledOnPageSizeChange,
2839
1431
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
2840
1432
  onSortModelChange: controlledOnSortModelChange
2841
1433
  } = useControlledDatagridState({
2842
1434
  initialState,
2843
- pageSizeOptions,
1435
+ rowsPerPageOptions,
2844
1436
  propsColumnVisibilityModel,
2845
1437
  propsFilterModel,
2846
1438
  propsOnColumnVisibilityModelChange,
2847
1439
  propsOnFilterModelChange,
2848
1440
  propsOnPinnedColumnsChange,
2849
1441
  propsOnSortModelChange,
2850
- propsPaginationModel,
1442
+ propsPage,
1443
+ propsPageSize,
2851
1444
  propsPinnedColumns,
2852
1445
  propsSortModel,
2853
- propsOnPaginationModelChange
1446
+ propsOnPageChange,
1447
+ propsOnPageSizeChange
2854
1448
  });
2855
1449
  const {
2856
1450
  columnVisibilityModel,
2857
1451
  filterModel,
2858
1452
  onColumnVisibilityModelChange,
2859
1453
  onFilterModelChange,
2860
- onPaginationModelChange,
1454
+ onPageChange,
1455
+ onPageSizeChange,
2861
1456
  onPinnedColumnsChange,
2862
1457
  onSortModelChange,
2863
- paginationModel,
1458
+ page,
1459
+ pageSize,
2864
1460
  pinnedColumns,
2865
1461
  sortModel,
2866
1462
  onColumnWidthChange
@@ -2871,43 +1467,40 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2871
1467
  onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
2872
1468
  onColumnWidthChange: propsOnColumnWidthChange,
2873
1469
  onFilterModelChange: controlledOnFilterModelChange,
2874
- onPaginationModelChange: controlledOnPaginationModelChange,
1470
+ onPageChange: controlledOnPageChange,
1471
+ onPageSizeChange: controlledOnPageSizeChange,
2875
1472
  onPinnedColumnsChange: controlledOnPinnedColumnsChange,
2876
1473
  onSortModelChange: controlledOnSortModelChange,
2877
1474
  useRouter: useRouter,
2878
1475
  localStorageVersion,
2879
1476
  previousLocalStorageVersions
2880
1477
  });
2881
- const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
1478
+ const [selectionModel, setSelectionModel] = useState(propsSelectionModel !== null && propsSelectionModel !== void 0 ? propsSelectionModel : []);
2882
1479
  useEffect(() => {
2883
- setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
2884
- }, [propsRowSelectionModel]);
2885
- const onRowSelectionModelChange = (selectionModel, details) => {
2886
- if (propsOnRowSelectionModelChange) {
2887
- 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);
2888
1485
  } else {
2889
- setRowSelectionModel(selectionModel);
1486
+ setSelectionModel(selectionModel);
2890
1487
  }
2891
1488
  };
2892
1489
  const selectionStatus = useRef({
2893
1490
  type: 'none',
2894
1491
  numberOfSelectedRows: 0,
2895
1492
  numberOfSelectedRowsInPage: 0,
2896
- page: paginationModel.page,
2897
- pageSize: paginationModel.pageSize
1493
+ page,
1494
+ pageSize: pageSize
2898
1495
  });
2899
1496
 
2900
- // The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
2901
- // for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
2902
- const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
2903
-
2904
1497
  // in server-side pagination we want to update the selection status
2905
1498
  // every time we navigate between pages, resize our page or select something
2906
1499
  useEffect(() => {
2907
1500
  if (paginationMode == 'server') {
2908
- onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatus, isRowSelectable, paginationModel.page, paginationModel.pageSize);
1501
+ onServerSideSelectionStatusChange(Array.isArray(selectionModel) ? selectionModel : [selectionModel], apiRef, selectionStatus, isRowSelectable, page, pageSize);
2909
1502
  }
2910
- }, [rowSelectionModel, paginationModel.page, paginationModel.pageSize]);
1503
+ }, [selectionModel, page, pageSize]);
2911
1504
  if (!Array.isArray(rows)) {
2912
1505
  return null;
2913
1506
  }
@@ -2933,20 +1526,22 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2933
1526
  ref: datagridRef,
2934
1527
  className: classNames(StatefulDataGrid.className, className),
2935
1528
  $height: height
2936
- }, /*#__PURE__*/React__default.createElement(DataGridPro, _extends$1({}, forwardedProps, {
1529
+ }, /*#__PURE__*/React__default.createElement(DataGridPro, _extends({}, forwardedProps, {
2937
1530
  apiRef: apiRef,
2938
1531
  columns: columns,
2939
1532
  columnVisibilityModel: columnVisibilityModel,
2940
1533
  filterModel: filterModel,
2941
1534
  onColumnVisibilityModelChange: onColumnVisibilityModelChange,
2942
1535
  onFilterModelChange: onFilterModelChange,
2943
- onPaginationModelChange: onPaginationModelChange,
1536
+ onPageChange: onPageChange,
1537
+ onPageSizeChange: onPageSizeChange,
2944
1538
  onPinnedColumnsChange: onPinnedColumnsChange,
2945
1539
  onSortModelChange: onSortModelChange,
2946
- paginationModel: paginationModel,
1540
+ page: page,
1541
+ pageSize: pageSize,
2947
1542
  pinnedColumns: pinnedColumns,
2948
1543
  sortModel: sortModel,
2949
- pageSizeOptions: pageSizeOptions,
1544
+ rowsPerPageOptions: rowsPerPageOptions,
2950
1545
  onColumnWidthChange: onColumnWidthChange,
2951
1546
  initialState: initialState,
2952
1547
  isRowSelectable: isRowSelectable,
@@ -2956,75 +1551,80 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
2956
1551
  rows: rows,
2957
1552
  rowCount: rowCount,
2958
1553
  autoHeight: autoHeight,
2959
- checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
2960
- slots: _objectSpread2(_objectSpread2({
2961
- baseButton: BaseButton,
2962
- baseCheckbox: BaseCheckbox,
2963
- // baseTextField,
2964
- basePopper: BasePopper,
2965
- columnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, 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, {
2966
1562
  displayName: "ColumnFilteredIcon"
2967
1563
  })),
2968
- columnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1564
+ ColumnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2969
1565
  displayName: "ColumnSelectorIcon"
2970
1566
  })),
2971
- columnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1567
+ ColumnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2972
1568
  displayName: "ColumnSortedAscendingIcon"
2973
1569
  })),
2974
- columnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1570
+ ColumnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2975
1571
  displayName: "ColumnSortedDescendingIcon"
2976
1572
  })),
2977
- densityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1573
+ DensityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2978
1574
  displayName: "DensityCompactIcon"
2979
1575
  })),
2980
- densityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1576
+ DensityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2981
1577
  displayName: "DensityStandardIcon"
2982
1578
  })),
2983
- densityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1579
+ DensityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2984
1580
  displayName: "DensityComfortableIcon"
2985
1581
  })),
2986
- detailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1582
+ DetailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2987
1583
  displayName: "DetailPanelCollapseIcon"
2988
1584
  })),
2989
- detailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1585
+ DetailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2990
1586
  displayName: "DetailPanelExpandIcon"
2991
1587
  })),
2992
- exportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({}, props, {
1588
+ ExportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
2993
1589
  displayName: "ExportIcon"
2994
1590
  })),
2995
- openFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends$1({
1591
+ OpenFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({
2996
1592
  displayName: "OpenFilterButtonIcon"
2997
1593
  }, props))
2998
- }, slots), {}, {
2999
- toolbar: ToolbarWrapper,
3000
- pagination: props => {
3001
- return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends$1({}, props, {
1594
+ }, components), {}, {
1595
+ Toolbar: ToolbarWrapper,
1596
+ Pagination: props => {
1597
+ return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
3002
1598
  displaySelection: false,
3003
1599
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3004
1600
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3005
1601
  selectionStatus: selectionStatus.current,
3006
- paginationModel: paginationModel,
3007
- onPaginationModelChange: onPaginationModelChange,
3008
- pageSizeOptions: pageSizeOptions,
1602
+ page: page,
1603
+ pageSize: pageSize,
1604
+ onPageChange: onPageChange,
1605
+ onPageSizeChange: onPageSizeChange,
1606
+ rowsPerPageOptions: rowsPerPageOptions,
3009
1607
  paginationProps: paginationProps,
3010
1608
  paginationMode: paginationMode,
3011
1609
  rowCount: rowCount
3012
- })) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends$1({}, props, {
1610
+ })) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends({}, props, {
3013
1611
  displaySelection: false,
3014
1612
  displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
3015
1613
  displayPagination: ['bottom', 'both'].includes(paginationPlacement),
3016
1614
  selectionStatus: selectionStatus.current,
3017
1615
  apiRef: apiRef,
3018
1616
  isRowSelectable: isRowSelectable,
3019
- paginationModel: paginationModel,
3020
- onPaginationModelChange: onPaginationModelChange,
3021
- pageSizeOptions: pageSizeOptions,
1617
+ page: page,
1618
+ pageSize: pageSize,
1619
+ onPageChange: onPageChange,
1620
+ onPageSizeChange: onPageSizeChange,
1621
+ rowsPerPageOptions: rowsPerPageOptions,
3022
1622
  paginationProps: paginationProps,
3023
1623
  paginationMode: paginationMode
3024
1624
  })) : null;
3025
1625
  }
3026
1626
  }),
3027
- slotProps: _objectSpread2(_objectSpread2({}, slotProps), {}, {
1627
+ componentsProps: _objectSpread2(_objectSpread2({}, componentsProps), {}, {
3028
1628
  toolbar: _objectSpread2({
3029
1629
  hideToolbar,
3030
1630
  RenderedToolbar,
@@ -3035,16 +1635,18 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3035
1635
  selectionStatus,
3036
1636
  apiRef,
3037
1637
  isRowSelectable,
3038
- paginationModel,
3039
- onPaginationModelChange,
3040
- pageSizeOptions,
1638
+ page,
1639
+ pageSize,
1640
+ onPageChange,
1641
+ onPageSizeChange,
1642
+ rowsPerPageOptions,
3041
1643
  paginationProps,
3042
1644
  paginationMode,
3043
1645
  rowCount
3044
- }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar)
1646
+ }, componentsProps === null || componentsProps === void 0 ? void 0 : componentsProps.toolbar)
3045
1647
  }),
3046
- rowSelectionModel: rowSelectionModel,
3047
- onRowSelectionModelChange: (newSelectionModel, details) => {
1648
+ selectionModel: selectionModel,
1649
+ onSelectionModelChange: (newSelectionModel, details) => {
3048
1650
  if (pagination && paginationMode != 'server') {
3049
1651
  const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref => {
3050
1652
  let {
@@ -3102,7 +1704,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3102
1704
  };
3103
1705
  }
3104
1706
  }
3105
- onRowSelectionModelChange === null || onRowSelectionModelChange === void 0 ? void 0 : onRowSelectionModelChange(newSelectionModel, details);
1707
+ onSelectionModelChange === null || onSelectionModelChange === void 0 ? void 0 : onSelectionModelChange(newSelectionModel, details);
3106
1708
  },
3107
1709
  sx: _objectSpread2(_objectSpread2({}, sx), {}, {
3108
1710
  '.MuiDataGrid-columnHeaders': {
@@ -3118,5 +1720,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
3118
1720
  StatefulDataGrid.className = CLASSNAME;
3119
1721
  StatefulDataGrid.displayName = COMPONENT_NAME;
3120
1722
 
3121
- 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 };
3122
1724
  //# sourceMappingURL=StatefulDataGrid2.js.map