@mtes-mct/monitor-ui 2.14.0 → 2.14.1

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [2.14.0](https://github.com/MTES-MCT/monitor-ui/compare/v2.13.2...v2.14.0) (2023-02-07)
2
+
3
+
4
+ ### Features
5
+
6
+ * **components:** add SingleTag ([0379159](https://github.com/MTES-MCT/monitor-ui/commit/0379159f6eec3a8d880e0f44f447bac8b5173bf8))
7
+
1
8
  ## [2.13.2](https://github.com/MTES-MCT/monitor-ui/compare/v2.13.1...v2.13.2) (2023-02-07)
2
9
 
3
10
 
package/index.js CHANGED
@@ -1567,6 +1567,77 @@ _curry2(function equals(a, b) {
1567
1567
  return _equals(a, b, [], []);
1568
1568
  });
1569
1569
 
1570
+ function _indexOf(list, a, idx) {
1571
+ var inf, item; // Array.prototype.indexOf doesn't exist below IE9
1572
+
1573
+ if (typeof list.indexOf === 'function') {
1574
+ switch (typeof a) {
1575
+ case 'number':
1576
+ if (a === 0) {
1577
+ // manually crawl the list to distinguish between +0 and -0
1578
+ inf = 1 / a;
1579
+
1580
+ while (idx < list.length) {
1581
+ item = list[idx];
1582
+
1583
+ if (item === 0 && 1 / item === inf) {
1584
+ return idx;
1585
+ }
1586
+
1587
+ idx += 1;
1588
+ }
1589
+
1590
+ return -1;
1591
+ } else if (a !== a) {
1592
+ // NaN
1593
+ while (idx < list.length) {
1594
+ item = list[idx];
1595
+
1596
+ if (typeof item === 'number' && item !== item) {
1597
+ return idx;
1598
+ }
1599
+
1600
+ idx += 1;
1601
+ }
1602
+
1603
+ return -1;
1604
+ } // non-zero numbers can utilise Set
1605
+
1606
+
1607
+ return list.indexOf(a, idx);
1608
+ // all these types can utilise Set
1609
+
1610
+ case 'string':
1611
+ case 'boolean':
1612
+ case 'function':
1613
+ case 'undefined':
1614
+ return list.indexOf(a, idx);
1615
+
1616
+ case 'object':
1617
+ if (a === null) {
1618
+ // null can utilise Set
1619
+ return list.indexOf(a, idx);
1620
+ }
1621
+
1622
+ }
1623
+ } // anything else not covered above, defer to R.equals
1624
+
1625
+
1626
+ while (idx < list.length) {
1627
+ if (equals(list[idx], a)) {
1628
+ return idx;
1629
+ }
1630
+
1631
+ idx += 1;
1632
+ }
1633
+
1634
+ return -1;
1635
+ }
1636
+
1637
+ function _includes(a, list) {
1638
+ return _indexOf(list, a, 0) >= 0;
1639
+ }
1640
+
1570
1641
  function _complement(f) {
1571
1642
  return function () {
1572
1643
  return !f.apply(this, arguments);
@@ -1720,6 +1791,33 @@ _curry3(function remove(start, count, list) {
1720
1791
  return result;
1721
1792
  });
1722
1793
 
1794
+ /**
1795
+ * Returns `true` if the specified value is equal, in [`R.equals`](#equals)
1796
+ * terms, to at least one element of the given list; `false` otherwise.
1797
+ * Also works with strings.
1798
+ *
1799
+ * @func
1800
+ * @memberOf R
1801
+ * @since v0.26.0
1802
+ * @category List
1803
+ * @sig a -> [a] -> Boolean
1804
+ * @param {Object} a The item to compare against.
1805
+ * @param {Array} list The array to consider.
1806
+ * @return {Boolean} `true` if an equivalent item is in the list, `false` otherwise.
1807
+ * @see R.any
1808
+ * @example
1809
+ *
1810
+ * R.includes(3, [1, 2, 3]); //=> true
1811
+ * R.includes(4, [1, 2, 3]); //=> false
1812
+ * R.includes({ name: 'Fred' }, [{ name: 'Fred' }]); //=> true
1813
+ * R.includes([42], [[42]]); //=> true
1814
+ * R.includes('ba', 'banana'); //=>true
1815
+ */
1816
+
1817
+ var includes =
1818
+ /*#__PURE__*/
1819
+ _curry2(_includes);
1820
+
1723
1821
  /**
1724
1822
  * Creates a new object with the own properties of the two provided objects. If
1725
1823
  * a key exists in both objects, the provided function is applied to the key
@@ -2543,23 +2641,24 @@ const Field$2 = styled.div `
2543
2641
  const Label = styled.label `
2544
2642
  color: ${p =>
2545
2643
  // eslint-disable-next-line no-nested-ternary
2546
- p.isDisabled ? p.theme.color.lightGray : p.hasError ? p.theme.color.maximumRed : p.theme.color.slateGray};
2644
+ p.disabled ? p.theme.color.lightGray : p.hasError ? p.theme.color.maximumRed : p.theme.color.slateGray};
2547
2645
  display: ${p => (p.isHidden ? 'none' : 'block')};
2548
2646
  font-size: 13px;
2549
2647
  line-height: 1.3846;
2550
2648
  margin-bottom: 4px;
2551
2649
  `;
2552
2650
 
2553
- function Legend({ isDisabled = false, isHidden = false, ...nativeProps }) {
2554
- return jsx(StyledLabel, { as: "legend", isDisabled: isDisabled, isHidden: isHidden, ...nativeProps });
2651
+ // eslint-disable-next-line @typescript-eslint/naming-convention
2652
+ function Legend({ disabled = false, isHidden = false, ...nativeProps }) {
2653
+ return jsx(StyledLabel, { as: "legend", disabled: disabled, isHidden: isHidden, ...nativeProps });
2555
2654
  }
2556
2655
  const StyledLabel = styled(Label) `
2557
2656
  padding: 0;
2558
2657
  `;
2559
2658
 
2560
- function Fieldset({ children, hasBorder = false, isHidden = false, isLight = false, legend, ...nativeProps }) {
2659
+ function Fieldset({ children, hasBorder = false, isLegendHidden = false, isLight = false, legend, ...nativeProps }) {
2561
2660
  const hasLegend = useMemo(() => Boolean(legend), [legend]);
2562
- return (jsxs(StyledField, { as: "fieldset", ...nativeProps, children: [legend && jsx(Legend, { isHidden: isHidden, children: legend }), jsx(Box$b, { "$hasBorder": hasBorder, "$hasLegend": hasLegend, "$isLight": isLight, children: children })] }));
2661
+ return (jsxs(StyledField, { as: "fieldset", ...nativeProps, children: [legend && (jsx(Legend, { disabled: nativeProps.disabled, isHidden: isLegendHidden, children: legend })), jsx(Box$b, { "$hasBorder": hasBorder, "$hasLegend": hasLegend, "$isLight": isLight, children: children })] }));
2563
2662
  }
2564
2663
  const StyledField = styled(Field$2) `
2565
2664
  border: 0;
@@ -3203,17 +3302,18 @@ const useClickOutsideEffect = (zoneRefOrzoneRefs, action, baseContainer) => {
3203
3302
 
3204
3303
  function useFieldUndefineEffect(
3205
3304
  // eslint-disable-next-line @typescript-eslint/naming-convention
3206
- disabled, onChange) {
3305
+ disabled, onChange, onDisable) {
3207
3306
  useEffect(() => {
3208
- if (disabled && onChange) {
3307
+ if (!disabled) {
3308
+ return;
3309
+ }
3310
+ if (onDisable) {
3311
+ onDisable();
3312
+ }
3313
+ if (onChange) {
3209
3314
  onChange(undefined);
3210
3315
  }
3211
- return () => {
3212
- if (onChange) {
3213
- onChange(undefined);
3214
- }
3215
- };
3216
- }, [disabled, onChange]);
3316
+ }, [disabled, onChange, onDisable]);
3217
3317
  }
3218
3318
 
3219
3319
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -3674,6 +3774,26 @@ function useForceUpdate() {
3674
3774
  return { forceDebouncedUpdate, forceUpdate };
3675
3775
  }
3676
3776
 
3777
+ const getPseudoRandomString = () => Math.random().toString(36).slice(2);
3778
+
3779
+ function usePrevious(value) {
3780
+ const ref = useRef();
3781
+ useEffect(() => {
3782
+ ref.current = value;
3783
+ }, [value]); // Only re-run if value changes
3784
+ return ref.current;
3785
+ }
3786
+
3787
+ function useKey(deps) {
3788
+ const keyRef = useRef(getPseudoRandomString());
3789
+ const prevDeps = usePrevious(deps);
3790
+ if (!prevDeps || equals(deps, prevDeps)) {
3791
+ return keyRef.current;
3792
+ }
3793
+ keyRef.current = getPseudoRandomString();
3794
+ return keyRef.current;
3795
+ }
3796
+
3677
3797
  /**
3678
3798
  * Trim and single-space a string
3679
3799
  */
@@ -3704,11 +3824,14 @@ function AutoComplete({ baseContainer, defaultValue, error, isLabelHidden, isLig
3704
3824
  const controlledError = useMemo(() => normalizeString(error), [error]);
3705
3825
  const controlledOptions = useMemo(() => options ?? autoGeneratedOptions, [autoGeneratedOptions, options]);
3706
3826
  const controlledValueAsLabel = useMemo(() => {
3827
+ if (originalProps.disabled) {
3828
+ return undefined;
3829
+ }
3707
3830
  const foundOption = controlledOptions.find(propEq('value', controlledDefaultValue));
3708
3831
  return foundOption ? foundOption.label : undefined;
3709
- }, [controlledDefaultValue, controlledOptions]);
3832
+ }, [controlledDefaultValue, controlledOptions, originalProps.disabled]);
3710
3833
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
3711
- const key = useMemo(() => `${originalProps.name}-${JSON.stringify(controlledDefaultValue)}`, [controlledDefaultValue, originalProps.name]);
3834
+ const key = useKey([controlledDefaultValue, originalProps.disabled, originalProps.name]);
3712
3835
  const close = useCallback(() => {
3713
3836
  setIsOpen(false);
3714
3837
  }, []);
@@ -3751,7 +3874,7 @@ function AutoComplete({ baseContainer, defaultValue, error, isLabelHidden, isLig
3751
3874
  useEffect(() => {
3752
3875
  forceUpdate();
3753
3876
  }, [forceUpdate]);
3754
- return (jsxs(Field$2, { children: [jsx(Label, { hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box$9, { ref: boxRef, onClick: open, children: boxRef.current && (jsx(StyledAutoComplete, { "$isLight": isLight, container: boxRef.current, data: controlledOptions, defaultValue: controlledValueAsLabel, id: originalProps.name, onChange: handleChange, onSelect: handleSelect, open: isOpen, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
3877
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box$9, { ref: boxRef, onClick: open, children: boxRef.current && (jsx(StyledAutoComplete, { "$isLight": isLight, container: boxRef.current, data: controlledOptions, defaultValue: controlledValueAsLabel, id: originalProps.name, onChange: handleChange, onSelect: handleSelect, open: isOpen, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
3755
3878
  }
3756
3879
  const StyledAutoComplete = styled(AutoComplete$1) `
3757
3880
  font-size: 13px;
@@ -3781,10 +3904,14 @@ const Box$9 = styled.div `
3781
3904
  }
3782
3905
  `;
3783
3906
 
3784
- function Checkbox({ error, label, onChange, ...originalProps }) {
3907
+ function Checkbox({
3908
+ // eslint-disable-next-line @typescript-eslint/naming-convention
3909
+ defaultChecked, error, label, onChange, ...originalProps }) {
3910
+ // eslint-disable-next-line @typescript-eslint/naming-convention
3911
+ const controlledDefaultChecked = useMemo(() => (!originalProps.disabled ? defaultChecked : undefined), [defaultChecked, originalProps.disabled]);
3785
3912
  const controlledError = useMemo(() => normalizeString(error), [error]);
3786
3913
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
3787
- const key = useMemo(() => `${originalProps.name}-${String(originalProps.defaultChecked)}`, [originalProps.defaultChecked, originalProps.name]);
3914
+ const key = useKey([controlledDefaultChecked, originalProps.disabled, originalProps.name]);
3788
3915
  const handleChange = useCallback((_, isChecked) => {
3789
3916
  if (!onChange) {
3790
3917
  return;
@@ -3792,7 +3919,7 @@ function Checkbox({ error, label, onChange, ...originalProps }) {
3792
3919
  onChange(isChecked);
3793
3920
  }, [onChange]);
3794
3921
  useFieldUndefineEffect(originalProps.disabled, onChange);
3795
- return (jsxs(Field$2, { children: [jsx(StyledCheckbox, { id: originalProps.name, onChange: handleChange, ...originalProps, children: label }, key), hasError && jsx(FieldError, { children: controlledError })] }));
3922
+ return (jsxs(Field$2, { children: [jsx(StyledCheckbox, { defaultChecked: controlledDefaultChecked, id: originalProps.name, onChange: handleChange, ...originalProps, children: label }, key), hasError && jsx(FieldError, { children: controlledError })] }));
3796
3923
  }
3797
3924
  const StyledCheckbox = styled(Checkbox$1) `
3798
3925
  > .rs-checkbox-checker {
@@ -4625,6 +4752,11 @@ disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden
4625
4752
  timeInputRef.current.focus();
4626
4753
  }
4627
4754
  }, [closeCalendarPicker, forceUpdate, submit, withTime]);
4755
+ const handleDisable = useCallback(() => {
4756
+ selectedLocalizedDateTupleRef.current = undefined;
4757
+ selectedLocalizedTimeTupleRef.current = undefined;
4758
+ forceUpdate();
4759
+ }, [forceUpdate]);
4628
4760
  const handleTimeInputFilled = useCallback((nextTimeTuple) => {
4629
4761
  // If a date has already been selected
4630
4762
  if (selectedLocalizedDateTupleRef.current) {
@@ -4640,9 +4772,9 @@ disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden
4640
4772
  isCalendarPickerOpenRef.current = true;
4641
4773
  forceUpdate();
4642
4774
  }, [forceUpdate]);
4643
- useFieldUndefineEffect(disabled, onChange);
4775
+ useFieldUndefineEffect(disabled, onChange, handleDisable);
4644
4776
  useClickOutsideEffect(boxRef, closeCalendarPicker, baseContainer);
4645
- return (jsxs(Fieldset, { disabled: disabled, ...nativeProps, children: [jsx(Legend, { isDisabled: disabled, isHidden: isLabelHidden, children: label }), jsxs(Box$4, { ref: boxRef, children: [jsx(Field$1, { children: jsx(DateInput, { ref: dateInputRef, defaultValue: selectedLocalizedDateTupleRef.current, disabled: disabled, isCompact: isCompact, isForcedFocused: isCalendarPickerOpenRef.current, isLight: isLight, onChange: handleDateInputChange, onClick: openCalendarPicker, onNext: handleDateInputNext }) }), withTime && (jsx(Field$1, { "$isTimeField": true, children: jsx(TimeInput, { ref: timeInputRef, baseContainer: baseContainer, defaultValue: selectedLocalizedTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isLight: isLight, minutesRange: minutesRange, onBack: () => dateInputRef.current.focus(true), onChange: handleTimeInputFilled, onFocus: closeCalendarPicker, onPrevious: () => dateInputRef.current.focus(true) }) }))] }), hasError && jsx(FieldError, { children: controlledError }), jsx(CalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isCalendarPickerOpenRef.current, onChange: handleCalendarPickerChange })] }));
4777
+ return (jsxs(Fieldset, { disabled: disabled, isLegendHidden: isLabelHidden, legend: label, ...nativeProps, children: [jsxs(Box$4, { ref: boxRef, children: [jsx(Field$1, { children: jsx(DateInput, { ref: dateInputRef, defaultValue: selectedLocalizedDateTupleRef.current, disabled: disabled, isCompact: isCompact, isForcedFocused: isCalendarPickerOpenRef.current, isLight: isLight, onChange: handleDateInputChange, onClick: openCalendarPicker, onNext: handleDateInputNext }) }), withTime && (jsx(Field$1, { "$isTimeField": true, children: jsx(TimeInput, { ref: timeInputRef, baseContainer: baseContainer, defaultValue: selectedLocalizedTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isLight: isLight, minutesRange: minutesRange, onBack: () => dateInputRef.current.focus(true), onChange: handleTimeInputFilled, onFocus: closeCalendarPicker, onPrevious: () => dateInputRef.current.focus(true) }) }))] }), hasError && jsx(FieldError, { children: controlledError }), jsx(CalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isCalendarPickerOpenRef.current, onChange: handleCalendarPickerChange })] }));
4646
4778
  }
4647
4779
  const Box$4 = styled.div `
4648
4780
  * {
@@ -4913,6 +5045,13 @@ disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden
4913
5045
  isRangeCalendarPickerOpenRef.current = false;
4914
5046
  forceUpdate();
4915
5047
  }, [forceUpdate]);
5048
+ const handleDisable = useCallback(() => {
5049
+ selectedLocalizedStartDateTupleRef.current = undefined;
5050
+ selectedLocalizedStartTimeTupleRef.current = undefined;
5051
+ selectedLocalizedEndDateTupleRef.current = undefined;
5052
+ selectedLocalizedEndTimeTupleRef.current = undefined;
5053
+ forceUpdate();
5054
+ }, [forceUpdate]);
4916
5055
  const handleEndDateInputNext = useCallback(() => {
4917
5056
  if (!withTime) {
4918
5057
  return;
@@ -5018,9 +5157,9 @@ disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden
5018
5157
  isRangeCalendarPickerOpenRef.current = true;
5019
5158
  forceUpdate();
5020
5159
  }, [forceUpdate]);
5021
- useFieldUndefineEffect(disabled, onChange);
5160
+ useFieldUndefineEffect(disabled, onChange, handleDisable);
5022
5161
  useClickOutsideEffect([endDateInputRef, startDateInputRef], closeRangeCalendarPicker, baseContainer);
5023
- return (jsxs(Fieldset, { ...nativeProps, children: [jsx(Legend, { isDisabled: disabled, isHidden: isLabelHidden, children: label }), jsxs(Box$2, { isDisabled: disabled, children: [jsx(Field, { children: jsx(DateInput, { ref: startDateInputRef, defaultValue: selectedLocalizedStartDateTupleRef.current, disabled: disabled, isCompact: isCompact, isForcedFocused: isRangeCalendarPickerOpenRef.current, isLight: isLight, isStartDate: true, onChange: (nextDateTuple, isFilled) => handleDateInputChange(DateRangePosition.START, nextDateTuple, isFilled), onClick: openRangeCalendarPicker, onNext: handleStartDateInputNext }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: startTimeInputRef, baseContainer: baseContainer, defaultValue: selectedLocalizedStartTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isLight: isLight, isStartDate: true, minutesRange: minutesRange, onBack: () => startDateInputRef.current.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.START, nextTimeTuple), onFocus: closeRangeCalendarPicker, onNext: () => endDateInputRef.current.focus(), onPrevious: () => startDateInputRef.current.focus(true) }) })), jsx(Field, { isEndDateField: true, children: jsx(DateInput, { ref: endDateInputRef, defaultValue: selectedLocalizedEndDateTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: true, isForcedFocused: isRangeCalendarPickerOpenRef.current, isLight: isLight, onBack: handleEndDateInputPrevious, onChange: (nextDateTuple, isFilled) => handleDateInputChange(DateRangePosition.END, nextDateTuple, isFilled), onClick: openRangeCalendarPicker, onNext: handleEndDateInputNext, onPrevious: handleEndDateInputPrevious }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: endTimeInputRef, baseContainer: baseContainer, defaultValue: selectedLocalizedEndTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: true, isLight: isLight, minutesRange: minutesRange, onBack: () => endDateInputRef.current.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.END, nextTimeTuple), onFocus: closeRangeCalendarPicker, onPrevious: () => endDateInputRef.current.focus(true) }) }))] }), hasError && jsx(FieldError, { children: controlledError }), jsx(RangeCalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isRangeCalendarPickerOpenRef.current, onChange: handleRangeCalendarPickerChange })] }));
5162
+ return (jsxs(Fieldset, { disabled: disabled, isLegendHidden: isLabelHidden, legend: label, ...nativeProps, children: [jsxs(Box$2, { isDisabled: disabled, children: [jsx(Field, { children: jsx(DateInput, { ref: startDateInputRef, defaultValue: selectedLocalizedStartDateTupleRef.current, disabled: disabled, isCompact: isCompact, isForcedFocused: isRangeCalendarPickerOpenRef.current, isLight: isLight, isStartDate: true, onChange: (nextDateTuple, isFilled) => handleDateInputChange(DateRangePosition.START, nextDateTuple, isFilled), onClick: openRangeCalendarPicker, onNext: handleStartDateInputNext }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: startTimeInputRef, baseContainer: baseContainer, defaultValue: selectedLocalizedStartTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isLight: isLight, isStartDate: true, minutesRange: minutesRange, onBack: () => startDateInputRef.current.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.START, nextTimeTuple), onFocus: closeRangeCalendarPicker, onNext: () => endDateInputRef.current.focus(), onPrevious: () => startDateInputRef.current.focus(true) }) })), jsx(Field, { isEndDateField: true, children: jsx(DateInput, { ref: endDateInputRef, defaultValue: selectedLocalizedEndDateTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: true, isForcedFocused: isRangeCalendarPickerOpenRef.current, isLight: isLight, onBack: handleEndDateInputPrevious, onChange: (nextDateTuple, isFilled) => handleDateInputChange(DateRangePosition.END, nextDateTuple, isFilled), onClick: openRangeCalendarPicker, onNext: handleEndDateInputNext, onPrevious: handleEndDateInputPrevious }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: endTimeInputRef, baseContainer: baseContainer, defaultValue: selectedLocalizedEndTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: true, isLight: isLight, minutesRange: minutesRange, onBack: () => endDateInputRef.current.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.END, nextTimeTuple), onFocus: closeRangeCalendarPicker, onPrevious: () => endDateInputRef.current.focus(true) }) }))] }), hasError && jsx(FieldError, { children: controlledError }), jsx(RangeCalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isRangeCalendarPickerOpenRef.current, onChange: handleRangeCalendarPickerChange })] }));
5024
5163
  }
5025
5164
  const Box$2 = styled.div `
5026
5165
  * {
@@ -5055,9 +5194,10 @@ function MultiCheckbox({ defaultValue = [],
5055
5194
  // eslint-disable-next-line @typescript-eslint/naming-convention
5056
5195
  disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, label, name, onChange, options }) {
5057
5196
  const checkedOptionValues = useRef(defaultValue);
5197
+ const controlledDefaultValue = useMemo(() => (!disabled ? defaultValue : undefined), [defaultValue, disabled]);
5058
5198
  const controlledError = useMemo(() => normalizeString(error), [error]);
5059
5199
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5060
- const key = useMemo(() => `${name}-${JSON.stringify(defaultValue)}`, [defaultValue, name]);
5200
+ const key = useKey([controlledDefaultValue, disabled, name]);
5061
5201
  const handleChange = useCallback((nextOptionValue, isChecked) => {
5062
5202
  const nextCheckedOptionValues = isChecked
5063
5203
  ? [...checkedOptionValues.current, nextOptionValue]
@@ -5069,10 +5209,10 @@ disabled = false, error, isInline = false, isLabelHidden = false, isLight = fals
5069
5209
  }
5070
5210
  }, [onChange]);
5071
5211
  useFieldUndefineEffect(disabled, onChange);
5072
- const checkboxesElement = useMemo(() => (jsx(Fragment, { children: options.map((option, index) => (jsx(Checkbox, { defaultChecked: defaultValue.includes(option.value), disabled: disabled, label: option.label, name: `${name}${index}`, onChange: (isChecked) => handleChange(option.value, isChecked) }, String(option.value)))) })),
5212
+ const checkboxesElement = useMemo(() => (jsx(Fragment, { children: options.map((option, index) => (jsx(Checkbox, { defaultChecked: includes(option.value, controlledDefaultValue || []), disabled: disabled, label: option.label, name: `${name}${index}`, onChange: (isChecked) => handleChange(option.value, isChecked) }, String(option.value)))) })),
5073
5213
  // eslint-disable-next-line react-hooks/exhaustive-deps
5074
5214
  [disabled, handleChange, name, options]);
5075
- return (jsxs(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(ChecboxesBox$1, { "$isInline": isInline, children: checkboxesElement }), hasError && jsx(FieldError, { children: controlledError })] }, key));
5215
+ return (jsxs(Fieldset, { disabled: disabled, isLegendHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(ChecboxesBox$1, { "$isInline": isInline, children: checkboxesElement }), hasError && jsx(FieldError, { children: controlledError })] }, key));
5076
5216
  }
5077
5217
  const ChecboxesBox$1 = styled.div `
5078
5218
  color: ${p => p.theme.color.gunMetal};
@@ -5104,15 +5244,16 @@ const ChecboxesBox$1 = styled.div `
5104
5244
  `}
5105
5245
  `;
5106
5246
 
5107
- function MultiSelect({ baseContainer, error, fixedWidth, isLabelHidden = false, isLight = false, label, onChange, options,
5247
+ function MultiSelect({ baseContainer, defaultValue, error, fixedWidth, isLabelHidden = false, isLight = false, label, onChange, options,
5108
5248
  // eslint-disable-next-line @typescript-eslint/naming-convention
5109
5249
  searchable = false, ...originalProps }) {
5110
5250
  // eslint-disable-next-line no-null/no-null
5111
5251
  const boxRef = useRef(null);
5112
5252
  const [isOpen, setIsOpen] = useState(false);
5253
+ const controlledDefaultValue = useMemo(() => (!originalProps.disabled ? defaultValue : undefined), [defaultValue, originalProps.disabled]);
5113
5254
  const controlledError = useMemo(() => normalizeString(error), [error]);
5114
5255
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5115
- const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5256
+ const key = useKey([controlledDefaultValue, originalProps.disabled, originalProps.name]);
5116
5257
  const { forceUpdate } = useForceUpdate();
5117
5258
  const close = useCallback(() => {
5118
5259
  setIsOpen(false);
@@ -5142,7 +5283,7 @@ searchable = false, ...originalProps }) {
5142
5283
  useEffect(() => {
5143
5284
  forceUpdate();
5144
5285
  }, [forceUpdate]);
5145
- return (jsxs(Field$2, { children: [jsx(Label, { hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box$1, { ref: boxRef, "$isActive": isOpen, "$isLight": isLight, onClick: toggle, children: boxRef.current && (jsx(TagPicker, { container: boxRef.current, data: options, id: originalProps.name, onChange: handleChange, onClick: toggle, open: isOpen, searchable: searchable, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
5286
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box$1, { ref: boxRef, "$isActive": isOpen, "$isLight": isLight, onClick: toggle, children: boxRef.current && (jsx(TagPicker, { container: boxRef.current, data: options, defaultValue: controlledDefaultValue, id: originalProps.name, onChange: handleChange, onClick: toggle, open: isOpen, searchable: searchable, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
5146
5287
  }
5147
5288
  const Box$1 = styled.div `
5148
5289
  position: relative;
@@ -5225,28 +5366,29 @@ const Box$1 = styled.div `
5225
5366
  function MultiRadio({ defaultValue,
5226
5367
  // eslint-disable-next-line @typescript-eslint/naming-convention
5227
5368
  disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, label, name, onChange, options }) {
5228
- const [checkedOptionValue, setCheckedOptionValue] = useState(undefined);
5369
+ const [controlledDefaultValue, setControlledDefaultValue] = useState(undefined);
5229
5370
  const controlledError = useMemo(() => normalizeString(error), [error]);
5230
5371
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5231
- const key = useMemo(() => `${name}-${String(checkedOptionValue)}}`, [checkedOptionValue, name]);
5372
+ const key = useKey([controlledDefaultValue, disabled, name]);
5232
5373
  const handleChange = useCallback((nextOptionValue, isChecked) => {
5233
5374
  const nextCheckedOptionValue = isChecked ? nextOptionValue : undefined;
5234
- setCheckedOptionValue(nextCheckedOptionValue);
5375
+ setControlledDefaultValue(nextCheckedOptionValue);
5235
5376
  if (onChange) {
5236
5377
  onChange(nextCheckedOptionValue);
5237
5378
  }
5238
5379
  }, [onChange]);
5239
5380
  useFieldUndefineEffect(disabled, onChange);
5240
- // TODO There may be a better solution.
5381
+ // TODO There may be a better solution. Replace the map with a rendering memo?
5241
5382
  // A key change is not enough to force radio checked check changes
5242
5383
  // on `defaultValue` property update (even when appending `defaultValue` to `key`),
5243
5384
  // we need to force a second re-render in order for the changes to be applied.
5244
5385
  useEffect(() => {
5245
- setCheckedOptionValue(defaultValue);
5246
- }, [defaultValue]);
5247
- return (jsxs(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(ChecboxesBox, { "$isInline": isInline, children: options.map((option, index) => (jsx(Radio
5386
+ const nextControlledDefaultValue = !disabled ? defaultValue : undefined;
5387
+ setControlledDefaultValue(nextControlledDefaultValue);
5388
+ }, [defaultValue, disabled]);
5389
+ return (jsxs(Fieldset, { disabled: disabled, isLegendHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(ChecboxesBox, { "$isInline": isInline, children: options.map((option, index) => (jsx(Radio
5248
5390
  // eslint-disable-next-line react/no-array-index-key
5249
- , { defaultChecked: option.value === checkedOptionValue, disabled: disabled, name: name, onChange: (_, isChecked) => handleChange(option.value, isChecked), children: option.label }, `${name}-${index}`))) }), hasError && jsx(FieldError, { children: controlledError })] }, key));
5391
+ , { defaultChecked: equals(option.value, controlledDefaultValue), disabled: disabled, name: name, onChange: (_, isChecked) => handleChange(option.value, isChecked), children: option.label }, `${key}-${index}`))) }), hasError && jsx(FieldError, { children: controlledError })] }, key));
5250
5392
  }
5251
5393
  const ChecboxesBox = styled.div `
5252
5394
  color: ${p => p.theme.color.gunMetal};
@@ -5282,7 +5424,9 @@ const ChecboxesBox = styled.div `
5282
5424
  `}
5283
5425
  `;
5284
5426
 
5285
- function MultiZoneEditor({ addButtonLabel, defaultValue = [], error, initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onDelete, onEdit }) {
5427
+ function MultiZoneEditor({ addButtonLabel, defaultValue = [],
5428
+ // eslint-disable-next-line @typescript-eslint/naming-convention
5429
+ disabled = false, error, initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onChange, onDelete, onEdit }) {
5286
5430
  const prevDefaultValueRef = useRef(defaultValue);
5287
5431
  const [zones, setZones] = useState(defaultValue);
5288
5432
  const controlledError = useMemo(() => normalizeString(error), [error]);
@@ -5311,13 +5455,17 @@ function MultiZoneEditor({ addButtonLabel, defaultValue = [], error, initialZone
5311
5455
  onEdit(zone, index);
5312
5456
  }
5313
5457
  }, [onEdit]);
5458
+ const handleDisable = useCallback(() => {
5459
+ setZones([]);
5460
+ }, []);
5314
5461
  useEffect(() => {
5315
5462
  if (equals(defaultValue, prevDefaultValueRef.current)) {
5316
5463
  return;
5317
5464
  }
5318
5465
  setZones(defaultValue);
5319
5466
  }, [defaultValue]);
5320
- return (jsxs(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(Button, { accent: Accent.SECONDARY, Icon: Plus, isFullWidth: true, onClick: addZone, children: addButtonLabel }), jsx(Fragment, { children: zones.map((zone, index) => (
5467
+ useFieldUndefineEffect(disabled, onChange, handleDisable);
5468
+ return (jsxs(Fieldset, { disabled: disabled, isLegendHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(Button, { accent: Accent.SECONDARY, disabled: disabled, Icon: Plus, isFullWidth: true, onClick: addZone, children: addButtonLabel }), jsx(Fragment, { children: zones.map((zone, index) => (
5321
5469
  // eslint-disable-next-line react/no-array-index-key
5322
5470
  jsxs(Row, { children: [jsxs(ZoneWrapper, { children: [zone[labelPropName], jsxs(Link, { onClick: () => centerZone(zone), children: [jsx(SelectRectangle, {}), jsx("span", { children: "Centrer sur la carte" })] })] }), jsx(IconButton, { accent: Accent.SECONDARY, Icon: Edit, onClick: () => editZone(index, zone) }), jsx(IconButton, { accent: Accent.SECONDARY, "aria-label": "Supprimer cette zone", Icon: Delete, onClick: () => deleteZone(index) })] }, `zone-${index}`))) }), hasError && jsx(FieldError, { children: controlledError })] }));
5323
5471
  }
@@ -5350,10 +5498,11 @@ const Link = styled.a `
5350
5498
  }
5351
5499
  `;
5352
5500
 
5353
- function NumberInput({ error, isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5501
+ function NumberInput({ defaultValue, error, isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5502
+ const controlledDefaultValue = useMemo(() => (!originalProps.disabled ? defaultValue : undefined), [defaultValue, originalProps.disabled]);
5354
5503
  const controlledError = useMemo(() => normalizeString(error), [error]);
5355
5504
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5356
- const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5505
+ const key = useKey([controlledDefaultValue, originalProps.disabled, originalProps.name]);
5357
5506
  const handleChange = useCallback((nextValue) => {
5358
5507
  if (!onChange) {
5359
5508
  return;
@@ -5364,7 +5513,7 @@ function NumberInput({ error, isLabelHidden = false, isLight = false, label, onC
5364
5513
  onChange(normalizedNextValue);
5365
5514
  }, [onChange]);
5366
5515
  useFieldUndefineEffect(originalProps.disabled, onChange);
5367
- return (jsxs(Field$2, { children: [jsx(Label, { htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(StyledInput$2, { "$isLight": isLight, id: originalProps.name, onChange: handleChange, type: "number", ...originalProps }, key), hasError && jsx(FieldError, { children: controlledError })] }));
5516
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(StyledInput$2, { "$isLight": isLight, defaultValue: controlledDefaultValue, id: originalProps.name, onChange: handleChange, type: "number", ...originalProps }, key), hasError && jsx(FieldError, { children: controlledError })] }));
5368
5517
  }
5369
5518
  const StyledInput$2 = styled(Input) `
5370
5519
  background-color: ${p => (p.$isLight ? p.theme.color.white : p.theme.color.gainsboro)};
@@ -5373,16 +5522,17 @@ const StyledInput$2 = styled(Input) `
5373
5522
  width: 100%;
5374
5523
  `;
5375
5524
 
5376
- function Select({ baseContainer, error, isLabelHidden = false, isLight = false, label, onChange, options,
5525
+ function Select({ baseContainer, defaultValue, error, isLabelHidden = false, isLight = false, label, onChange, options,
5377
5526
  // eslint-disable-next-line @typescript-eslint/naming-convention
5378
5527
  searchable = false, ...originalProps }) {
5379
5528
  // eslint-disable-next-line no-null/no-null
5380
5529
  const boxRef = useRef(null);
5381
5530
  const [isOpen, setIsOpen] = useState(false);
5382
5531
  const { forceUpdate } = useForceUpdate();
5532
+ const controlledDefaultValue = useMemo(() => (!originalProps.disabled ? defaultValue : undefined), [defaultValue, originalProps.disabled]);
5383
5533
  const controlledError = useMemo(() => normalizeString(error), [error]);
5384
5534
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5385
- const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5535
+ const key = useKey([controlledDefaultValue, originalProps.disabled, originalProps.name]);
5386
5536
  const close = useCallback(() => {
5387
5537
  setIsOpen(false);
5388
5538
  }, []);
@@ -5412,7 +5562,7 @@ searchable = false, ...originalProps }) {
5412
5562
  useEffect(() => {
5413
5563
  forceUpdate();
5414
5564
  }, [forceUpdate]);
5415
- return (jsxs(Field$2, { children: [jsx(Label, { hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box, { ref: boxRef, onClick: toggle, children: boxRef.current && (jsx(StyledSelectPicker, { "$isLight": isLight, container: boxRef.current, data: options, id: originalProps.name,
5565
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box, { ref: boxRef, onClick: toggle, children: boxRef.current && (jsx(StyledSelectPicker, { "$isLight": isLight, container: boxRef.current, data: options, defaultValue: controlledDefaultValue, id: originalProps.name,
5416
5566
  // The `unknown` type from Rsuite library is wrong. It should be inferred from `data` prop type.
5417
5567
  // `onChange: ((value: unknown, event: React.SyntheticEvent<Element, Event>) => void) | undefined`
5418
5568
  onChange: handleChange, open: isOpen, searchable: searchable, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
@@ -5462,11 +5612,12 @@ const Box = styled.div `
5462
5612
  }
5463
5613
  `;
5464
5614
 
5465
- function Textarea({ error, isLabelHidden = false, isLight = false, label, onChange, rows = 3, ...originalProps }) {
5615
+ function Textarea({ defaultValue, error, isLabelHidden = false, isLight = false, label, onChange, rows = 3, ...originalProps }) {
5466
5616
  const inputRef = useRef();
5617
+ const controlledDefaultValue = useMemo(() => (!originalProps.disabled ? defaultValue : undefined), [defaultValue, originalProps.disabled]);
5467
5618
  const controlledError = useMemo(() => normalizeString(error), [error]);
5468
5619
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5469
- const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5620
+ const key = useKey([controlledDefaultValue, originalProps.disabled, originalProps.name]);
5470
5621
  const handleChange = useCallback(() => {
5471
5622
  if (!onChange) {
5472
5623
  return;
@@ -5476,7 +5627,7 @@ function Textarea({ error, isLabelHidden = false, isLight = false, label, onChan
5476
5627
  onChange(normalizedNextValue);
5477
5628
  }, [onChange]);
5478
5629
  useFieldUndefineEffect(originalProps.disabled, onChange);
5479
- return (jsxs(Field$2, { children: [jsx(Label, { htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(StyledInput$1, { ref: inputRef, "$isLight": isLight, as: "textarea", id: originalProps.name, onChange: handleChange, rows: rows, ...originalProps }, key), hasError && jsx(FieldError, { children: controlledError })] }));
5630
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(StyledInput$1, { ref: inputRef, "$isLight": isLight, as: "textarea", defaultValue: controlledDefaultValue, id: originalProps.name, onChange: handleChange, rows: rows, ...originalProps }, key), hasError && jsx(FieldError, { children: controlledError })] }));
5480
5631
  }
5481
5632
  const StyledInput$1 = styled(Input) `
5482
5633
  background-color: ${p => (p.$isLight ? p.theme.color.white : p.theme.color.gainsboro)};
@@ -5490,10 +5641,11 @@ const StyledInput$1 = styled(Input) `
5490
5641
  }
5491
5642
  `;
5492
5643
 
5493
- function TextInput({ error, isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5644
+ function TextInput({ defaultValue, error, isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5645
+ const controlledDefaultValue = useMemo(() => (!originalProps.disabled ? defaultValue : undefined), [defaultValue, originalProps.disabled]);
5494
5646
  const controlledError = useMemo(() => normalizeString(error), [error]);
5495
5647
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5496
- const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5648
+ const key = useKey([controlledDefaultValue, originalProps.disabled, originalProps.name]);
5497
5649
  const handleChange = useCallback((nextValue) => {
5498
5650
  if (!onChange) {
5499
5651
  return;
@@ -5502,7 +5654,7 @@ function TextInput({ error, isLabelHidden = false, isLight = false, label, onCha
5502
5654
  onChange(normalizedNextValue);
5503
5655
  }, [onChange]);
5504
5656
  useFieldUndefineEffect(originalProps.disabled, onChange);
5505
- return (jsxs(Field$2, { children: [jsx(Label, { htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(StyledInput, { "$isLight": isLight, id: originalProps.name, onChange: handleChange, type: "text", ...originalProps }, key), hasError && jsx(FieldError, { children: controlledError })] }));
5657
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(StyledInput, { "$isLight": isLight, defaultValue: controlledDefaultValue, id: originalProps.name, onChange: handleChange, type: "text", ...originalProps }, key), hasError && jsx(FieldError, { children: controlledError })] }));
5506
5658
  }
5507
5659
  const StyledInput = styled(Input) `
5508
5660
  background-color: ${p => (p.$isLight ? p.theme.color.white : p.theme.color.gainsboro)};