pixelize-design-library 2.4.2-beta.34 → 2.4.2-beta.36

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 (93) hide show
  1. package/dist/Components/AppSwitcher/AppSwitcher.js +12 -49
  2. package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -3
  3. package/dist/Components/Common/fieldStyles.js +1 -1
  4. package/dist/Components/CopyButton/CopyButton.js +7 -6
  5. package/dist/Components/DatePicker/CalendarPanel.js +8 -5
  6. package/dist/Components/DatePicker/RangeDatePicker.js +27 -3
  7. package/dist/Components/DatePicker/SingleDatePicker.js +48 -14
  8. package/dist/Components/DatePicker/TimeOnlyPicker.js +7 -1
  9. package/dist/Components/DatePicker/TimePicker.js +3 -3
  10. package/dist/Components/DatePicker/TimePickerInput.js +1 -1
  11. package/dist/Components/Dropdown/DropDown.js +19 -6
  12. package/dist/Components/EmptyState/EmptyState.js +1 -1
  13. package/dist/Components/FileUpload/FileUpload.js +2 -2
  14. package/dist/Components/FilterSidebar/FilterSidebar.js +5 -5
  15. package/dist/Components/FilterSidebar/filterHoverStyle.d.ts +2 -1
  16. package/dist/Components/FilterSidebar/filterHoverStyle.js +3 -4
  17. package/dist/Components/Input/TextInput.styles.js +2 -2
  18. package/dist/Components/InputTextArea/InputTextArea.style.js +2 -2
  19. package/dist/Components/MoreItems/MoreItems.js +3 -1
  20. package/dist/Components/MultiSelect/MultiSelect.js +2 -2
  21. package/dist/Components/NavigationBar/NavigationBar.js +6 -7
  22. package/dist/Components/NumberInput/NumberInput.styles.js +2 -2
  23. package/dist/Components/OrgSwitcher/OrgSwitcher.js +14 -10
  24. package/dist/Components/PdfViewer/PdfViewer.js +4 -4
  25. package/dist/Components/RolesPermission/RolesPermission.js +4 -3
  26. package/dist/Components/SearchSelect/SearchSelect.js +46 -41
  27. package/dist/Components/SegmentedControl/SegmentedControl.d.ts +1 -1
  28. package/dist/Components/SegmentedControl/SegmentedControl.js +40 -10
  29. package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +3 -0
  30. package/dist/Components/Select/Select.styles.js +1 -1
  31. package/dist/Components/SelectSearch/SelectSearch.js +35 -17
  32. package/dist/Components/SelectV2/SelectV2.js +3 -0
  33. package/dist/Components/Table/TableProps.d.ts +2 -0
  34. package/dist/Components/Table/components/TableBody.js +7 -10
  35. package/dist/Components/Table/filters/CompactSelect.js +29 -8
  36. package/dist/Components/Table/settings/ManageColumns.js +5 -3
  37. package/dist/Components/Table/settings/TableSettings.js +4 -2
  38. package/dist/Components/Toggle/TableToggle.js +68 -18
  39. package/dist/Components/Toggle/TableToggleProps.d.ts +3 -0
  40. package/dist/Components/ToggleSwitch/ToggleSwitch.js +1 -1
  41. package/dist/Components/Trail/EditableCell.js +1 -1
  42. package/dist/Components/UserDetails/DeactivateConfirmModal.js +1 -1
  43. package/dist/Components/UserDetails/UserDetails.js +5 -3
  44. package/dist/Hooks/exclusiveOverlay.d.ts +4 -0
  45. package/dist/Hooks/exclusiveOverlay.js +22 -0
  46. package/dist/Hooks/useExclusiveOverlay.d.ts +5 -0
  47. package/dist/Hooks/useExclusiveOverlay.js +24 -0
  48. package/dist/Theme/chakra/Menu.styles.js +4 -2
  49. package/dist/Utils/table.d.ts +3 -0
  50. package/dist/Utils/table.js +44 -1
  51. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +13 -50
  52. package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -3
  53. package/dist/esm/Components/Common/fieldStyles.js +1 -1
  54. package/dist/esm/Components/CopyButton/CopyButton.js +7 -6
  55. package/dist/esm/Components/DatePicker/CalendarPanel.js +9 -6
  56. package/dist/esm/Components/DatePicker/RangeDatePicker.js +28 -4
  57. package/dist/esm/Components/DatePicker/SingleDatePicker.js +49 -15
  58. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +7 -1
  59. package/dist/esm/Components/DatePicker/TimePicker.js +3 -3
  60. package/dist/esm/Components/DatePicker/TimePickerInput.js +1 -1
  61. package/dist/esm/Components/Dropdown/DropDown.js +20 -7
  62. package/dist/esm/Components/EmptyState/EmptyState.js +1 -1
  63. package/dist/esm/Components/FileUpload/FileUpload.js +2 -2
  64. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +5 -5
  65. package/dist/esm/Components/FilterSidebar/filterHoverStyle.js +3 -4
  66. package/dist/esm/Components/Input/TextInput.styles.js +2 -2
  67. package/dist/esm/Components/InputTextArea/InputTextArea.style.js +2 -2
  68. package/dist/esm/Components/MoreItems/MoreItems.js +3 -1
  69. package/dist/esm/Components/MultiSelect/MultiSelect.js +2 -2
  70. package/dist/esm/Components/NavigationBar/NavigationBar.js +6 -7
  71. package/dist/esm/Components/NumberInput/NumberInput.styles.js +2 -2
  72. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +14 -10
  73. package/dist/esm/Components/PdfViewer/PdfViewer.js +4 -4
  74. package/dist/esm/Components/RolesPermission/RolesPermission.js +4 -3
  75. package/dist/esm/Components/SearchSelect/SearchSelect.js +46 -41
  76. package/dist/esm/Components/SegmentedControl/SegmentedControl.js +42 -12
  77. package/dist/esm/Components/Select/Select.styles.js +1 -1
  78. package/dist/esm/Components/SelectSearch/SelectSearch.js +35 -17
  79. package/dist/esm/Components/SelectV2/SelectV2.js +3 -0
  80. package/dist/esm/Components/Table/components/TableBody.js +7 -10
  81. package/dist/esm/Components/Table/filters/CompactSelect.js +29 -8
  82. package/dist/esm/Components/Table/settings/ManageColumns.js +5 -3
  83. package/dist/esm/Components/Table/settings/TableSettings.js +5 -3
  84. package/dist/esm/Components/Toggle/TableToggle.js +67 -17
  85. package/dist/esm/Components/ToggleSwitch/ToggleSwitch.js +1 -1
  86. package/dist/esm/Components/Trail/EditableCell.js +1 -1
  87. package/dist/esm/Components/UserDetails/DeactivateConfirmModal.js +1 -1
  88. package/dist/esm/Components/UserDetails/UserDetails.js +5 -3
  89. package/dist/esm/Hooks/exclusiveOverlay.js +16 -0
  90. package/dist/esm/Hooks/useExclusiveOverlay.js +20 -0
  91. package/dist/esm/Theme/chakra/Menu.styles.js +4 -2
  92. package/dist/esm/Utils/table.js +45 -3
  93. package/package.json +1 -1
@@ -41,6 +41,8 @@ const useCustomTheme_1 = require("../../Theme/useCustomTheme");
41
41
  const chartColorsFromTheme_1 = require("../../Theme/tokens/builders/chartColorsFromTheme");
42
42
  const accentText_1 = require("../../Theme/tokens/builders/accentText");
43
43
  const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
44
+ const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
45
+ const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
44
46
  const AppMark_1 = __importStar(require("./AppMark"));
45
47
  const AppSwitcherProps_1 = require("./AppSwitcherProps");
46
48
  const useAppSwitcherShortcut_1 = require("./useAppSwitcherShortcut");
@@ -68,25 +70,18 @@ const validate = (apps) => {
68
70
  warnOnce(`url-${app.id || i}`, `app "${app.name}" has no url; it cannot be opened.`);
69
71
  });
70
72
  };
71
- // Past a pointer's pause threshold, so crossing the launcher on the way elsewhere does not open it,
72
- // but short enough that deliberately resting on it feels instant.
73
- const HOVER_OPEN_DELAY = 450;
74
- // Long enough to travel the gap between the launcher and the panel below it.
75
- const HOVER_CLOSE_GRACE = 250;
76
73
  // Flip back to true to restore `searchThreshold` opening the field on its own.
77
74
  const SEARCH_OPENS_BY_COUNT = false;
78
75
  const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable, searchThreshold = 8, shortcut = null, showShortcutHint = true, hideWhenAlone = true, emptyMessage = "No app matches that name.", footer, ariaLabel = "Switch app", panelWidth, maxHeight = "24rem", isLoading = false, }) => {
79
76
  const theme = (0, useCustomTheme_1.useCustomTheme)();
80
77
  const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
78
+ const requestExclusiveOpen = (0, useExclusiveOverlay_1.useExclusiveOverlay)(isOpen, onClose);
81
79
  const [query, setQuery] = (0, react_1.useState)("");
82
80
  const [activeIndex, setActiveIndex] = (0, react_1.useState)(0);
83
81
  const searchRef = (0, react_1.useRef)(null);
84
82
  const triggerRef = (0, react_1.useRef)(null);
85
- const panelRef = (0, react_1.useRef)(null);
86
83
  const itemRefs = (0, react_1.useRef)([]);
87
84
  const typeahead = (0, react_1.useRef)({ buffer: "", at: 0 });
88
- const hoverTimer = (0, react_1.useRef)();
89
- const openedByHover = (0, react_1.useRef)(false);
90
85
  (0, react_1.useEffect)(() => validate(apps), [apps]);
91
86
  // Search is off while the panel's design settles: the app count alone no longer opens it. An
92
87
  // explicit `isSearchable` still wins, so nothing about the prop changed.
@@ -94,47 +89,15 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
94
89
  const hues = (0, react_1.useMemo)(() => (0, AppMark_1.assignAppHues)(apps, (0, chartColorsFromTheme_1.chartMode)(theme.colors)), [apps, theme.colors]);
95
90
  const visible = (0, react_1.useMemo)(() => (0, AppSwitcherProps_1.filterApps)(apps, query), [apps, query]);
96
91
  const setOpen = (0, react_1.useCallback)((next) => {
97
- if (next)
92
+ if (next) {
93
+ requestExclusiveOpen();
98
94
  onOpen();
99
- else
95
+ }
96
+ else {
100
97
  onClose();
98
+ }
101
99
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(next);
102
- }, [onOpen, onClose, onOpenChange]);
103
- const cancelHoverTimer = (0, react_1.useCallback)(() => {
104
- if (hoverTimer.current)
105
- clearTimeout(hoverTimer.current);
106
- hoverTimer.current = undefined;
107
- }, []);
108
- (0, react_1.useEffect)(() => cancelHoverTimer, [cancelHoverTimer]);
109
- // Touch and stylus report no hover; a timer there would open the panel on a tap-and-hold.
110
- const pointerHovers = () => {
111
- var _a;
112
- return typeof window !== "undefined" &&
113
- ((_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, "(hover: hover) and (pointer: fine)").matches);
114
- };
115
- const handleHoverStart = (0, react_1.useCallback)(() => {
116
- if (isOpen || !pointerHovers())
117
- return;
118
- cancelHoverTimer();
119
- hoverTimer.current = setTimeout(() => {
120
- openedByHover.current = true;
121
- setOpen(true);
122
- }, HOVER_OPEN_DELAY);
123
- }, [isOpen, cancelHoverTimer, setOpen]);
124
- // A click-opened panel is sticky, and a keyboard user inside it is not "hovering away".
125
- const handleHoverEnd = (0, react_1.useCallback)(() => {
126
- cancelHoverTimer();
127
- if (!isOpen || !openedByHover.current)
128
- return;
129
- hoverTimer.current = setTimeout(() => {
130
- var _a;
131
- if ((_a = panelRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement))
132
- return;
133
- openedByHover.current = false;
134
- setOpen(false);
135
- setQuery("");
136
- }, HOVER_CLOSE_GRACE);
137
- }, [isOpen, cancelHoverTimer, setOpen]);
100
+ }, [onOpen, onClose, onOpenChange, requestExclusiveOpen]);
138
101
  const closeAndRefocus = (0, react_1.useCallback)(() => {
139
102
  var _a;
140
103
  setOpen(false);
@@ -243,7 +206,7 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
243
206
  const nothingToSwitchTo = apps.length === 0 || (hideWhenAlone && apps.every((a) => a.id === currentAppId));
244
207
  if (nothingToSwitchTo)
245
208
  return null;
246
- const rowHoverBg = (0, outlineRung_1.resolveHoverTint)(theme.colors.gray[50], theme.colors.backgroundColor.light);
209
+ const rowHoverBg = (0, rowStates_1.listRowBackgrounds)(theme.colors).active;
247
210
  const footerRule = (0, outlineRung_1.ruleInk)(theme.colors.boxborder[200], [theme.colors.backgroundColor.subtle], outlineRung_1.CHROME_RULE);
248
211
  // Neutral, not `backgroundColor.tertiary`: that rung is brand-tinted in the hand-authored light
249
212
  // palettes, so lifting it painted the row a saturated block. The rail identifies the row, so the
@@ -258,7 +221,7 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
258
221
  const currentSub = (0, outlineRung_1.liftToContrast)(theme.colors.textMuted, currentBg, accentText_1.AA_NORMAL_TEXT);
259
222
  const width = panelWidth !== null && panelWidth !== void 0 ? panelWidth : "28rem";
260
223
  const hint = shortcut && showShortcutHint ? (0, AppSwitcherProps_1.formatShortcut)(shortcut) : null;
261
- return ((0, jsx_runtime_1.jsxs)(react_2.Popover, { isOpen: isOpen, onOpen: () => setOpen(true), onClose: () => { setOpen(false); setQuery(""); }, placement: "bottom-end", initialFocusRef: showSearch ? searchRef : undefined, isLazy: true, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_2.Flex, { ref: triggerRef, as: "button", type: "button", "aria-label": ariaLabel, align: "center", justify: "center", boxSize: s.trigger, borderRadius: "lg", border: "1px solid", borderColor: isOpen ? theme.colors.boxborder[500] : theme.colors.boxborder[200], bg: isOpen ? theme.colors.backgroundColor.tertiary : "transparent", color: isOpen ? theme.colors.text[900] : theme.colors.textMuted, cursor: "pointer", transition: "background 0.15s ease, border-color 0.15s ease", _hover: { bg: rowHoverBg, color: theme.colors.text[900] }, onMouseEnter: handleHoverStart, onMouseLeave: handleHoverEnd, onClick: () => { openedByHover.current = false; cancelHoverTimer(); }, onKeyDown: (e) => {
224
+ return ((0, jsx_runtime_1.jsxs)(react_2.Popover, { isOpen: isOpen, onOpen: () => setOpen(true), onClose: () => { setOpen(false); setQuery(""); }, placement: "bottom-end", initialFocusRef: showSearch ? searchRef : undefined, isLazy: true, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_2.Flex, { ref: triggerRef, as: "button", type: "button", "aria-label": ariaLabel, align: "center", justify: "center", boxSize: s.trigger, borderRadius: "lg", border: "1px solid", borderColor: isOpen ? theme.colors.boxborder[500] : theme.colors.boxborder[200], bg: isOpen ? theme.colors.backgroundColor.tertiary : "transparent", color: isOpen ? theme.colors.text[900] : theme.colors.textMuted, cursor: "pointer", transition: "background 0.15s ease, border-color 0.15s ease", _hover: { bg: rowHoverBg, color: theme.colors.text[900] }, onKeyDown: (e) => {
262
225
  if (!isOpen) {
263
226
  if (e.key === "ArrowDown") {
264
227
  e.preventDefault();
@@ -267,7 +230,7 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
267
230
  return;
268
231
  }
269
232
  handlePanelKeyDown(e);
270
- }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Grip, { size: s.icon + 1 }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { ref: panelRef, onMouseEnter: cancelHoverTimer, onMouseLeave: handleHoverEnd, w: width, maxW: "calc(100vw - 1.5rem)", textAlign: "start", onKeyDown: handlePanelKeyDown, bg: theme.colors.backgroundColor.light, borderRadius: "xl", overflow: "hidden", boxShadow: `0 10px 30px ${theme.colors.boxShadow.default}`, _focus: { outline: "none", boxShadow: `0 10px 30px ${theme.colors.boxShadow.default}` }, children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 2, px: 3, pt: 3, pb: showSearch ? 2 : 1, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "0.6875rem", fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: theme.colors.textMuted, children: HEADING }), (0, jsx_runtime_1.jsx)(react_2.Box, { flex: "1" }), hint && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "kbd", fontSize: "0.6875rem", fontFamily: "inherit", color: theme.colors.textMuted, border: "1px solid", borderRadius: "base", px: 1.5, py: 0.5, children: hint }))] }), showSearch && ((0, jsx_runtime_1.jsx)(react_2.Box, { px: 3, pb: 2, children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: "sm", children: [(0, jsx_runtime_1.jsx)(react_2.InputLeftElement, { pointerEvents: "none", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Search, { size: 15, color: theme.colors.textMuted }) }), (0, jsx_runtime_1.jsx)(react_2.Input, { ref: searchRef, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search apps", borderRadius: "lg", "aria-label": "Search apps", onKeyDown: (e) => {
233
+ }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Grip, { size: s.icon + 1 }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { w: width, maxW: "calc(100vw - 1.5rem)", textAlign: "start", onKeyDown: handlePanelKeyDown, bg: theme.colors.backgroundColor.light, borderRadius: "xl", overflow: "hidden", boxShadow: `0 10px 30px ${theme.colors.boxShadow.default}`, _focus: { outline: "none", boxShadow: `0 10px 30px ${theme.colors.boxShadow.default}` }, children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 2, px: 3, pt: 3, pb: showSearch ? 2 : 1, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "0.6875rem", fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: theme.colors.textMuted, children: HEADING }), (0, jsx_runtime_1.jsx)(react_2.Box, { flex: "1" }), hint && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "kbd", fontSize: "0.6875rem", fontFamily: "inherit", color: theme.colors.textMuted, border: "1px solid", borderRadius: "base", px: 1.5, py: 0.5, children: hint }))] }), showSearch && ((0, jsx_runtime_1.jsx)(react_2.Box, { px: 3, pb: 2, children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: "sm", children: [(0, jsx_runtime_1.jsx)(react_2.InputLeftElement, { pointerEvents: "none", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Search, { size: 15, color: theme.colors.textMuted }) }), (0, jsx_runtime_1.jsx)(react_2.Input, { ref: searchRef, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search apps", borderRadius: "lg", "aria-label": "Search apps", onKeyDown: (e) => {
271
234
  if (e.key === "ArrowDown" && visible.length > 0) {
272
235
  e.preventDefault();
273
236
  focusItem(0);
@@ -82,7 +82,7 @@ rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, left
82
82
  borderRadius: "lg",
83
83
  fontSize: "13px",
84
84
  fontWeight: 500,
85
- color: theme.colors.gray[700],
85
+ color: theme.colors.text[700],
86
86
  transition: "background 0.12s",
87
87
  "& svg": { width: "16px", height: "16px" },
88
88
  ...(divider
@@ -93,8 +93,6 @@ rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, left
93
93
  borderColor: theme.colors.boxborder[200],
94
94
  }
95
95
  : {}),
96
- _hover: { bg: theme.colors.primary[50], color: theme.colors.primary[700] },
97
- _focus: { bg: theme.colors.primary[50], color: theme.colors.primary[700] },
98
96
  "&:last-child": { borderBottom: "none" },
99
97
  }, children: [option === null || option === void 0 ? void 0 : option.image, option.label] }, index))) }) })] })) : (rightIcon && ((0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": "Right icon button", icon: rightIcon, isLoading: RightIconLoading, onClick: onRightIconClick, onBlur: onBlurRightIcon, style: buttonGroupRightIconStyle, sx: gradientItemSx })))] }));
100
98
  }
@@ -20,7 +20,7 @@ const getFieldStateStyles = (theme, { error = false, focused = false } = {}) =>
20
20
  const ringPrimary = theme.colors.boxShadow.primary;
21
21
  const ringError = theme.colors.boxShadow.error;
22
22
  return {
23
- bg: theme.colors.gray[50],
23
+ bg: theme.colors.background[50],
24
24
  borderRadius: exports.FIELD_RADIUS,
25
25
  border: `${exports.FIELD_BORDER_WIDTH} solid`,
26
26
  borderColor: error ? errorColor : focused ? primary : idleBorder,
@@ -9,6 +9,7 @@ const react_2 = require("@chakra-ui/react");
9
9
  const lucide_react_1 = require("lucide-react");
10
10
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
11
11
  const accentText_1 = require("../../Theme/tokens/builders/accentText");
12
+ const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
12
13
  const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
13
14
  const ToolTip_1 = __importDefault(require("../ToolTip/ToolTip"));
14
15
  const CopyButton = ({ value, variant = "icon", label = "Copy", copiedLabel = "Copied!", tooltip = "Copy", feedbackDuration = 1500, iconSize = 16, size = "sm", onCopy, }) => {
@@ -34,17 +35,17 @@ const CopyButton = ({ value, variant = "icon", label = "Copy", copiedLabel = "Co
34
35
  // nearest rung that clears AA against the canvas this button actually sits on.
35
36
  const accent = (0, accentText_1.accentTextOnCanvas)(theme.colors.primary, theme.colors.backgroundColor.main);
36
37
  const success = theme.colors.semanticText.success;
38
+ const rowBackgrounds = (0, rowStates_1.listRowBackgrounds)(theme.colors);
37
39
  if (variant === "menu-item") {
38
- // Ink also sits on the row's own hover fill (gray[100]), not just the canvas — resolve against it.
39
- const hoverAccent = (0, accentText_1.accentTextOnCanvas)(theme.colors.primary, theme.colors.gray[100]);
40
- const hoverSuccess = (0, outlineRung_1.liftToContrast)(theme.colors.semantic.success[500], theme.colors.gray[100], accentText_1.AA_NORMAL_TEXT);
41
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "0.5rem", px: "12px", py: "8px", width: "100%", cursor: "pointer", borderRadius: "md", transition: "background 0.15s ease", _hover: { bg: theme.colors.gray[100] }, onClick: handleCopy, children: [copied ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconSize, color: hoverSuccess })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { size: iconSize, color: hoverAccent })), (0, jsx_runtime_1.jsx)(react_2.Box, { fontSize: "14px", fontWeight: 500, color: copied ? hoverSuccess : hoverAccent, children: copied ? copiedLabel : label })] }));
40
+ const hoverAccent = (0, accentText_1.accentTextOnCanvas)(theme.colors.primary, rowBackgrounds.active);
41
+ const hoverSuccess = (0, outlineRung_1.liftToContrast)(theme.colors.semantic.success[500], rowBackgrounds.active, accentText_1.AA_NORMAL_TEXT);
42
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "0.5rem", px: "12px", py: "8px", width: "100%", cursor: "pointer", borderRadius: "md", transition: "background 0.15s ease", _hover: { bg: rowBackgrounds.active }, onClick: handleCopy, children: [copied ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconSize, color: hoverSuccess })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { size: iconSize, color: hoverAccent })), (0, jsx_runtime_1.jsx)(react_2.Box, { fontSize: "14px", fontWeight: 500, color: copied ? hoverSuccess : hoverAccent, children: copied ? copiedLabel : label })] }));
42
43
  }
43
44
  if (variant === "button") {
44
45
  return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", align: "center", gap: "6px", px: "12px", py: "6px", borderRadius: "lg", border: "1px solid",
45
46
  // [800], not [500]: a real control boundary needs >=3:1 on every surface up to `muted`.
46
- borderColor: copied ? success : theme.colors.boxborder[500], bg: "transparent", color: copied ? success : theme.colors.gray[700], fontSize: "14px", fontWeight: 500, transition: "all 0.15s ease", _hover: { borderColor: accent, color: accent }, onClick: handleCopy, children: [copied ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconSize }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { size: iconSize }), (0, jsx_runtime_1.jsx)(react_2.Text, { children: copied ? copiedLabel : label })] }));
47
+ borderColor: copied ? success : theme.colors.boxborder[500], bg: "transparent", color: copied ? success : theme.colors.text[700], fontSize: "14px", fontWeight: 500, transition: "all 0.15s ease", _hover: { borderColor: accent, color: accent }, onClick: handleCopy, children: [copied ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconSize }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { size: iconSize }), (0, jsx_runtime_1.jsx)(react_2.Text, { children: copied ? copiedLabel : label })] }));
47
48
  }
48
- return ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: copied ? copiedLabel : tooltip, placement: "top", children: (0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": tooltip, size: size, variant: "ghost", onClick: handleCopy, color: copied ? success : theme.colors.gray[500], _hover: { color: accent, bg: theme.colors.primary[50] }, icon: copied ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconSize }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { size: iconSize }) }) }));
49
+ return ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: copied ? copiedLabel : tooltip, placement: "top", children: (0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": tooltip, size: size, variant: "ghost", onClick: handleCopy, color: copied ? success : theme.colors.textMuted, _hover: { color: accent, bg: rowBackgrounds.active }, icon: copied ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconSize }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { size: iconSize }) }) }));
49
50
  };
50
51
  exports.default = CopyButton;
@@ -124,7 +124,10 @@ const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, tempDate
124
124
  const customContent = renderDayContent ? renderDayContent(thisDay, states) : null;
125
125
  const markerColor = customContent == null && (stateVisual === null || stateVisual === void 0 ? void 0 : stateVisual.markerColor) ? stateVisual.markerColor : null;
126
126
  const hasDayOverlay = customContent != null || markerColor != null;
127
- days.push((0, jsx_runtime_1.jsx)(react_1.Box, { h: "2rem", display: "flex", alignItems: "center", justifyContent: "center", style: cellBg ? { background: cellBg } : undefined, children: (0, jsx_runtime_1.jsxs)(react_1.Box, { as: "button", type: "button", disabled: disabled, className: dayStates ? (0, dayStates_1.dayStateClassName)(states) : undefined, "aria-label": dayStates ? (0, dayStates_1.dayAccessibleName)((0, date_fns_1.format)(thisDay, "d MMMM yyyy"), states) : undefined, onClick: () => !disabled && onDaySelect(new Date(thisDay)), onMouseEnter: () => !disabled && (onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(new Date(thisDay))), position: hasDayOverlay ? "relative" : undefined, w: "1.75rem", h: "1.75rem", borderRadius: "full", display: "flex", alignItems: "center", justifyContent: "center", fontSize: "0.8125rem", fontWeight: circleSolid ? 600 : 500, lineHeight: "1", cursor: disabled ? "not-allowed" : "pointer", bg: circleSolid ? solidFill : "transparent", color: dayColor, textDecoration: (stateVisual === null || stateVisual === void 0 ? void 0 : stateVisual.strikethrough) ? "line-through" : undefined, border: dayBorder, transition: "background 0.12s, color 0.12s", _hover: disabled
127
+ const dayLabel = dayStates
128
+ ? (0, dayStates_1.dayAccessibleName)((0, date_fns_1.format)(thisDay, "d MMMM yyyy"), states)
129
+ : (0, date_fns_1.format)(thisDay, "d MMMM yyyy");
130
+ days.push((0, jsx_runtime_1.jsx)(react_1.Box, { role: "gridcell", h: "2rem", display: "flex", alignItems: "center", justifyContent: "center", style: cellBg ? { background: cellBg } : undefined, children: (0, jsx_runtime_1.jsxs)(react_1.Box, { as: "button", type: "button", disabled: disabled, className: dayStates ? (0, dayStates_1.dayStateClassName)(states) : undefined, "aria-label": dayLabel, "aria-selected": isSelected || isStart || isEnd || undefined, "aria-current": isToday ? "date" : undefined, onClick: () => !disabled && onDaySelect(new Date(thisDay)), onMouseEnter: () => !disabled && (onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(new Date(thisDay))), position: hasDayOverlay ? "relative" : undefined, w: "1.75rem", h: "1.75rem", borderRadius: "full", display: "flex", alignItems: "center", justifyContent: "center", fontSize: "0.8125rem", fontWeight: circleSolid ? 600 : 500, lineHeight: "1", cursor: disabled ? "not-allowed" : "pointer", bg: circleSolid ? solidFill : "transparent", color: dayColor, textDecoration: (stateVisual === null || stateVisual === void 0 ? void 0 : stateVisual.strikethrough) ? "line-through" : undefined, border: dayBorder, transition: "background 0.12s, color 0.12s", _hover: disabled
128
131
  ? {}
129
132
  : circleSolid
130
133
  ? { bg: solidHoverFill, color: circleHoverColor }
@@ -133,14 +136,14 @@ const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, tempDate
133
136
  pointerEvents: "none", children: customContent !== null && customContent !== void 0 ? customContent : ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "span", className: `${dayStates_1.DAY_CLASS}__marker`, w: "0.25rem", h: "0.25rem", borderRadius: "full", bg: markerColor })) }))] }) }, thisDay.toString()));
134
137
  day = (0, date_fns_1.addDays)(day, 1);
135
138
  }
136
- rows.push((0, jsx_runtime_1.jsx)(react_1.Grid, { templateColumns: "repeat(7, 1fr)", gap: 0, children: days }, day.toString()));
139
+ rows.push((0, jsx_runtime_1.jsx)(react_1.Box, { role: "row", display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0, children: days }, day.toString()));
137
140
  }
138
141
  return rows;
139
142
  };
140
- return ((0, jsx_runtime_1.jsxs)(react_1.Box, { children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2, gap: 1, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1, 1)), "aria-label": "Previous month", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeftIcon, { size: 16 }) }), (0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", alignItems: "center", gap: 1.5, minW: 0, children: [(0, jsx_runtime_1.jsx)(react_1.Box, { as: "select", value: currentMonth.getMonth(), onChange: (e) => {
143
+ return ((0, jsx_runtime_1.jsxs)(react_1.Box, { children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2, gap: 1, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1, 1)), "aria-label": "Previous month", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeftIcon, { size: 16 }) }), (0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", alignItems: "center", gap: 1.5, minW: 0, children: [(0, jsx_runtime_1.jsx)(react_1.Box, { as: "select", "aria-label": "Month", value: currentMonth.getMonth(), onChange: (e) => {
141
144
  const newMonth = parseInt(e.target.value, 10);
142
145
  setCurrentMonth((prev) => new Date(prev.getFullYear(), newMonth, 1));
143
- }, ...selectStyles, children: Array.from({ length: 12 }).map((_, i) => ((0, jsx_runtime_1.jsx)("option", { value: i, children: (0, date_fns_1.format)(new Date(2000, i, 1), "MMMM") }, i))) }), (0, jsx_runtime_1.jsx)(react_1.Box, { as: "select", value: currentMonth.getFullYear(), onChange: (e) => {
146
+ }, ...selectStyles, children: Array.from({ length: 12 }).map((_, i) => ((0, jsx_runtime_1.jsx)("option", { value: i, children: (0, date_fns_1.format)(new Date(2000, i, 1), "MMMM") }, i))) }), (0, jsx_runtime_1.jsx)(react_1.Box, { as: "select", "aria-label": "Year", value: currentMonth.getFullYear(), onChange: (e) => {
144
147
  const newYear = parseInt(e.target.value, 10);
145
148
  setCurrentMonth((prev) => new Date(newYear, prev.getMonth(), 1));
146
149
  }, ...selectStyles, children: Array.from({ length: 100 }).map((_, i) => {
@@ -151,7 +154,7 @@ const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, tempDate
151
154
  if (!disableToday) {
152
155
  onDaySelect(new Date(today));
153
156
  }
154
- }, "aria-label": "Today", sx: { fontSize: "0.7rem", px: 2, flexShrink: 0 }, isDisabled: disableToday, children: "Today" })), (0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1, 1)), "aria-label": "Next month", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRightIcon, { size: 16 }) })] })] }), renderWeekdays !== null && renderWeekdays !== void 0 ? renderWeekdays : ((0, jsx_runtime_1.jsx)(react_1.Grid, { templateColumns: "repeat(7, 1fr)", gap: 0, mb: 1, children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => ((0, jsx_runtime_1.jsx)(react_1.Box, { textAlign: "center", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.02em", color: theme.colors.textMuted, py: 1, children: day }, day))) })), (0, jsx_runtime_1.jsx)(react_1.Box, { onMouseLeave: () => onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(null), children: renderDays() })] }));
157
+ }, "aria-label": "Today", sx: { fontSize: "0.7rem", px: 2, flexShrink: 0 }, isDisabled: disableToday, children: "Today" })), (0, jsx_runtime_1.jsx)(Button_1.default, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1, 1)), "aria-label": "Next month", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRightIcon, { size: 16 }) })] })] }), (0, jsx_runtime_1.jsxs)(react_1.Box, { role: "grid", "aria-label": "Calendar", children: [renderWeekdays !== null && renderWeekdays !== void 0 ? renderWeekdays : ((0, jsx_runtime_1.jsx)(react_1.Box, { role: "row", display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0, mb: 1, children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => ((0, jsx_runtime_1.jsx)(react_1.Box, { role: "columnheader", textAlign: "center", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.02em", color: theme.colors.textMuted, py: 1, children: day }, day))) })), (0, jsx_runtime_1.jsx)(react_1.Box, { onMouseLeave: () => onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(null), children: renderDays() })] })] }));
155
158
  };
156
159
  exports.CalendarPanel = CalendarPanel;
157
160
  exports.default = exports.CalendarPanel;
@@ -18,6 +18,7 @@ const useCustomTheme_1 = require("../../Theme/useCustomTheme");
18
18
  const textInputIconSize_1 = require("../Input/textInputIconSize");
19
19
  const TimePicker_1 = __importDefault(require("./TimePicker"));
20
20
  const TimePickerInput_1 = require("./TimePickerInput");
21
+ const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
21
22
  // helper to set time on date while preserving date part
22
23
  const setTimeFrom = (base, time) => {
23
24
  const b = base ? new Date(base) : new Date();
@@ -31,6 +32,9 @@ const RangeDatePicker = (props) => {
31
32
  const calendarIconPx = (0, textInputIconSize_1.getTextInputIconSizePx)(sizeKey);
32
33
  const calendarIconWrapperSx = (0, textInputIconSize_1.getTextInputIconWrapperSx)(sizeKey);
33
34
  const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
35
+ const requestExclusiveOpen = (0, useExclusiveOverlay_1.useExclusiveOverlay)(isOpen, onClose);
36
+ const errorFieldId = id ? `${id}-error` : undefined;
37
+ const calendarLabel = label !== null && label !== void 0 ? label : "Choose date range";
34
38
  const inputRef = (0, react_1.useRef)(null);
35
39
  const triggerRef = (0, react_1.useRef)(null);
36
40
  const popoverRef = (0, react_1.useRef)(null);
@@ -97,8 +101,20 @@ const RangeDatePicker = (props) => {
97
101
  onClose();
98
102
  };
99
103
  const handleOpen = () => {
104
+ requestExclusiveOpen();
100
105
  onOpen();
101
106
  };
107
+ const handleInputKeyDown = (e) => {
108
+ if (e.key === "Escape" && isOpen) {
109
+ e.preventDefault();
110
+ onClose();
111
+ return;
112
+ }
113
+ if (!isOpen && (e.key === "ArrowDown" || e.key === "Enter")) {
114
+ e.preventDefault();
115
+ handleOpen();
116
+ }
117
+ };
102
118
  const handleDaySelect = (day) => {
103
119
  const updated = new Date(day);
104
120
  if (selectingStart) {
@@ -165,7 +181,7 @@ const RangeDatePicker = (props) => {
165
181
  return `${(0, date_fns_1.format)(tempRangeStart, dateFormat)} -`;
166
182
  return "";
167
183
  }, [inputValue, tempRangeStart, tempRangeEnd, dateFormat]);
168
- return ((0, jsx_runtime_1.jsxs)(react_2.FormControl, { id: id, isInvalid: error, isRequired: isRequired, isDisabled: disabled, width: width, children: [label && ((0, jsx_runtime_1.jsx)(FormLabel_1.TextLabel, { label: label, isRequired: isRequired, isInformation: isInformation, informationMessage: informationMessage })), (0, jsx_runtime_1.jsxs)(react_2.Popover, { isLazy: true, isOpen: isOpen, onClose: finalize, placement: "bottom-start", closeOnBlur: false, returnFocusOnClose: false, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_2.Box, { ref: triggerRef, as: "div", children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: sizeKey, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { ref: inputRef, id: id, name: name, size: sizeKey, placeholder: placeholder, value: displayValue, readOnly: true, isDisabled: disabled, autoComplete: autoComplete, onFocus: () => {
184
+ return ((0, jsx_runtime_1.jsxs)(react_2.FormControl, { id: id, isInvalid: error, isRequired: isRequired, isDisabled: disabled, width: width, children: [label && ((0, jsx_runtime_1.jsx)(FormLabel_1.TextLabel, { label: label, id: id, isRequired: isRequired, isInformation: isInformation, informationMessage: informationMessage })), (0, jsx_runtime_1.jsxs)(react_2.Popover, { isLazy: true, isOpen: isOpen, onClose: finalize, placement: "bottom-start", closeOnBlur: false, returnFocusOnClose: true, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverAnchor, { children: (0, jsx_runtime_1.jsx)(react_2.Box, { ref: triggerRef, as: "div", children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: sizeKey, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { ref: inputRef, id: id, name: name, size: sizeKey, placeholder: placeholder, value: displayValue, readOnly: true, isDisabled: disabled, isInvalid: error, isRequired: isRequired, "aria-describedby": error && errorMessage ? errorFieldId : undefined, autoComplete: autoComplete, onKeyDown: handleInputKeyDown, onFocus: () => {
169
185
  if (!isOpen)
170
186
  handleOpen();
171
187
  }, onClick: () => {
@@ -178,7 +194,15 @@ const RangeDatePicker = (props) => {
178
194
  : `0 0 0 1px ${theme.colors.primary[500]}`,
179
195
  }, _hover: {
180
196
  borderColor: error ? theme.colors.semanticText.error : undefined,
181
- }, cursor: "pointer" }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", style: { cursor: "pointer" }, onClick: () => (isOpen ? onClose() : handleOpen()), children: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", sx: calendarIconWrapperSx, children: (0, jsx_runtime_1.jsx)(lucide_react_1.CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { w: "18rem", maxW: "18rem", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { display: "flex", flexWrap: "wrap", gap: 2, mb: 3, children: presets.map((p) => ((0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "gray", sx: { flex: "1 1 auto" }, onClick: () => {
197
+ }, cursor: "pointer" }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", children: (0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": "Open calendar", variant: "ghost", size: "sm", minW: "auto", h: "auto", isDisabled: disabled, onClick: (e) => {
198
+ e.stopPropagation();
199
+ if (!isOpen) {
200
+ handleOpen();
201
+ }
202
+ else {
203
+ onClose();
204
+ }
205
+ }, icon: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", sx: calendarIconWrapperSx, children: (0, jsx_runtime_1.jsx)(lucide_react_1.CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) }) })] }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { w: "18rem", maxW: "18rem", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], role: "dialog", "aria-label": calendarLabel, children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { display: "flex", flexWrap: "wrap", gap: 2, mb: 3, children: presets.map((p) => ((0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "gray", sx: { flex: "1 1 auto" }, onClick: () => {
182
206
  const [from, to] = p.getRange();
183
207
  applyPreset(from, to);
184
208
  }, children: p.label }, p.label))) }), (0, jsx_runtime_1.jsx)(CalendarPanel_1.default, { currentMonth: currentMonth, setCurrentMonth: (updater) => setCurrentMonthState((prev) => updater(prev)), today: today, isRange: true, tempDate: null, tempRangeStart: tempRangeStart, tempRangeEnd: tempRangeEnd, hoveredDate: hoveredDate, onDayHover: setHoveredDate, isSameDay: date_fns_1.isSameDay, isBefore: date_fns_1.isBefore, isAfter: date_fns_1.isAfter, minDate: minDate, maxDate: maxDate, disablePastDates: disablePastDates, disableFutureDates: disableFutureDates, disableToday: disableToday, onDaySelect: handleDaySelect, dayStates: dayStates, renderDayContent: renderDayContent }), formatHasTime && ((0, jsx_runtime_1.jsxs)(react_2.Box, { mt: 3, display: "grid", gridTemplateColumns: "1fr", gap: 2, children: [(0, jsx_runtime_1.jsxs)(react_2.Box, { children: [(0, jsx_runtime_1.jsx)(react_2.Box, { fontSize: "xs", color: theme.colors.textMuted, mb: 1, children: "Start time" }), shouldUseSelectTimePicker ? ((0, jsx_runtime_1.jsx)(TimePicker_1.default, { date: startTimeBaseDate, onChange: (updated) => {
@@ -207,7 +231,7 @@ const RangeDatePicker = (props) => {
207
231
  return;
208
232
  }
209
233
  setTempRangeEnd(setTimeFrom(endTimeBaseDate, t));
210
- }, dateFormat: timePickerFormat, disabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) })] }), error && errorMessage && (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { errorMessage: errorMessage }), helperText && !error && (0, jsx_runtime_1.jsx)(HelperText_1.default, { helperText: helperText })] }));
234
+ }, dateFormat: timePickerFormat, disabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) })] }), error && errorMessage && ((0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { id: errorFieldId, errorMessage: errorMessage })), helperText && !error && (0, jsx_runtime_1.jsx)(HelperText_1.default, { helperText: helperText })] }));
211
235
  };
212
236
  exports.RangeDatePicker = RangeDatePicker;
213
237
  exports.default = exports.RangeDatePicker;
@@ -18,6 +18,7 @@ const ErrorMessage_1 = __importDefault(require("../Common/ErrorMessage"));
18
18
  const TimePicker_1 = __importDefault(require("./TimePicker"));
19
19
  const TimePickerInput_1 = require("./TimePickerInput");
20
20
  const CalendarPanel_1 = __importDefault(require("./CalendarPanel"));
21
+ const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
21
22
  const TOKEN_CHARS = /[dMyHhmsaAm]/;
22
23
  const getPlaceholderForToken = (token, length) => {
23
24
  const lower = token.toLowerCase();
@@ -232,6 +233,9 @@ const SingleDatePicker = (props) => {
232
233
  const calendarIconPx = (0, textInputIconSize_1.getTextInputIconSizePx)(sizeKey);
233
234
  const calendarIconWrapperSx = (0, textInputIconSize_1.getTextInputIconWrapperSx)(sizeKey);
234
235
  const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
236
+ const requestExclusiveOpen = (0, useExclusiveOverlay_1.useExclusiveOverlay)(isOpen, onClose);
237
+ const errorFieldId = id ? `${id}-error` : undefined;
238
+ const calendarLabel = label !== null && label !== void 0 ? label : "Choose date";
235
239
  const inputRef = (0, react_1.useRef)(null);
236
240
  const popoverRef = (0, react_1.useRef)(null);
237
241
  const triggerRef = (0, react_1.useRef)(null);
@@ -393,6 +397,7 @@ const SingleDatePicker = (props) => {
393
397
  }
394
398
  }, [inputValue, tokenSegments, enableMask, isMaskActive]);
395
399
  const handleOpen = () => {
400
+ requestExclusiveOpen();
396
401
  if (!selectedDate && showDate) {
397
402
  setTempDate(disableToday ? tomorrow : new Date());
398
403
  }
@@ -783,14 +788,28 @@ const SingleDatePicker = (props) => {
783
788
  }
784
789
  if (key === "Escape") {
785
790
  e.preventDefault();
786
- (_d = inputRef.current) === null || _d === void 0 ? void 0 : _d.blur();
791
+ if (isOpen) {
792
+ onClose();
793
+ }
794
+ else {
795
+ (_d = inputRef.current) === null || _d === void 0 ? void 0 : _d.blur();
796
+ }
787
797
  return;
788
798
  }
789
799
  if (key === "Enter") {
790
800
  e.preventDefault();
801
+ if (!isOpen && showDate) {
802
+ handleOpen();
803
+ return;
804
+ }
791
805
  handleInputBlur();
792
806
  return;
793
807
  }
808
+ if (key === "ArrowDown" && !isOpen && showDate) {
809
+ e.preventDefault();
810
+ handleOpen();
811
+ return;
812
+ }
794
813
  if (key === "Backspace" || key === "Delete") {
795
814
  e.preventDefault();
796
815
  const baseValue = ensureMaskValue();
@@ -932,20 +951,35 @@ const SingleDatePicker = (props) => {
932
951
  };
933
952
  const handleInputFocusMask = enableMask ? handleInputFocus : undefined;
934
953
  const handleInputClickMask = enableMask ? handleInputClick : undefined;
935
- const handleKeyDownMask = enableMask ? handleKeyDown : undefined;
936
954
  const handlePasteMask = enableMask ? handlePaste : undefined;
955
+ const handleInputKeyDown = (e) => {
956
+ if (!enableMask) {
957
+ if (e.key === "Escape" && isOpen) {
958
+ e.preventDefault();
959
+ onClose();
960
+ return;
961
+ }
962
+ if (!isOpen && showDate && (e.key === "ArrowDown" || e.key === "Enter")) {
963
+ e.preventDefault();
964
+ handleOpen();
965
+ return;
966
+ }
967
+ return;
968
+ }
969
+ handleKeyDown(e);
970
+ };
937
971
  const displayValue = isTyping
938
972
  ? inputValue
939
973
  : tempDate
940
974
  ? (0, date_fns_1.format)(tempDate, resolvedDateFormat)
941
975
  : "";
942
- return ((0, jsx_runtime_1.jsxs)(react_2.FormControl, { id: id, isDisabled: disabled, width: width, children: [label && ((0, jsx_runtime_1.jsx)(FormLabel_1.TextLabel, { label: label, isRequired: isRequired, isInformation: isInformation, informationMessage: informationMessage })), (0, jsx_runtime_1.jsxs)(react_2.Popover, { isLazy: true, isOpen: isOpen, onClose: () => {
976
+ return ((0, jsx_runtime_1.jsxs)(react_2.FormControl, { id: id, isDisabled: disabled, isInvalid: error, isRequired: isRequired, width: width, children: [label && ((0, jsx_runtime_1.jsx)(FormLabel_1.TextLabel, { label: label, id: id, isRequired: isRequired, isInformation: isInformation, informationMessage: informationMessage })), (0, jsx_runtime_1.jsxs)(react_2.Popover, { isLazy: true, isOpen: isOpen, onClose: () => {
943
977
  if (suppressOnCloseFinalizeRef.current) {
944
978
  suppressOnCloseFinalizeRef.current = false;
945
979
  return;
946
980
  }
947
981
  finalize();
948
- }, placement: "bottom-start", closeOnBlur: false, returnFocusOnClose: false, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_2.Box, { ref: triggerRef, as: "div", children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: sizeKey, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { ref: inputRef, id: id, name: name, size: sizeKey, placeholder: displayPlaceholder, value: displayValue, onChange: handleInputChange, onKeyDown: handleKeyDownMask, onPaste: handlePasteMask, onBlur: handleInputBlur, onClick: handleInputClickMask, onFocus: handleInputFocusMask, isDisabled: disabled, autoComplete: autoComplete, bg: theme.colors.gray[50], borderColor: error
982
+ }, placement: "bottom-start", closeOnBlur: false, returnFocusOnClose: true, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverAnchor, { children: (0, jsx_runtime_1.jsx)(react_2.Box, { ref: triggerRef, as: "div", children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: sizeKey, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { ref: inputRef, id: id, name: name, size: sizeKey, placeholder: displayPlaceholder, value: displayValue, onChange: handleInputChange, onKeyDown: handleInputKeyDown, onPaste: handlePasteMask, onBlur: handleInputBlur, onClick: handleInputClickMask, onFocus: handleInputFocusMask, isDisabled: disabled, isInvalid: error, isRequired: isRequired, "aria-describedby": error && errorMessage ? errorFieldId : undefined, autoComplete: autoComplete, bg: theme.colors.background[50], borderColor: error
949
983
  ? theme.colors.semanticText.error
950
984
  : theme.colors.boxborder[500], _focus: {
951
985
  borderColor: error ? theme.colors.semanticText.error : theme.colors.primary[500],
@@ -954,15 +988,15 @@ const SingleDatePicker = (props) => {
954
988
  : `0 0 0 0.125rem ${theme.colors.boxShadow.primary}`,
955
989
  }, _hover: {
956
990
  borderColor: error ? theme.colors.semanticText.error : theme.colors.primary[500],
957
- }, cursor: "text", boxShadow: error ? `0 0 0 0.125rem ${theme.colors.boxShadow.error}` : `` }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", onClick: (e) => {
958
- e.stopPropagation();
959
- if (!isOpen) {
960
- handleOpen();
961
- }
962
- else {
963
- onClose();
964
- }
965
- }, style: { cursor: "pointer" }, children: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", sx: calendarIconWrapperSx, children: (0, jsx_runtime_1.jsx)(lucide_react_1.CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { width: "auto", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [showDate && ((0, jsx_runtime_1.jsx)(CalendarPanel_1.default, { currentMonth: currentMonth, setCurrentMonth: (updater) => setCurrentMonth((prev) => updater(prev)), today: today, isRange: false, tempDate: tempDate, tempRangeStart: null, tempRangeEnd: null, isSameDay: date_fns_1.isSameDay, isBefore: date_fns_1.isBefore, isAfter: date_fns_1.isAfter, minDate: minDate, maxDate: maxDate, disablePastDates: disablePastDates, disableFutureDates: disableFutureDates, disableToday: disableToday, onDaySelect: handleDaySelect })), showTime && ((0, jsx_runtime_1.jsx)(react_2.Box, { mt: showDate ? 3 : 0, children: resolvedPickerType === "time" ? ((0, jsx_runtime_1.jsx)(TimePickerInput_1.TimePickerInput, { value: tempDate, onChange: (updatedDate) => {
991
+ }, cursor: "text", boxShadow: error ? `0 0 0 0.125rem ${theme.colors.boxShadow.error}` : `` }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", children: (0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": "Open calendar", variant: "ghost", size: "sm", minW: "auto", h: "auto", isDisabled: disabled, onClick: (e) => {
992
+ e.stopPropagation();
993
+ if (!isOpen) {
994
+ handleOpen();
995
+ }
996
+ else {
997
+ onClose();
998
+ }
999
+ }, icon: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", sx: calendarIconWrapperSx, children: (0, jsx_runtime_1.jsx)(lucide_react_1.CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) }) })] }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { width: "auto", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], role: "dialog", "aria-label": calendarLabel, children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [showDate && ((0, jsx_runtime_1.jsx)(CalendarPanel_1.default, { currentMonth: currentMonth, setCurrentMonth: (updater) => setCurrentMonth((prev) => updater(prev)), today: today, isRange: false, tempDate: tempDate, tempRangeStart: null, tempRangeEnd: null, isSameDay: date_fns_1.isSameDay, isBefore: date_fns_1.isBefore, isAfter: date_fns_1.isAfter, minDate: minDate, maxDate: maxDate, disablePastDates: disablePastDates, disableFutureDates: disableFutureDates, disableToday: disableToday, onDaySelect: handleDaySelect })), showTime && ((0, jsx_runtime_1.jsx)(react_2.Box, { mt: showDate ? 3 : 0, children: resolvedPickerType === "time" ? ((0, jsx_runtime_1.jsx)(TimePickerInput_1.TimePickerInput, { value: tempDate, onChange: (updatedDate) => {
966
1000
  setTempDate(updatedDate);
967
1001
  setInputValue(updatedDate ? (0, date_fns_1.format)(updatedDate, resolvedDateFormat) : "");
968
1002
  setIsTyping(false);
@@ -973,7 +1007,7 @@ const SingleDatePicker = (props) => {
973
1007
  }, disabled: disabled })) })), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: () => {
974
1008
  setTempDate(null);
975
1009
  requestClose(null);
976
- }, children: "Clear" }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "gradient", onClick: () => requestClose(), children: "Apply" })] })] }) })] }), error && errorMessage && (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { errorMessage: errorMessage }), helperText && !error && (0, jsx_runtime_1.jsx)(HelperText_1.default, { helperText: helperText })] }));
1010
+ }, children: "Clear" }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "gradient", onClick: () => requestClose(), children: "Apply" })] })] }) })] }), error && errorMessage && ((0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { id: errorFieldId, errorMessage: errorMessage })), helperText && !error && (0, jsx_runtime_1.jsx)(HelperText_1.default, { helperText: helperText })] }));
977
1011
  };
978
1012
  exports.SingleDatePicker = SingleDatePicker;
979
1013
  exports.default = exports.SingleDatePicker;
@@ -13,6 +13,7 @@ const HelperText_1 = __importDefault(require("../Common/HelperText"));
13
13
  const ErrorMessage_1 = __importDefault(require("../Common/ErrorMessage"));
14
14
  const TimePicker_1 = __importDefault(require("./TimePicker"));
15
15
  const TimePickerInput_1 = require("./TimePickerInput");
16
+ const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
16
17
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
17
18
  const formatToPlaceholder = (formatStr) => formatStr.replace(/h{1,2}/gi, "HH").replace(/m{1,2}/gi, "mm").replace(/a{1,2}/gi, "AM");
18
19
  const TimeOnlyPicker = (props) => {
@@ -20,6 +21,11 @@ const TimeOnlyPicker = (props) => {
20
21
  const { id, label, isRequired, isInformation, informationMessage, error, errorMessage, helperText, placeholderText, dateFormat = "HH:mm", disabled, width = "100%", disableToday = false, size = "md", } = props;
21
22
  const theme = (0, useCustomTheme_1.useCustomTheme)();
22
23
  const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
24
+ const requestExclusiveOpen = (0, useExclusiveOverlay_1.useExclusiveOverlay)(isOpen, onClose);
25
+ const openPicker = () => {
26
+ requestExclusiveOpen();
27
+ onOpen();
28
+ };
23
29
  const popoverRef = (0, react_1.useRef)(null);
24
30
  const triggerRef = (0, react_1.useRef)(null);
25
31
  const inputWrapperRef = (0, react_1.useRef)(null);
@@ -76,7 +82,7 @@ const TimeOnlyPicker = (props) => {
76
82
  handleTimeInputChange(date);
77
83
  }, dateFormat: dateFormat, disabled: disabled, placeholder: placeholder, onFocus: () => {
78
84
  if (!disabled && !isOpen)
79
- onOpen();
85
+ openPicker();
80
86
  }, error: error, size: sizeKey }) }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { width: "auto", p: 4, ref: popoverRef, boxShadow: "lg", bg: theme.colors.background[50], children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { children: [(0, jsx_runtime_1.jsx)(TimePicker_1.default, { date: resolvedTempDate, dateFormat: dateFormat, onChange: (updatedDate) => {
81
87
  handleTimePickerChange(updatedDate);
82
88
  } }), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [(0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", variant: "ghost", onClick: handleClear, children: "Clear" }), (0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", colorScheme: "primary", onClick: handleOk, children: "OK" })] })] }) })] }), error && errorMessage && (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { errorMessage: errorMessage }), helperText && !error && (0, jsx_runtime_1.jsx)(HelperText_1.default, { helperText: helperText })] }));
@@ -54,16 +54,16 @@ const TimePicker = ({ date, onChange, dateFormat, disabled = false }) => {
54
54
  updateTime(hour, minute, newMeridiem);
55
55
  };
56
56
  const displayHour = is12HourFormat ? (hour % 12 === 0 ? 12 : hour % 12) : hour;
57
- return ((0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 1.5, w: "100%", children: [(0, jsx_runtime_1.jsx)(react_2.Select, { value: displayHour, onChange: handleHourChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: theme.colors.gray[50], borderColor: theme.colors.boxborder[500], _focus: {
57
+ return ((0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 1.5, w: "100%", children: [(0, jsx_runtime_1.jsx)(react_2.Select, { "aria-label": "Hour", value: displayHour, onChange: handleHourChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: theme.colors.background[50], borderColor: theme.colors.boxborder[500], _focus: {
58
58
  borderColor: theme.colors.primary[500],
59
59
  boxShadow: `0 0 0 0.125rem ${theme.colors.boxShadow.primary}`,
60
60
  }, _hover: { borderColor: theme.colors.primary[500] }, children: Array.from({ length: is12HourFormat ? 12 : 24 }, (_, i) => {
61
61
  const value = is12HourFormat ? i + 1 : i;
62
62
  return ((0, jsx_runtime_1.jsx)("option", { value: value, children: value.toString().padStart(2, "0") }, value));
63
- }) }), (0, jsx_runtime_1.jsx)(react_2.Select, { value: minute, onChange: handleMinuteChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: theme.colors.gray[50], borderColor: theme.colors.boxborder[500], _focus: {
63
+ }) }), (0, jsx_runtime_1.jsx)(react_2.Select, { "aria-label": "Minute", value: minute, onChange: handleMinuteChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: theme.colors.background[50], borderColor: theme.colors.boxborder[500], _focus: {
64
64
  borderColor: theme.colors.primary[500],
65
65
  boxShadow: `0 0 0 0.125rem ${theme.colors.boxShadow.primary}`,
66
- }, _hover: { borderColor: theme.colors.primary[500] }, children: Array.from({ length: 60 }, (_, i) => ((0, jsx_runtime_1.jsx)("option", { value: i, children: i.toString().padStart(2, "0") }, i))) }), is12HourFormat && ((0, jsx_runtime_1.jsxs)(react_2.Select, { value: ampm, onChange: handleAmpmChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: theme.colors.gray[50], borderColor: theme.colors.boxborder[500], _focus: {
66
+ }, _hover: { borderColor: theme.colors.primary[500] }, children: Array.from({ length: 60 }, (_, i) => ((0, jsx_runtime_1.jsx)("option", { value: i, children: i.toString().padStart(2, "0") }, i))) }), is12HourFormat && ((0, jsx_runtime_1.jsxs)(react_2.Select, { "aria-label": "AM or PM", value: ampm, onChange: handleAmpmChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: theme.colors.background[50], borderColor: theme.colors.boxborder[500], _focus: {
67
67
  borderColor: theme.colors.primary[500],
68
68
  boxShadow: `0 0 0 0.125rem ${theme.colors.boxShadow.primary}`,
69
69
  }, _hover: { borderColor: theme.colors.primary[500] }, children: [(0, jsx_runtime_1.jsx)("option", { value: "AM", children: "AM" }), (0, jsx_runtime_1.jsx)("option", { value: "PM", children: "PM" })] }))] }));
@@ -403,7 +403,7 @@ const TimePickerInput = ({ value, onChange, dateFormat, disabled = false, placeh
403
403
  inputRef.current.value = is12Hour && formatted ? `${formatted} ${ampm}` : formatted;
404
404
  }
405
405
  }, [digits, ampm, is12Hour]);
406
- return ((0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: sizeKey, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { ref: inputRef, defaultValue: "", onChange: handleInput, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, onClick: handleClick, onPaste: handlePaste, placeholder: placeholderText, isDisabled: disabled, autoComplete: "off", isInvalid: error, size: sizeKey, bg: theme.colors.gray[50], borderColor: error ? theme.colors.semanticText.error : theme.colors.boxborder[500], _focus: {
406
+ return ((0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: sizeKey, children: [(0, jsx_runtime_1.jsx)(react_2.Input, { ref: inputRef, defaultValue: "", onChange: handleInput, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, onClick: handleClick, onPaste: handlePaste, placeholder: placeholderText, isDisabled: disabled, autoComplete: "off", isInvalid: error, size: sizeKey, bg: theme.colors.background[50], borderColor: error ? theme.colors.semanticText.error : theme.colors.boxborder[500], _focus: {
407
407
  borderColor: error ? theme.colors.semanticText.error : theme.colors.primary[500],
408
408
  boxShadow: error
409
409
  ? `0 0 0 0.125rem ${theme.colors.boxShadow.error}`
@@ -6,7 +6,8 @@ const react_2 = require("@chakra-ui/react");
6
6
  const framer_motion_1 = require("framer-motion");
7
7
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
8
8
  const scrollbar_1 = require("../../Theme/tokens/builders/scrollbar");
9
- const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
9
+ const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
10
+ const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
10
11
  const lucide_react_1 = require("lucide-react");
11
12
  const rafThrottle_1 = require("../../Utils/rafThrottle");
12
13
  const MotionBox = (0, framer_motion_1.motion)((0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(react_2.Box, { ref: ref, ...props }))));
@@ -21,7 +22,9 @@ const SIZE_MAP = {
21
22
  const Dropdown = (0, react_1.forwardRef)(({ dropDownButtonStyle, ButtonText, options, handleOptionSelect, dropdownType = "button", text, DropdownIcon, isVisibleIconShow = true, buttonProps, headStyle, ListStyle, ItemStyle, LabelStyle, ImageStyle, size, optionsSize, divider = false, ariaLabel, }, ref) => {
22
23
  var _a, _b;
23
24
  const theme = (0, useCustomTheme_1.useCustomTheme)();
24
- const { isOpen, onOpen, onToggle, onClose } = (0, react_2.useDisclosure)();
25
+ const rowBackgrounds = (0, react_1.useMemo)(() => (0, rowStates_1.listRowBackgrounds)(theme.colors), [theme.colors]);
26
+ const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
27
+ const requestExclusiveOpen = (0, useExclusiveOverlay_1.useExclusiveOverlay)(isOpen, onClose);
25
28
  const dropdownRef = (0, react_1.useRef)(null);
26
29
  const menuRef = (0, react_1.useRef)(null);
27
30
  const [menuPos, setMenuPos] = (0, react_1.useState)({ top: 0, left: 0, width: 0 });
@@ -51,6 +54,16 @@ const Dropdown = (0, react_1.forwardRef)(({ dropDownButtonStyle, ButtonText, opt
51
54
  }
52
55
  else {
53
56
  pendingFocusIndex.current = index;
57
+ requestExclusiveOpen();
58
+ onOpen();
59
+ }
60
+ };
61
+ const handleToggle = () => {
62
+ if (isOpen) {
63
+ onClose();
64
+ }
65
+ else {
66
+ requestExclusiveOpen();
54
67
  onOpen();
55
68
  }
56
69
  };
@@ -93,7 +106,7 @@ const Dropdown = (0, react_1.forwardRef)(({ dropDownButtonStyle, ButtonText, opt
93
106
  // `fireEvent` does not simulate a real browser's Enter/Space-activates-
94
107
  // button default action either.
95
108
  e.preventDefault();
96
- onToggle();
109
+ handleToggle();
97
110
  }
98
111
  };
99
112
  const handleMenuKeyDown = (e) => {
@@ -209,13 +222,13 @@ const Dropdown = (0, react_1.forwardRef)(({ dropDownButtonStyle, ButtonText, opt
209
222
  };
210
223
  const Chevron = isVisibleIconShow ? ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", display: "inline-flex", transition: "transform 0.2s ease", transform: isOpen ? "rotate(180deg)" : "rotate(0deg)", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { size: s.chevron }) })) : undefined;
211
224
  const dropDownToggleOption = () => {
212
- const ButtonToggle = ((0, jsx_runtime_1.jsx)(react_2.Button, { ref: buttonTriggerRef, onClick: onToggle, onKeyDown: handleTriggerKeyDown, size: s.btn, colorScheme: "primary", borderRadius: "lg", fontWeight: 600, "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (ButtonText ? undefined : "Open menu"), rightIcon: Chevron, sx: { transition: "all 0.15s ease", ...(dropDownButtonStyle) }, ...buttonProps, children: (0, jsx_runtime_1.jsxs)(react_2.Box, { as: "span", display: "inline-flex", alignItems: "center", gap: DropdownIcon && ButtonText ? s.gap : 0, children: [DropdownIcon, ButtonText] }) }));
213
- const TextToggle = ((0, jsx_runtime_1.jsxs)(react_2.Flex, { ref: textTriggerRef, onClick: onToggle, onKeyDown: handleTriggerKeyDown, align: "center", gap: 1.5, cursor: "pointer", fontSize: s.fontSize, fontWeight: 500, color: theme.colors.text[700], transition: "color 0.15s ease", _hover: { color: theme.colors.accentText }, style: dropDownButtonStyle, role: "button", tabIndex: 0, "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (text ? undefined : "Open menu"), children: [DropdownIcon, text, Chevron] }));
225
+ const ButtonToggle = ((0, jsx_runtime_1.jsx)(react_2.Button, { ref: buttonTriggerRef, onClick: handleToggle, onKeyDown: handleTriggerKeyDown, size: s.btn, colorScheme: "primary", borderRadius: "lg", fontWeight: 600, "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (ButtonText ? undefined : "Open menu"), rightIcon: Chevron, sx: { transition: "all 0.15s ease", ...(dropDownButtonStyle) }, ...buttonProps, children: (0, jsx_runtime_1.jsxs)(react_2.Box, { as: "span", display: "inline-flex", alignItems: "center", gap: DropdownIcon && ButtonText ? s.gap : 0, children: [DropdownIcon, ButtonText] }) }));
226
+ const TextToggle = ((0, jsx_runtime_1.jsxs)(react_2.Flex, { ref: textTriggerRef, onClick: handleToggle, onKeyDown: handleTriggerKeyDown, align: "center", gap: 1.5, cursor: "pointer", fontSize: s.fontSize, fontWeight: 500, color: theme.colors.text[700], transition: "color 0.15s ease", _hover: { color: theme.colors.accentText }, style: dropDownButtonStyle, role: "button", tabIndex: 0, "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (text ? undefined : "Open menu"), children: [DropdownIcon, text, Chevron] }));
214
227
  return dropdownType === "button" ? ButtonToggle : TextToggle;
215
228
  };
216
229
  const DropdownContentRender = () => {
217
230
  var _a;
218
- const hoverTint = (0, outlineRung_1.resolveHoverTint)(theme.colors.primary[500], theme.colors.background[50]);
231
+ const hoverTint = rowBackgrounds.active;
219
232
  return ((0, jsx_runtime_1.jsx)(react_2.List, { id: menuId, role: "menu", onKeyDown: handleMenuKeyDown, bg: theme.colors.background[50], border: `0.063rem solid ${theme.colors.boxborder[200]}`, borderRadius: "xl", boxShadow: (_a = theme.shadows) === null || _a === void 0 ? void 0 : _a.lg, py: 1.5, mt: "0.375rem", minWidth: s.minW, maxH: "18rem", overflowY: "auto", overflowX: "hidden", sx: (0, scrollbar_1.scrollbarStyles)(theme.colors, "overlay"), style: ListStyle, children: options.map((option, index) => ((0, jsx_runtime_1.jsxs)(react_2.ListItem, { ref: (node) => {
220
233
  itemRefs.current[index] = node;
221
234
  }, role: "menuitem", tabIndex: index === activeIndex ? 0 : -1, onClick: () => {