pixelize-design-library 2.4.1-beta.1 → 2.4.1-beta.2

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 (70) hide show
  1. package/.cursor/modules/account-management/MODULE.md +8 -1
  2. package/.cursor/modules/feedback/MODULE.md +6 -0
  3. package/.cursor/modules/inputs-date-file/MODULE.md +12 -1
  4. package/.cursor/modules/inputs-select/MODULE.md +64 -2
  5. package/.cursor/modules/inputs-toggle/MODULE.md +6 -0
  6. package/.cursor/modules/layout-navigation/MODULE.md +55 -5
  7. package/.cursor/modules/overlays/MODULE.md +29 -16
  8. package/.cursor/modules/table/MODULE.md +6 -0
  9. package/.cursor/modules/theme/MODULE.md +117 -0
  10. package/dist/Assets/defaultLogo.d.ts.map +1 -1
  11. package/dist/Assets/defaultLogo.js +1 -3
  12. package/dist/Assets/defaultLogo.tsx +4 -8
  13. package/dist/Components/DatePicker/CalendarPanel.d.ts.map +1 -1
  14. package/dist/Components/DatePicker/CalendarPanel.js +12 -3
  15. package/dist/Components/DatePicker/SingleDatePicker.d.ts.map +1 -1
  16. package/dist/Components/DatePicker/SingleDatePicker.js +11 -9
  17. package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -2
  18. package/dist/Components/DatePicker/TimePicker.d.ts.map +1 -1
  19. package/dist/Components/DatePicker/TimePicker.js +14 -2
  20. package/dist/Components/DatePicker/TimePickerInput.d.ts.map +1 -1
  21. package/dist/Components/DatePicker/TimePickerInput.js +9 -1
  22. package/dist/Components/SelectV2/SelectV2.d.ts +3 -0
  23. package/dist/Components/SelectV2/SelectV2.d.ts.map +1 -0
  24. package/dist/Components/SelectV2/SelectV2.js +185 -0
  25. package/dist/Components/SelectV2/SelectV2Props.d.ts +67 -0
  26. package/dist/Components/SelectV2/SelectV2Props.d.ts.map +1 -0
  27. package/dist/Components/SelectV2/SelectV2Props.js +2 -0
  28. package/dist/Components/SideBar/SideBar.js +1 -1
  29. package/dist/Components/WorkspaceWindow/WorkspaceTrayPreview.js +2 -1
  30. package/dist/Components/WorkspaceWindow/WorkspaceWindow.d.ts +2 -2
  31. package/dist/Components/WorkspaceWindow/WorkspaceWindow.d.ts.map +1 -1
  32. package/dist/Components/WorkspaceWindow/WorkspaceWindow.js +25 -4
  33. package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts +18 -0
  34. package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts.map +1 -1
  35. package/dist/Theme/chakra/Avatar.styles.d.ts +33 -0
  36. package/dist/Theme/chakra/Avatar.styles.d.ts.map +1 -0
  37. package/dist/Theme/chakra/Avatar.styles.js +28 -0
  38. package/dist/Theme/chakra/Drawer.styles.d.ts +32 -0
  39. package/dist/Theme/chakra/Drawer.styles.d.ts.map +1 -0
  40. package/dist/Theme/chakra/Drawer.styles.js +26 -0
  41. package/dist/Theme/chakra/Menu.styles.d.ts +70 -0
  42. package/dist/Theme/chakra/Menu.styles.d.ts.map +1 -0
  43. package/dist/Theme/chakra/Menu.styles.js +50 -0
  44. package/dist/Theme/chakra/Modal.styles.d.ts +32 -0
  45. package/dist/Theme/chakra/Modal.styles.d.ts.map +1 -0
  46. package/dist/Theme/chakra/Modal.styles.js +26 -0
  47. package/dist/Theme/chakra/Popover.styles.d.ts +37 -0
  48. package/dist/Theme/chakra/Popover.styles.d.ts.map +1 -0
  49. package/dist/Theme/chakra/Popover.styles.js +30 -0
  50. package/dist/Theme/chakra/Slider.styles.d.ts +31 -0
  51. package/dist/Theme/chakra/Slider.styles.d.ts.map +1 -0
  52. package/dist/Theme/chakra/Slider.styles.js +25 -0
  53. package/dist/Theme/chakra/Switch.styles.d.ts +31 -0
  54. package/dist/Theme/chakra/Switch.styles.d.ts.map +1 -0
  55. package/dist/Theme/chakra/Switch.styles.js +24 -0
  56. package/dist/Theme/chakra/Tabs.styles.d.ts +43 -0
  57. package/dist/Theme/chakra/Tabs.styles.d.ts.map +1 -0
  58. package/dist/Theme/chakra/Tabs.styles.js +41 -0
  59. package/dist/Theme/chakra/componentStyles.d.ts +228 -1
  60. package/dist/Theme/chakra/componentStyles.d.ts.map +1 -1
  61. package/dist/Theme/chakra/componentStyles.js +62 -0
  62. package/dist/Theme/provider/PixelizeThemeProvider.d.ts +11 -1
  63. package/dist/Theme/provider/PixelizeThemeProvider.d.ts.map +1 -1
  64. package/dist/Theme/provider/PixelizeThemeProvider.js +35 -2
  65. package/dist/Theme/provider/ThemeSwitcher.d.ts.map +1 -1
  66. package/dist/Theme/provider/ThemeSwitcher.js +23 -11
  67. package/dist/index.d.ts +3 -1
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +4 -2
  70. package/package.json +1 -1
@@ -225,7 +225,7 @@ const normalizeTimeBuffer = (tokenChar, rawBuffer, segmentLength, is12Hour) => {
225
225
  return { value: buf, completed: buf.length >= segmentLength };
226
226
  };
227
227
  const SingleDatePicker = (props) => {
228
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
228
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
229
229
  const { id, name, label, isRequired, isInformation, informationMessage, error, errorMessage, helperText, placeholderText, dateFormat = "dd/MM/yyyy", pickerType, minDate, maxDate, disableFutureDates, disablePastDates, autoComplete = "off", disabled, width = "100%", disableToday = false, size = "md", } = props;
230
230
  const theme = (0, useCustomTheme_1.useCustomTheme)();
231
231
  const sizeKey = typeof size === "string" ? size : "md";
@@ -945,14 +945,16 @@ const SingleDatePicker = (props) => {
945
945
  return;
946
946
  }
947
947
  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, borderColor: error ? (_d = (_c = theme.colors.semantic) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d[500] : undefined, _focus: {
949
- borderColor: error ? (_f = (_e = theme.colors.semantic) === null || _e === void 0 ? void 0 : _e.error) === null || _f === void 0 ? void 0 : _f[500] : theme.colors.primary[500],
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: (_c = theme.colors.gray) === null || _c === void 0 ? void 0 : _c[50], borderColor: error
949
+ ? (_e = (_d = theme.colors.semantic) === null || _d === void 0 ? void 0 : _d.error) === null || _e === void 0 ? void 0 : _e[500]
950
+ : (_f = theme.colors.boxborder) === null || _f === void 0 ? void 0 : _f[800], _focus: {
951
+ borderColor: error ? (_h = (_g = theme.colors.semantic) === null || _g === void 0 ? void 0 : _g.error) === null || _h === void 0 ? void 0 : _h[500] : theme.colors.primary[500],
950
952
  boxShadow: error
951
- ? `0 0 0 0.125rem ${(_g = theme.colors.boxShadow) === null || _g === void 0 ? void 0 : _g.error}`
952
- : `0 0 0 0.125rem ${(_h = theme.colors.boxShadow) === null || _h === void 0 ? void 0 : _h.primary}`,
953
+ ? `0 0 0 0.125rem ${(_j = theme.colors.boxShadow) === null || _j === void 0 ? void 0 : _j.error}`
954
+ : `0 0 0 0.125rem ${(_k = theme.colors.boxShadow) === null || _k === void 0 ? void 0 : _k.primary}`,
953
955
  }, _hover: {
954
- borderColor: error ? (_k = (_j = theme.colors.semantic) === null || _j === void 0 ? void 0 : _j.error) === null || _k === void 0 ? void 0 : _k[500] : undefined,
955
- }, cursor: "text", boxShadow: error ? `0 0 0 0.125rem ${(_l = theme.colors.boxShadow) === null || _l === void 0 ? void 0 : _l.error}` : `` }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", onClick: (e) => {
956
+ borderColor: error ? (_m = (_l = theme.colors.semantic) === null || _l === void 0 ? void 0 : _l.error) === null || _m === void 0 ? void 0 : _m[500] : theme.colors.primary[500],
957
+ }, cursor: "text", boxShadow: error ? `0 0 0 0.125rem ${(_o = theme.colors.boxShadow) === null || _o === void 0 ? void 0 : _o.error}` : `` }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", onClick: (e) => {
956
958
  e.stopPropagation();
957
959
  if (!isOpen) {
958
960
  handleOpen();
@@ -960,7 +962,7 @@ const SingleDatePicker = (props) => {
960
962
  else {
961
963
  onClose();
962
964
  }
963
- }, 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.gray[500] }) }) })] }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { width: "auto", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "0.75rem", border: "1px solid", borderColor: (_m = theme.colors.boxborder) === null || _m === void 0 ? void 0 : _m[500], 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) => {
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.gray[500] }) }) })] }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { width: "auto", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "0.75rem", border: "1px solid", borderColor: (_p = theme.colors.boxborder) === null || _p === void 0 ? void 0 : _p[500], 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) => {
964
966
  setTempDate(updatedDate);
965
967
  setInputValue(updatedDate ? (0, date_fns_1.format)(updatedDate, resolvedDateFormat) : "");
966
968
  setIsTyping(false);
@@ -968,7 +970,7 @@ const SingleDatePicker = (props) => {
968
970
  setTempDate(updatedDate);
969
971
  setInputValue((0, date_fns_1.format)(updatedDate, resolvedDateFormat));
970
972
  setIsTyping(false);
971
- }, 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: (_o = theme.colors.boxborder) === null || _o === void 0 ? void 0 : _o[300], children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: () => {
973
+ }, 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: (_q = theme.colors.boxborder) === null || _q === void 0 ? void 0 : _q[300], children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: () => {
972
974
  setTempDate(null);
973
975
  requestClose(null);
974
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 })] }));
@@ -16,7 +16,7 @@ const TimePickerInput_1 = require("./TimePickerInput");
16
16
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
17
17
  const formatToPlaceholder = (formatStr) => formatStr.replace(/h{1,2}/gi, "HH").replace(/m{1,2}/gi, "mm").replace(/a{1,2}/gi, "AM");
18
18
  const TimeOnlyPicker = (props) => {
19
- var _a, _b;
19
+ var _a, _b, _c;
20
20
  const { id, label, isRequired, isInformation, informationMessage, error, errorMessage, helperText, placeholderText, dateFormat = "HH:mm", disabled, width = "100%", disableToday = false, size = "md", } = props;
21
21
  const theme = (0, useCustomTheme_1.useCustomTheme)();
22
22
  const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
@@ -79,7 +79,7 @@ const TimeOnlyPicker = (props) => {
79
79
  onOpen();
80
80
  }, 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
81
  handleTimePickerChange(updatedDate);
82
- } }), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: "gray.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 })] }));
82
+ } }), (0, jsx_runtime_1.jsxs)(react_2.Box, { display: "flex", justifyContent: "space-between", mt: 4, pt: 4, borderTop: "1px solid", borderColor: (_c = theme.colors.boxborder) === null || _c === void 0 ? void 0 : _c[300], 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 })] }));
83
83
  };
84
84
  exports.TimeOnlyPicker = TimeOnlyPicker;
85
85
  exports.default = exports.TimeOnlyPicker;
@@ -1 +1 @@
1
- {"version":3,"file":"TimePicker.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/TimePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAmGzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"TimePicker.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/TimePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8IzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -3,7 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("react/jsx-runtime");
4
4
  const react_1 = require("react");
5
5
  const react_2 = require("@chakra-ui/react");
6
+ const useCustomTheme_1 = require("../../Theme/useCustomTheme");
6
7
  const TimePicker = ({ date, onChange, dateFormat, disabled = false }) => {
8
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
9
+ const theme = (0, useCustomTheme_1.useCustomTheme)();
7
10
  const is12HourFormat = /(hh|h).*a/i.test(dateFormat);
8
11
  const deriveDisplayHour = (rawHour) => {
9
12
  if (!is12HourFormat)
@@ -52,9 +55,18 @@ const TimePicker = ({ date, onChange, dateFormat, disabled = false }) => {
52
55
  updateTime(hour, minute, newMeridiem);
53
56
  };
54
57
  const displayHour = is12HourFormat ? (hour % 12 === 0 ? 12 : hour % 12) : hour;
55
- 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, children: Array.from({ length: is12HourFormat ? 12 : 24 }, (_, i) => {
58
+ 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: (_a = theme.colors.gray) === null || _a === void 0 ? void 0 : _a[50], borderColor: (_b = theme.colors.boxborder) === null || _b === void 0 ? void 0 : _b[800], _focus: {
59
+ borderColor: theme.colors.primary[500],
60
+ boxShadow: `0 0 0 0.125rem ${(_c = theme.colors.boxShadow) === null || _c === void 0 ? void 0 : _c.primary}`,
61
+ }, _hover: { borderColor: theme.colors.primary[500] }, children: Array.from({ length: is12HourFormat ? 12 : 24 }, (_, i) => {
56
62
  const value = is12HourFormat ? i + 1 : i;
57
63
  return ((0, jsx_runtime_1.jsx)("option", { value: value, children: value.toString().padStart(2, "0") }, value));
58
- }) }), (0, jsx_runtime_1.jsx)(react_2.Select, { value: minute, onChange: handleMinuteChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, 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, children: [(0, jsx_runtime_1.jsx)("option", { value: "AM", children: "AM" }), (0, jsx_runtime_1.jsx)("option", { value: "PM", children: "PM" })] }))] }));
64
+ }) }), (0, jsx_runtime_1.jsx)(react_2.Select, { value: minute, onChange: handleMinuteChange, flex: "1", minW: 0, size: "sm", isDisabled: disabled, bg: (_d = theme.colors.gray) === null || _d === void 0 ? void 0 : _d[50], borderColor: (_e = theme.colors.boxborder) === null || _e === void 0 ? void 0 : _e[800], _focus: {
65
+ borderColor: theme.colors.primary[500],
66
+ boxShadow: `0 0 0 0.125rem ${(_f = theme.colors.boxShadow) === null || _f === void 0 ? void 0 : _f.primary}`,
67
+ }, _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: (_g = theme.colors.gray) === null || _g === void 0 ? void 0 : _g[50], borderColor: (_h = theme.colors.boxborder) === null || _h === void 0 ? void 0 : _h[800], _focus: {
68
+ borderColor: theme.colors.primary[500],
69
+ boxShadow: `0 0 0 0.125rem ${(_j = theme.colors.boxShadow) === null || _j === void 0 ? void 0 : _j.primary}`,
70
+ }, _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" })] }))] }));
59
71
  };
60
72
  exports.default = TimePicker;
@@ -1 +1 @@
1
- {"version":3,"file":"TimePickerInput.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/TimePickerInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAUjF,UAAU,oBAAoB;IAC5B,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAClC;AA6ED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAyX1D,CAAC"}
1
+ {"version":3,"file":"TimePickerInput.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/TimePickerInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAUjF,UAAU,oBAAoB;IAC5B,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAClC;AA6ED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAoY1D,CAAC"}
@@ -92,6 +92,7 @@ const caretFromDigitIndex = (digitIndex, digitsLen) => {
92
92
  };
93
93
  const formatToPlaceholder = (formatStr) => formatStr.replace(/h{1,2}/gi, "HH").replace(/m{1,2}/gi, "mm").replace(/a{1,2}/gi, "AM");
94
94
  const TimePickerInput = ({ value, onChange, dateFormat, disabled = false, placeholder, onFocus, onBlur, error, size = "md", }) => {
95
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
95
96
  const theme = (0, useCustomTheme_1.useCustomTheme)();
96
97
  const sizeKey = typeof size === "string" ? size : "md";
97
98
  const iconPx = (0, textInputIconSize_1.getTextInputIconSizePx)(sizeKey);
@@ -403,6 +404,13 @@ const TimePickerInput = ({ value, onChange, dateFormat, disabled = false, placeh
403
404
  inputRef.current.value = is12Hour && formatted ? `${formatted} ${ampm}` : formatted;
404
405
  }
405
406
  }, [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 }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { pointerEvents: "none", height: "100%", display: "flex", alignItems: "center", children: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", sx: iconWrapperSx, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ClockIcon, { size: iconPx, color: theme.colors.gray[500] }) }) })] }));
407
+ 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: (_a = theme.colors.gray) === null || _a === void 0 ? void 0 : _a[50], borderColor: error ? (_c = (_b = theme.colors.semantic) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c[500] : (_d = theme.colors.boxborder) === null || _d === void 0 ? void 0 : _d[800], _focus: {
408
+ borderColor: error ? (_f = (_e = theme.colors.semantic) === null || _e === void 0 ? void 0 : _e.error) === null || _f === void 0 ? void 0 : _f[500] : theme.colors.primary[500],
409
+ boxShadow: error
410
+ ? `0 0 0 0.125rem ${(_g = theme.colors.boxShadow) === null || _g === void 0 ? void 0 : _g.error}`
411
+ : `0 0 0 0.125rem ${(_h = theme.colors.boxShadow) === null || _h === void 0 ? void 0 : _h.primary}`,
412
+ }, _hover: {
413
+ borderColor: error ? (_k = (_j = theme.colors.semantic) === null || _j === void 0 ? void 0 : _j.error) === null || _k === void 0 ? void 0 : _k[500] : theme.colors.primary[500],
414
+ } }), (0, jsx_runtime_1.jsx)(react_2.InputRightElement, { pointerEvents: "none", height: "100%", display: "flex", alignItems: "center", children: (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", sx: iconWrapperSx, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ClockIcon, { size: iconPx, color: theme.colors.gray[500] }) }) })] }));
407
415
  };
408
416
  exports.TimePickerInput = TimePickerInput;
@@ -0,0 +1,3 @@
1
+ import { SelectV2Props } from "./SelectV2Props";
2
+ export default function SelectV2(props: SelectV2Props): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=SelectV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectV2.d.ts","sourceRoot":"","sources":["../../../src/Components/SelectV2/SelectV2.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAc,aAAa,EAAgB,MAAM,iBAAiB,CAAC;AAY1E,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,aAAa,2CAiYpD"}
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = SelectV2;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const react_2 = require("@chakra-ui/react");
10
+ const lucide_react_1 = require("lucide-react");
11
+ const useCustomTheme_1 = require("../../Theme/useCustomTheme");
12
+ const fieldStyles_1 = require("../Common/fieldStyles");
13
+ const FormLabel_1 = require("../Common/FormLabel");
14
+ const ErrorMessage_1 = __importDefault(require("../Common/ErrorMessage"));
15
+ const HelperText_1 = __importDefault(require("../Common/HelperText"));
16
+ // Mirrors Select.styles.ts sizing so a call site swapping Select -> SelectV2 keeps its layout.
17
+ const SIZE_MAP = {
18
+ sm: { h: "2.125rem", fontSize: "0.8125rem", px: "0.5rem" },
19
+ md: { h: "2.375rem", fontSize: "0.875rem", px: "0.75rem" },
20
+ lg: { h: "2.75rem", fontSize: "0.9375rem", px: "1rem" },
21
+ };
22
+ const asIdSet = (values) => new Set((values !== null && values !== void 0 ? values : []).map((v) => v.toString()));
23
+ function SelectV2(props) {
24
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
25
+ const { options = [], placeholder = "Select Option", label, error = false, errorMessage, helperText, isDisabled = false, isRequired = false, size = "md", isSearchable = true, width, formControlStyle, onBlur, onFocus, renderOption, renderValue, maxMenuHeight = "16rem", defaultOpen = false, "data-testid": dataTestId, "aria-label": ariaLabel, } = props;
26
+ const theme = (0, useCustomTheme_1.useCustomTheme)();
27
+ const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)({ defaultIsOpen: defaultOpen });
28
+ const [filterText, setFilterText] = (0, react_1.useState)("");
29
+ const [activeIndex, setActiveIndex] = (0, react_1.useState)(-1);
30
+ const triggerRef = (0, react_1.useRef)(null);
31
+ const filterInputRef = (0, react_1.useRef)(null);
32
+ const listRef = (0, react_1.useRef)(null);
33
+ const s = (_a = SIZE_MAP[size]) !== null && _a !== void 0 ? _a : SIZE_MAP.md;
34
+ const fieldStyles = (0, fieldStyles_1.getFieldStateStyles)(theme, { error, focused: isOpen });
35
+ const selectedIds = (0, react_1.useMemo)(() => props.isMulti
36
+ ? asIdSet(props.value)
37
+ : asIdSet(props.value !== undefined ? [props.value] : undefined),
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps
39
+ [props.isMulti, props.isMulti ? props.value : props.value]);
40
+ const selectedOptions = (0, react_1.useMemo)(() => options.filter((option) => selectedIds.has(option.id.toString())), [options, selectedIds]);
41
+ const filteredOptions = (0, react_1.useMemo)(() => {
42
+ if (!isSearchable || !filterText.trim())
43
+ return options;
44
+ const needle = filterText.trim().toLowerCase();
45
+ return options.filter((option) => option.label.toString().toLowerCase().includes(needle));
46
+ }, [options, filterText, isSearchable]);
47
+ const resetAndClose = (0, react_1.useCallback)((opts) => {
48
+ if (props.isMulti && (opts === null || opts === void 0 ? void 0 : opts.keepOpenForMulti))
49
+ return;
50
+ onClose();
51
+ setFilterText("");
52
+ setActiveIndex(-1);
53
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur();
54
+ },
55
+ // eslint-disable-next-line react-hooks/exhaustive-deps
56
+ [onClose, onBlur, props.isMulti]);
57
+ const handleOpen = () => {
58
+ var _a;
59
+ if (isDisabled)
60
+ return;
61
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus();
62
+ onOpen();
63
+ const firstSelected = props.isMulti ? (_a = props.value) === null || _a === void 0 ? void 0 : _a[0] : props.value;
64
+ const selectedFilteredIndex = filteredOptions.findIndex((option) => option.id.toString() === (firstSelected === null || firstSelected === void 0 ? void 0 : firstSelected.toString()));
65
+ setActiveIndex(selectedFilteredIndex);
66
+ };
67
+ const handleSelect = (option) => {
68
+ var _a, _b;
69
+ if (option.isDisabled)
70
+ return;
71
+ if (props.isMulti) {
72
+ const alreadySelected = selectedIds.has(option.id.toString());
73
+ const next = alreadySelected
74
+ ? selectedOptions.filter((selected) => selected.id.toString() !== option.id.toString())
75
+ : [...selectedOptions, option];
76
+ props.onChange(next);
77
+ resetAndClose({ keepOpenForMulti: true });
78
+ (_a = filterInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
79
+ return;
80
+ }
81
+ props.onChange(option);
82
+ resetAndClose();
83
+ (_b = triggerRef.current) === null || _b === void 0 ? void 0 : _b.focus();
84
+ };
85
+ (0, react_1.useEffect)(() => {
86
+ if (isOpen && isSearchable) {
87
+ // Popover content mounts after open; defer focus so it lands on the rendered input.
88
+ const id = requestAnimationFrame(() => { var _a; return (_a = filterInputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); });
89
+ return () => cancelAnimationFrame(id);
90
+ }
91
+ }, [isOpen, isSearchable]);
92
+ (0, react_1.useEffect)(() => {
93
+ var _a;
94
+ if (activeIndex < 0 || !listRef.current)
95
+ return;
96
+ const activeEl = listRef.current.querySelector(`[data-index="${activeIndex}"]`);
97
+ (_a = activeEl === null || activeEl === void 0 ? void 0 : activeEl.scrollIntoView) === null || _a === void 0 ? void 0 : _a.call(activeEl, { block: "nearest" });
98
+ }, [activeIndex]);
99
+ const moveActive = (delta) => {
100
+ if (!filteredOptions.length)
101
+ return;
102
+ setActiveIndex((current) => {
103
+ const next = current + delta;
104
+ if (next < 0)
105
+ return filteredOptions.length - 1;
106
+ if (next >= filteredOptions.length)
107
+ return 0;
108
+ return next;
109
+ });
110
+ };
111
+ const handleTriggerKeyDown = (event) => {
112
+ if (isDisabled)
113
+ return;
114
+ if (event.key === "ArrowDown" || event.key === "ArrowUp" || event.key === "Enter" || event.key === " ") {
115
+ event.preventDefault();
116
+ handleOpen();
117
+ }
118
+ };
119
+ const handleListKeyDown = (event) => {
120
+ var _a;
121
+ switch (event.key) {
122
+ case "ArrowDown":
123
+ event.preventDefault();
124
+ moveActive(1);
125
+ break;
126
+ case "ArrowUp":
127
+ event.preventDefault();
128
+ moveActive(-1);
129
+ break;
130
+ case "Enter": {
131
+ event.preventDefault();
132
+ const activeOption = filteredOptions[activeIndex];
133
+ if (activeOption)
134
+ handleSelect(activeOption);
135
+ break;
136
+ }
137
+ case "Escape":
138
+ event.preventDefault();
139
+ resetAndClose();
140
+ (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
141
+ break;
142
+ case "Tab":
143
+ resetAndClose();
144
+ break;
145
+ default:
146
+ break;
147
+ }
148
+ };
149
+ const listboxId = `selectv2-listbox-${label !== null && label !== void 0 ? label : "field"}`;
150
+ const defaultTriggerContent = () => {
151
+ var _a;
152
+ if (props.isMulti) {
153
+ const max = (_a = props.maxLabelsBeforeSummary) !== null && _a !== void 0 ? _a : 2;
154
+ if (selectedOptions.length === 0)
155
+ return placeholder;
156
+ if (selectedOptions.length > max) {
157
+ return `${selectedOptions.length} selected`;
158
+ }
159
+ return selectedOptions.map((o) => o.label).join(", ");
160
+ }
161
+ return selectedOptions[0] ? selectedOptions[0].label : placeholder;
162
+ };
163
+ const triggerIcon = !props.isMulti && ((_b = selectedOptions[0]) === null || _b === void 0 ? void 0 : _b.icon) ? selectedOptions[0].icon : null;
164
+ return ((0, jsx_runtime_1.jsxs)(react_2.FormControl, { isInvalid: error, isDisabled: isDisabled, style: formControlStyle, width: width, children: [label && ((0, jsx_runtime_1.jsx)(FormLabel_1.TextLabel, { label: label, isRequired: isRequired })), (0, jsx_runtime_1.jsxs)(react_2.Popover, { isOpen: isOpen, onClose: () => resetAndClose(), placement: "bottom-start", matchWidth: true, autoFocus: false, returnFocusOnClose: false, gutter: 4, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsxs)(react_2.Box, { as: "button", type: "button", ref: triggerRef, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-disabled": isDisabled, "aria-label": ariaLabel, disabled: isDisabled, onClick: handleOpen, onKeyDown: handleTriggerKeyDown, display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", h: s.h, px: s.px, fontSize: s.fontSize, fontWeight: 500, textAlign: "left", cursor: isDisabled ? "not-allowed" : "pointer", opacity: isDisabled ? 0.4 : 1, color: selectedOptions.length ? (_c = theme.colors.text) === null || _c === void 0 ? void 0 : _c[900] : (_d = theme.colors.gray) === null || _d === void 0 ? void 0 : _d[500], "data-testid": dataTestId, ...fieldStyles, children: [(0, jsx_runtime_1.jsxs)(react_2.Box, { as: "span", display: "inline-flex", alignItems: "center", gap: 1.5, minW: 0, isTruncated: true, children: [triggerIcon ? ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", display: "inline-flex", flexShrink: 0, children: triggerIcon })) : null, (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", isTruncated: true, fontStyle: selectedOptions.length ? "normal" : "italic", children: renderValue ? renderValue(selectedOptions) : defaultTriggerContent() })] }), (0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", display: "inline-flex", flexShrink: 0, ml: 2, transition: "transform 0.2s ease", transform: isOpen ? "rotate(180deg)" : "rotate(0deg)", color: (_e = theme.colors.gray) === null || _e === void 0 ? void 0 : _e[500], children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { size: 16 }) })] }) }), (0, jsx_runtime_1.jsx)(react_2.Portal, { children: (0, jsx_runtime_1.jsxs)(react_2.PopoverContent, { width: "100%", borderRadius: "0.625rem", border: `0.063rem solid ${(_g = (_f = theme.colors.boxborder) === null || _f === void 0 ? void 0 : _f[200]) !== null && _g !== void 0 ? _g : (_h = theme.colors.gray) === null || _h === void 0 ? void 0 : _h[200]}`, boxShadow: (_j = theme.shadows) === null || _j === void 0 ? void 0 : _j.lg, overflow: "hidden", onKeyDown: handleListKeyDown, children: [isSearchable && ((0, jsx_runtime_1.jsx)(react_2.Box, { p: 2, borderBottom: `0.063rem solid ${(_l = (_k = theme.colors.boxborder) === null || _k === void 0 ? void 0 : _k[100]) !== null && _l !== void 0 ? _l : (_m = theme.colors.gray) === null || _m === void 0 ? void 0 : _m[200]}`, children: (0, jsx_runtime_1.jsx)(react_2.Input, { ref: filterInputRef, size: "sm", placeholder: "Type to filter...", value: filterText, onChange: (event) => {
165
+ setFilterText(event.target.value);
166
+ setActiveIndex(0);
167
+ }, "aria-label": "Filter options" }) })), (0, jsx_runtime_1.jsxs)(react_2.Box, { id: listboxId, ref: listRef, role: "listbox", "aria-multiselectable": props.isMulti || undefined, maxH: maxMenuHeight, overflowY: "auto", py: 1, sx: {
168
+ scrollbarWidth: "thin",
169
+ scrollbarColor: `${(_o = theme.colors.gray) === null || _o === void 0 ? void 0 : _o[300]} transparent`,
170
+ "&::-webkit-scrollbar": { width: "6px" },
171
+ "&::-webkit-scrollbar-thumb": {
172
+ background: (_p = theme.colors.gray) === null || _p === void 0 ? void 0 : _p[300],
173
+ borderRadius: "3px",
174
+ },
175
+ }, children: [filteredOptions.length === 0 && ((0, jsx_runtime_1.jsx)(react_2.Box, { px: 3, py: 2, fontSize: "0.8125rem", color: (_q = theme.colors.gray) === null || _q === void 0 ? void 0 : _q[500], children: "No Options" })), filteredOptions.map((option, index) => {
176
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
177
+ const isSelected = selectedIds.has(option.id.toString());
178
+ const isActive = index === activeIndex;
179
+ return ((0, jsx_runtime_1.jsxs)(react_2.Box, { id: `${listboxId}-option-${index}`, "data-index": index, role: "option", "aria-selected": isSelected, "aria-disabled": option.isDisabled, onMouseEnter: () => setActiveIndex(index), onClick: () => handleSelect(option), mx: 1.5, px: 2.5, py: 1.5, borderRadius: "0.375rem", cursor: option.isDisabled ? "not-allowed" : "pointer", opacity: option.isDisabled ? 0.4 : 1, display: "flex", alignItems: "center", gap: 2, fontSize: "0.8125rem", fontWeight: isSelected && !props.isMulti ? 600 : 500, color: isSelected && !props.isMulti
180
+ ? (_b = (_a = theme.colors.primary) === null || _a === void 0 ? void 0 : _a[700]) !== null && _b !== void 0 ? _b : (_c = theme.colors.primary) === null || _c === void 0 ? void 0 : _c[600]
181
+ : (_e = (_d = theme.colors.text) === null || _d === void 0 ? void 0 : _d[700]) !== null && _e !== void 0 ? _e : (_f = theme.colors.gray) === null || _f === void 0 ? void 0 : _f[700], bg: isActive
182
+ ? (_j = (_h = (_g = theme.colors.primary) === null || _g === void 0 ? void 0 : _g.opacity) === null || _h === void 0 ? void 0 : _h[8]) !== null && _j !== void 0 ? _j : (_k = theme.colors.gray) === null || _k === void 0 ? void 0 : _k[100]
183
+ : "transparent", transition: "background 0.12s ease, color 0.12s ease", children: [props.isMulti ? ((0, jsx_runtime_1.jsx)(react_2.Checkbox, { isChecked: isSelected, isDisabled: option.isDisabled, pointerEvents: "none", tabIndex: -1 })) : null, renderOption ? ((0, jsx_runtime_1.jsx)(react_2.Box, { flex: 1, minW: 0, children: renderOption(option, { isSelected, isActive }) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [option.icon ? ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", display: "inline-flex", flexShrink: 0, children: option.icon })) : null, (0, jsx_runtime_1.jsxs)(react_2.Box, { flex: 1, minW: 0, isTruncated: true, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", isTruncated: true, children: option.label }), option.description ? ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", display: "block", fontSize: "0.75rem", fontWeight: 400, color: (_l = theme.colors.gray) === null || _l === void 0 ? void 0 : _l[500], isTruncated: true, children: option.description })) : null] })] }))] }, option.id));
184
+ })] })] }) })] }), error && (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { errorMessage: errorMessage }), helperText && !error && (0, jsx_runtime_1.jsx)(HelperText_1.default, { helperText: helperText })] }));
185
+ }
@@ -0,0 +1,67 @@
1
+ import type { ReactNode } from "react";
2
+ export type OptionProp = {
3
+ id: string | number;
4
+ label: string | number;
5
+ /** Optional leading icon/avatar for this option's row (and the trigger, when selected). */
6
+ icon?: ReactNode;
7
+ /** Optional secondary line under the label (e.g. an email under a name). */
8
+ description?: string;
9
+ isDisabled?: boolean;
10
+ };
11
+ export type SelectV2Size = "sm" | "md" | "lg";
12
+ type SelectV2CommonProps = {
13
+ options: OptionProp[];
14
+ placeholder?: string;
15
+ label?: string;
16
+ error?: boolean;
17
+ errorMessage?: string;
18
+ helperText?: string;
19
+ isDisabled?: boolean;
20
+ isRequired?: boolean;
21
+ size?: SelectV2Size;
22
+ /** Shows a type-ahead filter input at the top of the popup. Defaults to true. */
23
+ isSearchable?: boolean;
24
+ /** Width applied to the trigger + popup. Defaults to 100% of the container. */
25
+ width?: string | number;
26
+ formControlStyle?: React.CSSProperties;
27
+ onBlur?: () => void;
28
+ onFocus?: () => void;
29
+ /** Forwarded to the trigger button — lets call sites keep existing RTL/e2e queries when migrating from `Select`. */
30
+ "data-testid"?: string;
31
+ /** Forwarded to the trigger button — for a labelless select (no `label` prop) that still needs an accessible name. */
32
+ "aria-label"?: string;
33
+ /**
34
+ * Full control over an option row's contents (icon + label + badge, avatar + name/email, etc).
35
+ * Falls back to plain `option.label` text when omitted. Receives `isSelected`/`isActive` so a
36
+ * custom row can mirror the built-in selected/keyboard-active styling if it re-implements them.
37
+ */
38
+ renderOption?: (option: OptionProp, state: {
39
+ isSelected: boolean;
40
+ isActive: boolean;
41
+ }) => ReactNode;
42
+ /** Custom trigger content when a value (or values) is selected. Falls back to label text / icon. */
43
+ renderValue?: (selected: OptionProp[]) => ReactNode;
44
+ /** Max popup height before the option list scrolls. Defaults to "16rem". */
45
+ maxMenuHeight?: string;
46
+ /**
47
+ * Opens the popup immediately on mount instead of waiting for a click — for inline-edit
48
+ * patterns (a table cell that swaps to a select the instant it becomes editable). Clicking
49
+ * away still closes it via the normal Popover close-on-blur behavior (which fires `onBlur`).
50
+ */
51
+ defaultOpen?: boolean;
52
+ };
53
+ export type SelectV2SingleProps = SelectV2CommonProps & {
54
+ isMulti?: false;
55
+ value?: string | number;
56
+ onChange: (selectedOption: OptionProp | undefined) => void;
57
+ };
58
+ export type SelectV2MultiProps = SelectV2CommonProps & {
59
+ isMulti: true;
60
+ value?: (string | number)[];
61
+ onChange: (selectedOptions: OptionProp[]) => void;
62
+ /** Show "N selected" once more than this many are chosen, instead of listing every label. Defaults to 2. */
63
+ maxLabelsBeforeSummary?: number;
64
+ };
65
+ export type SelectV2Props = SelectV2SingleProps | SelectV2MultiProps;
66
+ export {};
67
+ //# sourceMappingURL=SelectV2Props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectV2Props.d.ts","sourceRoot":"","sources":["../../../src/Components/SelectV2/SelectV2Props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,oHAAoH;IACpH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sHAAsH;IACtH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CACb,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,KAC9C,SAAS,CAAC;IACf,oGAAoG;IACpG,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,SAAS,CAAC;IACpD,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG;IACtD,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,EAAE,CAAC,cAAc,EAAE,UAAU,GAAG,SAAS,KAAK,IAAI,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG;IACrD,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,eAAe,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IAClD,4GAA4G;IAC5G,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -29,7 +29,7 @@ const SidebarHeader = ({ logo, companyName, companySubtitle, toggle, isLoading,
29
29
  if (isLoading) {
30
30
  return ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "100%", px: toggle ? 2 : 4, py: 2, h: Sidebar_1.HEADER_HEIGHT, display: "flex", alignItems: "center", flexShrink: 0, children: toggle ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", gap: 4, justifyContent: "center", w: "100%", children: (0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "28px", h: "28px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }) })) : ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 3, w: "100%", children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "28px", h: "28px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { h: "1.25rem", w: "60%", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" })] })) }));
31
31
  }
32
- const logoNode = logo ? ((0, jsx_runtime_1.jsx)(react_2.Image, { borderRadius: "md", boxSize: "1.75rem", src: logo, alt: "Company Logo", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, "aria-label": toggle ? "Expand sidebar" : undefined })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { bg: theme.colors.primary[500], color: theme.colors.white, borderRadius: "md", boxSize: "1.75rem", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, "aria-label": toggle ? "Expand sidebar" : undefined, children: (0, jsx_runtime_1.jsx)(defaultLogo_1.default, {}) }));
32
+ const logoNode = logo ? ((0, jsx_runtime_1.jsx)(react_2.Image, { borderRadius: "md", boxSize: "1.75rem", src: logo, alt: "Company Logo", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, "aria-label": toggle ? "Expand sidebar" : undefined })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { bg: theme.colors.primary[500], color: (0, accentText_1.onFilled)(theme.colors.primary[500], theme.colors.white, theme.colors.black), borderRadius: "md", boxSize: "1.75rem", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, "aria-label": toggle ? "Expand sidebar" : undefined, children: (0, jsx_runtime_1.jsx)(defaultLogo_1.default, {}) }));
33
33
  return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { h: Sidebar_1.HEADER_HEIGHT, w: "100%", alignItems: "center", justifyContent: toggle ? "center" : "flex-start", gap: "8px", px: toggle ? "8px" : "10px", borderBottom: "1px solid", borderColor: "whiteAlpha.100", minW: 0, overflow: "hidden", flexShrink: 0, children: [logoNode, !toggle && ((0, jsx_runtime_1.jsxs)(react_2.Box, { flex: "1", minW: 0, children: [(0, jsx_runtime_1.jsx)(OverflowTooltipText_1.default, { placement: "right", fontWeight: 600, fontSize: "12.5px", textAlign: "left", color: theme.colors.white, lineHeight: "1.3", as: "p", width: "100%", children: companyName !== null && companyName !== void 0 ? companyName : "" }), companySubtitle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "10px", color: "whiteAlpha.500", lineHeight: "1.3", isTruncated: true, children: companySubtitle }))] })), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "button", type: "button", onClick: overlay ? onClose : onToggle, "aria-label": overlay ? "Close menu" : "Collapse sidebar", w: "22px", h: "22px", borderRadius: "5px", bg: "whiteAlpha.100", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, _hover: { bg: "whiteAlpha.300" }, transition: "background 0.15s", children: overlay ? ((0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 15, color: theme.colors.white, opacity: 0.7 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { size: 14, color: theme.colors.white, opacity: 0.6 })) }))] }));
34
34
  };
35
35
  const SkeletonMenuRow = ({ toggle }) => ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "100%", px: toggle ? 1 : 2, py: 2, children: toggle ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", gap: 4, justifyContent: "center", children: (0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "24px", h: "24px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }) })) : ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 3, children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "18px", h: "18px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { h: "0.875rem", w: "80%", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" })] })) }));
@@ -25,6 +25,7 @@ const PLACEMENT_STYLE = {
25
25
  * `onOpenChange`.
26
26
  */
27
27
  function WorkspaceTrayPreview({ children, preview, enabled = true, openDelayMs = 350, closeDelayMs = 200, placement = "top-end", onOpenChange, width = "340px", testId = "workspace-tray-preview", }) {
28
+ var _a, _b, _c, _d;
28
29
  const theme = (0, useCustomTheme_1.useCustomTheme)();
29
30
  const [open, setOpen] = (0, react_1.useState)(false);
30
31
  const openTimer = (0, react_1.useRef)(null);
@@ -79,7 +80,7 @@ function WorkspaceTrayPreview({ children, preview, enabled = true, openDelayMs =
79
80
  e.stopPropagation();
80
81
  closeNow();
81
82
  }
82
- }, children: [children, open && ((0, jsx_runtime_1.jsx)(react_2.Box, { position: "absolute", ...PLACEMENT_STYLE[placement], w: typeof width === "number" ? `${width}px` : width, maxW: "min(360px, calc(100vw - 2rem))", bg: theme.colors.background[50], borderWidth: "1px", borderColor: "gray.200", borderRadius: "lg", boxShadow: "xl", zIndex: 1500, pointerEvents: "auto", p: 3, textAlign: "left", color: "gray.800", cursor: "default", onMouseEnter: clearCloseTimer, onMouseLeave: scheduleClose, "data-testid": testId, children: typeof preview === "function"
83
+ }, children: [children, open && ((0, jsx_runtime_1.jsx)(react_2.Box, { position: "absolute", ...PLACEMENT_STYLE[placement], w: typeof width === "number" ? `${width}px` : width, maxW: "min(360px, calc(100vw - 2rem))", bg: theme.colors.background[50], borderWidth: "1px", borderColor: (_b = (_a = theme.colors.boxborder) === null || _a === void 0 ? void 0 : _a[200]) !== null && _b !== void 0 ? _b : theme.colors.gray[200], borderRadius: "lg", boxShadow: "xl", zIndex: 1500, pointerEvents: "auto", p: 3, textAlign: "left", color: (_d = (_c = theme.colors.text) === null || _c === void 0 ? void 0 : _c[700]) !== null && _d !== void 0 ? _d : theme.colors.gray[800], cursor: "default", onMouseEnter: clearCloseTimer, onMouseLeave: scheduleClose, "data-testid": testId, children: typeof preview === "function"
83
84
  ? preview({ close: closeNow })
84
85
  : preview }))] }));
85
86
  }
@@ -6,10 +6,10 @@ import type { WorkspaceTrayProps, WorkspaceWindowProps } from "./WorkspaceWindow
6
6
  * management: the parent owns the window state and passes callbacks. Render
7
7
  * minimized windows with the companion WorkspaceTray.
8
8
  */
9
- export default function WorkspaceWindow({ title, state, children, onMinimize, onClose, onOpenFullPage, headerActions, testId, }: WorkspaceWindowProps): import("react/jsx-runtime").JSX.Element | null;
9
+ export default function WorkspaceWindow({ title, state, children, onMinimize, onClose, onOpenFullPage, onOverlayClick, headerActions, testId, }: WorkspaceWindowProps): import("react/jsx-runtime").JSX.Element | null;
10
10
  /**
11
11
  * Bottom tray of restore pills for minimized WorkspaceWindows. Presentational —
12
12
  * the parent supplies the minimized items and restore/close handlers.
13
13
  */
14
- export declare function WorkspaceTray({ items, onRestore, onClose, testId, }: WorkspaceTrayProps): import("react/jsx-runtime").JSX.Element | null;
14
+ export declare function WorkspaceTray({ items, onRestore, onClose, testId, renderItem, }: WorkspaceTrayProps): import("react/jsx-runtime").JSX.Element | null;
15
15
  //# sourceMappingURL=WorkspaceWindow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceWindow.d.ts","sourceRoot":"","sources":["../../../src/Components/WorkspaceWindow/WorkspaceWindow.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAOhC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,KAAK,EACL,KAAK,EACL,QAAQ,EACR,UAAU,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,MAA2B,GAC5B,EAAE,oBAAoB,kDAyGtB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,SAAS,EACT,OAAO,EACP,MAAyB,GAC1B,EAAE,kBAAkB,kDAkEpB"}
1
+ {"version":3,"file":"WorkspaceWindow.d.ts","sourceRoot":"","sources":["../../../src/Components/WorkspaceWindow/WorkspaceWindow.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAOhC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EACtC,KAAK,EACL,KAAK,EACL,QAAQ,EACR,UAAU,EACV,OAAO,EACP,cAAc,EACd,cAAc,EACd,aAAa,EACb,MAA2B,GAC5B,EAAE,oBAAoB,kDAkHtB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,SAAS,EACT,OAAO,EACP,MAAyB,EACzB,UAAU,GACX,EAAE,kBAAkB,kDA6EpB"}
@@ -17,7 +17,8 @@ const WINDOW_SIZE = { maxW: "88rem", h: "92vh" };
17
17
  * management: the parent owns the window state and passes callbacks. Render
18
18
  * minimized windows with the companion WorkspaceTray.
19
19
  */
20
- function WorkspaceWindow({ title, state, children, onMinimize, onClose, onOpenFullPage, headerActions, testId = "workspace-window", }) {
20
+ function WorkspaceWindow({ title, state, children, onMinimize, onClose, onOpenFullPage, onOverlayClick, headerActions, testId = "workspace-window", }) {
21
+ var _a, _b, _c, _d, _e, _f;
21
22
  // Must run before the early return: a minimized render would otherwise skip the hook
22
23
  // and change hook order when the window reopens.
23
24
  const theme = (0, useCustomTheme_1.useCustomTheme)();
@@ -27,18 +28,38 @@ function WorkspaceWindow({ title, state, children, onMinimize, onClose, onOpenFu
27
28
  return ((0, jsx_runtime_1.jsxs)(react_1.Modal, { isOpen: true, onClose: () => onClose === null || onClose === void 0 ? void 0 : onClose(), size: "full", isCentered: true, scrollBehavior: "inside",
28
29
  // Don't discard unsaved work on an accidental overlay click / Esc — the
29
30
  // parent decides via the explicit Close control.
30
- closeOnOverlayClick: false, closeOnEsc: false, children: [(0, jsx_runtime_1.jsx)(react_1.ModalOverlay, { backdropFilter: "blur(3px)" }), (0, jsx_runtime_1.jsx)(react_1.ModalContent, { bg: "transparent", boxShadow: "none", m: 0, display: "flex", alignItems: "center", justifyContent: "center", children: (0, jsx_runtime_1.jsxs)(react_1.Box, { bg: theme.colors.background[50], borderRadius: "0.75rem", boxShadow: "2xl", overflow: "hidden", w: "100%", maxW: size.maxW, h: size.h, display: "flex", flexDirection: "column", "data-testid": testId, "data-window-state": state, children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", justify: "space-between", px: 3, py: 2, borderBottomWidth: "1px", borderColor: "gray.100", bg: "gray.50", flexShrink: 0, children: [(0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "sm", fontWeight: 600, color: "gray.700", noOfLines: 1, "data-testid": `${testId}-title`, children: title }), (0, jsx_runtime_1.jsxs)(react_1.HStack, { spacing: 1, children: [headerActions, onOpenFullPage ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Open full page", size: "xs", variant: "ghost", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { size: 14 }), onClick: onOpenFullPage, "data-testid": `${testId}-fullpage` })) : null, onMinimize ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Minimize", size: "xs", variant: "ghost", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { size: 15 }), onClick: onMinimize, "data-testid": `${testId}-minimize` })) : null, onClose ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Close", size: "xs", variant: "ghost", colorScheme: "red", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 15 }), onClick: onClose, "data-testid": `${testId}-close` })) : null] })] }), (0, jsx_runtime_1.jsx)(react_1.Box, { flex: "1", overflow: "auto", px: { base: 3, md: 5 }, py: 4, children: children })] }) })] }));
31
+ closeOnOverlayClick: false, closeOnEsc: false, children: [(0, jsx_runtime_1.jsx)(react_1.ModalOverlay, { backdropFilter: "blur(3px)" }), (0, jsx_runtime_1.jsx)(react_1.ModalContent, { bg: "transparent", boxShadow: "none", m: 0, display: "flex", alignItems: "center", justifyContent: "center",
32
+ // With size="full" the transparent ModalContent covers the whole
33
+ // viewport, so Chakra's own closeOnOverlayClick never fires (the
34
+ // ModalOverlay sits behind it). Detect "clicked the blurred area
35
+ // around the window" ourselves: only when the click lands on this
36
+ // wrapper, not on the window Box or its children.
37
+ onMouseDown: (e) => {
38
+ if (e.target === e.currentTarget)
39
+ onOverlayClick === null || onOverlayClick === void 0 ? void 0 : onOverlayClick();
40
+ }, "data-testid": `${testId}-backdrop`, children: (0, jsx_runtime_1.jsxs)(react_1.Box, { bg: theme.colors.background[50], borderRadius: "0.75rem", boxShadow: "2xl", overflow: "hidden", w: "100%", maxW: size.maxW, h: size.h, display: "flex", flexDirection: "column", "data-testid": testId, "data-window-state": state, children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", justify: "space-between", px: 3, py: 2, borderBottomWidth: "1px", borderColor: (_b = (_a = theme.colors.boxborder) === null || _a === void 0 ? void 0 : _a[200]) !== null && _b !== void 0 ? _b : theme.colors.gray[100], bg: (_d = (_c = theme.colors.background) === null || _c === void 0 ? void 0 : _c[100]) !== null && _d !== void 0 ? _d : theme.colors.gray[50], flexShrink: 0, children: [(0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "sm", fontWeight: 600, color: (_f = (_e = theme.colors.text) === null || _e === void 0 ? void 0 : _e[700]) !== null && _f !== void 0 ? _f : theme.colors.gray[700], noOfLines: 1, "data-testid": `${testId}-title`, children: title }), (0, jsx_runtime_1.jsxs)(react_1.HStack, { spacing: 1, children: [headerActions, onOpenFullPage ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Open full page", size: "xs", variant: "ghost", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { size: 14 }), onClick: onOpenFullPage, "data-testid": `${testId}-fullpage` })) : null, onMinimize ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Minimize", size: "xs", variant: "ghost", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { size: 15 }), onClick: onMinimize, "data-testid": `${testId}-minimize` })) : null, onClose ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Close", size: "xs", variant: "ghost", colorScheme: "red", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 15 }), onClick: onClose, "data-testid": `${testId}-close` })) : null] })] }), (0, jsx_runtime_1.jsx)(react_1.Box, { flex: "1", overflow: "auto", px: { base: 3, md: 5 }, py: 4, children: children })] }) })] }));
31
41
  }
32
42
  /**
33
43
  * Bottom tray of restore pills for minimized WorkspaceWindows. Presentational —
34
44
  * the parent supplies the minimized items and restore/close handlers.
35
45
  */
36
- function WorkspaceTray({ items, onRestore, onClose, testId = "workspace-tray", }) {
46
+ function WorkspaceTray({ items, onRestore, onClose, testId = "workspace-tray", renderItem, }) {
47
+ const theme = (0, useCustomTheme_1.useCustomTheme)();
37
48
  if (!items.length)
38
49
  return null;
39
50
  return (
40
51
  // Floating bottom-right cluster (Gmail/Jira minimized-window pattern) rather
41
52
  // than a full-width docked bar, so it never covers the bottom strip of page
42
53
  // content and needs no reserved page gutter. Pills wrap upward.
43
- (0, jsx_runtime_1.jsx)(react_1.Flex, { position: "fixed", bottom: 4, right: 4, zIndex: 1400, direction: "row-reverse", wrap: "wrap-reverse", justify: "flex-start", gap: 2, maxW: { base: "calc(100vw - 2rem)", md: "36rem" }, "data-testid": testId, children: items.map((item) => ((0, jsx_runtime_1.jsxs)(react_1.HStack, { spacing: 1, pl: 3, pr: 1, py: 1, borderRadius: "full", bg: "blue.100", color: "blue.700", boxShadow: "md", borderWidth: "1px", borderColor: "blue.200", "data-testid": `${testId}-pill`, children: [(0, jsx_runtime_1.jsx)(react_1.Box, { as: "button", type: "button", fontSize: "sm", onClick: () => onRestore === null || onRestore === void 0 ? void 0 : onRestore(item.id), "data-testid": `${testId}-restore`, maxW: "16rem", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: item.title }), onClose ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Close", size: "xs", variant: "ghost", borderRadius: "full", minW: "auto", h: "auto", p: 1, color: "inherit", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 13 }), onClick: () => onClose(item.id), "data-testid": `${testId}-close` })) : null] }, item.id))) }));
54
+ (0, jsx_runtime_1.jsx)(react_1.Flex, { position: "fixed", bottom: 4, right: 4, zIndex: 1400, direction: "row-reverse", wrap: "wrap-reverse", justify: "flex-start", gap: 2, maxW: { base: "calc(100vw - 2rem)", md: "36rem" }, "data-testid": testId, children: items.map((item) => {
55
+ var _a, _b, _c, _d, _e, _f;
56
+ const api = {
57
+ restore: () => onRestore === null || onRestore === void 0 ? void 0 : onRestore(item.id),
58
+ close: () => onClose === null || onClose === void 0 ? void 0 : onClose(item.id),
59
+ };
60
+ if (renderItem) {
61
+ return (0, jsx_runtime_1.jsx)(react_1.Box, { children: renderItem(item, api) }, item.id);
62
+ }
63
+ return ((0, jsx_runtime_1.jsxs)(react_1.HStack, { spacing: 1, pl: 3, pr: 1, py: 1, borderRadius: "full", bg: (_b = (_a = theme.colors.primary) === null || _a === void 0 ? void 0 : _a[100]) !== null && _b !== void 0 ? _b : "blue.100", color: (_d = (_c = theme.colors.primary) === null || _c === void 0 ? void 0 : _c[700]) !== null && _d !== void 0 ? _d : "blue.700", boxShadow: "md", borderWidth: "1px", borderColor: (_f = (_e = theme.colors.primary) === null || _e === void 0 ? void 0 : _e[200]) !== null && _f !== void 0 ? _f : "blue.200", "data-testid": `${testId}-pill`, children: [(0, jsx_runtime_1.jsx)(react_1.Box, { as: "button", type: "button", fontSize: "sm", onClick: api.restore, "data-testid": `${testId}-restore`, maxW: "16rem", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: item.title }), onClose ? ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": "Close", size: "xs", variant: "ghost", borderRadius: "full", minW: "auto", h: "auto", p: 1, color: "inherit", icon: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 13 }), onClick: api.close, "data-testid": `${testId}-close` })) : null] }, item.id));
64
+ }) }));
44
65
  }
@@ -19,6 +19,13 @@ export interface WorkspaceWindowProps {
19
19
  onClose?: () => void;
20
20
  /** Optional "pop out to full page" affordance; hidden when omitted. */
21
21
  onOpenFullPage?: () => void;
22
+ /**
23
+ * Fires when the blurred area around the window is clicked. With
24
+ * `size="full"` the transparent ModalContent covers the whole viewport, so
25
+ * Chakra's own `closeOnOverlayClick` never fires — the parent handles this
26
+ * itself (e.g. minimize-on-backdrop-click) via this callback.
27
+ */
28
+ onOverlayClick?: () => void;
22
29
  /** Extra controls rendered in the control bar, left of the window buttons. */
23
30
  headerActions?: ReactNode;
24
31
  /** data-testid for the window container. */
@@ -34,6 +41,17 @@ export interface WorkspaceTrayProps {
34
41
  onRestore?: (id: string) => void;
35
42
  onClose?: (id: string) => void;
36
43
  testId?: string;
44
+ /**
45
+ * Full override for a single item's pill markup — e.g. to wrap it in an
46
+ * app-specific hover preview, or to show extra state (a dirty dot) the
47
+ * generic pill doesn't know about. Receives the item plus ready-bound
48
+ * restore/close callbacks; when provided, the built-in pill is skipped for
49
+ * that item and this renders in its place inside the same positioned tray.
50
+ */
51
+ renderItem?: (item: WorkspaceTrayItem, api: {
52
+ restore: () => void;
53
+ close: () => void;
54
+ }) => ReactNode;
37
55
  }
38
56
  export interface WorkspaceTrayPreviewProps {
39
57
  /**