@mtes-mct/monitor-ui 2.11.0 → 2.12.0

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.11.0](https://github.com/MTES-MCT/monitor-ui/compare/v2.10.0...v2.11.0) (2023-02-07)
2
+
3
+
4
+ ### Features
5
+
6
+ * **formiks:** set value to undefined on destroy ([8d810ad](https://github.com/MTES-MCT/monitor-ui/commit/8d810ad5dae3990628b3a63744adcc5fb339a3ad))
7
+
1
8
  # [2.10.0](https://github.com/MTES-MCT/monitor-ui/compare/v2.9.5...v2.10.0) (2023-01-31)
2
9
 
3
10
 
package/index.js CHANGED
@@ -2794,7 +2794,7 @@ const FieldError = styled.p `
2794
2794
  margin-top: 4px;
2795
2795
  `;
2796
2796
 
2797
- const useClickOutside = (zoneRefOrzoneRefs, action, baseContainer) => {
2797
+ const useClickOutsideEffect = (zoneRefOrzoneRefs, action, baseContainer) => {
2798
2798
  const handleClickOutside = useCallback((event) => {
2799
2799
  const eventTarget = event.target;
2800
2800
  const zoneRefs = Array.isArray(zoneRefOrzoneRefs) ? zoneRefOrzoneRefs : [zoneRefOrzoneRefs];
@@ -2813,6 +2813,21 @@ const useClickOutside = (zoneRefOrzoneRefs, action, baseContainer) => {
2813
2813
  }, [baseContainer, handleClickOutside]);
2814
2814
  };
2815
2815
 
2816
+ function useFieldUndefineEffect(
2817
+ // eslint-disable-next-line @typescript-eslint/naming-convention
2818
+ disabled, onChange) {
2819
+ useEffect(() => {
2820
+ if (disabled && onChange) {
2821
+ onChange(undefined);
2822
+ }
2823
+ return () => {
2824
+ if (onChange) {
2825
+ onChange(undefined);
2826
+ }
2827
+ };
2828
+ }, [disabled, onChange]);
2829
+ }
2830
+
2816
2831
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2817
2832
 
2818
2833
  function getDefaultExportFromCjs (x) {
@@ -3343,7 +3358,8 @@ function AutoComplete({ baseContainer, defaultValue, error, isLabelHidden, isLig
3343
3358
  }
3344
3359
  setDefaultControlledValue(defaultValue);
3345
3360
  }, [defaultValue]);
3346
- useClickOutside(boxRef, close, baseContainer);
3361
+ useFieldUndefineEffect(originalProps.disabled, onChange);
3362
+ useClickOutsideEffect(boxRef, close, baseContainer);
3347
3363
  useEffect(() => {
3348
3364
  forceUpdate();
3349
3365
  }, [forceUpdate]);
@@ -3377,7 +3393,9 @@ const Box$9 = styled.div `
3377
3393
  }
3378
3394
  `;
3379
3395
 
3380
- function Checkbox({ label, onChange, ...originalProps }) {
3396
+ function Checkbox({ error, label, onChange, ...originalProps }) {
3397
+ const controlledError = useMemo(() => normalizeString(error), [error]);
3398
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
3381
3399
  const key = useMemo(() => `${originalProps.name}-${String(originalProps.defaultChecked)}`, [originalProps.defaultChecked, originalProps.name]);
3382
3400
  const handleChange = useCallback((_, isChecked) => {
3383
3401
  if (!onChange) {
@@ -3385,7 +3403,8 @@ function Checkbox({ label, onChange, ...originalProps }) {
3385
3403
  }
3386
3404
  onChange(isChecked);
3387
3405
  }, [onChange]);
3388
- return (jsx(StyledCheckbox, { id: originalProps.name, onChange: handleChange, ...originalProps, children: label }, key));
3406
+ useFieldUndefineEffect(originalProps.disabled, onChange);
3407
+ return (jsxs(Field$2, { children: [jsx(StyledCheckbox, { id: originalProps.name, onChange: handleChange, ...originalProps, children: label }, key), hasError && jsx(FieldError, { children: controlledError })] }));
3389
3408
  }
3390
3409
  const StyledCheckbox = styled(Checkbox$1) `
3391
3410
  > .rs-checkbox-checker {
@@ -4246,7 +4265,7 @@ disabled = false, isCompact, isEndDate = false, isLight, isStartDate = false, mi
4246
4265
  const nextTimeTuple = [hourInputRef.current.value, minuteInputRef.current.value];
4247
4266
  onChange(nextTimeTuple);
4248
4267
  }, [closeRangedTimePicker, onChange]);
4249
- useClickOutside(boxRef, closeRangedTimePicker, baseContainer);
4268
+ useClickOutsideEffect(boxRef, closeRangedTimePicker, baseContainer);
4250
4269
  return (jsxs(Box$6, { ref: boxRef, "$hasError": hasFormatError || hasValidationError, "$isCompact": isCompact, "$isDisabled": disabled, "$isFocused": isFocused, "$isLight": isLight, children: [jsxs(InputGroup, { children: [jsxs("div", { children: [jsx(NumberInput$1, { ref: hourInputRef, "aria-label": `Heure${isStartDate ? ' de début' : ''}${isEndDate ? ' de fin' : ''}`, defaultValue: controlledDefaultValue && controlledDefaultValue[0], disabled: disabled, isLight: isLight, max: 23, min: 0, onBack: handleBack, onBlur: handleBlur, onClick: openRangedTimePicker, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onInput: handleHourInput, onNext: () => minuteInputRef.current.focus(), onPrevious: onPrevious, size: 2 }), ":", jsx(NumberInput$1, { ref: minuteInputRef, "aria-label": `Minute${isStartDate ? ' de début' : ''}${isEndDate ? ' de fin' : ''}`, defaultValue: controlledDefaultValue && controlledDefaultValue[1], disabled: disabled, isLight: isLight, max: 59, min: 0, onBack: () => hourInputRef.current.focus(), onBlur: handleBlur, onClick: openRangedTimePicker, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onNext: onNext, onPrevious: () => hourInputRef.current.focus(), size: 2 })] }), !isCompact && jsx(Clock, {})] }), isRangedTimePickerOpenRef.current && (jsx(RangedTimePicker, { filter: rangedTimePickerFilter, minutesRange: minutesRange, onChange: handleRangedTimePickedChange }))] }));
4251
4270
  }
4252
4271
  const TimeInput = forwardRef(TimeInputWithRef);
@@ -4492,7 +4511,7 @@ const Box$5 = styled.div `
4492
4511
 
4493
4512
  function DatePicker({ baseContainer, defaultValue,
4494
4513
  // eslint-disable-next-line @typescript-eslint/naming-convention
4495
- disabled = false, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
4514
+ disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
4496
4515
  const boxRef = useRef();
4497
4516
  const dateInputRef = useRef();
4498
4517
  const timeInputRef = useRef();
@@ -4501,6 +4520,8 @@ disabled = false, isCompact = false, isHistorical = false, isLabelHidden = false
4501
4520
  const selectedLocalizedDateTupleRef = useRef(getDateTupleFromDate(selectedLocalizedDateRef.current));
4502
4521
  const selectedLocalizedTimeTupleRef = useRef(getTimeTupleFromDate(selectedLocalizedDateRef.current));
4503
4522
  const { forceUpdate } = useForceUpdate();
4523
+ const controlledError = useMemo(() => normalizeString(error), [error]);
4524
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
4504
4525
  const rangeCalendarPickerDefaultValue = useMemo(() => selectedLocalizedDateTupleRef.current
4505
4526
  ? getDateFromDateAndTimeTuple(selectedLocalizedDateTupleRef.current, ['00', '00'])
4506
4527
  : undefined,
@@ -4579,8 +4600,9 @@ disabled = false, isCompact = false, isHistorical = false, isLabelHidden = false
4579
4600
  isCalendarPickerOpenRef.current = true;
4580
4601
  forceUpdate();
4581
4602
  }, [forceUpdate]);
4582
- useClickOutside(boxRef, closeCalendarPicker, baseContainer);
4583
- 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) }) }))] }), jsx(CalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isCalendarPickerOpenRef.current, onChange: handleCalendarPickerChange })] }));
4603
+ useFieldUndefineEffect(disabled, onChange);
4604
+ useClickOutsideEffect(boxRef, closeCalendarPicker, baseContainer);
4605
+ 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 })] }));
4584
4606
  }
4585
4607
  const Box$4 = styled.div `
4586
4608
  * {
@@ -4807,7 +4829,7 @@ var DateRangePosition;
4807
4829
 
4808
4830
  function DateRangePicker({ baseContainer, defaultValue,
4809
4831
  // eslint-disable-next-line @typescript-eslint/naming-convention
4810
- disabled = false, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
4832
+ disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
4811
4833
  const startDateInputRef = useRef();
4812
4834
  const startTimeInputRef = useRef();
4813
4835
  const endDateInputRef = useRef();
@@ -4820,6 +4842,8 @@ disabled = false, isCompact = false, isHistorical = false, isLabelHidden = false
4820
4842
  const selectedLocalizedStartTimeTupleRef = useRef(getTimeTupleFromDate(selectedLocalizedStartDateRef.current));
4821
4843
  const selectedLocalizedEndTimeTupleRef = useRef(getTimeTupleFromDate(selectedLocalizedEndDateRef.current));
4822
4844
  const { forceUpdate } = useForceUpdate();
4845
+ const controlledError = useMemo(() => normalizeString(error), [error]);
4846
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
4823
4847
  const rangeCalendarPickerDefaultValue = useMemo(() => selectedLocalizedStartDateTupleRef.current && selectedLocalizedEndDateTupleRef.current
4824
4848
  ? [
4825
4849
  getDateFromDateAndTimeTuple(selectedLocalizedStartDateTupleRef.current, ['00', '00']),
@@ -4954,8 +4978,9 @@ disabled = false, isCompact = false, isHistorical = false, isLabelHidden = false
4954
4978
  isRangeCalendarPickerOpenRef.current = true;
4955
4979
  forceUpdate();
4956
4980
  }, [forceUpdate]);
4957
- useClickOutside([endDateInputRef, startDateInputRef], closeRangeCalendarPicker, baseContainer);
4958
- 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) }) }))] }), jsx(RangeCalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isRangeCalendarPickerOpenRef.current, onChange: handleRangeCalendarPickerChange })] }));
4981
+ useFieldUndefineEffect(disabled, onChange);
4982
+ useClickOutsideEffect([endDateInputRef, startDateInputRef], closeRangeCalendarPicker, baseContainer);
4983
+ 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 })] }));
4959
4984
  }
4960
4985
  const Box$2 = styled.div `
4961
4986
  * {
@@ -4986,8 +5011,12 @@ const Field = styled.span `
4986
5011
  }};
4987
5012
  `;
4988
5013
 
4989
- function MultiCheckbox({ defaultValue = [], isInline = false, isLabelHidden = false, isLight = false, label, name, onChange, options }) {
5014
+ function MultiCheckbox({ defaultValue = [],
5015
+ // eslint-disable-next-line @typescript-eslint/naming-convention
5016
+ disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, label, name, onChange, options }) {
4990
5017
  const checkedOptionValues = useRef(defaultValue);
5018
+ const controlledError = useMemo(() => normalizeString(error), [error]);
5019
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
4991
5020
  const key = useMemo(() => `${name}-${JSON.stringify(defaultValue)}`, [defaultValue, name]);
4992
5021
  const handleChange = useCallback((nextOptionValue, isChecked) => {
4993
5022
  const nextCheckedOptionValues = isChecked
@@ -4999,9 +5028,10 @@ function MultiCheckbox({ defaultValue = [], isInline = false, isLabelHidden = fa
4999
5028
  onChange(normalizedNextValue);
5000
5029
  }
5001
5030
  }, [onChange]);
5002
- return (jsx(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: jsx(ChecboxesBox$1, { "$isInline": isInline, children: options.map((option, index) => (jsx(Checkbox
5003
- // eslint-disable-next-line react/no-array-index-key
5004
- , { defaultChecked: defaultValue.includes(option.value), label: option.label, name: `${name}${index}`, onChange: (isChecked) => handleChange(option.value, isChecked) }, `${name}-${index}`))) }) }, key));
5031
+ useFieldUndefineEffect(disabled, onChange);
5032
+ return (jsxs(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(ChecboxesBox$1, { "$isInline": isInline, children: options.map((option, index) => (jsx(Checkbox
5033
+ // eslint-disable-next-line react/no-array-index-key
5034
+ , { defaultChecked: defaultValue.includes(option.value), disabled: disabled, label: option.label, name: `${name}${index}`, onChange: (isChecked) => handleChange(option.value, isChecked) }, `${name}-${index}`))) }), hasError && jsx(FieldError, { children: controlledError })] }, key));
5005
5035
  }
5006
5036
  const ChecboxesBox$1 = styled.div `
5007
5037
  color: ${p => p.theme.color.gunMetal};
@@ -5056,7 +5086,8 @@ searchable = false, ...originalProps }) {
5056
5086
  setIsOpen(!isOpen);
5057
5087
  }
5058
5088
  }, [isOpen]);
5059
- useClickOutside(boxRef, close, baseContainer);
5089
+ useFieldUndefineEffect(originalProps.disabled, onChange);
5090
+ useClickOutsideEffect(boxRef, close, baseContainer);
5060
5091
  useEffect(() => {
5061
5092
  forceUpdate();
5062
5093
  }, [forceUpdate]);
@@ -5140,8 +5171,12 @@ const Box$1 = styled.div `
5140
5171
  }
5141
5172
  `;
5142
5173
 
5143
- function MultiRadio({ defaultValue, isInline = false, isLabelHidden = false, isLight = false, label, name, onChange, options }) {
5174
+ function MultiRadio({ defaultValue,
5175
+ // eslint-disable-next-line @typescript-eslint/naming-convention
5176
+ disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, label, name, onChange, options }) {
5144
5177
  const [checkedOptionValue, setCheckedOptionValue] = useState(undefined);
5178
+ const controlledError = useMemo(() => normalizeString(error), [error]);
5179
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5145
5180
  const key = useMemo(() => `${name}-${String(checkedOptionValue)}}`, [checkedOptionValue, name]);
5146
5181
  const handleChange = useCallback((nextOptionValue, isChecked) => {
5147
5182
  const nextCheckedOptionValue = isChecked ? nextOptionValue : undefined;
@@ -5150,6 +5185,7 @@ function MultiRadio({ defaultValue, isInline = false, isLabelHidden = false, isL
5150
5185
  onChange(nextCheckedOptionValue);
5151
5186
  }
5152
5187
  }, [onChange]);
5188
+ useFieldUndefineEffect(disabled, onChange);
5153
5189
  // TODO There may be a better solution.
5154
5190
  // A key change is not enough to force radio checked check changes
5155
5191
  // on `defaultValue` property update (even when appending `defaultValue` to `key`),
@@ -5157,9 +5193,9 @@ function MultiRadio({ defaultValue, isInline = false, isLabelHidden = false, isL
5157
5193
  useEffect(() => {
5158
5194
  setCheckedOptionValue(defaultValue);
5159
5195
  }, [defaultValue]);
5160
- return (jsx(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: jsx(ChecboxesBox, { "$isInline": isInline, children: options.map((option, index) => (jsx(Radio
5161
- // eslint-disable-next-line react/no-array-index-key
5162
- , { defaultChecked: option.value === checkedOptionValue, name: name, onChange: (_, isChecked) => handleChange(option.value, isChecked), children: option.label }, `${name}-${index}`))) }) }, key));
5196
+ return (jsxs(Fieldset, { isHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(ChecboxesBox, { "$isInline": isInline, children: options.map((option, index) => (jsx(Radio
5197
+ // eslint-disable-next-line react/no-array-index-key
5198
+ , { 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));
5163
5199
  }
5164
5200
  const ChecboxesBox = styled.div `
5165
5201
  color: ${p => p.theme.color.gunMetal};
@@ -5194,9 +5230,11 @@ const ChecboxesBox = styled.div `
5194
5230
  `}
5195
5231
  `;
5196
5232
 
5197
- function MultiZoneEditor({ addButtonLabel, defaultValue = [], initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onDelete, onEdit }) {
5233
+ function MultiZoneEditor({ addButtonLabel, defaultValue = [], error, initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onDelete, onEdit }) {
5198
5234
  const prevDefaultValueRef = useRef(defaultValue);
5199
5235
  const [zones, setZones] = useState(defaultValue);
5236
+ const controlledError = useMemo(() => normalizeString(error), [error]);
5237
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5200
5238
  const addZone = useCallback(() => {
5201
5239
  const nextZones = [...zones, initialZone];
5202
5240
  if (onAdd) {
@@ -5229,7 +5267,7 @@ function MultiZoneEditor({ addButtonLabel, defaultValue = [], initialZone, isLab
5229
5267
  }, [defaultValue]);
5230
5268
  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) => (
5231
5269
  // eslint-disable-next-line react/no-array-index-key
5232
- 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}`))) })] }));
5270
+ 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 })] }));
5233
5271
  }
5234
5272
  const Row = styled.div `
5235
5273
  align-items: center;
@@ -5260,7 +5298,9 @@ const Link = styled.a `
5260
5298
  }
5261
5299
  `;
5262
5300
 
5263
- function NumberInput({ isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5301
+ function NumberInput({ error, isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5302
+ const controlledError = useMemo(() => normalizeString(error), [error]);
5303
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5264
5304
  const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5265
5305
  const handleChange = useCallback((nextValue) => {
5266
5306
  if (!onChange) {
@@ -5271,7 +5311,8 @@ function NumberInput({ isLabelHidden = false, isLight = false, label, onChange,
5271
5311
  const normalizedNextValue = !Number.isNaN(nextValueAsNumber) ? nextValueAsNumber : undefined;
5272
5312
  onChange(normalizedNextValue);
5273
5313
  }, [onChange]);
5274
- 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)] }));
5314
+ useFieldUndefineEffect(originalProps.disabled, onChange);
5315
+ 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 })] }));
5275
5316
  }
5276
5317
  const StyledInput$2 = styled(Input) `
5277
5318
  background-color: ${p => (p.$isLight ? p.theme.color.white : p.theme.color.gainsboro)};
@@ -5314,7 +5355,8 @@ searchable = false, ...originalProps }) {
5314
5355
  setIsOpen(!isOpen);
5315
5356
  }
5316
5357
  }, [isOpen]);
5317
- useClickOutside(boxRef, close, baseContainer);
5358
+ useFieldUndefineEffect(originalProps.disabled, onChange);
5359
+ useClickOutsideEffect(boxRef, close, baseContainer);
5318
5360
  useEffect(() => {
5319
5361
  forceUpdate();
5320
5362
  }, [forceUpdate]);
@@ -5368,8 +5410,10 @@ const Box = styled.div `
5368
5410
  }
5369
5411
  `;
5370
5412
 
5371
- function Textarea({ isLabelHidden = false, isLight = false, label, onChange, rows = 3, ...originalProps }) {
5413
+ function Textarea({ error, isLabelHidden = false, isLight = false, label, onChange, rows = 3, ...originalProps }) {
5372
5414
  const inputRef = useRef();
5415
+ const controlledError = useMemo(() => normalizeString(error), [error]);
5416
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5373
5417
  const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5374
5418
  const handleChange = useCallback(() => {
5375
5419
  if (!onChange) {
@@ -5379,7 +5423,8 @@ function Textarea({ isLabelHidden = false, isLight = false, label, onChange, row
5379
5423
  const normalizedNextValue = nextValue.length ? nextValue : undefined;
5380
5424
  onChange(normalizedNextValue);
5381
5425
  }, [onChange]);
5382
- 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)] }));
5426
+ useFieldUndefineEffect(originalProps.disabled, onChange);
5427
+ 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 })] }));
5383
5428
  }
5384
5429
  const StyledInput$1 = styled(Input) `
5385
5430
  background-color: ${p => (p.$isLight ? p.theme.color.white : p.theme.color.gainsboro)};
@@ -5393,7 +5438,9 @@ const StyledInput$1 = styled(Input) `
5393
5438
  }
5394
5439
  `;
5395
5440
 
5396
- function TextInput({ isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5441
+ function TextInput({ error, isLabelHidden = false, isLight = false, label, onChange, ...originalProps }) {
5442
+ const controlledError = useMemo(() => normalizeString(error), [error]);
5443
+ const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
5397
5444
  const key = useMemo(() => `${originalProps.name}-${JSON.stringify(originalProps.defaultValue)}`, [originalProps.defaultValue, originalProps.name]);
5398
5445
  const handleChange = useCallback((nextValue) => {
5399
5446
  if (!onChange) {
@@ -5402,7 +5449,8 @@ function TextInput({ isLabelHidden = false, isLight = false, label, onChange, ..
5402
5449
  const normalizedNextValue = nextValue && nextValue.trim().length ? nextValue : undefined;
5403
5450
  onChange(normalizedNextValue);
5404
5451
  }, [onChange]);
5405
- 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)] }));
5452
+ useFieldUndefineEffect(originalProps.disabled, onChange);
5453
+ 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 })] }));
5406
5454
  }
5407
5455
  const StyledInput = styled(Input) `
5408
5456
  background-color: ${p => (p.$isLight ? p.theme.color.white : p.theme.color.gainsboro)};
@@ -5416,56 +5464,48 @@ const StyledInput = styled(Input) `
5416
5464
  `;
5417
5465
 
5418
5466
  function FormikAutoComplete({ name, ...originalProps }) {
5419
- const [field, , helpers] = useField(name);
5420
- // eslint-disable-next-line react-hooks/exhaustive-deps, @typescript-eslint/naming-convention
5467
+ const [field, meta, helpers] = useField(name);
5468
+ // eslint-disable-next-line react-hooks/exhaustive-deps
5421
5469
  const defaultValue = useMemo(() => field.value, []);
5422
- useEffect(() => () => {
5423
- helpers.setValue(undefined);
5424
- },
5470
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5425
5471
  // eslint-disable-next-line react-hooks/exhaustive-deps
5426
- []);
5472
+ const handleChange = useMemo(() => helpers.setValue, []);
5427
5473
  if (!defaultValue) {
5428
5474
  return jsx(AutoComplete, { name: name, onChange: helpers.setValue, ...originalProps });
5429
5475
  }
5430
- return jsx(AutoComplete, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5476
+ return (jsx(AutoComplete, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps }));
5431
5477
  }
5432
5478
 
5433
5479
  function FormikCheckbox({ name, ...originalProps }) {
5434
- const [field, , helpers] = useField(name);
5435
- // eslint-disable-next-line react-hooks/exhaustive-deps, @typescript-eslint/naming-convention
5436
- const defaultChecked = useMemo(() => Boolean(field.value), []);
5437
- useEffect(() => () => {
5438
- helpers.setValue(undefined);
5439
- },
5480
+ const [field, meta, helpers] = useField(name);
5481
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5482
+ // eslint-disable-next-line react-hooks/exhaustive-deps
5483
+ const handleChange = useMemo(() => helpers.setValue, []);
5440
5484
  // eslint-disable-next-line react-hooks/exhaustive-deps
5441
- []);
5442
- return jsx(Checkbox, { defaultChecked: defaultChecked, name: name, onChange: helpers.setValue, ...originalProps });
5485
+ const isDefaultChecked = useMemo(() => Boolean(field.value), []);
5486
+ return (jsx(Checkbox, { defaultChecked: isDefaultChecked, error: error, name: name, onChange: handleChange, ...originalProps }));
5443
5487
  }
5444
5488
 
5445
5489
  const UntypedDatePicker = DatePicker;
5446
5490
  function FormikDatePicker({ name, ...originalProps }) {
5447
- const [field, , helpers] = useField(name);
5491
+ const [field, meta, helpers] = useField(name);
5448
5492
  // eslint-disable-next-line react-hooks/exhaustive-deps
5449
5493
  const defaultValue = useMemo(() => field.value, []);
5450
- useEffect(() => () => {
5451
- helpers.setValue(undefined);
5452
- },
5494
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5453
5495
  // eslint-disable-next-line react-hooks/exhaustive-deps
5454
- []);
5455
- return jsx(UntypedDatePicker, { defaultValue: defaultValue, onChange: helpers.setValue, ...originalProps });
5496
+ const handleChange = useMemo(() => helpers.setValue, []);
5497
+ return jsx(UntypedDatePicker, { defaultValue: defaultValue, error: error, onChange: handleChange, ...originalProps });
5456
5498
  }
5457
5499
 
5458
5500
  const UntypedDateRangePicker = DateRangePicker;
5459
5501
  function FormikDateRangePicker({ name, ...originalProps }) {
5460
- const [field, , helpers] = useField(name);
5502
+ const [field, meta, helpers] = useField(name);
5461
5503
  // eslint-disable-next-line react-hooks/exhaustive-deps
5462
5504
  const defaultValue = useMemo(() => field.value, []);
5463
- useEffect(() => () => {
5464
- helpers.setValue(undefined);
5465
- },
5505
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5466
5506
  // eslint-disable-next-line react-hooks/exhaustive-deps
5467
- []);
5468
- return jsx(UntypedDateRangePicker, { defaultValue: defaultValue, onChange: helpers.setValue, ...originalProps });
5507
+ const handleChange = useMemo(() => helpers.setValue, []);
5508
+ return jsx(UntypedDateRangePicker, { defaultValue: defaultValue, error: error, onChange: handleChange, ...originalProps });
5469
5509
  }
5470
5510
 
5471
5511
  function FormikEffect({ onChange }) {
@@ -5477,51 +5517,43 @@ function FormikEffect({ onChange }) {
5477
5517
  }
5478
5518
 
5479
5519
  function FormikMultiCheckbox({ name, ...originalProps }) {
5480
- const [field, , helpers] = useField(name);
5520
+ const [field, meta, helpers] = useField(name);
5481
5521
  // eslint-disable-next-line react-hooks/exhaustive-deps
5482
5522
  const defaultValue = useMemo(() => field.value, []);
5483
- useEffect(() => () => {
5484
- helpers.setValue(undefined);
5485
- },
5523
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5486
5524
  // eslint-disable-next-line react-hooks/exhaustive-deps
5487
- []);
5488
- return jsx(MultiCheckbox, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5525
+ const handleChange = useMemo(() => helpers.setValue, []);
5526
+ return (jsx(MultiCheckbox, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps }));
5489
5527
  }
5490
5528
 
5491
5529
  function FormikMultiSelect({ name, ...originalProps }) {
5492
- const [field, , helpers] = useField(name);
5530
+ const [field, meta, helpers] = useField(name);
5493
5531
  // eslint-disable-next-line react-hooks/exhaustive-deps
5494
5532
  const defaultValue = useMemo(() => field.value, []);
5495
- useEffect(() => () => {
5496
- helpers.setValue(undefined);
5497
- },
5533
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5498
5534
  // eslint-disable-next-line react-hooks/exhaustive-deps
5499
- []);
5500
- return jsx(MultiSelect, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5535
+ const handleChange = useMemo(() => helpers.setValue, []);
5536
+ return (jsx(MultiSelect, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps }));
5501
5537
  }
5502
5538
 
5503
5539
  function FormikMultiRadio({ name, ...originalProps }) {
5504
- const [field, , helpers] = useField(name);
5540
+ const [field, meta, helpers] = useField(name);
5505
5541
  // eslint-disable-next-line react-hooks/exhaustive-deps
5506
5542
  const defaultValue = useMemo(() => field.value, []);
5507
- useEffect(() => () => {
5508
- helpers.setValue(undefined);
5509
- },
5543
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5510
5544
  // eslint-disable-next-line react-hooks/exhaustive-deps
5511
- []);
5512
- return jsx(MultiRadio, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5545
+ const handleChange = useMemo(() => helpers.setValue, []);
5546
+ return jsx(MultiRadio, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps });
5513
5547
  }
5514
5548
 
5515
5549
  function FormikNumberInput({ name, ...originalProps }) {
5516
- const [field, , helpers] = useField(name);
5550
+ const [field, meta, helpers] = useField(name);
5517
5551
  // eslint-disable-next-line react-hooks/exhaustive-deps
5518
5552
  const defaultValue = useMemo(() => field.value, []);
5519
- useEffect(() => () => {
5520
- helpers.setValue(undefined);
5521
- },
5553
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5522
5554
  // eslint-disable-next-line react-hooks/exhaustive-deps
5523
- []);
5524
- return jsx(NumberInput, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5555
+ const handleChange = useMemo(() => helpers.setValue, []);
5556
+ return (jsx(NumberInput, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps }));
5525
5557
  }
5526
5558
 
5527
5559
  function FormikSelect({ name, ...originalProps }) {
@@ -5529,39 +5561,32 @@ function FormikSelect({ name, ...originalProps }) {
5529
5561
  // eslint-disable-next-line react-hooks/exhaustive-deps
5530
5562
  const defaultValue = useMemo(() => field.value, []);
5531
5563
  const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5532
- useEffect(() => () => {
5533
- helpers.setValue(undefined);
5534
- },
5535
5564
  // eslint-disable-next-line react-hooks/exhaustive-deps
5536
- []);
5537
- return jsx(Select, { defaultValue: defaultValue, error: error, name: name, onChange: helpers.setValue, ...originalProps });
5565
+ const handleChange = useMemo(() => helpers.setValue, []);
5566
+ return jsx(Select, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps });
5538
5567
  }
5539
5568
 
5540
5569
  function FormikTextarea({ name, ...originalProps }) {
5541
- const [field, , helpers] = useField(name);
5570
+ const [field, meta, helpers] = useField(name);
5542
5571
  // eslint-disable-next-line react-hooks/exhaustive-deps
5543
5572
  const defaultValue = useMemo(() => field.value, []);
5544
- useEffect(() => () => {
5545
- helpers.setValue(undefined);
5546
- },
5573
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5547
5574
  // eslint-disable-next-line react-hooks/exhaustive-deps
5548
- []);
5549
- return jsx(Textarea, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5575
+ const handleChange = useMemo(() => helpers.setValue, []);
5576
+ return jsx(Textarea, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps });
5550
5577
  }
5551
5578
 
5552
5579
  function FormikTextInput({ name, ...originalProps }) {
5553
- const [field, , helpers] = useField(name);
5580
+ const [field, meta, helpers] = useField(name);
5554
5581
  // eslint-disable-next-line react-hooks/exhaustive-deps
5555
5582
  const defaultValue = useMemo(() => field.value, []);
5556
- useEffect(() => () => {
5557
- helpers.setValue(undefined);
5558
- },
5583
+ const error = useMemo(() => (meta.initialTouched ? meta.error : undefined), [meta.error, meta.initialTouched]);
5559
5584
  // eslint-disable-next-line react-hooks/exhaustive-deps
5560
- []);
5561
- return jsx(TextInput, { defaultValue: defaultValue, name: name, onChange: helpers.setValue, ...originalProps });
5585
+ const handleChange = useMemo(() => helpers.setValue, []);
5586
+ return jsx(TextInput, { defaultValue: defaultValue, error: error, name: name, onChange: handleChange, ...originalProps });
5562
5587
  }
5563
5588
 
5564
5589
  const noop = () => { };
5565
5590
 
5566
- export { Accent, AutoComplete, Button, Checkbox, DatePicker, DateRangePicker, Dropdown, Field$2 as Field, Fieldset, FormikAutoComplete, FormikCheckbox, FormikDatePicker, FormikDateRangePicker, FormikEffect, FormikMultiCheckbox, FormikMultiRadio, FormikMultiSelect, FormikNumberInput, FormikSelect, FormikTextInput, FormikTextarea, GlobalStyle, index as Icon, IconButton, Label, Legend, MultiCheckbox, MultiRadio, MultiSelect, MultiZoneEditor, NumberInput, OnlyFontGlobalStyle, Select, Size, THEME, Tag$1 as Tag, TagGroup, TextInput, Textarea, ThemeProvider, dayjs, getLocalizedDayjs, getUtcizedDayjs, noop, stopMouseEventPropagation, useClickOutside, useForceUpdate };
5591
+ export { Accent, AutoComplete, Button, Checkbox, DatePicker, DateRangePicker, Dropdown, Field$2 as Field, Fieldset, FormikAutoComplete, FormikCheckbox, FormikDatePicker, FormikDateRangePicker, FormikEffect, FormikMultiCheckbox, FormikMultiRadio, FormikMultiSelect, FormikNumberInput, FormikSelect, FormikTextInput, FormikTextarea, GlobalStyle, index as Icon, IconButton, Label, Legend, MultiCheckbox, MultiRadio, MultiSelect, MultiZoneEditor, NumberInput, OnlyFontGlobalStyle, Select, Size, THEME, Tag$1 as Tag, TagGroup, TextInput, Textarea, ThemeProvider, dayjs, getLocalizedDayjs, getUtcizedDayjs, noop, stopMouseEventPropagation, useClickOutsideEffect, useForceUpdate };
5567
5592
  //# sourceMappingURL=index.js.map