pixelize-design-library 2.4.2-beta.53 → 2.4.2-beta.55

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 (64) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/COMPONENT-GOTCHAS.md +57 -4
  3. package/DESIGN-GUIDE.md +8 -6
  4. package/dist/Components/AppSwitcher/AppSwitcher.js +1 -2
  5. package/dist/Components/Button/Button.styles.js +1 -1
  6. package/dist/Components/Button/ButtonProps.d.ts +1 -1
  7. package/dist/Components/Common/fieldStyles.d.ts +1 -1
  8. package/dist/Components/Common/fieldStyles.js +1 -1
  9. package/dist/Components/DatePicker/DatePickerProps.d.ts +1 -1
  10. package/dist/Components/Dropdown/DropDown.js +4 -4
  11. package/dist/Components/Dropdown/DropdownProps.d.ts +1 -1
  12. package/dist/Components/Input/PhoneNumberInputProps.d.ts +1 -1
  13. package/dist/Components/MultiSelect/MultiSelectProps.d.ts +1 -1
  14. package/dist/Components/NotificationBell/NotificationBellProps.d.ts +1 -1
  15. package/dist/Components/OrgSwitcher/OrgSwitcher.js +3 -4
  16. package/dist/Components/PinInput/PinInputProps.d.ts +1 -1
  17. package/dist/Components/RangeSlider/RangeSliderProps.d.ts +1 -1
  18. package/dist/Components/RangeSlider/rangeSliderSize.d.ts +1 -1
  19. package/dist/Components/RangeSlider/rangeSliderSize.js +1 -1
  20. package/dist/Components/Search/SearchProps.d.ts +1 -1
  21. package/dist/Components/SearchSelect/SearchSelectProps.d.ts +1 -1
  22. package/dist/Components/SegmentedControl/SegmentedControl.js +1 -1
  23. package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +1 -1
  24. package/dist/Components/Select/SelectProps.d.ts +1 -1
  25. package/dist/Components/SelectSearch/SelectSearchProps.d.ts +1 -1
  26. package/dist/Components/SelectV2/SelectV2Props.d.ts +1 -1
  27. package/dist/Components/SideBar/SecondaryBar.js +4 -2
  28. package/dist/Components/SideBar/SideBar.js +14 -8
  29. package/dist/Components/SideBar/components/MenuItemBox.js +9 -5
  30. package/dist/Components/SideBar/components/MenuPopoverContent.js +5 -3
  31. package/dist/Components/SideBar/components/OtherApps.js +1 -1
  32. package/dist/Components/Table/Table.js +16 -4
  33. package/dist/Components/Table/TableProps.d.ts +1 -1
  34. package/dist/Components/Table/components/rowMetrics.d.ts +1 -0
  35. package/dist/Components/Table/components/rowMetrics.js +2 -1
  36. package/dist/Components/Tabs/TabsProps.d.ts +1 -1
  37. package/dist/Components/Tabs/components/Tab.js +1 -1
  38. package/dist/Components/Toggle/TableToggle.js +1 -1
  39. package/dist/Constants/Sidebar.js +3 -3
  40. package/dist/Theme/tokens/builders/sidebarAccent.js +4 -2
  41. package/dist/Theme/tokens/primitives/controlSizes.d.ts +2 -1
  42. package/dist/Theme/tokens/primitives/controlSizes.js +10 -4
  43. package/dist/Theme/tokens/primitives/optionRowSizes.js +6 -6
  44. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +1 -2
  45. package/dist/esm/Components/Button/Button.styles.js +2 -2
  46. package/dist/esm/Components/Common/fieldStyles.js +1 -1
  47. package/dist/esm/Components/Dropdown/DropDown.js +5 -5
  48. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +3 -4
  49. package/dist/esm/Components/RangeSlider/rangeSliderSize.js +1 -1
  50. package/dist/esm/Components/SegmentedControl/SegmentedControl.js +2 -2
  51. package/dist/esm/Components/SideBar/SecondaryBar.js +6 -4
  52. package/dist/esm/Components/SideBar/SideBar.js +14 -8
  53. package/dist/esm/Components/SideBar/components/MenuItemBox.js +9 -5
  54. package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +6 -4
  55. package/dist/esm/Components/SideBar/components/OtherApps.js +1 -1
  56. package/dist/esm/Components/Table/Table.js +17 -5
  57. package/dist/esm/Components/Table/components/rowMetrics.js +1 -0
  58. package/dist/esm/Components/Tabs/components/Tab.js +2 -2
  59. package/dist/esm/Components/Toggle/TableToggle.js +2 -2
  60. package/dist/esm/Constants/Sidebar.js +3 -3
  61. package/dist/esm/Theme/tokens/builders/sidebarAccent.js +5 -3
  62. package/dist/esm/Theme/tokens/primitives/controlSizes.js +9 -3
  63. package/dist/esm/Theme/tokens/primitives/optionRowSizes.js +6 -6
  64. package/package.json +1 -1
@@ -86,7 +86,7 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
86
86
  opacity: isBlocked ? 0.6 : 1,
87
87
  transition: "background 0.12s",
88
88
  };
89
- const buttonContent = (_jsxs(Flex, { align: "center", gap: "9px", justify: toggle ? "center" : "space-between", w: "100%", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", children: [_jsxs(Box, { position: "relative", display: "flex", alignItems: "center", children: [_jsx(Icon, { as: icon, fontSize: "md", verticalAlign: "middle", color: isAnyActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isAnyActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" }), toggle && (badgeValue != null || hasSubmenuBadge) && (_jsx(Box, { position: "absolute", top: "0", right: "0", w: "0.375rem", h: "0.375rem", borderRadius: "full", bg: theme.colors.red[400] }))] }), !toggle && (_jsx(TruncatedTextWithTooltip
89
+ const buttonContent = (_jsxs(Flex, { align: "center", gap: "9px", justify: toggle ? "center" : "space-between", w: "100%", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", children: [_jsxs(Box, { position: "relative", display: "flex", alignItems: "center", children: [_jsx(Icon, { as: icon, fontSize: "md", verticalAlign: "middle", color: isAnyActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isAnyActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" }), toggle && (badgeValue != null || hasSubmenuBadge) && (_jsx(Box, { position: "absolute", top: "0", right: "0", w: "0.375rem", h: "0.375rem", borderRadius: "full", bg: theme.colors.sidebar.semanticText.error }))] }), !toggle && (_jsx(TruncatedTextWithTooltip
90
90
  // open={isOpen}
91
91
  , {
92
92
  // open={isOpen}
@@ -123,15 +123,19 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
123
123
  var _a, _b, _c;
124
124
  const isSubActive = activeMenu === sub.id;
125
125
  const isSubBlocked = menuDisabled(sub) || sub.locked;
126
- return (_jsxs(Box, { as: "a", href: (_a = sub.url) !== null && _a !== void 0 ? _a : "#", "data-group": "", "aria-current": isSubActive ? "page" : undefined, "aria-disabled": isSubBlocked ? true : undefined, textDecoration: "none", h: SIDEBAR_ROW.subHeight, pl: "30px", pr: "10px", borderRadius: "lg", fontSize: SIDEBAR_ROW.fontSize, backgroundColor: "transparent", _hover: { backgroundColor: "whiteAlpha.100" }, opacity: isSubBlocked ? 0.6 : 1, cursor: isSubBlocked ? "not-allowed" : "pointer", pointerEvents: isSubBlocked ? "none" : "auto", onClick: (e) => {
126
+ return (_jsxs(Box, { as: "a", href: (_a = sub.url) !== null && _a !== void 0 ? _a : "#", "data-group": "", "aria-current": isSubActive ? "page" : undefined, "aria-disabled": isSubBlocked ? true : undefined, textDecoration: "none", h: SIDEBAR_ROW.subHeight, pl: "28px", pr: "10px", borderRadius: "lg", fontSize: SIDEBAR_ROW.fontSize, borderLeft: "2px solid", borderLeftColor: isSubActive ? theme.colors.sidebar.activeIcon : "transparent", backgroundColor: isSubActive ? "whiteAlpha.300" : "transparent", _hover: {
127
+ backgroundColor: isSubBlocked
128
+ ? "transparent"
129
+ : isSubActive
130
+ ? "whiteAlpha.400"
131
+ : "whiteAlpha.200",
132
+ }, opacity: isSubBlocked ? 0.6 : 1, cursor: isSubBlocked ? "not-allowed" : "pointer", pointerEvents: isSubBlocked ? "none" : "auto", onClick: (e) => {
127
133
  if (sub.url && isBrowserNavigationGesture(e))
128
134
  return;
129
135
  e.preventDefault();
130
136
  if (!isSubBlocked)
131
137
  handleClick === null || handleClick === void 0 ? void 0 : handleClick(sub);
132
- }, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, transition: "background 0.12s", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? (_jsx(Icon, { as: sub.icon, fontSize: SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : (_jsx(Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), _jsx(TruncatedTextWithTooltip, { fontSize: SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, lineHeight: "1",
133
- // open={isOpen}
134
- color: isSubActive ? theme.colors.white : theme.colors.sidebar.mutedLabel, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? (_jsx(Icon, { as: LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon })) : (() => {
138
+ }, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, transition: "background 0.12s", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? (_jsx(Icon, { as: sub.icon, fontSize: SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : (_jsx(Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), _jsx(TruncatedTextWithTooltip, { fontSize: SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, lineHeight: "1", color: isSubActive ? activeAccent.label : theme.colors.sidebar.mutedLabel, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? (_jsx(Icon, { as: LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon })) : (() => {
135
139
  var _a, _b, _c, _d;
136
140
  const subCfg = typeof sub.badge === "object" && sub.badge !== null
137
141
  ? sub.badge
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Icon, Flex, Badge } from "@chakra-ui/react";
2
+ import { Icon, Flex, Badge, Box } from "@chakra-ui/react";
3
3
  import { LockKeyhole } from "lucide-react";
4
4
  import { menuDisabled } from "../menuDisabled.js";
5
5
  import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
@@ -17,7 +17,9 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
17
17
  const isBlocked = menuDisabled(menu) || locked;
18
18
  const hasSubMenu = !!(subMenu === null || subMenu === void 0 ? void 0 : subMenu.length);
19
19
  const isParentActive = activeMenu === menu.id;
20
- return (_jsxs(_Fragment, { children: [_jsxs(Flex, { as: (hasSubMenu ? "div" : "a"), href: hasSubMenu ? undefined : (_a = menu.url) !== null && _a !== void 0 ? _a : "#", "aria-current": !hasSubMenu && isParentActive ? "page" : undefined, textDecoration: "none", align: "center", gap: 2, px: 2, h: "32px", mb: hasSubMenu ? "4px" : 0, borderBottom: hasSubMenu ? "1px solid" : undefined, borderColor: hasSubMenu ? theme.colors.sidebar.divider : undefined, borderRadius: hasSubMenu ? "none" : "lg", bg: !hasSubMenu && isParentActive ? "whiteAlpha.300" : "transparent", _hover: !hasSubMenu && !isBlocked ? { bg: "whiteAlpha.100" } : undefined, onClick: (e) => {
20
+ return (_jsxs(_Fragment, { children: [_jsxs(Flex, { as: (hasSubMenu ? "div" : "a"), href: hasSubMenu ? undefined : (_a = menu.url) !== null && _a !== void 0 ? _a : "#", "aria-current": !hasSubMenu && isParentActive ? "page" : undefined, textDecoration: "none", align: "center", gap: 2, px: 2, h: "32px", mb: hasSubMenu ? "4px" : 0, borderBottom: hasSubMenu ? "1px solid" : undefined, borderColor: hasSubMenu ? theme.colors.sidebar.divider : undefined, borderRadius: hasSubMenu ? "none" : "lg", bg: !hasSubMenu && isParentActive ? "whiteAlpha.300" : "transparent", _hover: !hasSubMenu && !isBlocked
21
+ ? { bg: isParentActive ? "whiteAlpha.400" : "whiteAlpha.200" }
22
+ : undefined, onClick: (e) => {
21
23
  if (!hasSubMenu) {
22
24
  e.preventDefault();
23
25
  if (!isBlocked)
@@ -45,9 +47,9 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
45
47
  if (!isSubBlocked)
46
48
  handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(sub);
47
49
  }, px: 2, h: SIDEBAR_ROW.subHeight, mb: "2px", borderRadius: "lg", align: "center", justify: "space-between", gap: 2, borderLeft: "2px solid", borderLeftColor: isSubActive ? theme.colors.sidebar.activeIcon : "transparent", bg: isSubActive ? "whiteAlpha.300" : "transparent", _hover: {
48
- bg: !isSubBlocked ? "whiteAlpha.100" : "transparent",
50
+ bg: isSubBlocked ? "transparent" : isSubActive ? "whiteAlpha.400" : "whiteAlpha.200",
49
51
  cursor: !isSubBlocked ? "pointer" : "not-allowed",
50
- }, opacity: isSubBlocked ? 0.5 : 1, pointerEvents: isSubBlocked ? "none" : "auto", transition: "background 0.12s", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [_jsx(Icon, { as: sub.icon, fontSize: SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" }), _jsx(TruncatedTextWithTooltip, { fontSize: SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? (_jsx(Icon, { as: LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon })) : (() => {
52
+ }, opacity: isSubBlocked ? 0.5 : 1, pointerEvents: isSubBlocked ? "none" : "auto", transition: "background 0.12s", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? (_jsx(Icon, { as: sub.icon, fontSize: SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : (_jsx(Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), _jsx(TruncatedTextWithTooltip, { fontSize: SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? (_jsx(Icon, { as: LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon })) : (() => {
51
53
  var _a, _b, _c, _d;
52
54
  const cfg = typeof sub.badge === "object" && sub.badge !== null
53
55
  ? sub.badge
@@ -10,7 +10,7 @@ const OtherApps = ({ toggle, otherApps }) => {
10
10
  return (_jsx(Box, { display: "flex", alignItems: "center", justifyContent: "center", color: theme.colors.sidebar.mutedIcon, fontSize: "15px", flexShrink: 0, children: (_a = app.icon) !== null && _a !== void 0 ? _a : (_jsx(Box, { w: "0.5rem", h: "0.5rem", borderRadius: "full", bg: app.color, boxShadow: `0 0 5px ${app.color}`, flexShrink: 0 })) }));
11
11
  };
12
12
  // Grid cell: icon on top, truncated label below (label hidden when collapsed).
13
- const appCell = (app) => (_jsxs(Flex, { as: "button", type: "button", direction: "column", align: "center", justify: "center", gap: "3px", px: "2px", py: "6px", borderRadius: "lg", cursor: "pointer", border: "none", bg: "transparent", w: "100%", _hover: { backgroundColor: "whiteAlpha.100" }, transition: "background 0.12s", onClick: app.onClick, children: [appIcon(app), !toggle && (_jsx(Text, { fontSize: "9.5px", color: theme.colors.sidebar.mutedLabel, textAlign: "center", maxW: "44px", isTruncated: true, children: app.name }))] }));
13
+ const appCell = (app) => (_jsxs(Flex, { as: "button", type: "button", direction: "column", align: "center", justify: "center", gap: "3px", px: "2px", py: "6px", borderRadius: "lg", cursor: "pointer", border: "none", bg: "transparent", w: "100%", _hover: { backgroundColor: "whiteAlpha.200" }, transition: "background 0.12s", onClick: app.onClick, children: [appIcon(app), !toggle && (_jsx(Text, { fontSize: "9.5px", color: theme.colors.sidebar.mutedLabel, textAlign: "center", maxW: "44px", isTruncated: true, children: app.name }))] }));
14
14
  const flyoutBody = (app) => {
15
15
  var _a;
16
16
  return (_jsxs(_Fragment, { children: [_jsxs(Flex, { alignItems: "center", gap: 2, mb: 1, onClick: app.onClick, children: [(_a = app.icon) !== null && _a !== void 0 ? _a : (_jsx(Box, { w: "0.5rem", h: "0.5rem", borderRadius: "full", bg: app.color, boxShadow: `0 0 5px ${app.color}`, flexShrink: 0 })), _jsx(Text, { fontSize: "sm", fontWeight: 700, color: theme.colors.white, children: app.name })] }), app.description && (_jsx(Text, { fontSize: "xs", color: theme.colors.sidebar.mutedLabel, children: app.description }))] }));
@@ -15,7 +15,7 @@ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
15
15
  import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
16
16
  import { reducedMotionSx } from "../../Theme/chakra/motion.js";
17
17
  import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
18
- import { DENSITY_ROWS, EMPTY_STATE_HEIGHT, GROUP_HEADER_HEIGHT, TOOLBAR_HEIGHT, pxOf, rowHeightFor } from "./components/rowMetrics.js";
18
+ import { DENSITY_ROWS, EMPTY_STATE_HEIGHT, GROUP_HEADER_HEIGHT, MAX_TABLE_HEIGHT, TOOLBAR_HEIGHT, pxOf, rowHeightFor } from "./components/rowMetrics.js";
19
19
  import { scrollbarStyles, SCROLLBAR_WIDTH } from "../../Theme/tokens/builders/scrollbar.js";
20
20
  import { scrollShadowStyles } from "../../Theme/tokens/builders/scrollShadow.js";
21
21
  import useTable from "./hooks/useTable.js";
@@ -312,9 +312,21 @@ export default function Table({ data, columns, onSelection, isLoading, isCheckbo
312
312
  rowsHeight += ((_c = renderGroups === null || renderGroups === void 0 ? void 0 : renderGroups.length) !== null && _c !== void 0 ? _c : 1) * GROUP_HEADER_HEIGHT;
313
313
  if (isEmptyState)
314
314
  rowsHeight = Math.max(rowsHeight, headerHeight + EMPTY_STATE_HEIGHT);
315
- const dynamicMaxH = Math.min(500, rowsHeight);
315
+ const dynamicMaxH = Math.min(MAX_TABLE_HEIGHT, rowsHeight);
316
316
  const fittedMaxH = autoFitViewport ? Math.min(dynamicMaxH, viewportAvailableH) : dynamicMaxH;
317
- const tableMaxH = typeof tableMaxHeight === "number" ? tableMaxHeight : (isCompactRows ? rowsHeight + 8 : fittedMaxH);
317
+ const formulaMaxH = typeof tableMaxHeight === "number" ? tableMaxHeight : (isCompactRows ? rowsHeight + 8 : fittedMaxH);
318
+ // NOTE: wrapped cell content can exceed the per-row estimate; when the row count is
319
+ // within the display cap (explicit maxVisibleRows, else the default 10), size naturally
320
+ // instead of clipping. `visibleRowsCount` isn't used here — minRows defaults to
321
+ // actualRows, which would make this true for any row count.
322
+ const rawMaxRows = typeof maxVisibleRows === "number" ? maxVisibleRows : (actualRows === 0 ? 1 : 10);
323
+ const showsAllRows = actualRows <= rawMaxRows;
324
+ const useNaturalHeight = typeof tableMaxHeight !== "number" && showsAllRows && !isTableLoading && !canInfinite &&
325
+ !(filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar);
326
+ const tableMinH = useNaturalHeight ? formulaMaxH : undefined;
327
+ const tableMaxH = useNaturalHeight
328
+ ? (autoFitViewport ? viewportAvailableH : undefined)
329
+ : formulaMaxH;
318
330
  const isCompactHeader = useBreakpointValue({ base: true, md: true, lg: false });
319
331
  useEffect(() => {
320
332
  if (!isCompactHeader) {
@@ -365,7 +377,7 @@ export default function Table({ data, columns, onSelection, isLoading, isCheckbo
365
377
  from { transform: rotate(0deg); }
366
378
  to { transform: rotate(360deg); }
367
379
  }
368
- ` }), _jsxs(Box, { bg: theme.colors.background[50], border: `0.063rem solid ${theme.colors.boxborder[200]}`, borderRadius: "xl", overflow: "hidden", children: [filterSidebar && filterMode === "modal" && (_jsxs(Modal, { isOpen: isFilterModalOpen, onClose: onFilterModalClose, size: "4xl", scrollBehavior: "inside", children: [_jsx(ModalOverlay, {}), _jsxs(ModalContent, { bg: theme.colors.surfaceRaised, my: 0, top: "10%", position: "fixed", left: "auto", right: "auto", children: [_jsx(ModalCloseButton, { size: "sm" }), _jsx(ModalBody, { p: 0, children: _jsx(LeftFilterPane, { theme: theme, sections: (_d = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.sidebarOptions) !== null && _d !== void 0 ? _d : [], selected: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.selected, onApply: (sel) => { var _a; (_a = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onApply) === null || _a === void 0 ? void 0 : _a.call(filterSidebar, sel); onFilterModalClose(); }, onClear: () => { var _a; (_a = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onClearAllHandler) === null || _a === void 0 ? void 0 : _a.call(filterSidebar); }, isApplyLoading: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isApplyLoading, filterMode: filterMode }) })] })] })), _jsxs(Flex, { align: "start", children: [filterMode === "sidebar" && (_jsx(MotionBox, { "data-testid": "filter-sidebar-pane", initial: { width: 0 }, animate: { width: (filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar) ? 180 : 0 }, transition: { type: "tween", duration: 0.5 }, overflow: "hidden", flexShrink: 0, borderRight: (filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar) ? "1px solid" : "none", borderColor: theme.colors.boxborder[200], style: { height: TOOLBAR_HEIGHT + tableMaxH }, minHeight: (filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar) ? "32rem" : "auto", children: _jsx(LeftFilterPane, { height: TOOLBAR_HEIGHT + tableMaxH, theme: theme, sections: (_e = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.sidebarOptions) !== null && _e !== void 0 ? _e : [], selected: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.selected, onApply: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onApply, onClear: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onClearAllHandler, isApplyLoading: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isApplyLoading, filterMode: filterMode }) })), _jsxs(Box, { flex: "1", minW: 0, children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", px: 3, py: 0, height: `${TOOLBAR_HEIGHT}px`, gap: 3, flexWrap: "nowrap", bg: theme.colors.background[50], borderBottom: `0.063rem solid ${theme.colors.boxborder[200]}`, children: [[
380
+ ` }), _jsxs(Box, { bg: theme.colors.background[50], border: `0.063rem solid ${theme.colors.boxborder[200]}`, borderRadius: "xl", overflow: "hidden", children: [filterSidebar && filterMode === "modal" && (_jsxs(Modal, { isOpen: isFilterModalOpen, onClose: onFilterModalClose, size: "4xl", scrollBehavior: "inside", children: [_jsx(ModalOverlay, {}), _jsxs(ModalContent, { bg: theme.colors.surfaceRaised, my: 0, top: "10%", position: "fixed", left: "auto", right: "auto", children: [_jsx(ModalCloseButton, { size: "sm" }), _jsx(ModalBody, { p: 0, children: _jsx(LeftFilterPane, { theme: theme, sections: (_d = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.sidebarOptions) !== null && _d !== void 0 ? _d : [], selected: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.selected, onApply: (sel) => { var _a; (_a = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onApply) === null || _a === void 0 ? void 0 : _a.call(filterSidebar, sel); onFilterModalClose(); }, onClear: () => { var _a; (_a = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onClearAllHandler) === null || _a === void 0 ? void 0 : _a.call(filterSidebar); }, isApplyLoading: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isApplyLoading, filterMode: filterMode }) })] })] })), _jsxs(Flex, { align: "start", children: [filterMode === "sidebar" && (_jsx(MotionBox, { "data-testid": "filter-sidebar-pane", initial: { width: 0 }, animate: { width: (filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar) ? 180 : 0 }, transition: { type: "tween", duration: 0.5 }, overflow: "hidden", flexShrink: 0, borderRight: (filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar) ? "1px solid" : "none", borderColor: theme.colors.boxborder[200], style: { height: TOOLBAR_HEIGHT + formulaMaxH }, minHeight: (filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar) ? "32rem" : "auto", children: _jsx(LeftFilterPane, { height: TOOLBAR_HEIGHT + formulaMaxH, theme: theme, sections: (_e = filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.sidebarOptions) !== null && _e !== void 0 ? _e : [], selected: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.selected, onApply: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onApply, onClear: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.onClearAllHandler, isApplyLoading: filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isApplyLoading, filterMode: filterMode }) })), _jsxs(Box, { flex: "1", minW: 0, children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", px: 3, py: 0, height: `${TOOLBAR_HEIGHT}px`, gap: 3, flexWrap: "nowrap", bg: theme.colors.background[50], borderBottom: `0.063rem solid ${theme.colors.boxborder[200]}`, children: [[
369
381
  filterSidebar && (_jsx(ToolTip, { label: "Filter", placement: "top", children: _jsxs(Box, { position: "relative", display: "inline-block", children: [_jsx(Box, { as: "button", type: "button", "aria-label": "Filter", "aria-haspopup": filterMode === "modal" ? "dialog" : undefined, "aria-expanded": filterMode === "modal"
370
382
  ? isFilterModalOpen
371
383
  : !!(filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.isFilterSidebar), display: "inline-flex", alignItems: "center", justifyContent: "center", p: 0, bg: "transparent", border: "none", borderRadius: "md", cursor: "pointer", onClick: filterMode === "modal" ? onFilterModalOpen : filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.filterSidebarToggle, _hover: {
@@ -401,7 +413,7 @@ export default function Table({ data, columns, onSelection, isLoading, isCheckbo
401
413
  .filter(Boolean)
402
414
  .flatMap((tool, i) => (i === 0 ? [tool] : [_jsx(VeritcalDivider, {}, `divider-${i}`), tool])), _jsx(ActiveFilters, { columns: columnsList, columnsSearch: columnsSearch, setColumnsSearch: setColumnsSearch }), _jsxs(Box, { ml: "auto", display: "flex", alignItems: "center", gap: 2, children: [groupLoadMoreActive && loadMorePosition === "top" && (groupLoadMoreCaption || canGroupLoadMore) && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flex: "0 0 auto", children: [groupLoadMoreCaption && (_jsx(Box, { fontSize: "0.75rem", color: theme.colors.text[500], whiteSpace: "nowrap", children: groupLoadMoreCaption })), canGroupLoadMore && (_jsx(Button, { size: "xs", variant: "outline", colorScheme: "gray", isLoading: isLoadingMore, loadingText: loadMoreText, onClick: handleGroupLoadMore, label: loadMoreText }))] })), (isPagination || isServerPagination) && !isGrouped && !canInfinite && !isCompactHeader && (_jsx("div", { children: _jsx(Pagination, { currentPage: currentPage, setCurrentPage: setCurrentPage, rowsPerPage: rowsPerPage, pages: pages, paginationText: tablePaginationText, handlePageSizeChange: handlePageSizeChange, dataLength: tableData.length, isServerPagination: isServerPagination, paginationSelectOptions: paginationSelectOptions }) })), (isPagination || isServerPagination) && !isGrouped && !canInfinite && isCompactHeader && (_jsxs(Popover, { isOpen: isPaginationPopoverOpen, onClose: () => setIsPaginationPopoverOpen(false), placement: "bottom-end", children: [_jsx(PopoverTrigger, { children: _jsx(IconButton, { "aria-label": "Pagination", size: "sm", variant: "ghost", icon: _jsx(EllipsisVertical, { size: 18 }), color: theme.colors.text[500], _hover: {
403
415
  color: theme.colors.accentText,
404
- }, onClick: () => setIsPaginationPopoverOpen((open) => !open) }) }), _jsx(Portal, { children: _jsx(PopoverContent, { maxW: "22rem", p: 2, zIndex: 1600, bg: theme.colors.surfaceRaised, boxShadow: "lg", children: _jsx(PopoverBody, { p: 0, children: _jsx(Pagination, { currentPage: currentPage, setCurrentPage: setCurrentPage, rowsPerPage: rowsPerPage, pages: pages, paginationText: tablePaginationText, handlePageSizeChange: handlePageSizeChange, dataLength: tableData.length, isServerPagination: isServerPagination, paginationSelectOptions: paginationSelectOptions }) }) }) })] }))] })] }), _jsxs(TableContainer, { ref: tableContainerRef, position: "relative", h: isTableLoading ? tableMaxH : undefined, maxH: !isTableLoading ? tableMaxH : undefined, pb: isTableLoading ? 0 : compactScrollbarPadding, overflowY: isCompactRows ? "hidden" : "auto", overflowX: "auto", sx: {
416
+ }, onClick: () => setIsPaginationPopoverOpen((open) => !open) }) }), _jsx(Portal, { children: _jsx(PopoverContent, { maxW: "22rem", p: 2, zIndex: 1600, bg: theme.colors.surfaceRaised, boxShadow: "lg", children: _jsx(PopoverBody, { p: 0, children: _jsx(Pagination, { currentPage: currentPage, setCurrentPage: setCurrentPage, rowsPerPage: rowsPerPage, pages: pages, paginationText: tablePaginationText, handlePageSizeChange: handlePageSizeChange, dataLength: tableData.length, isServerPagination: isServerPagination, paginationSelectOptions: paginationSelectOptions }) }) }) })] }))] })] }), _jsxs(TableContainer, { ref: tableContainerRef, position: "relative", h: isTableLoading ? tableMaxH : undefined, minH: !isTableLoading ? tableMinH : undefined, maxH: !isTableLoading ? tableMaxH : undefined, pb: isTableLoading ? 0 : compactScrollbarPadding, overflowY: isCompactRows ? "hidden" : "auto", overflowX: "auto", sx: {
405
417
  ...scrollShadowStyles(theme.colors.background[50]),
406
418
  ...scrollbarStyles(theme.colors),
407
419
  // Compact rows hide the horizontal bar until hover to keep the row height.
@@ -6,5 +6,6 @@ export const DENSITY_ROWS = {
6
6
  export const TOOLBAR_HEIGHT = 45;
7
7
  export const GROUP_HEADER_HEIGHT = 42;
8
8
  export const EMPTY_STATE_HEIGHT = 200;
9
+ export const MAX_TABLE_HEIGHT = 500;
9
10
  export const rowHeightFor = (density) => DENSITY_ROWS[density !== null && density !== void 0 ? density : "normal"].height;
10
11
  export const pxOf = (length) => parseFloat(length);
@@ -7,7 +7,7 @@ import { AA_NON_TEXT, liftToContrast } from "../../../Theme/tokens/builders/outl
7
7
  import { compositeOver } from "../../../Theme/tokens/builders/color.js";
8
8
  import { transitionFor } from "../../../Theme/tokens/primitives/motion.js";
9
9
  import { reducedMotionSx } from "../../../Theme/chakra/motion.js";
10
- import { CONTROL_SIZES } from "../../../Theme/tokens/primitives/controlSizes.js";
10
+ import { BUTTON_SIZES } from "../../../Theme/tokens/primitives/controlSizes.js";
11
11
  import { iconBoxSx } from "../../Common/iconBox.js";
12
12
  import { resolveTabStyle, scaleForColorScheme } from "../tabStyles.js";
13
13
  import { panelId, tabId, useTabsContext } from "../TabsContext.js";
@@ -24,7 +24,7 @@ const Tab = ({ value, children, icon, count, isDisabled }) => {
24
24
  const canvas = colors.backgroundColor.main;
25
25
  const scale = scaleForColorScheme(colors, ctx.colorScheme);
26
26
  const style = resolveTabStyle(colors, scale, canvas, ctx.variant, isSelected);
27
- const spec = CONTROL_SIZES[ctx.size];
27
+ const spec = BUTTON_SIZES[ctx.size];
28
28
  // The list scrolls on both axes, so an outer ring is clipped into arcs; a negative offset draws it
29
29
  // inside the tab, clear of its own border rather than thickening it.
30
30
  const focusRing = {
@@ -6,9 +6,9 @@ import { AA_NON_TEXT, liftToContrast } from "../../Theme/tokens/builders/outline
6
6
  import { resolveFilledSurface } from "../../Theme/tokens/builders/filledSurface.js";
7
7
  import ToolTip from "../ToolTip/ToolTip.js";
8
8
  import { useSlidingPill } from "../SegmentedControl/useSlidingPill.js";
9
- import { CONTROL_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
9
+ import { BUTTON_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
10
10
  const MODES = ["grid", "list"];
11
- const TRACK_HEIGHT = CONTROL_SIZES.sm.height;
11
+ const TRACK_HEIGHT = BUTTON_SIZES.sm.height;
12
12
  const SEGMENT_HEIGHT = `calc(${TRACK_HEIGHT} - 0.25rem)`;
13
13
  /** Two icon-only IconButtons (Grid/List), aria-pressed marks the active one; shares variant with SegmentedControl (see MODULE.md). */
14
14
  const TableToggle = ({ value, onChange, variant = "default" }) => {
@@ -12,14 +12,14 @@ export const cssForScrollBar = (theme) => ({
12
12
  borderRadius: "0.5rem",
13
13
  },
14
14
  "&:hover::-webkit-scrollbar-thumb": {
15
- background: theme.colors.primary[500],
15
+ background: theme.colors.sidebar.mutedIcon,
16
16
  },
17
17
  "&:hover::-webkit-scrollbar-thumb:hover": {
18
- background: theme.colors.primary[700],
18
+ background: theme.colors.sidebar.mutedLabel,
19
19
  },
20
20
  scrollbarWidth: "none",
21
21
  "&:hover": {
22
22
  scrollbarWidth: "thin",
23
- scrollbarColor: `${theme.colors.primary[500]} ${theme.colors.sidebar.background[500]}`,
23
+ scrollbarColor: `${theme.colors.sidebar.mutedIcon} ${theme.colors.sidebar.background[500]}`,
24
24
  },
25
25
  });
@@ -1,5 +1,5 @@
1
1
  import { compositeOver } from "./color.js";
2
- import { liftToContrast, resolveHoverTint, AA_NON_TEXT } from "./outlineRung.js";
2
+ import { liftToContrast, resolveHoverTint, settleAcross, AA_NON_TEXT } from "./outlineRung.js";
3
3
  import { buildSemanticText } from "./semanticText.js";
4
4
  /** WCAG 1.4.3 — the active label is normal-size text. */
5
5
  export const AA_NORMAL_TEXT = 4.5;
@@ -18,13 +18,15 @@ export const sidebarDivider = (background) => resolveHoverTint(compositeOver(DIV
18
18
  export const buildSidebarTokens = (background, lightPrimary, semantic) => {
19
19
  const surface = sidebarActiveSurface(background);
20
20
  const elevated = resolveHoverTint(background[500], background[500]);
21
+ // Muted chrome must clear contrast on the bare rail AND the lightest row-hover overlay.
22
+ const rowPeak = sidebarRowPeak(elevated);
21
23
  return {
22
24
  background,
23
25
  elevated,
24
26
  activeIcon: liftToContrast(lightPrimary[300], surface, AA_NON_TEXT),
25
27
  activeLabel: liftToContrast(lightPrimary[100], surface, AA_NORMAL_TEXT),
26
- mutedIcon: liftToContrast(background[300], elevated, AA_NON_TEXT),
27
- mutedLabel: liftToContrast(background[100], elevated, AA_NORMAL_TEXT),
28
+ mutedIcon: settleAcross(background[300], [elevated, rowPeak], AA_NON_TEXT),
29
+ mutedLabel: settleAcross(background[100], [elevated, rowPeak], AA_NORMAL_TEXT),
28
30
  semanticText: buildSemanticText(semantic, elevated),
29
31
  hoverBg: sidebarHoverSurface(background),
30
32
  activeBg: surface,
@@ -1,8 +1,14 @@
1
- /** One height scale for fields, selects and buttons, so controls side by side line up. */
1
+ /** Height scale for form fields and selects — text inputs, pickers, anything typed or picked into. */
2
2
  export const CONTROL_SIZES = {
3
- xs: { height: "1.875rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
3
+ xs: { height: "1.5rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
4
4
  sm: { height: "2.375rem", fontSize: "0.8125rem", paddingX: "0.75rem", iconSize: 14 },
5
- md: { height: "2.625rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
5
+ md: { height: "2.5rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
6
+ lg: { height: "3rem", fontSize: "1rem", paddingX: "1.5rem", iconSize: 18 },
7
+ };
8
+ export const BUTTON_SIZES = {
9
+ xs: { height: "1.5rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
10
+ sm: { height: "2rem", fontSize: "0.8125rem", paddingX: "0.75rem", iconSize: 14 },
11
+ md: { height: "2.5rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
6
12
  lg: { height: "3rem", fontSize: "1rem", paddingX: "1.5rem", iconSize: 18 },
7
13
  };
8
14
  export const CONTROL_SIZE_NAMES = ["xs", "sm", "md", "lg"];
@@ -1,19 +1,19 @@
1
1
  /** One density for every option row — Select, SearchSelect, SelectSearch, table filters and Chakra's MenuItem. */
2
2
  export const OPTION_ROW_SIZES = {
3
3
  xs: {
4
- minH: "1.625rem", px: "0.5rem", py: "0.125rem", gap: "0.375rem", mx: "0.25rem",
4
+ minH: "1.5rem", px: "0.5rem", py: "0.125rem", gap: "0.375rem", mx: "0.25rem",
5
5
  fontSize: "0.75rem", descriptionFontSize: "0.6875rem", iconSize: 12,
6
- avatarSize: "2xs", virtualRowHeightPx: 26,
6
+ avatarSize: "2xs", virtualRowHeightPx: 24,
7
7
  },
8
8
  sm: {
9
- minH: "2rem", px: "0.625rem", py: "0.25rem", gap: "0.5rem", mx: "0.375rem",
9
+ minH: "1.875rem", px: "0.625rem", py: "0.25rem", gap: "0.5rem", mx: "0.375rem",
10
10
  fontSize: "0.8125rem", descriptionFontSize: "0.75rem", iconSize: 14,
11
- avatarSize: "xs", virtualRowHeightPx: 32,
11
+ avatarSize: "xs", virtualRowHeightPx: 30,
12
12
  },
13
13
  md: {
14
- minH: "2.25rem", px: "0.75rem", py: "0.3125rem", gap: "0.5rem", mx: "0.375rem",
14
+ minH: "2.125rem", px: "0.75rem", py: "0.3125rem", gap: "0.5rem", mx: "0.375rem",
15
15
  fontSize: "0.875rem", descriptionFontSize: "0.75rem", iconSize: 16,
16
- avatarSize: "xs", virtualRowHeightPx: 36,
16
+ avatarSize: "xs", virtualRowHeightPx: 34,
17
17
  },
18
18
  lg: {
19
19
  minH: "2.5rem", px: "0.875rem", py: "0.375rem", gap: "0.625rem", mx: "0.5rem",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.4.2-beta.53",
3
+ "version": "2.4.2-beta.55",
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",