pixelize-design-library 2.4.2-beta.40 → 2.4.2-beta.41

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.
@@ -972,10 +972,12 @@ matches either, even when the "same" stage is clearly intended.
972
972
  current `stages` list whenever it's filtered, and keep `id`/`value` the same primitive type at every
973
973
  call site.
974
974
 
975
- ### `Table`'s `isVisiblity`, `tableSettings`, `handleExportChange`/`exportOptions`/`exportLabel`, and `onColumnFilter` are dead props
975
+ ### `Table`'s `isVisiblity`, `tableSettings`, `handleExportChange`/`exportOptions`/`exportLabel`, and `onColumnFilter` are dead props — now `@deprecated`
976
976
 
977
- None of these do anything in the current implementation, despite being typed on `TableProps` (and
978
- some documented on the demo page):
977
+ Grepped account-frontend, tickets, crm-frontend, hrms and social-frontend: zero consumers set any of
978
+ these six. All six are now marked `@deprecated` in `TableProps.tsx` rather than removed outright, in
979
+ case an app outside those five repos relies on one. None of these do anything in the current
980
+ implementation, despite being typed on `TableProps` (and some documented on the demo page):
979
981
 
980
982
  - `isVisiblity` — `Table`'s own destructure never lists it, so a consumer's value is dropped. It's
981
983
  hardcoded `true` into both `Pagination` call sites regardless, and `Pagination` doesn't read it
@@ -1048,36 +1050,49 @@ consumer-managed state, not driven by this component resolving the promise.
1048
1050
  **Apply:** don't assume symmetry with the awaited callbacks in the same props interface; manage your
1049
1051
  own loading state for these three around the promise you return.
1050
1052
 
1051
- ### `OrganizationDetails`' `CreateOrgFormValues.default`/`defaultOrg` are dead fields
1053
+ ### `OrganizationDetails`' `CreateOrgFormValues.default`/`defaultOrg` are dead fields — now `@deprecated`
1052
1054
 
1053
1055
  The built-in `CreateOrgModal`'s internal state and submit handler never set or forward them, and the
1054
1056
  public `onCreateOrganization` callback's parameter type doesn't declare them at all — populating
1055
- them in a custom create form has no effect on the built-in flow.
1057
+ them in a custom create form has no effect on the built-in flow. account-frontend, the only real
1058
+ consumer of `OrganizationDetails`, never reads either field. Both are now `@deprecated` in
1059
+ `OrganizationDetailsProps.tsx`.
1056
1060
 
1057
1061
  **Apply:** don't rely on these two fields to pre-mark a newly created org as default.
1058
1062
 
1059
- ### `SideBar`'s `selectedSubMenu` prop is accepted but never read
1063
+ ### `SideBar`'s `selectedSubMenu` prop is accepted but never read — now `@deprecated`
1060
1064
 
1061
1065
  `SidebarProps.selectedSubMenu` is threaded through `SideBar` → `MenuItems` → `MenuItemBox`, but the
1062
- component's destructure never includes it — passing it has no effect of any kind.
1066
+ component's destructure never includes it — passing it has no effect of any kind. Zero consumers set
1067
+ it; now `@deprecated` in `SideBarProps.tsx`.
1063
1068
 
1064
1069
  **Apply:** don't pass `selectedSubMenu` expecting it to highlight a submenu row.
1065
1070
 
1066
- ### `SideBar`'s `locked` menu-item flag doesn't lock anything
1071
+ ### `KanbanBoard`'s `kanbanSelect`/`onOpen` don't check `permissions` — decision: accepted as-is
1067
1072
 
1068
- `MenuProps.locked` only swaps the trailing badge/chevron for a lock icon. The click handler checks
1069
- only `disabled` — a `locked: true, disabled: false` item still fully navigates/expands.
1073
+ Looked like an asymmetry with the gated `kanbanEdit`/`kanbanCreate`/`onDelete`, but on inspection
1074
+ `kanbanSelect` is a header filter dropdown (`options`/`onSelectChange`/`value`) — a view-level
1075
+ affordance, not a mutation trigger — and `onOpen` (opening a card) is a view action too. Both are
1076
+ already covered by the existing `permissions.isViewable` gate: the whole board (including the
1077
+ header) returns `null` before rendering when `isViewable` is `false`, so a viewer who can't see the
1078
+ board can't reach either. Gating them a second time against `isEditable`/`isCreatable`/`isDeletable`
1079
+ would be wrong — filtering/opening isn't an edit, create, or delete. No code change made.
1070
1080
 
1071
- **Apply:** set `disabled: true` alongside `locked: true` to actually prevent interaction.
1081
+ **Apply:** if you need `kanbanSelect` or `onOpen` gated on something narrower than view access, gate
1082
+ it yourself (e.g. `isSelect: canEdit`); the component won't do it for you.
1072
1083
 
1073
- ### `KanbanBoard`'s `kanbanSelect` ignores `permissions`, unlike `kanbanEdit`/`kanbanCreate`
1084
+ ### `SideBar`'s `locked` menu-item flag — decision: fixed to actually block interaction
1074
1085
 
1075
- `kanbanEdit`/`kanbanCreate` are only forwarded when `permissions.isEditable`/`isCreatable` allow it;
1076
- `kanbanSelect` is passed through unconditionally regardless of `permissions`. `onOpen` similarly has
1077
- no permission gate at all, asymmetric with the gated `onDelete`.
1086
+ Previously `locked` only swapped in a padlock icon; the click handler checked `disabled`, not
1087
+ `locked`, so a `locked: true` item still fully navigated. Zero consumers set `locked: true` in
1088
+ account-frontend, tickets, crm-frontend, hrms, social-frontend or crm-mobile, so there was no
1089
+ working behavior to preserve — the misleading name was a trap waiting for the first adopter. As of
1090
+ this release, `locked` blocks clicks/expansion the same way `disabled` does, in both the expanded
1091
+ sidebar (`MenuItemBox`) and the collapsed-sidebar flyout (`MenuPopoverContent`), for both top-level
1092
+ and submenu items. `disabled` is unchanged and still works independently.
1078
1093
 
1079
- **Apply:** gate `kanbanSelect.isSelect` (and any `onOpen` affordance) yourself if they should also be
1080
- permission-locked.
1094
+ **Apply:** `locked: true` alone now prevents interaction; you no longer need to also set
1095
+ `disabled: true`.
1081
1096
 
1082
1097
  ### `KanbanBoard`'s `permissions.isViewable: false` hides everything, including header actions
1083
1098
 
@@ -28,8 +28,9 @@ export type CreateOrgFormValues = {
28
28
  company_name: string;
29
29
  company_address: string;
30
30
  phone?: string;
31
- /** Never populated by the built-in CreateOrgModal — dead unless your own submit handler sets it. */
31
+ /** @deprecated Dead — never populated by the built-in CreateOrgModal, no known consumer usage. */
32
32
  default?: number;
33
+ /** @deprecated Dead — never populated by the built-in CreateOrgModal, no known consumer usage. */
33
34
  defaultOrg?: number;
34
35
  };
35
36
  /** All copy in OrganizationDetails is overridable here; unset fields fall back to its built-in DEFAULT_LABELS. */
@@ -25,7 +25,7 @@ export type SidebarProps = {
25
25
  /** true hides the Add New row completely, rather than disabling it. */
26
26
  isDisableAddNew?: boolean;
27
27
  onAddNewClick?: () => void;
28
- /** Threaded down to MenuItemBox but never read there — currently has no effect. */
28
+ /** @deprecated Dead — threaded down to MenuItemBox but never read there; no known consumer usage. */
29
29
  selectedSubMenu?: string | null;
30
30
  selectedSecondaryItem?: string | number | null;
31
31
  /** Shows skeleton rows instead of MenuItems; header and footer render normally. */
@@ -21,6 +21,9 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
21
21
  const theme = (0, useCustomTheme_1.useCustomTheme)();
22
22
  const activeAccent = (0, sidebarAccentColors_1.getSidebarActiveAccent)(theme.colors);
23
23
  const { title, icon, disabled, locked, badge, subMenu, url } = menu;
24
+ // `locked` blocks interaction the same as `disabled` — a locked item showing the padlock icon
25
+ // but still fully clickable was a real gotcha (see COMPONENT-GOTCHAS.md).
26
+ const isBlocked = disabled || locked;
24
27
  const hasSubMenu = !!(subMenu === null || subMenu === void 0 ? void 0 : subMenu.length);
25
28
  const submenuPanelId = `submenu-${String((_a = menu.id) !== null && _a !== void 0 ? _a : title)}`;
26
29
  // A submenu parent only expands, so it is a button; every other row navigates.
@@ -40,11 +43,11 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
40
43
  const isParentActive = activeMenu === menu.id;
41
44
  const isAnyActive = isParentActive || isChildActive;
42
45
  const handleToggleSubMenu = (e) => {
43
- if (!disabled && hasSubMenu) {
46
+ if (!isBlocked && hasSubMenu) {
44
47
  onToggle === null || onToggle === void 0 ? void 0 : onToggle(menu, e === null || e === void 0 ? void 0 : e.clientY);
45
48
  return;
46
49
  }
47
- if (!disabled)
50
+ if (!isBlocked)
48
51
  handleClick === null || handleClick === void 0 ? void 0 : handleClick(menu);
49
52
  };
50
53
  // Pill-style nav item. The fill is a white overlay, not a brand tint: the sidebar is a
@@ -68,14 +71,14 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
68
71
  borderLeft: "2px solid",
69
72
  borderLeftColor: isAnyActive ? theme.colors.sidebar.activeIcon : "transparent",
70
73
  backgroundColor: isAnyActive ? "whiteAlpha.300" : "transparent",
71
- color: disabled ? "whiteAlpha.400" : "whiteAlpha.700",
72
- _hover: disabled
74
+ color: isBlocked ? "whiteAlpha.400" : "whiteAlpha.700",
75
+ _hover: isBlocked
73
76
  ? {}
74
77
  : {
75
78
  backgroundColor: isAnyActive ? "whiteAlpha.400" : "whiteAlpha.200",
76
79
  },
77
- cursor: disabled ? "not-allowed" : "pointer",
78
- opacity: disabled ? 0.6 : 1,
80
+ cursor: isBlocked ? "not-allowed" : "pointer",
81
+ opacity: isBlocked ? 0.6 : 1,
79
82
  transition: "background 0.12s",
80
83
  };
81
84
  const buttonContent = ((0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", justify: toggle ? "center" : "space-between", children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { position: "relative", display: "flex", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: icon, fontSize: "1rem", verticalAlign: "middle", color: isAnyActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isAnyActive ? undefined : { color: "white" }, transition: "color 0.12s" }), toggle && (badgeValue != null || hasSubmenuBadge) && ((0, jsx_runtime_1.jsx)(react_1.Box, { position: "absolute", top: "0", right: "0", w: "0.375rem", h: "0.375rem", borderRadius: "full", bg: theme.colors.red[400] }))] }), !toggle && ((0, jsx_runtime_1.jsx)(TextTruncation_1.default
@@ -92,14 +95,14 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
92
95
  })(), locked && (0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "1rem", color: "whiteAlpha.600" }), hasSubMenu && ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: isOpen ? lucide_react_1.ChevronDown : lucide_react_1.ChevronRight, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon }))] }))] }));
93
96
  if (toggle) {
94
97
  // Collapsed sidebar: show Popover
95
- return ((0, jsx_runtime_1.jsxs)(react_1.Popover, { trigger: "hover", placement: "right-start", closeOnBlur: false, isLazy: true, children: [(0, jsx_runtime_1.jsx)(react_1.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_1.Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-label": title, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": disabled ? true : undefined, onClick: (e) => {
98
+ return ((0, jsx_runtime_1.jsxs)(react_1.Popover, { trigger: "hover", placement: "right-start", closeOnBlur: false, isLazy: true, children: [(0, jsx_runtime_1.jsx)(react_1.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_1.Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-label": title, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": isBlocked ? true : undefined, onClick: (e) => {
96
99
  if (!hasSubMenu && url && isBrowserNavigationGesture(e))
97
100
  return;
98
101
  e.preventDefault();
99
102
  handleToggleSubMenu(e);
100
- }, "data-menu-id": String((_d = menu.id) !== null && _d !== void 0 ? _d : title), children: buttonContent }) }), (0, jsx_runtime_1.jsx)(react_1.Portal, { children: (0, jsx_runtime_1.jsx)(react_1.PopoverContent, { borderRadius: "lg", bg: theme.colors.sidebar.elevated, boxShadow: "lg", minW: "10rem", maxW: "14rem", py: "0.125rem", ml: "-0.5rem", border: 'none', cursor: disabled ? "not-allowed" : "pointer", zIndex: 1500, children: (0, jsx_runtime_1.jsx)(react_1.PopoverBody, { p: "0.625rem", color: "white", children: (0, jsx_runtime_1.jsx)(MenuPopoverContent_1.default, { menu: menu, handleMenuClick: handleClick, activeMenu: activeMenu }) }) }) })] }));
103
+ }, "data-menu-id": String((_d = menu.id) !== null && _d !== void 0 ? _d : title), children: buttonContent }) }), (0, jsx_runtime_1.jsx)(react_1.Portal, { children: (0, jsx_runtime_1.jsx)(react_1.PopoverContent, { borderRadius: "lg", bg: theme.colors.sidebar.elevated, boxShadow: "lg", minW: "10rem", maxW: "14rem", py: "0.125rem", ml: "-0.5rem", border: 'none', cursor: isBlocked ? "not-allowed" : "pointer", zIndex: 1500, children: (0, jsx_runtime_1.jsx)(react_1.PopoverBody, { p: "0.625rem", color: "white", children: (0, jsx_runtime_1.jsx)(MenuPopoverContent_1.default, { menu: menu, handleMenuClick: handleClick, activeMenu: activeMenu }) }) }) })] }));
101
104
  }
102
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_1.Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-expanded": hasSubMenu ? !!isOpen : undefined, "aria-controls": hasSubMenu ? submenuPanelId : undefined, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": disabled ? true : undefined, onClick: (e) => {
105
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_1.Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-expanded": hasSubMenu ? !!isOpen : undefined, "aria-controls": hasSubMenu ? submenuPanelId : undefined, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": isBlocked ? true : undefined, onClick: (e) => {
103
106
  if (!hasSubMenu && url && isBrowserNavigationGesture(e))
104
107
  return;
105
108
  e.preventDefault();
@@ -111,11 +114,12 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
111
114
  }, children: subMenu.map((sub, sIdx) => {
112
115
  var _a, _b, _c;
113
116
  const isSubActive = activeMenu === sub.id;
114
- return ((0, jsx_runtime_1.jsxs)(react_1.Box, { as: "a", href: (_a = sub.url) !== null && _a !== void 0 ? _a : "#", "data-group": "", "aria-current": isSubActive ? "page" : undefined, "aria-disabled": sub.disabled ? true : undefined, textDecoration: "none", py: "5px", pl: "30px", pr: "10px", borderRadius: "md", fontSize: "11.5px", backgroundColor: "transparent", _hover: { backgroundColor: "whiteAlpha.100" }, opacity: sub.disabled ? 0.6 : 1, cursor: sub.disabled ? "not-allowed" : "pointer", pointerEvents: sub.disabled ? "none" : "auto", onClick: (e) => {
117
+ const isSubBlocked = sub.disabled || sub.locked;
118
+ return ((0, jsx_runtime_1.jsxs)(react_1.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", py: "5px", pl: "30px", pr: "10px", borderRadius: "md", fontSize: "11.5px", backgroundColor: "transparent", _hover: { backgroundColor: "whiteAlpha.100" }, opacity: isSubBlocked ? 0.6 : 1, cursor: isSubBlocked ? "not-allowed" : "pointer", pointerEvents: isSubBlocked ? "none" : "auto", onClick: (e) => {
115
119
  if (sub.url && isBrowserNavigationGesture(e))
116
120
  return;
117
121
  e.preventDefault();
118
- if (!sub.disabled)
122
+ if (!isSubBlocked)
119
123
  handleClick === null || handleClick === void 0 ? void 0 : handleClick(sub);
120
124
  }, display: "flex", alignItems: "center", justifyContent: "space-between", gap: "0.5rem", transition: "background 0.12s", children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: sub.icon, fontSize: "0.95rem", flexShrink: 0, color: isSubActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isSubActive ? undefined : { color: "white" }, transition: "color 0.12s" })) : ((0, jsx_runtime_1.jsx)(react_1.Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : "whiteAlpha.500", _groupHover: isSubActive ? undefined : { bg: "whiteAlpha.700" }, transition: "background 0.12s" })), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: "12px", fontWeight: isSubActive ? 600 : 500, lineHeight: "1",
121
125
  // open={isOpen}
@@ -13,15 +13,17 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
13
13
  var _a;
14
14
  const theme = (0, useCustomTheme_1.useCustomTheme)();
15
15
  const activeAccent = (0, sidebarAccentColors_1.getSidebarActiveAccent)(theme.colors);
16
- const { title, icon, subMenu, badge, locked } = menu;
16
+ const { title, icon, subMenu, badge, locked, disabled } = menu;
17
+ const isBlocked = disabled || locked;
17
18
  const hasSubMenu = !!(subMenu === null || subMenu === void 0 ? void 0 : subMenu.length);
18
19
  const isParentActive = activeMenu === menu.id;
19
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.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: "8px", px: "8px", py: hasSubMenu ? "6px" : "8px", mb: hasSubMenu ? "4px" : 0, borderBottom: hasSubMenu ? "1px solid" : undefined, borderColor: hasSubMenu ? "whiteAlpha.100" : undefined, borderRadius: hasSubMenu ? "none" : "md", bg: !hasSubMenu && isParentActive ? "whiteAlpha.300" : "transparent", _hover: !hasSubMenu ? { bg: "whiteAlpha.100" } : undefined, onClick: (e) => {
20
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.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: "8px", px: "8px", py: hasSubMenu ? "6px" : "8px", mb: hasSubMenu ? "4px" : 0, borderBottom: hasSubMenu ? "1px solid" : undefined, borderColor: hasSubMenu ? "whiteAlpha.100" : undefined, borderRadius: hasSubMenu ? "none" : "md", bg: !hasSubMenu && isParentActive ? "whiteAlpha.300" : "transparent", _hover: !hasSubMenu && !isBlocked ? { bg: "whiteAlpha.100" } : undefined, onClick: (e) => {
20
21
  if (!hasSubMenu) {
21
22
  e.preventDefault();
22
- handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(menu);
23
+ if (!isBlocked)
24
+ handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(menu);
23
25
  }
24
- }, cursor: !hasSubMenu ? "pointer" : "default", children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: icon, fontSize: "1rem", flexShrink: 0, color: !hasSubMenu && isParentActive ? activeAccent.icon : "whiteAlpha.700" }), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontWeight: 600, fontSize: "13px", flex: "1", color: theme.colors.white, children: title }), (() => {
26
+ }, cursor: !hasSubMenu ? (isBlocked ? "not-allowed" : "pointer") : "default", "aria-disabled": !hasSubMenu && isBlocked ? true : undefined, children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: icon, fontSize: "1rem", flexShrink: 0, color: !hasSubMenu && isParentActive ? activeAccent.icon : "whiteAlpha.700" }), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontWeight: 600, fontSize: "13px", flex: "1", color: theme.colors.white, children: title }), (() => {
25
27
  var _a, _b, _c, _d;
26
28
  const cfg = typeof badge === "object" && badge !== null
27
29
  ? badge
@@ -34,14 +36,15 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
34
36
  })(), locked && (0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon })] }), subMenu === null || subMenu === void 0 ? void 0 : subMenu.map((sub) => {
35
37
  var _a;
36
38
  const isSubActive = activeMenu === sub.id;
37
- return ((0, jsx_runtime_1.jsxs)(react_1.Flex, { as: "a", href: (_a = sub.url) !== null && _a !== void 0 ? _a : "#", "data-group": "", "aria-current": isSubActive ? "page" : undefined, "aria-disabled": sub.disabled ? true : undefined, textDecoration: "none", onClick: (e) => {
39
+ const isSubBlocked = sub.disabled || sub.locked;
40
+ return ((0, jsx_runtime_1.jsxs)(react_1.Flex, { 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", onClick: (e) => {
38
41
  e.preventDefault();
39
- if (!sub.disabled)
42
+ if (!isSubBlocked)
40
43
  handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(sub);
41
44
  }, px: "8px", py: "7px", mb: "2px", borderRadius: "md", align: "center", justify: "space-between", gap: "8px", borderLeft: "2px solid", borderLeftColor: isSubActive ? theme.colors.sidebar.activeIcon : "transparent", bg: isSubActive ? "whiteAlpha.300" : "transparent", _hover: {
42
- bg: !sub.disabled ? "whiteAlpha.100" : "transparent",
43
- cursor: !sub.disabled ? "pointer" : "not-allowed",
44
- }, opacity: sub.disabled ? 0.5 : 1, pointerEvents: sub.disabled ? "none" : "auto", transition: "background 0.12s", children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: sub.icon, fontSize: "0.95rem", flexShrink: 0, color: isSubActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isSubActive ? undefined : { color: "white" }, transition: "color 0.12s" }), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: "12.5px", fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: "white" }, children: sub.title })] }), sub.locked ? ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon })) : (() => {
45
+ bg: !isSubBlocked ? "whiteAlpha.100" : "transparent",
46
+ cursor: !isSubBlocked ? "pointer" : "not-allowed",
47
+ }, opacity: isSubBlocked ? 0.5 : 1, pointerEvents: isSubBlocked ? "none" : "auto", transition: "background 0.12s", children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: sub.icon, fontSize: "0.95rem", flexShrink: 0, color: isSubActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isSubActive ? undefined : { color: "white" }, transition: "color 0.12s" }), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: "12.5px", fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: "white" }, children: sub.title })] }), sub.locked ? ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon })) : (() => {
45
48
  var _a, _b, _c, _d;
46
49
  const cfg = typeof sub.badge === "object" && sub.badge !== null
47
50
  ? sub.badge
@@ -29,14 +29,14 @@ export type TableProps = {
29
29
  /** Accepted and forwarded to TableBody but never read there — no visual effect (see COMPONENT-GOTCHAS.md). */
30
30
  stripe?: boolean;
31
31
  emptyState?: TableEmptyState | ReactNode;
32
- /** Dead prop — Table renders no export UI and never reads this; declared for a feature that was never wired up. */
32
+ /** @deprecated Dead — Table renders no export UI and never reads this; no known consumer usage. */
33
33
  handleExportChange?: (value: string) => void | undefined;
34
- /** Dead prop — same unwired export feature as handleExportChange/exportLabel. */
34
+ /** @deprecated Dead — same unwired export feature as handleExportChange/exportLabel. */
35
35
  exportOptions?: ExportOption[];
36
- /** Dead prop — same unwired export feature as handleExportChange/exportOptions. */
36
+ /** @deprecated Dead — same unwired export feature as handleExportChange/exportOptions. */
37
37
  exportLabel?: string;
38
38
  isLoading?: boolean;
39
- /** sic — misspelling of isVisibility, kept for backward compat. Dead: Table never destructures it, so it has no effect. */
39
+ /** @deprecated Dead — misspelling of isVisibility; Table never destructures it, no effect, no known consumer usage. */
40
40
  isVisiblity?: boolean;
41
41
  isCheckbox?: boolean;
42
42
  headerBgColor?: string;
@@ -81,11 +81,11 @@ export type TableProps = {
81
81
  loadingSkeletonRows?: number;
82
82
  headerActions?: HeaderActionsProps;
83
83
  onGlobalSearch?: (searchVal: string) => void;
84
- /** Dead prop — Table.tsx has it commented out of its own destructure; never called. */
84
+ /** @deprecated Dead — Table.tsx has it commented out of its own destructure; never called, no known consumer usage. */
85
85
  onColumnFilter?: (filters: FilterValues) => void;
86
86
  /** Gates the Settings gear (Density / Manage Columns / Group) — the real switch for column-visibility UI, unlike tableSettings or isVisiblity. */
87
87
  isTableSettings?: boolean;
88
- /** Dead prop — TableSettings receives it but never destructures it; these fields currently do nothing. */
88
+ /** @deprecated Dead — TableSettings receives it but never destructures it; no known consumer usage. */
89
89
  tableSettings?: {
90
90
  filters?: string[];
91
91
  filterSelected?: string[];
@@ -16,6 +16,9 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
16
16
  const theme = useCustomTheme();
17
17
  const activeAccent = getSidebarActiveAccent(theme.colors);
18
18
  const { title, icon, disabled, locked, badge, subMenu, url } = menu;
19
+ // `locked` blocks interaction the same as `disabled` — a locked item showing the padlock icon
20
+ // but still fully clickable was a real gotcha (see COMPONENT-GOTCHAS.md).
21
+ const isBlocked = disabled || locked;
19
22
  const hasSubMenu = !!(subMenu === null || subMenu === void 0 ? void 0 : subMenu.length);
20
23
  const submenuPanelId = `submenu-${String((_a = menu.id) !== null && _a !== void 0 ? _a : title)}`;
21
24
  // A submenu parent only expands, so it is a button; every other row navigates.
@@ -35,11 +38,11 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
35
38
  const isParentActive = activeMenu === menu.id;
36
39
  const isAnyActive = isParentActive || isChildActive;
37
40
  const handleToggleSubMenu = (e) => {
38
- if (!disabled && hasSubMenu) {
41
+ if (!isBlocked && hasSubMenu) {
39
42
  onToggle === null || onToggle === void 0 ? void 0 : onToggle(menu, e === null || e === void 0 ? void 0 : e.clientY);
40
43
  return;
41
44
  }
42
- if (!disabled)
45
+ if (!isBlocked)
43
46
  handleClick === null || handleClick === void 0 ? void 0 : handleClick(menu);
44
47
  };
45
48
  // Pill-style nav item. The fill is a white overlay, not a brand tint: the sidebar is a
@@ -63,14 +66,14 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
63
66
  borderLeft: "2px solid",
64
67
  borderLeftColor: isAnyActive ? theme.colors.sidebar.activeIcon : "transparent",
65
68
  backgroundColor: isAnyActive ? "whiteAlpha.300" : "transparent",
66
- color: disabled ? "whiteAlpha.400" : "whiteAlpha.700",
67
- _hover: disabled
69
+ color: isBlocked ? "whiteAlpha.400" : "whiteAlpha.700",
70
+ _hover: isBlocked
68
71
  ? {}
69
72
  : {
70
73
  backgroundColor: isAnyActive ? "whiteAlpha.400" : "whiteAlpha.200",
71
74
  },
72
- cursor: disabled ? "not-allowed" : "pointer",
73
- opacity: disabled ? 0.6 : 1,
75
+ cursor: isBlocked ? "not-allowed" : "pointer",
76
+ opacity: isBlocked ? 0.6 : 1,
74
77
  transition: "background 0.12s",
75
78
  };
76
79
  const buttonContent = (_jsxs(Flex, { align: "center", gap: "9px", justify: toggle ? "center" : "space-between", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", children: [_jsxs(Box, { position: "relative", display: "flex", alignItems: "center", children: [_jsx(Icon, { as: icon, fontSize: "1rem", verticalAlign: "middle", color: isAnyActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isAnyActive ? undefined : { color: "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
@@ -87,14 +90,14 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
87
90
  })(), locked && _jsx(Icon, { as: LockKeyhole, fontSize: "1rem", color: "whiteAlpha.600" }), hasSubMenu && (_jsx(Icon, { as: isOpen ? ChevronDown : ChevronRight, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon }))] }))] }));
88
91
  if (toggle) {
89
92
  // Collapsed sidebar: show Popover
90
- return (_jsxs(Popover, { trigger: "hover", placement: "right-start", closeOnBlur: false, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsx(Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-label": title, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": disabled ? true : undefined, onClick: (e) => {
93
+ return (_jsxs(Popover, { trigger: "hover", placement: "right-start", closeOnBlur: false, isLazy: true, children: [_jsx(PopoverTrigger, { children: _jsx(Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-label": title, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": isBlocked ? true : undefined, onClick: (e) => {
91
94
  if (!hasSubMenu && url && isBrowserNavigationGesture(e))
92
95
  return;
93
96
  e.preventDefault();
94
97
  handleToggleSubMenu(e);
95
- }, "data-menu-id": String((_d = menu.id) !== null && _d !== void 0 ? _d : title), children: buttonContent }) }), _jsx(Portal, { children: _jsx(PopoverContent, { borderRadius: "lg", bg: theme.colors.sidebar.elevated, boxShadow: "lg", minW: "10rem", maxW: "14rem", py: "0.125rem", ml: "-0.5rem", border: 'none', cursor: disabled ? "not-allowed" : "pointer", zIndex: 1500, children: _jsx(PopoverBody, { p: "0.625rem", color: "white", children: _jsx(MenuPopoverContent, { menu: menu, handleMenuClick: handleClick, activeMenu: activeMenu }) }) }) })] }));
98
+ }, "data-menu-id": String((_d = menu.id) !== null && _d !== void 0 ? _d : title), children: buttonContent }) }), _jsx(Portal, { children: _jsx(PopoverContent, { borderRadius: "lg", bg: theme.colors.sidebar.elevated, boxShadow: "lg", minW: "10rem", maxW: "14rem", py: "0.125rem", ml: "-0.5rem", border: 'none', cursor: isBlocked ? "not-allowed" : "pointer", zIndex: 1500, children: _jsx(PopoverBody, { p: "0.625rem", color: "white", children: _jsx(MenuPopoverContent, { menu: menu, handleMenuClick: handleClick, activeMenu: activeMenu }) }) }) })] }));
96
99
  }
97
- return (_jsxs(_Fragment, { children: [_jsx(Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-expanded": hasSubMenu ? !!isOpen : undefined, "aria-controls": hasSubMenu ? submenuPanelId : undefined, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": disabled ? true : undefined, onClick: (e) => {
100
+ return (_jsxs(_Fragment, { children: [_jsx(Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-expanded": hasSubMenu ? !!isOpen : undefined, "aria-controls": hasSubMenu ? submenuPanelId : undefined, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": isBlocked ? true : undefined, onClick: (e) => {
98
101
  if (!hasSubMenu && url && isBrowserNavigationGesture(e))
99
102
  return;
100
103
  e.preventDefault();
@@ -106,11 +109,12 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
106
109
  }, children: subMenu.map((sub, sIdx) => {
107
110
  var _a, _b, _c;
108
111
  const isSubActive = activeMenu === sub.id;
109
- return (_jsxs(Box, { as: "a", href: (_a = sub.url) !== null && _a !== void 0 ? _a : "#", "data-group": "", "aria-current": isSubActive ? "page" : undefined, "aria-disabled": sub.disabled ? true : undefined, textDecoration: "none", py: "5px", pl: "30px", pr: "10px", borderRadius: "md", fontSize: "11.5px", backgroundColor: "transparent", _hover: { backgroundColor: "whiteAlpha.100" }, opacity: sub.disabled ? 0.6 : 1, cursor: sub.disabled ? "not-allowed" : "pointer", pointerEvents: sub.disabled ? "none" : "auto", onClick: (e) => {
112
+ const isSubBlocked = sub.disabled || sub.locked;
113
+ 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", py: "5px", pl: "30px", pr: "10px", borderRadius: "md", fontSize: "11.5px", backgroundColor: "transparent", _hover: { backgroundColor: "whiteAlpha.100" }, opacity: isSubBlocked ? 0.6 : 1, cursor: isSubBlocked ? "not-allowed" : "pointer", pointerEvents: isSubBlocked ? "none" : "auto", onClick: (e) => {
110
114
  if (sub.url && isBrowserNavigationGesture(e))
111
115
  return;
112
116
  e.preventDefault();
113
- if (!sub.disabled)
117
+ if (!isSubBlocked)
114
118
  handleClick === null || handleClick === void 0 ? void 0 : handleClick(sub);
115
119
  }, display: "flex", alignItems: "center", justifyContent: "space-between", gap: "0.5rem", transition: "background 0.12s", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? (_jsx(Icon, { as: sub.icon, fontSize: "0.95rem", flexShrink: 0, color: isSubActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isSubActive ? undefined : { color: "white" }, transition: "color 0.12s" })) : (_jsx(Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : "whiteAlpha.500", _groupHover: isSubActive ? undefined : { bg: "whiteAlpha.700" }, transition: "background 0.12s" })), _jsx(TruncatedTextWithTooltip, { fontSize: "12px", fontWeight: isSubActive ? 600 : 500, lineHeight: "1",
116
120
  // open={isOpen}
@@ -8,15 +8,17 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
8
8
  var _a;
9
9
  const theme = useCustomTheme();
10
10
  const activeAccent = getSidebarActiveAccent(theme.colors);
11
- const { title, icon, subMenu, badge, locked } = menu;
11
+ const { title, icon, subMenu, badge, locked, disabled } = menu;
12
+ const isBlocked = disabled || locked;
12
13
  const hasSubMenu = !!(subMenu === null || subMenu === void 0 ? void 0 : subMenu.length);
13
14
  const isParentActive = activeMenu === menu.id;
14
- 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: "8px", px: "8px", py: hasSubMenu ? "6px" : "8px", mb: hasSubMenu ? "4px" : 0, borderBottom: hasSubMenu ? "1px solid" : undefined, borderColor: hasSubMenu ? "whiteAlpha.100" : undefined, borderRadius: hasSubMenu ? "none" : "md", bg: !hasSubMenu && isParentActive ? "whiteAlpha.300" : "transparent", _hover: !hasSubMenu ? { bg: "whiteAlpha.100" } : undefined, onClick: (e) => {
15
+ 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: "8px", px: "8px", py: hasSubMenu ? "6px" : "8px", mb: hasSubMenu ? "4px" : 0, borderBottom: hasSubMenu ? "1px solid" : undefined, borderColor: hasSubMenu ? "whiteAlpha.100" : undefined, borderRadius: hasSubMenu ? "none" : "md", bg: !hasSubMenu && isParentActive ? "whiteAlpha.300" : "transparent", _hover: !hasSubMenu && !isBlocked ? { bg: "whiteAlpha.100" } : undefined, onClick: (e) => {
15
16
  if (!hasSubMenu) {
16
17
  e.preventDefault();
17
- handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(menu);
18
+ if (!isBlocked)
19
+ handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(menu);
18
20
  }
19
- }, cursor: !hasSubMenu ? "pointer" : "default", children: [_jsx(Icon, { as: icon, fontSize: "1rem", flexShrink: 0, color: !hasSubMenu && isParentActive ? activeAccent.icon : "whiteAlpha.700" }), _jsx(TruncatedTextWithTooltip, { fontWeight: 600, fontSize: "13px", flex: "1", color: theme.colors.white, children: title }), (() => {
21
+ }, cursor: !hasSubMenu ? (isBlocked ? "not-allowed" : "pointer") : "default", "aria-disabled": !hasSubMenu && isBlocked ? true : undefined, children: [_jsx(Icon, { as: icon, fontSize: "1rem", flexShrink: 0, color: !hasSubMenu && isParentActive ? activeAccent.icon : "whiteAlpha.700" }), _jsx(TruncatedTextWithTooltip, { fontWeight: 600, fontSize: "13px", flex: "1", color: theme.colors.white, children: title }), (() => {
20
22
  var _a, _b, _c, _d;
21
23
  const cfg = typeof badge === "object" && badge !== null
22
24
  ? badge
@@ -29,14 +31,15 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
29
31
  })(), locked && _jsx(Icon, { as: LockKeyhole, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon })] }), subMenu === null || subMenu === void 0 ? void 0 : subMenu.map((sub) => {
30
32
  var _a;
31
33
  const isSubActive = activeMenu === sub.id;
32
- return (_jsxs(Flex, { as: "a", href: (_a = sub.url) !== null && _a !== void 0 ? _a : "#", "data-group": "", "aria-current": isSubActive ? "page" : undefined, "aria-disabled": sub.disabled ? true : undefined, textDecoration: "none", onClick: (e) => {
34
+ const isSubBlocked = sub.disabled || sub.locked;
35
+ return (_jsxs(Flex, { 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", onClick: (e) => {
33
36
  e.preventDefault();
34
- if (!sub.disabled)
37
+ if (!isSubBlocked)
35
38
  handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(sub);
36
39
  }, px: "8px", py: "7px", mb: "2px", borderRadius: "md", align: "center", justify: "space-between", gap: "8px", borderLeft: "2px solid", borderLeftColor: isSubActive ? theme.colors.sidebar.activeIcon : "transparent", bg: isSubActive ? "whiteAlpha.300" : "transparent", _hover: {
37
- bg: !sub.disabled ? "whiteAlpha.100" : "transparent",
38
- cursor: !sub.disabled ? "pointer" : "not-allowed",
39
- }, opacity: sub.disabled ? 0.5 : 1, pointerEvents: sub.disabled ? "none" : "auto", transition: "background 0.12s", children: [_jsxs(Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [_jsx(Icon, { as: sub.icon, fontSize: "0.95rem", flexShrink: 0, color: isSubActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isSubActive ? undefined : { color: "white" }, transition: "color 0.12s" }), _jsx(TruncatedTextWithTooltip, { fontSize: "12.5px", fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: "white" }, children: sub.title })] }), sub.locked ? (_jsx(Icon, { as: LockKeyhole, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon })) : (() => {
40
+ bg: !isSubBlocked ? "whiteAlpha.100" : "transparent",
41
+ cursor: !isSubBlocked ? "pointer" : "not-allowed",
42
+ }, 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: "0.95rem", flexShrink: 0, color: isSubActive ? activeAccent.icon : "whiteAlpha.800", _groupHover: isSubActive ? undefined : { color: "white" }, transition: "color 0.12s" }), _jsx(TruncatedTextWithTooltip, { fontSize: "12.5px", fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: "white" }, children: sub.title })] }), sub.locked ? (_jsx(Icon, { as: LockKeyhole, fontSize: "1rem", color: theme.colors.sidebar.mutedIcon })) : (() => {
40
43
  var _a, _b, _c, _d;
41
44
  const cfg = typeof sub.badge === "object" && sub.badge !== null
42
45
  ? sub.badge
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.4.2-beta.40",
3
+ "version": "2.4.2-beta.41",
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",