orcs-design-system 3.3.43 → 3.3.44

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.
@@ -353,6 +353,41 @@ export const circleVariantActionsMenu = () => /*#__PURE__*/_jsxs(ActionsMenu, {
353
353
  })]
354
354
  });
355
355
  circleVariantActionsMenu.storyName = "Circle Variant";
356
+ export const disabledActionsMenu = () => /*#__PURE__*/_jsxs(ActionsMenu, {
357
+ disabled: true,
358
+ children: [/*#__PURE__*/_jsx(ActionsMenuItem, {
359
+ href: "https://orchestrated.io/",
360
+ children: "Open details page"
361
+ }), /*#__PURE__*/_jsx(BrowserRouter, {
362
+ children: /*#__PURE__*/_jsx(ActionsMenuItem, {
363
+ as: Link,
364
+ to: "/",
365
+ children: "Edit"
366
+ })
367
+ }), /*#__PURE__*/_jsx(ActionsMenuItem, {
368
+ onClick: action("clicked"),
369
+ children: "Remove"
370
+ })]
371
+ });
372
+ disabledActionsMenu.storyName = "Disabled Default";
373
+ export const disabledCircleVariantActionsMenu = () => /*#__PURE__*/_jsxs(ActionsMenu, {
374
+ variant: "circle",
375
+ disabled: true,
376
+ children: [/*#__PURE__*/_jsx(ActionsMenuItem, {
377
+ href: "https://orchestrated.io/",
378
+ children: "Open details page"
379
+ }), /*#__PURE__*/_jsx(BrowserRouter, {
380
+ children: /*#__PURE__*/_jsx(ActionsMenuItem, {
381
+ as: Link,
382
+ to: "/",
383
+ children: "Edit"
384
+ })
385
+ }), /*#__PURE__*/_jsx(ActionsMenuItem, {
386
+ onClick: action("clicked"),
387
+ children: "Remove"
388
+ })]
389
+ });
390
+ disabledCircleVariantActionsMenu.storyName = "Disabled Circle Variant";
356
391
  defaultActionsMenu.__docgenInfo = {
357
392
  "description": "",
358
393
  "methods": [],
@@ -387,4 +422,14 @@ circleVariantActionsMenu.__docgenInfo = {
387
422
  "description": "",
388
423
  "methods": [],
389
424
  "displayName": "circleVariantActionsMenu"
425
+ };
426
+ disabledActionsMenu.__docgenInfo = {
427
+ "description": "",
428
+ "methods": [],
429
+ "displayName": "disabledActionsMenu"
430
+ };
431
+ disabledCircleVariantActionsMenu.__docgenInfo = {
432
+ "description": "",
433
+ "methods": [],
434
+ "displayName": "disabledCircleVariantActionsMenu"
390
435
  };
@@ -8,7 +8,6 @@ import useActionMenu from "./useActionMenu";
8
8
  import { crossFadeIn, beforeDotCollapsing, beforeDotExpanding, afterDotCollapsing, afterDotExpanding, beforeCrossExpanding, beforeCrossCollapsing, afterCrossExpanding, afterCrossCollapsing } from "./ActionsMenu.animations";
9
9
  import { FloatingFocusManager, FloatingPortal, useMergeRefs } from "@floating-ui/react";
10
10
  import { getFloatingUiRootElement, getFloatingUiZIndex } from "../../utils/floatingUiHelpers";
11
- import { variant } from "styled-system";
12
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
12
  const ActionMenuContext = /*#__PURE__*/createContext({});
14
13
  const StyledActionsMenuContainer = styled.div.withConfig({
@@ -22,27 +21,7 @@ const Wrapper = styled.div.withConfig({
22
21
  const Control = styled.button.withConfig({
23
22
  displayName: "ActionsMenu__Control",
24
23
  componentId: "sc-yvbni2-2"
25
- })(["position:relative;display:flex;align-items:center;justify-content:center;-moz-appearance:none;-webkit-appearance:none;appearance:none;box-shadow:none;text-decoration:none;text-align:center;border-radius:", ";transition:", ";cursor:pointer;width:30px;height:30px;&:hover,&:focus{outline:0;border-color:", ";}", " &[data-state=\"open\"] .actionsMenu__dots{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}&[data-state=\"open\"] .actionsMenu__cross{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}&[data-state=\"closed\"] .actionsMenu__dots{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}&[data-state=\"closed\"] .actionsMenu__cross{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}"], props => themeGet("radii.2")(props), props => themeGet("transition.transitionDefault")(props), props => themeGet("colors.primary")(props), variant({
26
- prop: "variant",
27
- variants: {
28
- default: {
29
- backgroundColor: "white",
30
- border: "solid 1px",
31
- borderColor: "greyLight",
32
- width: "30px",
33
- height: "30px",
34
- borderRadius: 2
35
- },
36
- circle: {
37
- backgroundColor: "greyDarkest",
38
- border: "solid 2px",
39
- borderColor: "greyDarkest",
40
- width: "35px",
41
- height: "35px",
42
- borderRadius: "50%"
43
- }
44
- }
45
- }), beforeDotCollapsing, afterDotCollapsing, beforeCrossExpanding, afterCrossExpanding, beforeDotExpanding, afterDotExpanding, beforeCrossCollapsing, afterCrossCollapsing);
24
+ })(["position:relative;display:flex;align-items:center;justify-content:center;-moz-appearance:none;-webkit-appearance:none;appearance:none;box-shadow:none;text-decoration:none;text-align:center;border-radius:", ";transition:", ";cursor:", ";width:", ";height:", ";border-radius:", ";border:", ";", " ", " &:hover,&:focus{outline:0;border-color:", ";}&[data-state=\"open\"] .actionsMenu__dots{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}&[data-state=\"open\"] .actionsMenu__cross{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}&[data-state=\"closed\"] .actionsMenu__dots{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}&[data-state=\"closed\"] .actionsMenu__cross{&:before{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}&:after{animation:500ms ", " cubic-bezier(0.68,-0.6,0.32,1.6) forwards;}}"], props => themeGet("radii.2")(props), props => themeGet("transition.transitionDefault")(props), props => props.disabled ? "not-allowed" : "pointer", props => props.variant === "circle" ? "35px" : "30px", props => props.variant === "circle" ? "35px" : "30px", props => props.variant === "circle" ? "50%" : themeGet("radii.2")(props), props => props.variant === "circle" ? "solid 2px" : "solid 1px", props => props.variant === "default" && css(["background-color:", ";border-color:", ";"], props.disabled ? themeGet("colors.greyLighter")(props) : "white", props.disabled ? themeGet("colors.greyLighter")(props) : themeGet("colors.greyLight")(props)), props => props.variant === "circle" && css(["background-color:", ";border-color:", ";"], props.disabled ? themeGet("colors.greyLighter")(props) : themeGet("colors.greyDarkest")(props), props.disabled ? themeGet("colors.greyLighter")(props) : themeGet("colors.greyDarkest")(props)), props => props.disabled ? themeGet("colors.greyLighter")(props) : themeGet("colors.primary")(props), beforeDotCollapsing, afterDotCollapsing, beforeCrossExpanding, afterCrossExpanding, beforeDotExpanding, afterDotExpanding, beforeCrossCollapsing, afterCrossCollapsing);
46
25
  const Dots = styled.div.withConfig({
47
26
  displayName: "ActionsMenu__Dots",
48
27
  componentId: "sc-yvbni2-3"
@@ -150,6 +129,7 @@ export const ActionsMenuBody = _ref2 => {
150
129
  closeOnClick = false,
151
130
  "data-testid": dataTestId = "ActionsMenu",
152
131
  variant = "default",
132
+ disabled = false,
153
133
  ...props
154
134
  } = _ref2;
155
135
  const id = useId();
@@ -169,17 +149,19 @@ export const ActionsMenuBody = _ref2 => {
169
149
  "aria-label": ariaLabel,
170
150
  onFocus: onTriggerFocus,
171
151
  id,
152
+ disabled,
172
153
  ...actionMenu.getReferenceProps({
173
154
  ...props,
174
- onClick: onToggle,
155
+ onClick: disabled ? undefined : onToggle,
175
156
  ref: triggerRef,
176
157
  "data-state": actionMenu.open ? "open" : "closed",
177
158
  "data-testid": dataTestId
178
159
  })
179
- }), [ariaLabel, onTriggerFocus, id, actionMenu, onToggle, props, triggerRef, dataTestId]);
160
+ }), [ariaLabel, onTriggerFocus, id, actionMenu, onToggle, props, triggerRef, dataTestId, disabled]);
180
161
  let triggerComponent = /*#__PURE__*/_jsxs(Control, {
181
162
  ...triggerProps,
182
163
  variant: variant,
164
+ disabled: disabled,
183
165
  children: [/*#__PURE__*/_jsx(Dots, {
184
166
  className: "actionsMenu__dots",
185
167
  variant: variant
@@ -283,7 +265,8 @@ ActionsMenuBody.propTypes = {
283
265
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
284
266
  theme: PropTypes.object,
285
267
  ariaLabel: PropTypes.string,
286
- variant: PropTypes.oneOf(["default", "circle"])
268
+ variant: PropTypes.oneOf(["default", "circle"]),
269
+ disabled: PropTypes.bool
287
270
  };
288
271
  const ActionsMenu = /*#__PURE__*/React.forwardRef((props, ref) => {
289
272
  const [toggleState, setToggle] = useState(false);
@@ -316,7 +299,9 @@ ActionsMenu.propTypes = {
316
299
  /** Specifies the aria-label for the button */
317
300
  ariaLabel: PropTypes.string,
318
301
  /** Specifies the variant of the ActionsMenu */
319
- variant: PropTypes.oneOf(["default", "circle"])
302
+ variant: PropTypes.oneOf(["default", "circle"]),
303
+ /** Specifies whether the ActionsMenu is disabled */
304
+ disabled: PropTypes.bool
320
305
  };
321
306
  ActionsMenu.__docgenInfo = {
322
307
  "description": "",
@@ -437,6 +422,13 @@ ActionsMenu.__docgenInfo = {
437
422
  }]
438
423
  },
439
424
  "required": false
425
+ },
426
+ "disabled": {
427
+ "description": "Specifies whether the ActionsMenu is disabled",
428
+ "type": {
429
+ "name": "bool"
430
+ },
431
+ "required": false
440
432
  }
441
433
  }
442
434
  };
@@ -508,6 +500,17 @@ ActionsMenuBody.__docgenInfo = {
508
500
  },
509
501
  "required": false
510
502
  },
503
+ "disabled": {
504
+ "defaultValue": {
505
+ "value": "false",
506
+ "computed": false
507
+ },
508
+ "description": "",
509
+ "type": {
510
+ "name": "bool"
511
+ },
512
+ "required": false
513
+ },
511
514
  "onTriggerFocus": {
512
515
  "description": "",
513
516
  "type": {
@@ -94,6 +94,7 @@ export default function Popover(_ref) {
94
94
  withFocusControl = true,
95
95
  offset: customOffset,
96
96
  headerAvatarSizing,
97
+ disabled,
97
98
  ...props
98
99
  } = _ref;
99
100
  const [visible, setVisible] = useState(false);
@@ -131,7 +132,7 @@ export default function Popover(_ref) {
131
132
  context
132
133
  } = useFloating({
133
134
  open: visible,
134
- onOpenChange: setVisible,
135
+ onOpenChange: disabled ? () => {} : setVisible,
135
136
  placement: DIRECTIONS_MAP[direction] || direction || "right",
136
137
  whileElementsMounted: autoUpdate,
137
138
  middleware
@@ -271,7 +272,9 @@ Popover.propTypes = {
271
272
  /** Custom offset configuration for the popover positioning. Can be an object with mainAxis and/or alignmentAxis properties, or a function that returns an offset object. */
272
273
  offset: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
273
274
  /** Special prop for Header Avatar to apply CSS-based positioning adjustments when sizing changes dynamically */
274
- headerAvatarSizing: PropTypes.oneOf(["large", "default", "small"])
275
+ headerAvatarSizing: PropTypes.oneOf(["large", "default", "small"]),
276
+ /** Disable the popover */
277
+ disabled: PropTypes.bool
275
278
  };
276
279
  Popover.__docgenInfo = {
277
280
  "description": "",
@@ -431,6 +434,13 @@ Popover.__docgenInfo = {
431
434
  }]
432
435
  },
433
436
  "required": false
437
+ },
438
+ "disabled": {
439
+ "description": "Disable the popover",
440
+ "type": {
441
+ "name": "bool"
442
+ },
443
+ "required": false
434
444
  }
435
445
  }
436
446
  };
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useMemo } from "react";
2
2
  import styled, { css as styledCss } from "styled-components";
3
3
  import { css } from "@styled-system/css";
4
4
  import { themeGet } from "@styled-system/theme-get";
@@ -10,7 +10,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const sharedNavItemStyles = styledCss(["cursor:pointer;padding:", ";text-decoration:none;border-radius:", ";width:100%;position:relative;border:none;path{transition:", ";fill:", ";}font-family:", ";display:flex;align-items:center;justify-content:center;transition:", ";background-color:transparent;font-size:1.4rem;font-weight:", ";&:hover,&:focus{color:", ";path{fill:", ";}}@media screen and (max-width:", "px){width:auto;max-height:30px;height:30px;}&:focus{outline:0;color:", ";path{fill:", ";}}"], themeGet("space.s"), themeGet("radii.2"), themeGet("transition.transitionDefault"), themeGet("colors.greyDarker"), themeGet("fonts.main"), themeGet("transition.transitionDefault"), themeGet("fontWeights.1"), themeGet("colors.primary"), themeGet("colors.primary"), BREAKPOINTS.SMALL_SCREEN, themeGet("colors.primary"), themeGet("colors.primary"));
11
11
  const expandedNavItemStyles = props => styledCss(["justify-content:flex-start;gap:", ";.nav-item-text{font-size:", ";line-height:1;font-weight:", ";color:", ";white-space:nowrap;text-overflow:ellipsis;}&:hover .nav-item-text,&:focus .nav-item-text{color:", ";}"], themeGet("space.s"), themeGet("fontSizes.1"), themeGet("fontWeights.1"), props.active ? themeGet("colors.greyDarkest") : themeGet("colors.greyDarker"), props.active ? themeGet("colors.greyDarkest") : themeGet("colors.primary"));
12
12
  const variantActiveStyles = {
13
- expandableItem: props => styledCss(["color:", ";path{fill:", ";}:after{height:100%;position:absolute;right:0;transform:", ";content:\"\";border-right:3px solid ", ";z-index:5;}@media screen and (max-width:", "px){:after{border-top:3px solid ", ";border-right:none;top:-16px;right:0;width:100%;}}"], themeGet("colors.greyDarkest"), themeGet("colors.greyDarkest"), props.isExpanded ? "translateX(8px)" : "translateX(10px)", themeGet("colors.primary"), BREAKPOINTS.SMALL_SCREEN, themeGet("colors.primary")),
13
+ expandableItem: props => styledCss(["color:", ";path{fill:", ";}:after{height:100%;position:absolute;right:0;transform:", ";content:\"\";border-right:3px solid ", ";z-index:5;}&:hover .nav-item-text,&:focus .nav-item-text{color:", ";}@media screen and (max-width:", "px){:after{border-top:3px solid ", ";border-right:none;transform:translateY(-10px);right:auto;width:100%;}}"], themeGet("colors.greyDarkest"), themeGet("colors.greyDarkest"), props.isExpanded ? "translateX(9px)" : "translateX(8px)", themeGet("colors.primary"), themeGet("colors.primary"), BREAKPOINTS.SMALL_SCREEN, themeGet("colors.primary")),
14
14
  default: styledCss(["background-color:", ";path{fill:", ";}&:hover,&:focus{path{fill:", ";}}&:focus{path{fill:", ";}}"], themeGet("colors.primaryLightest"), themeGet("colors.greyDarkest"), themeGet("colors.greyDarkest"), themeGet("colors.greyDarkest"))
15
15
  };
16
16
  const getActiveStyles = props => {
@@ -58,47 +58,12 @@ const BadgeDot = styled("div").withConfig({
58
58
  top: props.isExpanded ? "12px" : "2px",
59
59
  right: "0"
60
60
  }));
61
- const SideNavItemPopover = styled(Popover).withConfig({
62
- displayName: "NavItem__SideNavItemPopover",
61
+ const SideNavItemWrapper = styled.div.withConfig({
62
+ displayName: "NavItem__SideNavItemWrapper",
63
63
  componentId: "sc-1qz1q0h-4"
64
64
  })(props => css({
65
- [`@media screen and (min-width: ${BREAKPOINTS.SMALL_SCREEN}px)`]: {
66
- ":nth-child(1 of .bottom-aligned) ": {
67
- marginTop: props.bottomAligned && "auto"
68
- }
69
- },
70
- "&:hover,&:focus-within": {
71
- "& .popoverText": {
72
- opacity: "1",
73
- zIndex: "100",
74
- visibility: "visible",
75
- pointerEvents: "auto",
76
- display: "initial"
77
- }
78
- },
79
- "&:focus-within": {
80
- "& .popoverText": {
81
- opacity: props.active ? "0" : "1",
82
- zIndex: props.active ? "-100" : "100",
83
- visibility: props.active ? "hidden" : "visible",
84
- pointerEvents: props.active ? "none" : "auto",
85
- display: props.active ? "none" : "initial"
86
- }
87
- },
88
- [`@media screen and (max-width: ${BREAKPOINTS.SMALL_SCREEN}px)`]: {
89
- width: "auto",
90
- marginBottom: "0",
91
- marginTop: "0",
92
- "&:hover,&:focus-within": {
93
- "& .popoverText": {
94
- opacity: "0",
95
- zIndex: "-100",
96
- visibility: "hidden",
97
- pointerEvents: "none",
98
- justifyContent: "space-around",
99
- display: "none"
100
- }
101
- }
65
+ "&:nth-child(1 of .bottom-aligned) ": {
66
+ marginTop: props.bottomAligned && "auto"
102
67
  }
103
68
  }));
104
69
  const NavItem = _ref => {
@@ -111,56 +76,63 @@ const NavItem = _ref => {
111
76
  isSmallScreen,
112
77
  isExpanded
113
78
  } = _ref;
114
- // Use the ternary operator to render the appropriate component based on actionType
115
- const accessibilityProps = {
116
- ...(item.actionType === "component" && {
117
- "aria-expanded": isActive ? "true" : "false"
118
- }),
119
- "aria-label": item.name
120
- };
121
- return /*#__PURE__*/_jsx(SideNavItemPopover, {
122
- className: item.bottomAligned && "bottom-aligned",
123
- text: !isExpanded ? item.name : "",
124
- direction: isSmallScreen ? "top" : "right",
125
- textAlign: "center",
126
- width: "fit-content",
127
- tabIndex: "-1",
128
- active: isActive,
129
- bottomAligned: item.bottomAligned,
130
- children: item.actionType === "link" ? /*#__PURE__*/_jsx(SideNavItemLink, {
131
- active: isActive,
132
- bottomAligned: item.bottomAligned,
133
- isExpanded: isExpanded,
134
- onClick: () => handleItemClick(item),
135
- ref: el => navItemRefs.current[item.index] = el,
136
- children: /*#__PURE__*/_jsxs(Component, {
137
- item: item,
138
- children: [/*#__PURE__*/_jsx(Icon, {
79
+ const renderedNavItem = useMemo(() => {
80
+ const accessibilityProps = {
81
+ ...(item.actionType === "component" && {
82
+ "aria-expanded": isActive ? "true" : "false"
83
+ }),
84
+ "aria-label": item.name
85
+ };
86
+ if (item.actionType === "link") {
87
+ return /*#__PURE__*/_jsx(SideNavItemLink, {
88
+ active: isActive,
89
+ bottomAligned: item.bottomAligned,
90
+ isExpanded: isExpanded,
91
+ onClick: () => handleItemClick(item),
92
+ ref: el => navItemRefs.current[item.index] = el,
93
+ children: /*#__PURE__*/_jsxs(Component, {
94
+ item: item,
95
+ children: [/*#__PURE__*/_jsx(Icon, {
96
+ icon: ["far", item.iconName]
97
+ }), isExpanded && !isSmallScreen && /*#__PURE__*/_jsx("span", {
98
+ className: "nav-item-text",
99
+ children: item.name
100
+ })]
101
+ })
102
+ }, item.index);
103
+ } else {
104
+ return /*#__PURE__*/_jsxs(SideNavItem, {
105
+ active: isActive,
106
+ onClick: () => handleItemClick(item),
107
+ bottomAligned: item.bottomAligned,
108
+ isExpanded: isExpanded,
109
+ ...accessibilityProps,
110
+ ref: el => navItemRefs.current[item.index] = el,
111
+ children: [item.badgeNumber && /*#__PURE__*/_jsx(BadgeNumber, {
112
+ isExpanded: isExpanded,
113
+ children: item.badgeNumber
114
+ }), item.badgeDot && /*#__PURE__*/_jsx(BadgeDot, {
115
+ isExpanded: isExpanded
116
+ }), /*#__PURE__*/_jsx(Icon, {
139
117
  icon: ["far", item.iconName]
140
118
  }), isExpanded && !isSmallScreen && /*#__PURE__*/_jsx("span", {
141
119
  className: "nav-item-text",
142
120
  children: item.name
143
121
  })]
144
- })
145
- }, item.index) : /*#__PURE__*/_jsxs(SideNavItem, {
146
- active: isActive,
147
- onClick: () => handleItemClick(item),
148
- bottomAligned: item.bottomAligned,
149
- isExpanded: isExpanded,
150
- ...accessibilityProps,
151
- ref: el => navItemRefs.current[item.index] = el,
152
- children: [item.badgeNumber && /*#__PURE__*/_jsx(BadgeNumber, {
153
- isExpanded: isExpanded,
154
- children: item.badgeNumber
155
- }), item.badgeDot && /*#__PURE__*/_jsx(BadgeDot, {
156
- isExpanded: isExpanded
157
- }), /*#__PURE__*/_jsx(Icon, {
158
- icon: ["far", item.iconName]
159
- }), isExpanded && !isSmallScreen && /*#__PURE__*/_jsx("span", {
160
- className: "nav-item-text",
161
- children: item.name
162
- })]
163
- }, item.index)
122
+ }, item.index);
123
+ }
124
+ }, [item, isActive, isExpanded, isSmallScreen, handleItemClick, navItemRefs]);
125
+ return isSmallScreen ? /*#__PURE__*/_jsx(Popover, {
126
+ text: item.name,
127
+ direction: "top",
128
+ textAlign: "center",
129
+ width: "fit-content",
130
+ tabIndex: "-1",
131
+ children: renderedNavItem
132
+ }) : /*#__PURE__*/_jsx(SideNavItemWrapper, {
133
+ className: item.bottomAligned && "bottom-aligned",
134
+ bottomAligned: item.bottomAligned,
135
+ children: renderedNavItem
164
136
  });
165
137
  };
166
138
  NavItem.propTypes = {
@@ -33,17 +33,22 @@ const SideNavV2 = _ref => {
33
33
  expandedWidth,
34
34
  expandedRef,
35
35
  navItemRefs,
36
+ wrapperRef,
37
+ isLocked,
36
38
  handleItemClick,
37
39
  handleBlur,
38
- handleExpandToggle,
39
- handleWidthChange
40
+ handleWidthChange,
41
+ handleLockToggle
40
42
  } = useSideNavState(items);
41
43
  const {
42
44
  isSmallScreen
43
45
  } = useResponsive();
46
+
47
+ // Get the current expanded item
48
+ const currentItem = expandedItem !== null ? items[expandedItem] : null;
44
49
  const {
45
50
  handleResizeStart
46
- } = useResize(expandedRef, isSmallScreen, expandedItem, handleWidthChange);
51
+ } = useResize(expandedRef, isSmallScreen, expandedItem, handleWidthChange, currentItem);
47
52
 
48
53
  // Categorize items
49
54
  const {
@@ -53,17 +58,20 @@ const SideNavV2 = _ref => {
53
58
  allItems
54
59
  } = categorizeItems(items);
55
60
  return /*#__PURE__*/_jsxs(SideNavWrapper, {
61
+ ref: wrapperRef,
56
62
  sideNavHeight: sideNavHeight,
57
63
  children: [/*#__PURE__*/_jsxs(SideNavItems, {
58
64
  isExpanded: isExpanded,
59
65
  "data-testid": "side-nav-items",
60
66
  children: [!isSmallScreen && /*#__PURE__*/_jsx(PanelControlComponent, {
61
67
  isExpanded: isExpanded,
62
- onClick: handleExpandToggle,
63
- ariaLabel: "toggle side navigation",
68
+ isLocked: isLocked,
69
+ onClick: handleLockToggle,
70
+ ariaLabel: isLocked ? "unlock navigation" : isExpanded ? "lock navigation" : "open navigation",
64
71
  mt: "10px",
65
72
  mb: "4px",
66
- tooltipText: isExpanded ? "Collapse navigation" : "Expand navigation"
73
+ tooltipText: isLocked ? "Collapse" : isExpanded ? "Keep open" : "Expand navigation",
74
+ mode: "lock"
67
75
  }), /*#__PURE__*/_jsx(ItemSection, {
68
76
  items: topAlignedItems,
69
77
  isExpanded: isExpanded,
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { render, fireEvent } from "@testing-library/react";
3
3
  import "@testing-library/jest-dom";
4
+ import PropTypes from "prop-types";
4
5
  import useResize from "../hooks/useResize";
5
6
  import { calculateDesktopWidth, calculateMobileHeight } from "../utils/resizeUtils";
6
7
 
@@ -19,9 +20,10 @@ const TestComponent = _ref => {
19
20
  expandedRef,
20
21
  isSmallScreen,
21
22
  expandedItem,
22
- onWidthChange
23
+ onWidthChange,
24
+ currentItem
23
25
  } = _ref;
24
- const resizeHandlers = useResize(expandedRef, isSmallScreen, expandedItem, onWidthChange);
26
+ const resizeHandlers = useResize(expandedRef, isSmallScreen, expandedItem, onWidthChange, currentItem);
25
27
  return /*#__PURE__*/_jsxs("div", {
26
28
  children: [/*#__PURE__*/_jsx("div", {
27
29
  "data-testid": "resize-handle",
@@ -32,6 +34,13 @@ const TestComponent = _ref => {
32
34
  })]
33
35
  });
34
36
  };
37
+ TestComponent.propTypes = {
38
+ expandedRef: PropTypes.object,
39
+ isSmallScreen: PropTypes.bool,
40
+ expandedItem: PropTypes.number,
41
+ onWidthChange: PropTypes.func,
42
+ currentItem: PropTypes.number
43
+ };
35
44
  describe("useResize hook", () => {
36
45
  let mockExpandedRef;
37
46
  let mockOnWidthChange;
@@ -99,7 +108,7 @@ describe("useResize hook", () => {
99
108
  fireEvent.mouseMove(document, {
100
109
  clientX: 600
101
110
  });
102
- expect(calculateDesktopWidth).toHaveBeenCalledWith(600, expect.any(Object));
111
+ expect(calculateDesktopWidth).toHaveBeenCalledWith(600, expect.any(Object), undefined);
103
112
  expect(mockOnWidthChange).toHaveBeenCalledWith(400);
104
113
  });
105
114
  it("should handle mobile resize correctly", () => {