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
@@ -14,5 +14,5 @@ function ToggleSwitch({ isChecked, onChange, isDisabled = false, size = "md", id
14
14
  return ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "button", type: "button", id: id, role: "switch", "aria-checked": isChecked, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, disabled: isDisabled, onClick: () => onChange(!isChecked), position: "relative", display: "inline-flex", alignItems: "center", flexShrink: 0, w: dims.w, h: dims.h, p: 0, borderRadius: "full", borderWidth: "1px", borderStyle: "solid", borderColor: isChecked ? colors.primary[500] : colors.boxborder[500], bg: isChecked ? colors.primary[500] : colors.background[600], opacity: isDisabled ? 0.5 : 1, cursor: isDisabled ? "not-allowed" : "pointer", transition: "background-color 0.2s ease, border-color 0.2s ease", _focusVisible: {
15
15
  outline: "none",
16
16
  boxShadow: `0 0 0 2px ${colors.primary[300]}`,
17
- }, children: (0, jsx_runtime_1.jsx)(react_1.Box, { "aria-hidden": "true", position: "absolute", left: "0.125rem", w: dims.knob, h: dims.knob, borderRadius: "full", bg: colors.background[50], boxShadow: "sm", transition: "transform 0.2s ease", transform: isChecked ? `translateX(${dims.travel})` : "translateX(0)" }) }));
17
+ }, children: (0, jsx_runtime_1.jsx)(react_1.Box, { "aria-hidden": "true", position: "absolute", left: "0.125rem", w: dims.knob, h: dims.knob, borderRadius: "full", bg: colors.white, boxShadow: "sm", transition: "transform 0.2s ease", transform: isChecked ? `translateX(${dims.travel})` : "translateX(0)" }) }));
18
18
  }
@@ -23,7 +23,7 @@ const EditableCell = ({ row, column, isEditable, handleCellClick, handleCellChan
23
23
  return ((0, jsx_runtime_1.jsx)(react_2.Box, { width: "50%", ref: cellRef, children: (0, jsx_runtime_1.jsx)(react_2.Input, { type: "date", value: value, onChange: (e) => handleCellChange(row.id, column.label, e.target.value) }) }));
24
24
  }
25
25
  else if (column.label === "priority") {
26
- return ((0, jsx_runtime_1.jsx)(react_2.Box, { width: "100%", ref: cellRef, children: (0, jsx_runtime_1.jsxs)(react_2.Menu, { isOpen: true, children: [(0, jsx_runtime_1.jsx)(react_2.MenuButton, { as: react_2.Button, rightIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, {}), bg: colors.teal[50], color: (0, accentText_1.accentTextOnCanvas)(colors.teal, colors.teal[50]), _hover: { bg: colors.teal[100] }, _active: { bg: colors.teal[200] }, children: value }), (0, jsx_runtime_1.jsxs)(react_2.MenuList, { children: [(0, jsx_runtime_1.jsx)(react_2.MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Low"), _hover: { bg: colors.teal[100] }, children: "Low" }), (0, jsx_runtime_1.jsx)(react_2.MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Medium"), _hover: { bg: colors.teal[100] }, children: "Medium" }), (0, jsx_runtime_1.jsx)(react_2.MenuItem, { onClick: () => handleCellChange(row.id, column.label, "High"), _hover: { bg: colors.teal[100] }, children: "High" })] })] }) }));
26
+ return ((0, jsx_runtime_1.jsx)(react_2.Box, { width: "100%", ref: cellRef, children: (0, jsx_runtime_1.jsxs)(react_2.Menu, { isOpen: true, children: [(0, jsx_runtime_1.jsx)(react_2.MenuButton, { as: react_2.Button, rightIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, {}), bg: colors.teal[50], color: (0, accentText_1.accentTextOnCanvas)(colors.teal, colors.teal[50]), _hover: { bg: colors.teal[100] }, _active: { bg: colors.teal[200] }, children: value }), (0, jsx_runtime_1.jsxs)(react_2.MenuList, { children: [(0, jsx_runtime_1.jsx)(react_2.MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Low"), children: "Low" }), (0, jsx_runtime_1.jsx)(react_2.MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Medium"), children: "Medium" }), (0, jsx_runtime_1.jsx)(react_2.MenuItem, { onClick: () => handleCellChange(row.id, column.label, "High"), children: "High" })] })] }) }));
27
27
  }
28
28
  else {
29
29
  return ((0, jsx_runtime_1.jsx)(react_2.Box, { width: "100%", ref: cellRef, children: (0, jsx_runtime_1.jsx)(react_2.Input, { value: value, onChange: (e) => handleCellChange(row.id, column.label, e.target.value) }) }));
@@ -14,6 +14,6 @@ const DeactivateConfirmModal = ({ isOpen, onClose, userName, isLoading, onConfir
14
14
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
15
15
  const mode = (0, accentText_1.isDarkCanvas)(colors.backgroundColor.main) ? "dark" : "light";
16
16
  const errorTone = (0, statusTone_1.resolveStatusTone)(colors.semantic.error, mode);
17
- return ((0, jsx_runtime_1.jsxs)(react_1.Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [(0, jsx_runtime_1.jsx)(react_1.ModalOverlay, { backdropFilter: "blur(4px)" }), (0, jsx_runtime_1.jsxs)(react_1.ModalContent, { bg: colors.background[50], borderRadius: "2xl", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_1.ModalHeader, { borderBottom: "1px solid", borderColor: colors.boxborder[200], display: "flex", alignItems: "center", gap: 3, children: [(0, jsx_runtime_1.jsx)(react_1.Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: errorTone.bg, color: errorTone.fg, children: (0, jsx_runtime_1.jsx)(lucide_react_1.AlertTriangle, { size: 18 }) }), (0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "1.05rem", fontWeight: 600, children: labels.confirmDeactivation })] }), (0, jsx_runtime_1.jsx)(react_1.ModalCloseButton, {}), (0, jsx_runtime_1.jsx)(react_1.ModalBody, { py: 6, children: (0, jsx_runtime_1.jsxs)(react_1.VStack, { spacing: 4, align: "stretch", children: [(0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "md", fontWeight: 500, color: colors.text[900], children: labels.deactivateConfirmQuestion }), (0, jsx_runtime_1.jsx)(react_1.Box, { bg: colors.gray[50], borderRadius: "lg", p: 4, border: "1px solid", borderColor: colors.boxborder[200], children: (0, jsx_runtime_1.jsxs)(react_1.Text, { color: colors.textMuted, fontSize: "sm", children: [userName ? `${userName} ` : "", labels.deactivateConfirmDescription] }) }), (0, jsx_runtime_1.jsxs)(react_1.HStack, { justifyContent: "flex-end", spacing: 3, pt: 2, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { label: labels.cancel, onClick: onClose, variant: "outline", size: "sm", colorScheme: "gray" }), (0, jsx_runtime_1.jsx)(Button_1.default, { label: labels.deactivateUser, onClick: onConfirm, colorScheme: "red", size: "sm", isLoading: isLoading, leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { size: 16 }) })] })] }) })] })] }));
17
+ return ((0, jsx_runtime_1.jsxs)(react_1.Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [(0, jsx_runtime_1.jsx)(react_1.ModalOverlay, { backdropFilter: "blur(4px)" }), (0, jsx_runtime_1.jsxs)(react_1.ModalContent, { bg: colors.background[50], borderRadius: "2xl", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_1.ModalHeader, { borderBottom: "1px solid", borderColor: colors.boxborder[200], display: "flex", alignItems: "center", gap: 3, children: [(0, jsx_runtime_1.jsx)(react_1.Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: errorTone.bg, color: errorTone.fg, children: (0, jsx_runtime_1.jsx)(lucide_react_1.AlertTriangle, { size: 18 }) }), (0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "1.05rem", fontWeight: 600, children: labels.confirmDeactivation })] }), (0, jsx_runtime_1.jsx)(react_1.ModalCloseButton, {}), (0, jsx_runtime_1.jsx)(react_1.ModalBody, { py: 6, children: (0, jsx_runtime_1.jsxs)(react_1.VStack, { spacing: 4, align: "stretch", children: [(0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "md", fontWeight: 500, color: colors.text[900], children: labels.deactivateConfirmQuestion }), (0, jsx_runtime_1.jsx)(react_1.Box, { bg: colors.background[50], borderRadius: "lg", p: 4, border: "1px solid", borderColor: colors.boxborder[200], children: (0, jsx_runtime_1.jsxs)(react_1.Text, { color: colors.textMuted, fontSize: "sm", children: [userName ? `${userName} ` : "", labels.deactivateConfirmDescription] }) }), (0, jsx_runtime_1.jsxs)(react_1.HStack, { justifyContent: "flex-end", spacing: 3, pt: 2, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { label: labels.cancel, onClick: onClose, variant: "outline", size: "sm", colorScheme: "gray" }), (0, jsx_runtime_1.jsx)(Button_1.default, { label: labels.deactivateUser, onClick: onConfirm, colorScheme: "red", size: "sm", isLoading: isLoading, leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { size: 16 }) })] })] }) })] })] }));
18
18
  };
19
19
  exports.default = DeactivateConfirmModal;
@@ -43,6 +43,7 @@ const lucide_react_1 = require("lucide-react");
43
43
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
44
44
  const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
45
45
  const accentText_1 = require("../../Theme/tokens/builders/accentText");
46
+ const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
46
47
  const EmptyState_1 = __importDefault(require("../EmptyState/EmptyState"));
47
48
  const AddUserModal_1 = __importDefault(require("./AddUserModal"));
48
49
  const ChangeRoleModal_1 = __importDefault(require("./ChangeRoleModal"));
@@ -93,6 +94,7 @@ const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], ca
93
94
  const [actionUserId, setActionUserId] = (0, react_1.useState)(null);
94
95
  const border = colors.boxborder[200];
95
96
  const surface = colors.background[50];
97
+ const rowBackgrounds = (0, react_1.useMemo)(() => (0, rowStates_1.listRowBackgrounds)(colors), [colors]);
96
98
  const muted = colors.textMuted;
97
99
  const heading = colors.text[900];
98
100
  const avatarBg = colors.primary[100];
@@ -109,10 +111,10 @@ const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], ca
109
111
  const renderStatusBadge = (isActive) => ((0, jsx_runtime_1.jsx)(react_2.Badge, { variant: "subtle", colorScheme: isActive ? successScheme : dangerScheme, borderRadius: "full", px: 2, py: 0.5, fontSize: "0.65rem", fontWeight: 600, textTransform: "none", children: isActive ? labels.active : labels.inactive }));
110
112
  return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { backgroundColor: colors.backgroundColor.main, minHeight: minHeight, p: { base: 3, md: 4 }, gap: 3, flexDirection: { base: "column", lg: "row" }, children: [(0, jsx_runtime_1.jsxs)(react_2.Box, { width: { base: "100%", lg: "300px" }, backgroundColor: surface, borderRadius: "xl", boxShadow: "sm", border: "1px solid", borderColor: border, position: "relative", order: { base: 2, lg: 1 }, overflow: "hidden", display: "flex", flexDirection: "column", children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { px: 4, py: 3, borderBottom: "1px solid", borderColor: border, alignItems: "center", justifyContent: "space-between", children: [(0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 2, children: [onBack && ((0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": "Go back", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { size: 18 }), variant: "ghost", size: "xs", color: muted, onClick: onBack })), (0, jsx_runtime_1.jsx)(react_2.Heading, { size: "sm", fontWeight: 600, color: heading, children: labels.teamMembers }), (0, jsx_runtime_1.jsx)(react_2.Badge, { colorScheme: "gray", borderRadius: "full", fontSize: "0.65rem", px: 2, children: users.length })] }), onRefresh && ((0, jsx_runtime_1.jsx)(react_2.IconButton, { "aria-label": labels.refreshList, icon: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { size: 15 }), variant: "ghost", size: "xs", color: muted, onClick: onRefresh, isLoading: isUsersLoading }))] }), (0, jsx_runtime_1.jsx)(react_2.Box, { flex: 1, overflowY: "auto", maxHeight: { base: "380px", lg: `calc(${minHeight} - 80px)` }, children: isUsersLoading ? ((0, jsx_runtime_1.jsx)(react_2.VStack, { spacing: 2, p: 3, children: Array.from({ length: 6 }).map((_, idx) => ((0, jsx_runtime_1.jsxs)(react_2.Flex, { alignItems: "center", gap: 3, p: 2, w: "100%", children: [(0, jsx_runtime_1.jsx)(react_2.SkeletonCircle, { size: "9" }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flex: 1, children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "12px", mb: 2, width: "80%" }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "9px", width: "60%" })] })] }, idx))) })) : users.length === 0 ? ((0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.Users, title: labels.noUsers, size: "sm", minH: "220px" })) : ((0, jsx_runtime_1.jsx)(react_2.VStack, { spacing: 1, p: 2, align: "stretch", children: users.map((user) => {
111
113
  const isSelected = selectedUserId != null && selectedUserId === user.id;
112
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { p: 2.5, w: "100%", cursor: "pointer", alignItems: "center", gap: 2.5, backgroundColor: isSelected ? colors.primary[50] : "transparent", _hover: {
114
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { p: 2.5, w: "100%", cursor: "pointer", alignItems: "center", gap: 2.5, backgroundColor: isSelected ? rowBackgrounds.selected : "transparent", _hover: {
113
115
  background: isSelected
114
- ? colors.primary[50]
115
- : (0, outlineRung_1.resolveHoverTint)(colors.gray[50], surface),
116
+ ? rowBackgrounds.selectedActive
117
+ : rowBackgrounds.active,
116
118
  }, transition: "background 0.15s ease", borderRadius: "lg", position: "relative", onClick: () => onSelectUser === null || onSelectUser === void 0 ? void 0 : onSelectUser(user), children: [isSelected && ((0, jsx_runtime_1.jsx)(react_2.Box, { position: "absolute", left: 0, top: "20%", bottom: "20%", width: "3px", borderRadius: "full", bg: colors.primary[500] })), (0, jsx_runtime_1.jsx)(react_2.Avatar, { size: "sm", name: `${user.firstName} ${user.lastName}`, src: user.profile, bg: avatarBg, color: avatarColor }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flex: 1, overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_2.Text, { fontSize: "sm", fontWeight: 600, noOfLines: 1, color: heading, children: [user.firstName, " ", user.lastName] }), (0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "xs", color: muted, noOfLines: 1, children: user.email })] }), renderStatusBadge(user.isActive)] }, user.id));
117
119
  }) })) })] }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flex: 1, backgroundColor: surface, borderRadius: "xl", boxShadow: "sm", border: "1px solid", borderColor: border, display: "flex", flexDirection: "column", order: { base: 1, lg: 2 }, overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { justifyContent: "space-between", alignItems: "center", px: 4, py: 3, borderBottom: "1px solid", borderColor: border, children: [(0, jsx_runtime_1.jsx)(react_2.Heading, { size: "sm", fontWeight: 600, color: heading, children: selectedUser ? labels.userDetails : labels.selectTeamMember }), canManageUsers && ((0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", colorScheme: "primary", fontSize: "xs", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.UserPlus, { size: 15 }), onClick: onAddUserOpen, children: labels.addUser }))] }), (0, jsx_runtime_1.jsx)(react_2.Box, { flex: 1, overflowY: "auto", children: isUsersLoading ? ((0, jsx_runtime_1.jsxs)(react_2.VStack, { spacing: 4, p: 4, align: "stretch", children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 4, children: [(0, jsx_runtime_1.jsx)(react_2.SkeletonCircle, { size: "16" }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flex: 1, children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "18px", width: "50%", mb: 2 }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "12px", width: "35%" })] })] }), Array.from({ length: 4 }).map((_, idx) => ((0, jsx_runtime_1.jsxs)(react_2.Box, { w: "100%", children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "12px", width: "30%", mb: 2 }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { height: "10px", width: "80%" })] }, idx)))] })) : selectedUser ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { direction: { base: "column", md: "row" }, alignItems: { base: "flex-start", md: "center" }, justifyContent: "space-between", gap: 4, p: 4, borderBottom: "1px solid", borderColor: border, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { alignItems: "center", gap: 4, children: [(0, jsx_runtime_1.jsxs)(react_2.Box, { position: "relative", children: [(0, jsx_runtime_1.jsx)(react_2.Avatar, { size: "lg", name: selectedUser.name, src: selectedUser.profilePhoto, bg: avatarBg, color: avatarColor }), selectedUser.isCurrent && ((0, jsx_runtime_1.jsx)(react_2.Badge, { position: "absolute", bottom: -1, right: -1, colorScheme: "blue", variant: "solid", fontSize: "0.6rem", borderRadius: "full", px: 2, py: 0.5, boxShadow: "sm", textTransform: "none", children: labels.you }))] }), (0, jsx_runtime_1.jsxs)(react_2.Box, { children: [(0, jsx_runtime_1.jsx)(react_2.Heading, { size: "md", mb: 1, color: heading, children: selectedUser.name }), (0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "sm", color: muted, mb: 2, children: selectedUser.role }), (0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 2, children: [renderStatusBadge(selectedUser.isActive), selectedUser.isPending && ((0, jsx_runtime_1.jsx)(react_2.Badge, { variant: "subtle", borderRadius: "full", px: 2, py: 0.5, fontSize: "0.65rem", fontWeight: 600, colorScheme: "orange", textTransform: "none", children: labels.pendingInvitation }))] })] })] }), canManageUsers &&
118
120
  !selectedUser.isSuperAdmin && ((0, jsx_runtime_1.jsxs)(react_2.HStack, { spacing: 2, flexWrap: "wrap", children: [!selectedUser.isCurrent && !selectedUser.isActive && ((0, jsx_runtime_1.jsx)(react_2.Button, { size: "xs", variant: "outline", colorScheme: "blue", fontSize: "xs", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Send, { size: 13 }), isLoading: isInviteLoading, onClick: () => selectedUser.userId != null &&
@@ -0,0 +1,4 @@
1
+ export declare const exclusiveOpen: (id: string, close: () => void) => void;
2
+ export declare const exclusiveClose: (id: string) => void;
3
+ /** Test-only reset — not exported from the package root. */
4
+ export declare const resetExclusiveOverlay: () => void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resetExclusiveOverlay = exports.exclusiveClose = exports.exclusiveOpen = void 0;
4
+ let active = null;
5
+ const exclusiveOpen = (id, close) => {
6
+ if (active && active.id !== id) {
7
+ active.close();
8
+ }
9
+ active = { id, close };
10
+ };
11
+ exports.exclusiveOpen = exclusiveOpen;
12
+ const exclusiveClose = (id) => {
13
+ if ((active === null || active === void 0 ? void 0 : active.id) === id) {
14
+ active = null;
15
+ }
16
+ };
17
+ exports.exclusiveClose = exclusiveClose;
18
+ /** Test-only reset — not exported from the package root. */
19
+ const resetExclusiveOverlay = () => {
20
+ active = null;
21
+ };
22
+ exports.resetExclusiveOverlay = resetExclusiveOverlay;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Register this overlay with the global dismiss coordinator. Call `requestOpen()`
3
+ * immediately before opening; `onClose` is invoked when another overlay opens.
4
+ */
5
+ export declare const useExclusiveOverlay: (isOpen: boolean, onClose: () => void) => () => void;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useExclusiveOverlay = void 0;
4
+ const react_1 = require("react");
5
+ const exclusiveOverlay_1 = require("./exclusiveOverlay");
6
+ /**
7
+ * Register this overlay with the global dismiss coordinator. Call `requestOpen()`
8
+ * immediately before opening; `onClose` is invoked when another overlay opens.
9
+ */
10
+ const useExclusiveOverlay = (isOpen, onClose) => {
11
+ const id = (0, react_1.useId)();
12
+ const onCloseRef = (0, react_1.useRef)(onClose);
13
+ onCloseRef.current = onClose;
14
+ const requestOpen = (0, react_1.useCallback)(() => {
15
+ (0, exclusiveOverlay_1.exclusiveOpen)(id, () => onCloseRef.current());
16
+ }, [id]);
17
+ (0, react_1.useEffect)(() => {
18
+ if (!isOpen) {
19
+ (0, exclusiveOverlay_1.exclusiveClose)(id);
20
+ }
21
+ }, [isOpen, id]);
22
+ return requestOpen;
23
+ };
24
+ exports.useExclusiveOverlay = useExclusiveOverlay;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Menu = void 0;
4
4
  const react_1 = require("@chakra-ui/react");
5
5
  const anatomy_1 = require("@chakra-ui/anatomy");
6
+ const rowStates_1 = require("../tokens/builders/rowStates");
6
7
  const paletteFromTheme_1 = require("./paletteFromTheme");
7
8
  const { defineMultiStyleConfig, definePartsStyle } = (0, react_1.createMultiStyleConfigHelpers)(anatomy_1.menuAnatomy.keys);
8
9
  const $bg = (0, react_1.cssVar)("menu-bg");
@@ -24,8 +25,9 @@ const $bg = (0, react_1.cssVar)("menu-bg");
24
25
  const $itemBg = (0, react_1.cssVar)("menu-item-bg");
25
26
  const baseStyle = definePartsStyle(({ theme }) => {
26
27
  const colors = (0, paletteFromTheme_1.paletteOf)(theme);
27
- const hoverBg = colors.primary.opacity[8];
28
- const activeBg = colors.primary.opacity[16];
28
+ const rowBgs = (0, rowStates_1.listRowBackgrounds)(colors);
29
+ const hoverBg = rowBgs.active;
30
+ const activeBg = rowBgs.selectedActive;
29
31
  return {
30
32
  list: {
31
33
  [$bg.variable]: colors.backgroundColor.light,
@@ -16,6 +16,9 @@ export type TablePaletteColor = {
16
16
  text: string;
17
17
  onSolid?: string;
18
18
  };
19
+ export type SemanticStatusTone = "info" | "warning" | "success" | "error" | "neutral";
20
+ /** Theme-aware status palette per value — soft fill + semantic ink from `resolveStatusTone`. */
21
+ export declare function buildSemanticStatusPalette(toneByValue: Record<string, SemanticStatusTone>, theme: CustomThemeProps): Record<string, TablePaletteColor>;
19
22
  /** Deterministic, theme-aware color palette for groups + status pills. */
20
23
  export declare function buildTablePalette(theme: CustomThemeProps): TablePaletteColor[];
21
24
  /** Pick a deterministic palette color for a value, with optional consumer override hex. */
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.TableCellCalculation = exports.pageSizeCalculation = exports.searchAndSortData = exports.calculateLeftOffset = void 0;
37
37
  exports.compareValues = compareValues;
38
38
  exports.SortMultiColumnData = SortMultiColumnData;
39
+ exports.buildSemanticStatusPalette = buildSemanticStatusPalette;
39
40
  exports.buildTablePalette = buildTablePalette;
40
41
  exports.pickTableColor = pickTableColor;
41
42
  exports.groupRows = groupRows;
@@ -45,6 +46,8 @@ exports.useDebounce = useDebounce;
45
46
  exports.globalSearchFilter = globalSearchFilter;
46
47
  const react_1 = __importStar(require("react"));
47
48
  const accentText_1 = require("../Theme/tokens/builders/accentText");
49
+ const color_1 = require("../Theme/tokens/builders/color");
50
+ const outlineRung_1 = require("../Theme/tokens/builders/outlineRung");
48
51
  const filledSurface_1 = require("../Theme/tokens/builders/filledSurface");
49
52
  const statusTone_1 = require("../Theme/tokens/builders/statusTone");
50
53
  // Built once, not per comparison: sorting 10k rows runs this ~130k times, and constructing a
@@ -99,7 +102,45 @@ function SortMultiColumnData(data, sortConfig) {
99
102
  return 0;
100
103
  });
101
104
  }
105
+ /** Theme-aware status palette per value — soft fill + semantic ink from `resolveStatusTone`. */
106
+ function buildSemanticStatusPalette(toneByValue, theme) {
107
+ const c = theme.colors;
108
+ const mode = (0, accentText_1.isDarkCanvas)(c.backgroundColor.main) ? "dark" : "light";
109
+ const scales = {
110
+ info: c.semantic.info,
111
+ warning: c.semantic.warning,
112
+ success: c.semantic.success,
113
+ error: c.semantic.error,
114
+ neutral: c.gray,
115
+ };
116
+ return Object.fromEntries(Object.entries(toneByValue).map(([value, key]) => {
117
+ const scale = scales[key];
118
+ const tone = (0, statusTone_1.resolveStatusTone)(scale, mode);
119
+ const solidRung = (0, filledSurface_1.solidFillRung)(scale, c.white);
120
+ const solid = scale[solidRung];
121
+ return [
122
+ value,
123
+ {
124
+ solid,
125
+ soft: tone.bg,
126
+ text: tone.fg,
127
+ onSolid: (0, filledSurface_1.labelOnFill)(solid, c.white, c.black),
128
+ },
129
+ ];
130
+ }));
131
+ }
102
132
  const withAlpha = (hex, aa) => /^#([0-9a-fA-F]{6})$/.test(hex) ? `${hex}${aa}` : hex;
133
+ /** Consumer `statusColors` values are fill seeds — derive bleed + pill ink from them. */
134
+ const resolveStatusOverride = (fill, white, black, surface) => {
135
+ const soft = withAlpha(fill, "22");
136
+ const solid = (0, statusTone_1.resolveAvatarFill)(fill);
137
+ return {
138
+ solid,
139
+ soft,
140
+ text: (0, outlineRung_1.liftToContrast)(fill, (0, color_1.compositeOver)(soft, surface), accentText_1.AA_NORMAL_TEXT),
141
+ onSolid: (0, accentText_1.onFilled)(solid, white, black),
142
+ };
143
+ };
103
144
  /** Deterministic, theme-aware color palette for groups + status pills. */
104
145
  function buildTablePalette(theme) {
105
146
  const c = theme.colors;
@@ -137,10 +178,12 @@ const hashKey = (value) => {
137
178
  };
138
179
  /** Pick a deterministic palette color for a value, with optional consumer override hex. */
139
180
  function pickTableColor(value, palette, override, theme) {
181
+ var _a;
140
182
  const white = theme ? theme.colors.white : accentText_1.DEFAULT_WHITE;
141
183
  const black = theme ? theme.colors.black : accentText_1.DEFAULT_BLACK;
142
184
  if (override) {
143
- return { solid: override, soft: withAlpha(override, "22"), text: override, onSolid: (0, accentText_1.onFilled)(override, white, black) };
185
+ const surface = (_a = theme === null || theme === void 0 ? void 0 : theme.colors.background[50]) !== null && _a !== void 0 ? _a : accentText_1.DEFAULT_WHITE;
186
+ return resolveStatusOverride(override, white, black, surface);
144
187
  }
145
188
  if (!palette.length) {
146
189
  throw new Error("pickTableColor: empty palette — build it with buildTablePalette(theme).");
@@ -5,7 +5,9 @@ import { Grip, Lock, Search } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
6
  import { chartMode } from "../../Theme/tokens/builders/chartColorsFromTheme.js";
7
7
  import { AA_NORMAL_TEXT } from "../../Theme/tokens/builders/accentText.js";
8
- import { liftToContrast, neutralStep, resolveHoverTint, ruleInk, AA_NON_TEXT, CHROME_RULE, MIN_PERCEPTIBLE_STEP, } from "../../Theme/tokens/builders/outlineRung.js";
8
+ import { liftToContrast, neutralStep, ruleInk, AA_NON_TEXT, CHROME_RULE, MIN_PERCEPTIBLE_STEP, } from "../../Theme/tokens/builders/outlineRung.js";
9
+ import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
10
+ import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
9
11
  import AppMark, { assignAppHues } from "./AppMark.js";
10
12
  import { filterApps, formatShortcut, } from "./AppSwitcherProps.js";
11
13
  import { useAppSwitcherShortcut } from "./useAppSwitcherShortcut.js";
@@ -33,25 +35,18 @@ const validate = (apps) => {
33
35
  warnOnce(`url-${app.id || i}`, `app "${app.name}" has no url; it cannot be opened.`);
34
36
  });
35
37
  };
36
- // Past a pointer's pause threshold, so crossing the launcher on the way elsewhere does not open it,
37
- // but short enough that deliberately resting on it feels instant.
38
- const HOVER_OPEN_DELAY = 450;
39
- // Long enough to travel the gap between the launcher and the panel below it.
40
- const HOVER_CLOSE_GRACE = 250;
41
38
  // Flip back to true to restore `searchThreshold` opening the field on its own.
42
39
  const SEARCH_OPENS_BY_COUNT = false;
43
40
  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, }) => {
44
41
  const theme = useCustomTheme();
45
42
  const { isOpen, onOpen, onClose } = useDisclosure();
43
+ const requestExclusiveOpen = useExclusiveOverlay(isOpen, onClose);
46
44
  const [query, setQuery] = useState("");
47
45
  const [activeIndex, setActiveIndex] = useState(0);
48
46
  const searchRef = useRef(null);
49
47
  const triggerRef = useRef(null);
50
- const panelRef = useRef(null);
51
48
  const itemRefs = useRef([]);
52
49
  const typeahead = useRef({ buffer: "", at: 0 });
53
- const hoverTimer = useRef();
54
- const openedByHover = useRef(false);
55
50
  useEffect(() => validate(apps), [apps]);
56
51
  // Search is off while the panel's design settles: the app count alone no longer opens it. An
57
52
  // explicit `isSearchable` still wins, so nothing about the prop changed.
@@ -59,47 +54,15 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
59
54
  const hues = useMemo(() => assignAppHues(apps, chartMode(theme.colors)), [apps, theme.colors]);
60
55
  const visible = useMemo(() => filterApps(apps, query), [apps, query]);
61
56
  const setOpen = useCallback((next) => {
62
- if (next)
57
+ if (next) {
58
+ requestExclusiveOpen();
63
59
  onOpen();
64
- else
60
+ }
61
+ else {
65
62
  onClose();
63
+ }
66
64
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(next);
67
- }, [onOpen, onClose, onOpenChange]);
68
- const cancelHoverTimer = useCallback(() => {
69
- if (hoverTimer.current)
70
- clearTimeout(hoverTimer.current);
71
- hoverTimer.current = undefined;
72
- }, []);
73
- useEffect(() => cancelHoverTimer, [cancelHoverTimer]);
74
- // Touch and stylus report no hover; a timer there would open the panel on a tap-and-hold.
75
- const pointerHovers = () => {
76
- var _a;
77
- return typeof window !== "undefined" &&
78
- ((_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, "(hover: hover) and (pointer: fine)").matches);
79
- };
80
- const handleHoverStart = useCallback(() => {
81
- if (isOpen || !pointerHovers())
82
- return;
83
- cancelHoverTimer();
84
- hoverTimer.current = setTimeout(() => {
85
- openedByHover.current = true;
86
- setOpen(true);
87
- }, HOVER_OPEN_DELAY);
88
- }, [isOpen, cancelHoverTimer, setOpen]);
89
- // A click-opened panel is sticky, and a keyboard user inside it is not "hovering away".
90
- const handleHoverEnd = useCallback(() => {
91
- cancelHoverTimer();
92
- if (!isOpen || !openedByHover.current)
93
- return;
94
- hoverTimer.current = setTimeout(() => {
95
- var _a;
96
- if ((_a = panelRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement))
97
- return;
98
- openedByHover.current = false;
99
- setOpen(false);
100
- setQuery("");
101
- }, HOVER_CLOSE_GRACE);
102
- }, [isOpen, cancelHoverTimer, setOpen]);
65
+ }, [onOpen, onClose, onOpenChange, requestExclusiveOpen]);
103
66
  const closeAndRefocus = useCallback(() => {
104
67
  var _a;
105
68
  setOpen(false);
@@ -208,7 +171,7 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
208
171
  const nothingToSwitchTo = apps.length === 0 || (hideWhenAlone && apps.every((a) => a.id === currentAppId));
209
172
  if (nothingToSwitchTo)
210
173
  return null;
211
- const rowHoverBg = resolveHoverTint(theme.colors.gray[50], theme.colors.backgroundColor.light);
174
+ const rowHoverBg = listRowBackgrounds(theme.colors).active;
212
175
  const footerRule = ruleInk(theme.colors.boxborder[200], [theme.colors.backgroundColor.subtle], CHROME_RULE);
213
176
  // Neutral, not `backgroundColor.tertiary`: that rung is brand-tinted in the hand-authored light
214
177
  // palettes, so lifting it painted the row a saturated block. The rail identifies the row, so the
@@ -223,7 +186,7 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
223
186
  const currentSub = liftToContrast(theme.colors.textMuted, currentBg, AA_NORMAL_TEXT);
224
187
  const width = panelWidth !== null && panelWidth !== void 0 ? panelWidth : "28rem";
225
188
  const hint = shortcut && showShortcutHint ? formatShortcut(shortcut) : null;
226
- return (_jsxs(Popover, { isOpen: isOpen, onOpen: () => setOpen(true), onClose: () => { setOpen(false); setQuery(""); }, placement: "bottom-end", initialFocusRef: showSearch ? searchRef : undefined, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsx(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) => {
189
+ return (_jsxs(Popover, { isOpen: isOpen, onOpen: () => setOpen(true), onClose: () => { setOpen(false); setQuery(""); }, placement: "bottom-end", initialFocusRef: showSearch ? searchRef : undefined, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsx(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) => {
227
190
  if (!isOpen) {
228
191
  if (e.key === "ArrowDown") {
229
192
  e.preventDefault();
@@ -232,7 +195,7 @@ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable,
232
195
  return;
233
196
  }
234
197
  handlePanelKeyDown(e);
235
- }, children: _jsx(Grip, { size: s.icon + 1 }) }) }), _jsx(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: _jsxs(PopoverBody, { p: 0, children: [_jsxs(Flex, { align: "center", gap: 2, px: 3, pt: 3, pb: showSearch ? 2 : 1, children: [_jsx(Text, { fontSize: "0.6875rem", fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: theme.colors.textMuted, children: HEADING }), _jsx(Box, { flex: "1" }), hint && (_jsx(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 && (_jsx(Box, { px: 3, pb: 2, children: _jsxs(InputGroup, { size: "sm", children: [_jsx(InputLeftElement, { pointerEvents: "none", children: _jsx(Search, { size: 15, color: theme.colors.textMuted }) }), _jsx(Input, { ref: searchRef, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search apps", borderRadius: "lg", "aria-label": "Search apps", onKeyDown: (e) => {
198
+ }, children: _jsx(Grip, { size: s.icon + 1 }) }) }), _jsx(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: _jsxs(PopoverBody, { p: 0, children: [_jsxs(Flex, { align: "center", gap: 2, px: 3, pt: 3, pb: showSearch ? 2 : 1, children: [_jsx(Text, { fontSize: "0.6875rem", fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: theme.colors.textMuted, children: HEADING }), _jsx(Box, { flex: "1" }), hint && (_jsx(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 && (_jsx(Box, { px: 3, pb: 2, children: _jsxs(InputGroup, { size: "sm", children: [_jsx(InputLeftElement, { pointerEvents: "none", children: _jsx(Search, { size: 15, color: theme.colors.textMuted }) }), _jsx(Input, { ref: searchRef, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search apps", borderRadius: "lg", "aria-label": "Search apps", onKeyDown: (e) => {
236
199
  if (e.key === "ArrowDown" && visible.length > 0) {
237
200
  e.preventDefault();
238
201
  focusItem(0);
@@ -79,7 +79,7 @@ rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, left
79
79
  borderRadius: "lg",
80
80
  fontSize: "13px",
81
81
  fontWeight: 500,
82
- color: theme.colors.gray[700],
82
+ color: theme.colors.text[700],
83
83
  transition: "background 0.12s",
84
84
  "& svg": { width: "16px", height: "16px" },
85
85
  ...(divider
@@ -90,8 +90,6 @@ rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, left
90
90
  borderColor: theme.colors.boxborder[200],
91
91
  }
92
92
  : {}),
93
- _hover: { bg: theme.colors.primary[50], color: theme.colors.primary[700] },
94
- _focus: { bg: theme.colors.primary[50], color: theme.colors.primary[700] },
95
93
  "&:last-child": { borderBottom: "none" },
96
94
  }, children: [option === null || option === void 0 ? void 0 : option.image, option.label] }, index))) }) })] })) : (rightIcon && (_jsx(IconButton, { "aria-label": "Right icon button", icon: rightIcon, isLoading: RightIconLoading, onClick: onRightIconClick, onBlur: onBlurRightIcon, style: buttonGroupRightIconStyle, sx: gradientItemSx })))] }));
97
95
  }
@@ -17,7 +17,7 @@ export const getFieldStateStyles = (theme, { error = false, focused = false } =
17
17
  const ringPrimary = theme.colors.boxShadow.primary;
18
18
  const ringError = theme.colors.boxShadow.error;
19
19
  return {
20
- bg: theme.colors.gray[50],
20
+ bg: theme.colors.background[50],
21
21
  borderRadius: FIELD_RADIUS,
22
22
  border: `${FIELD_BORDER_WIDTH} solid`,
23
23
  borderColor: error ? errorColor : focused ? primary : idleBorder,
@@ -4,6 +4,7 @@ import { Box, Flex, IconButton, Text } from "@chakra-ui/react";
4
4
  import { Check, Copy } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
6
  import { accentTextOnCanvas, AA_NORMAL_TEXT } from "../../Theme/tokens/builders/accentText.js";
7
+ import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
7
8
  import { liftToContrast } from "../../Theme/tokens/builders/outlineRung.js";
8
9
  import ToolTip from "../ToolTip/ToolTip.js";
9
10
  const CopyButton = ({ value, variant = "icon", label = "Copy", copiedLabel = "Copied!", tooltip = "Copy", feedbackDuration = 1500, iconSize = 16, size = "sm", onCopy, }) => {
@@ -29,17 +30,17 @@ const CopyButton = ({ value, variant = "icon", label = "Copy", copiedLabel = "Co
29
30
  // nearest rung that clears AA against the canvas this button actually sits on.
30
31
  const accent = accentTextOnCanvas(theme.colors.primary, theme.colors.backgroundColor.main);
31
32
  const success = theme.colors.semanticText.success;
33
+ const rowBackgrounds = listRowBackgrounds(theme.colors);
32
34
  if (variant === "menu-item") {
33
- // Ink also sits on the row's own hover fill (gray[100]), not just the canvas — resolve against it.
34
- const hoverAccent = accentTextOnCanvas(theme.colors.primary, theme.colors.gray[100]);
35
- const hoverSuccess = liftToContrast(theme.colors.semantic.success[500], theme.colors.gray[100], AA_NORMAL_TEXT);
36
- return (_jsxs(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 ? (_jsx(Check, { size: iconSize, color: hoverSuccess })) : (_jsx(Copy, { size: iconSize, color: hoverAccent })), _jsx(Box, { fontSize: "14px", fontWeight: 500, color: copied ? hoverSuccess : hoverAccent, children: copied ? copiedLabel : label })] }));
35
+ const hoverAccent = accentTextOnCanvas(theme.colors.primary, rowBackgrounds.active);
36
+ const hoverSuccess = liftToContrast(theme.colors.semantic.success[500], rowBackgrounds.active, AA_NORMAL_TEXT);
37
+ return (_jsxs(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 ? (_jsx(Check, { size: iconSize, color: hoverSuccess })) : (_jsx(Copy, { size: iconSize, color: hoverAccent })), _jsx(Box, { fontSize: "14px", fontWeight: 500, color: copied ? hoverSuccess : hoverAccent, children: copied ? copiedLabel : label })] }));
37
38
  }
38
39
  if (variant === "button") {
39
40
  return (_jsxs(Flex, { as: "button", align: "center", gap: "6px", px: "12px", py: "6px", borderRadius: "lg", border: "1px solid",
40
41
  // [800], not [500]: a real control boundary needs >=3:1 on every surface up to `muted`.
41
- 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 ? _jsx(Check, { size: iconSize }) : _jsx(Copy, { size: iconSize }), _jsx(Text, { children: copied ? copiedLabel : label })] }));
42
+ 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 ? _jsx(Check, { size: iconSize }) : _jsx(Copy, { size: iconSize }), _jsx(Text, { children: copied ? copiedLabel : label })] }));
42
43
  }
43
- return (_jsx(ToolTip, { label: copied ? copiedLabel : tooltip, placement: "top", children: _jsx(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 ? _jsx(Check, { size: iconSize }) : _jsx(Copy, { size: iconSize }) }) }));
44
+ return (_jsx(ToolTip, { label: copied ? copiedLabel : tooltip, placement: "top", children: _jsx(IconButton, { "aria-label": tooltip, size: size, variant: "ghost", onClick: handleCopy, color: copied ? success : theme.colors.textMuted, _hover: { color: accent, bg: rowBackgrounds.active }, icon: copied ? _jsx(Check, { size: iconSize }) : _jsx(Copy, { size: iconSize }) }) }));
44
45
  };
45
46
  export default CopyButton;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Grid } from "@chakra-ui/react";
2
+ import { Box } from "@chakra-ui/react";
3
3
  import { format, startOfMonth, endOfMonth, startOfWeek, endOfWeek, addDays } from "date-fns";
4
4
  import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
5
5
  import Button from "../Button/Button.js";
@@ -118,7 +118,10 @@ export const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, t
118
118
  const customContent = renderDayContent ? renderDayContent(thisDay, states) : null;
119
119
  const markerColor = customContent == null && (stateVisual === null || stateVisual === void 0 ? void 0 : stateVisual.markerColor) ? stateVisual.markerColor : null;
120
120
  const hasDayOverlay = customContent != null || markerColor != null;
121
- days.push(_jsx(Box, { h: "2rem", display: "flex", alignItems: "center", justifyContent: "center", style: cellBg ? { background: cellBg } : undefined, children: _jsxs(Box, { as: "button", type: "button", disabled: disabled, className: dayStates ? dayStateClassName(states) : undefined, "aria-label": dayStates ? dayAccessibleName(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
121
+ const dayLabel = dayStates
122
+ ? dayAccessibleName(format(thisDay, "d MMMM yyyy"), states)
123
+ : format(thisDay, "d MMMM yyyy");
124
+ days.push(_jsx(Box, { role: "gridcell", h: "2rem", display: "flex", alignItems: "center", justifyContent: "center", style: cellBg ? { background: cellBg } : undefined, children: _jsxs(Box, { as: "button", type: "button", disabled: disabled, className: dayStates ? 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
122
125
  ? {}
123
126
  : circleSolid
124
127
  ? { bg: solidHoverFill, color: circleHoverColor }
@@ -127,14 +130,14 @@ export const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, t
127
130
  pointerEvents: "none", children: customContent !== null && customContent !== void 0 ? customContent : (_jsx(Box, { as: "span", className: `${DAY_CLASS}__marker`, w: "0.25rem", h: "0.25rem", borderRadius: "full", bg: markerColor })) }))] }) }, thisDay.toString()));
128
131
  day = addDays(day, 1);
129
132
  }
130
- rows.push(_jsx(Grid, { templateColumns: "repeat(7, 1fr)", gap: 0, children: days }, day.toString()));
133
+ rows.push(_jsx(Box, { role: "row", display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0, children: days }, day.toString()));
131
134
  }
132
135
  return rows;
133
136
  };
134
- return (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2, gap: 1, children: [_jsx(Button, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1, 1)), "aria-label": "Previous month", children: _jsx(ChevronLeftIcon, { size: 16 }) }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 1.5, minW: 0, children: [_jsx(Box, { as: "select", value: currentMonth.getMonth(), onChange: (e) => {
137
+ return (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2, gap: 1, children: [_jsx(Button, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1, 1)), "aria-label": "Previous month", children: _jsx(ChevronLeftIcon, { size: 16 }) }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 1.5, minW: 0, children: [_jsx(Box, { as: "select", "aria-label": "Month", value: currentMonth.getMonth(), onChange: (e) => {
135
138
  const newMonth = parseInt(e.target.value, 10);
136
139
  setCurrentMonth((prev) => new Date(prev.getFullYear(), newMonth, 1));
137
- }, ...selectStyles, children: Array.from({ length: 12 }).map((_, i) => (_jsx("option", { value: i, children: format(new Date(2000, i, 1), "MMMM") }, i))) }), _jsx(Box, { as: "select", value: currentMonth.getFullYear(), onChange: (e) => {
140
+ }, ...selectStyles, children: Array.from({ length: 12 }).map((_, i) => (_jsx("option", { value: i, children: format(new Date(2000, i, 1), "MMMM") }, i))) }), _jsx(Box, { as: "select", "aria-label": "Year", value: currentMonth.getFullYear(), onChange: (e) => {
138
141
  const newYear = parseInt(e.target.value, 10);
139
142
  setCurrentMonth((prev) => new Date(newYear, prev.getMonth(), 1));
140
143
  }, ...selectStyles, children: Array.from({ length: 100 }).map((_, i) => {
@@ -145,6 +148,6 @@ export const CalendarPanel = ({ currentMonth, setCurrentMonth, today, isRange, t
145
148
  if (!disableToday) {
146
149
  onDaySelect(new Date(today));
147
150
  }
148
- }, "aria-label": "Today", sx: { fontSize: "0.7rem", px: 2, flexShrink: 0 }, isDisabled: disableToday, children: "Today" })), _jsx(Button, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1, 1)), "aria-label": "Next month", children: _jsx(ChevronRightIcon, { size: 16 }) })] })] }), renderWeekdays !== null && renderWeekdays !== void 0 ? renderWeekdays : (_jsx(Grid, { templateColumns: "repeat(7, 1fr)", gap: 0, mb: 1, children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => (_jsx(Box, { textAlign: "center", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.02em", color: theme.colors.textMuted, py: 1, children: day }, day))) })), _jsx(Box, { onMouseLeave: () => onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(null), children: renderDays() })] }));
151
+ }, "aria-label": "Today", sx: { fontSize: "0.7rem", px: 2, flexShrink: 0 }, isDisabled: disableToday, children: "Today" })), _jsx(Button, { variant: "ghost", size: "xs", sx: { flexShrink: 0 }, onClick: () => setCurrentMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1, 1)), "aria-label": "Next month", children: _jsx(ChevronRightIcon, { size: 16 }) })] })] }), _jsxs(Box, { role: "grid", "aria-label": "Calendar", children: [renderWeekdays !== null && renderWeekdays !== void 0 ? renderWeekdays : (_jsx(Box, { role: "row", display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0, mb: 1, children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((day) => (_jsx(Box, { role: "columnheader", textAlign: "center", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.02em", color: theme.colors.textMuted, py: 1, children: day }, day))) })), _jsx(Box, { onMouseLeave: () => onDayHover === null || onDayHover === void 0 ? void 0 : onDayHover(null), children: renderDays() })] })] }));
149
152
  };
150
153
  export default CalendarPanel;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useRef, useState } from "react";
3
- import { Box, FormControl, Input, InputGroup, InputRightElement, Popover, PopoverBody, PopoverContent, PopoverTrigger, useDisclosure, } from "@chakra-ui/react";
3
+ import { Box, FormControl, IconButton, Input, InputGroup, InputRightElement, Popover, PopoverAnchor, PopoverBody, PopoverContent, useDisclosure, } from "@chakra-ui/react";
4
4
  import { format, isAfter, isBefore, isSameDay, subDays, startOfMonth, endOfMonth } from "date-fns";
5
5
  import { CalendarIcon } from "lucide-react";
6
6
  import Button from "../Button/Button.js";
@@ -12,6 +12,7 @@ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
12
12
  import { getTextInputIconSizePx, getTextInputIconWrapperSx, } from "../Input/textInputIconSize.js";
13
13
  import TimePicker from "./TimePicker.js";
14
14
  import { TimePickerInput } from "./TimePickerInput.js";
15
+ import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
15
16
  // helper to set time on date while preserving date part
16
17
  const setTimeFrom = (base, time) => {
17
18
  const b = base ? new Date(base) : new Date();
@@ -25,6 +26,9 @@ export const RangeDatePicker = (props) => {
25
26
  const calendarIconPx = getTextInputIconSizePx(sizeKey);
26
27
  const calendarIconWrapperSx = getTextInputIconWrapperSx(sizeKey);
27
28
  const { isOpen, onOpen, onClose } = useDisclosure();
29
+ const requestExclusiveOpen = useExclusiveOverlay(isOpen, onClose);
30
+ const errorFieldId = id ? `${id}-error` : undefined;
31
+ const calendarLabel = label !== null && label !== void 0 ? label : "Choose date range";
28
32
  const inputRef = useRef(null);
29
33
  const triggerRef = useRef(null);
30
34
  const popoverRef = useRef(null);
@@ -91,8 +95,20 @@ export const RangeDatePicker = (props) => {
91
95
  onClose();
92
96
  };
93
97
  const handleOpen = () => {
98
+ requestExclusiveOpen();
94
99
  onOpen();
95
100
  };
101
+ const handleInputKeyDown = (e) => {
102
+ if (e.key === "Escape" && isOpen) {
103
+ e.preventDefault();
104
+ onClose();
105
+ return;
106
+ }
107
+ if (!isOpen && (e.key === "ArrowDown" || e.key === "Enter")) {
108
+ e.preventDefault();
109
+ handleOpen();
110
+ }
111
+ };
96
112
  const handleDaySelect = (day) => {
97
113
  const updated = new Date(day);
98
114
  if (selectingStart) {
@@ -159,7 +175,7 @@ export const RangeDatePicker = (props) => {
159
175
  return `${format(tempRangeStart, dateFormat)} -`;
160
176
  return "";
161
177
  }, [inputValue, tempRangeStart, tempRangeEnd, dateFormat]);
162
- return (_jsxs(FormControl, { id: id, isInvalid: error, isRequired: isRequired, isDisabled: disabled, width: width, children: [label && (_jsx(TextLabel, { label: label, isRequired: isRequired, isInformation: isInformation, informationMessage: informationMessage })), _jsxs(Popover, { isLazy: true, isOpen: isOpen, onClose: finalize, placement: "bottom-start", closeOnBlur: false, returnFocusOnClose: false, children: [_jsx(PopoverTrigger, { children: _jsx(Box, { ref: triggerRef, as: "div", children: _jsxs(InputGroup, { size: sizeKey, children: [_jsx(Input, { ref: inputRef, id: id, name: name, size: sizeKey, placeholder: placeholder, value: displayValue, readOnly: true, isDisabled: disabled, autoComplete: autoComplete, onFocus: () => {
178
+ return (_jsxs(FormControl, { id: id, isInvalid: error, isRequired: isRequired, isDisabled: disabled, width: width, children: [label && (_jsx(TextLabel, { label: label, id: id, isRequired: isRequired, isInformation: isInformation, informationMessage: informationMessage })), _jsxs(Popover, { isLazy: true, isOpen: isOpen, onClose: finalize, placement: "bottom-start", closeOnBlur: false, returnFocusOnClose: true, children: [_jsx(PopoverAnchor, { children: _jsx(Box, { ref: triggerRef, as: "div", children: _jsxs(InputGroup, { size: sizeKey, children: [_jsx(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: () => {
163
179
  if (!isOpen)
164
180
  handleOpen();
165
181
  }, onClick: () => {
@@ -172,7 +188,15 @@ export const RangeDatePicker = (props) => {
172
188
  : `0 0 0 1px ${theme.colors.primary[500]}`,
173
189
  }, _hover: {
174
190
  borderColor: error ? theme.colors.semanticText.error : undefined,
175
- }, cursor: "pointer" }), _jsx(InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", style: { cursor: "pointer" }, onClick: () => (isOpen ? onClose() : handleOpen()), children: _jsx(Box, { as: "span", sx: calendarIconWrapperSx, children: _jsx(CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), _jsx(PopoverContent, { w: "18rem", maxW: "18rem", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], children: _jsxs(PopoverBody, { p: 0, children: [_jsx(Box, { display: "flex", flexWrap: "wrap", gap: 2, mb: 3, children: presets.map((p) => (_jsx(Button, { size: "xs", variant: "outline", colorScheme: "gray", sx: { flex: "1 1 auto" }, onClick: () => {
191
+ }, cursor: "pointer" }), _jsx(InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", children: _jsx(IconButton, { "aria-label": "Open calendar", variant: "ghost", size: "sm", minW: "auto", h: "auto", isDisabled: disabled, onClick: (e) => {
192
+ e.stopPropagation();
193
+ if (!isOpen) {
194
+ handleOpen();
195
+ }
196
+ else {
197
+ onClose();
198
+ }
199
+ }, icon: _jsx(Box, { as: "span", sx: calendarIconWrapperSx, children: _jsx(CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) }) })] }) }) }), _jsx(PopoverContent, { w: "18rem", maxW: "18rem", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], role: "dialog", "aria-label": calendarLabel, children: _jsxs(PopoverBody, { p: 0, children: [_jsx(Box, { display: "flex", flexWrap: "wrap", gap: 2, mb: 3, children: presets.map((p) => (_jsx(Button, { size: "xs", variant: "outline", colorScheme: "gray", sx: { flex: "1 1 auto" }, onClick: () => {
176
200
  const [from, to] = p.getRange();
177
201
  applyPreset(from, to);
178
202
  }, children: p.label }, p.label))) }), _jsx(CalendarPanel, { currentMonth: currentMonth, setCurrentMonth: (updater) => setCurrentMonthState((prev) => updater(prev)), today: today, isRange: true, tempDate: null, tempRangeStart: tempRangeStart, tempRangeEnd: tempRangeEnd, hoveredDate: hoveredDate, onDayHover: setHoveredDate, isSameDay: isSameDay, isBefore: isBefore, isAfter: isAfter, minDate: minDate, maxDate: maxDate, disablePastDates: disablePastDates, disableFutureDates: disableFutureDates, disableToday: disableToday, onDaySelect: handleDaySelect, dayStates: dayStates, renderDayContent: renderDayContent }), formatHasTime && (_jsxs(Box, { mt: 3, display: "grid", gridTemplateColumns: "1fr", gap: 2, children: [_jsxs(Box, { children: [_jsx(Box, { fontSize: "xs", color: theme.colors.textMuted, mb: 1, children: "Start time" }), shouldUseSelectTimePicker ? (_jsx(TimePicker, { date: startTimeBaseDate, onChange: (updated) => {
@@ -201,6 +225,6 @@ export const RangeDatePicker = (props) => {
201
225
  return;
202
226
  }
203
227
  setTempRangeEnd(setTimeFrom(endTimeBaseDate, t));
204
- }, dateFormat: timePickerFormat, disabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), _jsx(Button, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) })] }), error && errorMessage && _jsx(ErrorMessage, { errorMessage: errorMessage }), helperText && !error && _jsx(HelperText, { helperText: helperText })] }));
228
+ }, dateFormat: timePickerFormat, disabled: disabled || !tempRangeEnd, size: sizeKey }))] })] })), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mt: 3, pt: 3, borderTop: "1px solid", borderColor: theme.colors.boxborder[200], children: [_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleClear, children: "Clear" }), _jsx(Button, { size: "sm", variant: "gradient", onClick: requestClose, children: "Apply" })] })] }) })] }), error && errorMessage && (_jsx(ErrorMessage, { id: errorFieldId, errorMessage: errorMessage })), helperText && !error && _jsx(HelperText, { helperText: helperText })] }));
205
229
  };
206
230
  export default RangeDatePicker;