pixelize-design-library 2.4.2-beta.34 → 2.4.2-beta.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/Components/AppSwitcher/AppSwitcher.js +10 -4
  2. package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -3
  3. package/dist/Components/Common/fieldStyles.js +1 -1
  4. package/dist/Components/CopyButton/CopyButton.js +7 -6
  5. package/dist/Components/DatePicker/CalendarPanel.js +8 -5
  6. package/dist/Components/DatePicker/RangeDatePicker.js +27 -3
  7. package/dist/Components/DatePicker/SingleDatePicker.js +48 -14
  8. package/dist/Components/DatePicker/TimeOnlyPicker.js +7 -1
  9. package/dist/Components/DatePicker/TimePicker.js +3 -3
  10. package/dist/Components/DatePicker/TimePickerInput.js +1 -1
  11. package/dist/Components/Dropdown/DropDown.js +19 -6
  12. package/dist/Components/EmptyState/EmptyState.js +1 -1
  13. package/dist/Components/FileUpload/FileUpload.js +2 -2
  14. package/dist/Components/FilterSidebar/FilterSidebar.js +5 -5
  15. package/dist/Components/FilterSidebar/filterHoverStyle.d.ts +2 -1
  16. package/dist/Components/FilterSidebar/filterHoverStyle.js +3 -4
  17. package/dist/Components/Input/TextInput.styles.js +2 -2
  18. package/dist/Components/InputTextArea/InputTextArea.style.js +2 -2
  19. package/dist/Components/MoreItems/MoreItems.js +3 -1
  20. package/dist/Components/MultiSelect/MultiSelect.js +2 -2
  21. package/dist/Components/NavigationBar/NavigationBar.js +6 -7
  22. package/dist/Components/NumberInput/NumberInput.styles.js +2 -2
  23. package/dist/Components/OrgSwitcher/OrgSwitcher.js +14 -10
  24. package/dist/Components/PdfViewer/PdfViewer.js +4 -4
  25. package/dist/Components/RolesPermission/RolesPermission.js +4 -3
  26. package/dist/Components/SearchSelect/SearchSelect.js +46 -41
  27. package/dist/Components/Select/Select.styles.js +1 -1
  28. package/dist/Components/SelectSearch/SelectSearch.js +35 -17
  29. package/dist/Components/SelectV2/SelectV2.js +3 -0
  30. package/dist/Components/Table/TableProps.d.ts +2 -0
  31. package/dist/Components/Table/components/TableBody.js +7 -10
  32. package/dist/Components/Table/filters/CompactSelect.js +29 -8
  33. package/dist/Components/Table/settings/ManageColumns.js +5 -3
  34. package/dist/Components/Table/settings/TableSettings.js +4 -2
  35. package/dist/Components/Trail/EditableCell.js +1 -1
  36. package/dist/Components/UserDetails/DeactivateConfirmModal.js +1 -1
  37. package/dist/Components/UserDetails/UserDetails.js +5 -3
  38. package/dist/Hooks/exclusiveOverlay.d.ts +4 -0
  39. package/dist/Hooks/exclusiveOverlay.js +22 -0
  40. package/dist/Hooks/useExclusiveOverlay.d.ts +5 -0
  41. package/dist/Hooks/useExclusiveOverlay.js +24 -0
  42. package/dist/Theme/chakra/Menu.styles.js +4 -2
  43. package/dist/Utils/table.d.ts +3 -0
  44. package/dist/Utils/table.js +44 -1
  45. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +11 -5
  46. package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -3
  47. package/dist/esm/Components/Common/fieldStyles.js +1 -1
  48. package/dist/esm/Components/CopyButton/CopyButton.js +7 -6
  49. package/dist/esm/Components/DatePicker/CalendarPanel.js +9 -6
  50. package/dist/esm/Components/DatePicker/RangeDatePicker.js +28 -4
  51. package/dist/esm/Components/DatePicker/SingleDatePicker.js +49 -15
  52. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +7 -1
  53. package/dist/esm/Components/DatePicker/TimePicker.js +3 -3
  54. package/dist/esm/Components/DatePicker/TimePickerInput.js +1 -1
  55. package/dist/esm/Components/Dropdown/DropDown.js +20 -7
  56. package/dist/esm/Components/EmptyState/EmptyState.js +1 -1
  57. package/dist/esm/Components/FileUpload/FileUpload.js +2 -2
  58. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +5 -5
  59. package/dist/esm/Components/FilterSidebar/filterHoverStyle.js +3 -4
  60. package/dist/esm/Components/Input/TextInput.styles.js +2 -2
  61. package/dist/esm/Components/InputTextArea/InputTextArea.style.js +2 -2
  62. package/dist/esm/Components/MoreItems/MoreItems.js +3 -1
  63. package/dist/esm/Components/MultiSelect/MultiSelect.js +2 -2
  64. package/dist/esm/Components/NavigationBar/NavigationBar.js +6 -7
  65. package/dist/esm/Components/NumberInput/NumberInput.styles.js +2 -2
  66. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +14 -10
  67. package/dist/esm/Components/PdfViewer/PdfViewer.js +4 -4
  68. package/dist/esm/Components/RolesPermission/RolesPermission.js +4 -3
  69. package/dist/esm/Components/SearchSelect/SearchSelect.js +46 -41
  70. package/dist/esm/Components/Select/Select.styles.js +1 -1
  71. package/dist/esm/Components/SelectSearch/SelectSearch.js +35 -17
  72. package/dist/esm/Components/SelectV2/SelectV2.js +3 -0
  73. package/dist/esm/Components/Table/components/TableBody.js +7 -10
  74. package/dist/esm/Components/Table/filters/CompactSelect.js +29 -8
  75. package/dist/esm/Components/Table/settings/ManageColumns.js +5 -3
  76. package/dist/esm/Components/Table/settings/TableSettings.js +5 -3
  77. package/dist/esm/Components/Trail/EditableCell.js +1 -1
  78. package/dist/esm/Components/UserDetails/DeactivateConfirmModal.js +1 -1
  79. package/dist/esm/Components/UserDetails/UserDetails.js +5 -3
  80. package/dist/esm/Hooks/exclusiveOverlay.js +16 -0
  81. package/dist/esm/Hooks/useExclusiveOverlay.js +20 -0
  82. package/dist/esm/Theme/chakra/Menu.styles.js +4 -2
  83. package/dist/esm/Utils/table.js +45 -3
  84. package/package.json +1 -1
@@ -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 ? colors.primary[50] : "transparent", _hover: {
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
- ? colors.primary[50]
77
- : resolveHoverTint(colors.gray[50], surface),
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 hoverBg = colors.primary.opacity[8];
25
- const activeBg = colors.primary.opacity[16];
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,
@@ -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
- return { solid: override, soft: withAlpha(override, "22"), text: override, onSolid: onFilled(override, white, black) };
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.4.2-beta.34",
3
+ "version": "2.4.2-beta.35",
4
4
  "description": "React component library for Pixelize apps: themeable Chakra-based components, design tokens and light/dark brand theming.",
5
5
  "keywords": [
6
6
  "react",