pixelize-design-library 2.4.2-beta.34 → 2.4.2-beta.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Components/AppSwitcher/AppSwitcher.js +12 -49
- 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/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/Components/SegmentedControl/SegmentedControl.js +40 -10
- package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +3 -0
- 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/Toggle/TableToggle.js +68 -18
- package/dist/Components/Toggle/TableToggleProps.d.ts +3 -0
- package/dist/Components/ToggleSwitch/ToggleSwitch.js +1 -1
- 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 +13 -50
- 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/SegmentedControl/SegmentedControl.js +42 -12
- 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/Toggle/TableToggle.js +67 -17
- package/dist/esm/Components/ToggleSwitch/ToggleSwitch.js +1 -1
- 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
|
@@ -5,9 +5,11 @@ import Checkbox from "../../Checkbox/Checkbox.js";
|
|
|
5
5
|
import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
6
6
|
import { scrollbarStyles } from "../../../Theme/tokens/builders/scrollbar.js";
|
|
7
7
|
import { accentTextOnCanvas } from "../../../Theme/tokens/builders/accentText.js";
|
|
8
|
+
import { listRowBackgrounds } from "../../../Theme/tokens/builders/rowStates.js";
|
|
8
9
|
import { ChevronDown, ChevronUp, GripVertical } from "lucide-react";
|
|
9
10
|
const ManageColumns = ({ columns, items, setItems, childInputMethodsRef, }) => {
|
|
10
11
|
const theme = useCustomTheme();
|
|
12
|
+
const rowBackgrounds = useMemo(() => listRowBackgrounds(theme.colors), [theme.colors]);
|
|
11
13
|
const [searchTerm, setSearchTerm] = useState("");
|
|
12
14
|
const [draggedItemIndex, setDraggedItemIndex] = useState(null);
|
|
13
15
|
const [error, setError] = useState(null);
|
|
@@ -78,14 +80,14 @@ const ManageColumns = ({ columns, items, setItems, childInputMethodsRef, }) => {
|
|
|
78
80
|
return (_jsxs(ListItem, { draggable: true, onDragStart: () => handleDragStart(index), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, bg: isDraggingThisItem
|
|
79
81
|
? theme.colors.primary[100]
|
|
80
82
|
: isDropZone
|
|
81
|
-
?
|
|
83
|
+
? rowBackgrounds.selected
|
|
82
84
|
: "transparent", display: "flex", alignItems: "center", borderRadius: "sm", border: "1px solid", borderColor: isDraggingThisItem
|
|
83
85
|
? theme.colors.primary[400]
|
|
84
86
|
: "transparent", cursor: "grab", fontSize: "13px", px: 2, py: "3px", mb: "3px", transition: "all 0.15s ease", _hover: {
|
|
85
|
-
bg:
|
|
87
|
+
bg: rowBackgrounds.active,
|
|
86
88
|
borderColor: theme.colors.boxborder[200],
|
|
87
89
|
}, _active: { cursor: "grabbing" }, children: [_jsx(Box, { as: "span", "aria-hidden": "true", display: "inline-flex", cursor: "grab", mr: 1, _hover: { color: theme.colors.gray[500] }, children: _jsx(GripVertical, { size: 14 }) }), _jsx(Checkbox, { isChecked: !item.isHidden, label: String(item.label), onChange: () => toggleCheckbox(item.id), size: "sm", labelSx: {
|
|
88
|
-
color: item.isHidden ? theme.colors.
|
|
90
|
+
color: item.isHidden ? theme.colors.textMuted : theme.colors.text[700],
|
|
89
91
|
} }), _jsx(Text, { fontSize: "12px", color: theme.colors.gray[500], ml: 'auto', children: index + 1 }), _jsx(IconButton, { "aria-label": `Move ${item.label} up`, icon: _jsx(ChevronUp, { size: 14 }), variant: "ghost", size: "xs", ml: 1, minW: "auto", h: "auto", p: 0, color: theme.colors.gray[500], isDisabled: realIndex <= 0, onClick: () => moveItem(item.id, -1) }), _jsx(IconButton, { "aria-label": `Move ${item.label} down`, icon: _jsx(ChevronDown, { size: 14 }), variant: "ghost", size: "xs", ml: 1, minW: "auto", h: "auto", p: 0, color: theme.colors.gray[500], isDisabled: realIndex === -1 || realIndex >= items.length - 1, onClick: () => moveItem(item.id, 1) })] }, item.id));
|
|
90
92
|
})) : (_jsx(Text, { color: theme.colors.textMuted, textAlign: "center", fontSize: "sm", py: 6, children: "No columns found" })) }), _jsxs(Text, { fontSize: "xs", color: theme.colors.gray[500], mt: 2, textAlign: "right", children: [visibleCount, " / ", items.length, " visible"] })] }));
|
|
91
93
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Flex, IconButton, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalOverlay, Tabs, TabList, TabPanels, Tab, TabPanel, Text, } from "@chakra-ui/react";
|
|
3
|
-
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
import { useCallback, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { motion } from "framer-motion";
|
|
5
5
|
import ManageColumns from "./ManageColumns.js";
|
|
6
6
|
import Button from "../../Button/Button.js";
|
|
@@ -8,6 +8,7 @@ import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
|
8
8
|
import { scrollbarStyles } from "../../../Theme/tokens/builders/scrollbar.js";
|
|
9
9
|
import { Settings, Check } from "lucide-react";
|
|
10
10
|
import ToolTip from "../../ToolTip/ToolTip.js";
|
|
11
|
+
import { listRowBackgrounds } from "../../../Theme/tokens/builders/rowStates.js";
|
|
11
12
|
const MotionModalContent = motion(ModalContent);
|
|
12
13
|
const DENSITY_OPTIONS = [
|
|
13
14
|
{ value: "compact", label: "Compact", desc: "Tight rows — fit more data on screen" },
|
|
@@ -16,6 +17,7 @@ const DENSITY_OPTIONS = [
|
|
|
16
17
|
];
|
|
17
18
|
const TableSettings = ({ columns, onSave, density = "normal", onDensityChange, groupBy, }) => {
|
|
18
19
|
const theme = useCustomTheme();
|
|
20
|
+
const rowBackgrounds = useMemo(() => listRowBackgrounds(theme.colors), [theme.colors]);
|
|
19
21
|
const childInputMethodsRef = useRef({});
|
|
20
22
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
21
23
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
@@ -50,7 +52,7 @@ const TableSettings = ({ columns, onSave, density = "normal", onDensityChange, g
|
|
|
50
52
|
color: theme.colors.accentText
|
|
51
53
|
} }) }), _jsxs(Modal, { isOpen: settingsOpen, onClose: () => setSettingsOpen(false), size: "md", children: [_jsx(ModalOverlay, {}), _jsxs(MotionModalContent, { mt: "0", top: "0", position: "absolute", borderTopRadius: "none", initial: { y: "-100%", opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: "-100%", opacity: 0 }, transition: { duration: 0.4, ease: "easeOut" }, padding: "0", minW: "620px", minH: "520px", maxH: "90vh", display: "flex", flexDirection: "column", bg: theme.colors.background[50], overflow: "hidden", children: [_jsx(ModalCloseButton, { top: 3, right: 3, zIndex: 2 }), _jsxs(Tabs, { index: selectedIndex, onChange: setSelectedIndex, variant: "unstyled", display: "flex", flexDirection: "column", flex: "1", minH: 0, children: [_jsxs(Box, { pt: 4, px: 4, children: [_jsx(Text, { fontWeight: 600, fontSize: "md", mb: 3, children: "Table Settings" }), _jsxs(TabList, { gap: 0, borderBottom: "1px solid", borderColor: theme.colors.boxborder[200], children: [_jsx(Tab, { ...tabStyle, children: "Density" }), _jsx(Tab, { ...tabStyle, children: "Manage Columns" }), _jsx(Tab, { ...tabStyle, children: "Group" })] })] }), _jsx(ModalBody, { px: 4, py: 3, flex: "1", overflowY: "auto", sx: scrollbarStyles(theme.colors), children: _jsxs(TabPanels, { children: [_jsx(TabPanel, { px: 0, py: 1, children: _jsx(Flex, { direction: "column", gap: 2, children: DENSITY_OPTIONS.map((opt) => {
|
|
52
54
|
const selected = density === opt.value;
|
|
53
|
-
return (_jsxs(Flex, { as: "button", type: "button", align: "center", gap: 3, px: 3, py: 2.5, borderRadius: "lg", border: "1px solid", borderColor: selected ? theme.colors.accentText : theme.colors.boxborder[200], bg: selected ?
|
|
55
|
+
return (_jsxs(Flex, { as: "button", type: "button", align: "center", gap: 3, px: 3, py: 2.5, borderRadius: "lg", border: "1px solid", borderColor: selected ? theme.colors.accentText : theme.colors.boxborder[200], bg: selected ? rowBackgrounds.selected : theme.colors.transparent, transition: "all 0.15s", _hover: { borderColor: theme.colors.accentText }, onClick: () => onDensityChange === null || onDensityChange === void 0 ? void 0 : onDensityChange(opt.value), children: [_jsx(Box, { boxSize: "1.1rem", borderRadius: "full", border: "2px solid", borderColor: selected ? theme.colors.accentText : theme.colors.boxborder[500], display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, children: selected && _jsx(Check, { size: 11, color: theme.colors.accentText, strokeWidth: 3 }) }), _jsxs(Box, { textAlign: "left", children: [_jsx(Text, { fontSize: "13px", fontWeight: 600, color: theme.colors.text[700], children: opt.label }), _jsx(Text, { fontSize: "11px", color: theme.colors.textMuted, children: opt.desc })] })] }, opt.value));
|
|
54
56
|
}) }) }), _jsx(TabPanel, { px: 0, py: 0, children: _jsx(Box, { sx: {
|
|
55
57
|
"& [role='listitem'], & > div > div": {
|
|
56
58
|
py: "4px !important",
|
|
@@ -68,7 +70,7 @@ const TableSettings = ({ columns, onSave, density = "normal", onDensityChange, g
|
|
|
68
70
|
.map((opt) => {
|
|
69
71
|
var _a;
|
|
70
72
|
const selected = selectedGroup === opt.id;
|
|
71
|
-
return (_jsxs(Flex, { as: "button", type: "button", align: "center", gap: 3, px: 3, py: 2.5, borderRadius: "lg", border: "1px solid", borderColor: selected ? theme.colors.accentText : theme.colors.boxborder[200], bg: selected ?
|
|
73
|
+
return (_jsxs(Flex, { as: "button", type: "button", align: "center", gap: 3, px: 3, py: 2.5, borderRadius: "lg", border: "1px solid", borderColor: selected ? theme.colors.accentText : theme.colors.boxborder[200], bg: selected ? rowBackgrounds.selected : theme.colors.transparent, transition: "all 0.15s", _hover: { borderColor: theme.colors.accentText }, onClick: () => setSelectedGroup(opt.id), children: [_jsx(Box, { boxSize: "1.1rem", borderRadius: "full", border: "2px solid", borderColor: selected ? theme.colors.accentText : theme.colors.boxborder[500], display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, children: selected && _jsx(Check, { size: 11, color: theme.colors.accentText, strokeWidth: 3 }) }), _jsx(Text, { fontSize: "13px", fontWeight: 600, color: theme.colors.text[700], textAlign: "left", children: opt.label })] }, String((_a = opt.id) !== null && _a !== void 0 ? _a : "__none__")));
|
|
72
74
|
}) })] })] }) })] }), _jsxs(ModalFooter, { gap: "0.5rem", borderTop: "1px solid", borderColor: theme.colors.boxborder[200], pt: 3, pb: 3, px: 4, children: [_jsx(Button, { label: "Close", size: "sm", onClick: () => setSettingsOpen(false), variant: "outline", colorScheme: "red" }), _jsx(Button, { label: "Save", size: "sm", onClick: handleSave })] })] })] })] }));
|
|
73
75
|
};
|
|
74
76
|
export default TableSettings;
|
|
@@ -1,43 +1,93 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef, useState } from "react";
|
|
2
3
|
import { Box, IconButton } from "@chakra-ui/react";
|
|
3
4
|
import { Columns3, Table2 } from "lucide-react";
|
|
4
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
6
|
import { AA_NON_TEXT, liftToContrast } from "../../Theme/tokens/builders/outlineRung.js";
|
|
7
|
+
import { resolveFilledSurface } from "../../Theme/tokens/builders/filledSurface.js";
|
|
6
8
|
import ToolTip from "../ToolTip/ToolTip.js";
|
|
7
|
-
const
|
|
9
|
+
const MODES = ["grid", "list"];
|
|
10
|
+
const TableToggle = ({ value, onChange, variant = "default" }) => {
|
|
8
11
|
const theme = useCustomTheme();
|
|
9
12
|
const { colors } = theme;
|
|
13
|
+
const isBrandSlide = variant === "brandSlide";
|
|
14
|
+
const isUnderlineSlide = variant === "underlineSlide";
|
|
15
|
+
const hasIndicator = isBrandSlide || isUnderlineSlide;
|
|
16
|
+
const brandFill = resolveFilledSurface(colors.primary, colors);
|
|
10
17
|
const restInk = liftToContrast(colors.background[800], colors.background[600], AA_NON_TEXT);
|
|
11
18
|
const hoverInk = liftToContrast(colors.background[900], colors.background[400], AA_NON_TEXT);
|
|
19
|
+
const trackRef = useRef(null);
|
|
20
|
+
const refs = useRef([]);
|
|
21
|
+
const [pill, setPill] = useState(null);
|
|
22
|
+
const selectedIndex = MODES.indexOf(value);
|
|
23
|
+
useLayoutEffect(() => {
|
|
24
|
+
if (!hasIndicator)
|
|
25
|
+
return;
|
|
26
|
+
const track = trackRef.current;
|
|
27
|
+
const node = refs.current[selectedIndex];
|
|
28
|
+
if (!track || !node) {
|
|
29
|
+
setPill(null);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const trackRect = track.getBoundingClientRect();
|
|
33
|
+
const nodeRect = node.getBoundingClientRect();
|
|
34
|
+
setPill({ left: nodeRect.left - trackRect.left, width: nodeRect.width });
|
|
35
|
+
}, [hasIndicator, selectedIndex]);
|
|
12
36
|
const styles = {
|
|
13
37
|
container: {
|
|
14
38
|
display: "flex",
|
|
15
39
|
alignItems: "center",
|
|
16
|
-
bg: colors.background[600],
|
|
17
|
-
p: "0.125rem",
|
|
18
|
-
borderRadius: "md",
|
|
40
|
+
bg: isBrandSlide ? colors.primary.opacity[8] : isUnderlineSlide ? "transparent" : colors.background[600],
|
|
41
|
+
p: isUnderlineSlide ? "0" : "0.125rem",
|
|
42
|
+
borderRadius: isUnderlineSlide ? "none" : "md",
|
|
43
|
+
borderBottom: isUnderlineSlide ? `0.0625rem solid ${colors.boxborder[200]}` : undefined,
|
|
19
44
|
height: "2rem",
|
|
20
|
-
gap: "0.125rem",
|
|
45
|
+
gap: isUnderlineSlide ? "0" : "0.125rem",
|
|
21
46
|
width: "6.3rem",
|
|
47
|
+
position: "relative",
|
|
22
48
|
},
|
|
23
49
|
button: (mode) => ({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
50
|
+
position: "relative",
|
|
51
|
+
zIndex: 1,
|
|
52
|
+
bg: hasIndicator ? "transparent" : value === mode ? colors.backgroundColor.light : "transparent",
|
|
53
|
+
boxShadow: hasIndicator ? "none" : value === mode ? "md" : "none",
|
|
54
|
+
color: isBrandSlide
|
|
55
|
+
? value === mode
|
|
56
|
+
? brandFill.color
|
|
57
|
+
: restInk
|
|
58
|
+
: value === mode
|
|
59
|
+
? colors.accentText
|
|
60
|
+
: restInk,
|
|
61
|
+
borderRadius: isUnderlineSlide ? "none" : "base",
|
|
28
62
|
height: "1.75rem",
|
|
29
|
-
border: "0.031rem solid",
|
|
30
|
-
borderColor:
|
|
63
|
+
border: hasIndicator ? "none" : "0.031rem solid",
|
|
64
|
+
borderColor: hasIndicator
|
|
65
|
+
? "transparent"
|
|
66
|
+
: value === mode
|
|
67
|
+
? colors.primary.opacity[32]
|
|
68
|
+
: "transparent",
|
|
31
69
|
padding: "0.313rem 0.813rem",
|
|
32
70
|
_hover: {
|
|
33
|
-
bg:
|
|
34
|
-
?
|
|
35
|
-
:
|
|
36
|
-
|
|
71
|
+
bg: hasIndicator
|
|
72
|
+
? "transparent"
|
|
73
|
+
: value === mode
|
|
74
|
+
? colors.backgroundColor.light
|
|
75
|
+
: colors.background[400],
|
|
76
|
+
color: isBrandSlide
|
|
77
|
+
? value === mode
|
|
78
|
+
? brandFill.color
|
|
79
|
+
: hoverInk
|
|
80
|
+
: value === mode
|
|
81
|
+
? colors.accentText
|
|
82
|
+
: hoverInk,
|
|
37
83
|
},
|
|
38
|
-
transition: "
|
|
84
|
+
transition: "color 0.2s ease-in-out",
|
|
39
85
|
}),
|
|
40
86
|
};
|
|
41
|
-
return (_jsxs(Box, { ...styles.container, children: [_jsx(
|
|
87
|
+
return (_jsxs(Box, { ref: trackRef, ...styles.container, children: [isBrandSlide && pill && (_jsx(Box, { "aria-hidden": "true", position: "absolute", top: "0.125rem", left: 0, h: "1.75rem", w: `${pill.width}px`, borderRadius: "base", bg: brandFill.fill, boxShadow: `0 0.125rem 0.5rem ${colors.boxShadow.primary}`, transform: `translateX(${pill.left}px)`, transition: "transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1), width 0.24s cubic-bezier(0.2, 0.8, 0.2, 1)" })), isUnderlineSlide && pill && (_jsx(Box, { "aria-hidden": "true", position: "absolute", bottom: "-0.0625rem", left: 0, h: "0.125rem", w: `${pill.width}px`, borderRadius: "full", bg: colors.primary[500], transform: `translateX(${pill.left}px)`, transition: "transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1), width 0.24s cubic-bezier(0.2, 0.8, 0.2, 1)" })), _jsx(ToolTip, { label: "Table View", placement: "top", fontSize: 12, hasArrow: true, children: _jsx(IconButton, { ref: (node) => {
|
|
88
|
+
refs.current[0] = node;
|
|
89
|
+
}, "aria-label": "Grid View", icon: _jsx(Table2, { size: "1.25rem" }), variant: "ghost", onClick: () => onChange("grid"), ...styles.button("grid") }) }), _jsx(ToolTip, { label: "Kanban View", placement: "top", fontSize: 12, hasArrow: true, children: _jsx(IconButton, { ref: (node) => {
|
|
90
|
+
refs.current[1] = node;
|
|
91
|
+
}, "aria-label": "List View", icon: _jsx(Columns3, { size: "1.25rem" }), variant: "ghost", onClick: () => onChange("list"), ...styles.button("list") }) })] }));
|
|
42
92
|
};
|
|
43
93
|
export default TableToggle;
|
|
@@ -11,5 +11,5 @@ export default function ToggleSwitch({ isChecked, onChange, isDisabled = false,
|
|
|
11
11
|
return (_jsx(Box, { as: "button", type: "button", id: id, role: "switch", "aria-checked": isChecked, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, disabled: isDisabled, onClick: () => onChange(!isChecked), position: "relative", display: "inline-flex", alignItems: "center", flexShrink: 0, w: dims.w, h: dims.h, p: 0, borderRadius: "full", borderWidth: "1px", borderStyle: "solid", borderColor: isChecked ? colors.primary[500] : colors.boxborder[500], bg: isChecked ? colors.primary[500] : colors.background[600], opacity: isDisabled ? 0.5 : 1, cursor: isDisabled ? "not-allowed" : "pointer", transition: "background-color 0.2s ease, border-color 0.2s ease", _focusVisible: {
|
|
12
12
|
outline: "none",
|
|
13
13
|
boxShadow: `0 0 0 2px ${colors.primary[300]}`,
|
|
14
|
-
}, children: _jsx(Box, { "aria-hidden": "true", position: "absolute", left: "0.125rem", w: dims.knob, h: dims.knob, borderRadius: "full", bg: colors.
|
|
14
|
+
}, children: _jsx(Box, { "aria-hidden": "true", position: "absolute", left: "0.125rem", w: dims.knob, h: dims.knob, borderRadius: "full", bg: colors.white, boxShadow: "sm", transition: "transform 0.2s ease", transform: isChecked ? `translateX(${dims.travel})` : "translateX(0)" }) }));
|
|
15
15
|
}
|
|
@@ -20,7 +20,7 @@ export const EditableCell = ({ row, column, isEditable, handleCellClick, handleC
|
|
|
20
20
|
return (_jsx(Box, { width: "50%", ref: cellRef, children: _jsx(Input, { type: "date", value: value, onChange: (e) => handleCellChange(row.id, column.label, e.target.value) }) }));
|
|
21
21
|
}
|
|
22
22
|
else if (column.label === "priority") {
|
|
23
|
-
return (_jsx(Box, { width: "100%", ref: cellRef, children: _jsxs(Menu, { isOpen: true, children: [_jsx(MenuButton, { as: Button, rightIcon: _jsx(ChevronDown, {}), bg: colors.teal[50], color: accentTextOnCanvas(colors.teal, colors.teal[50]), _hover: { bg: colors.teal[100] }, _active: { bg: colors.teal[200] }, children: value }), _jsxs(MenuList, { children: [_jsx(MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Low"),
|
|
23
|
+
return (_jsx(Box, { width: "100%", ref: cellRef, children: _jsxs(Menu, { isOpen: true, children: [_jsx(MenuButton, { as: Button, rightIcon: _jsx(ChevronDown, {}), bg: colors.teal[50], color: accentTextOnCanvas(colors.teal, colors.teal[50]), _hover: { bg: colors.teal[100] }, _active: { bg: colors.teal[200] }, children: value }), _jsxs(MenuList, { children: [_jsx(MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Low"), children: "Low" }), _jsx(MenuItem, { onClick: () => handleCellChange(row.id, column.label, "Medium"), children: "Medium" }), _jsx(MenuItem, { onClick: () => handleCellChange(row.id, column.label, "High"), children: "High" })] })] }) }));
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
return (_jsx(Box, { width: "100%", ref: cellRef, children: _jsx(Input, { value: value, onChange: (e) => handleCellChange(row.id, column.label, e.target.value) }) }));
|
|
@@ -9,6 +9,6 @@ const DeactivateConfirmModal = ({ isOpen, onClose, userName, isLoading, onConfir
|
|
|
9
9
|
const { colors } = useCustomTheme();
|
|
10
10
|
const mode = isDarkCanvas(colors.backgroundColor.main) ? "dark" : "light";
|
|
11
11
|
const errorTone = resolveStatusTone(colors.semantic.error, mode);
|
|
12
|
-
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.background[50], borderRadius: "2xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: colors.boxborder[200], display: "flex", alignItems: "center", gap: 3, children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: errorTone.bg, color: errorTone.fg, children: _jsx(AlertTriangle, { size: 18 }) }), _jsx(Text, { fontSize: "1.05rem", fontWeight: 600, children: labels.confirmDeactivation })] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 6, children: _jsxs(VStack, { spacing: 4, align: "stretch", children: [_jsx(Text, { fontSize: "md", fontWeight: 500, color: colors.text[900], children: labels.deactivateConfirmQuestion }), _jsx(Box, { bg: colors.
|
|
12
|
+
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.background[50], borderRadius: "2xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: colors.boxborder[200], display: "flex", alignItems: "center", gap: 3, children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: errorTone.bg, color: errorTone.fg, children: _jsx(AlertTriangle, { size: 18 }) }), _jsx(Text, { fontSize: "1.05rem", fontWeight: 600, children: labels.confirmDeactivation })] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 6, children: _jsxs(VStack, { spacing: 4, align: "stretch", children: [_jsx(Text, { fontSize: "md", fontWeight: 500, color: colors.text[900], children: labels.deactivateConfirmQuestion }), _jsx(Box, { bg: colors.background[50], borderRadius: "lg", p: 4, border: "1px solid", borderColor: colors.boxborder[200], children: _jsxs(Text, { color: colors.textMuted, fontSize: "sm", children: [userName ? `${userName} ` : "", labels.deactivateConfirmDescription] }) }), _jsxs(HStack, { justifyContent: "flex-end", spacing: 3, pt: 2, children: [_jsx(Button, { label: labels.cancel, onClick: onClose, variant: "outline", size: "sm", colorScheme: "gray" }), _jsx(Button, { label: labels.deactivateUser, onClick: onConfirm, colorScheme: "red", size: "sm", isLoading: isLoading, leftIcon: _jsx(Trash2, { size: 16 }) })] })] }) })] })] }));
|
|
13
13
|
};
|
|
14
14
|
export default DeactivateConfirmModal;
|
|
@@ -5,6 +5,7 @@ import { ChevronLeft, RefreshCw, Send, Shield, Trash2, UserPlus, Users, UserRoun
|
|
|
5
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
6
6
|
import { resolveHoverTint } from "../../Theme/tokens/builders/outlineRung.js";
|
|
7
7
|
import { accentTextOnCanvas } from "../../Theme/tokens/builders/accentText.js";
|
|
8
|
+
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
8
9
|
import EmptyState from "../EmptyState/EmptyState.js";
|
|
9
10
|
import AddUserModal from "./AddUserModal.js";
|
|
10
11
|
import ChangeRoleModal from "./ChangeRoleModal.js";
|
|
@@ -55,6 +56,7 @@ const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], ca
|
|
|
55
56
|
const [actionUserId, setActionUserId] = useState(null);
|
|
56
57
|
const border = colors.boxborder[200];
|
|
57
58
|
const surface = colors.background[50];
|
|
59
|
+
const rowBackgrounds = useMemo(() => listRowBackgrounds(colors), [colors]);
|
|
58
60
|
const muted = colors.textMuted;
|
|
59
61
|
const heading = colors.text[900];
|
|
60
62
|
const avatarBg = colors.primary[100];
|
|
@@ -71,10 +73,10 @@ const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], ca
|
|
|
71
73
|
const renderStatusBadge = (isActive) => (_jsx(Badge, { variant: "subtle", colorScheme: isActive ? successScheme : dangerScheme, borderRadius: "full", px: 2, py: 0.5, fontSize: "0.65rem", fontWeight: 600, textTransform: "none", children: isActive ? labels.active : labels.inactive }));
|
|
72
74
|
return (_jsxs(Flex, { backgroundColor: colors.backgroundColor.main, minHeight: minHeight, p: { base: 3, md: 4 }, gap: 3, flexDirection: { base: "column", lg: "row" }, children: [_jsxs(Box, { width: { base: "100%", lg: "300px" }, backgroundColor: surface, borderRadius: "xl", boxShadow: "sm", border: "1px solid", borderColor: border, position: "relative", order: { base: 2, lg: 1 }, overflow: "hidden", display: "flex", flexDirection: "column", children: [_jsxs(Flex, { px: 4, py: 3, borderBottom: "1px solid", borderColor: border, alignItems: "center", justifyContent: "space-between", children: [_jsxs(HStack, { spacing: 2, children: [onBack && (_jsx(IconButton, { "aria-label": "Go back", icon: _jsx(ChevronLeft, { size: 18 }), variant: "ghost", size: "xs", color: muted, onClick: onBack })), _jsx(Heading, { size: "sm", fontWeight: 600, color: heading, children: labels.teamMembers }), _jsx(Badge, { colorScheme: "gray", borderRadius: "full", fontSize: "0.65rem", px: 2, children: users.length })] }), onRefresh && (_jsx(IconButton, { "aria-label": labels.refreshList, icon: _jsx(RefreshCw, { size: 15 }), variant: "ghost", size: "xs", color: muted, onClick: onRefresh, isLoading: isUsersLoading }))] }), _jsx(Box, { flex: 1, overflowY: "auto", maxHeight: { base: "380px", lg: `calc(${minHeight} - 80px)` }, children: isUsersLoading ? (_jsx(VStack, { spacing: 2, p: 3, children: Array.from({ length: 6 }).map((_, idx) => (_jsxs(Flex, { alignItems: "center", gap: 3, p: 2, w: "100%", children: [_jsx(SkeletonCircle, { size: "9" }), _jsxs(Box, { flex: 1, children: [_jsx(Skeleton, { height: "12px", mb: 2, width: "80%" }), _jsx(Skeleton, { height: "9px", width: "60%" })] })] }, idx))) })) : users.length === 0 ? (_jsx(EmptyState, { icon: Users, title: labels.noUsers, size: "sm", minH: "220px" })) : (_jsx(VStack, { spacing: 1, p: 2, align: "stretch", children: users.map((user) => {
|
|
73
75
|
const isSelected = selectedUserId != null && selectedUserId === user.id;
|
|
74
|
-
return (_jsxs(Flex, { p: 2.5, w: "100%", cursor: "pointer", alignItems: "center", gap: 2.5, backgroundColor: isSelected ?
|
|
76
|
+
return (_jsxs(Flex, { p: 2.5, w: "100%", cursor: "pointer", alignItems: "center", gap: 2.5, backgroundColor: isSelected ? rowBackgrounds.selected : "transparent", _hover: {
|
|
75
77
|
background: isSelected
|
|
76
|
-
?
|
|
77
|
-
:
|
|
78
|
+
? rowBackgrounds.selectedActive
|
|
79
|
+
: rowBackgrounds.active,
|
|
78
80
|
}, transition: "background 0.15s ease", borderRadius: "lg", position: "relative", onClick: () => onSelectUser === null || onSelectUser === void 0 ? void 0 : onSelectUser(user), children: [isSelected && (_jsx(Box, { position: "absolute", left: 0, top: "20%", bottom: "20%", width: "3px", borderRadius: "full", bg: colors.primary[500] })), _jsx(Avatar, { size: "sm", name: `${user.firstName} ${user.lastName}`, src: user.profile, bg: avatarBg, color: avatarColor }), _jsxs(Box, { flex: 1, overflow: "hidden", children: [_jsxs(Text, { fontSize: "sm", fontWeight: 600, noOfLines: 1, color: heading, children: [user.firstName, " ", user.lastName] }), _jsx(Text, { fontSize: "xs", color: muted, noOfLines: 1, children: user.email })] }), renderStatusBadge(user.isActive)] }, user.id));
|
|
79
81
|
}) })) })] }), _jsxs(Box, { flex: 1, backgroundColor: surface, borderRadius: "xl", boxShadow: "sm", border: "1px solid", borderColor: border, display: "flex", flexDirection: "column", order: { base: 1, lg: 2 }, overflow: "hidden", children: [_jsxs(Flex, { justifyContent: "space-between", alignItems: "center", px: 4, py: 3, borderBottom: "1px solid", borderColor: border, children: [_jsx(Heading, { size: "sm", fontWeight: 600, color: heading, children: selectedUser ? labels.userDetails : labels.selectTeamMember }), canManageUsers && (_jsx(Button, { size: "sm", colorScheme: "primary", fontSize: "xs", leftIcon: _jsx(UserPlus, { size: 15 }), onClick: onAddUserOpen, children: labels.addUser }))] }), _jsx(Box, { flex: 1, overflowY: "auto", children: isUsersLoading ? (_jsxs(VStack, { spacing: 4, p: 4, align: "stretch", children: [_jsxs(Flex, { align: "center", gap: 4, children: [_jsx(SkeletonCircle, { size: "16" }), _jsxs(Box, { flex: 1, children: [_jsx(Skeleton, { height: "18px", width: "50%", mb: 2 }), _jsx(Skeleton, { height: "12px", width: "35%" })] })] }), Array.from({ length: 4 }).map((_, idx) => (_jsxs(Box, { w: "100%", children: [_jsx(Skeleton, { height: "12px", width: "30%", mb: 2 }), _jsx(Skeleton, { height: "10px", width: "80%" })] }, idx)))] })) : selectedUser ? (_jsxs(_Fragment, { children: [_jsxs(Flex, { direction: { base: "column", md: "row" }, alignItems: { base: "flex-start", md: "center" }, justifyContent: "space-between", gap: 4, p: 4, borderBottom: "1px solid", borderColor: border, children: [_jsxs(Flex, { alignItems: "center", gap: 4, children: [_jsxs(Box, { position: "relative", children: [_jsx(Avatar, { size: "lg", name: selectedUser.name, src: selectedUser.profilePhoto, bg: avatarBg, color: avatarColor }), selectedUser.isCurrent && (_jsx(Badge, { position: "absolute", bottom: -1, right: -1, colorScheme: "blue", variant: "solid", fontSize: "0.6rem", borderRadius: "full", px: 2, py: 0.5, boxShadow: "sm", textTransform: "none", children: labels.you }))] }), _jsxs(Box, { children: [_jsx(Heading, { size: "md", mb: 1, color: heading, children: selectedUser.name }), _jsx(Text, { fontSize: "sm", color: muted, mb: 2, children: selectedUser.role }), _jsxs(HStack, { spacing: 2, children: [renderStatusBadge(selectedUser.isActive), selectedUser.isPending && (_jsx(Badge, { variant: "subtle", borderRadius: "full", px: 2, py: 0.5, fontSize: "0.65rem", fontWeight: 600, colorScheme: "orange", textTransform: "none", children: labels.pendingInvitation }))] })] })] }), canManageUsers &&
|
|
80
82
|
!selectedUser.isSuperAdmin && (_jsxs(HStack, { spacing: 2, flexWrap: "wrap", children: [!selectedUser.isCurrent && !selectedUser.isActive && (_jsx(Button, { size: "xs", variant: "outline", colorScheme: "blue", fontSize: "xs", leftIcon: _jsx(Send, { size: 13 }), isLoading: isInviteLoading, onClick: () => selectedUser.userId != null &&
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
let active = null;
|
|
2
|
+
export const exclusiveOpen = (id, close) => {
|
|
3
|
+
if (active && active.id !== id) {
|
|
4
|
+
active.close();
|
|
5
|
+
}
|
|
6
|
+
active = { id, close };
|
|
7
|
+
};
|
|
8
|
+
export const exclusiveClose = (id) => {
|
|
9
|
+
if ((active === null || active === void 0 ? void 0 : active.id) === id) {
|
|
10
|
+
active = null;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
/** Test-only reset — not exported from the package root. */
|
|
14
|
+
export const resetExclusiveOverlay = () => {
|
|
15
|
+
active = null;
|
|
16
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useCallback, useEffect, useId, useRef } from "react";
|
|
2
|
+
import { exclusiveClose, exclusiveOpen } from "./exclusiveOverlay.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register this overlay with the global dismiss coordinator. Call `requestOpen()`
|
|
5
|
+
* immediately before opening; `onClose` is invoked when another overlay opens.
|
|
6
|
+
*/
|
|
7
|
+
export const useExclusiveOverlay = (isOpen, onClose) => {
|
|
8
|
+
const id = useId();
|
|
9
|
+
const onCloseRef = useRef(onClose);
|
|
10
|
+
onCloseRef.current = onClose;
|
|
11
|
+
const requestOpen = useCallback(() => {
|
|
12
|
+
exclusiveOpen(id, () => onCloseRef.current());
|
|
13
|
+
}, [id]);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!isOpen) {
|
|
16
|
+
exclusiveClose(id);
|
|
17
|
+
}
|
|
18
|
+
}, [isOpen, id]);
|
|
19
|
+
return requestOpen;
|
|
20
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createMultiStyleConfigHelpers, cssVar } from "@chakra-ui/react";
|
|
2
2
|
import { menuAnatomy } from "@chakra-ui/anatomy";
|
|
3
|
+
import { listRowBackgrounds } from "../tokens/builders/rowStates.js";
|
|
3
4
|
import { paletteOf } from "./paletteFromTheme.js";
|
|
4
5
|
const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(menuAnatomy.keys);
|
|
5
6
|
const $bg = cssVar("menu-bg");
|
|
@@ -21,8 +22,9 @@ const $bg = cssVar("menu-bg");
|
|
|
21
22
|
const $itemBg = cssVar("menu-item-bg");
|
|
22
23
|
const baseStyle = definePartsStyle(({ theme }) => {
|
|
23
24
|
const colors = paletteOf(theme);
|
|
24
|
-
const
|
|
25
|
-
const
|
|
25
|
+
const rowBgs = listRowBackgrounds(colors);
|
|
26
|
+
const hoverBg = rowBgs.active;
|
|
27
|
+
const activeBg = rowBgs.selectedActive;
|
|
26
28
|
return {
|
|
27
29
|
list: {
|
|
28
30
|
[$bg.variable]: colors.backgroundColor.light,
|
package/dist/esm/Utils/table.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef } from "react";
|
|
2
|
-
import { DEFAULT_BLACK, DEFAULT_WHITE, isDarkCanvas, onFilled, } from "../Theme/tokens/builders/accentText.js";
|
|
2
|
+
import { AA_NORMAL_TEXT, DEFAULT_BLACK, DEFAULT_WHITE, isDarkCanvas, onFilled, } from "../Theme/tokens/builders/accentText.js";
|
|
3
|
+
import { compositeOver } from "../Theme/tokens/builders/color.js";
|
|
4
|
+
import { liftToContrast } from "../Theme/tokens/builders/outlineRung.js";
|
|
3
5
|
import { labelOnFill, solidFillRung } from "../Theme/tokens/builders/filledSurface.js";
|
|
4
|
-
import { resolveStatusTone } from "../Theme/tokens/builders/statusTone.js";
|
|
6
|
+
import { resolveAvatarFill, resolveStatusTone } from "../Theme/tokens/builders/statusTone.js";
|
|
5
7
|
// Built once, not per comparison: sorting 10k rows runs this ~130k times, and constructing a
|
|
6
8
|
// collator is orders of magnitude dearer than using one.
|
|
7
9
|
const COLLATOR = new Intl.Collator(undefined, {
|
|
@@ -54,7 +56,45 @@ export function SortMultiColumnData(data, sortConfig) {
|
|
|
54
56
|
return 0;
|
|
55
57
|
});
|
|
56
58
|
}
|
|
59
|
+
/** Theme-aware status palette per value — soft fill + semantic ink from `resolveStatusTone`. */
|
|
60
|
+
export function buildSemanticStatusPalette(toneByValue, theme) {
|
|
61
|
+
const c = theme.colors;
|
|
62
|
+
const mode = isDarkCanvas(c.backgroundColor.main) ? "dark" : "light";
|
|
63
|
+
const scales = {
|
|
64
|
+
info: c.semantic.info,
|
|
65
|
+
warning: c.semantic.warning,
|
|
66
|
+
success: c.semantic.success,
|
|
67
|
+
error: c.semantic.error,
|
|
68
|
+
neutral: c.gray,
|
|
69
|
+
};
|
|
70
|
+
return Object.fromEntries(Object.entries(toneByValue).map(([value, key]) => {
|
|
71
|
+
const scale = scales[key];
|
|
72
|
+
const tone = resolveStatusTone(scale, mode);
|
|
73
|
+
const solidRung = solidFillRung(scale, c.white);
|
|
74
|
+
const solid = scale[solidRung];
|
|
75
|
+
return [
|
|
76
|
+
value,
|
|
77
|
+
{
|
|
78
|
+
solid,
|
|
79
|
+
soft: tone.bg,
|
|
80
|
+
text: tone.fg,
|
|
81
|
+
onSolid: labelOnFill(solid, c.white, c.black),
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
57
86
|
const withAlpha = (hex, aa) => /^#([0-9a-fA-F]{6})$/.test(hex) ? `${hex}${aa}` : hex;
|
|
87
|
+
/** Consumer `statusColors` values are fill seeds — derive bleed + pill ink from them. */
|
|
88
|
+
const resolveStatusOverride = (fill, white, black, surface) => {
|
|
89
|
+
const soft = withAlpha(fill, "22");
|
|
90
|
+
const solid = resolveAvatarFill(fill);
|
|
91
|
+
return {
|
|
92
|
+
solid,
|
|
93
|
+
soft,
|
|
94
|
+
text: liftToContrast(fill, compositeOver(soft, surface), AA_NORMAL_TEXT),
|
|
95
|
+
onSolid: onFilled(solid, white, black),
|
|
96
|
+
};
|
|
97
|
+
};
|
|
58
98
|
/** Deterministic, theme-aware color palette for groups + status pills. */
|
|
59
99
|
export function buildTablePalette(theme) {
|
|
60
100
|
const c = theme.colors;
|
|
@@ -92,10 +132,12 @@ const hashKey = (value) => {
|
|
|
92
132
|
};
|
|
93
133
|
/** Pick a deterministic palette color for a value, with optional consumer override hex. */
|
|
94
134
|
export function pickTableColor(value, palette, override, theme) {
|
|
135
|
+
var _a;
|
|
95
136
|
const white = theme ? theme.colors.white : DEFAULT_WHITE;
|
|
96
137
|
const black = theme ? theme.colors.black : DEFAULT_BLACK;
|
|
97
138
|
if (override) {
|
|
98
|
-
|
|
139
|
+
const surface = (_a = theme === null || theme === void 0 ? void 0 : theme.colors.background[50]) !== null && _a !== void 0 ? _a : DEFAULT_WHITE;
|
|
140
|
+
return resolveStatusOverride(override, white, black, surface);
|
|
99
141
|
}
|
|
100
142
|
if (!palette.length) {
|
|
101
143
|
throw new Error("pickTableColor: empty palette — build it with buildTablePalette(theme).");
|
package/package.json
CHANGED