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.
- package/.cursor/modules/account-management/MODULE.md +8 -1
- package/.cursor/modules/feedback/MODULE.md +6 -0
- package/.cursor/modules/inputs-date-file/MODULE.md +12 -1
- package/.cursor/modules/inputs-select/MODULE.md +64 -2
- package/.cursor/modules/inputs-toggle/MODULE.md +6 -0
- package/.cursor/modules/layout-navigation/MODULE.md +55 -5
- package/.cursor/modules/overlays/MODULE.md +29 -16
- package/.cursor/modules/table/MODULE.md +6 -0
- package/.cursor/modules/theme/MODULE.md +117 -0
- package/dist/Assets/defaultLogo.d.ts.map +1 -1
- package/dist/Assets/defaultLogo.js +1 -3
- package/dist/Assets/defaultLogo.tsx +4 -8
- package/dist/Components/DatePicker/CalendarPanel.d.ts.map +1 -1
- package/dist/Components/DatePicker/CalendarPanel.js +12 -3
- package/dist/Components/DatePicker/SingleDatePicker.d.ts.map +1 -1
- package/dist/Components/DatePicker/SingleDatePicker.js +11 -9
- package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -2
- package/dist/Components/DatePicker/TimePicker.d.ts.map +1 -1
- package/dist/Components/DatePicker/TimePicker.js +14 -2
- package/dist/Components/DatePicker/TimePickerInput.d.ts.map +1 -1
- package/dist/Components/DatePicker/TimePickerInput.js +9 -1
- package/dist/Components/SelectV2/SelectV2.d.ts +3 -0
- package/dist/Components/SelectV2/SelectV2.d.ts.map +1 -0
- package/dist/Components/SelectV2/SelectV2.js +185 -0
- package/dist/Components/SelectV2/SelectV2Props.d.ts +67 -0
- package/dist/Components/SelectV2/SelectV2Props.d.ts.map +1 -0
- package/dist/Components/SelectV2/SelectV2Props.js +2 -0
- package/dist/Components/SideBar/SideBar.js +1 -1
- package/dist/Components/WorkspaceWindow/WorkspaceTrayPreview.js +2 -1
- package/dist/Components/WorkspaceWindow/WorkspaceWindow.d.ts +2 -2
- package/dist/Components/WorkspaceWindow/WorkspaceWindow.d.ts.map +1 -1
- package/dist/Components/WorkspaceWindow/WorkspaceWindow.js +25 -4
- package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts +18 -0
- package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts.map +1 -1
- package/dist/Theme/chakra/Avatar.styles.d.ts +33 -0
- package/dist/Theme/chakra/Avatar.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Avatar.styles.js +28 -0
- package/dist/Theme/chakra/Drawer.styles.d.ts +32 -0
- package/dist/Theme/chakra/Drawer.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Drawer.styles.js +26 -0
- package/dist/Theme/chakra/Menu.styles.d.ts +70 -0
- package/dist/Theme/chakra/Menu.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Menu.styles.js +50 -0
- package/dist/Theme/chakra/Modal.styles.d.ts +32 -0
- package/dist/Theme/chakra/Modal.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Modal.styles.js +26 -0
- package/dist/Theme/chakra/Popover.styles.d.ts +37 -0
- package/dist/Theme/chakra/Popover.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Popover.styles.js +30 -0
- package/dist/Theme/chakra/Slider.styles.d.ts +31 -0
- package/dist/Theme/chakra/Slider.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Slider.styles.js +25 -0
- package/dist/Theme/chakra/Switch.styles.d.ts +31 -0
- package/dist/Theme/chakra/Switch.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Switch.styles.js +24 -0
- package/dist/Theme/chakra/Tabs.styles.d.ts +43 -0
- package/dist/Theme/chakra/Tabs.styles.d.ts.map +1 -0
- package/dist/Theme/chakra/Tabs.styles.js +41 -0
- package/dist/Theme/chakra/componentStyles.d.ts +228 -1
- package/dist/Theme/chakra/componentStyles.d.ts.map +1 -1
- package/dist/Theme/chakra/componentStyles.js +62 -0
- package/dist/Theme/provider/PixelizeThemeProvider.d.ts +11 -1
- package/dist/Theme/provider/PixelizeThemeProvider.d.ts.map +1 -1
- package/dist/Theme/provider/PixelizeThemeProvider.js +35 -2
- package/dist/Theme/provider/ThemeSwitcher.d.ts.map +1 -1
- package/dist/Theme/provider/ThemeSwitcher.js +23 -11
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- 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,
|
|
949
|
-
|
|
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 ${(
|
|
952
|
-
: `0 0 0 0.125rem ${(
|
|
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 ? (
|
|
955
|
-
}, cursor: "text", boxShadow: error ? `0 0 0 0.125rem ${(
|
|
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: (
|
|
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: (
|
|
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:
|
|
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;
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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 @@
|
|
|
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"}
|
|
@@ -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:
|
|
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,
|
|
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",
|
|
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) =>
|
|
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
|
/**
|