pixelize-design-library 2.4.2-beta.62 → 2.4.2-beta.63
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/CHANGELOG.md +75 -2
- package/COMPONENT-GOTCHAS.md +25 -6
- package/DESIGN-GUIDE.md +12 -5
- package/dist/Components/Button/Button.styles.js +51 -21
- package/dist/Components/Card/CardProps.d.ts +2 -2
- package/dist/Components/ConfirmDialog/ConfirmDialog.js +2 -1
- package/dist/Components/CustomModulesTable/CustomModulesTable.js +6 -4
- package/dist/Components/CustomModulesTable/EditModuleModal.js +2 -1
- package/dist/Components/DatePicker/RangeDatePicker.js +2 -1
- package/dist/Components/DatePicker/SingleDatePicker.js +2 -1
- package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -1
- package/dist/Components/DatePicker/dayStates.js +2 -1
- package/dist/Components/Drawer/Drawer.js +2 -1
- package/dist/Components/Dropdown/DropDown.js +2 -1
- package/dist/Components/FileUpload/FileUpload.js +9 -2
- package/dist/Components/FilterSidebar/FilterSidebar.js +7 -4
- package/dist/Components/KanbanBoard/AccountCard.js +4 -2
- package/dist/Components/NavigationBar/NavigationBar.js +3 -2
- package/dist/Components/Notification/Notification.js +4 -3
- package/dist/Components/NotificationBell/NotificationPanel.js +4 -3
- package/dist/Components/OrganizationDetails/CreateOrgModal.js +2 -1
- package/dist/Components/OrganizationDetails/OrganizationDetails.js +5 -3
- package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +7 -3
- package/dist/Components/SearchSelect/SearchSelect.js +42 -21
- package/dist/Components/SearchSelect/searchSelectNav.d.ts +13 -0
- package/dist/Components/SearchSelect/searchSelectNav.js +40 -0
- package/dist/Components/Select/SelectPopup.js +2 -1
- package/dist/Components/SelectSearch/SelectSearch.js +2 -1
- package/dist/Components/SettingRow/SettingRow.js +2 -1
- package/dist/Components/SettingRow/SettingsSection.js +2 -1
- package/dist/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/Components/SideBar/SideBar.js +16 -13
- package/dist/Components/SideBar/SideBarProps.d.ts +1 -1
- package/dist/Components/SideBar/components/MenuItemBox.js +7 -4
- package/dist/Components/SideBar/components/MenuPopoverContent.js +2 -1
- package/dist/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/Components/SideBar/components/PinnedSection.js +7 -4
- package/dist/Components/SideBar/sidebarMotion.d.ts +2 -0
- package/dist/Components/SideBar/sidebarMotion.js +6 -0
- package/dist/Components/SignInActivityTable/SignInActivityTable.js +6 -4
- package/dist/Components/StageProgress/StageItem.js +5 -2
- package/dist/Components/StageProgress/StepperStage.js +2 -2
- package/dist/Components/StatCard/StatCard.js +2 -1
- package/dist/Components/Table/Table.js +6 -2
- package/dist/Components/Table/components/TableActions.js +3 -2
- package/dist/Components/Table/filters/CompactSelect.js +2 -1
- package/dist/Components/Table/settings/TableSettings.js +7 -2
- package/dist/Components/Table/variants/classic.js +3 -2
- package/dist/Components/Timeline/Timeline.js +11 -4
- package/dist/Components/Toaster/Toaster.js +19 -8
- package/dist/Components/Toggle/TableToggle.js +5 -2
- package/dist/Components/UserDetails/AddUserModal.js +2 -1
- package/dist/Components/UserDetails/ChangeRoleModal.js +2 -1
- package/dist/Components/UserDetails/UserDetails.js +3 -1
- package/dist/Theme/chakra/Card.styles.d.ts +7 -1
- package/dist/Theme/chakra/Card.styles.js +4 -1
- package/dist/Theme/chakra/Menu.styles.d.ts +3 -5
- package/dist/Theme/chakra/Menu.styles.js +3 -0
- package/dist/Theme/chakra/Popover.styles.d.ts +2 -11
- package/dist/Theme/chakra/Popover.styles.js +2 -0
- package/dist/Theme/chakra/common.web.d.ts +4 -0
- package/dist/Theme/chakra/componentStyles.d.ts +11 -3
- package/dist/Theme/chakra/componentStyles.js +10 -6
- package/dist/Theme/chakra/motion.d.ts +1 -0
- package/dist/Theme/chakra/motion.js +2 -1
- package/dist/Theme/chakra/overlay.styles.d.ts +5 -0
- package/dist/Theme/chakra/overlay.styles.js +4 -1
- package/dist/Theme/themeProps.d.ts +4 -0
- package/dist/Theme/tokens/brands/index.d.ts +1 -0
- package/dist/Theme/tokens/brands/index.js +17 -1
- package/dist/Theme/tokens/brands/radiant/palette.light.js +15 -0
- package/dist/Theme/tokens/brands/rosewood/palette.light.js +10 -10
- package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +7 -29
- package/dist/Theme/tokens/brands/zinc/palette.dark.js +3 -35
- package/dist/Theme/tokens/builders/buildDarkPalette.d.ts +6 -1
- package/dist/Theme/tokens/builders/buildDarkPalette.js +37 -8
- package/dist/Theme/tokens/builders/mutedText.d.ts +1 -1
- package/dist/Theme/tokens/builders/mutedText.js +13 -3
- package/dist/Theme/tokens/builders/planeStep.d.ts +4 -0
- package/dist/Theme/tokens/builders/planeStep.js +20 -0
- package/dist/Theme/tokens/builders/planes.d.ts +4 -0
- package/dist/Theme/tokens/builders/planes.js +33 -0
- package/dist/Theme/tokens/builders/skeletonShimmer.d.ts +9 -0
- package/dist/Theme/tokens/builders/skeletonShimmer.js +25 -0
- package/dist/Theme/tokens/builders/surfaceRaised.d.ts +3 -1
- package/dist/Theme/tokens/builders/surfaceRaised.js +18 -8
- package/dist/Theme/tokens/builders/surfaceRungs.js +3 -1
- package/dist/Theme/tokens/primitives/index.d.ts +2 -2
- package/dist/Theme/tokens/primitives/index.js +4 -1
- package/dist/Theme/tokens/primitives/motion.d.ts +1 -0
- package/dist/Theme/tokens/primitives/motion.js +2 -1
- package/dist/Theme/tokens/primitives/shadows.d.ts +16 -0
- package/dist/Theme/tokens/primitives/shadows.js +56 -6
- package/dist/Theme/tokens/primitives/typography.js +1 -1
- package/dist/esm/Components/Button/Button.styles.js +54 -24
- package/dist/esm/Components/ConfirmDialog/ConfirmDialog.js +2 -1
- package/dist/esm/Components/CustomModulesTable/CustomModulesTable.js +6 -4
- package/dist/esm/Components/CustomModulesTable/EditModuleModal.js +2 -1
- package/dist/esm/Components/DatePicker/RangeDatePicker.js +2 -1
- package/dist/esm/Components/DatePicker/SingleDatePicker.js +2 -1
- package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +2 -1
- package/dist/esm/Components/DatePicker/dayStates.js +2 -1
- package/dist/esm/Components/Drawer/Drawer.js +2 -1
- package/dist/esm/Components/Dropdown/DropDown.js +2 -1
- package/dist/esm/Components/FileUpload/FileUpload.js +10 -3
- package/dist/esm/Components/FilterSidebar/FilterSidebar.js +7 -4
- package/dist/esm/Components/KanbanBoard/AccountCard.js +4 -2
- package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -2
- package/dist/esm/Components/Notification/Notification.js +4 -3
- package/dist/esm/Components/NotificationBell/NotificationPanel.js +4 -3
- package/dist/esm/Components/OrganizationDetails/CreateOrgModal.js +2 -1
- package/dist/esm/Components/OrganizationDetails/OrganizationDetails.js +5 -3
- package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +7 -3
- package/dist/esm/Components/SearchSelect/SearchSelect.js +42 -21
- package/dist/esm/Components/SearchSelect/searchSelectNav.js +32 -0
- package/dist/esm/Components/Select/SelectPopup.js +2 -1
- package/dist/esm/Components/SelectSearch/SelectSearch.js +2 -1
- package/dist/esm/Components/SettingRow/SettingRow.js +2 -1
- package/dist/esm/Components/SettingRow/SettingsSection.js +2 -1
- package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/esm/Components/SideBar/SideBar.js +17 -14
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +7 -4
- package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +2 -1
- package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/esm/Components/SideBar/components/PinnedSection.js +7 -4
- package/dist/esm/Components/SideBar/sidebarMotion.js +3 -0
- package/dist/esm/Components/SignInActivityTable/SignInActivityTable.js +6 -4
- package/dist/esm/Components/StageProgress/StageItem.js +5 -2
- package/dist/esm/Components/StageProgress/StepperStage.js +2 -2
- package/dist/esm/Components/StatCard/StatCard.js +2 -1
- package/dist/esm/Components/Table/Table.js +8 -4
- package/dist/esm/Components/Table/components/TableActions.js +3 -2
- package/dist/esm/Components/Table/filters/CompactSelect.js +2 -1
- package/dist/esm/Components/Table/settings/TableSettings.js +8 -3
- package/dist/esm/Components/Table/variants/classic.js +3 -2
- package/dist/esm/Components/Timeline/Timeline.js +11 -4
- package/dist/esm/Components/Toaster/Toaster.js +20 -9
- package/dist/esm/Components/Toggle/TableToggle.js +5 -2
- package/dist/esm/Components/UserDetails/AddUserModal.js +2 -1
- package/dist/esm/Components/UserDetails/ChangeRoleModal.js +2 -1
- package/dist/esm/Components/UserDetails/UserDetails.js +3 -1
- package/dist/esm/Theme/chakra/Card.styles.js +4 -1
- package/dist/esm/Theme/chakra/Menu.styles.js +3 -0
- package/dist/esm/Theme/chakra/Popover.styles.js +2 -0
- package/dist/esm/Theme/chakra/componentStyles.js +10 -6
- package/dist/esm/Theme/chakra/motion.js +1 -0
- package/dist/esm/Theme/chakra/overlay.styles.js +3 -0
- package/dist/esm/Theme/tokens/brands/index.js +16 -0
- package/dist/esm/Theme/tokens/brands/radiant/palette.light.js +15 -0
- package/dist/esm/Theme/tokens/brands/rosewood/palette.light.js +10 -10
- package/dist/esm/Theme/tokens/brands/zinc/palette.dark.js +3 -35
- package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +38 -9
- package/dist/esm/Theme/tokens/builders/mutedText.js +12 -2
- package/dist/esm/Theme/tokens/builders/planeStep.js +14 -0
- package/dist/esm/Theme/tokens/builders/planes.js +28 -0
- package/dist/esm/Theme/tokens/builders/skeletonShimmer.js +21 -0
- package/dist/esm/Theme/tokens/builders/surfaceRaised.js +16 -7
- package/dist/esm/Theme/tokens/builders/surfaceRungs.js +3 -1
- package/dist/esm/Theme/tokens/primitives/index.js +1 -1
- package/dist/esm/Theme/tokens/primitives/motion.js +1 -0
- package/dist/esm/Theme/tokens/primitives/shadows.js +54 -5
- package/dist/esm/Theme/tokens/primitives/typography.js +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +9 -5
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import React, { forwardRef, useEffect, useId, useLayoutEffect, useRef, useState
|
|
|
3
3
|
import { Button, IconButton, Popover, PopoverAnchor, PopoverBody, PopoverContent, Portal, VStack, } from "@chakra-ui/react";
|
|
4
4
|
import { EllipsisVertical, ExternalLink, Pencil, Trash2 } from "lucide-react";
|
|
5
5
|
import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
6
|
+
import { raisedRule } from "../../../Theme/tokens/builders/surfaceRaised.js";
|
|
6
7
|
const assignRef = (ref, value) => {
|
|
7
8
|
if (typeof ref === "function")
|
|
8
9
|
ref(value);
|
|
@@ -53,11 +54,11 @@ const TableActions = React.memo(({ row }) => {
|
|
|
53
54
|
// ✅ if row itself is missing, render nothing
|
|
54
55
|
if (!row)
|
|
55
56
|
return null;
|
|
56
|
-
return (_jsxs("div", { ref: ref, children: [_jsx(IconButton, { ref: triggerRef, id: `popover-trigger-${popoverId}`, "aria-label": "Actions", "aria-haspopup": "dialog", "aria-expanded": isOpen, "aria-controls": `popover-content-${popoverId}`, color: theme.colors.text[900], icon: _jsx(EllipsisVertical, { size: 17 }), size: "sm", p: 0, variant: "ghost", _hover: { transform: "scale(1.2)" }, onClick: () => (isOpen ? handleClose() : handleOpen()) }), isOpen && (_jsxs(Popover, { id: popoverId, placement: "bottom-start", isOpen: true, onClose: handleClose, closeOnBlur: false, returnFocusOnClose: false, children: [_jsx(PopoverAnchor, { children: _jsx(TriggerAnchor, { target: triggerRef }) }), _jsx(Portal, { children: _jsx(PopoverContent, { w: "auto", minW: "100px", boxShadow: "lg", p: 0, zIndex: 999, bg: theme.colors.surfaceRaised, children: _jsx(PopoverBody, { p: 0, m: 0, children: _jsxs(VStack, { align: "stretch", spacing: 1, p: 0, m: 0, children: [row.onLink && (_jsxs(Button, { size: "sm", variant: "ghost", justifyContent: "flex-start", borderBottom: `1px solid ${theme.colors
|
|
57
|
+
return (_jsxs("div", { ref: ref, children: [_jsx(IconButton, { ref: triggerRef, id: `popover-trigger-${popoverId}`, "aria-label": "Actions", "aria-haspopup": "dialog", "aria-expanded": isOpen, "aria-controls": `popover-content-${popoverId}`, color: theme.colors.text[900], icon: _jsx(EllipsisVertical, { size: 17 }), size: "sm", p: 0, variant: "ghost", _hover: { transform: "scale(1.2)" }, onClick: () => (isOpen ? handleClose() : handleOpen()) }), isOpen && (_jsxs(Popover, { id: popoverId, placement: "bottom-start", isOpen: true, onClose: handleClose, closeOnBlur: false, returnFocusOnClose: false, children: [_jsx(PopoverAnchor, { children: _jsx(TriggerAnchor, { target: triggerRef }) }), _jsx(Portal, { children: _jsx(PopoverContent, { w: "auto", minW: "100px", boxShadow: "lg", p: 0, zIndex: 999, bg: theme.colors.surfaceRaised, children: _jsx(PopoverBody, { p: 0, m: 0, children: _jsxs(VStack, { align: "stretch", spacing: 1, p: 0, m: 0, children: [row.onLink && (_jsxs(Button, { size: "sm", variant: "ghost", justifyContent: "flex-start", borderBottom: `1px solid ${raisedRule(theme.colors)}`, borderRadius: 0, gap: 2, onClick: () => {
|
|
57
58
|
var _a;
|
|
58
59
|
(_a = row.onLink) === null || _a === void 0 ? void 0 : _a.call(row, row);
|
|
59
60
|
handleClose();
|
|
60
|
-
}, children: [_jsx(ExternalLink, { size: 17 }), " View"] })), row.onEdit && (_jsxs(Button, { size: "sm", variant: "ghost", justifyContent: "flex-start", gap: 2, borderBottom: `1px solid ${theme.colors
|
|
61
|
+
}, children: [_jsx(ExternalLink, { size: 17 }), " View"] })), row.onEdit && (_jsxs(Button, { size: "sm", variant: "ghost", justifyContent: "flex-start", gap: 2, borderBottom: `1px solid ${raisedRule(theme.colors)}`, borderRadius: 0, onClick: () => {
|
|
61
62
|
var _a;
|
|
62
63
|
(_a = row.onEdit) === null || _a === void 0 ? void 0 : _a.call(row, row);
|
|
63
64
|
handleClose();
|
|
@@ -3,6 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
3
3
|
import { Box, Text, Input, Popover, PopoverTrigger, PopoverContent, PopoverBody, VStack, Portal } from "@chakra-ui/react";
|
|
4
4
|
import { ChevronDown, ChevronUp, Check } from "lucide-react";
|
|
5
5
|
import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
6
|
+
import { raisedRule } from "../../../Theme/tokens/builders/surfaceRaised.js";
|
|
6
7
|
import { listRowBackgrounds } from "../../../Theme/tokens/builders/rowStates.js";
|
|
7
8
|
import { optionRowSpec, OPTION_ROW_RADIUS } from "../../../Theme/tokens/primitives/optionRowSizes.js";
|
|
8
9
|
import { optionRowInk, optionRowWeight } from "../../Select/optionRowInk.js";
|
|
@@ -54,7 +55,7 @@ const CompactSelect = ({ options, value, placeholder = "Select", height = "22px"
|
|
|
54
55
|
e.preventDefault();
|
|
55
56
|
focusOption(0);
|
|
56
57
|
}
|
|
57
|
-
}, sx: { fontSize: "0.75rem", height: "22px" } }), _jsxs(Box, { role: "listbox", "aria-label": placeholder, maxH: "12rem", overflowY: "auto", borderTop: "1px solid", borderColor: theme.colors
|
|
58
|
+
}, sx: { fontSize: "0.75rem", height: "22px" } }), _jsxs(Box, { role: "listbox", "aria-label": placeholder, maxH: "12rem", overflowY: "auto", borderTop: "1px solid", borderColor: raisedRule(theme.colors), onKeyDown: handleListKeyDown, children: [filtered.map((opt, i) => {
|
|
58
59
|
const selected = (value === null || value === void 0 ? void 0 : value.id) === opt.id;
|
|
59
60
|
const isActive = i === activeIndex;
|
|
60
61
|
const rowBg = selected
|
|
@@ -5,13 +5,17 @@ import { motion } from "framer-motion";
|
|
|
5
5
|
import ManageColumns from "./ManageColumns.js";
|
|
6
6
|
import Button from "../../Button/Button.js";
|
|
7
7
|
import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
8
|
+
import { raisedRule } from "../../../Theme/tokens/builders/surfaceRaised.js";
|
|
8
9
|
import { scrollbarStyles } from "../../../Theme/tokens/builders/scrollbar.js";
|
|
9
10
|
import { columnLabelText } from "../columnLabel.js";
|
|
10
11
|
import { Settings, Check } from "lucide-react";
|
|
11
12
|
import ToolTip from "../../ToolTip/ToolTip.js";
|
|
12
13
|
import { listRowBackgrounds } from "../../../Theme/tokens/builders/rowStates.js";
|
|
13
|
-
import { transitionFor } from "../../../Theme/tokens/primitives/motion.js";
|
|
14
|
+
import { motionTransition, transitionFor } from "../../../Theme/tokens/primitives/motion.js";
|
|
15
|
+
import { usePrefersReducedMotion } from "../../../Theme/chakra/motion.js";
|
|
14
16
|
const MotionModalContent = motion(ModalContent);
|
|
17
|
+
const SHEET_ENTER = motionTransition("enter", "out");
|
|
18
|
+
const SHEET_EXIT = motionTransition("exit", "in");
|
|
15
19
|
const DENSITY_OPTIONS = [
|
|
16
20
|
{ value: "compact", label: "Compact", desc: "Tight rows — fit more data on screen" },
|
|
17
21
|
{ value: "normal", label: "Normal", desc: "Balanced default spacing" },
|
|
@@ -19,6 +23,7 @@ const DENSITY_OPTIONS = [
|
|
|
19
23
|
];
|
|
20
24
|
const TableSettings = ({ columns, onSave, density = "normal", onDensityChange, groupBy, }) => {
|
|
21
25
|
const theme = useCustomTheme();
|
|
26
|
+
const sheetOffset = usePrefersReducedMotion() ? 0 : "-100%";
|
|
22
27
|
const rowBackgrounds = useMemo(() => listRowBackgrounds(theme.colors), [theme.colors]);
|
|
23
28
|
const childInputMethodsRef = useRef({});
|
|
24
29
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
@@ -52,7 +57,7 @@ const TableSettings = ({ columns, onSave, density = "normal", onDensityChange, g
|
|
|
52
57
|
return (_jsxs(Box, { children: [_jsx(ToolTip, { label: "Table Settings", placement: "top", children: _jsx(IconButton, { "aria-label": "Table settings", icon: _jsx(Settings, { size: "1.25rem" }), onClick: handleOpen, variant: "unstyled", minW: "auto", h: "auto", display: "flex", justifyContent: "flex-end", cursor: "pointer", transition: transitionFor(["color", "transform"], "base"), color: theme.colors.text[500], _hover: {
|
|
53
58
|
transform: "scale(1.1)",
|
|
54
59
|
color: theme.colors.accentText
|
|
55
|
-
} }) }), _jsxs(Modal, { isOpen: settingsOpen, onClose: () => setSettingsOpen(false), size: { base: "full", md: "md" }, children: [_jsx(ModalOverlay, {}), _jsxs(MotionModalContent, { mt: "0", top: "0", left: { base: 0, md: "auto" }, right: { base: 0, md: "auto" }, position: "absolute", borderTopRadius: "none", initial: { y:
|
|
60
|
+
} }) }), _jsxs(Modal, { isOpen: settingsOpen, onClose: () => setSettingsOpen(false), size: { base: "full", md: "md" }, children: [_jsx(ModalOverlay, {}), _jsxs(MotionModalContent, { mt: "0", top: "0", left: { base: 0, md: "auto" }, right: { base: 0, md: "auto" }, position: "absolute", borderTopRadius: "none", initial: { y: sheetOffset, opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: sheetOffset, opacity: 0, transition: SHEET_EXIT }, transition: SHEET_ENTER, padding: "0", minW: { base: "auto", md: "620px" }, minH: { base: "auto", md: "520px" }, maxH: "90vh", display: "flex", flexDirection: "column", bg: theme.colors.surfaceRaised, 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: raisedRule(theme.colors), 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) => {
|
|
56
61
|
const selected = density === opt.value;
|
|
57
62
|
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: transitionFor(["background-color", "border-color"]), _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));
|
|
58
63
|
}) }) }), _jsx(TabPanel, { px: 0, py: 0, children: _jsx(Box, { sx: {
|
|
@@ -73,6 +78,6 @@ const TableSettings = ({ columns, onSave, density = "normal", onDensityChange, g
|
|
|
73
78
|
var _a;
|
|
74
79
|
const selected = selectedGroup === opt.id;
|
|
75
80
|
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: transitionFor(["background-color", "border-color"]), _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__")));
|
|
76
|
-
}) })] })] }) })] }), _jsxs(ModalFooter, { gap: "0.5rem", borderTop: "1px solid", borderColor: theme.colors
|
|
81
|
+
}) })] })] }) })] }), _jsxs(ModalFooter, { gap: "0.5rem", borderTop: "1px solid", borderColor: raisedRule(theme.colors), 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 })] })] })] })] }));
|
|
77
82
|
};
|
|
78
83
|
export default TableSettings;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { accentTextOnCanvas } from "../../../Theme/tokens/builders/accentText.js";
|
|
2
|
+
import { cardRule } from "../../../Theme/tokens/builders/planeStep.js";
|
|
2
3
|
import { getTableRowHoverStyle } from "../components/tableRowHoverStyle.js";
|
|
3
4
|
import { stripeFill } from "./stripe.js";
|
|
4
5
|
/**
|
|
@@ -16,14 +17,14 @@ export const classicPreset = (colors, isDark) => {
|
|
|
16
17
|
textTransform: "capitalize",
|
|
17
18
|
letterSpacing: "normal",
|
|
18
19
|
height: "45px",
|
|
19
|
-
ruleColor: colors
|
|
20
|
+
ruleColor: cardRule(colors),
|
|
20
21
|
showColumnRule: true,
|
|
21
22
|
actions: "always",
|
|
22
23
|
},
|
|
23
24
|
row: {
|
|
24
25
|
hoverBg: getTableRowHoverStyle(colors, isDark).backgroundColor,
|
|
25
26
|
hoverScope: "cell",
|
|
26
|
-
ruleColor: colors
|
|
27
|
+
ruleColor: cardRule(colors),
|
|
27
28
|
frozenRuleColor: colors.boxborder[300],
|
|
28
29
|
selectedBg: colors.primary.opacity[16],
|
|
29
30
|
selectedBarColor: colors.primary[500],
|
|
@@ -4,6 +4,7 @@ import { ArrowRight, FileText, IndianRupee, Paperclip, Pencil, PencilLine, Plus,
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
6
6
|
import { accentTextOnCanvas } from "../../Theme/tokens/builders/accentText.js";
|
|
7
|
+
import { bandOn } from "../../Theme/tokens/builders/planeStep.js";
|
|
7
8
|
import { AA_NON_TEXT, liftToContrast } from "../../Theme/tokens/builders/outlineRung.js";
|
|
8
9
|
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
9
10
|
import { BORDER_WIDTHS } from "../../Theme/tokens/primitives/borderWidths.js";
|
|
@@ -152,12 +153,14 @@ const NoteItem = React.memo(function NoteItem({ note, event, index, colors, acti
|
|
|
152
153
|
var _a, _b;
|
|
153
154
|
const isEditing = activeEditNoteId === note.log_note_id;
|
|
154
155
|
const isDeleting = deletingNoteId != null && deletingNoteId === note.log_note_id;
|
|
156
|
+
const noteChip = bandOn(colors.primary[50], colors.gray[50]);
|
|
157
|
+
const noteChipInk = accentTextOnCanvas(colors.primary, noteChip);
|
|
155
158
|
if (isEditing) {
|
|
156
159
|
return (_jsx(Box, { children: _jsx(NoteTextArea, { isEditable: true, value: (_a = note.note) !== null && _a !== void 0 ? _a : "", title: (_b = note.title) !== null && _b !== void 0 ? _b : "", saveButtonLoading: editNoteLoading, handleSubmit: (n, t, f) => onEditNote === null || onEditNote === void 0 ? void 0 : onEditNote(note.log_note_id, n, t, f, event, index), handleCancel: () => setActiveEditNoteId(null) }) }));
|
|
157
160
|
}
|
|
158
161
|
return (_jsxs(Box, { position: "relative", zIndex: 1, bg: colors.gray[50], border: `${BORDER_WIDTHS.hairline} solid ${colors.boxborder[200]}`, borderRadius: "lg", px: 2.5, py: 2, opacity: isDeleting ? 0.6 : 1, _hover: { ".timeline-note-actions": { opacity: 1 } }, _focusWithin: { ".timeline-note-actions": { opacity: 1 } }, children: [_jsxs(Flex, { align: "center", gap: 1.5, mb: note.note ? 1 : 0, children: [_jsx(Box, { as: "span", color: accentTextOnCanvas(colors.primary, colors.gray[50]), display: "inline-flex", children: _jsx(StickyNote, { size: 12 }) }), note.title && (_jsx(Text, { fontSize: fontSizes["xs-minus"], fontWeight: 700, color: colors.text[800], noOfLines: 1, children: note.title })), (onEditNote || onDeleteNote) && (_jsx(Flex, { className: "timeline-note-actions", align: "center", gap: 0.5, ml: "auto", flexShrink: 0, opacity: isDeleting ? 1 : 0, transition: REVEAL_TRANSITION, sx: reducedMotionSx(), children: isDeleting ? (_jsx(Spinner, { size: "xs", color: colors.textMuted })) : (_jsxs(_Fragment, { children: [onEditNote && (_jsx(Tooltip, { label: "Edit", placement: "top", hasArrow: true, children: _jsx(Box, { as: "button", type: "button", "aria-label": "Edit note", sx: focusVisibleStyles(colors), display: "inline-flex", alignItems: "center", justifyContent: "center", p: 1, borderRadius: "md", color: colors.textMuted, bg: "transparent", cursor: "pointer", _hover: {
|
|
159
|
-
bg:
|
|
160
|
-
color:
|
|
162
|
+
bg: noteChip,
|
|
163
|
+
color: noteChipInk,
|
|
161
164
|
}, onClick: (e) => {
|
|
162
165
|
e.stopPropagation();
|
|
163
166
|
setActiveEditNoteId(note.log_note_id);
|
|
@@ -167,7 +170,7 @@ const NoteItem = React.memo(function NoteItem({ note, event, index, colors, acti
|
|
|
167
170
|
}, onClick: (e) => {
|
|
168
171
|
e.stopPropagation();
|
|
169
172
|
onDeleteNote === null || onDeleteNote === void 0 ? void 0 : onDeleteNote(note.log_note_id, event, index);
|
|
170
|
-
}, children: _jsx(Trash2, { size: 12 }) }) }))] })) }))] }), note.note && (_jsx(Text, { fontSize: fontSizes["xs-minus"], color: colors.text[700], whiteSpace: "pre-wrap", children: note.note })), note.attachments && note.attachments.length > 0 && (_jsx(Flex, { wrap: "wrap", gap: 1.5, mt: 1.5, children: note.attachments.map((att, attIndex) => (_jsxs(Flex, { as: "a", href: att.url, target: "_blank", rel: "noopener noreferrer", onClick: (e) => e.stopPropagation(), align: "center", gap: 1, px: 1.5, py: 0.5, borderRadius: "full", bg:
|
|
173
|
+
}, children: _jsx(Trash2, { size: 12 }) }) }))] })) }))] }), note.note && (_jsx(Text, { fontSize: fontSizes["xs-minus"], color: colors.text[700], whiteSpace: "pre-wrap", children: note.note })), note.attachments && note.attachments.length > 0 && (_jsx(Flex, { wrap: "wrap", gap: 1.5, mt: 1.5, children: note.attachments.map((att, attIndex) => (_jsxs(Flex, { as: "a", href: att.url, target: "_blank", rel: "noopener noreferrer", onClick: (e) => e.stopPropagation(), align: "center", gap: 1, px: 1.5, py: 0.5, borderRadius: "full", bg: noteChip, color: noteChipInk, fontSize: MIN_TEXT, maxW: "100%", _hover: { bg: colors.primary[100] }, children: [_jsx(Paperclip, { size: 10 }), _jsx(Box, { as: "span", noOfLines: 1, maxW: "9rem", children: att.name || "attachment" })] }, attIndex))) })), (note.created_by || note.created_at) && (_jsxs(Text, { fontSize: MIN_TEXT, color: colors.textMuted, mt: 1, children: [note.created_by ? formatName(note.created_by) : "", note.created_by && note.created_at ? " · " : "", note.created_at ? formatTimestamp(note.created_at, "time") : ""] }))] }));
|
|
171
174
|
});
|
|
172
175
|
// The colored event card (shared by both the desktop "tree" and mobile rail).
|
|
173
176
|
// `accent` decides which edge carries the colored bar (pointing toward the spine).
|
|
@@ -177,6 +180,7 @@ const EventCard = React.memo(function EventCard({ event, index, accent, colors,
|
|
|
177
180
|
const changes = useMemo(() => parseChanges(event.changes), [event.changes]);
|
|
178
181
|
const clickable = typeof onEventClick === "function";
|
|
179
182
|
const actor = formatName(event.action_by);
|
|
183
|
+
const addNoteHover = bandOn(colors.primary[50], colors.background[50]);
|
|
180
184
|
return (_jsxs(Box, { _hover: { ".timeline-add-note": { opacity: 1 } }, _focusWithin: { ".timeline-add-note": { opacity: 1 } }, children: [_jsxs(Box, { position: "relative", zIndex: 1, bg: colors.background[50], border: `${BORDER_WIDTHS.hairline} solid ${colors.boxborder[200]}`, borderInlineStartWidth: accent === "left" ? "0.1875rem" : undefined, borderInlineEndWidth: accent === "right" ? "0.1875rem" : undefined, borderInlineStartColor: accent === "left" ? scale[400] : undefined, borderInlineEndColor: accent === "right" ? scale[400] : undefined, borderRadius: "xl", px: 3.5, py: 2.5, ...(clickable && {
|
|
181
185
|
transition: CARD_TRANSITION,
|
|
182
186
|
_hover: {
|
|
@@ -189,7 +193,10 @@ const EventCard = React.memo(function EventCard({ event, index, accent, colors,
|
|
|
189
193
|
e.stopPropagation();
|
|
190
194
|
setActiveNoteEventIndex(isActiveNote ? null : index);
|
|
191
195
|
}, position: "relative", zIndex: 1, opacity: isActiveNote ? 1 : 0, transition: REVEAL_TRANSITION, sx: { ...focusVisibleStyles(colors), ...reducedMotionSx() }, px: 2, py: 1, borderRadius: "md", fontSize: fontSizes.xs, fontWeight: 600, color: accentTextOnCanvas(colors.primary, colors.background[50]), bg: "transparent", cursor: "pointer", _hover: {
|
|
192
|
-
bg:
|
|
196
|
+
bg: addNoteHover,
|
|
197
|
+
color: addNoteHover === colors.primary[50]
|
|
198
|
+
? undefined
|
|
199
|
+
: accentTextOnCanvas(colors.primary, addNoteHover),
|
|
193
200
|
}, children: isActiveNote ? "Hide note" : "Add note" }))] }), event.notes && event.notes.length > 0 && (_jsx(Flex, { direction: "column", gap: 2, mt: 2, pt: 2, borderTop: `${BORDER_WIDTHS.hairline} solid ${colors.boxborder[200]}`, children: event.notes.map((note, noteIndex) => {
|
|
194
201
|
var _a;
|
|
195
202
|
return (_jsx(NoteItem, { note: note, event: event, index: index, colors: colors, activeEditNoteId: activeEditNoteId, setActiveEditNoteId: setActiveEditNoteId, editNoteLoading: editNoteLoading, deletingNoteId: deletingNoteId, onEditNote: onEditNote, onDeleteNote: onDeleteNote }, (_a = note.log_note_id) !== null && _a !== void 0 ? _a : noteIndex));
|
|
@@ -7,9 +7,10 @@ import { CheckCircle2, AlertTriangle, Info, XCircle, } from "lucide-react";
|
|
|
7
7
|
import Spinner from "../Spinner/Spinner.js";
|
|
8
8
|
import { toastDuration } from "./toastDuration.js";
|
|
9
9
|
import { REDUCED_MOTION_QUERY, reducedMotionSx } from "../../Theme/chakra/motion.js";
|
|
10
|
-
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
10
|
+
import { motionTransition, transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
11
11
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
12
12
|
import { resolveSoftTone } from "../../Theme/tokens/builders/tone.js";
|
|
13
|
+
import { compositeOver } from "../../Theme/tokens/builders/color.js";
|
|
13
14
|
const ToasterContext = createContext(undefined);
|
|
14
15
|
const shrink = keyframes `
|
|
15
16
|
from { transform: scaleX(1); }
|
|
@@ -17,11 +18,13 @@ const shrink = keyframes `
|
|
|
17
18
|
`;
|
|
18
19
|
// One-shot ring pulse on the status icon — a subtle "just happened" beat.
|
|
19
20
|
const iconPulse = keyframes `
|
|
20
|
-
0% {
|
|
21
|
-
70% {
|
|
22
|
-
100% {
|
|
21
|
+
0% { transform: scale(1); opacity: 1; }
|
|
22
|
+
70% { transform: scale(1.5); opacity: 0; }
|
|
23
|
+
100% { transform: scale(1.5); opacity: 0; }
|
|
23
24
|
`;
|
|
24
25
|
const MotionBox = motion(Box);
|
|
26
|
+
const TOAST_ENTER = motionTransition("enter", "out");
|
|
27
|
+
const TOAST_EXIT = motionTransition("exit", "in");
|
|
25
28
|
// Presentational toast card — owns hover state so auto-dismiss pauses while the pointer is over it.
|
|
26
29
|
function ToastCard({ onClose, title, description, actions, isClosable, duration, meta, colors: c, isUrgent, }) {
|
|
27
30
|
const [paused, setPaused] = useState(false);
|
|
@@ -33,15 +36,23 @@ function ToastCard({ onClose, title, description, actions, isClosable, duration,
|
|
|
33
36
|
, {
|
|
34
37
|
// The single live-region root: an explicit aria-live here, on the card's own
|
|
35
38
|
// root, keeps errors from being announced a second time by a duplicate wrapper.
|
|
36
|
-
role: isUrgent ? "alert" : undefined, "aria-live": isUrgent ? "assertive" : undefined, initial: { opacity: 0, x: 24 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 24
|
|
39
|
+
role: isUrgent ? "alert" : undefined, "aria-live": isUrgent ? "assertive" : undefined, initial: { opacity: 0, x: 24 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 24, transition: TOAST_EXIT }, transition: TOAST_ENTER, onHoverStart: () => setPaused(true), onHoverEnd: () => setPaused(false), position: "relative", bg: c.surfaceRaised, border: `0.0625rem solid ${c.boxborder[200]}`, boxShadow: "md", borderRadius: "xl", overflow: "hidden", minW: "22.5rem", maxW: "26rem", sx: {
|
|
37
40
|
isolation: "isolate",
|
|
38
41
|
transition: transitionFor(["box-shadow"]),
|
|
39
42
|
_hover: { boxShadow: "lg" },
|
|
40
43
|
...reducedMotionSx(),
|
|
41
|
-
}, children: [_jsxs(Flex, { p: 3.5, gap: 3, align: actions ? "flex-start" : "center", children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "2rem", minW: "2rem", borderRadius: "full", bg: tone.bg, color: tone.fg, sx: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
}, children: [_jsxs(Flex, { p: 3.5, gap: 3, align: actions ? "flex-start" : "center", children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "2rem", minW: "2rem", borderRadius: "full", position: "relative", bg: compositeOver(tone.bg, c.surfaceRaised), color: tone.fg, sx: {
|
|
45
|
+
"&::after": {
|
|
46
|
+
content: '""',
|
|
47
|
+
position: "absolute",
|
|
48
|
+
inset: 0,
|
|
49
|
+
borderRadius: "full",
|
|
50
|
+
bg: tone.border,
|
|
51
|
+
zIndex: -1,
|
|
52
|
+
opacity: 0,
|
|
53
|
+
animation: `${iconPulse} 900ms ease-out 1`,
|
|
54
|
+
...reducedMotionSx(),
|
|
55
|
+
},
|
|
45
56
|
}, children: meta.icon }), _jsxs(VisuallyHidden, { children: [meta.label, ":"] }), _jsxs(Box, { flex: "1", minW: 0, children: [title && (_jsx(Text, { fontWeight: 600, fontSize: "0.875rem", lineHeight: "1.3", color: c.text[800], children: title })), description && (_jsx(Text, { fontSize: "0.8125rem", lineHeight: "1.45", color: c.textMuted, mt: title ? "0.125rem" : 0, children: description })), actions && (_jsx(Flex, { gap: 2, mt: 2.5, align: "center", wrap: "wrap", children: actions(onClose) }))] }), isClosable && (_jsx(CloseButton, { onClick: onClose, size: "sm", color: c.textMuted, borderRadius: "md", alignSelf: "flex-start", _hover: {
|
|
46
57
|
bg: c.gray[100],
|
|
47
58
|
color: c.text[700],
|
|
@@ -8,9 +8,12 @@ import ToolTip from "../ToolTip/ToolTip.js";
|
|
|
8
8
|
import { useSlidingPill } from "../SegmentedControl/useSlidingPill.js";
|
|
9
9
|
import { BUTTON_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
|
|
10
10
|
import { BORDER_WIDTHS } from "../../Theme/tokens/primitives/borderWidths.js";
|
|
11
|
+
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
11
12
|
const MODES = ["grid", "list"];
|
|
12
13
|
const TRACK_HEIGHT = BUTTON_SIZES.sm.height;
|
|
13
14
|
const SEGMENT_HEIGHT = `calc(${TRACK_HEIGHT} - 0.25rem)`;
|
|
15
|
+
const INK_TRANSITION = transitionFor(["color"], "base");
|
|
16
|
+
const PILL_TRANSITION = transitionFor(["transform", "width"], "base", "out");
|
|
14
17
|
/** Two icon-only IconButtons (Grid/List), aria-pressed marks the active one; shares variant with SegmentedControl (see MODULE.md). */
|
|
15
18
|
const TableToggle = ({ value, onChange, variant = "default" }) => {
|
|
16
19
|
const theme = useCustomTheme();
|
|
@@ -71,10 +74,10 @@ const TableToggle = ({ value, onChange, variant = "default" }) => {
|
|
|
71
74
|
? colors.accentText
|
|
72
75
|
: hoverInk,
|
|
73
76
|
},
|
|
74
|
-
transition:
|
|
77
|
+
transition: INK_TRANSITION,
|
|
75
78
|
}),
|
|
76
79
|
};
|
|
77
|
-
return (_jsxs(Box, { ref: trackRef, ...styles.container, children: [isBrandSlide && pill && (_jsx(Box, { "aria-hidden": "true", position: "absolute", top: "0.125rem", left: 0, h: SEGMENT_HEIGHT, w: `${pill.width}px`, borderRadius: "lg", bg: brandFill.fill, boxShadow: `0 0.125rem 0.5rem ${colors.boxShadow.primary}`, transform: `translateX(${pill.left}px)`, transition:
|
|
80
|
+
return (_jsxs(Box, { ref: trackRef, ...styles.container, children: [isBrandSlide && pill && (_jsx(Box, { "aria-hidden": "true", position: "absolute", top: "0.125rem", left: 0, h: SEGMENT_HEIGHT, w: `${pill.width}px`, borderRadius: "lg", bg: brandFill.fill, boxShadow: `0 0.125rem 0.5rem ${colors.boxShadow.primary}`, transform: `translateX(${pill.left}px)`, transition: PILL_TRANSITION })), isUnderlineSlide && pill && (_jsx(Box, { "aria-hidden": "true", position: "absolute", bottom: `-${BORDER_WIDTHS.hairline}`, left: 0, h: "0.125rem", w: `${pill.width}px`, borderRadius: "full", bg: colors.primary[500], transform: `translateX(${pill.left}px)`, transition: PILL_TRANSITION })), _jsx(ToolTip, { label: "Grid View", placement: "top", fontSize: "xs", hasArrow: true, children: _jsx(IconButton, { ref: (node) => {
|
|
78
81
|
refs.current[0] = node;
|
|
79
82
|
}, "aria-label": "Grid View", "aria-pressed": value === "grid", icon: _jsx(Table2, { size: "1.25rem" }), variant: "ghost", onClick: () => onChange("grid"), ...styles.button("grid") }) }), _jsx(ToolTip, { label: "List View", placement: "top", fontSize: "xs", hasArrow: true, children: _jsx(IconButton, { ref: (node) => {
|
|
80
83
|
refs.current[1] = node;
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, ModalFooter, FormControl, VStack, } from "@chakra-ui/react";
|
|
4
4
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
|
+
import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
|
|
5
6
|
import Button from "../Button/Button.js";
|
|
6
7
|
import TextInput from "../Input/TextInput.js";
|
|
7
8
|
import SearchSelect from "../SearchSelect/SearchSelect.js";
|
|
@@ -75,7 +76,7 @@ const AddUserModal = ({ isOpen, onClose, roleOptions, isLoading, onSubmit, onAdd
|
|
|
75
76
|
type: "email",
|
|
76
77
|
},
|
|
77
78
|
];
|
|
78
|
-
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, trapFocus: false, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: colors
|
|
79
|
+
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, trapFocus: false, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: raisedRule(colors), children: [labels.addNewUser, upgradeNotice] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 5, children: _jsxs(VStack, { spacing: 4, align: "stretch", children: [textFields.map((field) => (_jsx(FormControl, { isInvalid: !!errors[field.id], children: _jsx(TextInput, { id: field.id, name: field.id, type: field.type, label: field.label, placeholder: field.placeholder, value: values[field.id], onChange: handleChange(field.id), isRequired: true, error: !!errors[field.id], errorMessage: errors[field.id], width: "100%" }) }, field.id))), _jsx(FormControl, { isInvalid: !!errors.role, isRequired: true, children: _jsx(SearchSelect, { label: labels.role, options: roleOptions.map((item) => ({
|
|
79
80
|
id: item.id,
|
|
80
81
|
label: item.label,
|
|
81
82
|
})), value: (_a = values.role) !== null && _a !== void 0 ? _a : undefined, onSelect: (option) => {
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, ModalFooter, FormControl, VStack, } from "@chakra-ui/react";
|
|
4
4
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
|
+
import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
|
|
5
6
|
import Button from "../Button/Button.js";
|
|
6
7
|
import TextInput from "../Input/TextInput.js";
|
|
7
8
|
import SearchSelect from "../SearchSelect/SearchSelect.js";
|
|
@@ -31,7 +32,7 @@ const ChangeRoleModal = ({ isOpen, onClose, userId, email, currentRole, roleOpti
|
|
|
31
32
|
return;
|
|
32
33
|
await (onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit({ userId, roleId: selectedRole.id }));
|
|
33
34
|
};
|
|
34
|
-
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, trapFocus: false, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsx(ModalHeader, { borderBottom: "1px solid", borderColor: colors
|
|
35
|
+
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, trapFocus: false, isCentered: true, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsx(ModalHeader, { borderBottom: "1px solid", borderColor: raisedRule(colors), children: labels.changeRoleTitle }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 5, children: _jsxs(VStack, { spacing: 4, align: "stretch", children: [_jsx(TextInput, { label: labels.email, value: email !== null && email !== void 0 ? email : "", isDisabled: true, width: "100%" }), _jsx(FormControl, { isInvalid: !!error, isRequired: true, children: _jsx(SearchSelect, { label: labels.role, options: roleOptions.map((item) => ({
|
|
35
36
|
id: item.id,
|
|
36
37
|
label: item.label,
|
|
37
38
|
})), value: selectedRole !== null && selectedRole !== void 0 ? selectedRole : undefined, onSelect: (option) => {
|
|
@@ -6,6 +6,7 @@ import { ChevronLeft, RefreshCw, Send, Shield, Trash2, UserPlus, Users, UserRoun
|
|
|
6
6
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
7
7
|
import { resolveHoverTint } from "../../Theme/tokens/builders/outlineRung.js";
|
|
8
8
|
import { accentTextOnCanvas } from "../../Theme/tokens/builders/accentText.js";
|
|
9
|
+
import { bandOn } from "../../Theme/tokens/builders/planeStep.js";
|
|
9
10
|
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
10
11
|
import { focusVisibleRing } from "../../Theme/chakra/focusRing.styles.js";
|
|
11
12
|
import EmptyState from "../EmptyState/EmptyState.js";
|
|
@@ -60,6 +61,7 @@ const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], ca
|
|
|
60
61
|
const [actionUserId, setActionUserId] = useState(null);
|
|
61
62
|
const border = colors.boxborder[200];
|
|
62
63
|
const surface = colors.background[50];
|
|
64
|
+
const detailTile = bandOn(colors.primary[50], surface);
|
|
63
65
|
const rowBackgrounds = useMemo(() => listRowBackgrounds(colors), [colors]);
|
|
64
66
|
const muted = colors.textMuted;
|
|
65
67
|
const heading = colors.text[900];
|
|
@@ -100,7 +102,7 @@ const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], ca
|
|
|
100
102
|
const Icon = (_a = detail.icon) !== null && _a !== void 0 ? _a : UserRound;
|
|
101
103
|
return (_jsxs(React.Fragment, { children: [_jsxs(Flex, { gap: 3, px: 3, py: 2.5, _hover: {
|
|
102
104
|
bg: resolveHoverTint(colors.gray[50], surface),
|
|
103
|
-
}, alignItems: "center", transition: "background 0.15s ease", children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "30px", bg:
|
|
105
|
+
}, alignItems: "center", transition: "background 0.15s ease", children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "30px", bg: detailTile, borderRadius: "lg", color: accentTextOnCanvas(colors.primary, detailTile), flexShrink: 0, children: _jsx(Icon, { size: 15 }) }), _jsx(Box, { minWidth: "110px", children: _jsx(Text, { fontSize: "xs", fontWeight: 600, color: muted, children: detail.label }) }), _jsx(Box, { flex: 1, children: _jsx(Text, { fontSize: "sm", color: heading, fontWeight: 500, children: detail.value }) })] }), index < selectedUser.details.length - 1 && (_jsx(Divider, { borderColor: border }))] }, index));
|
|
104
106
|
}) })] })] })) : (_jsx(EmptyState, { icon: UserRound, title: labels.selectTeamMember, description: labels.noUserSelected, minH: "300px" })) })] }), _jsx(AddUserModal, { isOpen: isAddUserOpen, onClose: onAddUserClose, roleOptions: roleOptions, isLoading: isAddUserLoading, onSubmit: async (values) => {
|
|
105
107
|
await (onAddUserSubmit === null || onAddUserSubmit === void 0 ? void 0 : onAddUserSubmit(values));
|
|
106
108
|
onAddUserClose();
|
|
@@ -36,10 +36,13 @@ const variants = {
|
|
|
36
36
|
outline: definePartsStyle({
|
|
37
37
|
container: { [$border.variable]: "1px", [$shadow.variable]: "none" },
|
|
38
38
|
}),
|
|
39
|
+
elevated: definePartsStyle({
|
|
40
|
+
container: { [$border.variable]: "0", [$shadow.variable]: "shadows.card" },
|
|
41
|
+
}),
|
|
39
42
|
};
|
|
40
43
|
export const Card = defineMultiStyleConfig({
|
|
41
44
|
baseStyle,
|
|
42
45
|
sizes,
|
|
43
46
|
variants,
|
|
44
|
-
defaultProps: { variant: "
|
|
47
|
+
defaultProps: { variant: "elevated", size: "md" },
|
|
45
48
|
});
|
|
@@ -3,6 +3,7 @@ import { menuAnatomy } from "@chakra-ui/anatomy";
|
|
|
3
3
|
import { listRowBackgrounds } from "../tokens/builders/rowStates.js";
|
|
4
4
|
import { OPTION_ROW_SIZES, OPTION_ROW_RADIUS } from "../tokens/primitives/optionRowSizes.js";
|
|
5
5
|
import { paletteOf } from "./paletteFromTheme.js";
|
|
6
|
+
import { POPUP_SURFACE } from "./overlay.styles.js";
|
|
6
7
|
const itemRowSpec = OPTION_ROW_SIZES.sm;
|
|
7
8
|
const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(menuAnatomy.keys);
|
|
8
9
|
const $bg = cssVar("menu-bg");
|
|
@@ -21,12 +22,14 @@ const baseStyle = definePartsStyle(({ theme }) => {
|
|
|
21
22
|
borderWidth: "1px",
|
|
22
23
|
borderStyle: "solid",
|
|
23
24
|
borderColor: colors.boxborder[200],
|
|
25
|
+
...POPUP_SURFACE,
|
|
24
26
|
},
|
|
25
27
|
item: {
|
|
26
28
|
minH: itemRowSpec.minH,
|
|
27
29
|
px: itemRowSpec.px,
|
|
28
30
|
py: itemRowSpec.py,
|
|
29
31
|
mx: itemRowSpec.mx,
|
|
32
|
+
width: `calc(100% - 2 * ${itemRowSpec.mx})`,
|
|
30
33
|
fontSize: itemRowSpec.fontSize,
|
|
31
34
|
borderRadius: OPTION_ROW_RADIUS,
|
|
32
35
|
bg: "transparent",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createMultiStyleConfigHelpers, cssVar } from "@chakra-ui/react";
|
|
2
2
|
import { popoverAnatomy } from "@chakra-ui/anatomy";
|
|
3
3
|
import { paletteOf } from "./paletteFromTheme.js";
|
|
4
|
+
import { POPUP_SURFACE } from "./overlay.styles.js";
|
|
4
5
|
const { defineMultiStyleConfig, definePartsStyle } = createMultiStyleConfigHelpers(popoverAnatomy.keys);
|
|
5
6
|
const $popperBg = cssVar("popper-bg");
|
|
6
7
|
const $arrowShadowColor = cssVar("popper-arrow-shadow-color");
|
|
@@ -16,6 +17,7 @@ const baseStyle = definePartsStyle(({ theme }) => {
|
|
|
16
17
|
borderWidth: "1px",
|
|
17
18
|
borderStyle: "solid",
|
|
18
19
|
borderColor: colors.boxborder[200],
|
|
20
|
+
...POPUP_SURFACE,
|
|
19
21
|
},
|
|
20
22
|
};
|
|
21
23
|
});
|
|
@@ -12,6 +12,7 @@ import { AA_NORMAL_TEXT, accentTextOnCanvas, isDarkCanvas } from "../tokens/buil
|
|
|
12
12
|
import { labelOnFill, solidFillRung } from "../tokens/builders/filledSurface.js";
|
|
13
13
|
import { liftToContrast, resolveHoverTint } from "../tokens/builders/outlineRung.js";
|
|
14
14
|
import { resolveSoftTone } from "../tokens/builders/tone.js";
|
|
15
|
+
import { skeletonShimmer } from "../tokens/builders/skeletonShimmer.js";
|
|
15
16
|
import { tooltipSurface } from "../tokens/builders/tooltipSurface.js";
|
|
16
17
|
import { Drawer } from "./Drawer.styles.js";
|
|
17
18
|
import { Menu } from "./Menu.styles.js";
|
|
@@ -142,12 +143,15 @@ const $skeletonStart = cssVar("skeleton-start-color");
|
|
|
142
143
|
const $skeletonEnd = cssVar("skeleton-end-color");
|
|
143
144
|
// NOTE: fixes Chakra's Skeleton hardcoding gray.100/.400 via `_dark` (dead here) — an explicit startColor/endColor prop still wins.
|
|
144
145
|
const Skeleton = {
|
|
145
|
-
baseStyle: ({ theme }) =>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
baseStyle: ({ theme }) => {
|
|
147
|
+
const shimmer = skeletonShimmer(paletteOf(theme));
|
|
148
|
+
return {
|
|
149
|
+
[$skeletonStart.variable]: shimmer.start,
|
|
150
|
+
[$skeletonEnd.variable]: shimmer.end,
|
|
151
|
+
background: $skeletonStart.reference,
|
|
152
|
+
borderColor: $skeletonEnd.reference,
|
|
153
|
+
};
|
|
154
|
+
},
|
|
151
155
|
};
|
|
152
156
|
// NOTE: uses Chakra's own shorthand style keys (bg/w/h/pos) + !important — extendTheme deep-merges by key, so mismatched keys let Chakra's stock value win.
|
|
153
157
|
const Radio = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMatchMedia } from "../../Hooks/useMatchMedia.js";
|
|
2
2
|
export const REDUCED_MOTION_QUERY = "@media (prefers-reduced-motion: reduce)";
|
|
3
|
+
export const MOTION_OK_QUERY = "@media (prefers-reduced-motion: no-preference)";
|
|
3
4
|
const MEDIA = "(prefers-reduced-motion: reduce)";
|
|
4
5
|
export const usePrefersReducedMotion = () => useMatchMedia(MEDIA, false);
|
|
5
6
|
/** Spread into `sx`: drops transitions and animations when the user asks for less motion. */
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { overlayScrim } from "../tokens/builders/scrim.js";
|
|
2
2
|
import { raisedRule } from "../tokens/builders/surfaceRaised.js";
|
|
3
|
+
import { RADIUS_ROLE } from "../tokens/primitives/radii.js";
|
|
3
4
|
export const OVERLAY_BLUR = "blur(4px)";
|
|
5
|
+
/** Radius and elevation every anchored popup shares: menus, popovers, selects, dropdowns. */
|
|
6
|
+
export const POPUP_SURFACE = { borderRadius: RADIUS_ROLE.float, boxShadow: "md" };
|
|
4
7
|
/** The one Modal/Drawer backdrop; reuse it for any custom full-screen scrim. */
|
|
5
8
|
export const overlayScrimStyles = (colors) => ({
|
|
6
9
|
bg: overlayScrim(colors),
|
|
@@ -27,9 +27,25 @@ import { withSurfaceRungs } from "../builders/surfaceRungs.js";
|
|
|
27
27
|
import { buildSurfaceRaised, withSurfaceRaised } from "../builders/surfaceRaised.js";
|
|
28
28
|
import { buildStar } from "../builders/star.js";
|
|
29
29
|
import { lazyPalette } from "../builders/lazy.js";
|
|
30
|
+
import { contrastRatio, mix } from "../builders/color.js";
|
|
31
|
+
export const LIGHT_CANVAS_STEP = 1.09;
|
|
32
|
+
const CANVAS_MIX_STEP = 0.0025;
|
|
33
|
+
const CANVAS_MIX_MAX = 0.5;
|
|
34
|
+
const lightCanvas = (canvas, card, ink) => {
|
|
35
|
+
for (let weight = 0; weight < CANVAS_MIX_MAX; weight += CANVAS_MIX_STEP) {
|
|
36
|
+
const next = mix(canvas, ink, weight);
|
|
37
|
+
if (contrastRatio(next, card) >= LIGHT_CANVAS_STEP)
|
|
38
|
+
return next;
|
|
39
|
+
}
|
|
40
|
+
return mix(canvas, ink, CANVAS_MIX_MAX);
|
|
41
|
+
};
|
|
30
42
|
/** Derived, never hand-written: a copied hex goes stale the moment a canvas moves. */
|
|
31
43
|
export const finalizeLightPalette = (source) => ({
|
|
32
44
|
...source,
|
|
45
|
+
backgroundColor: {
|
|
46
|
+
...source.backgroundColor,
|
|
47
|
+
base: lightCanvas(source.backgroundColor.base, source.background[50], source.text[900]),
|
|
48
|
+
},
|
|
33
49
|
sidebar: withSidebarTokens(source),
|
|
34
50
|
accentText: pickAccentText(source.primary, source.backgroundColor.main),
|
|
35
51
|
textMuted: buildMutedText(source.text, source.backgroundColor.main),
|
|
@@ -15,8 +15,22 @@ const primary = {
|
|
|
15
15
|
900: "#531a14",
|
|
16
16
|
opacity: buildPrimaryOpacity(PRIMARY_500),
|
|
17
17
|
};
|
|
18
|
+
const danger = {
|
|
19
|
+
50: "#fcedf3",
|
|
20
|
+
100: "#f5c5db",
|
|
21
|
+
200: "#f1a9ca",
|
|
22
|
+
300: "#ec82b4",
|
|
23
|
+
400: "#ea69a7",
|
|
24
|
+
500: "#e74494",
|
|
25
|
+
600: "#d23e87",
|
|
26
|
+
700: "#a43069",
|
|
27
|
+
800: "#7f2651",
|
|
28
|
+
900: "#611c3e",
|
|
29
|
+
};
|
|
18
30
|
const palette = {
|
|
19
31
|
...neutralTokens,
|
|
32
|
+
red: danger,
|
|
33
|
+
semantic: { ...neutralTokens.semantic, error: danger },
|
|
20
34
|
...buildBrandInk(PRIMARY_500),
|
|
21
35
|
// NOTE: stops retuned so white gradient-button text clears AA at both ends — original let it drop to 4.37/2.15.
|
|
22
36
|
gradient: { from: "#cd4733", to: "#a36807" }, // terracotta red → amber
|
|
@@ -118,6 +132,7 @@ const palette = {
|
|
|
118
132
|
boxShadow: {
|
|
119
133
|
primary: buildPrimaryShadowTint(PRIMARY_500),
|
|
120
134
|
...sharedBoxShadow,
|
|
135
|
+
error: `${danger[500]}47`,
|
|
121
136
|
},
|
|
122
137
|
};
|
|
123
138
|
export default palette;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { neutralTokens, sharedBoxShadow } from "../neutrals.js";
|
|
2
2
|
import { buildPrimaryOpacity, buildPrimaryShadowTint } from "../../builders/buildBrandTokens.js";
|
|
3
3
|
import { buildBrandInk } from "../../builders/brandInk.js";
|
|
4
|
-
const PRIMARY_500 = "#
|
|
4
|
+
const PRIMARY_500 = "#cb6b94";
|
|
5
5
|
const primary = {
|
|
6
|
-
50: "#
|
|
7
|
-
100: "#
|
|
8
|
-
200: "#
|
|
9
|
-
300: "#
|
|
10
|
-
400: "#
|
|
6
|
+
50: "#fcf2f7",
|
|
7
|
+
100: "#f6d6e5",
|
|
8
|
+
200: "#edabc9",
|
|
9
|
+
300: "#e480ad",
|
|
10
|
+
400: "#d76398",
|
|
11
11
|
500: PRIMARY_500,
|
|
12
|
-
600: "#
|
|
13
|
-
700: "#
|
|
14
|
-
800: "#
|
|
15
|
-
900: "#
|
|
12
|
+
600: "#b35681",
|
|
13
|
+
700: "#93466a",
|
|
14
|
+
800: "#723754",
|
|
15
|
+
900: "#52273e",
|
|
16
16
|
opacity: buildPrimaryOpacity(PRIMARY_500),
|
|
17
17
|
};
|
|
18
18
|
const palette = {
|