@servicetitan/anvil2 1.40.2 → 1.41.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.
Files changed (136) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/{Calendar-KVYGk3wS-CEptqxjI.js → Calendar-CNrdcd3f-BAKv-Gz3.js} +6 -4
  3. package/dist/{Calendar-KVYGk3wS-CEptqxjI.js.map → Calendar-CNrdcd3f-BAKv-Gz3.js.map} +1 -1
  4. package/dist/{Calendar-2q8zRbMK.js → Calendar-MIwfKzm7.js} +2 -2
  5. package/dist/{Calendar-2q8zRbMK.js.map → Calendar-MIwfKzm7.js.map} +1 -1
  6. package/dist/Calendar.js +1 -1
  7. package/dist/{Checkbox-cfgZP7Z2.js → Checkbox-IPM-sdvR.js} +2 -2
  8. package/dist/{Checkbox-cfgZP7Z2.js.map → Checkbox-IPM-sdvR.js.map} +1 -1
  9. package/dist/{Checkbox-Qucv_PK8-Bovwdnlj.js → Checkbox-JWDraGFN--7ptfLKN.js} +2 -2
  10. package/dist/{Checkbox-Qucv_PK8-Bovwdnlj.js.map → Checkbox-JWDraGFN--7ptfLKN.js.map} +1 -1
  11. package/dist/Checkbox.js +1 -1
  12. package/dist/{Combobox-3l2SK47T.js → Combobox-CM8DmNMs.js} +4 -4
  13. package/dist/{Combobox-3l2SK47T.js.map → Combobox-CM8DmNMs.js.map} +1 -1
  14. package/dist/Combobox.js +1 -1
  15. package/dist/{DateField-CfNLRY0D.js → DateField-BDJEsVc1.js} +13 -10
  16. package/dist/DateField-BDJEsVc1.js.map +1 -0
  17. package/dist/DateField.js +1 -1
  18. package/dist/{DateFieldRange-BEL4Jdy8.js → DateFieldRange-BTq6MrNu.js} +2 -2
  19. package/dist/DateFieldRange-BTq6MrNu.js.map +1 -0
  20. package/dist/DateFieldRange.js +1 -1
  21. package/dist/{DateFieldSingle-CJ6j0p1L.js → DateFieldSingle-CaeOLrI4.js} +2 -2
  22. package/dist/DateFieldSingle-CaeOLrI4.js.map +1 -0
  23. package/dist/DateFieldSingle.js +1 -1
  24. package/dist/{DateFieldRange-DtppOifM-DZvtSHar.js → DateFieldYearless-CJP3H_Dg-BV5wGJp1.js} +393 -27
  25. package/dist/DateFieldYearless-CJP3H_Dg-BV5wGJp1.js.map +1 -0
  26. package/dist/DateFieldYearless-CbFo3oyZ.js +22 -0
  27. package/dist/DateFieldYearless-CbFo3oyZ.js.map +1 -0
  28. package/dist/DateFieldYearless.d.ts +2 -0
  29. package/dist/DateFieldYearless.js +2 -0
  30. package/dist/DateFieldYearless.js.map +1 -0
  31. package/dist/{DaysOfTheWeek-Dl31wkmU.js → DaysOfTheWeek-8zaAuw55.js} +2 -2
  32. package/dist/{DaysOfTheWeek-Dl31wkmU.js.map → DaysOfTheWeek-8zaAuw55.js.map} +1 -1
  33. package/dist/DaysOfTheWeek.js +1 -1
  34. package/dist/{Dialog-CJZEBa5r.js → Dialog-DnZE02ob.js} +9 -5
  35. package/dist/Dialog-DnZE02ob.js.map +1 -0
  36. package/dist/Dialog.js +1 -1
  37. package/dist/{Drawer-Cj3nJc4k.js → Drawer-5kgL0gY9.js} +2 -2
  38. package/dist/{Drawer-Cj3nJc4k.js.map → Drawer-5kgL0gY9.js.map} +1 -1
  39. package/dist/Drawer.js +1 -1
  40. package/dist/FieldLabel-D5rNXy6h.js +13 -0
  41. package/dist/FieldLabel-D5rNXy6h.js.map +1 -0
  42. package/dist/FieldLabel.d.ts +6 -0
  43. package/dist/FieldLabel.js +2 -0
  44. package/dist/FieldLabel.js.map +1 -0
  45. package/dist/{InputMask-BdLGTTAk.js → InputMask-B6kMdXCB.js} +2 -2
  46. package/dist/{InputMask-BdLGTTAk.js.map → InputMask-B6kMdXCB.js.map} +1 -1
  47. package/dist/{InputMask-Hn-xudp1-BKhtZ7Zk.js → InputMask-BLZh7hka-CTcRCY2k.js} +2 -2
  48. package/dist/{InputMask-Hn-xudp1-BKhtZ7Zk.js.map → InputMask-BLZh7hka-CTcRCY2k.js.map} +1 -1
  49. package/dist/InputMask.js +1 -1
  50. package/dist/{ListView-_YFTewqc.js → ListView-cMMBtp1O.js} +3 -3
  51. package/dist/{ListView-_YFTewqc.js.map → ListView-cMMBtp1O.js.map} +1 -1
  52. package/dist/ListView.js +1 -1
  53. package/dist/{Menu-CffX1bPZ-BeEOvryY.js → Menu-CAiyc2zk-rxU7H28t.js} +3 -3
  54. package/dist/{Menu-CffX1bPZ-BeEOvryY.js.map → Menu-CAiyc2zk-rxU7H28t.js.map} +1 -1
  55. package/dist/{Menu-1EwVMNIw.js → Menu-Dk3ESnzI.js} +2 -2
  56. package/dist/{Menu-1EwVMNIw.js.map → Menu-Dk3ESnzI.js.map} +1 -1
  57. package/dist/Menu.js +1 -1
  58. package/dist/{Page-BikjTlTM.js → Page-DWeD3rrr.js} +5 -5
  59. package/dist/{Page-BikjTlTM.js.map → Page-DWeD3rrr.js.map} +1 -1
  60. package/dist/Page.js +1 -1
  61. package/dist/Pagination.js +1 -1
  62. package/dist/Pagination.js.map +1 -1
  63. package/dist/{Popover-rB4BVx-A.js → Popover-2O1Q-34V.js} +2 -2
  64. package/dist/{Popover-rB4BVx-A.js.map → Popover-2O1Q-34V.js.map} +1 -1
  65. package/dist/{Popover-jcmNuir0-DjlCqU1z.js → Popover-DvLcjLjG-Yu5STx-v.js} +77 -14
  66. package/dist/Popover-DvLcjLjG-Yu5STx-v.js.map +1 -0
  67. package/dist/Popover.js +1 -1
  68. package/dist/{ProgressBar-CzXzPpIX-Clg1J71o.js → ProgressBar-BezETeA3-CeeedJ_w.js} +49 -15
  69. package/dist/ProgressBar-BezETeA3-CeeedJ_w.js.map +1 -0
  70. package/dist/{ProgressBar-BL34rg_J.js → ProgressBar-CfstmN5D.js} +2 -2
  71. package/dist/{ProgressBar-BL34rg_J.js.map → ProgressBar-CfstmN5D.js.map} +1 -1
  72. package/dist/ProgressBar.js +1 -1
  73. package/dist/{Radio-BnOSIK1U-1MmGQFPi.js → Radio-8E1l0DJa-CLVaSyQc.js} +3 -3
  74. package/dist/{Radio-BnOSIK1U-1MmGQFPi.js.map → Radio-8E1l0DJa-CLVaSyQc.js.map} +1 -1
  75. package/dist/{Radio-BzZUxQa6.js → Radio-P6dkI3W0.js} +2 -2
  76. package/dist/{Radio-BzZUxQa6.js.map → Radio-P6dkI3W0.js.map} +1 -1
  77. package/dist/Radio.js +1 -1
  78. package/dist/{SelectCard-ynL5QcZD-BtBzMtyR.js → SelectCard-m61WUlo--DlByowef.js} +4 -4
  79. package/dist/{SelectCard-ynL5QcZD-BtBzMtyR.js.map → SelectCard-m61WUlo--DlByowef.js.map} +1 -1
  80. package/dist/SelectCard.js +1 -1
  81. package/dist/{SelectCardGroup-D6GuJJB2.js → SelectCardGroup-DIaWX2Vp.js} +2 -2
  82. package/dist/{SelectCardGroup-D6GuJJB2.js.map → SelectCardGroup-DIaWX2Vp.js.map} +1 -1
  83. package/dist/{SelectTrigger-Bo2VPAD0.js → SelectTrigger-DKh0Bzy6.js} +2 -2
  84. package/dist/{SelectTrigger-Bo2VPAD0.js.map → SelectTrigger-DKh0Bzy6.js.map} +1 -1
  85. package/dist/SelectTrigger.js +1 -1
  86. package/dist/{SelectTriggerBase-BGHwx0mN-B3HiW5tQ.js → SelectTriggerBase-DnRvuD3R-CTFWVZhY.js} +3 -3
  87. package/dist/{SelectTriggerBase-BGHwx0mN-B3HiW5tQ.js.map → SelectTriggerBase-DnRvuD3R-CTFWVZhY.js.map} +1 -1
  88. package/dist/{TextField-COXABNrR.js → TextField--tytNBLh.js} +2 -2
  89. package/dist/{TextField-COXABNrR.js.map → TextField--tytNBLh.js.map} +1 -1
  90. package/dist/{TextField-BIeCvDD--C7yp05g5.js → TextField-D_fqJf85-Bcd6rWv4.js} +2 -2
  91. package/dist/{TextField-BIeCvDD--C7yp05g5.js.map → TextField-D_fqJf85-Bcd6rWv4.js.map} +1 -1
  92. package/dist/TextField.js +1 -1
  93. package/dist/{Textarea-D6K3Jc5_.js → Textarea-B0nZ9vOV.js} +2 -2
  94. package/dist/{Textarea-D6K3Jc5_.js.map → Textarea-B0nZ9vOV.js.map} +1 -1
  95. package/dist/Textarea.js +1 -1
  96. package/dist/Toast.js +1 -1
  97. package/dist/{Toolbar-CLsgDAKk.js → Toolbar-BM78DEEM.js} +3 -3
  98. package/dist/{Toolbar-CLsgDAKk.js.map → Toolbar-BM78DEEM.js.map} +1 -1
  99. package/dist/Toolbar.js +1 -1
  100. package/dist/{Tooltip-B_swJyoW.js → Tooltip-ZFFXA77Y.js} +2 -2
  101. package/dist/{Tooltip-B_swJyoW.js.map → Tooltip-ZFFXA77Y.js.map} +1 -1
  102. package/dist/Tooltip.js +1 -1
  103. package/dist/components/DateFieldRange/DateFieldRange.d.ts +4 -1
  104. package/dist/components/DateFieldRange/index.d.ts +1 -2
  105. package/dist/components/DateFieldSingle/DateFieldSingle.d.ts +3 -1
  106. package/dist/components/DateFieldSingle/index.d.ts +1 -2
  107. package/dist/components/DateFieldYearless/DateFieldYearless.d.ts +62 -0
  108. package/dist/components/DateFieldYearless/index.d.ts +1 -0
  109. package/dist/components/Dialog/Dialog.d.ts +1 -1
  110. package/dist/components/Drawer/Drawer.d.ts +1 -1
  111. package/dist/components/FieldLabel/FieldLabel.d.ts +8 -0
  112. package/dist/components/FieldLabel/index.d.ts +2 -0
  113. package/dist/components/index.d.ts +2 -0
  114. package/dist/index.js +25 -23
  115. package/dist/index.js.map +1 -1
  116. package/dist/{toast-CJSBieY0.js → toast-uADTqqrS.js} +2 -2
  117. package/dist/{toast-CJSBieY0.js.map → toast-uADTqqrS.js.map} +1 -1
  118. package/dist/usePopoverCloseDelayWorkaround-BhhG-xEB-hfJZaXHC.js +21 -0
  119. package/dist/usePopoverCloseDelayWorkaround-BhhG-xEB-hfJZaXHC.js.map +1 -0
  120. package/package.json +3 -3
  121. package/dist/DateField-CfNLRY0D.js.map +0 -1
  122. package/dist/DateFieldRange-BEL4Jdy8.js.map +0 -1
  123. package/dist/DateFieldRange-DtppOifM-DZvtSHar.js.map +0 -1
  124. package/dist/DateFieldSingle-CJ6j0p1L.js.map +0 -1
  125. package/dist/Dialog-CJZEBa5r.js.map +0 -1
  126. package/dist/Popover-jcmNuir0-DjlCqU1z.js.map +0 -1
  127. package/dist/ProgressBar-CzXzPpIX-Clg1J71o.js.map +0 -1
  128. package/dist/event-BEJFimi3.js +0 -6
  129. package/dist/event-BEJFimi3.js.map +0 -1
  130. /package/dist/{Calendar-KVYGk3wS.css → Calendar-CNrdcd3f.css} +0 -0
  131. /package/dist/{Menu-CffX1bPZ.css → Menu-CAiyc2zk.css} +0 -0
  132. /package/dist/{Popover-jcmNuir0.css → Popover-DvLcjLjG.css} +0 -0
  133. /package/dist/{ProgressBar-CzXzPpIX.css → ProgressBar-BezETeA3.css} +0 -0
  134. /package/dist/{Radio-BnOSIK1U.css → Radio-8E1l0DJa.css} +0 -0
  135. /package/dist/{SelectCard-ynL5QcZD.css → SelectCard-m61WUlo-.css} +0 -0
  136. /package/dist/{SelectTriggerBase-BGHwx0mN.css → SelectTriggerBase-DnRvuD3R.css} +0 -0
@@ -1,14 +1,14 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useState, useCallback, useRef, useLayoutEffect, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react';
3
- import { D as DateTime, f as Calendar } from './Calendar-KVYGk3wS-CEptqxjI.js';
4
- import { T as TextField } from './TextField-BIeCvDD--C7yp05g5.js';
3
+ import { D as DateTime, f as Calendar } from './Calendar-CNrdcd3f-BAKv-Gz3.js';
4
+ import { T as TextField } from './TextField-D_fqJf85-Bcd6rWv4.js';
5
5
  import { u as useMergeRefs$1 } from './floating-ui.react-BFNinq1w.js';
6
6
  import { I as Icon } from './Icon-B6HmlQiR-BxQkO3X5.js';
7
- import { S as SvgEvent } from './event-BEJFimi3.js';
8
- import { d as Popover } from './Popover-jcmNuir0-DjlCqU1z.js';
7
+ import { u as usePopoverCloseDelayWorkaround, S as SvgEvent } from './usePopoverCloseDelayWorkaround-BhhG-xEB-hfJZaXHC.js';
8
+ import { d as Popover } from './Popover-DvLcjLjG-Yu5STx-v.js';
9
9
  import { u as useMergeRefs } from './useMergeRefs-Bde85AWI-Bde85AWI.js';
10
10
  import { u as useOptionallyControlledState } from './useOptionallyControlledState-DAv5LXXh-DAv5LXXh.js';
11
- import { s as supportsPopover, u as useKeyboardFocusables } from './ProgressBar-CzXzPpIX-Clg1J71o.js';
11
+ import { s as supportsPopover, u as useKeyboardFocusables } from './ProgressBar-BezETeA3-CeeedJ_w.js';
12
12
 
13
13
  function getContentEditableSelection(element) {
14
14
  const { anchorOffset = 0, focusOffset = 0 } = element.ownerDocument.getSelection() || {};
@@ -1887,7 +1887,7 @@ const MaskedDateInput = forwardRef(
1887
1887
  useEffect(() => {
1888
1888
  if (mode !== previousMode) {
1889
1889
  setInputValue(
1890
- (oldInputValue) => swapMode$1(oldInputValue, previousMode ?? mode, mode)
1890
+ (oldInputValue) => swapMode$2(oldInputValue, previousMode ?? mode, mode)
1891
1891
  );
1892
1892
  }
1893
1893
  }, [mode, previousMode]);
@@ -1902,11 +1902,11 @@ const MaskedDateInput = forwardRef(
1902
1902
  }
1903
1903
  }, [lastValidDate, mode, placeholder]);
1904
1904
  const currentParsedData = useMemo(() => {
1905
- return parseInputValue(inputValue, mode, removePlaceholder);
1905
+ return parseInputValue$1(inputValue, mode, removePlaceholder);
1906
1906
  }, [inputValue, mode, removePlaceholder]);
1907
1907
  const handleChange = (event) => {
1908
1908
  setInputValue(event.target.value);
1909
- const { date, isInputValid, isInputEmpty } = parseInputValue(
1909
+ const { date, isInputValid, isInputEmpty } = parseInputValue$1(
1910
1910
  event.target.value,
1911
1911
  mode,
1912
1912
  removePlaceholder
@@ -1941,13 +1941,13 @@ const MaskedDateInput = forwardRef(
1941
1941
  value: inputValue,
1942
1942
  onChange: handleChange,
1943
1943
  prefix: /* @__PURE__ */ jsx(Icon, { svg: SvgEvent }),
1944
- hint: disableHint ? void 0 : `format: ${mode}`
1944
+ hint: disableHint ? void 0 : `Format: ${mode}`
1945
1945
  }
1946
1946
  );
1947
1947
  }
1948
1948
  );
1949
1949
  MaskedDateInput.displayName = "MaskedDateInput";
1950
- function parseInputValue(value, mode, removePlaceholder) {
1950
+ function parseInputValue$1(value, mode, removePlaceholder) {
1951
1951
  const valueMinusPlaceholder = removePlaceholder(value);
1952
1952
  const jsDate = maskitoParseDate(valueMinusPlaceholder, { mode });
1953
1953
  const luxonDate = jsDate ? DateTime.fromJSDate(jsDate, { zone: "utc" }) : null;
@@ -1957,11 +1957,11 @@ function parseInputValue(value, mode, removePlaceholder) {
1957
1957
  isInputEmpty: valueMinusPlaceholder === ""
1958
1958
  };
1959
1959
  }
1960
- function swapMode$1(inputString, previousMode, mode) {
1961
- const { day, month, year } = divideSegments(inputString, previousMode);
1960
+ function swapMode$2(inputString, previousMode, mode) {
1961
+ const { day, month, year } = divideSegments$1(inputString, previousMode);
1962
1962
  return orderSegmentsByMode(day, month, year, mode);
1963
1963
  }
1964
- function divideSegments(value, mode) {
1964
+ function divideSegments$1(value, mode) {
1965
1965
  const [segment1, segment2, segment3] = value.split("/");
1966
1966
  if (mode === "dd/mm/yyyy") {
1967
1967
  return { day: segment1, month: segment2, year: segment3 };
@@ -2104,6 +2104,36 @@ function validateDate({
2104
2104
  }
2105
2105
  return true;
2106
2106
  }
2107
+ function validateYearlessDate({
2108
+ value,
2109
+ constraints
2110
+ }) {
2111
+ const { required, unavailable, minDate, maxDate } = constraints;
2112
+ if (!value || !value?.day && !value?.month) {
2113
+ return required ? false : true;
2114
+ }
2115
+ if (value.day === null || value.month === null) {
2116
+ return false;
2117
+ }
2118
+ if (unavailable?.dates?.some(
2119
+ (d) => d.day === value.day && d.month === value.month
2120
+ )) {
2121
+ return false;
2122
+ }
2123
+ const minDateMonth = minDate?.month ?? 1;
2124
+ const minDateDay = minDate?.day ?? 1;
2125
+ const maxDateMonth = maxDate?.month ?? 12;
2126
+ const maxDateDay = maxDate?.day ?? 31;
2127
+ if (value.month < minDateMonth || // Earlier month
2128
+ value.month === minDateMonth && value.day < minDateDay) {
2129
+ return false;
2130
+ }
2131
+ if (value.month > maxDateMonth || // Later month
2132
+ value.month === maxDateMonth && value.day > maxDateDay) {
2133
+ return false;
2134
+ }
2135
+ return true;
2136
+ }
2107
2137
 
2108
2138
  const NormalizedDateFieldSingle = forwardRef(
2109
2139
  ({
@@ -2115,6 +2145,8 @@ const NormalizedDateFieldSingle = forwardRef(
2115
2145
  unavailable,
2116
2146
  minDate,
2117
2147
  maxDate,
2148
+ onFocus,
2149
+ onBlur,
2118
2150
  required = false,
2119
2151
  ...rest
2120
2152
  }, ref) => {
@@ -2138,6 +2170,7 @@ const NormalizedDateFieldSingle = forwardRef(
2138
2170
  defaultValue: defaultValueProp
2139
2171
  });
2140
2172
  const popoverSupported = usePopoverSupport();
2173
+ const shouldShowCalendar = usePopoverCloseDelayWorkaround(calendarOpen);
2141
2174
  const currentValidity = useMemo(
2142
2175
  () => validateDate({
2143
2176
  date: lastValidDate,
@@ -2225,16 +2258,17 @@ const NormalizedDateFieldSingle = forwardRef(
2225
2258
  open: calendarOpen,
2226
2259
  modal: true,
2227
2260
  placement: "bottom-start",
2261
+ disableFlipFallback: true,
2228
2262
  disableTriggerFocus: true,
2229
2263
  onClose: () => setCalendarOpen(false),
2230
2264
  disableAutoUpdate: true,
2231
- onOutsidePress: () => setCalendarOpen(false),
2265
+ onClickOutside: () => setCalendarOpen(false),
2232
2266
  children: [
2233
2267
  /* @__PURE__ */ jsx(Popover.Trigger, { children: ({ ref: iRef }) => {
2234
2268
  setPopoverTriggerRef(iRef);
2235
2269
  return justTheField;
2236
2270
  } }),
2237
- /* @__PURE__ */ jsx(Popover.Content, { ref: popoverContentRef, "data-calendar-popover": true, children: /* @__PURE__ */ jsx(
2271
+ /* @__PURE__ */ jsx(Popover.Content, { ref: popoverContentRef, "data-testid": "calendar-popover", children: shouldShowCalendar && /* @__PURE__ */ jsx(
2238
2272
  Calendar,
2239
2273
  {
2240
2274
  range: false,
@@ -2259,14 +2293,103 @@ const NormalizedDateFieldSingle = forwardRef(
2259
2293
  );
2260
2294
  NormalizedDateFieldSingle.displayName = "NormalizedDateFieldSingle";
2261
2295
 
2296
+ function containsRelatedTarget(event) {
2297
+ if (event.currentTarget instanceof HTMLElement && event.relatedTarget instanceof HTMLElement) {
2298
+ return event.currentTarget.contains(event.relatedTarget);
2299
+ }
2300
+ return false;
2301
+ }
2302
+ function useFocusWithin({
2303
+ onBlur,
2304
+ onFocus
2305
+ } = {}) {
2306
+ const [focused, setFocused] = useState(false);
2307
+ const focusedRef = useRef(false);
2308
+ const elementRef = useRef(null);
2309
+ const _setFocused = useCallback((value) => {
2310
+ setFocused(value);
2311
+ focusedRef.current = value;
2312
+ }, []);
2313
+ const handleFocusIn = useCallback(
2314
+ (event) => {
2315
+ if (!focusedRef.current) {
2316
+ _setFocused(true);
2317
+ onFocus?.(event);
2318
+ }
2319
+ },
2320
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2321
+ [onFocus]
2322
+ );
2323
+ const handleFocusOut = useCallback(
2324
+ (event) => {
2325
+ if (focusedRef.current && !containsRelatedTarget(event)) {
2326
+ _setFocused(false);
2327
+ onBlur?.(event);
2328
+ }
2329
+ },
2330
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2331
+ [onBlur]
2332
+ );
2333
+ useEffect(() => {
2334
+ const element = elementRef.current;
2335
+ if (!element) {
2336
+ return;
2337
+ }
2338
+ element.addEventListener("focusin", handleFocusIn);
2339
+ element.addEventListener("focusout", handleFocusOut);
2340
+ return () => {
2341
+ element.removeEventListener("focusin", handleFocusIn);
2342
+ element.removeEventListener("focusout", handleFocusOut);
2343
+ };
2344
+ }, [handleFocusIn, handleFocusOut]);
2345
+ return { ref: elementRef, focused };
2346
+ }
2347
+
2348
+ const useConditionalChange = ({
2349
+ changeHandler,
2350
+ compareFn
2351
+ }) => {
2352
+ const lastChangeRef = useRef(null);
2353
+ const onChange = useCallback(
2354
+ (change) => {
2355
+ if (!!lastChangeRef.current && !compareFn(lastChangeRef.current, change)) {
2356
+ return;
2357
+ }
2358
+ changeHandler?.(change);
2359
+ lastChangeRef.current = change;
2360
+ },
2361
+ [changeHandler, compareFn]
2362
+ );
2363
+ return onChange;
2364
+ };
2365
+
2262
2366
  const DateFieldSingle = ({
2263
2367
  value,
2264
2368
  defaultValue,
2265
2369
  minDate,
2266
2370
  maxDate,
2267
2371
  unavailable,
2372
+ onChange,
2373
+ onFocus,
2374
+ onBlur,
2268
2375
  ...rest
2269
2376
  }) => {
2377
+ const handleBlur = useCallback(
2378
+ (event) => {
2379
+ onBlur?.(event);
2380
+ },
2381
+ [onBlur]
2382
+ );
2383
+ const handleFocus = useCallback(
2384
+ (event) => {
2385
+ onFocus?.(event);
2386
+ },
2387
+ [onFocus]
2388
+ );
2389
+ const { ref: wrapperRef } = useFocusWithin({
2390
+ onBlur: handleBlur,
2391
+ onFocus: handleFocus
2392
+ });
2270
2393
  const normalizedValue = useMemo(() => convertStringToDate(value), [value]);
2271
2394
  const normalizedDefaultValue = useMemo(
2272
2395
  () => convertStringToDate(defaultValue),
@@ -2284,10 +2407,15 @@ const DateFieldSingle = ({
2284
2407
  () => unavailable?.dates?.map((d) => convertStringToDate(d)).filter((d) => d !== null && d !== void 0),
2285
2408
  [unavailable?.dates]
2286
2409
  );
2287
- return /* @__PURE__ */ jsx(
2410
+ const handleChange = useConditionalChange({
2411
+ changeHandler: onChange,
2412
+ compareFn: (a, b) => a.isInputValid !== b.isInputValid || a.isInputEmpty !== b.isInputEmpty || a.isDateValid !== b.isDateValid || a.date !== b.date
2413
+ });
2414
+ return /* @__PURE__ */ jsx("div", { ref: wrapperRef, children: /* @__PURE__ */ jsx(
2288
2415
  NormalizedDateFieldSingle,
2289
2416
  {
2290
2417
  ...rest,
2418
+ onChange: handleChange,
2291
2419
  value: normalizedValue,
2292
2420
  defaultValue: normalizedDefaultValue,
2293
2421
  minDate: normalizedMinDate,
@@ -2297,7 +2425,7 @@ const DateFieldSingle = ({
2297
2425
  daysOfWeek: unavailable?.daysOfWeek
2298
2426
  } : void 0
2299
2427
  }
2300
- );
2428
+ ) });
2301
2429
  };
2302
2430
  DateFieldSingle.displayName = "DateFieldSingle";
2303
2431
 
@@ -2360,7 +2488,7 @@ const MaskedDateRangeInput = forwardRef(
2360
2488
  useEffect(() => {
2361
2489
  if (mode !== previousMode) {
2362
2490
  setInputValue(
2363
- (previousInputValue) => swapMode(previousInputValue, previousMode ?? mode, mode)
2491
+ (previousInputValue) => swapMode$1(previousInputValue, previousMode ?? mode, mode)
2364
2492
  );
2365
2493
  }
2366
2494
  }, [mode, fullPlaceholder, previousMode]);
@@ -2432,7 +2560,7 @@ const MaskedDateRangeInput = forwardRef(
2432
2560
  value: inputValue,
2433
2561
  onChange: handleChange,
2434
2562
  prefix: /* @__PURE__ */ jsx(Icon, { svg: SvgEvent }),
2435
- hint: disableHint ? void 0 : `format: ${mode}`
2563
+ hint: disableHint ? void 0 : `Format: ${mode}`
2436
2564
  }
2437
2565
  );
2438
2566
  }
@@ -2455,7 +2583,7 @@ function parseRangeInputValue(value, mode, removePlaceholder) {
2455
2583
  isHalfEmpty: endDate === void 0
2456
2584
  };
2457
2585
  }
2458
- function swapMode(inputString, previousMode, mode) {
2586
+ function swapMode$1(inputString, previousMode, mode) {
2459
2587
  const halves = inputString.split(RANGE_SEPARATOR);
2460
2588
  const segments = halves.map((half) => half.split("/"));
2461
2589
  let startDay, startMonth, startYear, endDay, endMonth, endYear;
@@ -2506,6 +2634,8 @@ const NormalizedDateFieldRange = forwardRef(
2506
2634
  minDate,
2507
2635
  maxDate,
2508
2636
  required = false,
2637
+ onFocus,
2638
+ onBlur,
2509
2639
  ...rest
2510
2640
  }, ref) => {
2511
2641
  const inputRef = useRef(null);
@@ -2531,11 +2661,12 @@ const NormalizedDateFieldRange = forwardRef(
2531
2661
  handleCalendarKeyDown,
2532
2662
  handleInputKeyDown
2533
2663
  } = useDateFieldOrchestration({
2534
- inputRef: { current: null },
2664
+ inputRef,
2535
2665
  calendarDefaultOpen: false,
2536
2666
  popoverContentRef,
2537
2667
  disableCalendar
2538
2668
  });
2669
+ const shouldShowCalendar = usePopoverCloseDelayWorkaround(calendarOpen);
2539
2670
  const isDateRangeValid = useMemo(() => {
2540
2671
  return validateDate({
2541
2672
  date: startDate ?? null,
@@ -2650,6 +2781,7 @@ const NormalizedDateFieldRange = forwardRef(
2650
2781
  open: calendarOpen,
2651
2782
  modal: true,
2652
2783
  placement: "bottom-start",
2784
+ disableFlipFallback: true,
2653
2785
  disableTriggerFocus: true,
2654
2786
  onClose: () => setCalendarOpen(false),
2655
2787
  disableAutoUpdate: true,
@@ -2659,7 +2791,7 @@ const NormalizedDateFieldRange = forwardRef(
2659
2791
  setPopoverTriggerRef(iRef);
2660
2792
  return justTheField;
2661
2793
  } }),
2662
- /* @__PURE__ */ jsx(Popover.Content, { ref: popoverContentRef, "data-calendar-popover": true, children: /* @__PURE__ */ jsx(
2794
+ /* @__PURE__ */ jsx(Popover.Content, { ref: popoverContentRef, "data-testid": "calendar-popover", children: shouldShowCalendar && /* @__PURE__ */ jsx(
2663
2795
  Calendar,
2664
2796
  {
2665
2797
  range: true,
@@ -2710,8 +2842,27 @@ const DateFieldRange = ({
2710
2842
  minDate,
2711
2843
  maxDate,
2712
2844
  unavailable,
2845
+ onChange,
2846
+ onFocus,
2847
+ onBlur,
2713
2848
  ...rest
2714
2849
  }) => {
2850
+ const handleBlur = useCallback(
2851
+ (event) => {
2852
+ onBlur?.(event);
2853
+ },
2854
+ [onBlur]
2855
+ );
2856
+ const handleFocus = useCallback(
2857
+ (event) => {
2858
+ onFocus?.(event);
2859
+ },
2860
+ [onFocus]
2861
+ );
2862
+ const { ref: wrapperRef } = useFocusWithin({
2863
+ onBlur: handleBlur,
2864
+ onFocus: handleFocus
2865
+ });
2715
2866
  const normalizedValue = useMemo(
2716
2867
  () => value !== void 0 ? {
2717
2868
  startDate: convertStringToDate(value?.startDate ?? null) ?? null,
@@ -2738,7 +2889,11 @@ const DateFieldRange = ({
2738
2889
  () => unavailable?.dates?.map((d) => convertStringToDate(d)).filter((d) => d !== null && d !== void 0),
2739
2890
  [unavailable?.dates]
2740
2891
  );
2741
- return /* @__PURE__ */ jsx(
2892
+ const handleChange = useConditionalChange({
2893
+ changeHandler: onChange,
2894
+ compareFn: (a, b) => a.isInputValid !== b.isInputValid || a.isInputEmpty !== b.isInputEmpty || a.isDateRangeValid !== b.isDateRangeValid || a.startDate !== b.startDate || a.endDate !== b.endDate
2895
+ });
2896
+ return /* @__PURE__ */ jsx("div", { ref: wrapperRef, children: /* @__PURE__ */ jsx(
2742
2897
  NormalizedDateFieldRange,
2743
2898
  {
2744
2899
  ...rest,
@@ -2749,11 +2904,222 @@ const DateFieldRange = ({
2749
2904
  unavailable: unavailable ? {
2750
2905
  dates: normalizedUnavailableDates,
2751
2906
  daysOfWeek: unavailable?.daysOfWeek
2752
- } : void 0
2907
+ } : void 0,
2908
+ onChange: handleChange
2753
2909
  }
2754
- );
2910
+ ) });
2755
2911
  };
2756
2912
  DateFieldRange.displayName = "DateFieldRange";
2757
2913
 
2758
- export { DateFieldRange as D, DateFieldSingle as a };
2759
- //# sourceMappingURL=DateFieldRange-DtppOifM-DZvtSHar.js.map
2914
+ const yearlessDatePlaceholderMask = ({
2915
+ mode,
2916
+ separator = "/",
2917
+ placeholder
2918
+ }) => {
2919
+ const dateOptions = maskitoDateOptionsGenerator({
2920
+ mode,
2921
+ separator
2922
+ });
2923
+ const { plugins, removePlaceholder, ...placeholderOptions } = maskitoWithPlaceholder(placeholder);
2924
+ const datePlaceholderMask = {
2925
+ ...dateOptions,
2926
+ plugins: plugins.concat(dateOptions.plugins || []),
2927
+ preprocessors: [
2928
+ ...placeholderOptions.preprocessors,
2929
+ ...dateOptions.preprocessors,
2930
+ makeZeroShortcutPreprocessor(mode, separator)
2931
+ ],
2932
+ postprocessors: [
2933
+ ...dateOptions.postprocessors,
2934
+ ...placeholderOptions.postprocessors
2935
+ ]
2936
+ };
2937
+ return { options: datePlaceholderMask, removePlaceholder };
2938
+ };
2939
+
2940
+ const MaskedYearlessDateInput = forwardRef(({ onChange, mode = "mm/dd", value, disableHint = false, ...props }, ref) => {
2941
+ const placeholder = "__/__";
2942
+ const [inputValue, setInputValue] = useState(placeholder);
2943
+ const { options, removePlaceholder } = yearlessDatePlaceholderMask({
2944
+ mode,
2945
+ placeholder
2946
+ });
2947
+ const maskedInputRef = useMaskito({ options });
2948
+ const inputRef = useRef(null);
2949
+ const combinedRef = useMergeRefs$1([maskedInputRef, inputRef, ref]);
2950
+ const previousValue = usePrevious(value);
2951
+ const previousMode = usePrevious(mode);
2952
+ useEffect(() => {
2953
+ if (mode !== previousMode) {
2954
+ setInputValue(
2955
+ (oldInputValue) => swapMode(oldInputValue, previousMode ?? mode, mode)
2956
+ );
2957
+ }
2958
+ }, [mode, previousMode]);
2959
+ useEffect(() => {
2960
+ if (previousValue?.day !== value?.day || previousValue?.month !== value?.month) {
2961
+ if (value?.day && value?.month) {
2962
+ setInputValue(stringifyYearlessDate(value.day, value.month, mode));
2963
+ } else if (previousValue !== null && previousValue !== void 0 && (value === null || value?.day === null && value?.month === null)) {
2964
+ setInputValue(placeholder);
2965
+ } else {
2966
+ return;
2967
+ }
2968
+ }
2969
+ }, [value, mode, previousValue]);
2970
+ const currentParsedData = useMemo(() => {
2971
+ return parseInputValue(inputValue, mode, removePlaceholder);
2972
+ }, [inputValue, mode, removePlaceholder]);
2973
+ const handleChange = (event) => {
2974
+ setInputValue(event.target.value);
2975
+ const {
2976
+ value: v,
2977
+ isInputValid,
2978
+ isInputEmpty
2979
+ } = parseInputValue(event.target.value, mode, removePlaceholder);
2980
+ onChange?.({
2981
+ event,
2982
+ value: v ?? currentParsedData.value ?? null,
2983
+ isInputValid,
2984
+ isInputEmpty
2985
+ });
2986
+ };
2987
+ useImperativeHandle(ref, () => {
2988
+ const input = inputRef.current;
2989
+ if (!input) return null;
2990
+ return Object.assign(input, {
2991
+ setValue: (value2) => {
2992
+ if (!value2) {
2993
+ setInputValue(placeholder);
2994
+ return;
2995
+ }
2996
+ setInputValue(
2997
+ stringifyYearlessDate(value2.day ?? 1, value2.month ?? 1, mode)
2998
+ );
2999
+ }
3000
+ });
3001
+ }, [mode, placeholder]);
3002
+ return /* @__PURE__ */ jsx(
3003
+ TextField,
3004
+ {
3005
+ ref: combinedRef,
3006
+ "data-month-value": value?.month,
3007
+ "data-day-value": value?.day,
3008
+ "data-input-valid": currentParsedData.isInputValid,
3009
+ "data-input-empty": currentParsedData.isInputEmpty,
3010
+ ...props,
3011
+ showCounter: false,
3012
+ value: inputValue,
3013
+ onChange: handleChange,
3014
+ hint: disableHint ? void 0 : `Format: ${mode}`
3015
+ }
3016
+ );
3017
+ });
3018
+ MaskedYearlessDateInput.displayName = "MaskedYearlessDateInput";
3019
+ function parseInputValue(value, mode, removePlaceholder) {
3020
+ const valueMinusPlaceholder = removePlaceholder(value);
3021
+ const [segment1, segment2] = valueMinusPlaceholder.split("/");
3022
+ const incompleteFirstSegment = segment1?.length !== 2;
3023
+ const incompleteSecondSegment = segment2?.length !== 2;
3024
+ if (mode === "dd/mm") {
3025
+ return {
3026
+ value: {
3027
+ day: incompleteFirstSegment ? null : parseInt(segment1),
3028
+ month: incompleteSecondSegment ? null : parseInt(segment2)
3029
+ },
3030
+ isInputValid: !incompleteFirstSegment && !incompleteSecondSegment,
3031
+ isInputEmpty: valueMinusPlaceholder === ""
3032
+ };
3033
+ }
3034
+ return {
3035
+ value: {
3036
+ day: incompleteSecondSegment ? null : parseInt(segment2),
3037
+ month: incompleteFirstSegment ? null : parseInt(segment1)
3038
+ },
3039
+ isInputValid: !incompleteFirstSegment && !incompleteSecondSegment,
3040
+ isInputEmpty: valueMinusPlaceholder === ""
3041
+ };
3042
+ }
3043
+ function swapMode(inputString, previousMode, mode) {
3044
+ const { day, month } = divideSegments(inputString, previousMode);
3045
+ return stringifyYearlessDate(day, month, mode);
3046
+ }
3047
+ function divideSegments(value, mode) {
3048
+ const [segment1, segment2] = value.split("/");
3049
+ if (mode === "dd/mm") {
3050
+ return { day: segment1, month: segment2 };
3051
+ }
3052
+ return { day: segment2, month: segment1 };
3053
+ }
3054
+ function stringifyYearlessDate(day, month, mode) {
3055
+ const dd = day.toString().padStart(2, "0");
3056
+ const mm = month.toString().padStart(2, "0");
3057
+ if (mode === "dd/mm") {
3058
+ return `${dd}/${mm}`;
3059
+ }
3060
+ return `${mm}/${dd}`;
3061
+ }
3062
+
3063
+ const DateFieldYearless = ({
3064
+ value: valueProp,
3065
+ defaultValue: defaultValueProp,
3066
+ onChange,
3067
+ minDate,
3068
+ maxDate,
3069
+ unavailable,
3070
+ required,
3071
+ ...restProps
3072
+ }) => {
3073
+ const [value, setValue] = useOptionallyControlledState({
3074
+ controlledValue: valueProp,
3075
+ defaultValue: defaultValueProp
3076
+ });
3077
+ const currentValidity = useMemo(
3078
+ () => validateYearlessDate({
3079
+ value: value ?? null,
3080
+ constraints: {
3081
+ required,
3082
+ unavailable,
3083
+ minDate,
3084
+ maxDate
3085
+ }
3086
+ }),
3087
+ [value, required, unavailable, minDate, maxDate]
3088
+ );
3089
+ const conditionalChange = useConditionalChange({
3090
+ changeHandler: onChange,
3091
+ compareFn: (a, b) => a.isInputValid !== b.isInputValid || a.isInputEmpty !== b.isInputEmpty || a.isValid !== b.isValid || a.value?.day !== b.value?.day || a.value?.month !== b.value?.month
3092
+ });
3093
+ const handleInputChange = (change) => {
3094
+ const { event, value: value2, ...restChange } = change;
3095
+ setValue(value2);
3096
+ return conditionalChange({
3097
+ ...restChange,
3098
+ value: value2,
3099
+ isValid: validateYearlessDate({
3100
+ value: value2,
3101
+ constraints: {
3102
+ required,
3103
+ unavailable,
3104
+ minDate,
3105
+ maxDate
3106
+ }
3107
+ })
3108
+ });
3109
+ };
3110
+ return /* @__PURE__ */ jsx(
3111
+ MaskedYearlessDateInput,
3112
+ {
3113
+ required,
3114
+ ...restProps,
3115
+ autoComplete: "off",
3116
+ onChange: handleInputChange,
3117
+ value,
3118
+ "data-valid": currentValidity
3119
+ }
3120
+ );
3121
+ };
3122
+ DateFieldYearless.displayName = "DateFieldYearless";
3123
+
3124
+ export { DateFieldRange as D, DateFieldSingle as a, DateFieldYearless as b };
3125
+ //# sourceMappingURL=DateFieldYearless-CJP3H_Dg-BV5wGJp1.js.map