@carbon-labs/react-ui-shell 0.19.0 → 0.20.0

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.
@@ -96,23 +96,6 @@ const SideNavMenu = /*#__PURE__*/React.forwardRef(function SideNavMenu(_ref, ref
96
96
 
97
97
  // if depth is more than 0, that means its nested, thus we set treeview mode
98
98
  setIsTreeview?.(true);
99
- if (isTreeview) {
100
- const calcButtonOffset = () => {
101
- // menu with icon
102
- if (children && IconElement) {
103
- return depth + 3;
104
- }
105
-
106
- // menu without icon
107
- if (children) {
108
- return depth * 4;
109
- }
110
- return depth;
111
- };
112
- if (buttonRef.current) {
113
- buttonRef.current.style.paddingLeft = `${calcButtonOffset()}rem`;
114
- }
115
- }
116
99
  }, [isTreeview]);
117
100
 
118
101
  /**
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React, { ElementType, ComponentProps } from 'react';
7
+ import React, { ElementType, ComponentProps, ComponentType } from 'react';
8
8
  import Link from './Link';
9
9
  export interface SideNavMenuItemProps extends ComponentProps<typeof Link> {
10
10
  /**
@@ -15,11 +15,6 @@ export interface SideNavMenuItemProps extends ComponentProps<typeof Link> {
15
15
  * Provide an optional class to be applied to the containing node
16
16
  */
17
17
  className?: string;
18
- /**
19
- * **Note:** this is controlled by the parent SideNavMenu component, do not set manually.
20
- * SideNavMenu depth to determine spacing
21
- */
22
- depth?: number;
23
18
  /**
24
19
  * Optionally specify whether the link is "active". An active link is one that
25
20
  * has an href that is the same as the current page. Can also pass in
@@ -34,5 +29,9 @@ export interface SideNavMenuItemProps extends ComponentProps<typeof Link> {
34
29
  * Optional component to render instead of default Link
35
30
  */
36
31
  as?: ElementType;
32
+ /**
33
+ * Provide an icon to render in the side navigation link. Should be a React class.
34
+ */
35
+ renderIcon?: ComponentType;
37
36
  }
38
37
  export declare const SideNavMenuItem: React.ForwardRefExoticComponent<Omit<SideNavMenuItemProps, "ref"> & React.RefAttributes<HTMLElement>>;
@@ -8,11 +8,10 @@
8
8
  import { extends as _extends } from '../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import cx from '../_virtual/index.js';
10
10
  import PropTypes from 'prop-types';
11
- import React, { useContext, useRef, useEffect } from 'react';
12
- import { SideNavLinkText } from '@carbon/react';
11
+ import React, { useContext } from 'react';
12
+ import { SideNavIcon, SideNavLinkText } from '@carbon/react';
13
13
  import Link from './Link.js';
14
14
  import { usePrefix } from '../internal/usePrefix.js';
15
- import { useMergedRefs } from '../internal/useMergedRefs.js';
16
15
  import { SideNavContext } from './SideNav.js';
17
16
 
18
17
  const SideNavMenuItem = /*#__PURE__*/React.forwardRef(function SideNavMenuItem(props, ref) {
@@ -20,30 +19,19 @@ const SideNavMenuItem = /*#__PURE__*/React.forwardRef(function SideNavMenuItem(p
20
19
  const {
21
20
  children,
22
21
  className: customClassName,
23
- depth: propDepth,
24
22
  as: Component = Link,
25
23
  isActive,
24
+ renderIcon: IconElement,
26
25
  ...rest
27
26
  } = props;
28
27
  const {
29
28
  isTreeview
30
29
  } = useContext(SideNavContext);
31
30
  const className = cx(`${prefix}--side-nav__menu-item`, customClassName);
32
- const depth = propDepth;
33
31
  const linkClassName = cx({
34
32
  [`${prefix}--side-nav__link`]: true,
35
33
  [`${prefix}--side-nav__link--current`]: isActive
36
34
  });
37
- const linkRef = useRef(null);
38
- const itemRef = useMergedRefs([linkRef, ref]);
39
- useEffect(() => {
40
- const calcLinkOffset = () => {
41
- return 4 + Math.max(0, depth - 1) * 1;
42
- };
43
- if (linkRef.current) {
44
- linkRef.current.style.paddingLeft = `${calcLinkOffset()}rem`;
45
- }
46
- }, [isTreeview]);
47
35
  return /*#__PURE__*/React.createElement("li", {
48
36
  className: className
49
37
  }, /*#__PURE__*/React.createElement(Component, _extends({}, rest, {
@@ -51,11 +39,17 @@ const SideNavMenuItem = /*#__PURE__*/React.forwardRef(function SideNavMenuItem(p
51
39
  role: isTreeview ? 'treeitem' : undefined,
52
40
  className: linkClassName,
53
41
  tabIndex: isTreeview ? -1 : 0,
54
- ref: itemRef
55
- }), /*#__PURE__*/React.createElement(SideNavLinkText, null, children)));
42
+ ref: ref
43
+ }), IconElement && /*#__PURE__*/React.createElement(SideNavIcon, {
44
+ small: true
45
+ }, /*#__PURE__*/React.createElement(IconElement, null)), /*#__PURE__*/React.createElement(SideNavLinkText, null, children)));
56
46
  });
57
47
  SideNavMenuItem.displayName = 'SideNavMenuItem';
58
48
  SideNavMenuItem.propTypes = {
49
+ /**
50
+ * Optional component to render instead of default Link
51
+ */
52
+ as: PropTypes.elementType,
59
53
  /**
60
54
  * Specify the children to be rendered inside of the `SideNavMenuItem`
61
55
  */
@@ -64,11 +58,6 @@ SideNavMenuItem.propTypes = {
64
58
  * Provide an optional class to be applied to the containing node
65
59
  */
66
60
  className: PropTypes.string,
67
- /**
68
- * **Note:** this is controlled by the parent SideNavMenu component, do not set manually.
69
- * SideNavMenu depth to determine spacing
70
- */
71
- depth: PropTypes.number,
72
61
  /**
73
62
  * Optionally provide an href for the underlying li`
74
63
  */
@@ -80,9 +69,9 @@ SideNavMenuItem.propTypes = {
80
69
  */
81
70
  isActive: PropTypes.bool,
82
71
  /**
83
- * Optional component to render instead of default Link
72
+ * Provide an icon to render in the side navigation link. Should be a React class.
84
73
  */
85
- as: PropTypes.elementType
74
+ renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
86
75
  };
87
76
 
88
77
  export { SideNavMenuItem };
@@ -98,23 +98,6 @@ const SideNavMenu = /*#__PURE__*/React.forwardRef(function SideNavMenu(_ref, ref
98
98
 
99
99
  // if depth is more than 0, that means its nested, thus we set treeview mode
100
100
  setIsTreeview?.(true);
101
- if (isTreeview) {
102
- const calcButtonOffset = () => {
103
- // menu with icon
104
- if (children && IconElement) {
105
- return depth + 3;
106
- }
107
-
108
- // menu without icon
109
- if (children) {
110
- return depth * 4;
111
- }
112
- return depth;
113
- };
114
- if (buttonRef.current) {
115
- buttonRef.current.style.paddingLeft = `${calcButtonOffset()}rem`;
116
- }
117
- }
118
101
  }, [isTreeview]);
119
102
 
120
103
  /**
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import React, { ElementType, ComponentProps } from 'react';
7
+ import React, { ElementType, ComponentProps, ComponentType } from 'react';
8
8
  import Link from './Link';
9
9
  export interface SideNavMenuItemProps extends ComponentProps<typeof Link> {
10
10
  /**
@@ -15,11 +15,6 @@ export interface SideNavMenuItemProps extends ComponentProps<typeof Link> {
15
15
  * Provide an optional class to be applied to the containing node
16
16
  */
17
17
  className?: string;
18
- /**
19
- * **Note:** this is controlled by the parent SideNavMenu component, do not set manually.
20
- * SideNavMenu depth to determine spacing
21
- */
22
- depth?: number;
23
18
  /**
24
19
  * Optionally specify whether the link is "active". An active link is one that
25
20
  * has an href that is the same as the current page. Can also pass in
@@ -34,5 +29,9 @@ export interface SideNavMenuItemProps extends ComponentProps<typeof Link> {
34
29
  * Optional component to render instead of default Link
35
30
  */
36
31
  as?: ElementType;
32
+ /**
33
+ * Provide an icon to render in the side navigation link. Should be a React class.
34
+ */
35
+ renderIcon?: ComponentType;
37
36
  }
38
37
  export declare const SideNavMenuItem: React.ForwardRefExoticComponent<Omit<SideNavMenuItemProps, "ref"> & React.RefAttributes<HTMLElement>>;
@@ -14,7 +14,6 @@ var React = require('react');
14
14
  var react = require('@carbon/react');
15
15
  var Link = require('./Link.js');
16
16
  var usePrefix = require('../internal/usePrefix.js');
17
- var useMergedRefs = require('../internal/useMergedRefs.js');
18
17
  var SideNav = require('./SideNav.js');
19
18
 
20
19
  const SideNavMenuItem = /*#__PURE__*/React.forwardRef(function SideNavMenuItem(props, ref) {
@@ -22,30 +21,19 @@ const SideNavMenuItem = /*#__PURE__*/React.forwardRef(function SideNavMenuItem(p
22
21
  const {
23
22
  children,
24
23
  className: customClassName,
25
- depth: propDepth,
26
24
  as: Component = Link.default,
27
25
  isActive,
26
+ renderIcon: IconElement,
28
27
  ...rest
29
28
  } = props;
30
29
  const {
31
30
  isTreeview
32
31
  } = React.useContext(SideNav.SideNavContext);
33
32
  const className = index.default(`${prefix}--side-nav__menu-item`, customClassName);
34
- const depth = propDepth;
35
33
  const linkClassName = index.default({
36
34
  [`${prefix}--side-nav__link`]: true,
37
35
  [`${prefix}--side-nav__link--current`]: isActive
38
36
  });
39
- const linkRef = React.useRef(null);
40
- const itemRef = useMergedRefs.useMergedRefs([linkRef, ref]);
41
- React.useEffect(() => {
42
- const calcLinkOffset = () => {
43
- return 4 + Math.max(0, depth - 1) * 1;
44
- };
45
- if (linkRef.current) {
46
- linkRef.current.style.paddingLeft = `${calcLinkOffset()}rem`;
47
- }
48
- }, [isTreeview]);
49
37
  return /*#__PURE__*/React.createElement("li", {
50
38
  className: className
51
39
  }, /*#__PURE__*/React.createElement(Component, _rollupPluginBabelHelpers.extends({}, rest, {
@@ -53,11 +41,17 @@ const SideNavMenuItem = /*#__PURE__*/React.forwardRef(function SideNavMenuItem(p
53
41
  role: isTreeview ? 'treeitem' : undefined,
54
42
  className: linkClassName,
55
43
  tabIndex: isTreeview ? -1 : 0,
56
- ref: itemRef
57
- }), /*#__PURE__*/React.createElement(react.SideNavLinkText, null, children)));
44
+ ref: ref
45
+ }), IconElement && /*#__PURE__*/React.createElement(react.SideNavIcon, {
46
+ small: true
47
+ }, /*#__PURE__*/React.createElement(IconElement, null)), /*#__PURE__*/React.createElement(react.SideNavLinkText, null, children)));
58
48
  });
59
49
  SideNavMenuItem.displayName = 'SideNavMenuItem';
60
50
  SideNavMenuItem.propTypes = {
51
+ /**
52
+ * Optional component to render instead of default Link
53
+ */
54
+ as: PropTypes.elementType,
61
55
  /**
62
56
  * Specify the children to be rendered inside of the `SideNavMenuItem`
63
57
  */
@@ -66,11 +60,6 @@ SideNavMenuItem.propTypes = {
66
60
  * Provide an optional class to be applied to the containing node
67
61
  */
68
62
  className: PropTypes.string,
69
- /**
70
- * **Note:** this is controlled by the parent SideNavMenu component, do not set manually.
71
- * SideNavMenu depth to determine spacing
72
- */
73
- depth: PropTypes.number,
74
63
  /**
75
64
  * Optionally provide an href for the underlying li`
76
65
  */
@@ -82,9 +71,9 @@ SideNavMenuItem.propTypes = {
82
71
  */
83
72
  isActive: PropTypes.bool,
84
73
  /**
85
- * Optional component to render instead of default Link
74
+ * Provide an icon to render in the side navigation link. Should be a React class.
86
75
  */
87
- as: PropTypes.elementType
76
+ renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
88
77
  };
89
78
 
90
79
  exports.SideNavMenuItem = SideNavMenuItem;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbon-labs/react-ui-shell",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -33,5 +33,5 @@
33
33
  "dependencies": {
34
34
  "@ibm/telemetry-js": "^1.9.1"
35
35
  },
36
- "gitHead": "91dde120d99da5e4454f7411733aeabe037e222f"
36
+ "gitHead": "475eccc3c775b4dd4e087e823d4e5109653d2b11"
37
37
  }
@@ -38,6 +38,7 @@ div:has(.#{$prefix}--header)
38
38
  //----------------------------------------------------------------------------
39
39
  // Treeview Side-nav
40
40
  //----------------------------------------------------------------------------
41
+
41
42
  .#{$prefix}--side-nav__icon:not(.#{$prefix}--side-nav__submenu-chevron) {
42
43
  margin-inline-end: $spacing-05;
43
44
  }
@@ -62,6 +63,54 @@ div:has(.#{$prefix}--header)
62
63
  }
63
64
  }
64
65
 
66
+ // SideNavMenu
67
+ // Level 2
68
+ // without icon
69
+ .#{$prefix}--side-nav__submenu
70
+ + .#{$prefix}--side-nav__menu
71
+ > .#{$prefix}--side-nav__item
72
+ .#{$prefix}--side-nav__submenu {
73
+ padding-inline-start: $spacing-10;
74
+ }
75
+
76
+ // with icon
77
+ .#{$prefix}--side-nav__submenu
78
+ + .#{$prefix}--side-nav__menu
79
+ > .#{$prefix}--side-nav__item--icon
80
+ .#{$prefix}--side-nav__submenu {
81
+ padding-inline-start: $spacing-09;
82
+ }
83
+
84
+ // Nested SideNavMenuItem
85
+ // Level 2
86
+ // without icon
87
+ .#{$prefix}--side-nav__item.#{$prefix}--side-nav__item--icon
88
+ a.#{$prefix}--side-nav__link {
89
+ padding-inline-start: $spacing-10;
90
+ }
91
+
92
+ // with icon
93
+ .#{$prefix}--side-nav__item.#{$prefix}--side-nav__item--icon
94
+ a.#{$prefix}--side-nav__link:has(.#{$prefix}--side-nav__icon) {
95
+ padding-inline-start: $spacing-09;
96
+ }
97
+
98
+ // Level 3
99
+ // without icon parent
100
+ .#{$prefix}--side-nav__menu
101
+ .#{$prefix}--side-nav__menu
102
+ a.#{$prefix}--side-nav__link {
103
+ padding-inline-start: $spacing-11;
104
+ }
105
+
106
+ // with icon parent
107
+ .#{$prefix}--side-nav__menu
108
+ .#{$prefix}--side-nav__item.#{$prefix}--side-nav__item--icon
109
+ a.#{$prefix}--side-nav__link {
110
+ padding-inline-start: $spacing-12;
111
+ }
112
+
113
+ //----------------------------------------------------------------------------
65
114
  // Side-nav Panel
66
115
  //----------------------------------------------------------------------------
67
116
  .#{$prefix}--side-nav--panel {