@servicetitan/anvil2 1.45.2 → 1.46.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/{Calendar-BK861SAW.js → Calendar-BQ5F2ENO.js} +2 -2
- package/dist/{Calendar-BK861SAW.js.map → Calendar-BQ5F2ENO.js.map} +1 -1
- package/dist/Calendar.js +1 -1
- package/dist/{Checkbox-ZphVb1l0.js → Checkbox-DDrmVC-u.js} +2 -2
- package/dist/{Checkbox-ZphVb1l0.js.map → Checkbox-DDrmVC-u.js.map} +1 -1
- package/dist/{Checkbox-CYNjFdtO.js → Checkbox-Dl4KTwEJ.js} +2 -2
- package/dist/{Checkbox-CYNjFdtO.js.map → Checkbox-Dl4KTwEJ.js.map} +1 -1
- package/dist/Checkbox.js +2 -2
- package/dist/{useInfiniteCombobox-BaYWUxjg.js → Combobox-B9nesJuc.js} +18 -185
- package/dist/Combobox-B9nesJuc.js.map +1 -0
- package/dist/Combobox.js +2 -1
- package/dist/Combobox.js.map +1 -1
- package/dist/{DateField-DnasO2rB.js → DateField-DXxPsRtf.js} +2 -2
- package/dist/{DateField-DnasO2rB.js.map → DateField-DXxPsRtf.js.map} +1 -1
- package/dist/DateField.js +1 -1
- package/dist/{DateFieldRange-Ba-8T-Nz.js → DateFieldRange-Xauviu1w.js} +6 -6
- package/dist/DateFieldRange-Xauviu1w.js.map +1 -0
- package/dist/DateFieldRange.js +1 -1
- package/dist/{DateFieldSingle-BBu5Hi9c.js → DateFieldSingle-yLnwpVzd.js} +4 -4
- package/dist/{DateFieldSingle-BBu5Hi9c.js.map → DateFieldSingle-yLnwpVzd.js.map} +1 -1
- package/dist/DateFieldSingle.js +1 -1
- package/dist/Dnd.js +1 -1
- package/dist/DndSort.js +1 -1
- package/dist/{ListView-DEAMQopB.js → ListView-pb3rIcze.js} +2 -2
- package/dist/{ListView-DEAMQopB.js.map → ListView-pb3rIcze.js.map} +1 -1
- package/dist/ListView.js +1 -1
- package/dist/{Menu-C8we5CHP.js → Menu-DEVZz9xZ.js} +8 -3
- package/dist/Menu-DEVZz9xZ.js.map +1 -0
- package/dist/Menu.js +1 -1
- package/dist/{Page-cKXkjMmd.js → Page-BMDkbDcU.js} +2 -2
- package/dist/{Page-cKXkjMmd.js.map → Page-BMDkbDcU.js.map} +1 -1
- package/dist/Page.js +1 -1
- package/dist/{Pagination-ta8a2cJN.js → Pagination-BJsCppgW.js} +2 -2
- package/dist/{Pagination-ta8a2cJN.js.map → Pagination-BJsCppgW.js.map} +1 -1
- package/dist/Pagination.js +1 -1
- package/dist/{SearchField-BKXkoWPs.js → SearchField-Bb0uObwG.js} +2 -2
- package/dist/{SearchField-BKXkoWPs.js.map → SearchField-Bb0uObwG.js.map} +1 -1
- package/dist/SearchField.js +1 -1
- package/dist/{SelectCard-BWh8Yp7T.js → SelectCard-BTYZg9TG.js} +2 -2
- package/dist/{SelectCard-BWh8Yp7T.js.map → SelectCard-BTYZg9TG.js.map} +1 -1
- package/dist/SelectCard.js +1 -1
- package/dist/Toolbar-D4zuUFhb.js +2077 -0
- package/dist/Toolbar-D4zuUFhb.js.map +1 -0
- package/dist/Toolbar.css +139 -28
- package/dist/Toolbar.d.ts +3 -3
- package/dist/Toolbar.js +1 -1
- package/dist/assets/icons/st/gnav_legacy_search_filled.svg +1 -1
- package/dist/assets/icons/st/gnav_legacy_search_outline.svg +1 -1
- package/dist/beta/components/Toolbar/Filters/FilterButton.d.ts +30 -0
- package/dist/beta/components/Toolbar/Filters/FilterDateRange.d.ts +37 -0
- package/dist/beta/components/Toolbar/Filters/FilterDateSingle.d.ts +30 -0
- package/dist/beta/components/Toolbar/Filters/FilterDrawer.d.ts +15 -0
- package/dist/beta/components/Toolbar/Filters/FilterGroup.d.ts +25 -0
- package/dist/beta/components/Toolbar/Filters/FilterItemWrapper.d.ts +24 -0
- package/dist/beta/components/Toolbar/Filters/FilterSelect.d.ts +29 -0
- package/dist/beta/components/Toolbar/Filters/FilterToggleButton.d.ts +24 -0
- package/dist/beta/components/Toolbar/Filters/internal/FilterGroupContext.d.ts +40 -0
- package/dist/beta/components/Toolbar/Filters/internal/types.d.ts +130 -0
- package/dist/beta/components/Toolbar/Filters/internal/utils/filter-state.d.ts +40 -0
- package/dist/beta/components/Toolbar/Filters/internal/utils/test.d.ts +57 -0
- package/dist/beta/components/Toolbar/Toolbar.d.ts +302 -0
- package/dist/beta/components/Toolbar/ToolbarButton.d.ts +41 -0
- package/dist/beta/components/Toolbar/ToolbarButtonLink.d.ts +43 -0
- package/dist/beta/components/Toolbar/ToolbarButtonToggle.d.ts +42 -0
- package/dist/beta/components/Toolbar/ToolbarControlGroup.d.ts +20 -0
- package/dist/beta/components/Toolbar/ToolbarSearchField.d.ts +20 -0
- package/dist/beta/components/Toolbar/ToolbarSelect.d.ts +108 -0
- package/dist/beta/components/Toolbar/index.d.ts +9 -0
- package/dist/beta/components/Toolbar/internal/ToolbarItemOverflowContext.d.ts +19 -0
- package/dist/beta/components/Toolbar/internal/ToolbarItemWrapper.d.ts +40 -0
- package/dist/beta/components/Toolbar/internal/ToolbarOverflowContext.d.ts +35 -0
- package/dist/beta/components/Toolbar/internal/ToolbarOverflowMenu.d.ts +29 -0
- package/dist/beta/components/Toolbar/internal/utils/accessibility.d.ts +26 -0
- package/dist/beta/components/Toolbar/internal/utils/test.d.ts +29 -0
- package/dist/beta/components/Toolbar/types.d.ts +50 -0
- package/dist/beta/components/index.d.ts +1 -0
- package/dist/beta/index.d.ts +1 -0
- package/dist/beta.d.ts +2 -0
- package/dist/beta.js +2 -0
- package/dist/beta.js.map +1 -0
- package/dist/components/Combobox/ComboboxTypes.d.ts +8 -0
- package/dist/components/DateFieldRange/internal/DateFieldRangeCalendar.d.ts +1 -1
- package/dist/components/Dialog/index.d.ts +1 -1
- package/dist/{indeterminate_check_box-Bg24oeHy.js → indeterminate_check_box-RY9zr3xS.js} +17 -17
- package/dist/{indeterminate_check_box-Bg24oeHy.js.map → indeterminate_check_box-RY9zr3xS.js.map} +1 -1
- package/dist/indeterminate_check_box.css +72 -66
- package/dist/{index-CqdP5W00.js → index-V5Ez2gq_.js} +2 -2
- package/dist/{index-CqdP5W00.js.map → index-V5Ez2gq_.js.map} +1 -1
- package/dist/index.css +125 -26
- package/dist/index.js +759 -27
- package/dist/index.js.map +1 -1
- package/dist/index2.css +88 -105
- package/dist/internal/hooks/index.d.ts +1 -0
- package/dist/internal/hooks/useContainerQuery/index.d.ts +1 -0
- package/dist/internal/hooks/useContainerQuery/useContainerQuery.d.ts +46 -0
- package/dist/{useDateFieldOrchestration-DPLftOxu.js → useDateFieldOrchestration-BNJCsRkS.js} +2 -2
- package/dist/{useDateFieldOrchestration-DPLftOxu.js.map → useDateFieldOrchestration-BNJCsRkS.js.map} +1 -1
- package/dist/useInfiniteCombobox-WcRgC9p6.js +179 -0
- package/dist/useInfiniteCombobox-WcRgC9p6.js.map +1 -0
- package/dist/useIntersectionObserver-BEmMDO3P.js +70 -0
- package/dist/useIntersectionObserver-BEmMDO3P.js.map +1 -0
- package/package.json +2 -1
- package/dist/DateFieldRange-Ba-8T-Nz.js.map +0 -1
- package/dist/Menu-C8we5CHP.js.map +0 -1
- package/dist/Toolbar-DK7tXy_W.js +0 -807
- package/dist/Toolbar-DK7tXy_W.js.map +0 -1
- package/dist/useInfiniteCombobox-BaYWUxjg.js.map +0 -1
- /package/dist/{useInfiniteCombobox.css → Combobox.css} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useContainerQuery, type ContainerQueryReturnProps, } from './useContainerQuery';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Return type for the useContainerQuery hook
|
|
4
|
+
*/
|
|
5
|
+
export type ContainerQueryReturnProps = {
|
|
6
|
+
/**
|
|
7
|
+
* The breakpoint name
|
|
8
|
+
*/
|
|
9
|
+
name: "xs" | "sm" | "md" | "lg" | "xl" | "xxl";
|
|
10
|
+
/**
|
|
11
|
+
* Minimum width for this breakpoint
|
|
12
|
+
*/
|
|
13
|
+
min: number | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Maximum width for this breakpoint
|
|
16
|
+
*/
|
|
17
|
+
max: number | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Current container width
|
|
20
|
+
*/
|
|
21
|
+
containerWidth: number;
|
|
22
|
+
/**
|
|
23
|
+
* Current container height
|
|
24
|
+
*/
|
|
25
|
+
containerHeight: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Custom hook for detecting current breakpoint based on container dimensions.
|
|
29
|
+
*
|
|
30
|
+
* Features:
|
|
31
|
+
* - Detects current breakpoint based on container width instead of viewport width
|
|
32
|
+
* - Supports all standard breakpoints (xs, sm, md, lg, xl, xxl)
|
|
33
|
+
* - Provides container dimensions information
|
|
34
|
+
* - Uses hammer-token breakpoint values for consistency
|
|
35
|
+
* - Listens for container resize events using ResizeObserver
|
|
36
|
+
* - Supports optional disable functionality
|
|
37
|
+
* - Uses container element dimensions for accurate measurements
|
|
38
|
+
*
|
|
39
|
+
* @param containerRef - React ref to the container element to observe
|
|
40
|
+
* @param props - Optional configuration object
|
|
41
|
+
* @param props.disable - Whether to disable the hook
|
|
42
|
+
* @returns Current breakpoint information or undefined if disabled
|
|
43
|
+
*/
|
|
44
|
+
export declare const useContainerQuery: (containerRef: RefObject<HTMLElement>, props?: {
|
|
45
|
+
disable?: boolean;
|
|
46
|
+
}) => ContainerQueryReturnProps | undefined;
|
package/dist/{useDateFieldOrchestration-DPLftOxu.js → useDateFieldOrchestration-BNJCsRkS.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as DateTime } from './Calendar-
|
|
1
|
+
import { D as DateTime } from './Calendar-BQ5F2ENO.js';
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
3
|
import { a as useKeyboardFocusables } from './useOnClickOutside-BHEWMLa9.js';
|
|
4
4
|
|
|
@@ -135,4 +135,4 @@ const useDateFieldOrchestration = ({
|
|
|
135
135
|
};
|
|
136
136
|
|
|
137
137
|
export { DateModeToPlaceholderMap as D, DateModeToFormatMap as a, convertStringToDate as c, useDateFieldOrchestration as u, validateDate as v };
|
|
138
|
-
//# sourceMappingURL=useDateFieldOrchestration-
|
|
138
|
+
//# sourceMappingURL=useDateFieldOrchestration-BNJCsRkS.js.map
|
package/dist/{useDateFieldOrchestration-DPLftOxu.js.map → useDateFieldOrchestration-BNJCsRkS.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDateFieldOrchestration-
|
|
1
|
+
{"version":3,"file":"useDateFieldOrchestration-BNJCsRkS.js","sources":["../src/components/DateFieldSingle/internal/constants.ts","../src/components/DateFieldSingle/internal/utils.ts","../src/components/DateFieldSingle/internal/useDateFieldOrchestration.ts"],"sourcesContent":["import { DateMode } from \"../types\";\n\nexport const DateModeToFormatMap: Record<DateMode, string> = {\n \"mm/dd/yyyy\": \"MM/dd/yyyy\",\n \"dd/mm/yyyy\": \"dd/MM/yyyy\",\n \"yyyy/mm/dd\": \"yyyy/MM/dd\",\n};\n\nexport const DateModeToPlaceholderMap: Record<DateMode, string> = {\n \"dd/mm/yyyy\": \"__/__/____\",\n \"mm/dd/yyyy\": \"__/__/____\",\n \"yyyy/mm/dd\": \"____/__/__\",\n};\n","import { DateTime } from \"luxon\";\n\nexport function convertStringToDate(\n v: string | null | undefined,\n): DateTime | null | undefined {\n if (v === undefined || v === null) {\n return v;\n }\n const date = DateTime.fromISO(v, { setZone: true, zone: \"utc\" }).startOf(\n \"day\",\n );\n if (date.isValid) {\n return date;\n }\n return null;\n}\nexport function validateDate({\n date,\n constraints,\n}: {\n date: DateTime | null;\n constraints: {\n required?: boolean;\n unavailable?: {\n dates?: DateTime[];\n daysOfWeek?: number[];\n };\n minDate?: DateTime;\n maxDate?: DateTime;\n };\n}) {\n const { required, unavailable, minDate, maxDate } = constraints;\n if (!date) {\n return required ? false : true;\n }\n if (unavailable?.dates?.some((d) => d.equals(date))) {\n return false;\n }\n if (unavailable?.daysOfWeek?.includes(date.weekday)) {\n return false;\n }\n if (minDate && date < minDate) {\n return false;\n }\n if (maxDate && date > maxDate) {\n return false;\n }\n return true;\n}\n","import { KeyboardEventHandler, RefObject, useRef, useState } from \"react\";\nimport { useKeyboardFocusables } from \"../../../internal/hooks\";\n\n/**\n * Responsible for orchestrating the input and calendar popover states\n * @param inputRef - The ref to the input element\n * @returns calendarOpen, setCalendarOpen, handleCalendarKeyDown, handleInputKeyDown\n */\nexport const useDateFieldOrchestration = ({\n inputRef,\n calendarDefaultOpen,\n popoverContentRef,\n disableCalendar = false,\n}: {\n inputRef: RefObject<HTMLInputElement>;\n calendarDefaultOpen: boolean;\n popoverContentRef: RefObject<HTMLDivElement>;\n disableCalendar?: boolean;\n}) => {\n const documentRef = useRef<HTMLElement>(document.body);\n const [calendarOpen, setCalendarOpen] = useState(calendarDefaultOpen);\n\n const { focusables } = useKeyboardFocusables(documentRef, {\n observeChange: true,\n });\n\n const { focusables: popoverFocusables } = useKeyboardFocusables(\n popoverContentRef,\n {\n observeChange: true,\n },\n );\n\n const pageFocusables = focusables?.filter(\n (item) => !popoverFocusables?.includes(item),\n );\n\n const handleCalendarKeyDown = (\n event: React.KeyboardEvent<HTMLDivElement>,\n ) => {\n if (event.key === \"Escape\") {\n inputRef.current?.focus();\n }\n };\n\n const focusToCalendar = () => {\n if (popoverContentRef.current) {\n const currentFocusable =\n popoverContentRef.current.querySelectorAll('[tabindex = \"0\"]')[0];\n if (currentFocusable) {\n (currentFocusable as HTMLButtonElement).focus();\n }\n }\n };\n\n const handleInputKeyDown: KeyboardEventHandler<HTMLInputElement> = (ev) => {\n if (disableCalendar) {\n return;\n }\n let currentFocusIndex = 0;\n switch (ev.key) {\n case \"Escape\":\n setCalendarOpen(false);\n break;\n case \"Tab\":\n if (!calendarOpen || !pageFocusables?.length) {\n break;\n }\n ev.preventDefault();\n currentFocusIndex = pageFocusables.indexOf(inputRef.current!) || 0;\n setCalendarOpen(false);\n if (ev.shiftKey) {\n if (currentFocusIndex === 0) {\n requestAnimationFrame(() =>\n pageFocusables[pageFocusables.length - 1].focus(),\n );\n } else {\n requestAnimationFrame(() =>\n pageFocusables[currentFocusIndex - 1].focus(),\n );\n }\n break;\n }\n if (pageFocusables.length > currentFocusIndex + 1) {\n requestAnimationFrame(() =>\n pageFocusables[currentFocusIndex + 1].focus(),\n );\n } else {\n requestAnimationFrame(() => pageFocusables[0].focus());\n }\n break;\n case \"ArrowDown\":\n if (!calendarOpen) {\n setCalendarOpen(true);\n setTimeout(focusToCalendar, 200);\n } else {\n focusToCalendar();\n }\n }\n };\n\n return {\n calendarOpen,\n setCalendarOpen,\n handleCalendarKeyDown,\n handleInputKeyDown,\n };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { useState, useDeferredValue, useRef, useEffect, useLayoutEffect, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
const SCROLL_THRESHOLD = 0.64;
|
|
4
|
+
function useInfiniteCombobox({
|
|
5
|
+
query,
|
|
6
|
+
queryInitialItems,
|
|
7
|
+
initialItems = [],
|
|
8
|
+
initialPage = 0,
|
|
9
|
+
initialLoading = false,
|
|
10
|
+
initialInputValue,
|
|
11
|
+
defaultInputValue,
|
|
12
|
+
initialSelectedItem,
|
|
13
|
+
defaultSelectedItem,
|
|
14
|
+
initialSelectedItems,
|
|
15
|
+
defaultSelectedItems,
|
|
16
|
+
updateOnInputValueChange = true,
|
|
17
|
+
updateOnSelectedItemChange = true,
|
|
18
|
+
updateOnSelectedItemsChange = true,
|
|
19
|
+
queryOnFirstRender = false,
|
|
20
|
+
shouldTriggerQuery: shouldTriggerQueryProp
|
|
21
|
+
}) {
|
|
22
|
+
const [items, setItems] = useState(initialItems);
|
|
23
|
+
const deferredItems = useDeferredValue(items);
|
|
24
|
+
const [page, setPage] = useState(initialPage);
|
|
25
|
+
const [loading, setLoading] = useState(initialLoading);
|
|
26
|
+
const deferredLoading = useDeferredValue(loading);
|
|
27
|
+
const [inputValue, setInputValue] = useState(
|
|
28
|
+
initialInputValue ?? defaultInputValue ?? ""
|
|
29
|
+
);
|
|
30
|
+
const [selectedItem, setSelectedItem] = useState(
|
|
31
|
+
initialSelectedItem ?? defaultSelectedItem ?? null
|
|
32
|
+
);
|
|
33
|
+
const [selectedItems, setSelectedItems] = useState(
|
|
34
|
+
initialSelectedItems ?? defaultSelectedItems ?? []
|
|
35
|
+
);
|
|
36
|
+
const scrollerRef = useRef(null);
|
|
37
|
+
const defaultShouldTriggerQuery = (element) => {
|
|
38
|
+
const totalScrollHeight = element.scrollHeight - element.clientHeight;
|
|
39
|
+
return element.scrollTop / totalScrollHeight > SCROLL_THRESHOLD;
|
|
40
|
+
};
|
|
41
|
+
const [triggerQueryCount, setTriggerQueryCount] = useState(0);
|
|
42
|
+
const triggerQueryCountRef = useRef(0);
|
|
43
|
+
const triggerQuery = () => {
|
|
44
|
+
setTriggerQueryCount((x) => x + 1);
|
|
45
|
+
triggerQueryCountRef.current += 1;
|
|
46
|
+
};
|
|
47
|
+
const [done, setDone] = useState(false);
|
|
48
|
+
const firstRenderRef = useRef(true);
|
|
49
|
+
const scrollTimeoutRef = useRef(false);
|
|
50
|
+
const loadingRef = useRef(false);
|
|
51
|
+
const setLoadingStateAndRef = (isLoading) => {
|
|
52
|
+
setLoading(isLoading);
|
|
53
|
+
loadingRef.current = isLoading;
|
|
54
|
+
};
|
|
55
|
+
const queryRetryCountRef = useRef(0);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (firstRenderRef.current && queryInitialItems) {
|
|
58
|
+
setItems(queryInitialItems());
|
|
59
|
+
}
|
|
60
|
+
if (firstRenderRef.current && !queryOnFirstRender) {
|
|
61
|
+
firstRenderRef.current = false;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
setLoadingStateAndRef(true);
|
|
65
|
+
const timeoutID = setTimeout(() => {
|
|
66
|
+
if (triggerQueryCount < triggerQueryCountRef.current) return;
|
|
67
|
+
query({
|
|
68
|
+
page,
|
|
69
|
+
inputValue,
|
|
70
|
+
selectedItem,
|
|
71
|
+
selectedItems
|
|
72
|
+
}).then((res) => {
|
|
73
|
+
queryRetryCountRef.current = 0;
|
|
74
|
+
if (triggerQueryCount < triggerQueryCountRef.current) return;
|
|
75
|
+
setLoadingStateAndRef(false);
|
|
76
|
+
setPage((x) => x + 1);
|
|
77
|
+
if (res == null || page > 0 && res.length === 0) {
|
|
78
|
+
setDone(true);
|
|
79
|
+
} else if (page === 0) {
|
|
80
|
+
setItems(() => [...res]);
|
|
81
|
+
} else {
|
|
82
|
+
setItems((prevItems) => [...prevItems, ...res]);
|
|
83
|
+
}
|
|
84
|
+
}).catch(() => {
|
|
85
|
+
queryRetryCountRef.current += 1;
|
|
86
|
+
if (queryRetryCountRef.current > 7) {
|
|
87
|
+
queryRetryCountRef.current = 0;
|
|
88
|
+
return;
|
|
89
|
+
} else {
|
|
90
|
+
setTimeout(
|
|
91
|
+
() => {
|
|
92
|
+
triggerQuery();
|
|
93
|
+
},
|
|
94
|
+
2 ** queryRetryCountRef.current * 160
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}, 160);
|
|
99
|
+
return () => {
|
|
100
|
+
clearTimeout(timeoutID);
|
|
101
|
+
};
|
|
102
|
+
}, [triggerQueryCount]);
|
|
103
|
+
useLayoutEffect(() => {
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
if (scrollerRef.current && scrollerRef.current.scrollHeight > 0 && scrollerRef.current.clientHeight > 0 && scrollerRef.current.scrollHeight <= scrollerRef.current.clientHeight) {
|
|
106
|
+
triggerQuery();
|
|
107
|
+
}
|
|
108
|
+
}, 160);
|
|
109
|
+
}, [items]);
|
|
110
|
+
const isEmpty = items.length === 0 && page === 0;
|
|
111
|
+
const onStateChange = useCallback(
|
|
112
|
+
(changes) => {
|
|
113
|
+
if (isEmpty && "isOpen" in changes && changes.isOpen === true) {
|
|
114
|
+
triggerQuery();
|
|
115
|
+
}
|
|
116
|
+
const inputValueShouldUpdate = updateOnInputValueChange && "inputValue" in changes;
|
|
117
|
+
const selectedItemsShouldUpdate = updateOnSelectedItemsChange && "selectedItems" in changes && changes.selectedItems;
|
|
118
|
+
const selectedItemShouldUpdate = updateOnSelectedItemChange && "selectedItem" in changes && changes.selectedItem !== void 0;
|
|
119
|
+
if (inputValueShouldUpdate) {
|
|
120
|
+
setInputValue(changes.inputValue ?? "");
|
|
121
|
+
}
|
|
122
|
+
if (selectedItemsShouldUpdate) {
|
|
123
|
+
setSelectedItems(changes.selectedItems ?? []);
|
|
124
|
+
}
|
|
125
|
+
if (selectedItemShouldUpdate) {
|
|
126
|
+
setSelectedItem(changes.selectedItem);
|
|
127
|
+
}
|
|
128
|
+
if (inputValueShouldUpdate || selectedItemsShouldUpdate || selectedItemShouldUpdate) {
|
|
129
|
+
setPage(0);
|
|
130
|
+
setDone(false);
|
|
131
|
+
triggerQuery();
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
[
|
|
135
|
+
isEmpty,
|
|
136
|
+
updateOnInputValueChange,
|
|
137
|
+
updateOnSelectedItemsChange,
|
|
138
|
+
updateOnSelectedItemChange
|
|
139
|
+
]
|
|
140
|
+
);
|
|
141
|
+
const onScroll = useCallback(
|
|
142
|
+
(e) => {
|
|
143
|
+
const element = e.currentTarget;
|
|
144
|
+
if (!scrollTimeoutRef.current && !loadingRef.current) {
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
const shouldTriggerQuery = shouldTriggerQueryProp ?? defaultShouldTriggerQuery;
|
|
147
|
+
if (shouldTriggerQuery(element) && !done) {
|
|
148
|
+
triggerQuery();
|
|
149
|
+
}
|
|
150
|
+
scrollTimeoutRef.current = false;
|
|
151
|
+
}, 40);
|
|
152
|
+
scrollTimeoutRef.current = true;
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
[done, shouldTriggerQueryProp]
|
|
156
|
+
);
|
|
157
|
+
return {
|
|
158
|
+
comboboxProps: {
|
|
159
|
+
items: deferredItems,
|
|
160
|
+
loading: deferredLoading,
|
|
161
|
+
initialInputValue,
|
|
162
|
+
defaultInputValue,
|
|
163
|
+
initialSelectedItem,
|
|
164
|
+
defaultSelectedItem,
|
|
165
|
+
initialSelectedItems,
|
|
166
|
+
defaultSelectedItems,
|
|
167
|
+
disableFilter: true,
|
|
168
|
+
// assume the query will return a filtered/sorted list
|
|
169
|
+
onStateChange
|
|
170
|
+
},
|
|
171
|
+
contentProps: {
|
|
172
|
+
onScroll,
|
|
173
|
+
scrollerRef
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { useInfiniteCombobox as u };
|
|
179
|
+
//# sourceMappingURL=useInfiniteCombobox-WcRgC9p6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInfiniteCombobox-WcRgC9p6.js","sources":["../src/components/Combobox/useInfiniteCombobox.ts"],"sourcesContent":["import {\n useState,\n useEffect,\n useLayoutEffect,\n useRef,\n useDeferredValue,\n type UIEvent,\n useCallback,\n} from \"react\";\nimport { UseInfiniteComboboxProps, type ComboboxProps } from \"./ComboboxTypes\";\n\nconst SCROLL_THRESHOLD = 0.64; // arbitrary number\n\n/**\n * Hook for implementing infinite scroll functionality in combobox components.\n *\n * Features:\n * - Automatic pagination with scroll-based loading\n * - Configurable query triggers (input change, selection change, scroll)\n * - Debounced query execution to prevent excessive API calls\n * - Automatic retry logic with exponential backoff\n * - Support for both single and multiple selection modes\n * - Customizable scroll threshold for triggering new queries\n * - Loading state management with deferred updates\n * - Automatic detection of pagination end\n * - Support for initial items or query-based initialization\n *\n * @param options Configuration options for the infinite combobox\n * @returns Object containing comboboxProps and contentProps for use with Combobox component\n *\n * @example\n * const { comboboxProps, contentProps } = useInfiniteCombobox({\n * initialItems: [],\n * initialPage: 0,\n * initialLoading: true,\n * query: async ({ page, inputValue, selectedItems }) => {\n * return await fetchItems({\n * page,\n * pageSize: 25,\n * searchTerm: inputValue,\n * excludeIds: selectedItems.map(item => item.id),\n * });\n * },\n * });\n *\n * return (\n * <Combobox {...comboboxProps}>\n * <Combobox.SearchField label=\"Search items\" />\n * <Combobox.Content {...contentProps}>\n * {({ items }) => (\n * <Combobox.List>\n * {items.map((item, i) => (\n * <Combobox.Item key={item.id} item={item} index={i}>\n * {item.name}\n * </Combobox.Item>\n * ))}\n * </Combobox.List>\n * )}\n * </Combobox.Content>\n * </Combobox>\n * );\n */\nexport function useInfiniteCombobox<Item = any>({\n query,\n queryInitialItems,\n initialItems = [],\n initialPage = 0,\n initialLoading = false,\n initialInputValue,\n defaultInputValue,\n initialSelectedItem,\n defaultSelectedItem,\n initialSelectedItems,\n defaultSelectedItems,\n updateOnInputValueChange = true,\n updateOnSelectedItemChange = true,\n updateOnSelectedItemsChange = true,\n queryOnFirstRender = false,\n shouldTriggerQuery: shouldTriggerQueryProp,\n}: UseInfiniteComboboxProps<Item>) {\n const [items, setItems] = useState(initialItems);\n const deferredItems = useDeferredValue(items);\n const [page, setPage] = useState(initialPage);\n const [loading, setLoading] = useState(initialLoading);\n const deferredLoading = useDeferredValue(loading);\n const [inputValue, setInputValue] = useState(\n initialInputValue ?? defaultInputValue ?? \"\",\n );\n const [selectedItem, setSelectedItem] = useState<Item | null>(\n initialSelectedItem ?? defaultSelectedItem ?? null,\n );\n const [selectedItems, setSelectedItems] = useState<Item[]>(\n initialSelectedItems ?? defaultSelectedItems ?? [],\n );\n\n const scrollerRef = useRef<HTMLDivElement>(null);\n\n const defaultShouldTriggerQuery = (element: EventTarget & HTMLElement) => {\n const totalScrollHeight = element.scrollHeight - element.clientHeight;\n return element.scrollTop / totalScrollHeight > SCROLL_THRESHOLD;\n };\n\n // using both state and ref here since the state will be \"behind\" the ref\n // if another query has been triggered while the current one is in flight\n const [triggerQueryCount, setTriggerQueryCount] = useState(0);\n const triggerQueryCountRef = useRef(0);\n const triggerQuery = () => {\n setTriggerQueryCount((x) => x + 1);\n triggerQueryCountRef.current += 1;\n };\n\n const [done, setDone] = useState(false);\n\n const firstRenderRef = useRef(true);\n const scrollTimeoutRef = useRef(false);\n\n // using a similar state/ref idea for managing loading as well, since we\n // need to know immediately if queries are in flight, but state won't be\n // updated in the onScroll handler fast enough\n const loadingRef = useRef(false);\n const setLoadingStateAndRef = (isLoading: boolean) => {\n setLoading(isLoading);\n loadingRef.current = isLoading;\n };\n\n const queryRetryCountRef = useRef(0);\n\n useEffect(() => {\n if (firstRenderRef.current && queryInitialItems) {\n setItems(queryInitialItems());\n }\n\n // don't run on initial render unless we explicitly choose to\n if (firstRenderRef.current && !queryOnFirstRender) {\n firstRenderRef.current = false;\n return;\n }\n\n setLoadingStateAndRef(true);\n\n // using a short debounce delay to batch updates\n const timeoutID = setTimeout(() => {\n // if this query is outdated, don't call it\n if (triggerQueryCount < triggerQueryCountRef.current) return;\n\n query({\n page,\n inputValue,\n selectedItem,\n selectedItems,\n })\n .then((res) => {\n queryRetryCountRef.current = 0;\n\n // if this query is outdated, throw away it's results\n if (triggerQueryCount < triggerQueryCountRef.current) return;\n\n setLoadingStateAndRef(false);\n setPage((x) => x + 1);\n\n // if the result is nullish or empty\n // assume we've reached the end of the pagination\n if (res == null || (page > 0 && res.length === 0)) {\n setDone(true);\n } else if (page === 0) {\n setItems(() => [...res]);\n } else {\n setItems((prevItems) => [...prevItems, ...res]);\n }\n })\n .catch(() => {\n // if we fail, retry up to 8 times with exponential back-off\n queryRetryCountRef.current += 1;\n\n if (queryRetryCountRef.current > 7) {\n queryRetryCountRef.current = 0;\n return;\n } else {\n setTimeout(\n () => {\n triggerQuery();\n },\n 2 ** queryRetryCountRef.current * 160,\n );\n }\n });\n }, 160);\n\n return () => {\n clearTimeout(timeoutID);\n };\n\n // only re-query when we manually call triggerQuery\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [triggerQueryCount]);\n\n // if the popover isn't scrollable, keep firing more queries\n useLayoutEffect(() => {\n setTimeout(() => {\n if (\n scrollerRef.current &&\n scrollerRef.current.scrollHeight > 0 &&\n scrollerRef.current.clientHeight > 0 &&\n scrollerRef.current.scrollHeight <= scrollerRef.current.clientHeight\n ) {\n triggerQuery();\n }\n }, 160);\n }, [items]);\n\n // making this separate variable to satisfy react hooks deps linter\n const isEmpty = items.length === 0 && page === 0;\n\n const onStateChange = useCallback(\n (changes: Parameters<NonNullable<ComboboxProps[\"onStateChange\"]>>[0]) => {\n // if the user interacts and we're empty, fire the first query\n if (isEmpty && \"isOpen\" in changes && changes.isOpen === true) {\n triggerQuery();\n }\n\n // otherwise, if inputValue or selectedItems changes, assume we need an\n // entirely new list back from the query\n const inputValueShouldUpdate =\n updateOnInputValueChange && \"inputValue\" in changes;\n const selectedItemsShouldUpdate =\n updateOnSelectedItemsChange &&\n \"selectedItems\" in changes &&\n changes.selectedItems;\n const selectedItemShouldUpdate =\n updateOnSelectedItemChange &&\n \"selectedItem\" in changes &&\n changes.selectedItem !== undefined;\n\n if (inputValueShouldUpdate) {\n setInputValue(changes.inputValue ?? \"\");\n }\n\n if (selectedItemsShouldUpdate) {\n setSelectedItems(changes.selectedItems ?? []);\n }\n\n if (selectedItemShouldUpdate) {\n setSelectedItem(changes.selectedItem);\n }\n\n if (\n inputValueShouldUpdate ||\n selectedItemsShouldUpdate ||\n selectedItemShouldUpdate\n ) {\n setPage(0);\n setDone(false);\n triggerQuery();\n }\n },\n [\n isEmpty,\n updateOnInputValueChange,\n updateOnSelectedItemsChange,\n updateOnSelectedItemChange,\n ],\n );\n\n const onScroll = useCallback(\n (e: UIEvent<HTMLElement>) => {\n // React events don't persist, so we need to store the element through the timeout\n const element = e.currentTarget;\n\n // using timeoutRef to throttle scroll calls\n // using loadingRef to not make additional queries if a query is already in flight\n if (!scrollTimeoutRef.current && !loadingRef.current) {\n setTimeout(() => {\n const shouldTriggerQuery =\n shouldTriggerQueryProp ?? defaultShouldTriggerQuery;\n\n if (shouldTriggerQuery(element) && !done) {\n triggerQuery();\n }\n\n scrollTimeoutRef.current = false;\n }, 40);\n\n scrollTimeoutRef.current = true;\n }\n },\n [done, shouldTriggerQueryProp],\n );\n\n return {\n comboboxProps: {\n items: deferredItems,\n loading: deferredLoading,\n initialInputValue,\n defaultInputValue,\n initialSelectedItem,\n defaultSelectedItem,\n initialSelectedItems,\n defaultSelectedItems,\n disableFilter: true, // assume the query will return a filtered/sorted list\n onStateChange,\n },\n contentProps: {\n onScroll,\n scrollerRef,\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useIntersectionObserver({
|
|
4
|
+
threshold = 0,
|
|
5
|
+
root = null,
|
|
6
|
+
rootMargin = "0%",
|
|
7
|
+
freezeOnceVisible = false,
|
|
8
|
+
initialIsIntersecting = false,
|
|
9
|
+
onChange
|
|
10
|
+
} = {}) {
|
|
11
|
+
const [ref, setRef] = useState(null);
|
|
12
|
+
const [state, setState] = useState(() => ({
|
|
13
|
+
isIntersecting: initialIsIntersecting,
|
|
14
|
+
entry: void 0
|
|
15
|
+
}));
|
|
16
|
+
const callbackRef = useRef();
|
|
17
|
+
callbackRef.current = onChange;
|
|
18
|
+
const frozen = state.entry?.isIntersecting && freezeOnceVisible;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!ref) return;
|
|
21
|
+
if (!("IntersectionObserver" in window)) return;
|
|
22
|
+
if (frozen) return;
|
|
23
|
+
const observer = new IntersectionObserver(
|
|
24
|
+
(entries) => {
|
|
25
|
+
const thresholds = Array.isArray(observer.thresholds) ? observer.thresholds : [observer.thresholds];
|
|
26
|
+
entries.forEach((entry) => {
|
|
27
|
+
const isIntersecting = entry.isIntersecting && thresholds.some(
|
|
28
|
+
(threshold2) => entry.intersectionRatio >= threshold2
|
|
29
|
+
);
|
|
30
|
+
setState({ isIntersecting, entry });
|
|
31
|
+
if (callbackRef.current) {
|
|
32
|
+
callbackRef.current(isIntersecting, entry);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
{ threshold, root, rootMargin }
|
|
37
|
+
);
|
|
38
|
+
observer.observe(ref);
|
|
39
|
+
return () => {
|
|
40
|
+
observer.disconnect();
|
|
41
|
+
};
|
|
42
|
+
}, [
|
|
43
|
+
ref,
|
|
44
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
45
|
+
JSON.stringify(threshold),
|
|
46
|
+
root,
|
|
47
|
+
rootMargin,
|
|
48
|
+
frozen,
|
|
49
|
+
freezeOnceVisible
|
|
50
|
+
]);
|
|
51
|
+
const prevRef = useRef(null);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!ref && state.entry?.target && !freezeOnceVisible && !frozen && prevRef.current !== state.entry.target) {
|
|
54
|
+
prevRef.current = state.entry.target;
|
|
55
|
+
setState({ isIntersecting: initialIsIntersecting, entry: void 0 });
|
|
56
|
+
}
|
|
57
|
+
}, [ref, state.entry, freezeOnceVisible, frozen, initialIsIntersecting]);
|
|
58
|
+
const result = [
|
|
59
|
+
setRef,
|
|
60
|
+
!!state.isIntersecting,
|
|
61
|
+
state.entry
|
|
62
|
+
];
|
|
63
|
+
result.ref = result[0];
|
|
64
|
+
result.isIntersecting = result[1];
|
|
65
|
+
result.entry = result[2];
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { useIntersectionObserver as u };
|
|
70
|
+
//# sourceMappingURL=useIntersectionObserver-BEmMDO3P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIntersectionObserver-BEmMDO3P.js","sources":["../src/internal/hooks/useIntersectionObserver/useIntersectionObserver.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\n/**\n * Internal state type for intersection observer\n * @property {boolean} isIntersecting - Whether the element is intersecting\n * @property {IntersectionObserverEntry} [entry] - The intersection observer entry\n */\ntype State = {\n /**\n * Whether the element is intersecting\n */\n isIntersecting: boolean;\n /**\n * The intersection observer entry\n */\n entry?: IntersectionObserverEntry;\n};\n\n/**\n * Options for the useIntersectionObserver hook\n * @property {Element | Document | null} [root] - The root element for intersection calculations\n * @property {string} [rootMargin] - Margin around the root element\n * @property {number | number[]} [threshold] - Threshold values for intersection detection\n * @property {boolean} [freezeOnceVisible] - Whether to freeze once the element becomes visible\n * @property {(isIntersecting: boolean, entry: IntersectionObserverEntry) => void} [onChange] - Callback when intersection changes\n * @property {boolean} [initialIsIntersecting] - Initial intersection state\n */\nexport type UseIntersectionObserverOptions = {\n /**\n * The root element for intersection calculations\n */\n root?: Element | Document | null;\n /**\n * Margin around the root element\n */\n rootMargin?: string;\n /**\n * Threshold values for intersection detection\n */\n threshold?: number | number[];\n /**\n * Whether to freeze once the element becomes visible\n */\n freezeOnceVisible?: boolean;\n /**\n * Callback when intersection changes\n */\n onChange?: (\n isIntersecting: boolean,\n entry: IntersectionObserverEntry,\n ) => void;\n /**\n * Initial intersection state\n */\n initialIsIntersecting?: boolean;\n};\n\n/**\n * Return type for the useIntersectionObserver hook\n * @property {(node?: Element | null) => void} ref - Function to set the element to observe\n * @property {boolean} isIntersecting - Whether the element is intersecting\n * @property {IntersectionObserverEntry} [entry] - The intersection observer entry\n */\nexport type IntersectionReturn = [\n (node?: Element | null) => void,\n boolean,\n IntersectionObserverEntry | undefined,\n] & {\n ref: (node?: Element | null) => void;\n isIntersecting: boolean;\n entry?: IntersectionObserverEntry;\n};\n\n/**\n * Custom hook for observing element intersection with viewport or root element.\n *\n * Features:\n * - Observes element intersection with viewport or custom root element\n * - Supports configurable threshold values and root margins\n * - Provides intersection state and detailed entry information\n * - Supports freezing observation once element becomes visible\n * - Handles browser compatibility gracefully\n * - Provides both array and object destructuring support\n * - Automatically cleans up observer on unmount\n * - Supports onChange callback for custom intersection handling\n *\n * @param options - Configuration options for the intersection observer\n * @returns Array containing ref function, intersection state, and entry, with additional object properties\n */\nexport function useIntersectionObserver({\n threshold = 0,\n root = null,\n rootMargin = \"0%\",\n freezeOnceVisible = false,\n initialIsIntersecting = false,\n onChange,\n}: UseIntersectionObserverOptions = {}): IntersectionReturn {\n const [ref, setRef] = useState<Element | null>(null);\n\n const [state, setState] = useState<State>(() => ({\n isIntersecting: initialIsIntersecting,\n entry: undefined,\n }));\n\n const callbackRef = useRef<UseIntersectionObserverOptions[\"onChange\"]>();\n\n callbackRef.current = onChange;\n\n const frozen = state.entry?.isIntersecting && freezeOnceVisible;\n\n useEffect(() => {\n // Ensure we have a ref to observe\n if (!ref) return;\n\n // Ensure the browser supports the Intersection Observer API\n if (!(\"IntersectionObserver\" in window)) return;\n\n // Skip if frozen\n if (frozen) return;\n\n let unobserve: (() => void) | undefined;\n\n const observer = new IntersectionObserver(\n (entries: IntersectionObserverEntry[]): void => {\n const thresholds = Array.isArray(observer.thresholds)\n ? observer.thresholds\n : [observer.thresholds];\n\n entries.forEach((entry) => {\n const isIntersecting =\n entry.isIntersecting &&\n thresholds.some(\n (threshold) => entry.intersectionRatio >= threshold,\n );\n\n setState({ isIntersecting, entry });\n\n if (callbackRef.current) {\n callbackRef.current(isIntersecting, entry);\n }\n\n if (isIntersecting && freezeOnceVisible && unobserve) {\n unobserve();\n unobserve = undefined;\n }\n });\n },\n { threshold, root, rootMargin },\n );\n\n observer.observe(ref);\n\n return () => {\n observer.disconnect();\n };\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n ref,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n JSON.stringify(threshold),\n root,\n rootMargin,\n frozen,\n freezeOnceVisible,\n ]);\n\n // ensures that if the observed element changes, the intersection observer is reinitialized\n const prevRef = useRef<Element | null>(null);\n\n useEffect(() => {\n if (\n !ref &&\n state.entry?.target &&\n !freezeOnceVisible &&\n !frozen &&\n prevRef.current !== state.entry.target\n ) {\n prevRef.current = state.entry.target;\n setState({ isIntersecting: initialIsIntersecting, entry: undefined });\n }\n }, [ref, state.entry, freezeOnceVisible, frozen, initialIsIntersecting]);\n\n const result = [\n setRef,\n !!state.isIntersecting,\n state.entry,\n ] as IntersectionReturn;\n\n // Support object destructuring, by adding the specific values.\n result.ref = result[0];\n result.isIntersecting = result[1];\n result.entry = result[2];\n\n return result;\n}\n"],"names":["threshold"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/anvil2",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"exports": {
|
|
17
17
|
".": "./dist/index.js",
|
|
18
|
+
"./beta": "./dist/beta.js",
|
|
18
19
|
"./assets/*": "./dist/assets/*",
|
|
19
20
|
"./token": "./dist/token.js",
|
|
20
21
|
"./token/*": "./dist/token/*",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DateFieldRange-Ba-8T-Nz.js","sources":["../src/components/DateFieldRange/internal/maskito/dateRangePlaceholderMask.ts","../src/components/DateFieldRange/internal/MaskedDateRangeInput.tsx","../src/components/DateFieldRange/internal/DateFieldRangeCalendar.tsx","../src/components/DateFieldRange/internal/useDateFieldRangeConversion.ts","../src/components/DateFieldRange/internal/useDateFieldRangeState.ts","../src/components/DateFieldRange/internal/utils.ts","../src/components/DateFieldRange/DateFieldRange.tsx"],"sourcesContent":["import type { MaskitoOptions } from \"@maskito/core\";\nimport {\n MaskitoDateMode,\n maskitoDateRangeOptionsGenerator,\n maskitoWithPlaceholder,\n} from \"@maskito/kit\";\nimport { makeZeroShortcutPreprocessor } from \"../../../DateFieldSingle/internal/maskito/makeZeroShortcutPreprocessor\";\n\nexport type DateMode = Extract<\n MaskitoDateMode,\n \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy/mm/dd\"\n>;\n\nconst datePlaceholderMask = ({\n mode,\n dateSeparator = \"/\",\n rangeSeparator = \" - \",\n placeholder,\n}: {\n mode: DateMode;\n dateSeparator?: string;\n rangeSeparator?: string;\n placeholder: string;\n}) => {\n const dateRangeOptions = maskitoDateRangeOptionsGenerator({\n mode,\n dateSeparator,\n rangeSeparator,\n });\n\n const { plugins, removePlaceholder, ...placeholderOptions } =\n maskitoWithPlaceholder(placeholder);\n\n const datePlaceholderMask = {\n ...dateRangeOptions,\n plugins: plugins.concat(dateRangeOptions.plugins || []),\n preprocessors: [\n ...placeholderOptions.preprocessors,\n ...dateRangeOptions.preprocessors,\n makeZeroShortcutPreprocessor(placeholder, dateSeparator),\n ],\n postprocessors: [\n // NOTE this is super fragile. If Maskito maintainers change the order of the post-processors, this will break.\n // The last postprocessor is the date swap postprocessor, which we don't want to run.\n // A unit test is added to ensure this doesn't break on a dependency update.\n ...dateRangeOptions.postprocessors.slice(0, -1),\n ...placeholderOptions.postprocessors,\n ],\n } satisfies Required<MaskitoOptions>;\n\n return { options: datePlaceholderMask, removePlaceholder };\n};\n\nexport default datePlaceholderMask;\n","import { maskitoParseDate } from \"@maskito/kit\";\nimport { useMaskito } from \"@maskito/react\";\nimport { TextField, TextFieldProps } from \"../../TextField/internal/TextField\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useMergeRefs } from \"@floating-ui/react\";\nimport { DateTime } from \"luxon\";\nimport { Icon } from \"../../Icon\";\nimport Event from \"@servicetitan/hammer-icon/mdi/round/event.svg\";\nimport dateRangePlaceholderMask from \"./maskito/dateRangePlaceholderMask\";\nimport {\n DateModeToFormatMap,\n DateModeToPlaceholderMap,\n} from \"../../DateFieldSingle/internal/constants\";\nimport { DateMode } from \"../../DateFieldSingle/types\";\nimport { usePrevious } from \"../../../internal/hooks\";\n\nconst RANGE_SEPARATOR = \" - \";\n\nexport type MaskedDateRangeInputChange = {\n startDate: DateTime | null;\n endDate: DateTime | null;\n isInputValid: boolean;\n isInputEmpty: boolean;\n};\n\nexport type MaskedDateRangeInputChangeHandler = (\n change: MaskedDateRangeInputChange,\n) => void;\n\nexport type MaskedDateRangeInputProps = Omit<\n TextFieldProps,\n \"onChange\" | \"value\" | \"ref\" | \"showCounter\" | \"hint\" | \"prefix\"\n> & {\n onChange: MaskedDateRangeInputChangeHandler;\n mode?: DateMode;\n startDate: DateTime | null;\n endDate: DateTime | null;\n disableHint?: boolean;\n};\n\nexport type MaskedDateRangeInputRef = HTMLInputElement & {\n setDateRange: (startDate: DateTime | null, endDate: DateTime | null) => void;\n};\n\n/**\n * A masked date input component that allows for the input of a date in a specific format.\n *\n * Provides a `setDates` method that can be used to set the date from outside the component (e.g from a calendar).\n *\n * @internal This component is not intended to be used directly in consumer code.\n *\n * @param props - The props for the MaskedDateRangeInput component.\n * @param props.onChange - The function to call when the date changes.\n * @param props.mode - The mode of the date input.\n * @param props.startDate - The start date.\n * @param props.endDate - The end date.\n * @param props.disableHint - Whether to disable the hint.\n */\nexport const MaskedDateRangeInput = forwardRef<\n MaskedDateRangeInputRef,\n MaskedDateRangeInputProps\n>(\n (\n {\n onChange,\n mode = \"mm/dd/yyyy\",\n startDate,\n endDate,\n disableHint = false,\n ...props\n },\n ref,\n ) => {\n const halfPlaceholder = DateModeToPlaceholderMap[mode];\n const fullPlaceholder = `${halfPlaceholder}${RANGE_SEPARATOR}${halfPlaceholder}`;\n\n // Tracks the value of the input as it is being typed.\n const [inputValue, setInputValue] = useState(fullPlaceholder);\n\n const { options, removePlaceholder } = dateRangePlaceholderMask({\n mode,\n placeholder: fullPlaceholder,\n dateSeparator: \"/\",\n rangeSeparator: RANGE_SEPARATOR,\n });\n const maskedInputRef = useMaskito({ options });\n const inputRef = useRef<HTMLInputElement>(null);\n const combinedRef = useMergeRefs([maskedInputRef, inputRef, ref]);\n const previousStartDate = usePrevious(startDate);\n const previousEndDate = usePrevious(endDate);\n const previousMode = usePrevious(mode);\n\n // Update the input value when the mode changes.\n useEffect(() => {\n if (mode !== previousMode) {\n setInputValue((previousInputValue) =>\n swapMode(previousInputValue, previousMode ?? mode, mode),\n );\n }\n }, [mode, fullPlaceholder, previousMode]);\n\n // Update the input value when the parent's start date or end date changes.\n useEffect(() => {\n if (startDate === undefined || endDate === undefined) return;\n // Return early if the values haven't actually changed.\n if (startDate === previousStartDate && endDate === previousEndDate)\n return;\n if (\n // plus one just represents a date that is guaranteed to be different.\n startDate?.equals(previousStartDate ?? startDate?.plus({ days: 1 })) &&\n (endDate?.equals(previousEndDate ?? endDate?.plus({ days: 1 })) ||\n endDate === previousEndDate)\n )\n return;\n const startDateString =\n startDate?.toFormat(DateModeToFormatMap[mode]) ?? halfPlaceholder;\n const endDateString =\n endDate?.toFormat(DateModeToFormatMap[mode]) ?? halfPlaceholder;\n const newInputValue = `${startDateString}${RANGE_SEPARATOR}${endDateString}`;\n setInputValue(newInputValue);\n }, [\n startDate,\n endDate,\n mode,\n halfPlaceholder,\n previousStartDate,\n previousEndDate,\n ]);\n\n const currentParsedData = useMemo(() => {\n return parseRangeInputValue(inputValue, mode, removePlaceholder);\n }, [inputValue, mode, removePlaceholder]);\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(event.target.value);\n const {\n startDate: newlyParsedStartDate,\n endDate: newlyParsedEndDate,\n isInputValid,\n isInputEmpty,\n isHalfEmpty,\n } = parseRangeInputValue(event.target.value, mode, removePlaceholder);\n\n // We only want to call onChange for substantive changes.\n // This is to avoid unnecessary re-renders of upstream components.\n const isValueDifferent =\n isInputValid !== currentParsedData.isInputValid || // The input has changed validity\n isInputEmpty !== currentParsedData.isInputEmpty || // The input has changed emptiness\n (newlyParsedStartDate === null) !==\n (currentParsedData.startDate === null) || // The start date has changed from empty to non-empty or vice versa\n (newlyParsedEndDate === null) !==\n (currentParsedData.endDate === null) || // The end date has changed from empty to non-empty or vice versa\n isHalfEmpty !== currentParsedData.isHalfEmpty || // The half has changed from empty to non-empty or vice versa\n (newlyParsedStartDate !== null &&\n currentParsedData.startDate !== null &&\n !newlyParsedStartDate.equals(currentParsedData.startDate)) || // The start date has changed\n (newlyParsedEndDate !== null &&\n currentParsedData.endDate !== null &&\n !newlyParsedEndDate.equals(currentParsedData.endDate)); // The end date has changed\n\n // If the value has not changed, we do not need to call onChange.\n if (!isValueDifferent) return;\n onChange?.({\n startDate: isInputEmpty\n ? null\n : (newlyParsedStartDate ?? startDate ?? null),\n endDate:\n isInputEmpty || isHalfEmpty\n ? null\n : (newlyParsedEndDate ?? endDate ?? null),\n isInputValid,\n isInputEmpty,\n });\n };\n\n // Extend the input ref with additional methods.\n // This provides a way to set the input value from outside the component.\n useImperativeHandle(ref, () => {\n const input = inputRef.current;\n if (!input) return null as unknown as MaskedDateRangeInputRef;\n return Object.assign(input, {\n setDateRange: (\n startDate: DateTime | null,\n endDate: DateTime | null,\n ) => {\n const startDateString = startDate?.toFormat(\n DateModeToFormatMap[mode],\n );\n const endDateString = endDate?.toFormat(DateModeToFormatMap[mode]);\n const newInputValue = `${startDateString ?? halfPlaceholder}${RANGE_SEPARATOR}${endDateString ?? halfPlaceholder}`;\n setInputValue(newInputValue);\n },\n });\n }, [mode, halfPlaceholder]);\n\n return (\n <TextField\n ref={combinedRef}\n data-start-date={startDate?.toISODate() ?? \"\"}\n data-end-date={endDate?.toISODate() ?? \"\"}\n data-input-valid={currentParsedData.isInputValid}\n data-input-empty={currentParsedData.isInputEmpty}\n {...props}\n showCounter={false}\n value={inputValue}\n onChange={handleChange}\n prefix={<Icon svg={Event} />}\n hint={disableHint ? undefined : `Format: ${mode}`}\n />\n );\n },\n);\n\nMaskedDateRangeInput.displayName = \"MaskedDateRangeInput\";\n\nfunction parseRangeInputValue(\n value: string,\n mode: DateMode,\n removePlaceholder: (value: string) => string,\n) {\n const valueMinusPlaceholder = removePlaceholder(value);\n const [startDate, endDate] = valueMinusPlaceholder.split(RANGE_SEPARATOR);\n const startJsDate = maskitoParseDate(startDate, { mode });\n const endJsDate = endDate ? maskitoParseDate(endDate, { mode }) : null;\n const startLuxonDate = startJsDate\n ? DateTime.fromJSDate(startJsDate, { zone: \"utc\" })\n : null;\n const endLuxonDate = endJsDate\n ? DateTime.fromJSDate(endJsDate, { zone: \"utc\" })\n : null;\n return {\n startDate: startLuxonDate,\n endDate: endLuxonDate,\n isInputValid: !!(startLuxonDate && endLuxonDate), // input valid if both dates are filled\n isInputEmpty: valueMinusPlaceholder === \"\", // input empty if nothing is typed\n isHalfEmpty: endDate === undefined,\n };\n}\n\nfunction swapMode(inputString: string, previousMode: DateMode, mode: DateMode) {\n const halves = inputString.split(RANGE_SEPARATOR);\n const segments = halves.map((half) => half.split(\"/\"));\n\n let startDay, startMonth, startYear, endDay, endMonth, endYear;\n if (previousMode === \"mm/dd/yyyy\") {\n startDay = segments[0][1];\n startMonth = segments[0][0];\n startYear = segments[0][2];\n endDay = segments[1][1];\n endMonth = segments[1][0];\n endYear = segments[1][2];\n }\n if (previousMode === \"dd/mm/yyyy\") {\n startDay = segments[0][0];\n startMonth = segments[0][1];\n startYear = segments[0][2];\n endDay = segments[1][0];\n endMonth = segments[1][1];\n endYear = segments[1][2];\n }\n if (previousMode === \"yyyy/mm/dd\") {\n startDay = segments[0][2];\n startMonth = segments[0][1];\n startYear = segments[0][0];\n endDay = segments[1][2];\n endMonth = segments[1][1];\n endYear = segments[1][0];\n }\n\n if (mode === \"mm/dd/yyyy\") {\n return `${startMonth}/${startDay}/${startYear}${RANGE_SEPARATOR}${endMonth}/${endDay}/${endYear}`;\n }\n if (mode === \"dd/mm/yyyy\") {\n return `${startDay}/${startMonth}/${startYear}${RANGE_SEPARATOR}${endDay}/${endMonth}/${endYear}`;\n }\n if (mode === \"yyyy/mm/dd\") {\n return `${startYear}/${startMonth}/${startDay}${RANGE_SEPARATOR}${endYear}/${endMonth}/${endDay}`;\n }\n\n return inputString;\n}\n","import { DateTime, WeekdayNumbers } from \"luxon\";\nimport { Calendar, CalendarRangeValue } from \"../../Calendar/Calendar\";\nimport { useMemo } from \"react\";\nimport { usePrevious } from \"../../../internal/hooks\";\n\nexport type DateFieldRangeCalendarProps = {\n startDate: DateTime | null;\n endDate: DateTime | null;\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;\n onSelection: ({\n startDate,\n endDate,\n }: {\n startDate: DateTime | null;\n endDate: DateTime | null;\n }) => void;\n minDate?: DateTime | null;\n maxDate?: DateTime | null;\n unavailable?: {\n dates?: DateTime[];\n daysOfWeek?: WeekdayNumbers[];\n };\n};\n\nexport const DateFieldRangeCalendar = ({\n startDate,\n endDate,\n onKeyDown,\n onSelection,\n minDate,\n maxDate,\n unavailable,\n}: DateFieldRangeCalendarProps) => {\n const previousStartDate = usePrevious(startDate);\n const previousEndDate = usePrevious(endDate);\n\n const handleCalendarSelection = (data: { value: CalendarRangeValue }) => {\n if (!data.value) return;\n const calStartDate = data.value.start\n ? DateTime.fromISO(data.value.start, { zone: \"utc\" })\n : null;\n const calEndDate = data.value.end\n ? DateTime.fromISO(data.value.end, { zone: \"utc\" })\n : null;\n onSelection({\n startDate: calStartDate,\n endDate: calEndDate,\n });\n };\n\n const defaultFocusedDate = useMemo(() => {\n // Nothing selected, focus today\n if (!startDate && !endDate) return DateTime.now().toISODate();\n if (!startDate) return endDate?.toISODate();\n if (!endDate) return startDate?.toISODate();\n if (endDate && !previousEndDate?.equals(endDate)) {\n return endDate.toISODate();\n } else if (startDate && !previousStartDate?.equals(startDate)) {\n return startDate.toISODate();\n }\n\n if (endDate) return endDate.toISODate();\n if (startDate) return startDate.toISODate();\n return DateTime.now().toISODate();\n }, [previousStartDate, previousEndDate, startDate, endDate]);\n\n return (\n <Calendar\n // Crappy hack because the Calendar does not update when the value changes.\n key={`${startDate?.toISODate()}-${endDate?.toISODate()}`}\n range={true}\n onKeyDown={onKeyDown}\n defaultFocusedDate={defaultFocusedDate}\n value={{\n start: startDate?.toISODate() || undefined,\n end: endDate?.toISODate() || undefined,\n }}\n onSelection={handleCalendarSelection}\n defaultTimeZone=\"UTC\"\n minDate={minDate?.toISODate() ?? undefined}\n maxDate={maxDate?.toISODate() ?? undefined}\n unavailable={\n unavailable\n ? {\n dates: unavailable.dates?.map((d) => d.toISODate() ?? \"\"),\n daysOfWeek: unavailable.daysOfWeek,\n }\n : undefined\n }\n _disableAutofocus\n />\n );\n};\n","import { useCallback, useMemo } from \"react\";\nimport { DateFieldRangeChange, DateFieldRangeProps } from \"../DateFieldRange\";\nimport { convertStringToDate } from \"../../DateFieldSingle/internal/utils\";\nimport { DateTime } from \"luxon\";\n\n/**\n * This hook is used to convert the string props of a DateFieldRange component to a DateTime format.\n *\n * @param props - The props of the DateFieldRange component.\n * @returns The normalized value, defaultValue, minDate, maxDate, and unavailable dates in DateTime format.\n * @internal This hook is not intended to be used directly in consumer code.\n */\nexport const useDateFieldRangeConversion = (props: DateFieldRangeProps) => {\n const { value, defaultValue, minDate, maxDate, unavailable, onChange } =\n props;\n\n const normalizedValue = useMemo(() => {\n if (value === null || value === undefined) return value;\n return {\n startDate: convertStringToDate(value.startDate) ?? null,\n endDate: convertStringToDate(value.endDate) ?? null,\n };\n }, [value]);\n\n const normalizedDefaultValue = useMemo(() => {\n if (defaultValue === null || defaultValue === undefined)\n return defaultValue;\n return {\n startDate: convertStringToDate(defaultValue.startDate) ?? null,\n endDate: convertStringToDate(defaultValue.endDate) ?? null,\n };\n }, [defaultValue]);\n\n const normalizedMinDate = useMemo(\n () => convertStringToDate(minDate),\n [minDate],\n );\n const normalizedMaxDate = useMemo(\n () => convertStringToDate(maxDate),\n [maxDate],\n );\n\n const normalizedUnavailableDates = useMemo(() => {\n return unavailable?.dates\n ?.map((date) => convertStringToDate(date))\n .filter((date) => date !== null && date !== undefined);\n }, [unavailable?.dates]);\n\n const handleChange = useCallback(\n (\n change: Omit<DateFieldRangeChange, \"startDate\" | \"endDate\"> & {\n startDate: DateTime | null;\n endDate: DateTime | null;\n },\n ) => {\n onChange?.({\n ...change,\n startDate: change.startDate?.toISODate() ?? null,\n endDate: change.endDate?.toISODate() ?? null,\n });\n },\n [onChange],\n );\n\n return {\n value: normalizedValue,\n defaultValue: normalizedDefaultValue,\n minDate: normalizedMinDate,\n maxDate: normalizedMaxDate,\n unavailable: {\n dates: normalizedUnavailableDates,\n daysOfWeek: unavailable?.daysOfWeek,\n },\n onChange: handleChange,\n };\n};\n","import { DateTime } from \"luxon\";\nimport { useOptionallyControlledState } from \"../../../internal/hooks\";\nimport { MaskedDateRangeInputChange } from \"./MaskedDateRangeInput\";\n\nexport type DateFieldRangeStateChange = {\n startDate: DateTime | null;\n endDate: DateTime | null;\n isInputValid: boolean;\n isInputEmpty: boolean;\n};\n\nexport type DateFieldRangeStateChangeHandler = (\n change: DateFieldRangeStateChange,\n) => void;\n\nexport type DateFieldRangeStateParam = {\n /**\n * The controlled value of the start date.\n */\n valueProp?: {\n startDate: DateTime | null;\n endDate: DateTime | null;\n } | null;\n /**\n * The default value of the start date.\n */\n defaultValueProp?: {\n startDate: DateTime | null;\n endDate: DateTime | null;\n } | null;\n /**\n * The function to call when the state changes.\n */\n onChange: DateFieldRangeStateChangeHandler;\n};\n\n/**\n * This hook is used to keep the state of a DateFieldRange component in sync with the input and calendar.\n */\nexport type DateFieldRangeState = {\n /**\n * The start date.\n */\n startDate: DateTime | null;\n /**\n * The end date.\n */\n endDate: DateTime | null;\n /**\n * The function to set the start date.\n */\n setStartDate: (date: DateTime | null) => void;\n /**\n * The function to set the end date.\n */\n setEndDate: (date: DateTime | null) => void;\n /**\n * The function to handle the input change.\n */\n handleInputChange: (change: MaskedDateRangeInputChange) => void;\n /**\n * The function to handle the calendar selection.\n */\n handleCalendarSelection: ({\n startDate,\n endDate,\n }: {\n startDate: DateTime | null;\n endDate: DateTime | null;\n }) => void;\n};\n\n/**\n * This is a hook for keeping state in sync between a date input and calendar.\n */\nexport function useDateFieldRangeState({\n valueProp,\n defaultValueProp,\n onChange,\n}: DateFieldRangeStateParam): DateFieldRangeState {\n const [startDate, setStartDate] =\n useOptionallyControlledState<DateTime | null>({\n controlledValue:\n valueProp !== undefined ? valueProp?.startDate : undefined,\n defaultValue:\n defaultValueProp !== undefined\n ? defaultValueProp?.startDate\n : undefined,\n });\n const [endDate, setEndDate] = useOptionallyControlledState<DateTime | null>({\n controlledValue: valueProp !== undefined ? valueProp?.endDate : undefined,\n defaultValue:\n defaultValueProp !== undefined ? defaultValueProp?.endDate : undefined,\n });\n\n const setSharedValue = (value: {\n startDate: DateTime | null;\n endDate: DateTime | null;\n }) => {\n setStartDate(value.startDate);\n setEndDate(value.endDate);\n };\n\n const handleInputChange = (change: MaskedDateRangeInputChange) => {\n const range = change.isInputEmpty\n ? null\n : {\n startDate: change.startDate?.startOf(\"day\") ?? null,\n endDate: change.endDate?.startOf(\"day\") ?? null,\n };\n setStartDate(range?.startDate ?? null);\n setEndDate(range?.endDate ?? null);\n onChange?.({\n startDate: range?.startDate ?? null,\n endDate: range?.endDate ?? null,\n isInputValid: change.isInputValid,\n isInputEmpty: change.isInputEmpty,\n });\n };\n\n const handleCalendarSelection = ({\n startDate,\n endDate,\n }: {\n startDate: DateTime | null;\n endDate: DateTime | null;\n }) => {\n setSharedValue({ startDate, endDate });\n onChange?.({\n startDate,\n endDate,\n isInputValid: true,\n isInputEmpty: false,\n });\n };\n\n return {\n startDate,\n endDate,\n setStartDate,\n setEndDate,\n handleInputChange,\n handleCalendarSelection,\n };\n}\n","import { DateTime } from \"luxon\";\nimport { validateDate } from \"../../DateFieldSingle/internal/utils\";\n\ntype DateConstraints = {\n unavailable?: {\n dates?: DateTime[];\n daysOfWeek?: number[];\n };\n minDate?: DateTime;\n maxDate?: DateTime;\n};\n\nexport function validateDateRange({\n required,\n startDate,\n endDate,\n startDateConstraints,\n endDateConstraints,\n}: {\n required?: boolean;\n startDate: DateTime | null;\n endDate: DateTime | null;\n startDateConstraints: DateConstraints;\n endDateConstraints: DateConstraints;\n}) {\n if (!required && !startDate && !endDate) return true;\n return (\n validateDate({\n date: startDate,\n constraints: { ...startDateConstraints, required: true },\n }) &&\n validateDate({\n date: endDate,\n constraints: { ...endDateConstraints, required: true },\n }) &&\n (!startDate || !endDate || startDate <= endDate)\n );\n}\n","import { childrenToString } from \"../../internal/functions\";\nimport { useTrackingId, useMergeRefs } from \"../../hooks\";\nimport { DataTrackingId } from \"../../types\";\nimport {\n MaskedDateRangeInput,\n MaskedDateRangeInputProps,\n MaskedDateRangeInputRef,\n} from \"./internal/MaskedDateRangeInput\";\nimport { DateMode } from \"../DateFieldSingle/types\";\nimport { DateFieldRangeCalendar } from \"./internal/DateFieldRangeCalendar\";\nimport { RefObject, useMemo, useRef, useState } from \"react\";\nimport { useDateFieldRangeConversion } from \"./internal/useDateFieldRangeConversion\";\nimport {\n DateFieldRangeStateChange,\n useDateFieldRangeState,\n} from \"./internal/useDateFieldRangeState\";\nimport {\n useFocusWithin,\n usePopoverCloseDelayWorkaround,\n usePopoverSupport,\n} from \"../../internal/hooks\";\nimport { validateDateRange } from \"./internal/utils\";\nimport { useDateFieldOrchestration } from \"../DateFieldSingle/internal/useDateFieldOrchestration\";\nimport Popover from \"../Popover\";\n\nexport type DateFieldRangeChange = {\n /**\n * The start date in ISO 8601 format.\n * @example \"2025-03-22\"\n */\n startDate: string | null;\n /**\n * The end date in ISO 8601 format.\n * @example \"2025-07-02\"\n */\n endDate: string | null;\n /**\n * Whether the input field contains two parsable dates.\n * This is not the same as the date range being valid.\n *\n */\n isInputValid: boolean;\n /**\n * Whether the input field is empty.\n */\n isInputEmpty: boolean;\n /**\n * Whether the start and end dates are valid according to the constraints.\n * Constraints include:\n * - Required\n * - Unavailable dates\n * - Unavailable days of the week\n * - Min date\n * - Max date\n */\n isDateRangeValid: boolean;\n};\n\nexport type DateFieldRangeChangeHandler = (\n change: DateFieldRangeChange,\n) => void;\n\nexport type DateFieldRangeValue = {\n startDate: string | null;\n endDate: string | null;\n} | null;\n\nexport type DateFieldRangeProps = Omit<\n MaskedDateRangeInputProps,\n | \"onChange\"\n | \"value\"\n | \"autoComplete\"\n | \"onClick\"\n | \"onKeyDown\"\n | \"ref\"\n | \"required\"\n | \"startDate\"\n | \"endDate\"\n | \"defaultValue\"\n | \"onFocus\"\n | \"onBlur\"\n> & {\n value?: DateFieldRangeValue;\n defaultValue?: DateFieldRangeValue;\n onChange?: DateFieldRangeChangeHandler;\n mode?: Extract<DateMode, \"mm/dd/yyyy\" | \"dd/mm/yyyy\">;\n disableHint?: boolean;\n disableCalendar?: boolean;\n unavailable?: {\n dates?: string[];\n daysOfWeek?: (1 | 2 | 3 | 4 | 5 | 6 | 7)[];\n };\n minDate?: string;\n maxDate?: string;\n required?: boolean;\n onFocus?: (event: React.FocusEvent) => void;\n onBlur?: (event: React.FocusEvent) => void;\n} & DataTrackingId;\n\nexport const DateFieldRange = (props: DateFieldRangeProps) => {\n const data = {\n label: childrenToString(props.label),\n labelProps: props.labelProps,\n description: childrenToString(props.description),\n };\n\n const trackingId = useTrackingId({\n name: \"DateFieldRange\",\n data,\n hasOverride: !!props[\"data-tracking-id\"],\n });\n\n const {\n onFocus,\n onBlur,\n disableCalendar,\n required,\n mode,\n value: valueProp,\n defaultValue: defaultValueProp,\n minDate: minDateProp,\n maxDate: maxDateProp,\n unavailable: unavailableProp,\n onChange: onChangeProp,\n ...rest\n } = props;\n\n const { props: wrapperProps } = useFocusWithin({\n onBlur: (e) => {\n onBlur?.(e);\n setCalendarOpen(false);\n },\n onFocus: onFocus,\n });\n\n const { value, defaultValue, minDate, maxDate, unavailable, onChange } =\n useDateFieldRangeConversion({\n value: valueProp,\n defaultValue: defaultValueProp,\n minDate: minDateProp,\n maxDate: maxDateProp,\n unavailable: unavailableProp,\n onChange: onChangeProp,\n });\n\n const inputRef = useRef<MaskedDateRangeInputRef>(null);\n const [popoverTriggerRef, setPopoverTriggerRef] =\n useState<RefObject<HTMLInputElement>>();\n const popoverContentRef = useRef<HTMLDivElement>(null);\n const combinedRef = useMergeRefs([popoverTriggerRef, inputRef]);\n const popoverSupported = usePopoverSupport();\n\n const handleChange = (change: DateFieldRangeStateChange) => {\n const sharedConstraints = {\n unavailable,\n minDate: minDate ?? undefined,\n maxDate: maxDate ?? undefined,\n };\n\n onChange?.({\n startDate: change.startDate?.startOf(\"day\") ?? null,\n endDate: change.endDate?.startOf(\"day\") ?? null,\n isInputValid: change.isInputValid,\n isInputEmpty: change.isInputEmpty,\n isDateRangeValid: validateDateRange({\n required: required,\n startDate: change.startDate?.startOf(\"day\") ?? null,\n endDate: change.endDate?.startOf(\"day\") ?? null,\n startDateConstraints: sharedConstraints,\n endDateConstraints: sharedConstraints,\n }),\n });\n };\n\n const { startDate, endDate, handleInputChange, handleCalendarSelection } =\n useDateFieldRangeState({\n valueProp: value,\n defaultValueProp: defaultValue,\n onChange: handleChange,\n });\n\n const {\n calendarOpen,\n setCalendarOpen,\n handleCalendarKeyDown,\n handleInputKeyDown,\n } = useDateFieldOrchestration({\n inputRef,\n calendarDefaultOpen: false,\n popoverContentRef,\n disableCalendar,\n });\n\n const shouldShowCalendar = usePopoverCloseDelayWorkaround(calendarOpen);\n\n const currentValidity = useMemo(() => {\n return validateDateRange({\n required,\n startDate,\n endDate,\n startDateConstraints: {\n unavailable,\n minDate: minDate ?? undefined,\n maxDate: maxDate ?? undefined,\n },\n endDateConstraints: {\n unavailable,\n minDate: minDate ?? undefined,\n maxDate: maxDate ?? undefined,\n },\n });\n }, [required, startDate, endDate, minDate, maxDate, unavailable]);\n\n const justTheField = (\n <MaskedDateRangeInput\n data-tracking-id={trackingId}\n {...rest}\n mode={mode}\n ref={combinedRef}\n startDate={startDate ?? null}\n endDate={endDate ?? null}\n onChange={handleInputChange}\n disableHint={rest.disableHint}\n onKeyDown={handleInputKeyDown}\n onClick={() => setCalendarOpen(true)}\n required={required}\n autoComplete=\"off\"\n data-date-range-valid={currentValidity}\n onFocus={!disableCalendar && !popoverSupported ? onFocus : undefined}\n onBlur={!disableCalendar && !popoverSupported ? onBlur : undefined}\n />\n );\n\n if (disableCalendar || !popoverSupported) {\n return justTheField;\n }\n\n return (\n <div {...wrapperProps}>\n <Popover\n open={calendarOpen}\n modal\n placement=\"bottom-start\"\n disableFlipFallback\n disableTriggerFocus\n onClose={() => setCalendarOpen(false)}\n disableAutoUpdate\n onOutsidePress={() => setCalendarOpen(false)}\n >\n <Popover.Trigger>\n {({ ref: iRef }) => {\n setPopoverTriggerRef(iRef as RefObject<HTMLInputElement>);\n return justTheField;\n }}\n </Popover.Trigger>\n <Popover.Content ref={popoverContentRef} data-testid=\"calendar-popover\">\n {shouldShowCalendar && (\n <DateFieldRangeCalendar\n startDate={startDate}\n endDate={endDate}\n onKeyDown={handleCalendarKeyDown}\n onSelection={(v) => {\n if (v.endDate) {\n inputRef.current?.focus();\n setCalendarOpen(false);\n }\n handleCalendarSelection(v);\n }}\n minDate={minDate}\n maxDate={maxDate}\n unavailable={unavailable}\n />\n )}\n </Popover.Content>\n </Popover>\n </div>\n );\n};\n\nDateFieldRange.displayName = \"DateFieldRange\";\n"],"names":["datePlaceholderMask","dateRangePlaceholderMask","startDate","endDate","Event","useMergeRefs"],"mappings":"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"}
|