@carbon-labs/react-ui-shell 0.72.0 → 0.74.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/es/components/Profile.js +7 -4
- package/es/components/SideNav.d.ts +4 -1
- package/es/components/SideNav.js +63 -34
- package/es/components/SideNavLink.js +2 -2
- package/es/components/SideNavMenu.js +6 -5
- package/es/components/SideNavToggle.d.ts +37 -12
- package/es/components/SideNavToggle.js +50 -18
- package/lib/components/Profile.js +7 -4
- package/lib/components/SideNav.d.ts +4 -1
- package/lib/components/SideNav.js +61 -32
- package/lib/components/SideNavLink.js +1 -1
- package/lib/components/SideNavMenu.js +6 -5
- package/lib/components/SideNavToggle.d.ts +37 -12
- package/lib/components/SideNavToggle.js +47 -15
- package/package.json +2 -2
- package/scss/styles/_content.scss +14 -2
- package/scss/styles/_side-nav.scss +23 -7
package/es/components/Profile.js
CHANGED
|
@@ -19,14 +19,15 @@ const Profile = /*#__PURE__*/React__default.forwardRef(function Profile({
|
|
|
19
19
|
children,
|
|
20
20
|
renderIcon: IconElement,
|
|
21
21
|
...rest
|
|
22
|
-
}) {
|
|
22
|
+
}, ref) {
|
|
23
23
|
const prefix = usePrefix();
|
|
24
24
|
const className = cx({
|
|
25
25
|
[`${prefix}--profile`]: true,
|
|
26
26
|
[customClassName]: !!customClassName
|
|
27
27
|
});
|
|
28
28
|
return /*#__PURE__*/React__default.createElement(HeaderPopover, _extends({
|
|
29
|
-
|
|
29
|
+
ref: ref,
|
|
30
|
+
align: "bottom-end",
|
|
30
31
|
className: className
|
|
31
32
|
}, rest), /*#__PURE__*/React__default.createElement(HeaderPopoverButton, {
|
|
32
33
|
align: "bottom",
|
|
@@ -58,13 +59,14 @@ const ProfileUserInfo = /*#__PURE__*/React__default.forwardRef(function ProfileU
|
|
|
58
59
|
name,
|
|
59
60
|
email,
|
|
60
61
|
...rest
|
|
61
|
-
}) {
|
|
62
|
+
}, ref) {
|
|
62
63
|
const prefix = usePrefix();
|
|
63
64
|
const className = cx({
|
|
64
65
|
[`${prefix}--profile-user-info`]: true,
|
|
65
66
|
[customClassName]: !!customClassName
|
|
66
67
|
});
|
|
67
68
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
69
|
+
ref: ref,
|
|
68
70
|
className: className
|
|
69
71
|
}, /*#__PURE__*/React__default.createElement(UserAvatar, _extends({
|
|
70
72
|
size: "lg",
|
|
@@ -95,13 +97,14 @@ ProfileUserInfo.propTypes = {
|
|
|
95
97
|
const ProfileReadOnly = /*#__PURE__*/React__default.forwardRef(function ProfileReadOnly({
|
|
96
98
|
className: customClassName,
|
|
97
99
|
items
|
|
98
|
-
}) {
|
|
100
|
+
}, ref) {
|
|
99
101
|
const prefix = usePrefix();
|
|
100
102
|
const className = cx({
|
|
101
103
|
[`${prefix}--profile-read-only`]: true,
|
|
102
104
|
[customClassName]: !!customClassName
|
|
103
105
|
});
|
|
104
106
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
107
|
+
ref: ref,
|
|
105
108
|
className: className
|
|
106
109
|
}, items?.map((item, index) => /*#__PURE__*/React__default.createElement("div", {
|
|
107
110
|
className: `${prefix}--profile-read-only__items`,
|
|
@@ -9,12 +9,14 @@ import { TranslateWithId } from '../types/common';
|
|
|
9
9
|
export declare enum SIDE_NAV_TYPE {
|
|
10
10
|
DEFAULT = "default",
|
|
11
11
|
RAIL = "rail",
|
|
12
|
-
|
|
12
|
+
RAIL_PANEL = "panel"
|
|
13
13
|
}
|
|
14
14
|
export type TranslationKey = keyof typeof translationIds;
|
|
15
15
|
export declare const translationIds: {
|
|
16
16
|
readonly 'collapse.sidenav': "collapse.sidenav";
|
|
17
17
|
readonly 'expand.sidenav': "expand.sidenav";
|
|
18
|
+
readonly 'enable.autoexpand': "enable.autoexpand";
|
|
19
|
+
readonly 'disable.autoexpand': "disable.autoexpand";
|
|
18
20
|
};
|
|
19
21
|
export interface SideNavProps extends ComponentProps<'nav'>, TranslateWithId<TranslationKey> {
|
|
20
22
|
expanded?: boolean;
|
|
@@ -38,6 +40,7 @@ export interface SideNavProps extends ComponentProps<'nav'>, TranslateWithId<Tra
|
|
|
38
40
|
isTreeview?: boolean;
|
|
39
41
|
}
|
|
40
42
|
interface SideNavContextData {
|
|
43
|
+
autoExpand?: boolean;
|
|
41
44
|
expanded?: boolean;
|
|
42
45
|
isRail?: boolean;
|
|
43
46
|
navType?: SIDE_NAV_TYPE;
|
package/es/components/SideNav.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React__default, { createContext, useState, useRef, isValidElement, useEffect } from 'react';
|
|
9
|
+
import React__default, { createContext, useState, useRef, isValidElement, useCallback, useEffect } from 'react';
|
|
10
10
|
import cx from 'classnames';
|
|
11
11
|
import PropTypes from 'prop-types';
|
|
12
12
|
import { AriaLabelPropType } from '../prop-types/AriaPropTypes.js';
|
|
@@ -19,22 +19,28 @@ import { useWindowEvent } from '../internal/useEvent.js';
|
|
|
19
19
|
import { useDelayedState } from '../internal/useDelayedState.js';
|
|
20
20
|
import { breakpoints } from '../node_modules/@carbon/layout/es/index.js';
|
|
21
21
|
import { useMatchMedia } from '../internal/useMatchMedia.js';
|
|
22
|
-
import { SidePanelClose, SidePanelOpen } from '@carbon/icons-react';
|
|
22
|
+
import { PinFilled, Pin, SidePanelClose, SidePanelOpen } from '@carbon/icons-react';
|
|
23
23
|
import { SideNavToggle } from './SideNavToggle.js';
|
|
24
|
+
import { SideNavDivider } from '@carbon/react';
|
|
24
25
|
|
|
26
|
+
var _SideNavDivider;
|
|
25
27
|
let SIDE_NAV_TYPE = /*#__PURE__*/function (SIDE_NAV_TYPE) {
|
|
26
28
|
SIDE_NAV_TYPE["DEFAULT"] = "default";
|
|
27
29
|
SIDE_NAV_TYPE["RAIL"] = "rail";
|
|
28
|
-
SIDE_NAV_TYPE["
|
|
30
|
+
SIDE_NAV_TYPE["RAIL_PANEL"] = "panel";
|
|
29
31
|
return SIDE_NAV_TYPE;
|
|
30
32
|
}({});
|
|
31
33
|
const translationIds = {
|
|
32
34
|
'collapse.sidenav': 'collapse.sidenav',
|
|
33
|
-
'expand.sidenav': 'expand.sidenav'
|
|
35
|
+
'expand.sidenav': 'expand.sidenav',
|
|
36
|
+
'enable.autoexpand': 'enable.autoexpand',
|
|
37
|
+
'disable.autoexpand': 'disable.autoexpand'
|
|
34
38
|
};
|
|
35
39
|
const defaultTranslations = {
|
|
36
|
-
[translationIds['collapse.sidenav']]: '
|
|
37
|
-
[translationIds['expand.sidenav']]: '
|
|
40
|
+
[translationIds['collapse.sidenav']]: 'Unpin',
|
|
41
|
+
[translationIds['expand.sidenav']]: 'Pin open',
|
|
42
|
+
[translationIds['enable.autoexpand']]: 'Enable auto-expand',
|
|
43
|
+
[translationIds['disable.autoexpand']]: 'Disable auto-expand'
|
|
38
44
|
};
|
|
39
45
|
const defaultTranslateWithId = id => defaultTranslations[id];
|
|
40
46
|
const SideNavContext = /*#__PURE__*/createContext({});
|
|
@@ -69,13 +75,16 @@ function SideNavRenderFunction({
|
|
|
69
75
|
const {
|
|
70
76
|
current: controlled
|
|
71
77
|
} = useRef(expandedProp !== undefined);
|
|
78
|
+
const [autoExpand, setAutoExpand] = useState(false);
|
|
72
79
|
const [expandedState, setExpandedState] = useDelayedState(defaultExpanded);
|
|
73
80
|
const [expandedViaHoverState, setExpandedViaHoverState] = useDelayedState(defaultExpanded);
|
|
81
|
+
const [pinned, setPinned] = useState(false);
|
|
74
82
|
const expanded = controlled ? expandedProp : expandedState;
|
|
75
83
|
const sideNavRef = useRef(null);
|
|
76
84
|
const navRef = useMergedRefs([sideNavRef, ref]);
|
|
77
85
|
const [currentPrimaryMenu, setCurrentPrimaryMenu] = useState();
|
|
78
|
-
const
|
|
86
|
+
const pinText = pinned ? t('collapse.sidenav') : t('expand.sidenav');
|
|
87
|
+
const autoExpandText = autoExpand ? t('disable.autoexpand') : t('enable.autoexpand');
|
|
79
88
|
const handleToggle = (event, value = !expanded) => {
|
|
80
89
|
if (!controlled) {
|
|
81
90
|
setExpandedState(value, enterDelayMs);
|
|
@@ -96,8 +105,9 @@ function SideNavRenderFunction({
|
|
|
96
105
|
[`${prefix}--side-nav--expanded`]: expanded || expandedViaHoverState,
|
|
97
106
|
[`${prefix}--side-nav--collapsed`]: !expanded && isFixedNav,
|
|
98
107
|
[`${prefix}--side-nav--hide-rail-breakpoint-down-${hideRailBreakpointDown}`]: hideRailBreakpointDown,
|
|
99
|
-
[`${prefix}--side-nav--rail`]: isRail,
|
|
100
|
-
[`${prefix}--side-nav--panel`]: navType === SIDE_NAV_TYPE.
|
|
108
|
+
[`${prefix}--side-nav--rail`]: isRail || autoExpand,
|
|
109
|
+
[`${prefix}--side-nav--panel`]: navType === SIDE_NAV_TYPE.RAIL_PANEL,
|
|
110
|
+
[`${prefix}--side-nav--pinned`]: pinned,
|
|
101
111
|
[`${prefix}--side-nav--ux`]: isChildOfHeader,
|
|
102
112
|
[`${prefix}--side-nav--hidden`]: !isPersistent,
|
|
103
113
|
[`${prefix}--side-nav--collapsible`]: isCollapsible,
|
|
@@ -128,6 +138,15 @@ function SideNavRenderFunction({
|
|
|
128
138
|
return child;
|
|
129
139
|
});
|
|
130
140
|
const eventHandlers = {};
|
|
141
|
+
const resetNodeTabIndices = useCallback(() => {
|
|
142
|
+
const items = sideNavRef?.current?.querySelectorAll('[tabIndex="0"]') ?? [];
|
|
143
|
+
items.forEach(item => {
|
|
144
|
+
if (item.classList.contains(`${prefix}--side-nav__toggle`) || item.classList.contains(`${prefix}--side-nav__back-button`) || item.closest(`.${prefix}--side-nav__slot-item`) || item.classList.contains(`${prefix}--side-nav__link`) && item.closest('ul')?.getAttribute('aria-label') === ariaLabel) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
item.tabIndex = -1;
|
|
148
|
+
});
|
|
149
|
+
}, [prefix, ariaLabel]);
|
|
131
150
|
const treeWalkerRef = useRef(null);
|
|
132
151
|
useEffect(() => {
|
|
133
152
|
if (internalIsTreeview) {
|
|
@@ -147,7 +166,7 @@ function SideNavRenderFunction({
|
|
|
147
166
|
});
|
|
148
167
|
resetNodeTabIndices();
|
|
149
168
|
}
|
|
150
|
-
}, [prefix, internalIsTreeview]);
|
|
169
|
+
}, [prefix, internalIsTreeview, resetNodeTabIndices]);
|
|
151
170
|
const smMediaQuery = `(min-width: ${breakpoints.sm.width})`;
|
|
152
171
|
const isSm = useMatchMedia(smMediaQuery);
|
|
153
172
|
useEffect(() => {
|
|
@@ -156,7 +175,7 @@ function SideNavRenderFunction({
|
|
|
156
175
|
const slotElement = sideNavRef?.current.querySelector(`.${prefix}--side-nav__slot`);
|
|
157
176
|
const firstElement = sideNavRef?.current?.querySelector('a, button');
|
|
158
177
|
const currentElement = sideNavRef?.current?.querySelector(`.cds--side-nav__link--current`);
|
|
159
|
-
if (navType == SIDE_NAV_TYPE.
|
|
178
|
+
if (navType == SIDE_NAV_TYPE.RAIL_PANEL || expanded) {
|
|
160
179
|
if (isSm && backButton) {
|
|
161
180
|
backButton.tabIndex = 0;
|
|
162
181
|
const firstElementAfterBack = backButton.nextElementSibling?.querySelector('a, button');
|
|
@@ -176,7 +195,7 @@ function SideNavRenderFunction({
|
|
|
176
195
|
}
|
|
177
196
|
}
|
|
178
197
|
}
|
|
179
|
-
}, [expanded]);
|
|
198
|
+
}, [expanded, currentPrimaryMenu, isSm, navType, prefix]);
|
|
180
199
|
|
|
181
200
|
/**
|
|
182
201
|
* Returns the parent SideNavMenu, if node is actually inside one.
|
|
@@ -192,12 +211,12 @@ function SideNavRenderFunction({
|
|
|
192
211
|
}
|
|
193
212
|
if (addFocusListeners) {
|
|
194
213
|
eventHandlers.onFocus = event => {
|
|
195
|
-
if (!event.currentTarget.contains(event.relatedTarget) && isRail) {
|
|
214
|
+
if (!event.currentTarget.contains(event.relatedTarget) && (isRail || autoExpand)) {
|
|
196
215
|
handleToggle(event, true);
|
|
197
216
|
}
|
|
198
217
|
};
|
|
199
218
|
eventHandlers.onBlur = event => {
|
|
200
|
-
if (navType === SIDE_NAV_TYPE.
|
|
219
|
+
if (navType === SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
201
220
|
return;
|
|
202
221
|
}
|
|
203
222
|
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
@@ -325,7 +344,7 @@ function SideNavRenderFunction({
|
|
|
325
344
|
}
|
|
326
345
|
};
|
|
327
346
|
}
|
|
328
|
-
if (addMouseListeners && isRail) {
|
|
347
|
+
if (addMouseListeners && !pinned && (isRail || autoExpand)) {
|
|
329
348
|
eventHandlers.onMouseEnter = () => {
|
|
330
349
|
handleToggle(true, true);
|
|
331
350
|
};
|
|
@@ -335,6 +354,9 @@ function SideNavRenderFunction({
|
|
|
335
354
|
handleToggle(false, false);
|
|
336
355
|
};
|
|
337
356
|
eventHandlers.onClick = () => {
|
|
357
|
+
if (autoExpand) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
338
360
|
//if delay is enabled, and user intentionally clicks it to see it expanded immediately
|
|
339
361
|
setExpandedState(true);
|
|
340
362
|
setExpandedViaHoverState(true);
|
|
@@ -345,7 +367,7 @@ function SideNavRenderFunction({
|
|
|
345
367
|
const target = event.target;
|
|
346
368
|
const isNavItemClick = target.closest(`.${prefix}--side-nav a, .${prefix}--side-nav button`);
|
|
347
369
|
const isInRail = isNavItemClick?.closest(`.${prefix}--side-nav--rail`);
|
|
348
|
-
if (isNavItemClick && !isNavItemClick.classList.contains(`${prefix}--side-nav__submenu`) && !isNavItemClick.classList.contains(`${prefix}--side-nav__back-button`)) {
|
|
370
|
+
if (isNavItemClick && !isNavItemClick.classList.contains(`${prefix}--side-nav__submenu`) && !isNavItemClick.classList.contains(`${prefix}--side-nav__back-button`) && !isNavItemClick.classList.contains(`${prefix}--side-nav__toggle`)) {
|
|
349
371
|
isInRail ? handleToggle(false, false) : onSideNavBlur?.();
|
|
350
372
|
}
|
|
351
373
|
});
|
|
@@ -359,15 +381,6 @@ function SideNavRenderFunction({
|
|
|
359
381
|
});
|
|
360
382
|
const lgMediaQuery = `(min-width: ${breakpoints.lg.width})`;
|
|
361
383
|
const isLg = useMatchMedia(lgMediaQuery);
|
|
362
|
-
function resetNodeTabIndices() {
|
|
363
|
-
const items = sideNavRef?.current?.querySelectorAll('[tabIndex="0"]') ?? [];
|
|
364
|
-
items.forEach(item => {
|
|
365
|
-
if (item.classList.contains(`${prefix}--side-nav__toggle`) || item.classList.contains(`${prefix}--side-nav__back-button`) || item.closest(`.${prefix}--side-nav__slot-item`) || item.classList.contains(`${prefix}--side-nav__link`) && item.closest('ul')?.getAttribute('aria-label') === ariaLabel) {
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
item.tabIndex = -1;
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
384
|
|
|
372
385
|
// ensure that changes are in sync with internal treeview prop
|
|
373
386
|
useEffect(() => {
|
|
@@ -382,13 +395,22 @@ function SideNavRenderFunction({
|
|
|
382
395
|
setInternalIsTreeview(value);
|
|
383
396
|
}
|
|
384
397
|
};
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
398
|
+
const handlePinClick = () => {
|
|
399
|
+
setPinned(!pinned);
|
|
400
|
+
if (!autoExpand) {
|
|
401
|
+
setExpandedState(!pinned);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
const handleAutoExpand = () => {
|
|
405
|
+
if (pinned) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
setExpandedState(!autoExpand);
|
|
409
|
+
setAutoExpand(!autoExpand);
|
|
410
|
+
};
|
|
390
411
|
return /*#__PURE__*/React__default.createElement(SideNavContext.Provider, {
|
|
391
412
|
value: {
|
|
413
|
+
autoExpand,
|
|
392
414
|
expanded,
|
|
393
415
|
isRail,
|
|
394
416
|
navType,
|
|
@@ -397,7 +419,7 @@ function SideNavRenderFunction({
|
|
|
397
419
|
currentPrimaryMenu,
|
|
398
420
|
setCurrentPrimaryMenu
|
|
399
421
|
}
|
|
400
|
-
}, isFixedNav || hideOverlay || navType === SIDE_NAV_TYPE.
|
|
422
|
+
}, isFixedNav || hideOverlay || navType === SIDE_NAV_TYPE.RAIL_PANEL ? null :
|
|
401
423
|
/*#__PURE__*/
|
|
402
424
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
403
425
|
React__default.createElement("div", {
|
|
@@ -408,10 +430,17 @@ function SideNavRenderFunction({
|
|
|
408
430
|
tabIndex: -1,
|
|
409
431
|
ref: navRef,
|
|
410
432
|
className: `${prefix}--side-nav__navigation ${className}`,
|
|
411
|
-
inert: !isRail && navType !== SIDE_NAV_TYPE.
|
|
412
|
-
}, accessibilityLabel, eventHandlers, other), childrenToRender, navType === SIDE_NAV_TYPE.
|
|
433
|
+
inert: !isRail && navType !== SIDE_NAV_TYPE.RAIL_PANEL && !(expanded || isLg) ? -1 : undefined
|
|
434
|
+
}, accessibilityLabel, eventHandlers, other), childrenToRender, navType === SIDE_NAV_TYPE.RAIL_PANEL && /*#__PURE__*/React__default.createElement("ul", {
|
|
413
435
|
className: `${prefix}--side-nav__toggle-container`
|
|
414
|
-
},
|
|
436
|
+
}, _SideNavDivider || (_SideNavDivider = /*#__PURE__*/React__default.createElement(SideNavDivider, null)), /*#__PURE__*/React__default.createElement(SideNavToggle, {
|
|
437
|
+
onClick: handlePinClick,
|
|
438
|
+
renderIcon: pinned ? PinFilled : Pin
|
|
439
|
+
}, pinText), /*#__PURE__*/React__default.createElement(SideNavToggle, {
|
|
440
|
+
disabled: pinned,
|
|
441
|
+
renderIcon: expandedState ? SidePanelClose : SidePanelOpen,
|
|
442
|
+
onClick: handleAutoExpand
|
|
443
|
+
}, autoExpandText))));
|
|
415
444
|
}
|
|
416
445
|
const SideNav = /*#__PURE__*/React__default.forwardRef(SideNavRenderFunction);
|
|
417
446
|
SideNav.displayName = 'SideNav';
|
|
@@ -12,7 +12,7 @@ import React__default, { forwardRef, useContext } from 'react';
|
|
|
12
12
|
import Link, { LinkPropTypes } from './Link.js';
|
|
13
13
|
import { SideNavItem, SideNavLinkText, SideNavIcon } from '@carbon/react';
|
|
14
14
|
import { usePrefix } from '../internal/usePrefix.js';
|
|
15
|
-
import { SideNavContext } from './SideNav.js';
|
|
15
|
+
import { SideNavContext, SIDE_NAV_TYPE } from './SideNav.js';
|
|
16
16
|
import { SideNavLinkPopover } from './SideNavLinkPopover.js';
|
|
17
17
|
|
|
18
18
|
const SideNavLink = /*#__PURE__*/forwardRef(function SideNavLink({
|
|
@@ -39,7 +39,7 @@ const SideNavLink = /*#__PURE__*/forwardRef(function SideNavLink({
|
|
|
39
39
|
const SideNavLinkIcon = IconElement && /*#__PURE__*/React__default.createElement(SideNavIcon, {
|
|
40
40
|
small: true
|
|
41
41
|
}, /*#__PURE__*/React__default.createElement(IconElement, null));
|
|
42
|
-
if (!expanded && navType ===
|
|
42
|
+
if (!expanded && navType === SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
43
43
|
return /*#__PURE__*/React__default.createElement(SideNavLinkPopover, _extends({
|
|
44
44
|
align: "right",
|
|
45
45
|
label: children
|
|
@@ -62,6 +62,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
62
62
|
const [prevExpanded, setPrevExpanded] = useState(defaultExpanded);
|
|
63
63
|
const [isSecondaryOpen, setSecondaryOpen] = useState(defaultExpanded);
|
|
64
64
|
const {
|
|
65
|
+
autoExpand,
|
|
65
66
|
currentPrimaryMenu,
|
|
66
67
|
setCurrentPrimaryMenu
|
|
67
68
|
} = useContext(SideNavContext);
|
|
@@ -148,7 +149,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
148
149
|
return false;
|
|
149
150
|
}
|
|
150
151
|
useEffect(() => {
|
|
151
|
-
if (navType == SIDE_NAV_TYPE.
|
|
152
|
+
if (navType == SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
152
153
|
// grab first link to redirect if clicked when not expanded
|
|
153
154
|
if (!firstLink?.current && listRef?.current) {
|
|
154
155
|
const firstLinkElement = listRef.current.querySelector(`.${prefix}--side-nav__menu-item a`);
|
|
@@ -282,7 +283,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
282
283
|
}, [currentPrimaryMenu]);
|
|
283
284
|
// reset to opened/collapsed menu state when Panel SideNav is toggled
|
|
284
285
|
useEffect(() => {
|
|
285
|
-
if (navType == SIDE_NAV_TYPE.
|
|
286
|
+
if (navType == SIDE_NAV_TYPE.RAIL_PANEL && !sideNavExpanded) {
|
|
286
287
|
setIsExpanded(false);
|
|
287
288
|
}
|
|
288
289
|
|
|
@@ -319,7 +320,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
319
320
|
}
|
|
320
321
|
|
|
321
322
|
// only when sidenav is panel view
|
|
322
|
-
if (navType == SIDE_NAV_TYPE.
|
|
323
|
+
if (navType == SIDE_NAV_TYPE.RAIL_PANEL && !isExpanded && firstLink.current && !sideNavExpanded) {
|
|
323
324
|
setOpenPopover(!openPopover);
|
|
324
325
|
// window.location.href = firstLink.current;
|
|
325
326
|
} else if (isSm || !primary || currentPrimaryMenu !== uniqueId) {
|
|
@@ -332,7 +333,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
332
333
|
ref: menuRef,
|
|
333
334
|
type: "button",
|
|
334
335
|
tabIndex: isTreeview ? -1 : 0
|
|
335
|
-
}, IconElement && /*#__PURE__*/React__default.createElement(SideNavIcon, null, /*#__PURE__*/React__default.createElement(IconElement, null)), !sideNavExpanded && navType == SIDE_NAV_TYPE.
|
|
336
|
+
}, IconElement && /*#__PURE__*/React__default.createElement(SideNavIcon, null, /*#__PURE__*/React__default.createElement(IconElement, null)), !autoExpand && !sideNavExpanded && navType == SIDE_NAV_TYPE.RAIL_PANEL && /*#__PURE__*/React__default.createElement("div", {
|
|
336
337
|
className: `${prefix}--side-nav--panel-submenu-caret-container`
|
|
337
338
|
}, /*#__PURE__*/React__default.createElement("div", {
|
|
338
339
|
className: `${prefix}--side-nav--panel-submenu-caret`
|
|
@@ -362,7 +363,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
362
363
|
className: `${prefix}--side-nav__menu`,
|
|
363
364
|
role: "group"
|
|
364
365
|
}, childrenToRender));
|
|
365
|
-
return navType == SIDE_NAV_TYPE.
|
|
366
|
+
return navType == SIDE_NAV_TYPE.RAIL_PANEL && !sideNavExpanded ? /*#__PURE__*/React__default.createElement(SideNavFlyoutMenu, {
|
|
366
367
|
selected: active,
|
|
367
368
|
className: `${prefix}--side-nav-flyout-menu`,
|
|
368
369
|
title: title,
|
|
@@ -4,29 +4,54 @@
|
|
|
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
|
|
8
|
-
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import { ComponentType, ElementType, ForwardedRef, ReactNode } from 'react';
|
|
9
|
+
import { LinkProps } from './Link';
|
|
10
|
+
export type SideNavToggleProps<E extends ElementType> = LinkProps<E> & {
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Required props for the accessibility label
|
|
11
13
|
*/
|
|
12
|
-
|
|
14
|
+
'aria-label'?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Required props for the accessibility label
|
|
17
|
+
*/
|
|
18
|
+
'aria-labelledby'?: string;
|
|
13
19
|
/**
|
|
14
20
|
* Specify the text content for the link
|
|
15
21
|
*/
|
|
16
|
-
children
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Provide an optional class to be applied to the containing node
|
|
25
|
+
*/
|
|
26
|
+
className?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Specify whether the link is the current page
|
|
29
|
+
*/
|
|
30
|
+
isActive?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Property to indicate if the side nav container is open (or not). Use to
|
|
33
|
+
* keep local state and styling in step with the SideNav expansion state.
|
|
34
|
+
*/
|
|
35
|
+
isSideNavExpanded?: boolean;
|
|
17
36
|
/**
|
|
18
|
-
*
|
|
37
|
+
* Specify if this is a large variation of the SideNavLink
|
|
19
38
|
*/
|
|
20
|
-
|
|
39
|
+
large?: boolean;
|
|
21
40
|
/**
|
|
22
|
-
*
|
|
41
|
+
* Provide an icon to render in the side navigation link. Should be a React class.
|
|
23
42
|
*/
|
|
24
|
-
renderIcon?:
|
|
43
|
+
renderIcon?: ComponentType;
|
|
25
44
|
/**
|
|
26
|
-
*
|
|
27
|
-
* If not specified, the default validation will be applied.
|
|
45
|
+
* Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
|
|
28
46
|
*/
|
|
29
47
|
tabIndex?: number;
|
|
48
|
+
};
|
|
49
|
+
export interface SideNavLinkComponent {
|
|
50
|
+
(props: SideNavToggleProps<'button'> & {
|
|
51
|
+
ref?: ForwardedRef<HTMLButtonElement>;
|
|
52
|
+
}): JSX.Element | null;
|
|
53
|
+
displayName?: string;
|
|
54
|
+
propTypes?: Partial<Record<keyof SideNavToggleProps<any>, PropTypes.Validator<any>>>;
|
|
30
55
|
}
|
|
31
|
-
export declare const SideNavToggle:
|
|
56
|
+
export declare const SideNavToggle: SideNavLinkComponent;
|
|
32
57
|
export default SideNavToggle;
|
|
@@ -8,47 +8,79 @@
|
|
|
8
8
|
import { extends as _extends } from '../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import cx from 'classnames';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
|
-
import React__default from 'react';
|
|
12
|
-
import {
|
|
11
|
+
import React__default, { forwardRef, useContext } from 'react';
|
|
12
|
+
import { LinkPropTypes } from './Link.js';
|
|
13
|
+
import { SideNavItem, SideNavLinkText, SideNavIcon } from '@carbon/react';
|
|
13
14
|
import { usePrefix } from '../internal/usePrefix.js';
|
|
15
|
+
import { SideNavContext, SIDE_NAV_TYPE } from './SideNav.js';
|
|
16
|
+
import { SideNavLinkPopover } from './SideNavLinkPopover.js';
|
|
14
17
|
|
|
15
|
-
const SideNavToggle = /*#__PURE__*/
|
|
18
|
+
const SideNavToggle = /*#__PURE__*/forwardRef(function SideNavToggle({
|
|
19
|
+
children,
|
|
16
20
|
className: customClassName,
|
|
21
|
+
disabled,
|
|
17
22
|
renderIcon: IconElement,
|
|
23
|
+
large = false,
|
|
18
24
|
tabIndex,
|
|
19
|
-
children,
|
|
20
25
|
...rest
|
|
21
26
|
}, ref) {
|
|
27
|
+
const {
|
|
28
|
+
expanded,
|
|
29
|
+
navType
|
|
30
|
+
} = useContext(SideNavContext);
|
|
22
31
|
const prefix = usePrefix();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
const className = cx({
|
|
33
|
+
[`${prefix}--side-nav__toggle`]: true,
|
|
34
|
+
[`${prefix}--side-nav__toggle--disabled`]: disabled,
|
|
35
|
+
[customClassName]: !!customClassName
|
|
36
|
+
});
|
|
37
|
+
const SideNavLinkIcon = IconElement && /*#__PURE__*/React__default.createElement(SideNavIcon, {
|
|
38
|
+
small: true
|
|
39
|
+
}, /*#__PURE__*/React__default.createElement(IconElement, null));
|
|
40
|
+
if (!expanded && navType === SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
41
|
+
return /*#__PURE__*/React__default.createElement(SideNavLinkPopover, _extends({
|
|
42
|
+
align: "right",
|
|
43
|
+
className: className,
|
|
44
|
+
label: children
|
|
45
|
+
}, rest), SideNavLinkIcon);
|
|
46
|
+
}
|
|
47
|
+
return /*#__PURE__*/React__default.createElement(SideNavItem, {
|
|
48
|
+
large: large
|
|
49
|
+
}, /*#__PURE__*/React__default.createElement("button", _extends({
|
|
50
|
+
className: className,
|
|
27
51
|
ref: ref,
|
|
28
52
|
type: "button",
|
|
29
|
-
tabIndex: tabIndex ?? 0
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}, children));
|
|
53
|
+
tabIndex: tabIndex ?? 0,
|
|
54
|
+
disabled: disabled
|
|
55
|
+
}, rest), SideNavLinkIcon, /*#__PURE__*/React__default.createElement(SideNavLinkText, null, children)));
|
|
33
56
|
});
|
|
34
57
|
SideNavToggle.displayName = 'SideNavToggle';
|
|
35
58
|
SideNavToggle.propTypes = {
|
|
59
|
+
...LinkPropTypes,
|
|
36
60
|
/**
|
|
37
|
-
* Specify the text content for the
|
|
61
|
+
* Specify the text content for the link
|
|
38
62
|
*/
|
|
39
63
|
children: PropTypes.node,
|
|
40
64
|
/**
|
|
41
|
-
*
|
|
65
|
+
* Provide an optional class to be applied to the containing node
|
|
42
66
|
*/
|
|
43
67
|
className: PropTypes.string,
|
|
44
68
|
/**
|
|
45
|
-
*
|
|
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
|
|
46
79
|
*/
|
|
47
|
-
|
|
80
|
+
large: PropTypes.bool,
|
|
48
81
|
/**
|
|
49
|
-
*
|
|
82
|
+
* Provide an icon to render in the side navigation link. Should be a React class.
|
|
50
83
|
*/
|
|
51
|
-
// @ts-expect-error - PropTypes are unable to cover this case.
|
|
52
84
|
renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
53
85
|
/**
|
|
54
86
|
* Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
|
|
@@ -21,14 +21,15 @@ const Profile = /*#__PURE__*/React__default.forwardRef(function Profile({
|
|
|
21
21
|
children,
|
|
22
22
|
renderIcon: IconElement,
|
|
23
23
|
...rest
|
|
24
|
-
}) {
|
|
24
|
+
}, ref) {
|
|
25
25
|
const prefix = usePrefix.usePrefix();
|
|
26
26
|
const className = cx({
|
|
27
27
|
[`${prefix}--profile`]: true,
|
|
28
28
|
[customClassName]: !!customClassName
|
|
29
29
|
});
|
|
30
30
|
return /*#__PURE__*/React__default.createElement(HeaderPopover.HeaderPopover, _rollupPluginBabelHelpers.extends({
|
|
31
|
-
|
|
31
|
+
ref: ref,
|
|
32
|
+
align: "bottom-end",
|
|
32
33
|
className: className
|
|
33
34
|
}, rest), /*#__PURE__*/React__default.createElement(HeaderPopover.HeaderPopoverButton, {
|
|
34
35
|
align: "bottom",
|
|
@@ -60,13 +61,14 @@ const ProfileUserInfo = /*#__PURE__*/React__default.forwardRef(function ProfileU
|
|
|
60
61
|
name,
|
|
61
62
|
email,
|
|
62
63
|
...rest
|
|
63
|
-
}) {
|
|
64
|
+
}, ref) {
|
|
64
65
|
const prefix = usePrefix.usePrefix();
|
|
65
66
|
const className = cx({
|
|
66
67
|
[`${prefix}--profile-user-info`]: true,
|
|
67
68
|
[customClassName]: !!customClassName
|
|
68
69
|
});
|
|
69
70
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
71
|
+
ref: ref,
|
|
70
72
|
className: className
|
|
71
73
|
}, /*#__PURE__*/React__default.createElement(UserAvatar.UserAvatar, _rollupPluginBabelHelpers.extends({
|
|
72
74
|
size: "lg",
|
|
@@ -97,13 +99,14 @@ ProfileUserInfo.propTypes = {
|
|
|
97
99
|
const ProfileReadOnly = /*#__PURE__*/React__default.forwardRef(function ProfileReadOnly({
|
|
98
100
|
className: customClassName,
|
|
99
101
|
items
|
|
100
|
-
}) {
|
|
102
|
+
}, ref) {
|
|
101
103
|
const prefix = usePrefix.usePrefix();
|
|
102
104
|
const className = cx({
|
|
103
105
|
[`${prefix}--profile-read-only`]: true,
|
|
104
106
|
[customClassName]: !!customClassName
|
|
105
107
|
});
|
|
106
108
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
109
|
+
ref: ref,
|
|
107
110
|
className: className
|
|
108
111
|
}, items?.map((item, index) => /*#__PURE__*/React__default.createElement("div", {
|
|
109
112
|
className: `${prefix}--profile-read-only__items`,
|
|
@@ -9,12 +9,14 @@ import { TranslateWithId } from '../types/common';
|
|
|
9
9
|
export declare enum SIDE_NAV_TYPE {
|
|
10
10
|
DEFAULT = "default",
|
|
11
11
|
RAIL = "rail",
|
|
12
|
-
|
|
12
|
+
RAIL_PANEL = "panel"
|
|
13
13
|
}
|
|
14
14
|
export type TranslationKey = keyof typeof translationIds;
|
|
15
15
|
export declare const translationIds: {
|
|
16
16
|
readonly 'collapse.sidenav': "collapse.sidenav";
|
|
17
17
|
readonly 'expand.sidenav': "expand.sidenav";
|
|
18
|
+
readonly 'enable.autoexpand': "enable.autoexpand";
|
|
19
|
+
readonly 'disable.autoexpand': "disable.autoexpand";
|
|
18
20
|
};
|
|
19
21
|
export interface SideNavProps extends ComponentProps<'nav'>, TranslateWithId<TranslationKey> {
|
|
20
22
|
expanded?: boolean;
|
|
@@ -38,6 +40,7 @@ export interface SideNavProps extends ComponentProps<'nav'>, TranslateWithId<Tra
|
|
|
38
40
|
isTreeview?: boolean;
|
|
39
41
|
}
|
|
40
42
|
interface SideNavContextData {
|
|
43
|
+
autoExpand?: boolean;
|
|
41
44
|
expanded?: boolean;
|
|
42
45
|
isRail?: boolean;
|
|
43
46
|
navType?: SIDE_NAV_TYPE;
|
|
@@ -23,20 +23,26 @@ var index = require('../node_modules/@carbon/layout/es/index.js');
|
|
|
23
23
|
var useMatchMedia = require('../internal/useMatchMedia.js');
|
|
24
24
|
var iconsReact = require('@carbon/icons-react');
|
|
25
25
|
var SideNavToggle = require('./SideNavToggle.js');
|
|
26
|
+
var react = require('@carbon/react');
|
|
26
27
|
|
|
28
|
+
var _SideNavDivider;
|
|
27
29
|
let SIDE_NAV_TYPE = /*#__PURE__*/function (SIDE_NAV_TYPE) {
|
|
28
30
|
SIDE_NAV_TYPE["DEFAULT"] = "default";
|
|
29
31
|
SIDE_NAV_TYPE["RAIL"] = "rail";
|
|
30
|
-
SIDE_NAV_TYPE["
|
|
32
|
+
SIDE_NAV_TYPE["RAIL_PANEL"] = "panel";
|
|
31
33
|
return SIDE_NAV_TYPE;
|
|
32
34
|
}({});
|
|
33
35
|
const translationIds = {
|
|
34
36
|
'collapse.sidenav': 'collapse.sidenav',
|
|
35
|
-
'expand.sidenav': 'expand.sidenav'
|
|
37
|
+
'expand.sidenav': 'expand.sidenav',
|
|
38
|
+
'enable.autoexpand': 'enable.autoexpand',
|
|
39
|
+
'disable.autoexpand': 'disable.autoexpand'
|
|
36
40
|
};
|
|
37
41
|
const defaultTranslations = {
|
|
38
|
-
[translationIds['collapse.sidenav']]: '
|
|
39
|
-
[translationIds['expand.sidenav']]: '
|
|
42
|
+
[translationIds['collapse.sidenav']]: 'Unpin',
|
|
43
|
+
[translationIds['expand.sidenav']]: 'Pin open',
|
|
44
|
+
[translationIds['enable.autoexpand']]: 'Enable auto-expand',
|
|
45
|
+
[translationIds['disable.autoexpand']]: 'Disable auto-expand'
|
|
40
46
|
};
|
|
41
47
|
const defaultTranslateWithId = id => defaultTranslations[id];
|
|
42
48
|
const SideNavContext = /*#__PURE__*/React__default.createContext({});
|
|
@@ -71,13 +77,16 @@ function SideNavRenderFunction({
|
|
|
71
77
|
const {
|
|
72
78
|
current: controlled
|
|
73
79
|
} = React__default.useRef(expandedProp !== undefined);
|
|
80
|
+
const [autoExpand, setAutoExpand] = React__default.useState(false);
|
|
74
81
|
const [expandedState, setExpandedState] = useDelayedState.useDelayedState(defaultExpanded);
|
|
75
82
|
const [expandedViaHoverState, setExpandedViaHoverState] = useDelayedState.useDelayedState(defaultExpanded);
|
|
83
|
+
const [pinned, setPinned] = React__default.useState(false);
|
|
76
84
|
const expanded = controlled ? expandedProp : expandedState;
|
|
77
85
|
const sideNavRef = React__default.useRef(null);
|
|
78
86
|
const navRef = useMergedRefs.useMergedRefs([sideNavRef, ref]);
|
|
79
87
|
const [currentPrimaryMenu, setCurrentPrimaryMenu] = React__default.useState();
|
|
80
|
-
const
|
|
88
|
+
const pinText = pinned ? t('collapse.sidenav') : t('expand.sidenav');
|
|
89
|
+
const autoExpandText = autoExpand ? t('disable.autoexpand') : t('enable.autoexpand');
|
|
81
90
|
const handleToggle = (event, value = !expanded) => {
|
|
82
91
|
if (!controlled) {
|
|
83
92
|
setExpandedState(value, enterDelayMs);
|
|
@@ -98,8 +107,9 @@ function SideNavRenderFunction({
|
|
|
98
107
|
[`${prefix}--side-nav--expanded`]: expanded || expandedViaHoverState,
|
|
99
108
|
[`${prefix}--side-nav--collapsed`]: !expanded && isFixedNav,
|
|
100
109
|
[`${prefix}--side-nav--hide-rail-breakpoint-down-${hideRailBreakpointDown}`]: hideRailBreakpointDown,
|
|
101
|
-
[`${prefix}--side-nav--rail`]: isRail,
|
|
102
|
-
[`${prefix}--side-nav--panel`]: navType === SIDE_NAV_TYPE.
|
|
110
|
+
[`${prefix}--side-nav--rail`]: isRail || autoExpand,
|
|
111
|
+
[`${prefix}--side-nav--panel`]: navType === SIDE_NAV_TYPE.RAIL_PANEL,
|
|
112
|
+
[`${prefix}--side-nav--pinned`]: pinned,
|
|
103
113
|
[`${prefix}--side-nav--ux`]: isChildOfHeader,
|
|
104
114
|
[`${prefix}--side-nav--hidden`]: !isPersistent,
|
|
105
115
|
[`${prefix}--side-nav--collapsible`]: isCollapsible,
|
|
@@ -130,6 +140,15 @@ function SideNavRenderFunction({
|
|
|
130
140
|
return child;
|
|
131
141
|
});
|
|
132
142
|
const eventHandlers = {};
|
|
143
|
+
const resetNodeTabIndices = React__default.useCallback(() => {
|
|
144
|
+
const items = sideNavRef?.current?.querySelectorAll('[tabIndex="0"]') ?? [];
|
|
145
|
+
items.forEach(item => {
|
|
146
|
+
if (item.classList.contains(`${prefix}--side-nav__toggle`) || item.classList.contains(`${prefix}--side-nav__back-button`) || item.closest(`.${prefix}--side-nav__slot-item`) || item.classList.contains(`${prefix}--side-nav__link`) && item.closest('ul')?.getAttribute('aria-label') === ariaLabel) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
item.tabIndex = -1;
|
|
150
|
+
});
|
|
151
|
+
}, [prefix, ariaLabel]);
|
|
133
152
|
const treeWalkerRef = React__default.useRef(null);
|
|
134
153
|
React__default.useEffect(() => {
|
|
135
154
|
if (internalIsTreeview) {
|
|
@@ -149,7 +168,7 @@ function SideNavRenderFunction({
|
|
|
149
168
|
});
|
|
150
169
|
resetNodeTabIndices();
|
|
151
170
|
}
|
|
152
|
-
}, [prefix, internalIsTreeview]);
|
|
171
|
+
}, [prefix, internalIsTreeview, resetNodeTabIndices]);
|
|
153
172
|
const smMediaQuery = `(min-width: ${index.breakpoints.sm.width})`;
|
|
154
173
|
const isSm = useMatchMedia.useMatchMedia(smMediaQuery);
|
|
155
174
|
React__default.useEffect(() => {
|
|
@@ -158,7 +177,7 @@ function SideNavRenderFunction({
|
|
|
158
177
|
const slotElement = sideNavRef?.current.querySelector(`.${prefix}--side-nav__slot`);
|
|
159
178
|
const firstElement = sideNavRef?.current?.querySelector('a, button');
|
|
160
179
|
const currentElement = sideNavRef?.current?.querySelector(`.cds--side-nav__link--current`);
|
|
161
|
-
if (navType == SIDE_NAV_TYPE.
|
|
180
|
+
if (navType == SIDE_NAV_TYPE.RAIL_PANEL || expanded) {
|
|
162
181
|
if (isSm && backButton) {
|
|
163
182
|
backButton.tabIndex = 0;
|
|
164
183
|
const firstElementAfterBack = backButton.nextElementSibling?.querySelector('a, button');
|
|
@@ -178,7 +197,7 @@ function SideNavRenderFunction({
|
|
|
178
197
|
}
|
|
179
198
|
}
|
|
180
199
|
}
|
|
181
|
-
}, [expanded]);
|
|
200
|
+
}, [expanded, currentPrimaryMenu, isSm, navType, prefix]);
|
|
182
201
|
|
|
183
202
|
/**
|
|
184
203
|
* Returns the parent SideNavMenu, if node is actually inside one.
|
|
@@ -194,12 +213,12 @@ function SideNavRenderFunction({
|
|
|
194
213
|
}
|
|
195
214
|
if (addFocusListeners) {
|
|
196
215
|
eventHandlers.onFocus = event => {
|
|
197
|
-
if (!event.currentTarget.contains(event.relatedTarget) && isRail) {
|
|
216
|
+
if (!event.currentTarget.contains(event.relatedTarget) && (isRail || autoExpand)) {
|
|
198
217
|
handleToggle(event, true);
|
|
199
218
|
}
|
|
200
219
|
};
|
|
201
220
|
eventHandlers.onBlur = event => {
|
|
202
|
-
if (navType === SIDE_NAV_TYPE.
|
|
221
|
+
if (navType === SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
203
222
|
return;
|
|
204
223
|
}
|
|
205
224
|
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
@@ -327,7 +346,7 @@ function SideNavRenderFunction({
|
|
|
327
346
|
}
|
|
328
347
|
};
|
|
329
348
|
}
|
|
330
|
-
if (addMouseListeners && isRail) {
|
|
349
|
+
if (addMouseListeners && !pinned && (isRail || autoExpand)) {
|
|
331
350
|
eventHandlers.onMouseEnter = () => {
|
|
332
351
|
handleToggle(true, true);
|
|
333
352
|
};
|
|
@@ -337,6 +356,9 @@ function SideNavRenderFunction({
|
|
|
337
356
|
handleToggle(false, false);
|
|
338
357
|
};
|
|
339
358
|
eventHandlers.onClick = () => {
|
|
359
|
+
if (autoExpand) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
340
362
|
//if delay is enabled, and user intentionally clicks it to see it expanded immediately
|
|
341
363
|
setExpandedState(true);
|
|
342
364
|
setExpandedViaHoverState(true);
|
|
@@ -347,7 +369,7 @@ function SideNavRenderFunction({
|
|
|
347
369
|
const target = event.target;
|
|
348
370
|
const isNavItemClick = target.closest(`.${prefix}--side-nav a, .${prefix}--side-nav button`);
|
|
349
371
|
const isInRail = isNavItemClick?.closest(`.${prefix}--side-nav--rail`);
|
|
350
|
-
if (isNavItemClick && !isNavItemClick.classList.contains(`${prefix}--side-nav__submenu`) && !isNavItemClick.classList.contains(`${prefix}--side-nav__back-button`)) {
|
|
372
|
+
if (isNavItemClick && !isNavItemClick.classList.contains(`${prefix}--side-nav__submenu`) && !isNavItemClick.classList.contains(`${prefix}--side-nav__back-button`) && !isNavItemClick.classList.contains(`${prefix}--side-nav__toggle`)) {
|
|
351
373
|
isInRail ? handleToggle(false, false) : onSideNavBlur?.();
|
|
352
374
|
}
|
|
353
375
|
});
|
|
@@ -361,15 +383,6 @@ function SideNavRenderFunction({
|
|
|
361
383
|
});
|
|
362
384
|
const lgMediaQuery = `(min-width: ${index.breakpoints.lg.width})`;
|
|
363
385
|
const isLg = useMatchMedia.useMatchMedia(lgMediaQuery);
|
|
364
|
-
function resetNodeTabIndices() {
|
|
365
|
-
const items = sideNavRef?.current?.querySelectorAll('[tabIndex="0"]') ?? [];
|
|
366
|
-
items.forEach(item => {
|
|
367
|
-
if (item.classList.contains(`${prefix}--side-nav__toggle`) || item.classList.contains(`${prefix}--side-nav__back-button`) || item.closest(`.${prefix}--side-nav__slot-item`) || item.classList.contains(`${prefix}--side-nav__link`) && item.closest('ul')?.getAttribute('aria-label') === ariaLabel) {
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
item.tabIndex = -1;
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
386
|
|
|
374
387
|
// ensure that changes are in sync with internal treeview prop
|
|
375
388
|
React__default.useEffect(() => {
|
|
@@ -384,13 +397,22 @@ function SideNavRenderFunction({
|
|
|
384
397
|
setInternalIsTreeview(value);
|
|
385
398
|
}
|
|
386
399
|
};
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
400
|
+
const handlePinClick = () => {
|
|
401
|
+
setPinned(!pinned);
|
|
402
|
+
if (!autoExpand) {
|
|
403
|
+
setExpandedState(!pinned);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
const handleAutoExpand = () => {
|
|
407
|
+
if (pinned) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
setExpandedState(!autoExpand);
|
|
411
|
+
setAutoExpand(!autoExpand);
|
|
412
|
+
};
|
|
392
413
|
return /*#__PURE__*/React__default.createElement(SideNavContext.Provider, {
|
|
393
414
|
value: {
|
|
415
|
+
autoExpand,
|
|
394
416
|
expanded,
|
|
395
417
|
isRail,
|
|
396
418
|
navType,
|
|
@@ -399,7 +421,7 @@ function SideNavRenderFunction({
|
|
|
399
421
|
currentPrimaryMenu,
|
|
400
422
|
setCurrentPrimaryMenu
|
|
401
423
|
}
|
|
402
|
-
}, isFixedNav || hideOverlay || navType === SIDE_NAV_TYPE.
|
|
424
|
+
}, isFixedNav || hideOverlay || navType === SIDE_NAV_TYPE.RAIL_PANEL ? null :
|
|
403
425
|
/*#__PURE__*/
|
|
404
426
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
405
427
|
React__default.createElement("div", {
|
|
@@ -410,10 +432,17 @@ function SideNavRenderFunction({
|
|
|
410
432
|
tabIndex: -1,
|
|
411
433
|
ref: navRef,
|
|
412
434
|
className: `${prefix}--side-nav__navigation ${className}`,
|
|
413
|
-
inert: !isRail && navType !== SIDE_NAV_TYPE.
|
|
414
|
-
}, accessibilityLabel, eventHandlers, other), childrenToRender, navType === SIDE_NAV_TYPE.
|
|
435
|
+
inert: !isRail && navType !== SIDE_NAV_TYPE.RAIL_PANEL && !(expanded || isLg) ? -1 : undefined
|
|
436
|
+
}, accessibilityLabel, eventHandlers, other), childrenToRender, navType === SIDE_NAV_TYPE.RAIL_PANEL && /*#__PURE__*/React__default.createElement("ul", {
|
|
415
437
|
className: `${prefix}--side-nav__toggle-container`
|
|
416
|
-
},
|
|
438
|
+
}, _SideNavDivider || (_SideNavDivider = /*#__PURE__*/React__default.createElement(react.SideNavDivider, null)), /*#__PURE__*/React__default.createElement(SideNavToggle.SideNavToggle, {
|
|
439
|
+
onClick: handlePinClick,
|
|
440
|
+
renderIcon: pinned ? iconsReact.PinFilled : iconsReact.Pin
|
|
441
|
+
}, pinText), /*#__PURE__*/React__default.createElement(SideNavToggle.SideNavToggle, {
|
|
442
|
+
disabled: pinned,
|
|
443
|
+
renderIcon: expandedState ? iconsReact.SidePanelClose : iconsReact.SidePanelOpen,
|
|
444
|
+
onClick: handleAutoExpand
|
|
445
|
+
}, autoExpandText))));
|
|
417
446
|
}
|
|
418
447
|
const SideNav = /*#__PURE__*/React__default.forwardRef(SideNavRenderFunction);
|
|
419
448
|
SideNav.displayName = 'SideNav';
|
|
@@ -43,7 +43,7 @@ const SideNavLink = /*#__PURE__*/React__default.forwardRef(function SideNavLink(
|
|
|
43
43
|
const SideNavLinkIcon = IconElement && /*#__PURE__*/React__default.createElement(react.SideNavIcon, {
|
|
44
44
|
small: true
|
|
45
45
|
}, /*#__PURE__*/React__default.createElement(IconElement, null));
|
|
46
|
-
if (!expanded && navType ===
|
|
46
|
+
if (!expanded && navType === SideNav.SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
47
47
|
return /*#__PURE__*/React__default.createElement(SideNavLinkPopover.SideNavLinkPopover, _rollupPluginBabelHelpers.extends({
|
|
48
48
|
align: "right",
|
|
49
49
|
label: children
|
|
@@ -64,6 +64,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
64
64
|
const [prevExpanded, setPrevExpanded] = React__default.useState(defaultExpanded);
|
|
65
65
|
const [isSecondaryOpen, setSecondaryOpen] = React__default.useState(defaultExpanded);
|
|
66
66
|
const {
|
|
67
|
+
autoExpand,
|
|
67
68
|
currentPrimaryMenu,
|
|
68
69
|
setCurrentPrimaryMenu
|
|
69
70
|
} = React__default.useContext(SideNav.SideNavContext);
|
|
@@ -150,7 +151,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
150
151
|
return false;
|
|
151
152
|
}
|
|
152
153
|
React__default.useEffect(() => {
|
|
153
|
-
if (navType == SideNav.SIDE_NAV_TYPE.
|
|
154
|
+
if (navType == SideNav.SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
154
155
|
// grab first link to redirect if clicked when not expanded
|
|
155
156
|
if (!firstLink?.current && listRef?.current) {
|
|
156
157
|
const firstLinkElement = listRef.current.querySelector(`.${prefix}--side-nav__menu-item a`);
|
|
@@ -284,7 +285,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
284
285
|
}, [currentPrimaryMenu]);
|
|
285
286
|
// reset to opened/collapsed menu state when Panel SideNav is toggled
|
|
286
287
|
React__default.useEffect(() => {
|
|
287
|
-
if (navType == SideNav.SIDE_NAV_TYPE.
|
|
288
|
+
if (navType == SideNav.SIDE_NAV_TYPE.RAIL_PANEL && !sideNavExpanded) {
|
|
288
289
|
setIsExpanded(false);
|
|
289
290
|
}
|
|
290
291
|
|
|
@@ -321,7 +322,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
321
322
|
}
|
|
322
323
|
|
|
323
324
|
// only when sidenav is panel view
|
|
324
|
-
if (navType == SideNav.SIDE_NAV_TYPE.
|
|
325
|
+
if (navType == SideNav.SIDE_NAV_TYPE.RAIL_PANEL && !isExpanded && firstLink.current && !sideNavExpanded) {
|
|
325
326
|
setOpenPopover(!openPopover);
|
|
326
327
|
// window.location.href = firstLink.current;
|
|
327
328
|
} else if (isSm || !primary || currentPrimaryMenu !== uniqueId) {
|
|
@@ -334,7 +335,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
334
335
|
ref: menuRef,
|
|
335
336
|
type: "button",
|
|
336
337
|
tabIndex: isTreeview ? -1 : 0
|
|
337
|
-
}, IconElement && /*#__PURE__*/React__default.createElement(react.SideNavIcon, null, /*#__PURE__*/React__default.createElement(IconElement, null)), !sideNavExpanded && navType == SideNav.SIDE_NAV_TYPE.
|
|
338
|
+
}, IconElement && /*#__PURE__*/React__default.createElement(react.SideNavIcon, null, /*#__PURE__*/React__default.createElement(IconElement, null)), !autoExpand && !sideNavExpanded && navType == SideNav.SIDE_NAV_TYPE.RAIL_PANEL && /*#__PURE__*/React__default.createElement("div", {
|
|
338
339
|
className: `${prefix}--side-nav--panel-submenu-caret-container`
|
|
339
340
|
}, /*#__PURE__*/React__default.createElement("div", {
|
|
340
341
|
className: `${prefix}--side-nav--panel-submenu-caret`
|
|
@@ -364,7 +365,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
|
|
|
364
365
|
className: `${prefix}--side-nav__menu`,
|
|
365
366
|
role: "group"
|
|
366
367
|
}, childrenToRender));
|
|
367
|
-
return navType == SideNav.SIDE_NAV_TYPE.
|
|
368
|
+
return navType == SideNav.SIDE_NAV_TYPE.RAIL_PANEL && !sideNavExpanded ? /*#__PURE__*/React__default.createElement(SideNavFlyoutMenu.SideNavFlyoutMenu, {
|
|
368
369
|
selected: active,
|
|
369
370
|
className: `${prefix}--side-nav-flyout-menu`,
|
|
370
371
|
title: title,
|
|
@@ -4,29 +4,54 @@
|
|
|
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
|
|
8
|
-
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import { ComponentType, ElementType, ForwardedRef, ReactNode } from 'react';
|
|
9
|
+
import { LinkProps } from './Link';
|
|
10
|
+
export type SideNavToggleProps<E extends ElementType> = LinkProps<E> & {
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Required props for the accessibility label
|
|
11
13
|
*/
|
|
12
|
-
|
|
14
|
+
'aria-label'?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Required props for the accessibility label
|
|
17
|
+
*/
|
|
18
|
+
'aria-labelledby'?: string;
|
|
13
19
|
/**
|
|
14
20
|
* Specify the text content for the link
|
|
15
21
|
*/
|
|
16
|
-
children
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Provide an optional class to be applied to the containing node
|
|
25
|
+
*/
|
|
26
|
+
className?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Specify whether the link is the current page
|
|
29
|
+
*/
|
|
30
|
+
isActive?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Property to indicate if the side nav container is open (or not). Use to
|
|
33
|
+
* keep local state and styling in step with the SideNav expansion state.
|
|
34
|
+
*/
|
|
35
|
+
isSideNavExpanded?: boolean;
|
|
17
36
|
/**
|
|
18
|
-
*
|
|
37
|
+
* Specify if this is a large variation of the SideNavLink
|
|
19
38
|
*/
|
|
20
|
-
|
|
39
|
+
large?: boolean;
|
|
21
40
|
/**
|
|
22
|
-
*
|
|
41
|
+
* Provide an icon to render in the side navigation link. Should be a React class.
|
|
23
42
|
*/
|
|
24
|
-
renderIcon?:
|
|
43
|
+
renderIcon?: ComponentType;
|
|
25
44
|
/**
|
|
26
|
-
*
|
|
27
|
-
* If not specified, the default validation will be applied.
|
|
45
|
+
* Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
|
|
28
46
|
*/
|
|
29
47
|
tabIndex?: number;
|
|
48
|
+
};
|
|
49
|
+
export interface SideNavLinkComponent {
|
|
50
|
+
(props: SideNavToggleProps<'button'> & {
|
|
51
|
+
ref?: ForwardedRef<HTMLButtonElement>;
|
|
52
|
+
}): JSX.Element | null;
|
|
53
|
+
displayName?: string;
|
|
54
|
+
propTypes?: Partial<Record<keyof SideNavToggleProps<any>, PropTypes.Validator<any>>>;
|
|
30
55
|
}
|
|
31
|
-
export declare const SideNavToggle:
|
|
56
|
+
export declare const SideNavToggle: SideNavLinkComponent;
|
|
32
57
|
export default SideNavToggle;
|
|
@@ -13,46 +13,78 @@ var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.j
|
|
|
13
13
|
var cx = require('classnames');
|
|
14
14
|
var PropTypes = require('prop-types');
|
|
15
15
|
var React__default = require('react');
|
|
16
|
+
var Link = require('./Link.js');
|
|
16
17
|
var react = require('@carbon/react');
|
|
17
18
|
var usePrefix = require('../internal/usePrefix.js');
|
|
19
|
+
var SideNav = require('./SideNav.js');
|
|
20
|
+
var SideNavLinkPopover = require('./SideNavLinkPopover.js');
|
|
18
21
|
|
|
19
22
|
const SideNavToggle = /*#__PURE__*/React__default.forwardRef(function SideNavToggle({
|
|
23
|
+
children,
|
|
20
24
|
className: customClassName,
|
|
25
|
+
disabled,
|
|
21
26
|
renderIcon: IconElement,
|
|
27
|
+
large = false,
|
|
22
28
|
tabIndex,
|
|
23
|
-
children,
|
|
24
29
|
...rest
|
|
25
30
|
}, ref) {
|
|
31
|
+
const {
|
|
32
|
+
expanded,
|
|
33
|
+
navType
|
|
34
|
+
} = React__default.useContext(SideNav.SideNavContext);
|
|
26
35
|
const prefix = usePrefix.usePrefix();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
const className = cx({
|
|
37
|
+
[`${prefix}--side-nav__toggle`]: true,
|
|
38
|
+
[`${prefix}--side-nav__toggle--disabled`]: disabled,
|
|
39
|
+
[customClassName]: !!customClassName
|
|
40
|
+
});
|
|
41
|
+
const SideNavLinkIcon = IconElement && /*#__PURE__*/React__default.createElement(react.SideNavIcon, {
|
|
42
|
+
small: true
|
|
43
|
+
}, /*#__PURE__*/React__default.createElement(IconElement, null));
|
|
44
|
+
if (!expanded && navType === SideNav.SIDE_NAV_TYPE.RAIL_PANEL) {
|
|
45
|
+
return /*#__PURE__*/React__default.createElement(SideNavLinkPopover.SideNavLinkPopover, _rollupPluginBabelHelpers.extends({
|
|
46
|
+
align: "right",
|
|
47
|
+
className: className,
|
|
48
|
+
label: children
|
|
49
|
+
}, rest), SideNavLinkIcon);
|
|
50
|
+
}
|
|
51
|
+
return /*#__PURE__*/React__default.createElement(react.SideNavItem, {
|
|
52
|
+
large: large
|
|
53
|
+
}, /*#__PURE__*/React__default.createElement("button", _rollupPluginBabelHelpers.extends({
|
|
54
|
+
className: className,
|
|
31
55
|
ref: ref,
|
|
32
56
|
type: "button",
|
|
33
|
-
tabIndex: tabIndex ?? 0
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}, children));
|
|
57
|
+
tabIndex: tabIndex ?? 0,
|
|
58
|
+
disabled: disabled
|
|
59
|
+
}, rest), SideNavLinkIcon, /*#__PURE__*/React__default.createElement(react.SideNavLinkText, null, children)));
|
|
37
60
|
});
|
|
38
61
|
SideNavToggle.displayName = 'SideNavToggle';
|
|
39
62
|
SideNavToggle.propTypes = {
|
|
63
|
+
...Link.LinkPropTypes,
|
|
40
64
|
/**
|
|
41
|
-
* Specify the text content for the
|
|
65
|
+
* Specify the text content for the link
|
|
42
66
|
*/
|
|
43
67
|
children: PropTypes.node,
|
|
44
68
|
/**
|
|
45
|
-
*
|
|
69
|
+
* Provide an optional class to be applied to the containing node
|
|
46
70
|
*/
|
|
47
71
|
className: PropTypes.string,
|
|
48
72
|
/**
|
|
49
|
-
*
|
|
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
|
|
50
83
|
*/
|
|
51
|
-
|
|
84
|
+
large: PropTypes.bool,
|
|
52
85
|
/**
|
|
53
|
-
*
|
|
86
|
+
* Provide an icon to render in the side navigation link. Should be a React class.
|
|
54
87
|
*/
|
|
55
|
-
// @ts-expect-error - PropTypes are unable to cover this case.
|
|
56
88
|
renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
57
89
|
/**
|
|
58
90
|
* Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbon-labs/react-ui-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.74.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": true
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@ibm/telemetry-js": "^1.9.1"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "fd1fd1e946fc16c0cac7e637512ce1423085b9d9"
|
|
46
46
|
}
|
|
@@ -19,9 +19,21 @@ div:has(.#{$prefix}--side-nav--panel) ~ .#{$prefix}--content {
|
|
|
19
19
|
transition: $fast-02 motion(exit, productive);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
.#{$prefix}--side-nav--panel
|
|
22
|
+
.#{$prefix}--side-nav--panel:not(
|
|
23
|
+
.#{$prefix}--side-nav--rail
|
|
24
|
+
).#{$prefix}--side-nav--expanded
|
|
23
25
|
~ .#{$prefix}--content,
|
|
24
|
-
|
|
26
|
+
.#{$prefix}--side-nav--panel.#{$prefix}--side-nav--pinned.#{$prefix}--side-nav--expanded
|
|
27
|
+
~ .#{$prefix}--content,
|
|
28
|
+
div:has(
|
|
29
|
+
.#{$prefix}--side-nav--panel:not(
|
|
30
|
+
.#{$prefix}--side-nav--rail
|
|
31
|
+
).#{$prefix}--side-nav--expanded
|
|
32
|
+
)
|
|
33
|
+
~ .#{$prefix}--content,
|
|
34
|
+
div:has(
|
|
35
|
+
.#{$prefix}--side-nav--panel.#{$prefix}--side-nav--pinned.#{$prefix}--side-nav--expanded
|
|
36
|
+
)
|
|
25
37
|
~ .#{$prefix}--content {
|
|
26
38
|
margin-inline-start: convert.to-rem(256px);
|
|
27
39
|
transition: $moderate-01 motion(standard, productive);
|
|
@@ -350,6 +350,7 @@ div:has(.#{$prefix}--header)
|
|
|
350
350
|
display: flex;
|
|
351
351
|
overflow: visible;
|
|
352
352
|
flex-direction: column;
|
|
353
|
+
padding-block-end: $spacing-11;
|
|
353
354
|
}
|
|
354
355
|
|
|
355
356
|
.#{$prefix}--side-nav__items,
|
|
@@ -374,14 +375,14 @@ div:has(.#{$prefix}--header)
|
|
|
374
375
|
|
|
375
376
|
// Side Nav Toggle
|
|
376
377
|
.#{$prefix}--side-nav__toggle {
|
|
377
|
-
@include button-reset.reset($width:
|
|
378
|
-
@include type-style('
|
|
378
|
+
@include button-reset.reset($width: false);
|
|
379
|
+
@include type-style('label-01');
|
|
379
380
|
@include focus-outline('reset');
|
|
380
381
|
|
|
381
382
|
display: flex;
|
|
382
383
|
align-items: center;
|
|
383
384
|
padding: 0 $spacing-05;
|
|
384
|
-
block-size: $spacing-
|
|
385
|
+
block-size: $spacing-07;
|
|
385
386
|
color: $text-secondary;
|
|
386
387
|
transition: color $duration-fast-02, background-color $duration-fast-02,
|
|
387
388
|
outline $duration-fast-02;
|
|
@@ -396,6 +397,15 @@ div:has(.#{$prefix}--header)
|
|
|
396
397
|
}
|
|
397
398
|
}
|
|
398
399
|
|
|
400
|
+
.#{$prefix}--side-nav__toggle--disabled {
|
|
401
|
+
color: $text-disabled;
|
|
402
|
+
pointer-events: none;
|
|
403
|
+
|
|
404
|
+
svg {
|
|
405
|
+
fill: $icon-disabled;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
399
409
|
.#{$prefix}--side-nav__toggle-text {
|
|
400
410
|
@include text-overflow();
|
|
401
411
|
|
|
@@ -562,6 +572,10 @@ div:has(.#{$prefix}--header)
|
|
|
562
572
|
.#{$prefix}--side-nav__item {
|
|
563
573
|
overflow: visible;
|
|
564
574
|
}
|
|
575
|
+
|
|
576
|
+
.#{$prefix}--side-nav__toggle {
|
|
577
|
+
inline-size: 100%;
|
|
578
|
+
}
|
|
565
579
|
}
|
|
566
580
|
|
|
567
581
|
.#{$prefix}--side-nav__toggle-container {
|
|
@@ -569,10 +583,7 @@ div:has(.#{$prefix}--header)
|
|
|
569
583
|
background: $background;
|
|
570
584
|
inline-size: 100%;
|
|
571
585
|
inset-block-end: 0;
|
|
572
|
-
|
|
573
|
-
.#{$prefix}--side-nav__toggle.#{$prefix}--side-nav__toggle--collapsed:hover {
|
|
574
|
-
background: $background-hover;
|
|
575
|
-
}
|
|
586
|
+
white-space: nowrap;
|
|
576
587
|
}
|
|
577
588
|
|
|
578
589
|
//----------------------------------------------------------------------------
|
|
@@ -588,6 +599,11 @@ div:has(.#{$prefix}--header)
|
|
|
588
599
|
box-shadow: $spacing-02 0 convert.to-rem(6px) convert.to-rem(-3px) $shadow;
|
|
589
600
|
}
|
|
590
601
|
|
|
602
|
+
.#{$prefix}--side-nav--rail.#{$prefix}--side-nav--expanded.#{$prefix}--side-nav--pinned {
|
|
603
|
+
border-inline-end: 1px solid $border-subtle;
|
|
604
|
+
box-shadow: none;
|
|
605
|
+
}
|
|
606
|
+
|
|
591
607
|
@each $breakpoint in ('sm', 'md', 'lg', 'xlg', 'max') {
|
|
592
608
|
.#{$prefix}--side-nav--rail.#{$prefix}--side-nav--hide-rail-breakpoint-down-#{$breakpoint} {
|
|
593
609
|
@include breakpoint-down($breakpoint) {
|