@carbon-labs/react-ui-shell 0.20.0 → 0.22.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.
package/README.md CHANGED
@@ -31,6 +31,7 @@ components are provided by `@carbon-labs/react-ui-shell`:
31
31
 
32
32
  - `SideNav`
33
33
  - `SideNavItems`
34
+ - `SideNavLink`
34
35
  - `SideNavMenu`
35
36
  - `SideNavMenuItem`
36
37
  - `HeaderPanel`
@@ -158,7 +158,9 @@ function SideNavRenderFunction(_ref, ref) {
158
158
  */
159
159
  function parentSideNavMenu(node) {
160
160
  const parentNode = node.parentElement?.closest(`.${prefix}--side-nav__item`);
161
- if (parentNode) return parentNode;
161
+ if (parentNode) {
162
+ return parentNode;
163
+ }
162
164
  return node;
163
165
  }
164
166
  if (addFocusListeners) {
@@ -340,9 +342,9 @@ function SideNavRenderFunction(_ref, ref) {
340
342
  };
341
343
  return /*#__PURE__*/React.createElement(SideNavContext.Provider, {
342
344
  value: {
345
+ expanded,
343
346
  isRail,
344
347
  navType,
345
- expanded: expanded,
346
348
  isTreeview: internalIsTreeview,
347
349
  setIsTreeview
348
350
  }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { ComponentType, ElementType, ForwardedRef, ReactNode, WeakValidationMap } from 'react';
8
+ import { LinkProps } from './Link';
9
+ export type SideNavLinkProps<E extends ElementType> = LinkProps<E> & {
10
+ /**
11
+ * Required props for the accessibility label
12
+ */
13
+ 'aria-label'?: string;
14
+ /**
15
+ * Required props for the accessibility label
16
+ */
17
+ 'aria-labelledby'?: string;
18
+ /**
19
+ * Specify the text content for the link
20
+ */
21
+ children?: ReactNode;
22
+ /**
23
+ * Provide an optional class to be applied to the containing node
24
+ */
25
+ className?: string;
26
+ /**
27
+ * Specify whether the link is the current page
28
+ */
29
+ isActive?: boolean;
30
+ /**
31
+ * Property to indicate if the side nav container is open (or not). Use to
32
+ * keep local state and styling in step with the SideNav expansion state.
33
+ */
34
+ isSideNavExpanded?: boolean;
35
+ /**
36
+ * Specify if this is a large variation of the SideNavLink
37
+ */
38
+ large?: boolean;
39
+ /**
40
+ * Provide an icon to render in the side navigation link. Should be a React class.
41
+ */
42
+ renderIcon?: ComponentType;
43
+ /**
44
+ * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
45
+ */
46
+ tabIndex?: number;
47
+ };
48
+ export interface SideNavLinkComponent {
49
+ <E extends ElementType = 'a'>(props: SideNavLinkProps<E> & {
50
+ ref?: ForwardedRef<ElementType>;
51
+ }): JSX.Element | null;
52
+ displayName?: string;
53
+ propTypes?: WeakValidationMap<SideNavLinkProps<any>>;
54
+ }
55
+ export declare const SideNavLink: SideNavLinkComponent;
56
+ export declare const createCustomSideNavLink: (element: any) => (props: any) => import("react/jsx-runtime").JSX.Element;
57
+ export default SideNavLink;
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { extends as _extends } from '../_virtual/_rollupPluginBabelHelpers.js';
9
+ import cx from '../_virtual/index.js';
10
+ import PropTypes from 'prop-types';
11
+ import React, { forwardRef, useContext } from 'react';
12
+ import Link, { LinkPropTypes } from './Link.js';
13
+ import { SideNavItem, SideNavLinkText, SideNavIcon } from '@carbon/react';
14
+ import { usePrefix } from '../internal/usePrefix.js';
15
+ import { SideNavContext } from './SideNav.js';
16
+ import { SideNavLinkPopover } from './SideNavLinkPopover.js';
17
+
18
+ const SideNavLink = /*#__PURE__*/forwardRef(function SideNavLink(_ref, ref) {
19
+ let {
20
+ children,
21
+ className: customClassName,
22
+ renderIcon: IconElement,
23
+ isActive,
24
+ isSideNavExpanded,
25
+ large = false,
26
+ tabIndex,
27
+ ...rest
28
+ } = _ref;
29
+ const {
30
+ expanded,
31
+ isRail,
32
+ navType
33
+ } = useContext(SideNavContext);
34
+ const prefix = usePrefix();
35
+ const className = cx({
36
+ [`${prefix}--side-nav__link`]: true,
37
+ [`${prefix}--side-nav__link--current`]: isActive,
38
+ [customClassName]: !!customClassName
39
+ });
40
+ const SideNavLinkIcon = IconElement && /*#__PURE__*/React.createElement(SideNavIcon, {
41
+ small: true
42
+ }, /*#__PURE__*/React.createElement(IconElement, null));
43
+ if (!expanded && navType === 'panel') {
44
+ return /*#__PURE__*/React.createElement(SideNavLinkPopover, _extends({
45
+ align: "right",
46
+ label: children
47
+ }, rest), SideNavLinkIcon);
48
+ }
49
+ return /*#__PURE__*/React.createElement(SideNavItem, {
50
+ large: large
51
+ }, /*#__PURE__*/React.createElement(Link, _extends({}, rest, {
52
+ className: className,
53
+ ref: ref,
54
+ tabIndex: tabIndex === undefined ? !isSideNavExpanded && !isRail ? -1 : 0 : tabIndex
55
+ }), SideNavLinkIcon, /*#__PURE__*/React.createElement(SideNavLinkText, null, children)));
56
+ });
57
+ SideNavLink.displayName = 'SideNavLink';
58
+ SideNavLink.propTypes = {
59
+ ...LinkPropTypes,
60
+ /**
61
+ * Specify the text content for the link
62
+ */
63
+ children: PropTypes.node,
64
+ /**
65
+ * Provide an optional class to be applied to the containing node
66
+ */
67
+ className: PropTypes.string,
68
+ /**
69
+ * Specify whether the link is the current page
70
+ */
71
+ isActive: PropTypes.bool,
72
+ /**
73
+ * Property to indicate if the side nav container is open (or not). Use to
74
+ * keep local state and styling in step with the SideNav expansion state.
75
+ */
76
+ isSideNavExpanded: PropTypes.bool,
77
+ /**
78
+ * Specify if this is a large variation of the SideNavLink
79
+ */
80
+ large: PropTypes.bool,
81
+ /**
82
+ * Provide an icon to render in the side navigation link. Should be a React class.
83
+ */
84
+ // @ts-expect-error - PropTypes are unable to cover this case.
85
+ renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
86
+ /**
87
+ * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
88
+ */
89
+ tabIndex: PropTypes.number
90
+ };
91
+
92
+ export { SideNavLink, SideNavLink as default };
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import PropTypes from 'prop-types';
8
+ import React, { ReactNode } from 'react';
9
+ import { IconButtonAlignment, ButtonSize } from '@carbon/react';
10
+ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
11
+ /**
12
+ * Specify how the trigger should align with the tooltip
13
+ */
14
+ align?: IconButtonAlignment;
15
+ /**
16
+ * **Experimental**: Will attempt to automatically align the tooltip
17
+ */
18
+ autoAlign?: boolean;
19
+ /**
20
+ * Optionally specify an href for your IconButton to become an `<a>` element
21
+ */
22
+ href?: string;
23
+ /**
24
+ * Provide an icon or asset to be rendered inside of the IconButton
25
+ */
26
+ children?: ReactNode;
27
+ /**
28
+ * Specify an optional className to be added to your Button
29
+ */
30
+ className?: string;
31
+ /**
32
+ * Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
33
+ */
34
+ closeOnActivation?: boolean;
35
+ /**
36
+ * Specify whether the tooltip should be open when it first renders
37
+ */
38
+ defaultOpen?: boolean;
39
+ /**
40
+ * Specify whether the Button should be disabled, or not
41
+ */
42
+ disabled?: boolean;
43
+ /**
44
+ * Specify the duration in milliseconds to delay before displaying the tooltip
45
+ */
46
+ enterDelayMs?: number;
47
+ /**
48
+ * Specify whether the IconButton is currently selected
49
+ */
50
+ isSelected?: boolean;
51
+ /**
52
+ * Provide the label to be rendered inside of the Tooltip. The label will use
53
+ * `aria-labelledby` and will fully describe the child node that is provided.
54
+ * This means that if you have text in the child node it will not be
55
+ * announced to the screen reader.
56
+ */
57
+ label: ReactNode;
58
+ /**
59
+ * Specify the duration in milliseconds to delay before hiding the tooltip
60
+ */
61
+ leaveDelayMs?: number;
62
+ /**
63
+ * Specify the size of the Button. Defaults to `md`.
64
+ */
65
+ size?: ButtonSize;
66
+ /**
67
+ * Specify an optional className to be added to your Tooltip wrapper
68
+ */
69
+ wrapperClasses?: string;
70
+ }
71
+ export declare function SideNavLinkPopover({ className, children, ...rest }: IconButtonProps): import("react/jsx-runtime").JSX.Element;
72
+ export declare namespace SideNavLinkPopover {
73
+ var propTypes: {
74
+ /**
75
+ * Specify how the trigger should align with the tooltip
76
+ */
77
+ align: PropTypes.Requireable<string>;
78
+ /**
79
+ * **Experimental**: Will attempt to automatically align the tooltip
80
+ */
81
+ autoAlign: PropTypes.Requireable<boolean>;
82
+ /**
83
+ * Provide an icon or asset to be rendered inside of the IconButton
84
+ */
85
+ children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
86
+ /**
87
+ * Specify an optional className to be added to your Button
88
+ */
89
+ className: PropTypes.Requireable<string>;
90
+ /**
91
+ * Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
92
+ */
93
+ closeOnActivation: PropTypes.Requireable<boolean>;
94
+ /**
95
+ * Specify whether the tooltip should be open when it first renders
96
+ */
97
+ defaultOpen: PropTypes.Requireable<boolean>;
98
+ /**
99
+ * Specify whether the Button should be disabled, or not
100
+ */
101
+ disabled: PropTypes.Requireable<boolean>;
102
+ /**
103
+ * Specify the duration in milliseconds to delay before displaying the tooltip
104
+ */
105
+ enterDelayMs: PropTypes.Requireable<number>;
106
+ /**
107
+ * Optionally specify an href for your IconButton to become an `<a>` element
108
+ */
109
+ href: PropTypes.Requireable<string>;
110
+ /**
111
+ * Specify whether the IconButton is currently selected
112
+ */
113
+ isSelected: PropTypes.Requireable<boolean>;
114
+ /**
115
+ * Provide the label to be rendered inside of the Tooltip. The label will use
116
+ * `aria-labelledby` and will fully describe the child node that is provided.
117
+ * This means that if you have text in the child node it will not be
118
+ * announced to the screen reader.
119
+ */
120
+ label: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
121
+ /**
122
+ * Specify the duration in milliseconds to delay before hiding the tooltip
123
+ */
124
+ leaveDelayMs: PropTypes.Requireable<number>;
125
+ /**
126
+ * Specify the size of the Button. Defaults to `md`.
127
+ */
128
+ size: PropTypes.Requireable<string>;
129
+ /**
130
+ * Specify an optional className to be added to your Tooltip wrapper
131
+ */
132
+ wrapperClasses: PropTypes.Requireable<string>;
133
+ };
134
+ }
135
+ export default SideNavLinkPopover;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { extends as _extends } from '../_virtual/_rollupPluginBabelHelpers.js';
9
+ import cx from '../_virtual/index.js';
10
+ import PropTypes from 'prop-types';
11
+ import React from 'react';
12
+ import { IconButton } from '@carbon/react';
13
+ import { usePrefix } from '../internal/usePrefix.js';
14
+
15
+ function SideNavLinkPopover(_ref) {
16
+ let {
17
+ className,
18
+ children,
19
+ ...rest
20
+ } = _ref;
21
+ const prefix = usePrefix();
22
+ return /*#__PURE__*/React.createElement(IconButton, _extends({
23
+ className: cx(className, `${prefix}--side-nav-link-popover`),
24
+ kind: "ghost"
25
+ }, rest), children);
26
+ }
27
+ SideNavLinkPopover.propTypes = {
28
+ /**
29
+ * Specify how the trigger should align with the tooltip
30
+ */
31
+ align: PropTypes.oneOf(['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-end', 'left-start', 'right', 'right-end', 'right-start']),
32
+ /**
33
+ * **Experimental**: Will attempt to automatically align the tooltip
34
+ */
35
+ autoAlign: PropTypes.bool,
36
+ /**
37
+ * Provide an icon or asset to be rendered inside of the IconButton
38
+ */
39
+ children: PropTypes.node,
40
+ /**
41
+ * Specify an optional className to be added to your Button
42
+ */
43
+ className: PropTypes.string,
44
+ /**
45
+ * Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
46
+ */
47
+ closeOnActivation: PropTypes.bool,
48
+ /**
49
+ * Specify whether the tooltip should be open when it first renders
50
+ */
51
+ defaultOpen: PropTypes.bool,
52
+ /**
53
+ * Specify whether the Button should be disabled, or not
54
+ */
55
+ disabled: PropTypes.bool,
56
+ /**
57
+ * Specify the duration in milliseconds to delay before displaying the tooltip
58
+ */
59
+ enterDelayMs: PropTypes.number,
60
+ /**
61
+ * Optionally specify an href for your IconButton to become an `<a>` element
62
+ */
63
+ href: PropTypes.string,
64
+ /**
65
+ * Specify whether the IconButton is currently selected
66
+ */
67
+
68
+ isSelected: PropTypes.bool,
69
+ /**
70
+ * Provide the label to be rendered inside of the Tooltip. The label will use
71
+ * `aria-labelledby` and will fully describe the child node that is provided.
72
+ * This means that if you have text in the child node it will not be
73
+ * announced to the screen reader.
74
+ */
75
+ label: PropTypes.node.isRequired,
76
+ /**
77
+ * Specify the duration in milliseconds to delay before hiding the tooltip
78
+ */
79
+ leaveDelayMs: PropTypes.number,
80
+ /**
81
+ * Specify the size of the Button. Defaults to `md`.
82
+ */
83
+ size: PropTypes.oneOf(['sm', 'md', 'lg']),
84
+ /**
85
+ * Specify an optional className to be added to your Tooltip wrapper
86
+ */
87
+ wrapperClasses: PropTypes.string
88
+ };
89
+
90
+ export { SideNavLinkPopover, SideNavLinkPopover as default };
package/es/index.d.ts CHANGED
@@ -8,6 +8,8 @@
8
8
  */
9
9
  export { SideNav, SIDE_NAV_TYPE } from './components/SideNav.js';
10
10
  export { SideNavItems } from './components/SideNavItems.js';
11
+ export { SideNavLink } from './components/SideNavLink.js';
12
+ export { SideNavLinkPopover } from './components/SideNavLinkPopover.js';
11
13
  export { SideNavMenu } from './components/SideNavMenu.js';
12
14
  export { SideNavMenuItem } from './components/SideNavMenuItem.js';
13
15
  export { HeaderPanel } from './components/HeaderPanel';
package/es/index.js CHANGED
@@ -7,6 +7,8 @@
7
7
 
8
8
  export { SIDE_NAV_TYPE, SideNav } from './components/SideNav.js';
9
9
  export { SideNavItems } from './components/SideNavItems.js';
10
+ export { SideNavLink } from './components/SideNavLink.js';
11
+ export { SideNavLinkPopover } from './components/SideNavLinkPopover.js';
10
12
  export { SideNavMenu } from './components/SideNavMenu.js';
11
13
  export { SideNavMenuItem } from './components/SideNavMenuItem.js';
12
14
  export { HeaderPanel } from './components/HeaderPanel.js';
@@ -160,7 +160,9 @@ function SideNavRenderFunction(_ref, ref) {
160
160
  */
161
161
  function parentSideNavMenu(node) {
162
162
  const parentNode = node.parentElement?.closest(`.${prefix}--side-nav__item`);
163
- if (parentNode) return parentNode;
163
+ if (parentNode) {
164
+ return parentNode;
165
+ }
164
166
  return node;
165
167
  }
166
168
  if (addFocusListeners) {
@@ -342,9 +344,9 @@ function SideNavRenderFunction(_ref, ref) {
342
344
  };
343
345
  return /*#__PURE__*/React.createElement(SideNavContext.Provider, {
344
346
  value: {
347
+ expanded,
345
348
  isRail,
346
349
  navType,
347
- expanded: expanded,
348
350
  isTreeview: internalIsTreeview,
349
351
  setIsTreeview
350
352
  }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { ComponentType, ElementType, ForwardedRef, ReactNode, WeakValidationMap } from 'react';
8
+ import { LinkProps } from './Link';
9
+ export type SideNavLinkProps<E extends ElementType> = LinkProps<E> & {
10
+ /**
11
+ * Required props for the accessibility label
12
+ */
13
+ 'aria-label'?: string;
14
+ /**
15
+ * Required props for the accessibility label
16
+ */
17
+ 'aria-labelledby'?: string;
18
+ /**
19
+ * Specify the text content for the link
20
+ */
21
+ children?: ReactNode;
22
+ /**
23
+ * Provide an optional class to be applied to the containing node
24
+ */
25
+ className?: string;
26
+ /**
27
+ * Specify whether the link is the current page
28
+ */
29
+ isActive?: boolean;
30
+ /**
31
+ * Property to indicate if the side nav container is open (or not). Use to
32
+ * keep local state and styling in step with the SideNav expansion state.
33
+ */
34
+ isSideNavExpanded?: boolean;
35
+ /**
36
+ * Specify if this is a large variation of the SideNavLink
37
+ */
38
+ large?: boolean;
39
+ /**
40
+ * Provide an icon to render in the side navigation link. Should be a React class.
41
+ */
42
+ renderIcon?: ComponentType;
43
+ /**
44
+ * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
45
+ */
46
+ tabIndex?: number;
47
+ };
48
+ export interface SideNavLinkComponent {
49
+ <E extends ElementType = 'a'>(props: SideNavLinkProps<E> & {
50
+ ref?: ForwardedRef<ElementType>;
51
+ }): JSX.Element | null;
52
+ displayName?: string;
53
+ propTypes?: WeakValidationMap<SideNavLinkProps<any>>;
54
+ }
55
+ export declare const SideNavLink: SideNavLinkComponent;
56
+ export declare const createCustomSideNavLink: (element: any) => (props: any) => import("react/jsx-runtime").JSX.Element;
57
+ export default SideNavLink;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
13
+ var index = require('../_virtual/index.js');
14
+ var PropTypes = require('prop-types');
15
+ var React = require('react');
16
+ var Link = require('./Link.js');
17
+ var react = require('@carbon/react');
18
+ var usePrefix = require('../internal/usePrefix.js');
19
+ var SideNav = require('./SideNav.js');
20
+ var SideNavLinkPopover = require('./SideNavLinkPopover.js');
21
+
22
+ const SideNavLink = /*#__PURE__*/React.forwardRef(function SideNavLink(_ref, ref) {
23
+ let {
24
+ children,
25
+ className: customClassName,
26
+ renderIcon: IconElement,
27
+ isActive,
28
+ isSideNavExpanded,
29
+ large = false,
30
+ tabIndex,
31
+ ...rest
32
+ } = _ref;
33
+ const {
34
+ expanded,
35
+ isRail,
36
+ navType
37
+ } = React.useContext(SideNav.SideNavContext);
38
+ const prefix = usePrefix.usePrefix();
39
+ const className = index.default({
40
+ [`${prefix}--side-nav__link`]: true,
41
+ [`${prefix}--side-nav__link--current`]: isActive,
42
+ [customClassName]: !!customClassName
43
+ });
44
+ const SideNavLinkIcon = IconElement && /*#__PURE__*/React.createElement(react.SideNavIcon, {
45
+ small: true
46
+ }, /*#__PURE__*/React.createElement(IconElement, null));
47
+ if (!expanded && navType === 'panel') {
48
+ return /*#__PURE__*/React.createElement(SideNavLinkPopover.SideNavLinkPopover, _rollupPluginBabelHelpers.extends({
49
+ align: "right",
50
+ label: children
51
+ }, rest), SideNavLinkIcon);
52
+ }
53
+ return /*#__PURE__*/React.createElement(react.SideNavItem, {
54
+ large: large
55
+ }, /*#__PURE__*/React.createElement(Link.default, _rollupPluginBabelHelpers.extends({}, rest, {
56
+ className: className,
57
+ ref: ref,
58
+ tabIndex: tabIndex === undefined ? !isSideNavExpanded && !isRail ? -1 : 0 : tabIndex
59
+ }), SideNavLinkIcon, /*#__PURE__*/React.createElement(react.SideNavLinkText, null, children)));
60
+ });
61
+ SideNavLink.displayName = 'SideNavLink';
62
+ SideNavLink.propTypes = {
63
+ ...Link.LinkPropTypes,
64
+ /**
65
+ * Specify the text content for the link
66
+ */
67
+ children: PropTypes.node,
68
+ /**
69
+ * Provide an optional class to be applied to the containing node
70
+ */
71
+ className: PropTypes.string,
72
+ /**
73
+ * Specify whether the link is the current page
74
+ */
75
+ isActive: PropTypes.bool,
76
+ /**
77
+ * Property to indicate if the side nav container is open (or not). Use to
78
+ * keep local state and styling in step with the SideNav expansion state.
79
+ */
80
+ isSideNavExpanded: PropTypes.bool,
81
+ /**
82
+ * Specify if this is a large variation of the SideNavLink
83
+ */
84
+ large: PropTypes.bool,
85
+ /**
86
+ * Provide an icon to render in the side navigation link. Should be a React class.
87
+ */
88
+ // @ts-expect-error - PropTypes are unable to cover this case.
89
+ renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
90
+ /**
91
+ * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
92
+ */
93
+ tabIndex: PropTypes.number
94
+ };
95
+
96
+ exports.SideNavLink = SideNavLink;
97
+ exports.default = SideNavLink;
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import PropTypes from 'prop-types';
8
+ import React, { ReactNode } from 'react';
9
+ import { IconButtonAlignment, ButtonSize } from '@carbon/react';
10
+ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
11
+ /**
12
+ * Specify how the trigger should align with the tooltip
13
+ */
14
+ align?: IconButtonAlignment;
15
+ /**
16
+ * **Experimental**: Will attempt to automatically align the tooltip
17
+ */
18
+ autoAlign?: boolean;
19
+ /**
20
+ * Optionally specify an href for your IconButton to become an `<a>` element
21
+ */
22
+ href?: string;
23
+ /**
24
+ * Provide an icon or asset to be rendered inside of the IconButton
25
+ */
26
+ children?: ReactNode;
27
+ /**
28
+ * Specify an optional className to be added to your Button
29
+ */
30
+ className?: string;
31
+ /**
32
+ * Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
33
+ */
34
+ closeOnActivation?: boolean;
35
+ /**
36
+ * Specify whether the tooltip should be open when it first renders
37
+ */
38
+ defaultOpen?: boolean;
39
+ /**
40
+ * Specify whether the Button should be disabled, or not
41
+ */
42
+ disabled?: boolean;
43
+ /**
44
+ * Specify the duration in milliseconds to delay before displaying the tooltip
45
+ */
46
+ enterDelayMs?: number;
47
+ /**
48
+ * Specify whether the IconButton is currently selected
49
+ */
50
+ isSelected?: boolean;
51
+ /**
52
+ * Provide the label to be rendered inside of the Tooltip. The label will use
53
+ * `aria-labelledby` and will fully describe the child node that is provided.
54
+ * This means that if you have text in the child node it will not be
55
+ * announced to the screen reader.
56
+ */
57
+ label: ReactNode;
58
+ /**
59
+ * Specify the duration in milliseconds to delay before hiding the tooltip
60
+ */
61
+ leaveDelayMs?: number;
62
+ /**
63
+ * Specify the size of the Button. Defaults to `md`.
64
+ */
65
+ size?: ButtonSize;
66
+ /**
67
+ * Specify an optional className to be added to your Tooltip wrapper
68
+ */
69
+ wrapperClasses?: string;
70
+ }
71
+ export declare function SideNavLinkPopover({ className, children, ...rest }: IconButtonProps): import("react/jsx-runtime").JSX.Element;
72
+ export declare namespace SideNavLinkPopover {
73
+ var propTypes: {
74
+ /**
75
+ * Specify how the trigger should align with the tooltip
76
+ */
77
+ align: PropTypes.Requireable<string>;
78
+ /**
79
+ * **Experimental**: Will attempt to automatically align the tooltip
80
+ */
81
+ autoAlign: PropTypes.Requireable<boolean>;
82
+ /**
83
+ * Provide an icon or asset to be rendered inside of the IconButton
84
+ */
85
+ children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
86
+ /**
87
+ * Specify an optional className to be added to your Button
88
+ */
89
+ className: PropTypes.Requireable<string>;
90
+ /**
91
+ * Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
92
+ */
93
+ closeOnActivation: PropTypes.Requireable<boolean>;
94
+ /**
95
+ * Specify whether the tooltip should be open when it first renders
96
+ */
97
+ defaultOpen: PropTypes.Requireable<boolean>;
98
+ /**
99
+ * Specify whether the Button should be disabled, or not
100
+ */
101
+ disabled: PropTypes.Requireable<boolean>;
102
+ /**
103
+ * Specify the duration in milliseconds to delay before displaying the tooltip
104
+ */
105
+ enterDelayMs: PropTypes.Requireable<number>;
106
+ /**
107
+ * Optionally specify an href for your IconButton to become an `<a>` element
108
+ */
109
+ href: PropTypes.Requireable<string>;
110
+ /**
111
+ * Specify whether the IconButton is currently selected
112
+ */
113
+ isSelected: PropTypes.Requireable<boolean>;
114
+ /**
115
+ * Provide the label to be rendered inside of the Tooltip. The label will use
116
+ * `aria-labelledby` and will fully describe the child node that is provided.
117
+ * This means that if you have text in the child node it will not be
118
+ * announced to the screen reader.
119
+ */
120
+ label: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
121
+ /**
122
+ * Specify the duration in milliseconds to delay before hiding the tooltip
123
+ */
124
+ leaveDelayMs: PropTypes.Requireable<number>;
125
+ /**
126
+ * Specify the size of the Button. Defaults to `md`.
127
+ */
128
+ size: PropTypes.Requireable<string>;
129
+ /**
130
+ * Specify an optional className to be added to your Tooltip wrapper
131
+ */
132
+ wrapperClasses: PropTypes.Requireable<string>;
133
+ };
134
+ }
135
+ export default SideNavLinkPopover;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
13
+ var index = require('../_virtual/index.js');
14
+ var PropTypes = require('prop-types');
15
+ var React = require('react');
16
+ var react = require('@carbon/react');
17
+ var usePrefix = require('../internal/usePrefix.js');
18
+
19
+ function SideNavLinkPopover(_ref) {
20
+ let {
21
+ className,
22
+ children,
23
+ ...rest
24
+ } = _ref;
25
+ const prefix = usePrefix.usePrefix();
26
+ return /*#__PURE__*/React.createElement(react.IconButton, _rollupPluginBabelHelpers.extends({
27
+ className: index.default(className, `${prefix}--side-nav-link-popover`),
28
+ kind: "ghost"
29
+ }, rest), children);
30
+ }
31
+ SideNavLinkPopover.propTypes = {
32
+ /**
33
+ * Specify how the trigger should align with the tooltip
34
+ */
35
+ align: PropTypes.oneOf(['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-end', 'left-start', 'right', 'right-end', 'right-start']),
36
+ /**
37
+ * **Experimental**: Will attempt to automatically align the tooltip
38
+ */
39
+ autoAlign: PropTypes.bool,
40
+ /**
41
+ * Provide an icon or asset to be rendered inside of the IconButton
42
+ */
43
+ children: PropTypes.node,
44
+ /**
45
+ * Specify an optional className to be added to your Button
46
+ */
47
+ className: PropTypes.string,
48
+ /**
49
+ * Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
50
+ */
51
+ closeOnActivation: PropTypes.bool,
52
+ /**
53
+ * Specify whether the tooltip should be open when it first renders
54
+ */
55
+ defaultOpen: PropTypes.bool,
56
+ /**
57
+ * Specify whether the Button should be disabled, or not
58
+ */
59
+ disabled: PropTypes.bool,
60
+ /**
61
+ * Specify the duration in milliseconds to delay before displaying the tooltip
62
+ */
63
+ enterDelayMs: PropTypes.number,
64
+ /**
65
+ * Optionally specify an href for your IconButton to become an `<a>` element
66
+ */
67
+ href: PropTypes.string,
68
+ /**
69
+ * Specify whether the IconButton is currently selected
70
+ */
71
+
72
+ isSelected: PropTypes.bool,
73
+ /**
74
+ * Provide the label to be rendered inside of the Tooltip. The label will use
75
+ * `aria-labelledby` and will fully describe the child node that is provided.
76
+ * This means that if you have text in the child node it will not be
77
+ * announced to the screen reader.
78
+ */
79
+ label: PropTypes.node.isRequired,
80
+ /**
81
+ * Specify the duration in milliseconds to delay before hiding the tooltip
82
+ */
83
+ leaveDelayMs: PropTypes.number,
84
+ /**
85
+ * Specify the size of the Button. Defaults to `md`.
86
+ */
87
+ size: PropTypes.oneOf(['sm', 'md', 'lg']),
88
+ /**
89
+ * Specify an optional className to be added to your Tooltip wrapper
90
+ */
91
+ wrapperClasses: PropTypes.string
92
+ };
93
+
94
+ exports.SideNavLinkPopover = SideNavLinkPopover;
95
+ exports.default = SideNavLinkPopover;
package/lib/index.d.ts CHANGED
@@ -8,6 +8,8 @@
8
8
  */
9
9
  export { SideNav, SIDE_NAV_TYPE } from './components/SideNav.js';
10
10
  export { SideNavItems } from './components/SideNavItems.js';
11
+ export { SideNavLink } from './components/SideNavLink.js';
12
+ export { SideNavLinkPopover } from './components/SideNavLinkPopover.js';
11
13
  export { SideNavMenu } from './components/SideNavMenu.js';
12
14
  export { SideNavMenuItem } from './components/SideNavMenuItem.js';
13
15
  export { HeaderPanel } from './components/HeaderPanel';
package/lib/index.js CHANGED
@@ -9,6 +9,8 @@
9
9
 
10
10
  var SideNav = require('./components/SideNav.js');
11
11
  var SideNavItems = require('./components/SideNavItems.js');
12
+ var SideNavLink = require('./components/SideNavLink.js');
13
+ var SideNavLinkPopover = require('./components/SideNavLinkPopover.js');
12
14
  var SideNavMenu = require('./components/SideNavMenu.js');
13
15
  var SideNavMenuItem = require('./components/SideNavMenuItem.js');
14
16
  var HeaderPanel = require('./components/HeaderPanel.js');
@@ -18,6 +20,8 @@ var HeaderPanel = require('./components/HeaderPanel.js');
18
20
  exports.SIDE_NAV_TYPE = SideNav.SIDE_NAV_TYPE;
19
21
  exports.SideNav = SideNav.SideNav;
20
22
  exports.SideNavItems = SideNavItems.SideNavItems;
23
+ exports.SideNavLink = SideNavLink.SideNavLink;
24
+ exports.SideNavLinkPopover = SideNavLinkPopover.SideNavLinkPopover;
21
25
  exports.SideNavMenu = SideNavMenu.SideNavMenu;
22
26
  exports.SideNavMenuItem = SideNavMenuItem.SideNavMenuItem;
23
27
  exports.HeaderPanel = HeaderPanel.HeaderPanel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbon-labs/react-ui-shell",
3
- "version": "0.20.0",
3
+ "version": "0.22.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": "475eccc3c775b4dd4e087e823d4e5109653d2b11"
36
+ "gitHead": "8462ddc3f3be6e2d63e5e036630d12e7caf5c20c"
37
37
  }
@@ -115,6 +115,17 @@ div:has(.#{$prefix}--header)
115
115
  //----------------------------------------------------------------------------
116
116
  .#{$prefix}--side-nav--panel {
117
117
  z-index: 7999; /* needs to be below header */
118
+ overflow: visible;
119
+
120
+ .#{$prefix}--side-nav__items {
121
+ display: flex;
122
+ flex-direction: column;
123
+ }
124
+
125
+ .#{$prefix}--side-nav__items,
126
+ .#{$prefix}--side-nav__items:hover {
127
+ overflow: visible;
128
+ }
118
129
 
119
130
  .#{$prefix}--side-nav__icon:not(.#{$prefix}--side-nav__submenu-chevron) {
120
131
  margin-inline-end: $spacing-05;
@@ -131,6 +142,7 @@ div:has(.#{$prefix}--header)
131
142
  padding-inline-start: $spacing-10;
132
143
  }
133
144
 
145
+ // Side Nav Toggle
134
146
  .#{$prefix}--side-nav__toggle {
135
147
  @include button-reset.reset($width: true);
136
148
  @include type-style('heading-compact-01');
@@ -159,4 +171,15 @@ div:has(.#{$prefix}--header)
159
171
 
160
172
  text-align: start;
161
173
  }
174
+
175
+ // Side Nav Link Popover
176
+ .#{$prefix}--side-nav-link-popover.#{$prefix}--btn--icon-only {
177
+ padding: 0;
178
+ block-size: $spacing-07;
179
+ min-block-size: initial;
180
+
181
+ .#{$prefix}--side-nav__icon:not(.#{$prefix}--side-nav__submenu-chevron) {
182
+ margin-inline-end: 0;
183
+ }
184
+ }
162
185
  }