@mtes-mct/monitor-ui 4.0.7 → 5.0.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/index.js CHANGED
@@ -3475,7 +3475,7 @@ const useClickOutsideEffect = (zoneRefOrzoneRefs, action, baseContainer) => {
3475
3475
  const handleClickOutside = useCallback((event) => {
3476
3476
  const eventTarget = event.target;
3477
3477
  const zoneRefs = Array.isArray(zoneRefOrzoneRefs) ? zoneRefOrzoneRefs : [zoneRefOrzoneRefs];
3478
- const isEventTargetInZones = pipe(map((zoneRef) => zoneRef.current.contains(eventTarget)), any(identity))(zoneRefs);
3478
+ const isEventTargetInZones = pipe(map((zoneRef) => zoneRef.current && eventTarget ? zoneRef.current.contains(eventTarget) : false), any(identity))(zoneRefs);
3479
3479
  if (isEventTargetInZones) {
3480
3480
  return;
3481
3481
  }
@@ -20959,7 +20959,7 @@ function requireDayjs_min () {
20959
20959
  }
20960
20960
 
20961
20961
  var dayjs_minExports = requireDayjs_min();
20962
- var dayjs = /*@__PURE__*/getDefaultExportFromCjs(dayjs_minExports);
20962
+ var customDayjs = /*@__PURE__*/getDefaultExportFromCjs(dayjs_minExports);
20963
20963
 
20964
20964
  var timezoneExports = {};
20965
20965
  var timezone$1 = {
@@ -20995,28 +20995,65 @@ var fr = {
20995
20995
  !function(e,n){module.exports=n(requireDayjs_min());}(commonjsGlobal,(function(e){function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=n(e),i={name:"fr",weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekStart:1,yearStart:4,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinal:function(e){return ""+e+(1===e?"er":"")}};return t.default.locale(i,null,!0),i}));
20996
20996
  } (fr));
20997
20997
 
20998
- dayjs.extend(timezone);
20999
- dayjs.extend(utc);
21000
- dayjs.locale('fr');
21001
- dayjs.tz.setDefault('UTC');
20998
+ customDayjs.extend(timezone);
20999
+ customDayjs.extend(utc);
21000
+ customDayjs.locale('fr');
21002
21001
 
21003
- function getUtcDayjs() {
21004
- return dayjs().utc();
21002
+ /**
21003
+ * Get a Dayjs instance of a UTC date treated as if it was a locally timezoned one.
21004
+ *
21005
+ * @example
21006
+ * When run in Europe/Paris time zone while DST is not in application:
21007
+ * ```ts
21008
+ * getLocalizedDayjs(2022-01-02T03:04:05.006Z)`
21009
+ * // => `2022-01-02T03:04:05.006+01:00`
21010
+ * ```
21011
+ *
21012
+ * When run in Europe/Paris time zone while DST is in application:
21013
+ * ```ts
21014
+ * getLocalizedDayjs(2022-01-02T03:04:05.006Z)`
21015
+ * // => `2022-01-02T03:04:05.006+02:00`
21016
+ * ```
21017
+ *
21018
+ * When run in UTC time zone (there is no DST in UTC):
21019
+ * ```ts
21020
+ * getLocalizedDayjs(2022-01-02T03:04:05.006Z)`
21021
+ * // => `2022-01-02T03:04:05.006Z`
21022
+ * ```
21023
+ */
21024
+ function getLocalizedDayjs(utcDate) {
21025
+ const controlledUtcDate = typeof utcDate === 'string' ? new Date(utcDate) : utcDate;
21026
+ // The number of minutes returned by getTimezoneOffset() is positive if the local time zone is behind UTC,
21027
+ // and negative if the local time zone is ahead of UTC. For example, for UTC+10, `-600` will be returned.
21028
+ //
21029
+ // `Date.getTimezoneOffset()` includes the DST if it is in application during the period of the provided `utcDate`
21030
+ // (i.e.: if the date is in winter and we're running locally in Europe/Paris time zone, `-120` will be returned;
21031
+ // but if the date was in summer and we're running locally in Europe/Paris time zone, `-60` will be returned).
21032
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset#varied_results_in_daylight_saving_time_dst_regions
21033
+ const timezoneOffsetInMinutes = controlledUtcDate.getTimezoneOffset();
21034
+ return customDayjs(utcDate).add(timezoneOffsetInMinutes, 'minutes');
21005
21035
  }
21006
21036
 
21007
- // TODO Use `date-fns` instead of `dayjs`.
21008
21037
  /**
21009
- * Get a Dayjs instance of a locally timezoned date treated as if it was a UTC one
21038
+ * Get a Dayjs instance of a locally timezoned date treated as if it was a UTC one.
21010
21039
  *
21011
21040
  * @example
21012
- * `2022-01-02T03:04:05.006+01:00` => `2022-01-02T03:04:05.006Z`.
21041
+ * ```ts
21042
+ * getUtcizedDayjs(2022-01-02T03:04:05.006+01:00)
21043
+ * // => `2022-01-02T03:04:05.006Z
21044
+ * ```
21013
21045
  */
21014
21046
  function getUtcizedDayjs(localDate) {
21015
21047
  const definedLocalDate = localDate || new Date();
21016
21048
  // The number of minutes returned by getTimezoneOffset() is positive if the local time zone is behind UTC,
21017
- // and negative if the local time zone is ahead of UTC. For example, for UTC+10, -600 will be returned.
21049
+ // and negative if the local time zone is ahead of UTC. For example, for UTC+10, `-600` will be returned.
21050
+ //
21051
+ // `Date.getTimezoneOffset()` includes the DST if it is in application during the period of the provided `utcDate`
21052
+ // (i.e.: if the date is in winter and we're running locally in Europe/Paris time zone, `-120` will be returned;
21053
+ // but if the date was in summer and we're running locally in Europe/Paris time zone, `-60` will be returned).
21054
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset#varied_results_in_daylight_saving_time_dst_regions
21018
21055
  const timezoneOffsetInMinutes = definedLocalDate.getTimezoneOffset();
21019
- return dayjs(definedLocalDate).subtract(timezoneOffsetInMinutes, 'minutes');
21056
+ return customDayjs(definedLocalDate).utc().subtract(timezoneOffsetInMinutes, 'minutes');
21020
21057
  }
21021
21058
 
21022
21059
  new Array(24).fill(undefined).map((_, index) => ({
@@ -21047,14 +21084,56 @@ var STATUS;
21047
21084
  STATUS["START_DATE"] = "START_DATE";
21048
21085
  })(STATUS || (STATUS = {}));
21049
21086
 
21050
- // TODO Use `date-fns` instead of `dayjs`.
21051
21087
  function formatNumberAsDoubleDigit(numberLike) {
21052
21088
  return String(numberLike).padStart(2, '0');
21053
21089
  }
21054
- function getDateFromDateAndTimeTuple(dateTuple, timeTuple, isEnd = false) {
21090
+ /**
21091
+ * @description
21092
+ * This function will treat any date & time tuple in UTC, whichever the current time zone is.
21093
+ *
21094
+ * @example
21095
+ * ```ts
21096
+ * console.log(getDateFromDateAndTimeTuple(['2021', '31', '12'], ['00', '00']).toISOString())
21097
+ * // => "2021-12-31T00:00:00.000Z"
21098
+ * console.log(getDateFromDateAndTimeTuple(['2021', '31', '12'], ['23', '59'], true).toISOString())
21099
+ * // => "2021-12-31T23:59:59.000Z"
21100
+ * ```
21101
+ */
21102
+ function getDayjsFromUtcDateAndTimeTuple(utcDateTuple, utcTimeTuple, isEnd = false) {
21103
+ const [year, month, day] = utcDateTuple;
21104
+ const [hour, minute] = utcTimeTuple;
21105
+ const rawDateAsDayjs = customDayjs()
21106
+ .utc()
21107
+ .year(Number(year))
21108
+ .month(Number(month) - 1)
21109
+ .date(Number(day))
21110
+ .hour(Number(hour))
21111
+ .minute(Number(minute));
21112
+ return isEnd
21113
+ ? rawDateAsDayjs
21114
+ .endOf('minute')
21115
+ // TODO For some reason the API can't handle miliseconds in dates.
21116
+ // That's why we set it to 0 (instead of 999)
21117
+ .millisecond(0)
21118
+ : rawDateAsDayjs.startOf('minute');
21119
+ }
21120
+ /**
21121
+ * @description
21122
+ * This function will treat any date & time tuple in UTC, whichever the current time zone is.
21123
+ *
21124
+ * @example
21125
+ * ```ts
21126
+ * console.log(getDateFromDateAndTimeTuple(['2021', '31', '12'], ['00', '00']).toISOString())
21127
+ * // => "2021-12-31T00:00:00.000Z"
21128
+ * console.log(getDateFromDateAndTimeTuple(['2021', '31', '12'], ['23', '59'], true).toISOString())
21129
+ * // => "2021-12-31T23:59:59.000Z"
21130
+ * ```
21131
+ */
21132
+ function getUtcDateFromDateAndTimeTuple(dateTuple, timeTuple, isEnd = false) {
21055
21133
  const [year, month, day] = dateTuple;
21056
21134
  const [hour, minute] = timeTuple;
21057
- const rawDateAsDayjs = dayjs()
21135
+ const rawDateAsDayjs = customDayjs()
21136
+ .utc()
21058
21137
  .year(Number(year))
21059
21138
  .month(Number(month) - 1)
21060
21139
  .date(Number(day))
@@ -21069,14 +21148,14 @@ function getDateFromDateAndTimeTuple(dateTuple, timeTuple, isEnd = false) {
21069
21148
  .toDate()
21070
21149
  : rawDateAsDayjs.startOf('minute').toDate();
21071
21150
  }
21072
- function getDateTupleFromDate(date) {
21073
- if (!date) {
21151
+ function getDateTupleFromUtcDate(utcDate) {
21152
+ if (!utcDate) {
21074
21153
  return undefined;
21075
21154
  }
21076
21155
  return [
21077
- String(date.getFullYear()),
21078
- formatNumberAsDoubleDigit(date.getMonth() + 1),
21079
- formatNumberAsDoubleDigit(date.getDate())
21156
+ String(utcDate.getFullYear()),
21157
+ formatNumberAsDoubleDigit(utcDate.getMonth() + 1),
21158
+ formatNumberAsDoubleDigit(utcDate.getDate())
21080
21159
  ];
21081
21160
  }
21082
21161
  /**
@@ -21108,11 +21187,23 @@ const getRangedTimeOptions = (minutesRange) => {
21108
21187
  };
21109
21188
  });
21110
21189
  };
21111
- function getTimeTupleFromDate(date) {
21112
- if (!date) {
21190
+ function getTimeTupleFromUtcDate(utcDate) {
21191
+ if (!utcDate) {
21113
21192
  return undefined;
21114
21193
  }
21115
- return [formatNumberAsDoubleDigit(date.getHours()), formatNumberAsDoubleDigit(date.getMinutes())];
21194
+ return [formatNumberAsDoubleDigit(utcDate.getHours()), formatNumberAsDoubleDigit(utcDate.getMinutes())];
21195
+ }
21196
+ function getUtcDateTupleFromDayjs(dateAsDayjs) {
21197
+ if (!dateAsDayjs) {
21198
+ return undefined;
21199
+ }
21200
+ return [dateAsDayjs.utc().format('YYYY'), dateAsDayjs.utc().format('MM'), dateAsDayjs.utc().format('DD')];
21201
+ }
21202
+ function getUtcTimeTupleFromDayjs(dateAsDayjs) {
21203
+ if (!dateAsDayjs) {
21204
+ return undefined;
21205
+ }
21206
+ return [dateAsDayjs.utc().format('HH'), dateAsDayjs.utc().format('mm')];
21116
21207
  }
21117
21208
  // The type is not accurate here but it's good enough to use the protoypes we need for the feature
21118
21209
  // (they would work with any HTML element).
@@ -21123,25 +21214,26 @@ function isHtmlElement(element) {
21123
21214
  return Boolean(element.tagName);
21124
21215
  }
21125
21216
 
21126
- function CalendarPicker({ defaultValue, isHistorical, isOpen, onChange }) {
21217
+ function CalendarPicker({ isHistorical, isOpen, onChange, value }) {
21127
21218
  const boxRef = useRef();
21128
21219
  const { forceUpdate } = useForceUpdate();
21129
- const utcTodayAsDayjs = useMemo(() => getUtcDayjs().endOf('day'), []);
21220
+ const utcTodayAsDayjs = useMemo(() => customDayjs().utc().endOf('day'), []);
21221
+ const controlledValue = useMemo(() => (value ? getLocalizedDayjs(value).toDate() : undefined), [value]);
21130
21222
  const disabledDate = useMemo(() => (date) => date && isHistorical ? getUtcizedDayjs(date).isAfter(utcTodayAsDayjs) : false, [isHistorical, utcTodayAsDayjs]);
21131
- const handleSelect = useCallback((nextDate) => {
21132
- const nextDateTuple = getDateTupleFromDate(nextDate);
21133
- onChange(nextDateTuple);
21223
+ const handleSelect = useCallback((nextLocalDate) => {
21224
+ // We utcize the date picked by the user
21225
+ const nextUtcDateAsDayjs = getUtcizedDayjs(nextLocalDate);
21226
+ const nextUtcDateTuple = getUtcDateTupleFromDayjs(nextUtcDateAsDayjs);
21227
+ onChange(nextUtcDateTuple);
21134
21228
  }, [onChange]);
21135
21229
  useEffect(() => {
21136
21230
  // We wait for the <Box /> to render so that `boxRef` is defined
21137
21231
  // and can be used as a container for <RsuiteDatePicker />
21138
21232
  forceUpdate();
21139
21233
  }, [forceUpdate]);
21140
- return (jsx(Box$b, { ref: boxRef, onClick: stopMouseEventPropagation, children: boxRef.current && (jsx(DatePicker$1, { container: boxRef.current, disabledDate: disabledDate, format: "yyyy-MM-dd", locale: RSUITE_CALENDAR_LOCALE, oneTap: true, onSelect: handleSelect, open: isOpen,
21141
- // `defaultValue` seems to be immediatly cancelled so we come down to using a controlled `value`
21142
- ranges: [],
21234
+ return (jsx(Box$b, { ref: boxRef, onClick: stopMouseEventPropagation, children: boxRef.current && (jsx(DatePicker$1, { container: boxRef.current, disabledDate: disabledDate, format: "yyyy-MM-dd", locale: RSUITE_CALENDAR_LOCALE, oneTap: true, onSelect: handleSelect, open: isOpen, ranges: [],
21143
21235
  // eslint-disable-next-line no-null/no-null
21144
- value: defaultValue ?? null })) }));
21236
+ value: controlledValue ?? null })) }));
21145
21237
  }
21146
21238
  const Box$b = styled.div `
21147
21239
  height: 0;
@@ -21298,22 +21390,9 @@ const Box$b = styled.div `
21298
21390
  }
21299
21391
  `;
21300
21392
 
21301
- // TODO Use `date-fns` instead of `dayjs`.
21302
- /**
21303
- * Get a Dayjs instance of a UTC date treated as if it was a locally timezoned one
21304
- *
21305
- * @example
21306
- * `2022-01-02T03:04:05.006Z` => `2022-01-02T03:04:05.006+01:00` (or `+02:00` during DST) in Europe/Paris timezone.
21307
- */
21308
- function getLocalizedDayjs(utcDate) {
21309
- // The number of minutes returned by getTimezoneOffset() is positive if the local time zone is behind UTC,
21310
- // and negative if the local time zone is ahead of UTC. For example, for UTC+10, -600 will be returned.
21311
- const timezoneOffsetInMinutes = new Date().getTimezoneOffset();
21312
- return dayjs(utcDate).add(timezoneOffsetInMinutes, 'minutes');
21313
- }
21314
-
21315
21393
  function NumberInputWithRef({ defaultValue, isLight, max, min, onBack, onClick, onFilled, onFocus, onFormatError, onInput, onNext, onPrevious, size, ...nativeProps }, ref) {
21316
- const inputRef = useRef();
21394
+ // eslint-disable-next-line no-null/no-null
21395
+ const inputRef = useRef(null);
21317
21396
  const placeholder = useMemo(() => '-'.repeat(size), [size]);
21318
21397
  useImperativeHandle(ref, () => inputRef.current);
21319
21398
  const handleClick = useCallback((event) => {
@@ -21323,12 +21402,18 @@ function NumberInputWithRef({ defaultValue, isLight, max, min, onBack, onClick,
21323
21402
  }
21324
21403
  }, [onClick]);
21325
21404
  const handleFocus = useCallback((event) => {
21405
+ if (!inputRef.current) {
21406
+ return;
21407
+ }
21326
21408
  inputRef.current.select();
21327
21409
  if (onFocus) {
21328
21410
  onFocus(event);
21329
21411
  }
21330
21412
  }, [onFocus]);
21331
21413
  const handleInput = useCallback(() => {
21414
+ if (!inputRef.current) {
21415
+ return;
21416
+ }
21332
21417
  onFormatError(false);
21333
21418
  const { value } = inputRef.current;
21334
21419
  if (onInput) {
@@ -21347,6 +21432,9 @@ function NumberInputWithRef({ defaultValue, isLight, max, min, onBack, onClick,
21347
21432
  }
21348
21433
  }, [max, min, onFilled, onFormatError, onInput, size]);
21349
21434
  const handleKeyDown = useCallback((event) => {
21435
+ if (!inputRef.current) {
21436
+ return;
21437
+ }
21350
21438
  if (onPrevious &&
21351
21439
  event.key === 'ArrowLeft' &&
21352
21440
  inputRef.current.selectionStart === 0 &&
@@ -21389,26 +21477,33 @@ const StyledNumberInput = styled.input `
21389
21477
  }
21390
21478
  `;
21391
21479
 
21392
- function DateInputWithRef({ baseContainer, defaultValue, disabled = false, isCompact, isEndDate = false, isForcedFocused, isLight, isStartDate = false, onBack, onChange, onClick, onNext, onPrevious }, ref) {
21393
- const boxRef = useRef();
21394
- const dayInputRef = useRef();
21395
- const monthInputRef = useRef();
21396
- const yearInputRef = useRef();
21480
+ function DateInputWithRef({ baseContainer, defaultValue, disabled = false, isCompact, isEndDate = false, isForcedFocused, isLight, isRange = false, isStartDate = false, onBack, onChange, onClick, onInput, onNext, onPrevious }, ref) {
21481
+ /* eslint-disable no-null/no-null */
21482
+ const boxRef = useRef(null);
21483
+ const dayInputRef = useRef(null);
21484
+ const monthInputRef = useRef(null);
21485
+ const yearInputRef = useRef(null);
21486
+ /* eslint-enable no-null/no-null */
21397
21487
  const [hasFormatError, setHasFormatError] = useState(false);
21398
21488
  const [hasValidationError, setHasValidationError] = useState(false);
21399
21489
  const [isFocused, setIsFocused] = useState(false);
21400
21490
  const baseDocument = useMemo(() => (isHtmlElement(baseContainer) ? baseContainer.ownerDocument : window.document), [baseContainer]);
21401
21491
  useImperativeHandle(ref, () => ({
21402
21492
  box: boxRef.current,
21403
- contains: boxRef.current.contains.bind(boxRef.current),
21493
+ contains: boxRef.current ? boxRef.current.contains.bind(boxRef.current) : () => false,
21404
21494
  focus: (isInLastInputOfTheGroup = false) => {
21405
21495
  if (isInLastInputOfTheGroup) {
21406
- yearInputRef.current.focus();
21496
+ yearInputRef.current?.focus();
21407
21497
  }
21408
21498
  else {
21409
- dayInputRef.current.focus();
21499
+ dayInputRef.current?.focus();
21410
21500
  }
21411
- }
21501
+ },
21502
+ getValueAsPartialDateTuple: () => [
21503
+ yearInputRef.current?.value.length ? yearInputRef.current.value : undefined,
21504
+ monthInputRef.current?.value.length ? monthInputRef.current.value : undefined,
21505
+ dayInputRef.current?.value.length ? dayInputRef.current.value : undefined
21506
+ ]
21412
21507
  }));
21413
21508
  const handleBlur = useCallback(() => {
21414
21509
  setIsFocused(false);
@@ -21420,6 +21515,9 @@ function DateInputWithRef({ baseContainer, defaultValue, disabled = false, isCom
21420
21515
  setHasFormatError(hasNextFormatError);
21421
21516
  }, []);
21422
21517
  const submit = useCallback(() => {
21518
+ if (!yearInputRef.current || !monthInputRef.current || !dayInputRef.current) {
21519
+ return;
21520
+ }
21423
21521
  setHasValidationError(false);
21424
21522
  const isFilled = baseDocument.activeElement === yearInputRef.current;
21425
21523
  switch (baseDocument.activeElement) {
@@ -21447,7 +21545,7 @@ function DateInputWithRef({ baseContainer, defaultValue, disabled = false, isCom
21447
21545
  ];
21448
21546
  onChange(nextDateTuple, isFilled);
21449
21547
  }, [baseDocument, onChange]);
21450
- return (jsxs(Box$a, { ref: boxRef, "$hasError": hasFormatError || hasValidationError, "$isCompact": isCompact, "$isDisabled": disabled, "$isFocused": isForcedFocused || isFocused, "$isLight": isLight, children: [jsxs("div", { children: [isStartDate && jsx("span", { children: "Du " }), isEndDate && jsx("span", { children: "Au " }), jsx(NumberInput$1, { ref: dayInputRef, "aria-label": `Jour${isStartDate ? ' de début' : ''}${isEndDate ? ' de fin' : ''}`, defaultValue: defaultValue && formatNumberAsDoubleDigit(defaultValue[2]), disabled: disabled, isLight: isLight, max: 31, min: 1, onBack: onBack, onBlur: handleBlur, onClick: onClick, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onNext: () => monthInputRef.current.focus(), onPrevious: onPrevious, size: 2 }), "/", jsx(NumberInput$1, { ref: monthInputRef, "aria-label": `Mois${isStartDate ? ' de début' : ''}${isEndDate ? ' de fin' : ''}`, defaultValue: defaultValue && formatNumberAsDoubleDigit(defaultValue[1]), disabled: disabled, isLight: isLight, max: 12, min: 1, onBack: () => dayInputRef.current.focus(), onBlur: handleBlur, onClick: onClick, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onNext: () => yearInputRef.current.focus(), onPrevious: () => dayInputRef.current.focus(), size: 2 }), "/", jsx(NumberInput$1, { ref: yearInputRef, "aria-label": `Année${isStartDate ? ' de début' : ''}${isEndDate ? ' de fin' : ''}`, defaultValue: defaultValue && defaultValue[0], disabled: disabled, isLight: isLight, max: 2030, min: 2020, onBack: () => monthInputRef.current.focus(), onBlur: handleBlur, onClick: onClick, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onNext: onNext, onPrevious: () => monthInputRef.current.focus(), size: 4 })] }), !isCompact && jsx(Calendar, {})] }));
21548
+ return (jsxs(Box$a, { ref: boxRef, "$hasError": hasFormatError || hasValidationError, "$isCompact": isCompact, "$isDisabled": disabled, "$isFocused": isForcedFocused || isFocused, "$isLight": isLight, children: [jsxs("div", { children: [isRange && isStartDate && jsx("span", { children: "Du " }), isRange && isEndDate && jsx("span", { children: "Au " }), jsx(NumberInput$1, { ref: dayInputRef, "aria-label": `Jour${isRange && isStartDate ? ' de début' : ''}${isRange && isEndDate ? ' de fin' : ''}`, defaultValue: defaultValue && formatNumberAsDoubleDigit(defaultValue[2]), disabled: disabled, isLight: isLight, max: 31, min: 1, onBack: onBack, onBlur: handleBlur, onClick: onClick, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onInput: onInput, onNext: () => monthInputRef.current?.focus(), onPrevious: onPrevious, size: 2 }), "/", jsx(NumberInput$1, { ref: monthInputRef, "aria-label": `Mois${isRange && isStartDate ? ' de début' : ''}${isRange && isEndDate ? ' de fin' : ''}`, defaultValue: defaultValue && formatNumberAsDoubleDigit(defaultValue[1]), disabled: disabled, isLight: isLight, max: 12, min: 1, onBack: () => dayInputRef.current?.focus(), onBlur: handleBlur, onClick: onClick, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onInput: onInput, onNext: () => yearInputRef.current?.focus(), onPrevious: () => dayInputRef.current?.focus(), size: 2 }), "/", jsx(NumberInput$1, { ref: yearInputRef, "aria-label": `Année${isRange && isStartDate ? ' de début' : ''}${isRange && isEndDate ? ' de fin' : ''}`, defaultValue: defaultValue && defaultValue[0], disabled: disabled, isLight: isLight, max: 2030, min: 2020, onBack: () => monthInputRef.current?.focus(), onBlur: handleBlur, onClick: onClick, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onInput: onInput, onNext: onNext, onPrevious: () => monthInputRef.current?.focus(), size: 4 })] }), !isCompact && jsx(Calendar, {})] }));
21451
21549
  }
21452
21550
  const DateInput = forwardRef(DateInputWithRef);
21453
21551
  const Box$a = styled.div `
@@ -21573,33 +21671,37 @@ const Option = styled.div `
21573
21671
  }
21574
21672
  `;
21575
21673
 
21576
- function TimeInputWithRef({ baseContainer, defaultValue, disabled = false, isCompact, isEndDate = false, isLight, isStartDate = false, minutesRange = 15, onBack, onChange, onFocus, onNext, onPrevious }, ref) {
21577
- const boxRef = useRef();
21578
- const hourInputRef = useRef();
21579
- const minuteInputRef = useRef();
21674
+ function TimeInputWithRef({ baseContainer, defaultValue, disabled = false, isCompact, isEndDate = false, isLight, isStartDate = false, minutesRange = 15, onBack, onChange, onFocus, onInput, onNext, onPrevious }, ref) {
21675
+ /* eslint-disable no-null/no-null */
21676
+ const boxRef = useRef(null);
21677
+ const hourInputRef = useRef(null);
21678
+ const minuteInputRef = useRef(null);
21679
+ /* eslint-enable no-null/no-null */
21580
21680
  const [controlledDefaultValue, setControlledDefaultValue] = useState(defaultValue);
21581
21681
  const [hasFormatError, setHasFormatError] = useState(false);
21582
21682
  const [hasValidationError, setHasValidationError] = useState(false);
21583
21683
  const [isFocused, setIsFocused] = useState(false);
21684
+ const [isTimePickerOpen, setIsTimePickerOpen] = useState(false);
21685
+ const [timePickerFilter, setTimePickerFilter] = useState(/.*/);
21584
21686
  const baseDocument = useMemo(() => (isHtmlElement(baseContainer) ? baseContainer.ownerDocument : window.document), [baseContainer]);
21585
21687
  useImperativeHandle(ref, () => ({
21586
21688
  box: boxRef.current,
21587
21689
  focus: (isInLastInputOfTheGroup = false) => {
21588
21690
  if (isInLastInputOfTheGroup) {
21589
- minuteInputRef.current.focus();
21691
+ minuteInputRef.current?.focus();
21590
21692
  }
21591
21693
  else {
21592
- hourInputRef.current.focus();
21694
+ hourInputRef.current?.focus();
21593
21695
  }
21594
- }
21696
+ },
21697
+ getValueAsPartialTimeTuple: () => [
21698
+ hourInputRef.current?.value.length ? hourInputRef.current.value : undefined,
21699
+ minuteInputRef.current?.value.length ? minuteInputRef.current.value : undefined
21700
+ ]
21595
21701
  }));
21596
- const isRangedTimePickerOpenRef = useRef(false);
21597
- const [rangedTimePickerFilter, setRangedTimePickerFilter] = useState(/.*/);
21598
- const { forceUpdate } = useForceUpdate();
21599
21702
  const closeRangedTimePicker = useCallback(() => {
21600
- isRangedTimePickerOpenRef.current = false;
21601
- forceUpdate();
21602
- }, [forceUpdate]);
21703
+ setIsTimePickerOpen(false);
21704
+ }, []);
21603
21705
  const handleBack = useCallback(() => {
21604
21706
  if (!onBack) {
21605
21707
  return;
@@ -21619,21 +21721,24 @@ function TimeInputWithRef({ baseContainer, defaultValue, disabled = false, isCom
21619
21721
  const handleFormatError = useCallback((hasNextFormatError) => {
21620
21722
  setHasFormatError(hasNextFormatError);
21621
21723
  }, []);
21622
- const handleRangedTimePickedChange = useCallback((nextTimeTuple) => {
21724
+ const handleHourInput = useCallback((nextValue) => {
21725
+ // eslint-disable-next-line no-nested-ternary
21726
+ const nextRangedTimePickerFilter = nextValue.length ? new RegExp(`^${nextValue}`) : /.*/;
21727
+ setTimePickerFilter(nextRangedTimePickerFilter);
21728
+ onInput();
21729
+ }, [onInput]);
21730
+ const handleTimePickerChange = useCallback((nextTimeTuple) => {
21623
21731
  closeRangedTimePicker();
21624
21732
  setControlledDefaultValue(nextTimeTuple);
21625
21733
  onChange(nextTimeTuple);
21626
21734
  }, [closeRangedTimePicker, onChange]);
21627
- const handleHourInput = useCallback((nextValue) => {
21628
- // eslint-disable-next-line no-nested-ternary
21629
- const nextRangedTimePickerFilter = nextValue.length ? new RegExp(`^${nextValue}`) : /.*/;
21630
- setRangedTimePickerFilter(nextRangedTimePickerFilter);
21631
- }, []);
21632
21735
  const openRangedTimePicker = useCallback(() => {
21633
- isRangedTimePickerOpenRef.current = true;
21634
- forceUpdate();
21635
- }, [forceUpdate]);
21736
+ setIsTimePickerOpen(true);
21737
+ }, []);
21636
21738
  const submit = useCallback(() => {
21739
+ if (!hourInputRef.current || !minuteInputRef.current) {
21740
+ return;
21741
+ }
21637
21742
  setHasValidationError(false);
21638
21743
  if (baseDocument.activeElement === hourInputRef.current) {
21639
21744
  minuteInputRef.current.focus();
@@ -21649,7 +21754,7 @@ function TimeInputWithRef({ baseContainer, defaultValue, disabled = false, isCom
21649
21754
  onChange(nextTimeTuple);
21650
21755
  }, [baseDocument, closeRangedTimePicker, onChange]);
21651
21756
  useClickOutsideEffect(boxRef, closeRangedTimePicker, baseContainer);
21652
- return (jsxs(Box$8, { 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 }))] }));
21757
+ return (jsxs(Box$8, { 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, onInput: onInput, onNext: onNext, onPrevious: () => hourInputRef.current?.focus(), size: 2 })] }), !isCompact && jsx(Clock, {})] }), isTimePickerOpen && (jsx(RangedTimePicker, { filter: timePickerFilter, minutesRange: minutesRange, onChange: handleTimePickerChange }))] }));
21653
21758
  }
21654
21759
  const TimeInput = forwardRef(TimeInputWithRef);
21655
21760
  const Box$8 = styled.div `
@@ -21685,27 +21790,30 @@ const InputGroup = styled.div `
21685
21790
  }
21686
21791
  `;
21687
21792
 
21688
- function DatePicker({ baseContainer, className, defaultValue, disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
21689
- const boxRef = useRef();
21690
- const dateInputRef = useRef();
21691
- const timeInputRef = useRef();
21793
+ function DatePicker({ baseContainer, className, defaultValue, disabled = false, error, isCompact = false, isEndDate = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
21794
+ /* eslint-disable no-null/no-null */
21795
+ const boxRef = useRef(null);
21796
+ const dateInputRef = useRef(null);
21797
+ const timeInputRef = useRef(null);
21798
+ /* eslint-enable no-null/no-null */
21692
21799
  const isCalendarPickerOpenRef = useRef(false);
21693
- const selectedLocalizedDateRef = useRef(defaultValue ? getLocalizedDayjs(defaultValue).toDate() : undefined);
21694
- const selectedLocalizedDateTupleRef = useRef(getDateTupleFromDate(selectedLocalizedDateRef.current));
21695
- const selectedLocalizedTimeTupleRef = useRef(getTimeTupleFromDate(selectedLocalizedDateRef.current));
21800
+ const selectedUtcDateAsDayjsRef = useRef(defaultValue ? customDayjs(defaultValue) : undefined);
21801
+ const selectedUtcDateTupleRef = useRef(getUtcDateTupleFromDayjs(selectedUtcDateAsDayjsRef.current));
21802
+ const selectedUtcTimeTupleRef = useRef(getUtcTimeTupleFromDayjs(selectedUtcDateAsDayjsRef.current));
21696
21803
  const { forceUpdate } = useForceUpdate();
21697
21804
  const controlledError = useMemo(() => normalizeString(error), [error]);
21805
+ const defaultTimeTuple = useMemo(() => (isEndDate ? ['23', '59'] : ['00', '00']), [isEndDate]);
21698
21806
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
21699
- const rangeCalendarPickerDefaultValue = useMemo(() => selectedLocalizedDateTupleRef.current
21700
- ? getDateFromDateAndTimeTuple(selectedLocalizedDateTupleRef.current, ['00', '00'])
21807
+ const calendarPickerDefaultValue = useMemo(() => selectedUtcDateTupleRef.current
21808
+ ? getUtcDateFromDateAndTimeTuple(selectedUtcDateTupleRef.current, defaultTimeTuple)
21701
21809
  : undefined,
21702
21810
  // eslint-disable-next-line react-hooks/exhaustive-deps
21703
- [selectedLocalizedDateTupleRef.current]);
21811
+ [selectedUtcDateTupleRef.current]);
21704
21812
  const submit = useCallback(() => {
21705
- if (!onChange || !selectedLocalizedDateRef.current) {
21813
+ if (!onChange || !selectedUtcDateAsDayjsRef.current) {
21706
21814
  return;
21707
21815
  }
21708
- const nextDateAsDayjs = getUtcizedDayjs(selectedLocalizedDateRef.current);
21816
+ const nextDateAsDayjs = selectedUtcDateAsDayjsRef.current;
21709
21817
  if (isStringDate) {
21710
21818
  onChange(nextDateAsDayjs.toISOString());
21711
21819
  }
@@ -21718,61 +21826,82 @@ function DatePicker({ baseContainer, className, defaultValue, disabled = false,
21718
21826
  forceUpdate();
21719
21827
  }, [forceUpdate]);
21720
21828
  const handleDateInputNext = useCallback(() => {
21721
- if (!withTime) {
21829
+ if (!withTime || !timeInputRef.current) {
21722
21830
  return;
21723
21831
  }
21724
21832
  timeInputRef.current.focus();
21725
21833
  }, [withTime]);
21726
- const handleDateInputChange = useCallback((nextDateTuple, isFilled) => {
21727
- selectedLocalizedDateTupleRef.current = nextDateTuple;
21834
+ const handleDateInputChange = useCallback((nextUtcDateTuple, isFilled) => {
21835
+ selectedUtcDateTupleRef.current = nextUtcDateTuple;
21728
21836
  // If there is no time input or a time has already been selected,
21729
- if (!withTime || selectedLocalizedTimeTupleRef.current) {
21837
+ if (!withTime || selectedUtcTimeTupleRef.current) {
21730
21838
  // we must update the selected date and call onChange()
21731
- const timeTuple = (withTime ? selectedLocalizedTimeTupleRef.current : ['00', '00']);
21732
- const nextDate = getDateFromDateAndTimeTuple(nextDateTuple, timeTuple);
21733
- selectedLocalizedDateRef.current = getLocalizedDayjs(nextDate).toDate();
21839
+ const timeTuple = withTime && selectedUtcTimeTupleRef.current ? selectedUtcTimeTupleRef.current : defaultTimeTuple;
21840
+ selectedUtcDateAsDayjsRef.current = getDayjsFromUtcDateAndTimeTuple(nextUtcDateTuple, timeTuple, isEndDate);
21734
21841
  submit();
21735
21842
  }
21736
21843
  if (isFilled) {
21737
21844
  handleDateInputNext();
21738
21845
  }
21739
- }, [handleDateInputNext, submit, withTime]);
21740
- const handleCalendarPickerChange = useCallback((nextDateTuple) => {
21846
+ }, [defaultTimeTuple, handleDateInputNext, isEndDate, submit, withTime]);
21847
+ const handleCalendarPickerChange = useCallback((nextUtcizedDateTuple) => {
21741
21848
  // If this is a date picker without a time input,
21742
21849
  if (!withTime) {
21743
- // we have to fix the date at the beginning of the day
21744
- const nextDate = getDateFromDateAndTimeTuple(nextDateTuple, ['00', '00']);
21745
- selectedLocalizedDateRef.current = nextDate;
21850
+ selectedUtcDateAsDayjsRef.current = getDayjsFromUtcDateAndTimeTuple(nextUtcizedDateTuple,
21851
+ // we set the time to the start (or end) of the day
21852
+ defaultTimeTuple, isEndDate);
21746
21853
  }
21747
21854
  // If this is a date picker with a time input,
21748
21855
  else {
21749
- // we include the selected time if it exists, set it at the beginning of the day if not
21750
- const nextDate = getDateFromDateAndTimeTuple(nextDateTuple, selectedLocalizedTimeTupleRef.current || ['00', '00']);
21751
- selectedLocalizedDateRef.current = nextDate;
21856
+ selectedUtcDateAsDayjsRef.current = getDayjsFromUtcDateAndTimeTuple(nextUtcizedDateTuple,
21857
+ // we include the selected time if it exists, or set it to the start (or end) of the day if it doesn't
21858
+ selectedUtcTimeTupleRef.current || defaultTimeTuple, isEndDate);
21752
21859
  }
21753
- selectedLocalizedDateTupleRef.current = nextDateTuple;
21754
- selectedLocalizedTimeTupleRef.current = getTimeTupleFromDate(selectedLocalizedDateRef.current);
21860
+ selectedUtcDateTupleRef.current = nextUtcizedDateTuple;
21861
+ selectedUtcTimeTupleRef.current = getUtcTimeTupleFromDayjs(selectedUtcDateAsDayjsRef.current);
21755
21862
  closeCalendarPicker();
21756
21863
  forceUpdate();
21757
21864
  submit();
21758
- if (withTime && !selectedLocalizedTimeTupleRef.current) {
21865
+ if (withTime && !selectedUtcTimeTupleRef.current && timeInputRef.current) {
21759
21866
  timeInputRef.current.focus();
21760
21867
  }
21761
- }, [closeCalendarPicker, forceUpdate, submit, withTime]);
21868
+ }, [closeCalendarPicker, defaultTimeTuple, forceUpdate, isEndDate, submit, withTime]);
21762
21869
  const handleDisable = useCallback(() => {
21763
- selectedLocalizedDateTupleRef.current = undefined;
21764
- selectedLocalizedTimeTupleRef.current = undefined;
21870
+ selectedUtcDateTupleRef.current = undefined;
21871
+ selectedUtcTimeTupleRef.current = undefined;
21765
21872
  forceUpdate();
21766
21873
  }, [forceUpdate]);
21874
+ /**
21875
+ * @description
21876
+ * This function is used to detect a user clearing all the date/time-related inputs
21877
+ * in order to call `onChange(undefined)` when everything is cleared
21878
+ */
21879
+ const handleDateOrTimeInputInput = useCallback(() => {
21880
+ if (!dateInputRef.current || !onChange) {
21881
+ return;
21882
+ }
21883
+ const [year, month, day] = dateInputRef.current.getValueAsPartialDateTuple();
21884
+ if (!withTime && !year && !month && !day) {
21885
+ onChange(undefined);
21886
+ return;
21887
+ }
21888
+ if (!timeInputRef.current) {
21889
+ return;
21890
+ }
21891
+ const [hour, minute] = timeInputRef.current.getValueAsPartialTimeTuple();
21892
+ if (!year && !month && !day && !hour && !minute) {
21893
+ onChange(undefined);
21894
+ }
21895
+ }, [onChange, withTime]);
21767
21896
  const handleTimeInputFilled = useCallback((nextTimeTuple) => {
21768
21897
  // If a date has already been selected
21769
- if (selectedLocalizedDateTupleRef.current) {
21898
+ if (selectedUtcDateTupleRef.current) {
21770
21899
  // we must update the selected date accordingly and submit it
21771
- const nextDate = getDateFromDateAndTimeTuple(selectedLocalizedDateTupleRef.current, nextTimeTuple);
21772
- selectedLocalizedDateRef.current = nextDate;
21900
+ const nextDateAsDayjs = getDayjsFromUtcDateAndTimeTuple(selectedUtcDateTupleRef.current, nextTimeTuple);
21901
+ selectedUtcDateAsDayjsRef.current = nextDateAsDayjs;
21773
21902
  submit();
21774
21903
  }
21775
- selectedLocalizedTimeTupleRef.current = nextTimeTuple;
21904
+ selectedUtcTimeTupleRef.current = nextTimeTuple;
21776
21905
  submit();
21777
21906
  }, [submit]);
21778
21907
  const openCalendarPicker = useCallback(() => {
@@ -21781,7 +21910,7 @@ function DatePicker({ baseContainer, className, defaultValue, disabled = false,
21781
21910
  }, [forceUpdate]);
21782
21911
  useFieldUndefineEffect(disabled, onChange, handleDisable);
21783
21912
  useClickOutsideEffect(boxRef, closeCalendarPicker, baseContainer);
21784
- return (jsxs(Fieldset, { className: classNames('Field-DatePicker', className), disabled: disabled, isLegendHidden: isLabelHidden, legend: label, ...nativeProps, children: [jsxs(Box$7, { ref: boxRef, children: [jsx(Field$1, { children: jsx(DateInput, { ref: dateInputRef, baseContainer: baseContainer || undefined, 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 || undefined, 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 })] }));
21913
+ return (jsxs(Fieldset, { className: classNames('Field-DatePicker', className), disabled: disabled, isLegendHidden: isLabelHidden, legend: label, ...nativeProps, children: [jsxs(Box$7, { ref: boxRef, children: [jsx(Field$1, { children: jsx(DateInput, { ref: dateInputRef, baseContainer: baseContainer || undefined, defaultValue: selectedUtcDateTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: isEndDate, isForcedFocused: isCalendarPickerOpenRef.current, isLight: isLight, onChange: handleDateInputChange, onClick: openCalendarPicker, onInput: handleDateOrTimeInputInput, onNext: handleDateInputNext }) }), withTime && (jsx(Field$1, { "$isTimeField": true, children: jsx(TimeInput, { ref: timeInputRef, baseContainer: baseContainer || undefined, defaultValue: selectedUtcTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isLight: isLight, minutesRange: minutesRange, onBack: () => dateInputRef.current?.focus(true), onChange: handleTimeInputFilled, onFocus: closeCalendarPicker, onInput: handleDateOrTimeInputInput, onPrevious: () => dateInputRef.current?.focus(true) }, JSON.stringify(selectedUtcTimeTupleRef.current)) }))] }), hasError && jsx(FieldError, { children: controlledError }), jsx(CalendarPicker, { isHistorical: isHistorical, isOpen: isCalendarPickerOpenRef.current, onChange: handleCalendarPickerChange, value: calendarPickerDefaultValue })] }));
21785
21914
  }
21786
21915
  const Box$7 = styled.div `
21787
21916
  * {
@@ -21802,30 +21931,35 @@ function sortDates(dates) {
21802
21931
  return dates
21803
21932
  .map(date => date.toISOString())
21804
21933
  .sort()
21805
- .map(dateAsIsoString => dayjs(dateAsIsoString).toDate());
21934
+ .map(dateAsIsoString => customDayjs(dateAsIsoString).toDate());
21806
21935
  }
21807
21936
 
21808
21937
  function RangeCalendarPicker({ defaultValue, isHistorical, isOpen, onChange }) {
21809
21938
  const boxRef = useRef();
21810
- const selectedFirstDate = useRef();
21811
- const selectedSecondDate = useRef();
21939
+ // It's called "first" and "second" because the calendar can also be picked from right to left,
21940
+ // that's why we sort these first and second dates before calling `onChange()`
21941
+ // in order to distinguish the start date from the end date
21942
+ const selectedFirstUtcDate = useRef();
21943
+ const selectedSecondUtcDate = useRef();
21812
21944
  const { forceUpdate } = useForceUpdate();
21813
21945
  const controlledValue = useMemo(() => (defaultValue ? sortDates(defaultValue) : undefined), [defaultValue]);
21814
- const utcTodayAsDayjs = useMemo(() => getUtcDayjs().endOf('day'), []);
21946
+ const utcTodayAsDayjs = useMemo(() => customDayjs().utc().endOf('day'), []);
21815
21947
  const disabledDate = useMemo(() => (date) => isHistorical ? getUtcizedDayjs(date).isAfter(utcTodayAsDayjs) : false, [isHistorical, utcTodayAsDayjs]);
21816
- const handleSelect = useCallback((nextDate) => {
21817
- if (!selectedFirstDate.current || selectedSecondDate.current) {
21818
- selectedFirstDate.current = nextDate;
21819
- selectedSecondDate.current = undefined;
21948
+ const handleSelect = useCallback((nextLocalDate) => {
21949
+ // We utcize the date picked by the user
21950
+ const nextUtcDate = getUtcizedDayjs(nextLocalDate).toDate();
21951
+ if (!selectedFirstUtcDate.current || selectedSecondUtcDate.current) {
21952
+ selectedFirstUtcDate.current = nextUtcDate;
21953
+ selectedSecondUtcDate.current = undefined;
21820
21954
  return;
21821
21955
  }
21822
- const sortedDateRange = sortDates([selectedFirstDate.current, nextDate]);
21956
+ const sortedDateRange = sortDates([selectedFirstUtcDate.current, nextUtcDate]);
21823
21957
  const [startDate, endDate] = sortedDateRange;
21824
- const startDateTuple = getDateTupleFromDate(startDate);
21825
- const endDateTuple = getDateTupleFromDate(endDate);
21826
- const nextDateTupleRange = [startDateTuple, endDateTuple];
21827
- selectedSecondDate.current = nextDate;
21828
- onChange(nextDateTupleRange);
21958
+ const startDateTuple = getDateTupleFromUtcDate(startDate);
21959
+ const endDateTuple = getDateTupleFromUtcDate(endDate);
21960
+ const nextUtcDateTupleRange = [startDateTuple, endDateTuple];
21961
+ selectedSecondUtcDate.current = nextUtcDate;
21962
+ onChange(nextUtcDateTupleRange);
21829
21963
  }, [onChange]);
21830
21964
  useEffect(() => {
21831
21965
  // We wait for the <Box /> to render so that `boxRef` is defined
@@ -22007,41 +22141,43 @@ var DateRangePosition;
22007
22141
  })(DateRangePosition || (DateRangePosition = {}));
22008
22142
 
22009
22143
  function DateRangePicker({ baseContainer, defaultValue, disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
22010
- const startDateInputRef = useRef();
22011
- const startTimeInputRef = useRef();
22012
- const endDateInputRef = useRef();
22013
- const endTimeInputRef = useRef();
22144
+ /* eslint-disable no-null/no-null */
22145
+ const startDateInputRef = useRef(null);
22146
+ const startTimeInputRef = useRef(null);
22147
+ const endDateInputRef = useRef(null);
22148
+ const endTimeInputRef = useRef(null);
22149
+ /* eslint-enable no-null/no-null */
22014
22150
  const isRangeCalendarPickerOpenRef = useRef(false);
22015
- const selectedLocalizedStartDateRef = useRef(defaultValue ? getLocalizedDayjs(defaultValue[0]).toDate() : undefined);
22016
- const selectedLocalizedEndDateRef = useRef(defaultValue ? getLocalizedDayjs(defaultValue[1]).toDate() : undefined);
22017
- const selectedLocalizedStartDateTupleRef = useRef(getDateTupleFromDate(selectedLocalizedStartDateRef.current));
22018
- const selectedLocalizedEndDateTupleRef = useRef(getDateTupleFromDate(selectedLocalizedEndDateRef.current));
22019
- const selectedLocalizedStartTimeTupleRef = useRef(getTimeTupleFromDate(selectedLocalizedStartDateRef.current));
22020
- const selectedLocalizedEndTimeTupleRef = useRef(getTimeTupleFromDate(selectedLocalizedEndDateRef.current));
22151
+ const selectedStartUtcDateRef = useRef(defaultValue ? customDayjs(defaultValue[0]).toDate() : undefined);
22152
+ const selectedEndUtcDateRef = useRef(defaultValue ? customDayjs(defaultValue[1]).toDate() : undefined);
22153
+ const selectedStartDateTupleRef = useRef(getDateTupleFromUtcDate(selectedStartUtcDateRef.current));
22154
+ const selectedEndDateTupleRef = useRef(getDateTupleFromUtcDate(selectedEndUtcDateRef.current));
22155
+ const selectedStartTimeTupleRef = useRef(getTimeTupleFromUtcDate(selectedStartUtcDateRef.current));
22156
+ const selectedEndTimeTupleRef = useRef(getTimeTupleFromUtcDate(selectedEndUtcDateRef.current));
22021
22157
  const { forceUpdate } = useForceUpdate();
22022
22158
  const controlledError = useMemo(() => normalizeString(error), [error]);
22023
22159
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
22024
- const rangeCalendarPickerDefaultValue = useMemo(() => selectedLocalizedStartDateTupleRef.current && selectedLocalizedEndDateTupleRef.current
22160
+ const rangeCalendarPickerDefaultValue = useMemo(() => selectedStartDateTupleRef.current && selectedEndDateTupleRef.current
22025
22161
  ? [
22026
- getDateFromDateAndTimeTuple(selectedLocalizedStartDateTupleRef.current, ['00', '00']),
22027
- getDateFromDateAndTimeTuple(selectedLocalizedEndDateTupleRef.current, ['00', '00'], true)
22162
+ getUtcDateFromDateAndTimeTuple(selectedStartDateTupleRef.current, ['00', '00']),
22163
+ getUtcDateFromDateAndTimeTuple(selectedEndDateTupleRef.current, ['00', '00'], true)
22028
22164
  ]
22029
22165
  : undefined,
22030
22166
  // eslint-disable-next-line react-hooks/exhaustive-deps
22031
- [selectedLocalizedEndDateTupleRef.current, selectedLocalizedStartDateTupleRef.current]);
22167
+ [selectedEndDateTupleRef.current, selectedStartDateTupleRef.current]);
22032
22168
  const submit = useCallback(() => {
22033
- if (!onChange || !selectedLocalizedStartDateRef.current || !selectedLocalizedEndDateRef.current) {
22169
+ if (!onChange || !selectedStartUtcDateRef.current || !selectedEndUtcDateRef.current) {
22034
22170
  return;
22035
22171
  }
22036
22172
  if (isStringDate) {
22037
- const utcizedStartDateAsString = getUtcizedDayjs(selectedLocalizedStartDateRef.current).toISOString();
22038
- const utcizedEndDateAsString = getUtcizedDayjs(selectedLocalizedEndDateRef.current).toISOString();
22173
+ const utcizedStartDateAsString = selectedStartUtcDateRef.current.toISOString();
22174
+ const utcizedEndDateAsString = selectedEndUtcDateRef.current.toISOString();
22039
22175
  const nextDateAsStringRange = [utcizedStartDateAsString, utcizedEndDateAsString];
22040
22176
  onChange(nextDateAsStringRange);
22041
22177
  }
22042
22178
  else {
22043
- const utcizedStartDate = getUtcizedDayjs(selectedLocalizedStartDateRef.current).toDate();
22044
- const utcizedEndDate = getUtcizedDayjs(selectedLocalizedEndDateRef.current).toDate();
22179
+ const utcizedStartDate = selectedStartUtcDateRef.current;
22180
+ const utcizedEndDate = selectedEndUtcDateRef.current;
22045
22181
  const nextDateRange = [utcizedStartDate, utcizedEndDate];
22046
22182
  onChange(nextDateRange);
22047
22183
  }
@@ -22051,27 +22187,33 @@ function DateRangePicker({ baseContainer, defaultValue, disabled = false, error,
22051
22187
  forceUpdate();
22052
22188
  }, [forceUpdate]);
22053
22189
  const handleDisable = useCallback(() => {
22054
- selectedLocalizedStartDateTupleRef.current = undefined;
22055
- selectedLocalizedStartTimeTupleRef.current = undefined;
22056
- selectedLocalizedEndDateTupleRef.current = undefined;
22057
- selectedLocalizedEndTimeTupleRef.current = undefined;
22190
+ selectedStartDateTupleRef.current = undefined;
22191
+ selectedStartTimeTupleRef.current = undefined;
22192
+ selectedEndDateTupleRef.current = undefined;
22193
+ selectedEndTimeTupleRef.current = undefined;
22058
22194
  forceUpdate();
22059
22195
  }, [forceUpdate]);
22060
22196
  const handleEndDateInputNext = useCallback(() => {
22061
- if (!withTime) {
22197
+ if (!withTime || !endTimeInputRef.current) {
22062
22198
  return;
22063
22199
  }
22064
22200
  endTimeInputRef.current.focus();
22065
22201
  }, [withTime]);
22066
22202
  const handleEndDateInputPrevious = useCallback(() => {
22067
- if (withTime) {
22203
+ if (!startDateInputRef.current) {
22204
+ return;
22205
+ }
22206
+ if (withTime && startTimeInputRef.current) {
22068
22207
  startTimeInputRef.current.focus(true);
22069
22208
  return;
22070
22209
  }
22071
22210
  startDateInputRef.current.focus(true);
22072
22211
  }, [withTime]);
22073
22212
  const handleStartDateInputNext = useCallback(() => {
22074
- if (withTime) {
22213
+ if (!endDateInputRef.current) {
22214
+ return;
22215
+ }
22216
+ if (withTime && startTimeInputRef.current) {
22075
22217
  startTimeInputRef.current.focus();
22076
22218
  return;
22077
22219
  }
@@ -22079,13 +22221,13 @@ function DateRangePicker({ baseContainer, defaultValue, disabled = false, error,
22079
22221
  }, [withTime]);
22080
22222
  const handleDateInputChange = useCallback((position, nextDateTuple, isFilled) => {
22081
22223
  if (position === DateRangePosition.START) {
22082
- selectedLocalizedStartDateTupleRef.current = nextDateTuple;
22224
+ selectedStartDateTupleRef.current = nextDateTuple;
22083
22225
  // If there is no time input or a start time has already been selected,
22084
- if (!withTime || selectedLocalizedStartTimeTupleRef.current) {
22226
+ if (!withTime || selectedStartTimeTupleRef.current) {
22085
22227
  // we must update the selected start date and call onChange()
22086
- const startTimeTuple = (withTime ? selectedLocalizedStartTimeTupleRef.current : ['00', '00']);
22087
- const nextStartDate = getDateFromDateAndTimeTuple(nextDateTuple, startTimeTuple);
22088
- selectedLocalizedStartDateRef.current = nextStartDate;
22228
+ const startUtcTimeTuple = withTime && selectedStartTimeTupleRef.current ? selectedStartTimeTupleRef.current : ['00', '00'];
22229
+ const nextStartDate = getUtcDateFromDateAndTimeTuple(nextDateTuple, startUtcTimeTuple);
22230
+ selectedStartUtcDateRef.current = nextStartDate;
22089
22231
  submit();
22090
22232
  }
22091
22233
  if (isFilled) {
@@ -22093,13 +22235,13 @@ function DateRangePicker({ baseContainer, defaultValue, disabled = false, error,
22093
22235
  }
22094
22236
  }
22095
22237
  else {
22096
- selectedLocalizedEndDateTupleRef.current = nextDateTuple;
22238
+ selectedEndDateTupleRef.current = nextDateTuple;
22097
22239
  // If there is no time input or an end time has already been selected,
22098
- if (!withTime || selectedLocalizedEndTimeTupleRef.current) {
22240
+ if (!withTime || selectedEndTimeTupleRef.current) {
22099
22241
  // we must update the selected end date and call onChange()
22100
- const endTimeTuple = (withTime ? selectedLocalizedEndTimeTupleRef.current : ['23', '59']);
22101
- const nextEndDate = getDateFromDateAndTimeTuple(nextDateTuple, endTimeTuple, true);
22102
- selectedLocalizedEndDateRef.current = nextEndDate;
22242
+ const endTimeTuple = (withTime ? selectedEndTimeTupleRef.current : ['23', '59']);
22243
+ const nextEndDate = getUtcDateFromDateAndTimeTuple(nextDateTuple, endTimeTuple, true);
22244
+ selectedEndUtcDateRef.current = nextEndDate;
22103
22245
  submit();
22104
22246
  }
22105
22247
  if (isFilled) {
@@ -22107,54 +22249,86 @@ function DateRangePicker({ baseContainer, defaultValue, disabled = false, error,
22107
22249
  }
22108
22250
  }
22109
22251
  }, [handleEndDateInputNext, handleStartDateInputNext, submit, withTime]);
22110
- const handleRangeCalendarPickerChange = useCallback((nextDateTupleRange) => {
22111
- const [nextStartDateTuple, nextEndDateTuple] = nextDateTupleRange;
22252
+ /**
22253
+ * @description
22254
+ * This function is used to detect a user clearing all the date/time-related inputs
22255
+ * in order to call `onChange(undefined)` when everything is cleared
22256
+ */
22257
+ const handleDateOrTimeInputInput = useCallback(() => {
22258
+ if (!startDateInputRef.current || !endDateInputRef.current || !onChange) {
22259
+ return;
22260
+ }
22261
+ const [startYear, startMonth, startDay] = startDateInputRef.current.getValueAsPartialDateTuple();
22262
+ const [endYear, endMonth, endDay] = endDateInputRef.current.getValueAsPartialDateTuple();
22263
+ if (!withTime && !startYear && !startMonth && !startDay && !endYear && !endMonth && !endDay) {
22264
+ onChange(undefined);
22265
+ return;
22266
+ }
22267
+ if (!startTimeInputRef.current || !endTimeInputRef.current) {
22268
+ return;
22269
+ }
22270
+ const [startHour, startMinute] = startTimeInputRef.current.getValueAsPartialTimeTuple();
22271
+ const [endHour, endMinute] = endTimeInputRef.current.getValueAsPartialTimeTuple();
22272
+ if (!startYear &&
22273
+ !startMonth &&
22274
+ !startDay &&
22275
+ !startHour &&
22276
+ !startMinute &&
22277
+ !endYear &&
22278
+ !endMonth &&
22279
+ !endDay &&
22280
+ !endHour &&
22281
+ !endMinute) {
22282
+ onChange(undefined);
22283
+ }
22284
+ }, [onChange, withTime]);
22285
+ const handleRangeCalendarPickerChange = useCallback((nextUtcDateTupleRange) => {
22286
+ const [nextStartUtcDateTuple, nextEndUtcDateTuple] = nextUtcDateTupleRange;
22112
22287
  // If this is a date picker without a time input,
22113
22288
  if (!withTime) {
22114
22289
  // we have to fix the start date at the beginning of the day
22115
- const nextStartDate = getDateFromDateAndTimeTuple(nextStartDateTuple, ['00', '00']);
22290
+ selectedStartUtcDateRef.current = getUtcDateFromDateAndTimeTuple(nextStartUtcDateTuple, ['00', '00']);
22116
22291
  // and the end date at the end of the day
22117
- const nextEndDate = getDateFromDateAndTimeTuple(nextEndDateTuple, ['23', '59'], true);
22118
- selectedLocalizedStartDateRef.current = nextStartDate;
22119
- selectedLocalizedEndDateRef.current = nextEndDate;
22292
+ selectedEndUtcDateRef.current = getUtcDateFromDateAndTimeTuple(nextEndUtcDateTuple, ['23', '59'], true);
22120
22293
  }
22121
22294
  // If this is a date picker with a time input,
22122
22295
  else {
22123
22296
  // we include the selected start time if it exists, set it at the beginning of the day if not
22124
- const nextStartDate = getDateFromDateAndTimeTuple(nextStartDateTuple, selectedLocalizedStartTimeTupleRef.current || ['00', '00']);
22125
- selectedLocalizedStartDateRef.current = nextStartDate;
22297
+ selectedStartUtcDateRef.current = getUtcDateFromDateAndTimeTuple(nextStartUtcDateTuple, selectedStartTimeTupleRef.current || ['00', '00']);
22126
22298
  // we include the selected end time if it exists, set it at the end of the day if not
22127
- const nextEndDate = getDateFromDateAndTimeTuple(nextEndDateTuple, selectedLocalizedEndTimeTupleRef.current || ['23', '59'], true);
22128
- selectedLocalizedEndDateRef.current = nextEndDate;
22299
+ selectedEndUtcDateRef.current = getUtcDateFromDateAndTimeTuple(nextEndUtcDateTuple, selectedEndTimeTupleRef.current || ['23', '59'], true);
22129
22300
  }
22130
- selectedLocalizedStartDateTupleRef.current = nextStartDateTuple;
22131
- selectedLocalizedStartTimeTupleRef.current = getTimeTupleFromDate(selectedLocalizedStartDateRef.current);
22132
- selectedLocalizedEndDateTupleRef.current = nextEndDateTuple;
22133
- selectedLocalizedEndTimeTupleRef.current = getTimeTupleFromDate(selectedLocalizedEndDateRef.current);
22301
+ selectedStartDateTupleRef.current = nextStartUtcDateTuple;
22302
+ selectedStartTimeTupleRef.current = getTimeTupleFromUtcDate(selectedStartUtcDateRef.current);
22303
+ selectedEndDateTupleRef.current = nextEndUtcDateTuple;
22304
+ selectedEndTimeTupleRef.current = getTimeTupleFromUtcDate(selectedEndUtcDateRef.current);
22134
22305
  closeRangeCalendarPicker();
22135
22306
  submit();
22136
22307
  }, [closeRangeCalendarPicker, submit, withTime]);
22137
22308
  const handleTimeInputFilled = useCallback((position, nextTimeTuple) => {
22309
+ if (!endDateInputRef.current) {
22310
+ return;
22311
+ }
22138
22312
  if (position === DateRangePosition.START) {
22139
22313
  // If a start date has already been selected
22140
- if (selectedLocalizedStartDateTupleRef.current) {
22314
+ if (selectedStartDateTupleRef.current) {
22141
22315
  // we must update the selected start date accordingly and submit it
22142
- const nextStartDate = getDateFromDateAndTimeTuple(selectedLocalizedStartDateTupleRef.current, nextTimeTuple);
22143
- selectedLocalizedStartDateRef.current = nextStartDate;
22316
+ const nextStartDate = getUtcDateFromDateAndTimeTuple(selectedStartDateTupleRef.current, nextTimeTuple);
22317
+ selectedStartUtcDateRef.current = nextStartDate;
22144
22318
  submit();
22145
22319
  }
22146
- selectedLocalizedStartTimeTupleRef.current = nextTimeTuple;
22320
+ selectedStartTimeTupleRef.current = nextTimeTuple;
22147
22321
  endDateInputRef.current.focus();
22148
22322
  }
22149
22323
  else {
22150
22324
  // If an end date has already been selected
22151
- if (selectedLocalizedEndDateTupleRef.current) {
22325
+ if (selectedEndDateTupleRef.current) {
22152
22326
  // we must update the selected end date accordingly and submit it
22153
- const nextEndDate = getDateFromDateAndTimeTuple(selectedLocalizedEndDateTupleRef.current, nextTimeTuple, true);
22154
- selectedLocalizedEndDateRef.current = nextEndDate;
22327
+ const nextEndDate = getUtcDateFromDateAndTimeTuple(selectedEndDateTupleRef.current, nextTimeTuple, true);
22328
+ selectedEndUtcDateRef.current = nextEndDate;
22155
22329
  submit();
22156
22330
  }
22157
- selectedLocalizedEndTimeTupleRef.current = nextTimeTuple;
22331
+ selectedEndTimeTupleRef.current = nextTimeTuple;
22158
22332
  }
22159
22333
  submit();
22160
22334
  }, [submit]);
@@ -22164,7 +22338,7 @@ function DateRangePicker({ baseContainer, defaultValue, disabled = false, error,
22164
22338
  }, [forceUpdate]);
22165
22339
  useFieldUndefineEffect(disabled, onChange, handleDisable);
22166
22340
  useClickOutsideEffect([endDateInputRef, startDateInputRef], closeRangeCalendarPicker, baseContainer);
22167
- return (jsxs(Fieldset, { className: "Field-DateRangePicker", disabled: disabled, isLegendHidden: isLabelHidden, legend: label, ...nativeProps, children: [jsxs(Box$5, { isDisabled: disabled, children: [jsx(Field, { children: jsx(DateInput, { ref: startDateInputRef, baseContainer: baseContainer || undefined, 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 || undefined, 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, baseContainer: baseContainer || undefined, 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 || undefined, 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 })] }));
22341
+ return (jsxs(Fieldset, { className: "Field-DateRangePicker", disabled: disabled, isLegendHidden: isLabelHidden, legend: label, ...nativeProps, children: [jsxs(Box$5, { isDisabled: disabled, children: [jsx(Field, { children: jsx(DateInput, { ref: startDateInputRef, baseContainer: baseContainer || undefined, defaultValue: selectedStartDateTupleRef.current, disabled: disabled, isCompact: isCompact, isForcedFocused: isRangeCalendarPickerOpenRef.current, isLight: isLight, isRange: true, isStartDate: true, onChange: (nextDateTuple, isFilled) => handleDateInputChange(DateRangePosition.START, nextDateTuple, isFilled), onClick: openRangeCalendarPicker, onInput: handleDateOrTimeInputInput, onNext: handleStartDateInputNext }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: startTimeInputRef, baseContainer: baseContainer || undefined, defaultValue: selectedStartTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isLight: isLight, isStartDate: true, minutesRange: minutesRange, onBack: () => startDateInputRef.current?.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.START, nextTimeTuple), onFocus: closeRangeCalendarPicker, onInput: handleDateOrTimeInputInput, onNext: () => endDateInputRef.current?.focus(), onPrevious: () => startDateInputRef.current?.focus(true) }) })), jsx(Field, { isEndDateField: true, children: jsx(DateInput, { ref: endDateInputRef, baseContainer: baseContainer || undefined, defaultValue: selectedEndDateTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: true, isForcedFocused: isRangeCalendarPickerOpenRef.current, isLight: isLight, isRange: true, onBack: handleEndDateInputPrevious, onChange: (nextDateTuple, isFilled) => handleDateInputChange(DateRangePosition.END, nextDateTuple, isFilled), onClick: openRangeCalendarPicker, onInput: handleDateOrTimeInputInput, onNext: handleEndDateInputNext, onPrevious: handleEndDateInputPrevious }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: endTimeInputRef, baseContainer: baseContainer || undefined, defaultValue: selectedEndTimeTupleRef.current, disabled: disabled, isCompact: isCompact, isEndDate: true, isLight: isLight, minutesRange: minutesRange, onBack: () => endDateInputRef.current?.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.END, nextTimeTuple), onFocus: closeRangeCalendarPicker, onInput: handleDateOrTimeInputInput, onPrevious: () => endDateInputRef.current?.focus(true) }) }))] }), hasError && jsx(FieldError, { children: controlledError }), jsx(RangeCalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, isOpen: isRangeCalendarPickerOpenRef.current, onChange: handleRangeCalendarPickerChange })] }));
22168
22342
  }
22169
22343
  const Box$5 = styled.div `
22170
22344
  * {
@@ -22518,7 +22692,7 @@ const CheckboxesBox = styled.div `
22518
22692
  `}
22519
22693
  `;
22520
22694
 
22521
- function MultiZoneEditor({ addButtonLabel, defaultValue = [], disabled = false, error, initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onChange, onDelete, onEdit }) {
22695
+ function MultiZoneEditor({ addButtonLabel, defaultValue = [], disabled = false, error, initialZone, isAddButtonDisabled = false, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onChange, onDelete, onEdit }) {
22522
22696
  const prevDefaultValueRef = useRef(defaultValue);
22523
22697
  const [zones, setZones] = useState(defaultValue);
22524
22698
  const controlledError = useMemo(() => normalizeString(error), [error]);
@@ -22557,7 +22731,7 @@ function MultiZoneEditor({ addButtonLabel, defaultValue = [], disabled = false,
22557
22731
  setZones(defaultValue);
22558
22732
  }, [defaultValue]);
22559
22733
  useFieldUndefineEffect(disabled, onChange, handleDisable);
22560
- return (jsxs(Fieldset, { className: "Field-MultiZoneEditor", disabled: disabled, isLegendHidden: isLabelHidden, 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) => (
22734
+ return (jsxs(Fieldset, { className: "Field-MultiZoneEditor", disabled: disabled, isLegendHidden: isLabelHidden, legend: label, children: [jsx(Button, { accent: Accent.SECONDARY, disabled: disabled || isAddButtonDisabled, Icon: Plus, isFullWidth: true, onClick: addZone, children: addButtonLabel }), jsx(Fragment, { children: zones.map((zone, index) => (
22561
22735
  // eslint-disable-next-line react/no-array-index-key
22562
22736
  jsxs(Row, { children: [jsxs(ZoneBox, { "$isLight": isLight, 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 })] }));
22563
22737
  }
@@ -33057,5 +33231,5 @@ function FormikTextInput({ name, ...originalProps }) {
33057
33231
  return jsx(TextInput, { error: meta.error, name: name, onChange: handleChange, value: field.value, ...originalProps });
33058
33232
  }
33059
33233
 
33060
- export { Accent, Button, Checkbox, CoordinatesFormat, CoordinatesInput, DatePicker, DateRangePicker, Dropdown, Field$2 as Field, Fieldset, FormikCheckbox, FormikCoordinatesInput, FormikDatePicker, FormikDateRangePicker, FormikEffect, FormikMultiCheckbox, FormikMultiRadio, FormikMultiSelect, FormikNumberInput, FormikSearch, FormikSelect, FormikTextInput, FormikTextarea, GlobalStyle, index as Icon, IconButton, Label, Legend, MultiCheckbox, MultiRadio, MultiSelect, MultiZoneEditor, NumberInput, OPENLAYERS_PROJECTION, OnlyFontGlobalStyle, Search, Select, SingleTag, Size, THEME, Tag, TagBullet, TagGroup, TextInput, Textarea, ThemeProvider, WSG84_PROJECTION, coordinatesAreDistinct, dayjs, getCoordinates, getLocalizedDayjs, getPseudoRandomString, getUtcizedDayjs, isNumeric, noop, stopMouseEventPropagation, useClickOutsideEffect, useForceUpdate, useKey, usePrevious };
33234
+ export { Accent, Button, Checkbox, CoordinatesFormat, CoordinatesInput, DatePicker, DateRangePicker, Dropdown, Field$2 as Field, Fieldset, FormikCheckbox, FormikCoordinatesInput, FormikDatePicker, FormikDateRangePicker, FormikEffect, FormikMultiCheckbox, FormikMultiRadio, FormikMultiSelect, FormikNumberInput, FormikSearch, FormikSelect, FormikTextInput, FormikTextarea, GlobalStyle, index as Icon, IconButton, Label, Legend, MultiCheckbox, MultiRadio, MultiSelect, MultiZoneEditor, NumberInput, OPENLAYERS_PROJECTION, OnlyFontGlobalStyle, Search, Select, SingleTag, Size, THEME, Tag, TagBullet, TagGroup, TextInput, Textarea, ThemeProvider, WSG84_PROJECTION, coordinatesAreDistinct, customDayjs, getCoordinates, getLocalizedDayjs, getPseudoRandomString, getUtcizedDayjs, isNumeric, noop, stopMouseEventPropagation, useClickOutsideEffect, useForceUpdate, useKey, usePrevious };
33061
33235
  //# sourceMappingURL=index.js.map