pixelize-design-library 2.4.2-beta.34 → 2.4.2-beta.35
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/dist/Components/AppSwitcher/AppSwitcher.js +10 -4
- package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -3
- package/dist/Components/Common/fieldStyles.js +1 -1
- package/dist/Components/CopyButton/CopyButton.js +7 -6
- package/dist/Components/DatePicker/CalendarPanel.js +8 -5
- package/dist/Components/DatePicker/RangeDatePicker.js +27 -3
- package/dist/Components/DatePicker/SingleDatePicker.js +48 -14
- package/dist/Components/DatePicker/TimeOnlyPicker.js +7 -1
- package/dist/Components/DatePicker/TimePicker.js +3 -3
- package/dist/Components/DatePicker/TimePickerInput.js +1 -1
- package/dist/Components/Dropdown/DropDown.js +19 -6
- package/dist/Components/EmptyState/EmptyState.js +1 -1
- package/dist/Components/FileUpload/FileUpload.js +2 -2
- package/dist/Components/FilterSidebar/FilterSidebar.js +5 -5
- package/dist/Components/FilterSidebar/filterHoverStyle.d.ts +2 -1
- package/dist/Components/FilterSidebar/filterHoverStyle.js +3 -4
- package/dist/Components/Input/TextInput.styles.js +2 -2
- package/dist/Components/InputTextArea/InputTextArea.style.js +2 -2
- package/dist/Components/MoreItems/MoreItems.js +3 -1
- package/dist/Components/MultiSelect/MultiSelect.js +2 -2
- package/dist/Components/NavigationBar/NavigationBar.js +6 -7
- package/dist/Components/NumberInput/NumberInput.styles.js +2 -2
- package/dist/Components/OrgSwitcher/OrgSwitcher.js +14 -10
- package/dist/Components/PdfViewer/PdfViewer.js +4 -4
- package/dist/Components/RolesPermission/RolesPermission.js +4 -3
- package/dist/Components/SearchSelect/SearchSelect.js +46 -41
- package/dist/Components/Select/Select.styles.js +1 -1
- package/dist/Components/SelectSearch/SelectSearch.js +35 -17
- package/dist/Components/SelectV2/SelectV2.js +3 -0
- package/dist/Components/Table/TableProps.d.ts +2 -0
- package/dist/Components/Table/components/TableBody.js +7 -10
- package/dist/Components/Table/filters/CompactSelect.js +29 -8
- package/dist/Components/Table/settings/ManageColumns.js +5 -3
- package/dist/Components/Table/settings/TableSettings.js +4 -2
- package/dist/Components/Trail/EditableCell.js +1 -1
- package/dist/Components/UserDetails/DeactivateConfirmModal.js +1 -1
- package/dist/Components/UserDetails/UserDetails.js +5 -3
- package/dist/Hooks/exclusiveOverlay.d.ts +4 -0
- package/dist/Hooks/exclusiveOverlay.js +22 -0
- package/dist/Hooks/useExclusiveOverlay.d.ts +5 -0
- package/dist/Hooks/useExclusiveOverlay.js +24 -0
- package/dist/Theme/chakra/Menu.styles.js +4 -2
- package/dist/Utils/table.d.ts +3 -0
- package/dist/Utils/table.js +44 -1
- package/dist/esm/Components/AppSwitcher/AppSwitcher.js +11 -5
- package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -3
- package/dist/esm/Components/Common/fieldStyles.js +1 -1
- package/dist/esm/Components/CopyButton/CopyButton.js +7 -6
- package/dist/esm/Components/DatePicker/CalendarPanel.js +9 -6
- package/dist/esm/Components/DatePicker/RangeDatePicker.js +28 -4
- package/dist/esm/Components/DatePicker/SingleDatePicker.js +49 -15
- package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +7 -1
- package/dist/esm/Components/DatePicker/TimePicker.js +3 -3
- package/dist/esm/Components/DatePicker/TimePickerInput.js +1 -1
- package/dist/esm/Components/Dropdown/DropDown.js +20 -7
- package/dist/esm/Components/EmptyState/EmptyState.js +1 -1
- package/dist/esm/Components/FileUpload/FileUpload.js +2 -2
- package/dist/esm/Components/FilterSidebar/FilterSidebar.js +5 -5
- package/dist/esm/Components/FilterSidebar/filterHoverStyle.js +3 -4
- package/dist/esm/Components/Input/TextInput.styles.js +2 -2
- package/dist/esm/Components/InputTextArea/InputTextArea.style.js +2 -2
- package/dist/esm/Components/MoreItems/MoreItems.js +3 -1
- package/dist/esm/Components/MultiSelect/MultiSelect.js +2 -2
- package/dist/esm/Components/NavigationBar/NavigationBar.js +6 -7
- package/dist/esm/Components/NumberInput/NumberInput.styles.js +2 -2
- package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +14 -10
- package/dist/esm/Components/PdfViewer/PdfViewer.js +4 -4
- package/dist/esm/Components/RolesPermission/RolesPermission.js +4 -3
- package/dist/esm/Components/SearchSelect/SearchSelect.js +46 -41
- package/dist/esm/Components/Select/Select.styles.js +1 -1
- package/dist/esm/Components/SelectSearch/SelectSearch.js +35 -17
- package/dist/esm/Components/SelectV2/SelectV2.js +3 -0
- package/dist/esm/Components/Table/components/TableBody.js +7 -10
- package/dist/esm/Components/Table/filters/CompactSelect.js +29 -8
- package/dist/esm/Components/Table/settings/ManageColumns.js +5 -3
- package/dist/esm/Components/Table/settings/TableSettings.js +5 -3
- package/dist/esm/Components/Trail/EditableCell.js +1 -1
- package/dist/esm/Components/UserDetails/DeactivateConfirmModal.js +1 -1
- package/dist/esm/Components/UserDetails/UserDetails.js +5 -3
- package/dist/esm/Hooks/exclusiveOverlay.js +16 -0
- package/dist/esm/Hooks/useExclusiveOverlay.js +20 -0
- package/dist/esm/Theme/chakra/Menu.styles.js +4 -2
- package/dist/esm/Utils/table.js +45 -3
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef, useCallback, useEffect, useId, useRef, useState } from "react";
|
|
2
|
+
import { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { Box, Flex, Button, useDisclosure, List, ListItem, Portal, } from "@chakra-ui/react";
|
|
4
4
|
import { motion } from "framer-motion";
|
|
5
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
6
6
|
import { scrollbarStyles } from "../../Theme/tokens/builders/scrollbar.js";
|
|
7
|
-
import {
|
|
7
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
8
|
+
import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
|
|
8
9
|
import { ChevronDown } from "lucide-react";
|
|
9
10
|
import { rafThrottle } from "../../Utils/rafThrottle.js";
|
|
10
11
|
const MotionBox = motion(forwardRef((props, ref) => (_jsx(Box, { ref: ref, ...props }))));
|
|
@@ -19,7 +20,9 @@ const SIZE_MAP = {
|
|
|
19
20
|
const Dropdown = forwardRef(({ dropDownButtonStyle, ButtonText, options, handleOptionSelect, dropdownType = "button", text, DropdownIcon, isVisibleIconShow = true, buttonProps, headStyle, ListStyle, ItemStyle, LabelStyle, ImageStyle, size, optionsSize, divider = false, ariaLabel, }, ref) => {
|
|
20
21
|
var _a, _b;
|
|
21
22
|
const theme = useCustomTheme();
|
|
22
|
-
const
|
|
23
|
+
const rowBackgrounds = useMemo(() => listRowBackgrounds(theme.colors), [theme.colors]);
|
|
24
|
+
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
25
|
+
const requestExclusiveOpen = useExclusiveOverlay(isOpen, onClose);
|
|
23
26
|
const dropdownRef = useRef(null);
|
|
24
27
|
const menuRef = useRef(null);
|
|
25
28
|
const [menuPos, setMenuPos] = useState({ top: 0, left: 0, width: 0 });
|
|
@@ -49,6 +52,16 @@ const Dropdown = forwardRef(({ dropDownButtonStyle, ButtonText, options, handleO
|
|
|
49
52
|
}
|
|
50
53
|
else {
|
|
51
54
|
pendingFocusIndex.current = index;
|
|
55
|
+
requestExclusiveOpen();
|
|
56
|
+
onOpen();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const handleToggle = () => {
|
|
60
|
+
if (isOpen) {
|
|
61
|
+
onClose();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
requestExclusiveOpen();
|
|
52
65
|
onOpen();
|
|
53
66
|
}
|
|
54
67
|
};
|
|
@@ -91,7 +104,7 @@ const Dropdown = forwardRef(({ dropDownButtonStyle, ButtonText, options, handleO
|
|
|
91
104
|
// `fireEvent` does not simulate a real browser's Enter/Space-activates-
|
|
92
105
|
// button default action either.
|
|
93
106
|
e.preventDefault();
|
|
94
|
-
|
|
107
|
+
handleToggle();
|
|
95
108
|
}
|
|
96
109
|
};
|
|
97
110
|
const handleMenuKeyDown = (e) => {
|
|
@@ -207,13 +220,13 @@ const Dropdown = forwardRef(({ dropDownButtonStyle, ButtonText, options, handleO
|
|
|
207
220
|
};
|
|
208
221
|
const Chevron = isVisibleIconShow ? (_jsx(Box, { as: "span", display: "inline-flex", transition: "transform 0.2s ease", transform: isOpen ? "rotate(180deg)" : "rotate(0deg)", children: _jsx(ChevronDown, { size: s.chevron }) })) : undefined;
|
|
209
222
|
const dropDownToggleOption = () => {
|
|
210
|
-
const ButtonToggle = (_jsx(Button, { ref: buttonTriggerRef, onClick:
|
|
211
|
-
const TextToggle = (_jsxs(Flex, { ref: textTriggerRef, onClick:
|
|
223
|
+
const ButtonToggle = (_jsx(Button, { ref: buttonTriggerRef, onClick: handleToggle, onKeyDown: handleTriggerKeyDown, size: s.btn, colorScheme: "primary", borderRadius: "lg", fontWeight: 600, "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (ButtonText ? undefined : "Open menu"), rightIcon: Chevron, sx: { transition: "all 0.15s ease", ...(dropDownButtonStyle) }, ...buttonProps, children: _jsxs(Box, { as: "span", display: "inline-flex", alignItems: "center", gap: DropdownIcon && ButtonText ? s.gap : 0, children: [DropdownIcon, ButtonText] }) }));
|
|
224
|
+
const TextToggle = (_jsxs(Flex, { ref: textTriggerRef, onClick: handleToggle, onKeyDown: handleTriggerKeyDown, align: "center", gap: 1.5, cursor: "pointer", fontSize: s.fontSize, fontWeight: 500, color: theme.colors.text[700], transition: "color 0.15s ease", _hover: { color: theme.colors.accentText }, style: dropDownButtonStyle, role: "button", tabIndex: 0, "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (text ? undefined : "Open menu"), children: [DropdownIcon, text, Chevron] }));
|
|
212
225
|
return dropdownType === "button" ? ButtonToggle : TextToggle;
|
|
213
226
|
};
|
|
214
227
|
const DropdownContentRender = () => {
|
|
215
228
|
var _a;
|
|
216
|
-
const hoverTint =
|
|
229
|
+
const hoverTint = rowBackgrounds.active;
|
|
217
230
|
return (_jsx(List, { id: menuId, role: "menu", onKeyDown: handleMenuKeyDown, bg: theme.colors.background[50], border: `0.063rem solid ${theme.colors.boxborder[200]}`, borderRadius: "xl", boxShadow: (_a = theme.shadows) === null || _a === void 0 ? void 0 : _a.lg, py: 1.5, mt: "0.375rem", minWidth: s.minW, maxH: "18rem", overflowY: "auto", overflowX: "hidden", sx: scrollbarStyles(theme.colors, "overlay"), style: ListStyle, children: options.map((option, index) => (_jsxs(ListItem, { ref: (node) => {
|
|
218
231
|
itemRefs.current[index] = node;
|
|
219
232
|
}, role: "menuitem", tabIndex: index === activeIndex ? 0 : -1, onClick: () => {
|
|
@@ -25,7 +25,7 @@ const EmptyState = ({ title = "No data found", description, icon: IconComp = Inb
|
|
|
25
25
|
const accentSoft = palette[50];
|
|
26
26
|
const accent = accentTextOnCanvas(palette, accentSoft);
|
|
27
27
|
const containerStyles = variant === "subtle"
|
|
28
|
-
? { bg: theme.colors.
|
|
28
|
+
? { bg: theme.colors.background[50], borderRadius: "2xl" }
|
|
29
29
|
: variant === "dashed"
|
|
30
30
|
? {
|
|
31
31
|
border: "2px dashed",
|
|
@@ -14,7 +14,7 @@ const FileUpload = ({ onFilesUploaded, uploadedFiles, onRemoveFile, acceptTypes
|
|
|
14
14
|
const [previewUrl, setPreviewUrl] = React.useState(null);
|
|
15
15
|
const [previewTitle, setPreviewTitle] = React.useState(null);
|
|
16
16
|
const [errors, setErrors] = React.useState([]);
|
|
17
|
-
const bg = colors.
|
|
17
|
+
const bg = colors.background[50];
|
|
18
18
|
const border = colors.boxborder[500];
|
|
19
19
|
const mappedAccept = acceptTypes.reduce((acc, ext) => {
|
|
20
20
|
const mime = mimeMap[ext];
|
|
@@ -54,7 +54,7 @@ const FileUpload = ({ onFilesUploaded, uploadedFiles, onRemoveFile, acceptTypes
|
|
|
54
54
|
setErrors(messages);
|
|
55
55
|
},
|
|
56
56
|
});
|
|
57
|
-
return (_jsxs(_Fragment, { children: [_jsxs(VStack, { spacing: 4, align: "stretch", children: [_jsxs(Box, { ...getRootProps(), border: "2px dashed", borderColor: border, borderRadius: "md", p: compact ? 3 : 10, textAlign: "center", bg: bg, cursor: "pointer", transition: "all 0.2s", _hover: { bg: colors.
|
|
57
|
+
return (_jsxs(_Fragment, { children: [_jsxs(VStack, { spacing: 4, align: "stretch", children: [_jsxs(Box, { ...getRootProps(), border: "2px dashed", borderColor: border, borderRadius: "md", p: compact ? 3 : 10, textAlign: "center", bg: bg, cursor: "pointer", transition: "all 0.2s", _hover: { bg: colors.background[100] }, position: "relative", children: [_jsx("input", { ...getInputProps({ "aria-label": inputAriaLabel }) }), _jsxs(Stack, { direction: compact ? "row" : "column", spacing: compact ? 3 : 2, align: "center", justify: "center", children: [_jsx(Icon, { as: Upload, boxSize: compact ? 4 : 6 }), _jsxs(Stack, { spacing: 0, align: compact ? "start" : "center", children: [_jsx(Text, { fontWeight: "medium", fontSize: compact ? "sm" : "md", color: colors.textMuted, children: "Drag and drop files here" }), _jsxs(Text, { fontSize: compact ? "xs" : "sm", color: colors.textMuted, children: [acceptTypes.join(", "), " up to ", toMB(maxSizeKB), " ", maxFiles ? `- ${maxFiles} file(s) max` : ""] })] })] })] }), errors.length > 0 && (_jsx(Box, { children: errors.map((err, idx) => (_jsx(Text, { fontSize: "sm", color: colors.semanticText.error, children: err }, idx))) })), uploadedFiles.length > 0 && (_jsxs(Box, { children: [_jsx(Box, { display: "flex", alignItems: "center", gap: 2, children: _jsx(Text, { fontFamily: "open-sans, sans-serif", fontWeight: 600, fontSize: 14, lineHeight: "100%", letterSpacing: "4%", textTransform: "uppercase", py: 4, children: "Uploaded Files" }) }), _jsx(List, { spacing: 2, children: uploadedFiles.map((file, index) => (_jsxs(Box, { borderWidth: "0.063rem", borderRadius: "md", px: 3, py: 2, bg: colors.background[50], children: [_jsxs(ListItem, { display: "flex", justifyContent: "space-between", alignItems: "center", children: [_jsxs(HStack, { spacing: 3, flex: "1", children: [file.type.startsWith("image/") ? (_jsxs(Box, { boxSize: "2.5rem", cursor: "pointer", position: "relative", _hover: {
|
|
58
58
|
".hover-icon": {
|
|
59
59
|
opacity: 1,
|
|
60
60
|
bg: "blackAlpha.500",
|
|
@@ -144,13 +144,13 @@ panelPadding = 3, clearAllButton = true, onClearAllHandler,
|
|
|
144
144
|
pointerEvents: 'none', // Allow clicks to pass through track
|
|
145
145
|
zIndex: 3,
|
|
146
146
|
margin: 0,
|
|
147
|
-
} })] }), _jsxs(SimpleGrid, { columns: 2, spacing: 2, pt: 2, w: "full", children: [_jsxs(Popover, { isOpen: openPrice.id === section.id && openPrice.target === "min", onClose: () => setOpenPrice({}), placement: "bottom-start", closeOnBlur: true, children: [_jsx(PopoverTrigger, { children: _jsx(Flex, { borderWidth: "0", borderRadius: "md", alignItems: "center", px: 3, py: 2, bg: theme.colors.
|
|
147
|
+
} })] }), _jsxs(SimpleGrid, { columns: 2, spacing: 2, pt: 2, w: "full", children: [_jsxs(Popover, { isOpen: openPrice.id === section.id && openPrice.target === "min", onClose: () => setOpenPrice({}), placement: "bottom-start", closeOnBlur: true, children: [_jsx(PopoverTrigger, { children: _jsx(Flex, { borderWidth: "0", borderRadius: "md", alignItems: "center", px: 3, py: 2, bg: theme.colors.background[50], borderColor: theme.colors.boxborder[500], cursor: "pointer", onClick: () => setOpenPrice({ id: section.id, target: "min" }), gap: 2, overflow: "hidden", children: _jsx(Box, { ml: "auto", children: _jsxs(Text, { fontSize: "12px", color: theme.colors.text[500], whiteSpace: "nowrap", children: [currentMin, range.unit ? ` ${range.unit}` : ""] }) }) }) }), _jsx(Portal, { children: _jsx(PopoverContent, { width: "6rem", p: 0, zIndex: 1600, bg: theme.colors.background[50], children: _jsx(PopoverBody, { p: 0, children: _jsx(VStack, { align: "stretch", spacing: 0, maxH: "12rem", overflowY: "auto", children: values.map((v) => (_jsxs(Flex, { px: 2, py: 1, align: "center", justify: "space-between", cursor: "pointer", bg: currentMin === v ? theme.colors.red[50] : theme.colors.background[50], borderLeftWidth: currentMin === v ? 3 : 0, borderLeftStyle: "solid", borderLeftColor: currentMin === v ? theme.colors.red[400] : "transparent", _hover: { bg: hoverBg }, onClick: () => {
|
|
148
148
|
const min = v;
|
|
149
149
|
const max = currentMax;
|
|
150
150
|
const nextVal = [Math.min(min, max), Math.max(min, max)];
|
|
151
151
|
setInternalSelected((prev) => { const next = { ...prev, [section.id]: nextVal }; onChange === null || onChange === void 0 ? void 0 : onChange(next); return next; });
|
|
152
152
|
setOpenPrice({});
|
|
153
|
-
}, children: [_jsxs(Text, { fontSize: "sm", color: theme.colors.gray[800], children: [v, range.unit ? ` ${range.unit}` : ""] }), currentMin === v ? (_jsx(Box, { bg: theme.colors.red[100], borderRadius: "full", p: 1, display: "flex", alignItems: "center", children: _jsx(Check, { size: 9, color: onFilled(theme.colors.red[100], theme.colors.white, theme.colors.black) }) })) : null] }, `min-${v}`))) }) }) }) })] }), _jsxs(Popover, { isOpen: openPrice.id === section.id && openPrice.target === "max", onClose: () => setOpenPrice({}), placement: "bottom-start", closeOnBlur: true, children: [_jsx(PopoverTrigger, { children: _jsx(Flex, { borderWidth: "0", borderRadius: "md", alignItems: "center", px: 3, py: 2, bg: theme.colors.
|
|
153
|
+
}, children: [_jsxs(Text, { fontSize: "sm", color: theme.colors.gray[800], children: [v, range.unit ? ` ${range.unit}` : ""] }), currentMin === v ? (_jsx(Box, { bg: theme.colors.red[100], borderRadius: "full", p: 1, display: "flex", alignItems: "center", children: _jsx(Check, { size: 9, color: onFilled(theme.colors.red[100], theme.colors.white, theme.colors.black) }) })) : null] }, `min-${v}`))) }) }) }) })] }), _jsxs(Popover, { isOpen: openPrice.id === section.id && openPrice.target === "max", onClose: () => setOpenPrice({}), placement: "bottom-start", closeOnBlur: true, children: [_jsx(PopoverTrigger, { children: _jsx(Flex, { borderWidth: "0", borderRadius: "md", alignItems: "center", px: 3, py: 2, bg: theme.colors.background[50], borderColor: theme.colors.boxborder[500], cursor: "pointer", onClick: () => setOpenPrice({ id: section.id, target: "max" }), gap: 2, overflow: "hidden", children: _jsx(Box, { ml: "auto", children: _jsxs(Text, { fontSize: "12px", color: theme.colors.text[500], whiteSpace: "nowrap", children: [currentMax, range.unit ? ` ${range.unit}` : ""] }) }) }) }), _jsx(PopoverContent, { width: "6rem", p: 0, bg: theme.colors.background[50], children: _jsx(PopoverBody, { p: 0, children: _jsx(VStack, { align: "stretch", spacing: 0, maxH: "12rem", overflowY: "auto", children: values.map((v) => (_jsxs(Flex, { px: 2, py: 1, align: "center", justify: "space-between", cursor: "pointer", bg: currentMax === v ? theme.colors.red[50] : theme.colors.background[50], borderLeftWidth: currentMax === v ? 3 : 0, borderLeftStyle: "solid", borderLeftColor: currentMax === v ? theme.colors.red[400] : "transparent", _hover: { bg: hoverBg }, onClick: () => {
|
|
154
154
|
const max = v;
|
|
155
155
|
const min = currentMin;
|
|
156
156
|
const nextVal = [Math.min(min, max), Math.max(min, max)];
|
|
@@ -169,7 +169,7 @@ panelPadding = 3, clearAllButton = true, onClearAllHandler,
|
|
|
169
169
|
const isRowSelected = String(internalSelected[section.id] || "") === String(r);
|
|
170
170
|
const starColor = accentTextOnCanvas(theme.colors.orange, isRowSelected ? theme.colors.red[50] : theme.colors.background[50]);
|
|
171
171
|
return Array.from({ length: 5 }, (_, i) => (_jsx(Box, { children: _jsx(Star, { size: 16, color: starColor, fill: i < r ? starColor : "none" }) }, `star-${r}-${i}`)));
|
|
172
|
-
})() }), _jsx(Text, { fontSize: "sm", color: theme.colors.text[500], children: "& Up" })] }) }, `rating-${r}`))) })) : null, section.searchable && (_jsx(Input, { size: "xs", h: "26px", fontSize: "xs", placeholder: `Search ${section.label}...`, borderRadius: "md", bg: theme.colors.
|
|
172
|
+
})() }), _jsx(Text, { fontSize: "sm", color: theme.colors.text[500], children: "& Up" })] }) }, `rating-${r}`))) })) : null, section.searchable && (_jsx(Input, { size: "xs", h: "26px", fontSize: "xs", placeholder: `Search ${section.label}...`, borderRadius: "md", bg: theme.colors.background[50], border: "1px solid",
|
|
173
173
|
// boxborder[500], not raw gray[200]: WCAG 1.4.11 needs >=3.0 for a control
|
|
174
174
|
// boundary against any named surface up to `muted` (lightest); gray[200] fails
|
|
175
175
|
// there in dark mode.
|
|
@@ -228,7 +228,7 @@ panelPadding = 3, clearAllButton = true, onClearAllHandler,
|
|
|
228
228
|
: {
|
|
229
229
|
justifyContent: "space-between",
|
|
230
230
|
padding: 0,
|
|
231
|
-
background: theme.colors.
|
|
231
|
+
background: theme.colors.background[50],
|
|
232
232
|
borderRadius: theme.radii.lg,
|
|
233
233
|
border: `1px solid ${theme.colors.gray[200]}`,
|
|
234
234
|
marginBottom: 6,
|
|
@@ -249,6 +249,6 @@ panelPadding = 3, clearAllButton = true, onClearAllHandler,
|
|
|
249
249
|
},
|
|
250
250
|
},
|
|
251
251
|
}));
|
|
252
|
-
return (_jsxs(Box, { w: width, bg:
|
|
252
|
+
return (_jsxs(Box, { w: width, bg: theme.colors.background[50], p: containerPadding !== undefined ? containerPadding : (variant === "minimal" ? 3 : 2), borderRadius: variant === "minimal" ? "lg" : "none", boxShadow: variant === "minimal" ? "sm" : "none", border: variant === "minimal" ? `1px solid ${theme.colors.gray[200]}` : "none", h: "fit-content", maxH: containerHeight !== undefined ? containerHeight : undefined, overflowY: containerHeight !== undefined ? "auto" : "visible", children: [_jsxs(Flex, { className: "filters-header", align: "center", justify: "space-between", mb: 2, borderBottom: "2px solid", borderColor: theme.colors.gray[100], children: [_jsx(Text, { fontSize: "lg", fontWeight: "bold", color: theme.colors.text[500], children: "Filters" }), activeCount > 0 && clearAllButton && (_jsx(_Fragment, { children: _jsx(Button, { size: "xs", variant: "outline", leftIcon: _jsx(X, { size: 12 }), onClick: clearAll, "aria-label": "Clear All", className: "clear-all-btn", colorScheme: "red", children: "Clear All" }) }))] }), _jsx(Accordion, { allowMultiple: true, defaultIndex: sidebarOptions.map((_, i) => i), items: items })] }));
|
|
253
253
|
};
|
|
254
254
|
export default FilterSidebar;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const getFilterHoverBg = (colors, isDark) => isDark ? liftToContrast(colors.gray[300], colors.text[500], AA_NORMAL_TEXT) : colors.gray[50];
|
|
1
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
2
|
+
/** Shared with every selectable list row — never seed from `primary[500]` or `primary.opacity[8]`. */
|
|
3
|
+
export const getFilterHoverBg = (colors, _isDark) => listRowBackgrounds(colors).active;
|
|
@@ -47,7 +47,7 @@ export const Input = {
|
|
|
47
47
|
const primary = theme.colors.primary[500];
|
|
48
48
|
return {
|
|
49
49
|
field: {
|
|
50
|
-
bg: theme.colors.
|
|
50
|
+
bg: theme.colors.background[50],
|
|
51
51
|
border: "0.063rem solid",
|
|
52
52
|
borderColor,
|
|
53
53
|
_placeholder: {
|
|
@@ -81,7 +81,7 @@ export const Input = {
|
|
|
81
81
|
boxShadow: 'inherit',
|
|
82
82
|
},
|
|
83
83
|
_disabled: {
|
|
84
|
-
bg: theme.colors.
|
|
84
|
+
bg: theme.colors.background[100],
|
|
85
85
|
opacity: 1,
|
|
86
86
|
cursor: "not-allowed",
|
|
87
87
|
_hover: {
|
|
@@ -29,7 +29,7 @@ export const Textarea = {
|
|
|
29
29
|
return {
|
|
30
30
|
border: "0.063rem solid",
|
|
31
31
|
borderColor,
|
|
32
|
-
bg: theme.colors.
|
|
32
|
+
bg: theme.colors.background[50],
|
|
33
33
|
_placeholder: {
|
|
34
34
|
color: placeholderInk(theme.colors),
|
|
35
35
|
},
|
|
@@ -59,7 +59,7 @@ export const Textarea = {
|
|
|
59
59
|
boxShadow: 'inherit',
|
|
60
60
|
},
|
|
61
61
|
_disabled: {
|
|
62
|
-
bg: theme.colors.
|
|
62
|
+
bg: theme.colors.background[100],
|
|
63
63
|
opacity: 1,
|
|
64
64
|
cursor: "not-allowed",
|
|
65
65
|
_hover: {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Popover, PopoverArrow, PopoverBody, PopoverContent, PopoverTrigger, SimpleGrid, Text, } from "@chakra-ui/react";
|
|
3
3
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
4
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
4
5
|
const MoreItems = ({ items, moreCount, triggerText, colorResolver, hideDots = false, columns = 2, minWidth = "260px", triggerMaxWidth = "250px", trigger = "hover", placement = "bottom-start", }) => {
|
|
5
6
|
const theme = useCustomTheme();
|
|
7
|
+
const countBadgeBg = listRowBackgrounds(theme.colors).selected;
|
|
6
8
|
const count = moreCount !== null && moreCount !== void 0 ? moreCount : items.length;
|
|
7
9
|
if (count <= 0)
|
|
8
10
|
return triggerText ? _jsx(_Fragment, { children: triggerText }) : null;
|
|
9
|
-
return (_jsxs(Popover, { trigger: trigger, placement: placement, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsxs(Box, { display: "inline-flex", alignItems: "center", maxW: triggerMaxWidth, cursor: "pointer", children: [triggerText !== undefined && (_jsx(Box, { as: "span", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: triggerText })), _jsxs(Box, { as: "span", ml: "6px", px: "8px", py: "1px", fontSize: "12px", fontWeight: 600, lineHeight: "1.4", borderRadius: "full", color: theme.colors.accentText, bg:
|
|
11
|
+
return (_jsxs(Popover, { trigger: trigger, placement: placement, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsxs(Box, { display: "inline-flex", alignItems: "center", maxW: triggerMaxWidth, cursor: "pointer", children: [triggerText !== undefined && (_jsx(Box, { as: "span", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: triggerText })), _jsxs(Box, { as: "span", ml: "6px", px: "8px", py: "1px", fontSize: "12px", fontWeight: 600, lineHeight: "1.4", borderRadius: "full", color: theme.colors.accentText, bg: countBadgeBg, transition: "all 0.15s ease", _hover: { bg: listRowBackgrounds(theme.colors).selectedActive }, children: ["+", count, " more"] })] }) }), _jsxs(PopoverContent, { width: "auto", minWidth: minWidth, maxH: "280px", overflowY: "auto", borderRadius: "xl",
|
|
10
12
|
// Chakra defaults this surface to `colors.gray.700` in dark, which against the
|
|
11
13
|
// swapped (dark-inverted) palette is a *light* grey — wrong for a popover bg. Pin it.
|
|
12
14
|
bg: theme.colors.background[50], boxShadow: "lg", _focus: { outline: "none", boxShadow: "lg" }, children: [_jsx(PopoverArrow, { bg: theme.colors.background[50] }), _jsx(PopoverBody, { p: 3, children: _jsx(SimpleGrid, { columns: columns, spacingX: 4, spacingY: 2, children: items === null || items === void 0 ? void 0 : items.map((item, index) => {
|
|
@@ -55,14 +55,14 @@ export default function MultiSelect({ value, onValueChange, width = "100%", labe
|
|
|
55
55
|
// surface up to `muted` (lightest); [500] fails there, [800] clears all with margin.
|
|
56
56
|
borderColor: error || localError
|
|
57
57
|
? theme.colors.semanticText.error
|
|
58
|
-
: theme.colors.boxborder[500], borderRadius: "lg", bg: theme.colors.
|
|
58
|
+
: theme.colors.boxborder[500], borderRadius: "lg", bg: theme.colors.background[50], minH: s.minH, transition: "border-color 0.2s, box-shadow 0.2s", _focusWithin: {
|
|
59
59
|
borderColor: error || localError
|
|
60
60
|
? theme.colors.semanticText.error
|
|
61
61
|
: theme.colors.primary[500],
|
|
62
62
|
boxShadow: `0 0 0 0.125rem ${error || localError
|
|
63
63
|
? theme.colors.boxShadow.error
|
|
64
64
|
: theme.colors.boxShadow.primary}`,
|
|
65
|
-
}, children: [options.map((option) => (_jsx(Tag, { size: s.tagSize, colorScheme: "primary", label: option.label, onIconClick: () => handleRemove(option), icon: X }, option.id))), _jsx(Input, { ref: inputRef, type: "text", value: inputValue, isDisabled: isDisabled, isReadOnly: isReadOnly, id: id, name: name, size: size, variant: "unstyled", h: s.fieldHeight, minH: s.fieldHeight, fontSize: s.fieldFontSize, fontWeight: "500", color: theme.colors.
|
|
65
|
+
}, children: [options.map((option) => (_jsx(Tag, { size: s.tagSize, colorScheme: "primary", label: option.label, onIconClick: () => handleRemove(option), icon: X }, option.id))), _jsx(Input, { ref: inputRef, type: "text", value: inputValue, isDisabled: isDisabled, isReadOnly: isReadOnly, id: id, name: name, size: size, variant: "unstyled", h: s.fieldHeight, minH: s.fieldHeight, fontSize: s.fieldFontSize, fontWeight: "500", color: theme.colors.text[700], letterSpacing: "0.02em", flex: "1", minW: 0, style: {
|
|
66
66
|
backgroundColor: "transparent",
|
|
67
67
|
...inputStyle,
|
|
68
68
|
}, onChange: handleInputChange, onKeyDown: handleKeyDown, placeholder: options.length === 0 ? placeholderText : "" })] }), (error || localError) && (_jsx(ErrorMessage, { errorMessage: localError || errorMessage })), helperText && !error && _jsx(HelperText, { helperText: helperText })] }));
|
|
@@ -3,17 +3,16 @@ import { Avatar, Box, Button, Center, Flex, Menu, MenuButton, MenuDivider, MenuI
|
|
|
3
3
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
4
4
|
import { accentTextOnCanvas, isDarkCanvas } from "../../Theme/tokens/builders/accentText.js";
|
|
5
5
|
import { resolveHoverTint } from "../../Theme/tokens/builders/outlineRung.js";
|
|
6
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
6
7
|
import { resolveStatusTone } from "../../Theme/tokens/builders/statusTone.js";
|
|
7
8
|
import { CircleArrowLeft, LogOut, PanelLeftClose, PanelRightClose, } from "lucide-react";
|
|
8
9
|
// Roomy enough to hover without aiming: the glyph is only 1.25rem.
|
|
9
10
|
const SIDEBAR_TOGGLE_HIT = "2.5rem";
|
|
10
11
|
export default function NavBar({ userAvathar, userName, userRole, navMenu, moreIcon, handleNavOnClick, handleLogout, logoutText, navigationBarText, sideBarToggole, onSideBarToggole, forceSideBarToggle = false, onSideBarPeek, }) {
|
|
11
12
|
const theme = useCustomTheme();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const menuHoverBg = resolveHoverTint(theme.colors.primary[50], theme.colors.backgroundColor.light);
|
|
13
|
+
const rowBackgrounds = listRowBackgrounds(theme.colors);
|
|
14
|
+
const menuHoverBg = rowBackgrounds.active;
|
|
15
15
|
const barHoverBg = resolveHoverTint(theme.colors.gray[100], theme.colors.backgroundColor.light);
|
|
16
|
-
const menuHoverInk = accentTextOnCanvas(theme.colors.primary, menuHoverBg);
|
|
17
16
|
const dangerTone = resolveStatusTone(theme.colors.semantic.error, isDarkCanvas(theme.colors.backgroundColor.main) ? "dark" : "light");
|
|
18
17
|
// Shared rounded pill affordance for the bar's icon controls.
|
|
19
18
|
const iconButtonStyle = {
|
|
@@ -41,9 +40,9 @@ export default function NavBar({ userAvathar, userName, userRole, navMenu, moreI
|
|
|
41
40
|
color: theme.colors.text[900],
|
|
42
41
|
gap: theme.space["2"],
|
|
43
42
|
transition: "background 0.12s",
|
|
44
|
-
_hover: { bg: menuHoverBg
|
|
45
|
-
_focus: { bg: menuHoverBg
|
|
46
|
-
_active: { bg:
|
|
43
|
+
_hover: { bg: menuHoverBg },
|
|
44
|
+
_focus: { bg: menuHoverBg },
|
|
45
|
+
_active: { bg: rowBackgrounds.selectedActive },
|
|
47
46
|
};
|
|
48
47
|
return (_jsx(Box, { bg: theme.colors.backgroundColor.light, px: 4, borderBottom: "1px solid", borderColor: theme.colors.boxborder[200], children: _jsxs(Flex, { h: 16, alignItems: "center", justifyContent: "space-between", children: [_jsxs(Box, { display: "flex", gap: 1.5, alignItems: "center", children: [_jsx(Box, { as: "button", type: "button", onClick: () => onSideBarToggole === null || onSideBarToggole === void 0 ? void 0 : onSideBarToggole(), onMouseEnter: onSideBarPeek, onFocus: onSideBarPeek, "aria-label": sideBarToggole ? "Close navigation menu" : "Open navigation menu", "aria-expanded": !!sideBarToggole, ...iconButtonStyle, display: forceSideBarToggle ? "flex" : { base: "flex", lg: "none" }, w: SIDEBAR_TOGGLE_HIT, h: SIDEBAR_TOGGLE_HIT, children: sideBarToggole ? (_jsx(PanelLeftClose, { size: "1.25rem" })) : (_jsx(PanelRightClose, { size: "1.25rem" })) }), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) && (_jsx(Box, { ...iconButtonStyle, as: "button", type: "button", "aria-label": "Go back", display: "flex", onClick: () => { var _a; return (_a = navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) === null || _a === void 0 ? void 0 : _a.call(navigationBarText); }, children: _jsx(CircleArrowLeft, { size: "1.25rem", color: theme.colors.text[500] }) })), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text) && (_jsx(Text, { color: accentTextOnCanvas(theme.colors.secondary, theme.colors.backgroundColor.light), fontSize: "1.25rem", fontWeight: 600, fontFamily: "open-sans, sans-serif", letterSpacing: "-0.013rem", children: navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text }))] }), _jsx(Flex, { minW: 0, flexShrink: 1, children: _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 4, minW: 0, children: [moreIcon && (_jsx(Box, { display: "flex", alignItems: "center", minW: 0, children: moreIcon })), _jsxs(Menu, { children: [_jsx(MenuButton, { as: Button, rounded: "full", variant: "link", cursor: "pointer", minW: 0, flexShrink: 0, children: _jsx(Avatar, { size: "sm", name: userName, src: userAvathar }) }), _jsx(MenuList, { alignItems: "center", zIndex: 5, p: 0, py: "0.375rem",
|
|
49
48
|
// Without a cap one long title stretches the whole dropdown; titles truncate instead.
|
|
@@ -32,7 +32,7 @@ export const NumberInput = {
|
|
|
32
32
|
const primary = theme.colors.primary[500];
|
|
33
33
|
return {
|
|
34
34
|
field: {
|
|
35
|
-
bg: theme.colors.
|
|
35
|
+
bg: theme.colors.background[50],
|
|
36
36
|
border: "0.063rem solid",
|
|
37
37
|
borderColor,
|
|
38
38
|
_placeholder: {
|
|
@@ -66,7 +66,7 @@ export const NumberInput = {
|
|
|
66
66
|
boxShadow: 'inherit',
|
|
67
67
|
},
|
|
68
68
|
_disabled: {
|
|
69
|
-
bg: theme.colors.
|
|
69
|
+
bg: theme.colors.background[100],
|
|
70
70
|
opacity: 1,
|
|
71
71
|
cursor: "not-allowed",
|
|
72
72
|
_hover: {
|
|
@@ -6,6 +6,8 @@ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
|
6
6
|
import { accentTextOnCanvas, onFilled } from "../../Theme/tokens/builders/accentText.js";
|
|
7
7
|
import { chartMode } from "../../Theme/tokens/builders/chartColorsFromTheme.js";
|
|
8
8
|
import { resolveHoverTint } from "../../Theme/tokens/builders/outlineRung.js";
|
|
9
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
10
|
+
import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
|
|
9
11
|
import { avatarColor, orgInitial, } from "./OrgSwitcherProps.js";
|
|
10
12
|
const sizeMap = {
|
|
11
13
|
sm: { h: "32px", avatar: "22px", font: "0.8rem", sub: "0.65rem", px: 2 },
|
|
@@ -23,8 +25,14 @@ const Avatar = ({ org, boxSize, fontSize, }) => {
|
|
|
23
25
|
const OrgSwitcher = ({ organizations, value, onChange, isLoading = false, isSearchable, searchThreshold = 6, triggerVariant = "ghost", size = "md", maxWidth = "200px", menuMinWidth = "280px", placeholder = "Select organization", ariaLabel = "Switch organization", showRole = true, }) => {
|
|
24
26
|
var _a;
|
|
25
27
|
const theme = useCustomTheme();
|
|
28
|
+
const rowBackgrounds = useMemo(() => listRowBackgrounds(theme.colors), [theme.colors]);
|
|
26
29
|
const s = sizeMap[size];
|
|
27
30
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
31
|
+
const requestExclusiveOpen = useExclusiveOverlay(isOpen, onClose);
|
|
32
|
+
const handlePopoverOpen = () => {
|
|
33
|
+
requestExclusiveOpen();
|
|
34
|
+
onOpen();
|
|
35
|
+
};
|
|
28
36
|
const [query, setQuery] = useState("");
|
|
29
37
|
const searchRef = useRef(null);
|
|
30
38
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
@@ -69,7 +77,7 @@ const OrgSwitcher = ({ organizations, value, onChange, isLoading = false, isSear
|
|
|
69
77
|
const triggerStyles = triggerVariant === "outline"
|
|
70
78
|
? { border: "1px solid", borderColor: theme.colors.boxborder[500], bg: theme.colors.background[50] }
|
|
71
79
|
: triggerVariant === "subtle"
|
|
72
|
-
? { bg: theme.colors.
|
|
80
|
+
? { bg: theme.colors.background[50] }
|
|
73
81
|
: { bg: "transparent" };
|
|
74
82
|
// `gray[100]` hover on a "transparent" trigger reads against whatever's actually behind it —
|
|
75
83
|
// this control lives in a navbar-like shell, so `backgroundColor.light` is that surface. For a
|
|
@@ -82,7 +90,7 @@ const OrgSwitcher = ({ organizations, value, onChange, isLoading = false, isSear
|
|
|
82
90
|
if (org.id !== value)
|
|
83
91
|
onChange(org.id, org);
|
|
84
92
|
};
|
|
85
|
-
return (_jsxs(Popover, { isOpen: isOpen, onOpen:
|
|
93
|
+
return (_jsxs(Popover, { isOpen: isOpen, onOpen: handlePopoverOpen, onClose: () => {
|
|
86
94
|
onClose();
|
|
87
95
|
setQuery("");
|
|
88
96
|
}, placement: "bottom-start", initialFocusRef: showSearch ? searchRef : firstOptionRef, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsxs(Flex, { as: "button", type: "button", "aria-label": ariaLabel, align: "center", gap: s.px === 2 ? "8px" : "10px", h: s.h, px: s.px, borderRadius: "lg", cursor: isLoading ? "default" : "pointer", opacity: isLoading ? 0.6 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "background 0.15s ease", _hover: { bg: triggerVariant === "ghost" ? triggerHoverBg : undefined }, ...triggerStyles, children: [selected ? (_jsx(Avatar, { org: selected, boxSize: s.avatar, fontSize: s.sub })) : (_jsx(Flex, { align: "center", justify: "center", boxSize: s.avatar, borderRadius: "lg", bg: theme.colors.gray[100], color: accentTextOnCanvas(theme.colors.gray, theme.colors.gray[100]), flexShrink: 0, children: _jsx(Building2, { size: 14 }) })), _jsx(Text, { fontSize: s.font, fontWeight: 600, color: theme.colors.gray[700], maxW: maxWidth, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", textAlign: "left", children: (_a = selected === null || selected === void 0 ? void 0 : selected.name) !== null && _a !== void 0 ? _a : placeholder }), isLoading ? (_jsx(Spinner, { size: "xs", thickness: "1.5px", color: theme.colors.accentText, flexShrink: 0 })) : (_jsx(Box, { as: ChevronsUpDown, size: 16, color: theme.colors.textMuted, flexShrink: 0 }))] }) }), _jsx(PopoverContent, { minW: menuMinWidth, w: "auto",
|
|
@@ -97,18 +105,14 @@ const OrgSwitcher = ({ organizations, value, onChange, isLoading = false, isSear
|
|
|
97
105
|
}
|
|
98
106
|
}, borderRadius: "lg" })] }) })), _jsxs(Box, { role: "listbox", "aria-label": "Organizations", maxH: "320px", overflowY: "auto", py: 1, onKeyDown: handleListKeyDown, children: [filtered.map((org, idx) => {
|
|
99
107
|
const isActive = org.id === value;
|
|
100
|
-
// Active row's hover repeated its own resting `primary[50]` fill — a zero-delta
|
|
101
|
-
// hover, invisible by construction. `resolveHoverTint` walks a fill away from a
|
|
102
|
-
// backdrop until distinguishable, so handing it its own resting bg as the backdrop
|
|
103
|
-
// is enough to make hover read as a real state change on both active and inactive rows.
|
|
104
108
|
const rowHoverBg = isActive
|
|
105
|
-
?
|
|
106
|
-
:
|
|
109
|
+
? rowBackgrounds.selectedActive
|
|
110
|
+
: rowBackgrounds.active;
|
|
107
111
|
return (_jsxs(Flex, { as: "button", type: "button", role: "option", "aria-selected": isActive, ref: (el) => {
|
|
108
112
|
optionRefs.current[idx] = el;
|
|
109
113
|
if (idx === 0)
|
|
110
114
|
firstOptionRef.current = el;
|
|
111
|
-
}, tabIndex: idx === activeIndex ? 0 : -1, align: "center", gap: "10px", w: "100%", textAlign: "left", border: "none", fontFamily: "inherit", px: 3, py: 2, cursor: "pointer", bg: isActive ?
|
|
112
|
-
}), filtered.length === 0 && (_jsx(Text, { fontSize: "sm", color: theme.colors.
|
|
115
|
+
}, tabIndex: idx === activeIndex ? 0 : -1, align: "center", gap: "10px", w: "100%", textAlign: "left", border: "none", fontFamily: "inherit", px: 3, py: 2, cursor: "pointer", bg: isActive ? rowBackgrounds.selected : "transparent", transition: "background 0.12s ease", _hover: { bg: rowHoverBg }, onClick: () => handleSelect(org), children: [_jsx(Avatar, { org: org, boxSize: s.avatar, fontSize: s.sub }), _jsxs(Box, { flex: "1", minW: 0, children: [_jsx(Text, { fontSize: s.font, fontWeight: isActive ? 600 : 500, color: theme.colors.text[900], overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: org.name }), showRole && org.role && (_jsx(Text, { fontSize: s.sub, color: theme.colors.text[500], overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: org.role }))] }), isActive && (_jsx(Box, { as: Check, size: 16, color: theme.colors.accentText, flexShrink: 0 }))] }, org.id));
|
|
116
|
+
}), filtered.length === 0 && (_jsx(Text, { fontSize: "sm", color: theme.colors.textMuted, textAlign: "center", py: 6, children: "No organizations found" }))] })] }) })] }));
|
|
113
117
|
};
|
|
114
118
|
export default OrgSwitcher;
|
|
@@ -3,13 +3,13 @@ import { Box, Flex, Text } from "@chakra-ui/react";
|
|
|
3
3
|
import { Download, ExternalLink, FileText } from "lucide-react";
|
|
4
4
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
5
|
import { accentTextOnCanvas } from "../../Theme/tokens/builders/accentText.js";
|
|
6
|
-
import {
|
|
6
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
7
7
|
import ToolTip from "../ToolTip/ToolTip.js";
|
|
8
8
|
const PdfViewer = ({ pdfUrl, fileName = "Document.pdf", height = "480px", showToolbar = true, borderRadius = "xl", }) => {
|
|
9
9
|
const theme = useCustomTheme();
|
|
10
|
-
const toolbarSurface = theme.colors.
|
|
10
|
+
const toolbarSurface = theme.colors.background[50];
|
|
11
11
|
const iconHoverInk = accentTextOnCanvas(theme.colors.primary, toolbarSurface);
|
|
12
|
-
const iconHoverBg =
|
|
13
|
-
return (_jsxs(Box, { border: "1px solid", borderColor: theme.colors.gray[200], borderRadius: borderRadius, overflow: "hidden", bg: theme.colors.background[50], children: [showToolbar && (_jsxs(Flex, { align: "center", justify: "space-between", px: 4, py: 2.5, borderBottom: "1px solid", borderColor: theme.colors.gray[100], bg: theme.colors.
|
|
12
|
+
const iconHoverBg = listRowBackgrounds(theme.colors).active;
|
|
13
|
+
return (_jsxs(Box, { border: "1px solid", borderColor: theme.colors.gray[200], borderRadius: borderRadius, overflow: "hidden", bg: theme.colors.background[50], children: [showToolbar && (_jsxs(Flex, { align: "center", justify: "space-between", px: 4, py: 2.5, borderBottom: "1px solid", borderColor: theme.colors.gray[100], bg: theme.colors.background[50], children: [_jsxs(Flex, { align: "center", gap: 2, minW: 0, children: [_jsx(FileText, { size: 18, color: theme.colors.accentText }), _jsx(Text, { fontSize: "sm", fontWeight: 500, color: theme.colors.gray[700], overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: fileName })] }), _jsxs(Flex, { align: "center", gap: 1, children: [_jsx(ToolTip, { label: "Open in new tab", placement: "top", children: _jsx(Box, { as: "a", href: pdfUrl, target: "_blank", rel: "noopener noreferrer", p: 2, borderRadius: "lg", color: theme.colors.gray[600], _hover: { bg: iconHoverBg, color: iconHoverInk }, children: _jsx(ExternalLink, { size: 16 }) }) }), _jsx(ToolTip, { label: "Download", placement: "top", children: _jsx(Box, { as: "a", href: pdfUrl, download: fileName, p: 2, borderRadius: "lg", color: theme.colors.gray[600], _hover: { bg: iconHoverBg, color: iconHoverInk }, children: _jsx(Download, { size: 16 }) }) })] })] })), _jsx(Box, { as: "embed", src: pdfUrl, type: "application/pdf", width: "100%", height: height, display: "block" })] }));
|
|
14
14
|
};
|
|
15
15
|
export default PdfViewer;
|
|
@@ -3,7 +3,7 @@ import { useMemo, useState } from "react";
|
|
|
3
3
|
import { Badge, Box, Checkbox, Divider, Flex, Heading, HStack, IconButton, Skeleton, Table, Tbody, Td, Text, Th, Thead, Tooltip, Tr, VStack, } from "@chakra-ui/react";
|
|
4
4
|
import { ArrowLeft, Check, Pencil, Plus, ShieldCheck, SquareArrowOutUpRight, Trash2, } from "lucide-react";
|
|
5
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
6
|
-
import {
|
|
6
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
7
7
|
import Button from "../Button/Button.js";
|
|
8
8
|
import TextInput from "../Input/TextInput.js";
|
|
9
9
|
import EmptyState from "../EmptyState/EmptyState.js";
|
|
@@ -59,8 +59,9 @@ const RolesPermission = ({ view, mode = "create", roles, isRolesLoading = false,
|
|
|
59
59
|
const surface = colors.background[50];
|
|
60
60
|
const muted = colors.textMuted;
|
|
61
61
|
const heading = colors.text[900];
|
|
62
|
-
const
|
|
63
|
-
const
|
|
62
|
+
const rowBackgrounds = listRowBackgrounds(colors);
|
|
63
|
+
const headBg = colors.background[100];
|
|
64
|
+
const rowHover = rowBackgrounds.active;
|
|
64
65
|
const isViewMode = mode === "view";
|
|
65
66
|
const columnLabels = {
|
|
66
67
|
read: labels.read,
|