@atlaskit/navigation-system 4.4.0 → 4.5.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/CHANGELOG.md +20 -0
- package/dist/cjs/ui/page-layout/root.js +8 -3
- package/dist/cjs/ui/page-layout/side-nav/is-side-nav-shortcut-enabled-context.js +36 -0
- package/dist/cjs/ui/page-layout/side-nav/side-nav.js +9 -2
- package/dist/cjs/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +59 -0
- package/dist/es2019/ui/page-layout/root.js +7 -3
- package/dist/es2019/ui/page-layout/side-nav/is-side-nav-shortcut-enabled-context.js +29 -0
- package/dist/es2019/ui/page-layout/side-nav/side-nav.js +9 -2
- package/dist/es2019/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +54 -0
- package/dist/esm/ui/page-layout/root.js +8 -3
- package/dist/esm/ui/page-layout/side-nav/is-side-nav-shortcut-enabled-context.js +28 -0
- package/dist/esm/ui/page-layout/side-nav/side-nav.js +9 -2
- package/dist/esm/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +53 -0
- package/dist/types/ui/page-layout/root.d.ts +19 -1
- package/dist/types/ui/page-layout/side-nav/is-side-nav-shortcut-enabled-context.d.ts +13 -0
- package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +13 -1
- package/dist/types/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.d.ts +6 -0
- package/dist/types-ts4.5/ui/page-layout/root.d.ts +19 -1
- package/dist/types-ts4.5/ui/page-layout/side-nav/is-side-nav-shortcut-enabled-context.d.ts +13 -0
- package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav.d.ts +13 -1
- package/dist/types-ts4.5/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.d.ts +6 -0
- package/package.json +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlassian/navigation-system
|
|
2
2
|
|
|
3
|
+
## 4.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`8a71ce992f8c8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8a71ce992f8c8) -
|
|
8
|
+
`SideNav` now provides a built-in keyboard shortcut for expanding and collapsing. This is behind
|
|
9
|
+
the feature gate `navx-full-height-sidebar`.
|
|
10
|
+
- The shortcut key is `Ctrl` + `[`.
|
|
11
|
+
- The shortcut is not enabled by default.
|
|
12
|
+
- The prop `isSideNavShortcutEnabled` has been added to `Root`, as a way to control whether the
|
|
13
|
+
shortcut is enabled (whether the keyboard event listener is binded). It defaults to `false`.
|
|
14
|
+
- The prop `canToggleWithShortcut()` has been added to `SideNav`, as a way to run additional
|
|
15
|
+
checks after the shortcut is pressed, before the side nav is toggled.
|
|
16
|
+
- The shortcut will also be ignored if there are any open modals. This check is behind the feature
|
|
17
|
+
gate `platform-dst-open-layer-observer-layer-type`.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
|
|
3
23
|
## 4.4.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -15,6 +15,7 @@ var _skipLinksProvider = require("../../context/skip-links/skip-links-provider")
|
|
|
15
15
|
var _topNavStartContextProvider = require("../../context/top-nav-start/top-nav-start-context-provider");
|
|
16
16
|
var _hoistSlotSizesContext = require("./hoist-slot-sizes-context");
|
|
17
17
|
var _elementContext = require("./side-nav/element-context");
|
|
18
|
+
var _isSideNavShortcutEnabledContext = require("./side-nav/is-side-nav-shortcut-enabled-context");
|
|
18
19
|
var _toggleButtonProvider = require("./side-nav/toggle-button-provider");
|
|
19
20
|
var _visibilityProvider = require("./side-nav/visibility-provider");
|
|
20
21
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
@@ -36,7 +37,9 @@ function Root(_ref) {
|
|
|
36
37
|
_ref$skipLinksLabel = _ref.skipLinksLabel,
|
|
37
38
|
skipLinksLabel = _ref$skipLinksLabel === void 0 ? 'Skip to:' : _ref$skipLinksLabel,
|
|
38
39
|
testId = _ref.testId,
|
|
39
|
-
defaultSideNavCollapsed = _ref.defaultSideNavCollapsed
|
|
40
|
+
defaultSideNavCollapsed = _ref.defaultSideNavCollapsed,
|
|
41
|
+
_ref$isSideNavShortcu = _ref.isSideNavShortcutEnabled,
|
|
42
|
+
isSideNavShortcutEnabled = _ref$isSideNavShortcu === void 0 ? false : _ref$isSideNavShortcu;
|
|
40
43
|
var ref = (0, _react.useRef)(null);
|
|
41
44
|
(0, _react.useEffect)(function () {
|
|
42
45
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -53,7 +56,9 @@ function Root(_ref) {
|
|
|
53
56
|
}, []);
|
|
54
57
|
return /*#__PURE__*/_react.default.createElement(_visibilityProvider.SideNavVisibilityProvider, {
|
|
55
58
|
defaultCollapsed: defaultSideNavCollapsed
|
|
56
|
-
}, /*#__PURE__*/_react.default.createElement(_toggleButtonProvider.SideNavToggleButtonProvider, null, /*#__PURE__*/_react.default.createElement(_elementContext.SideNavElementProvider, null, /*#__PURE__*/_react.default.createElement(
|
|
59
|
+
}, /*#__PURE__*/_react.default.createElement(_toggleButtonProvider.SideNavToggleButtonProvider, null, /*#__PURE__*/_react.default.createElement(_elementContext.SideNavElementProvider, null, /*#__PURE__*/_react.default.createElement(_isSideNavShortcutEnabledContext.IsSideNavShortcutEnabledProvider, {
|
|
60
|
+
isSideNavShortcutEnabled: isSideNavShortcutEnabled
|
|
61
|
+
}, /*#__PURE__*/_react.default.createElement(_topNavStartContextProvider.TopNavStartProvider, null, /*#__PURE__*/_react.default.createElement(_openLayerObserver.OpenLayerObserver, null, /*#__PURE__*/_react.default.createElement(_hoistSlotSizesContext.DangerouslyHoistSlotSizes.Provider, {
|
|
57
62
|
value: UNSAFE_dangerouslyHoistSlotSizes
|
|
58
63
|
}, /*#__PURE__*/_react.default.createElement(_skipLinksProvider.SkipLinksProvider, {
|
|
59
64
|
label: skipLinksLabel,
|
|
@@ -63,5 +68,5 @@ function Root(_ref) {
|
|
|
63
68
|
className: (0, _runtime.ax)([styles.root, xcss]),
|
|
64
69
|
id: gridRootId,
|
|
65
70
|
"data-testid": testId
|
|
66
|
-
}, children))))))));
|
|
71
|
+
}, children)))))))));
|
|
67
72
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.IsSideNavShortcutEnabledProvider = IsSideNavShortcutEnabledProvider;
|
|
8
|
+
exports.useIsSideNavShortcutEnabled = useIsSideNavShortcutEnabled;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
11
|
+
/**
|
|
12
|
+
* Context for whether the side nav toggle shortcut is enabled.
|
|
13
|
+
*
|
|
14
|
+
* Used to share the `isSideNavShortcutEnabled` prop value from `Root` with other components,
|
|
15
|
+
* so the visual keyboard shortcut in tooltips can be conditionally displayed.
|
|
16
|
+
*/
|
|
17
|
+
var IsSideNavShortcutEnabledContext = /*#__PURE__*/(0, _react.createContext)(false);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Provider for the `IsSideNavShortcutEnabledContext`.
|
|
21
|
+
*/
|
|
22
|
+
function IsSideNavShortcutEnabledProvider(_ref) {
|
|
23
|
+
var children = _ref.children,
|
|
24
|
+
isSideNavShortcutEnabled = _ref.isSideNavShortcutEnabled;
|
|
25
|
+
return /*#__PURE__*/_react.default.createElement(IsSideNavShortcutEnabledContext.Provider, {
|
|
26
|
+
value: isSideNavShortcutEnabled
|
|
27
|
+
}, children);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns the value of the `isSideNavShortcutEnabled` prop from the `Root` component, which
|
|
32
|
+
* is shared through context.
|
|
33
|
+
*/
|
|
34
|
+
function useIsSideNavShortcutEnabled() {
|
|
35
|
+
return (0, _react.useContext)(IsSideNavShortcutEnabledContext);
|
|
36
|
+
}
|
|
@@ -36,6 +36,7 @@ var _elementContext = require("./element-context");
|
|
|
36
36
|
var _flyoutCloseDelayMs = require("./flyout-close-delay-ms");
|
|
37
37
|
var _toggleButtonContext = require("./toggle-button-context");
|
|
38
38
|
var _useExpandSideNav = require("./use-expand-side-nav");
|
|
39
|
+
var _useSideNavToggleKeyboardShortcut = require("./use-side-nav-toggle-keyboard-shortcut");
|
|
39
40
|
var _useSideNavVisibility2 = require("./use-side-nav-visibility");
|
|
40
41
|
var _useSideNavVisibilityCallbacks = require("./use-side-nav-visibility-callbacks");
|
|
41
42
|
var _useToggleSideNav = require("./use-toggle-side-nav");
|
|
@@ -100,7 +101,8 @@ function SideNavInternal(_ref) {
|
|
|
100
101
|
onCollapse = _ref.onCollapse,
|
|
101
102
|
onPeekStart = _ref.onPeekStart,
|
|
102
103
|
onPeekEnd = _ref.onPeekEnd,
|
|
103
|
-
providedId = _ref.id
|
|
104
|
+
providedId = _ref.id,
|
|
105
|
+
canToggleWithShortcut = _ref.canToggleWithShortcut;
|
|
104
106
|
var id = (0, _idUtils.useLayoutId)({
|
|
105
107
|
providedId: providedId
|
|
106
108
|
});
|
|
@@ -645,6 +647,9 @@ function SideNavInternal(_ref) {
|
|
|
645
647
|
}
|
|
646
648
|
devTimeOnlyAttributes['data-visible'] = visible.length ? visible.join(',') : 'false';
|
|
647
649
|
}
|
|
650
|
+
(0, _useSideNavToggleKeyboardShortcut.useSideNavToggleKeyboardShortcut)({
|
|
651
|
+
canToggleWithShortcut: canToggleWithShortcut
|
|
652
|
+
});
|
|
648
653
|
(0, _useResizingWidthCssVarOnRootElement.useResizingWidthCssVarOnRootElement)({
|
|
649
654
|
isEnabled: true,
|
|
650
655
|
cssVar: panelSplitterResizingVar,
|
|
@@ -746,6 +751,7 @@ function SideNav(_ref8) {
|
|
|
746
751
|
onCollapse = _ref8.onCollapse,
|
|
747
752
|
onPeekStart = _ref8.onPeekStart,
|
|
748
753
|
onPeekEnd = _ref8.onPeekEnd,
|
|
754
|
+
canToggleWithShortcut = _ref8.canToggleWithShortcut,
|
|
749
755
|
id = _ref8.id;
|
|
750
756
|
return /*#__PURE__*/React.createElement(_openLayerObserver.OpenLayerObserverNamespaceProvider, {
|
|
751
757
|
namespace: openLayerObserverSideNavNamespace
|
|
@@ -759,6 +765,7 @@ function SideNav(_ref8) {
|
|
|
759
765
|
onCollapse: onCollapse,
|
|
760
766
|
onPeekStart: onPeekStart,
|
|
761
767
|
onPeekEnd: onPeekEnd,
|
|
762
|
-
id: id
|
|
768
|
+
id: id,
|
|
769
|
+
canToggleWithShortcut: canToggleWithShortcut
|
|
763
770
|
}, children));
|
|
764
771
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useSideNavToggleKeyboardShortcut = useSideNavToggleKeyboardShortcut;
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _bindEventListener = require("bind-event-listener");
|
|
10
|
+
var _useStableRef = _interopRequireDefault(require("@atlaskit/ds-lib/use-stable-ref"));
|
|
11
|
+
var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
|
|
12
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
13
|
+
var _isSideNavShortcutEnabledContext = require("./is-side-nav-shortcut-enabled-context");
|
|
14
|
+
var _useToggleSideNav = require("./use-toggle-side-nav");
|
|
15
|
+
/**
|
|
16
|
+
* Binds the keyboard shortcut to toggle the side nav.
|
|
17
|
+
*/
|
|
18
|
+
function useSideNavToggleKeyboardShortcut(_ref) {
|
|
19
|
+
var canToggleWithShortcut = _ref.canToggleWithShortcut;
|
|
20
|
+
var openLayerObserver = (0, _openLayerObserver.useOpenLayerObserver)();
|
|
21
|
+
var toggleVisibilityByShortcut = (0, _useToggleSideNav.useToggleSideNav)({
|
|
22
|
+
trigger: 'keyboard'
|
|
23
|
+
});
|
|
24
|
+
var canToggleWithShortcutStableRef = (0, _useStableRef.default)(canToggleWithShortcut);
|
|
25
|
+
var isSideNavShortcutEnabled = (0, _isSideNavShortcutEnabledContext.useIsSideNavShortcutEnabled)();
|
|
26
|
+
(0, _react.useEffect)(function () {
|
|
27
|
+
if (!(0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!isSideNavShortcutEnabled) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
return (0, _bindEventListener.bind)(window, {
|
|
34
|
+
type: 'keydown',
|
|
35
|
+
listener: function listener(event) {
|
|
36
|
+
if (event.ctrlKey && event.key === '[') {
|
|
37
|
+
if (canToggleWithShortcutStableRef.current && !canToggleWithShortcutStableRef.current()) {
|
|
38
|
+
// Return early if the callback returns false.
|
|
39
|
+
// If the callback is not provided, we assume the shortcut is enabled.
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (event.repeat) {
|
|
43
|
+
// Ignore repeated keydown events from holding down the keys
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (openLayerObserver.getCount({
|
|
47
|
+
type: 'modal'
|
|
48
|
+
}) > 0 && (0, _platformFeatureFlags.fg)('platform-dst-open-layer-observer-layer-type')) {
|
|
49
|
+
// Return early if there are any open modals
|
|
50
|
+
// This check is behind the layer type FG, as `getCount` will return the count of all layers when
|
|
51
|
+
// the FG is disabled - meaning we would ignore the shortcut if there is any open layer (not just modals).
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
toggleVisibilityByShortcut();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}, [canToggleWithShortcutStableRef, openLayerObserver, toggleVisibilityByShortcut, isSideNavShortcutEnabled]);
|
|
59
|
+
}
|
|
@@ -7,6 +7,7 @@ import { SkipLinksProvider } from '../../context/skip-links/skip-links-provider'
|
|
|
7
7
|
import { TopNavStartProvider } from '../../context/top-nav-start/top-nav-start-context-provider';
|
|
8
8
|
import { DangerouslyHoistSlotSizes } from './hoist-slot-sizes-context';
|
|
9
9
|
import { SideNavElementProvider } from './side-nav/element-context';
|
|
10
|
+
import { IsSideNavShortcutEnabledProvider } from './side-nav/is-side-nav-shortcut-enabled-context';
|
|
10
11
|
import { SideNavToggleButtonProvider } from './side-nav/toggle-button-provider';
|
|
11
12
|
import { SideNavVisibilityProvider } from './side-nav/visibility-provider';
|
|
12
13
|
|
|
@@ -26,7 +27,8 @@ export function Root({
|
|
|
26
27
|
UNSAFE_dangerouslyHoistSlotSizes = false,
|
|
27
28
|
skipLinksLabel = 'Skip to:',
|
|
28
29
|
testId,
|
|
29
|
-
defaultSideNavCollapsed
|
|
30
|
+
defaultSideNavCollapsed,
|
|
31
|
+
isSideNavShortcutEnabled = false
|
|
30
32
|
}) {
|
|
31
33
|
const ref = useRef(null);
|
|
32
34
|
useEffect(() => {
|
|
@@ -53,7 +55,9 @@ This message will not be displayed in production.
|
|
|
53
55
|
}, []);
|
|
54
56
|
return /*#__PURE__*/React.createElement(SideNavVisibilityProvider, {
|
|
55
57
|
defaultCollapsed: defaultSideNavCollapsed
|
|
56
|
-
}, /*#__PURE__*/React.createElement(SideNavToggleButtonProvider, null, /*#__PURE__*/React.createElement(SideNavElementProvider, null, /*#__PURE__*/React.createElement(
|
|
58
|
+
}, /*#__PURE__*/React.createElement(SideNavToggleButtonProvider, null, /*#__PURE__*/React.createElement(SideNavElementProvider, null, /*#__PURE__*/React.createElement(IsSideNavShortcutEnabledProvider, {
|
|
59
|
+
isSideNavShortcutEnabled: isSideNavShortcutEnabled
|
|
60
|
+
}, /*#__PURE__*/React.createElement(TopNavStartProvider, null, /*#__PURE__*/React.createElement(OpenLayerObserver, null, /*#__PURE__*/React.createElement(DangerouslyHoistSlotSizes.Provider, {
|
|
57
61
|
value: UNSAFE_dangerouslyHoistSlotSizes
|
|
58
62
|
}, /*#__PURE__*/React.createElement(SkipLinksProvider, {
|
|
59
63
|
label: skipLinksLabel,
|
|
@@ -63,5 +67,5 @@ This message will not be displayed in production.
|
|
|
63
67
|
className: ax([styles.root, xcss]),
|
|
64
68
|
id: gridRootId,
|
|
65
69
|
"data-testid": testId
|
|
66
|
-
}, children))))))));
|
|
70
|
+
}, children)))))))));
|
|
67
71
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context for whether the side nav toggle shortcut is enabled.
|
|
5
|
+
*
|
|
6
|
+
* Used to share the `isSideNavShortcutEnabled` prop value from `Root` with other components,
|
|
7
|
+
* so the visual keyboard shortcut in tooltips can be conditionally displayed.
|
|
8
|
+
*/
|
|
9
|
+
const IsSideNavShortcutEnabledContext = /*#__PURE__*/createContext(false);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Provider for the `IsSideNavShortcutEnabledContext`.
|
|
13
|
+
*/
|
|
14
|
+
export function IsSideNavShortcutEnabledProvider({
|
|
15
|
+
children,
|
|
16
|
+
isSideNavShortcutEnabled
|
|
17
|
+
}) {
|
|
18
|
+
return /*#__PURE__*/React.createElement(IsSideNavShortcutEnabledContext.Provider, {
|
|
19
|
+
value: isSideNavShortcutEnabled
|
|
20
|
+
}, children);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns the value of the `isSideNavShortcutEnabled` prop from the `Root` component, which
|
|
25
|
+
* is shared through context.
|
|
26
|
+
*/
|
|
27
|
+
export function useIsSideNavShortcutEnabled() {
|
|
28
|
+
return useContext(IsSideNavShortcutEnabledContext);
|
|
29
|
+
}
|
|
@@ -25,6 +25,7 @@ import { useSideNavRef } from './element-context';
|
|
|
25
25
|
import { sideNavFlyoutCloseDelayMs } from './flyout-close-delay-ms';
|
|
26
26
|
import { SideNavToggleButtonElement } from './toggle-button-context';
|
|
27
27
|
import { useExpandSideNav } from './use-expand-side-nav';
|
|
28
|
+
import { useSideNavToggleKeyboardShortcut } from './use-side-nav-toggle-keyboard-shortcut';
|
|
28
29
|
import { useSideNavVisibility } from './use-side-nav-visibility';
|
|
29
30
|
import { useSideNavVisibilityCallbacks } from './use-side-nav-visibility-callbacks';
|
|
30
31
|
import { useToggleSideNav } from './use-toggle-side-nav';
|
|
@@ -82,7 +83,8 @@ function SideNavInternal({
|
|
|
82
83
|
onCollapse,
|
|
83
84
|
onPeekStart,
|
|
84
85
|
onPeekEnd,
|
|
85
|
-
id: providedId
|
|
86
|
+
id: providedId,
|
|
87
|
+
canToggleWithShortcut
|
|
86
88
|
}) {
|
|
87
89
|
var _sideNavState$lastTri;
|
|
88
90
|
const id = useLayoutId({
|
|
@@ -633,6 +635,9 @@ function SideNavInternal({
|
|
|
633
635
|
}
|
|
634
636
|
devTimeOnlyAttributes['data-visible'] = visible.length ? visible.join(',') : 'false';
|
|
635
637
|
}
|
|
638
|
+
useSideNavToggleKeyboardShortcut({
|
|
639
|
+
canToggleWithShortcut
|
|
640
|
+
});
|
|
636
641
|
useResizingWidthCssVarOnRootElement({
|
|
637
642
|
isEnabled: true,
|
|
638
643
|
cssVar: panelSplitterResizingVar,
|
|
@@ -737,6 +742,7 @@ export function SideNav({
|
|
|
737
742
|
onCollapse,
|
|
738
743
|
onPeekStart,
|
|
739
744
|
onPeekEnd,
|
|
745
|
+
canToggleWithShortcut,
|
|
740
746
|
id
|
|
741
747
|
}) {
|
|
742
748
|
return /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
|
|
@@ -751,6 +757,7 @@ export function SideNav({
|
|
|
751
757
|
onCollapse: onCollapse,
|
|
752
758
|
onPeekStart: onPeekStart,
|
|
753
759
|
onPeekEnd: onPeekEnd,
|
|
754
|
-
id: id
|
|
760
|
+
id: id,
|
|
761
|
+
canToggleWithShortcut: canToggleWithShortcut
|
|
755
762
|
}, children));
|
|
756
763
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { bind } from 'bind-event-listener';
|
|
3
|
+
import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
|
|
4
|
+
import { useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
|
|
5
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
|
+
import { useIsSideNavShortcutEnabled } from './is-side-nav-shortcut-enabled-context';
|
|
7
|
+
import { useToggleSideNav } from './use-toggle-side-nav';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Binds the keyboard shortcut to toggle the side nav.
|
|
11
|
+
*/
|
|
12
|
+
export function useSideNavToggleKeyboardShortcut({
|
|
13
|
+
canToggleWithShortcut
|
|
14
|
+
}) {
|
|
15
|
+
const openLayerObserver = useOpenLayerObserver();
|
|
16
|
+
const toggleVisibilityByShortcut = useToggleSideNav({
|
|
17
|
+
trigger: 'keyboard'
|
|
18
|
+
});
|
|
19
|
+
const canToggleWithShortcutStableRef = useStableRef(canToggleWithShortcut);
|
|
20
|
+
const isSideNavShortcutEnabled = useIsSideNavShortcutEnabled();
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!fg('navx-full-height-sidebar')) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!isSideNavShortcutEnabled) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
return bind(window, {
|
|
29
|
+
type: 'keydown',
|
|
30
|
+
listener(event) {
|
|
31
|
+
if (event.ctrlKey && event.key === '[') {
|
|
32
|
+
if (canToggleWithShortcutStableRef.current && !canToggleWithShortcutStableRef.current()) {
|
|
33
|
+
// Return early if the callback returns false.
|
|
34
|
+
// If the callback is not provided, we assume the shortcut is enabled.
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (event.repeat) {
|
|
38
|
+
// Ignore repeated keydown events from holding down the keys
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (openLayerObserver.getCount({
|
|
42
|
+
type: 'modal'
|
|
43
|
+
}) > 0 && fg('platform-dst-open-layer-observer-layer-type')) {
|
|
44
|
+
// Return early if there are any open modals
|
|
45
|
+
// This check is behind the layer type FG, as `getCount` will return the count of all layers when
|
|
46
|
+
// the FG is disabled - meaning we would ignore the shortcut if there is any open layer (not just modals).
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
toggleVisibilityByShortcut();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}, [canToggleWithShortcutStableRef, openLayerObserver, toggleVisibilityByShortcut, isSideNavShortcutEnabled]);
|
|
54
|
+
}
|
|
@@ -7,6 +7,7 @@ import { SkipLinksProvider } from '../../context/skip-links/skip-links-provider'
|
|
|
7
7
|
import { TopNavStartProvider } from '../../context/top-nav-start/top-nav-start-context-provider';
|
|
8
8
|
import { DangerouslyHoistSlotSizes } from './hoist-slot-sizes-context';
|
|
9
9
|
import { SideNavElementProvider } from './side-nav/element-context';
|
|
10
|
+
import { IsSideNavShortcutEnabledProvider } from './side-nav/is-side-nav-shortcut-enabled-context';
|
|
10
11
|
import { SideNavToggleButtonProvider } from './side-nav/toggle-button-provider';
|
|
11
12
|
import { SideNavVisibilityProvider } from './side-nav/visibility-provider';
|
|
12
13
|
|
|
@@ -28,7 +29,9 @@ export function Root(_ref) {
|
|
|
28
29
|
_ref$skipLinksLabel = _ref.skipLinksLabel,
|
|
29
30
|
skipLinksLabel = _ref$skipLinksLabel === void 0 ? 'Skip to:' : _ref$skipLinksLabel,
|
|
30
31
|
testId = _ref.testId,
|
|
31
|
-
defaultSideNavCollapsed = _ref.defaultSideNavCollapsed
|
|
32
|
+
defaultSideNavCollapsed = _ref.defaultSideNavCollapsed,
|
|
33
|
+
_ref$isSideNavShortcu = _ref.isSideNavShortcutEnabled,
|
|
34
|
+
isSideNavShortcutEnabled = _ref$isSideNavShortcu === void 0 ? false : _ref$isSideNavShortcu;
|
|
32
35
|
var ref = useRef(null);
|
|
33
36
|
useEffect(function () {
|
|
34
37
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -45,7 +48,9 @@ export function Root(_ref) {
|
|
|
45
48
|
}, []);
|
|
46
49
|
return /*#__PURE__*/React.createElement(SideNavVisibilityProvider, {
|
|
47
50
|
defaultCollapsed: defaultSideNavCollapsed
|
|
48
|
-
}, /*#__PURE__*/React.createElement(SideNavToggleButtonProvider, null, /*#__PURE__*/React.createElement(SideNavElementProvider, null, /*#__PURE__*/React.createElement(
|
|
51
|
+
}, /*#__PURE__*/React.createElement(SideNavToggleButtonProvider, null, /*#__PURE__*/React.createElement(SideNavElementProvider, null, /*#__PURE__*/React.createElement(IsSideNavShortcutEnabledProvider, {
|
|
52
|
+
isSideNavShortcutEnabled: isSideNavShortcutEnabled
|
|
53
|
+
}, /*#__PURE__*/React.createElement(TopNavStartProvider, null, /*#__PURE__*/React.createElement(OpenLayerObserver, null, /*#__PURE__*/React.createElement(DangerouslyHoistSlotSizes.Provider, {
|
|
49
54
|
value: UNSAFE_dangerouslyHoistSlotSizes
|
|
50
55
|
}, /*#__PURE__*/React.createElement(SkipLinksProvider, {
|
|
51
56
|
label: skipLinksLabel,
|
|
@@ -55,5 +60,5 @@ export function Root(_ref) {
|
|
|
55
60
|
className: ax([styles.root, xcss]),
|
|
56
61
|
id: gridRootId,
|
|
57
62
|
"data-testid": testId
|
|
58
|
-
}, children))))))));
|
|
63
|
+
}, children)))))))));
|
|
59
64
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context for whether the side nav toggle shortcut is enabled.
|
|
5
|
+
*
|
|
6
|
+
* Used to share the `isSideNavShortcutEnabled` prop value from `Root` with other components,
|
|
7
|
+
* so the visual keyboard shortcut in tooltips can be conditionally displayed.
|
|
8
|
+
*/
|
|
9
|
+
var IsSideNavShortcutEnabledContext = /*#__PURE__*/createContext(false);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Provider for the `IsSideNavShortcutEnabledContext`.
|
|
13
|
+
*/
|
|
14
|
+
export function IsSideNavShortcutEnabledProvider(_ref) {
|
|
15
|
+
var children = _ref.children,
|
|
16
|
+
isSideNavShortcutEnabled = _ref.isSideNavShortcutEnabled;
|
|
17
|
+
return /*#__PURE__*/React.createElement(IsSideNavShortcutEnabledContext.Provider, {
|
|
18
|
+
value: isSideNavShortcutEnabled
|
|
19
|
+
}, children);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the value of the `isSideNavShortcutEnabled` prop from the `Root` component, which
|
|
24
|
+
* is shared through context.
|
|
25
|
+
*/
|
|
26
|
+
export function useIsSideNavShortcutEnabled() {
|
|
27
|
+
return useContext(IsSideNavShortcutEnabledContext);
|
|
28
|
+
}
|
|
@@ -29,6 +29,7 @@ import { useSideNavRef } from './element-context';
|
|
|
29
29
|
import { sideNavFlyoutCloseDelayMs } from './flyout-close-delay-ms';
|
|
30
30
|
import { SideNavToggleButtonElement } from './toggle-button-context';
|
|
31
31
|
import { useExpandSideNav } from './use-expand-side-nav';
|
|
32
|
+
import { useSideNavToggleKeyboardShortcut } from './use-side-nav-toggle-keyboard-shortcut';
|
|
32
33
|
import { useSideNavVisibility } from './use-side-nav-visibility';
|
|
33
34
|
import { useSideNavVisibilityCallbacks } from './use-side-nav-visibility-callbacks';
|
|
34
35
|
import { useToggleSideNav } from './use-toggle-side-nav';
|
|
@@ -90,7 +91,8 @@ function SideNavInternal(_ref) {
|
|
|
90
91
|
onCollapse = _ref.onCollapse,
|
|
91
92
|
onPeekStart = _ref.onPeekStart,
|
|
92
93
|
onPeekEnd = _ref.onPeekEnd,
|
|
93
|
-
providedId = _ref.id
|
|
94
|
+
providedId = _ref.id,
|
|
95
|
+
canToggleWithShortcut = _ref.canToggleWithShortcut;
|
|
94
96
|
var id = useLayoutId({
|
|
95
97
|
providedId: providedId
|
|
96
98
|
});
|
|
@@ -635,6 +637,9 @@ function SideNavInternal(_ref) {
|
|
|
635
637
|
}
|
|
636
638
|
devTimeOnlyAttributes['data-visible'] = visible.length ? visible.join(',') : 'false';
|
|
637
639
|
}
|
|
640
|
+
useSideNavToggleKeyboardShortcut({
|
|
641
|
+
canToggleWithShortcut: canToggleWithShortcut
|
|
642
|
+
});
|
|
638
643
|
useResizingWidthCssVarOnRootElement({
|
|
639
644
|
isEnabled: true,
|
|
640
645
|
cssVar: panelSplitterResizingVar,
|
|
@@ -736,6 +741,7 @@ export function SideNav(_ref8) {
|
|
|
736
741
|
onCollapse = _ref8.onCollapse,
|
|
737
742
|
onPeekStart = _ref8.onPeekStart,
|
|
738
743
|
onPeekEnd = _ref8.onPeekEnd,
|
|
744
|
+
canToggleWithShortcut = _ref8.canToggleWithShortcut,
|
|
739
745
|
id = _ref8.id;
|
|
740
746
|
return /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
|
|
741
747
|
namespace: openLayerObserverSideNavNamespace
|
|
@@ -749,6 +755,7 @@ export function SideNav(_ref8) {
|
|
|
749
755
|
onCollapse: onCollapse,
|
|
750
756
|
onPeekStart: onPeekStart,
|
|
751
757
|
onPeekEnd: onPeekEnd,
|
|
752
|
-
id: id
|
|
758
|
+
id: id,
|
|
759
|
+
canToggleWithShortcut: canToggleWithShortcut
|
|
753
760
|
}, children));
|
|
754
761
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { bind } from 'bind-event-listener';
|
|
3
|
+
import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
|
|
4
|
+
import { useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
|
|
5
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
|
+
import { useIsSideNavShortcutEnabled } from './is-side-nav-shortcut-enabled-context';
|
|
7
|
+
import { useToggleSideNav } from './use-toggle-side-nav';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Binds the keyboard shortcut to toggle the side nav.
|
|
11
|
+
*/
|
|
12
|
+
export function useSideNavToggleKeyboardShortcut(_ref) {
|
|
13
|
+
var canToggleWithShortcut = _ref.canToggleWithShortcut;
|
|
14
|
+
var openLayerObserver = useOpenLayerObserver();
|
|
15
|
+
var toggleVisibilityByShortcut = useToggleSideNav({
|
|
16
|
+
trigger: 'keyboard'
|
|
17
|
+
});
|
|
18
|
+
var canToggleWithShortcutStableRef = useStableRef(canToggleWithShortcut);
|
|
19
|
+
var isSideNavShortcutEnabled = useIsSideNavShortcutEnabled();
|
|
20
|
+
useEffect(function () {
|
|
21
|
+
if (!fg('navx-full-height-sidebar')) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!isSideNavShortcutEnabled) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
return bind(window, {
|
|
28
|
+
type: 'keydown',
|
|
29
|
+
listener: function listener(event) {
|
|
30
|
+
if (event.ctrlKey && event.key === '[') {
|
|
31
|
+
if (canToggleWithShortcutStableRef.current && !canToggleWithShortcutStableRef.current()) {
|
|
32
|
+
// Return early if the callback returns false.
|
|
33
|
+
// If the callback is not provided, we assume the shortcut is enabled.
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (event.repeat) {
|
|
37
|
+
// Ignore repeated keydown events from holding down the keys
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (openLayerObserver.getCount({
|
|
41
|
+
type: 'modal'
|
|
42
|
+
}) > 0 && fg('platform-dst-open-layer-observer-layer-type')) {
|
|
43
|
+
// Return early if there are any open modals
|
|
44
|
+
// This check is behind the layer type FG, as `getCount` will return the count of all layers when
|
|
45
|
+
// the FG is disabled - meaning we would ignore the shortcut if there is any open layer (not just modals).
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
toggleVisibilityByShortcut();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}, [canToggleWithShortcutStableRef, openLayerObserver, toggleVisibilityByShortcut, isSideNavShortcutEnabled]);
|
|
53
|
+
}
|
|
@@ -9,7 +9,7 @@ export declare const gridRootId = "unsafe-design-system-page-layout-root";
|
|
|
9
9
|
* The root component of the navigation system. It wraps the underlying components with the necessary contexts allowing to use certain data and hooks
|
|
10
10
|
* @param skipLinksLabel - The very first element of the layout is a skip links container that can be accessed by pressing Tab button and holds the links to the other sections of the layout thus improving accessibility. This parameter defines the header text for this container
|
|
11
11
|
*/
|
|
12
|
-
export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes, skipLinksLabel, testId, defaultSideNavCollapsed, }: {
|
|
12
|
+
export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes, skipLinksLabel, testId, defaultSideNavCollapsed, isSideNavShortcutEnabled, }: {
|
|
13
13
|
/**
|
|
14
14
|
* For rendering the layout areas, e.g. TopNav, SideNav, Main.
|
|
15
15
|
* They should be rendered as immediate children.
|
|
@@ -47,4 +47,22 @@ export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes,
|
|
|
47
47
|
* __Note:__ When provided, the `defaultCollapsed` props on `SideNav` and `SideNavToggleButton` will be ignored.
|
|
48
48
|
*/
|
|
49
49
|
defaultSideNavCollapsed?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Controls whether the side nav toggle shortcut is enabled. This will be used to bind the keyboard event listener,
|
|
52
|
+
* and to display the keyboard shortcuts in the appropriate tooltips (`SideNavToggleButton`, `SideNavPanelSplitter`).
|
|
53
|
+
*
|
|
54
|
+
* The shortcut key is `Ctrl` + `[`.
|
|
55
|
+
*
|
|
56
|
+
* The shortcut is not enabled by default.
|
|
57
|
+
*
|
|
58
|
+
* The shortcut will also be ignored if there are any open ADS modal dialogs (`@atlaskit/modal-dialog`). This is behind
|
|
59
|
+
* the `platform-dst-open-layer-observer-layer-type` feature flag.
|
|
60
|
+
*
|
|
61
|
+
* `SideNav` has another prop `canToggleWithShortcut()` that can be used to run additional checks after the shortcut
|
|
62
|
+
* is pressed, before the SideNav is toggled. You can use this to conditionally disable the shortcut based on your
|
|
63
|
+
* your own custom checks, e.g. if there is a legacy dialog open.
|
|
64
|
+
*
|
|
65
|
+
* Note: The built-in keyboard shortcut is behind the `navx-full-height-sidebar` feature flag.
|
|
66
|
+
*/
|
|
67
|
+
isSideNavShortcutEnabled?: boolean;
|
|
50
68
|
}): JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Provider for the `IsSideNavShortcutEnabledContext`.
|
|
4
|
+
*/
|
|
5
|
+
export declare function IsSideNavShortcutEnabledProvider({ children, isSideNavShortcutEnabled, }: {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
isSideNavShortcutEnabled: boolean;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Returns the value of the `isSideNavShortcutEnabled` prop from the `Root` component, which
|
|
11
|
+
* is shared through context.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useIsSideNavShortcutEnabled(): boolean;
|
|
@@ -63,6 +63,18 @@ type SideNavProps = CommonSlotProps & {
|
|
|
63
63
|
onPeekEnd?: (args: {
|
|
64
64
|
trigger: 'mouse-leave' | 'side-nav-expand';
|
|
65
65
|
}) => void;
|
|
66
|
+
/**
|
|
67
|
+
* Whether the side nav should be toggled in response to the built-in keyboard shortcut. Use this callback to
|
|
68
|
+
* conditionally disable the shortcut based on your own custom checks, e.g. if there is a legacy dialog open.
|
|
69
|
+
*
|
|
70
|
+
* This prop will do nothing if `isSideNavShortcutEnabled` on Root is not set to `true`, as the keyboard event
|
|
71
|
+
* listener is only binded if `isSideNavShortcutEnabled` is `true`.
|
|
72
|
+
*
|
|
73
|
+
* The shortcut key is `Ctrl` + `[`.
|
|
74
|
+
*
|
|
75
|
+
* Note: The built-in keyboard shortcut is behind the `navx-full-height-sidebar` feature flag.
|
|
76
|
+
*/
|
|
77
|
+
canToggleWithShortcut?: () => boolean;
|
|
66
78
|
};
|
|
67
79
|
export declare const onPeekStartDelayMs = 500;
|
|
68
80
|
/**
|
|
@@ -75,5 +87,5 @@ export declare const onPeekStartDelayMs = 500;
|
|
|
75
87
|
*/
|
|
76
88
|
export declare function SideNav({ children, defaultCollapsed, defaultWidth, testId, label, // Default value is defined in `SideNavInternal`
|
|
77
89
|
skipLinkLabel, // Default value is defined in `SideNavInternal`
|
|
78
|
-
onExpand, onCollapse, onPeekStart, onPeekEnd, id, }: SideNavProps): JSX.Element;
|
|
90
|
+
onExpand, onCollapse, onPeekStart, onPeekEnd, canToggleWithShortcut, id, }: SideNavProps): JSX.Element;
|
|
79
91
|
export {};
|
|
@@ -9,7 +9,7 @@ export declare const gridRootId = "unsafe-design-system-page-layout-root";
|
|
|
9
9
|
* The root component of the navigation system. It wraps the underlying components with the necessary contexts allowing to use certain data and hooks
|
|
10
10
|
* @param skipLinksLabel - The very first element of the layout is a skip links container that can be accessed by pressing Tab button and holds the links to the other sections of the layout thus improving accessibility. This parameter defines the header text for this container
|
|
11
11
|
*/
|
|
12
|
-
export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes, skipLinksLabel, testId, defaultSideNavCollapsed, }: {
|
|
12
|
+
export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes, skipLinksLabel, testId, defaultSideNavCollapsed, isSideNavShortcutEnabled, }: {
|
|
13
13
|
/**
|
|
14
14
|
* For rendering the layout areas, e.g. TopNav, SideNav, Main.
|
|
15
15
|
* They should be rendered as immediate children.
|
|
@@ -47,4 +47,22 @@ export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes,
|
|
|
47
47
|
* __Note:__ When provided, the `defaultCollapsed` props on `SideNav` and `SideNavToggleButton` will be ignored.
|
|
48
48
|
*/
|
|
49
49
|
defaultSideNavCollapsed?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Controls whether the side nav toggle shortcut is enabled. This will be used to bind the keyboard event listener,
|
|
52
|
+
* and to display the keyboard shortcuts in the appropriate tooltips (`SideNavToggleButton`, `SideNavPanelSplitter`).
|
|
53
|
+
*
|
|
54
|
+
* The shortcut key is `Ctrl` + `[`.
|
|
55
|
+
*
|
|
56
|
+
* The shortcut is not enabled by default.
|
|
57
|
+
*
|
|
58
|
+
* The shortcut will also be ignored if there are any open ADS modal dialogs (`@atlaskit/modal-dialog`). This is behind
|
|
59
|
+
* the `platform-dst-open-layer-observer-layer-type` feature flag.
|
|
60
|
+
*
|
|
61
|
+
* `SideNav` has another prop `canToggleWithShortcut()` that can be used to run additional checks after the shortcut
|
|
62
|
+
* is pressed, before the SideNav is toggled. You can use this to conditionally disable the shortcut based on your
|
|
63
|
+
* your own custom checks, e.g. if there is a legacy dialog open.
|
|
64
|
+
*
|
|
65
|
+
* Note: The built-in keyboard shortcut is behind the `navx-full-height-sidebar` feature flag.
|
|
66
|
+
*/
|
|
67
|
+
isSideNavShortcutEnabled?: boolean;
|
|
50
68
|
}): JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Provider for the `IsSideNavShortcutEnabledContext`.
|
|
4
|
+
*/
|
|
5
|
+
export declare function IsSideNavShortcutEnabledProvider({ children, isSideNavShortcutEnabled, }: {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
isSideNavShortcutEnabled: boolean;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Returns the value of the `isSideNavShortcutEnabled` prop from the `Root` component, which
|
|
11
|
+
* is shared through context.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useIsSideNavShortcutEnabled(): boolean;
|
|
@@ -63,6 +63,18 @@ type SideNavProps = CommonSlotProps & {
|
|
|
63
63
|
onPeekEnd?: (args: {
|
|
64
64
|
trigger: 'mouse-leave' | 'side-nav-expand';
|
|
65
65
|
}) => void;
|
|
66
|
+
/**
|
|
67
|
+
* Whether the side nav should be toggled in response to the built-in keyboard shortcut. Use this callback to
|
|
68
|
+
* conditionally disable the shortcut based on your own custom checks, e.g. if there is a legacy dialog open.
|
|
69
|
+
*
|
|
70
|
+
* This prop will do nothing if `isSideNavShortcutEnabled` on Root is not set to `true`, as the keyboard event
|
|
71
|
+
* listener is only binded if `isSideNavShortcutEnabled` is `true`.
|
|
72
|
+
*
|
|
73
|
+
* The shortcut key is `Ctrl` + `[`.
|
|
74
|
+
*
|
|
75
|
+
* Note: The built-in keyboard shortcut is behind the `navx-full-height-sidebar` feature flag.
|
|
76
|
+
*/
|
|
77
|
+
canToggleWithShortcut?: () => boolean;
|
|
66
78
|
};
|
|
67
79
|
export declare const onPeekStartDelayMs = 500;
|
|
68
80
|
/**
|
|
@@ -75,5 +87,5 @@ export declare const onPeekStartDelayMs = 500;
|
|
|
75
87
|
*/
|
|
76
88
|
export declare function SideNav({ children, defaultCollapsed, defaultWidth, testId, label, // Default value is defined in `SideNavInternal`
|
|
77
89
|
skipLinkLabel, // Default value is defined in `SideNavInternal`
|
|
78
|
-
onExpand, onCollapse, onPeekStart, onPeekEnd, id, }: SideNavProps): JSX.Element;
|
|
90
|
+
onExpand, onCollapse, onPeekStart, onPeekEnd, canToggleWithShortcut, id, }: SideNavProps): JSX.Element;
|
|
79
91
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/navigation-system",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "The latest navigation system for Atlassian apps.",
|
|
5
5
|
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
|
|
6
6
|
"author": "Atlassian Pty Ltd",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@atlaskit/css": "^0.15.0",
|
|
73
73
|
"@atlaskit/ds-lib": "^5.1.0",
|
|
74
74
|
"@atlaskit/icon": "^28.5.0",
|
|
75
|
-
"@atlaskit/layering": "^3.
|
|
75
|
+
"@atlaskit/layering": "^3.2.0",
|
|
76
76
|
"@atlaskit/logo": "^19.9.0",
|
|
77
77
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
78
78
|
"@atlaskit/popup": "^4.4.0",
|
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
"@atlaskit/link": "^3.2.0",
|
|
108
108
|
"@atlaskit/lozenge": "^13.0.0",
|
|
109
109
|
"@atlaskit/menu": "^8.4.0",
|
|
110
|
+
"@atlaskit/modal-dialog": "^14.6.0",
|
|
110
111
|
"@atlaskit/onboarding": "^14.4.0",
|
|
111
112
|
"@atlaskit/page-header": "^12.1.0",
|
|
112
113
|
"@atlaskit/page-layout": "^4.2.0",
|
|
@@ -118,6 +119,7 @@
|
|
|
118
119
|
"@atlassian/gemini": "^1.20.0",
|
|
119
120
|
"@atlassian/search-dialog": "^9.7.0",
|
|
120
121
|
"@atlassian/ssr-tests": "^0.3.0",
|
|
122
|
+
"@atlassian/testing-library": "^0.4.0",
|
|
121
123
|
"@axe-core/playwright": "^4.8.0",
|
|
122
124
|
"@testing-library/react": "^13.4.0",
|
|
123
125
|
"@testing-library/react-hooks": "^8.0.1",
|
|
@@ -184,6 +186,9 @@
|
|
|
184
186
|
},
|
|
185
187
|
"platform_dst_side_nav_remove_custom_tooltip": {
|
|
186
188
|
"type": "boolean"
|
|
189
|
+
},
|
|
190
|
+
"platform-dst-open-layer-observer-layer-type": {
|
|
191
|
+
"type": "boolean"
|
|
187
192
|
}
|
|
188
193
|
},
|
|
189
194
|
"homepage": "https://atlassian.design/components/navigation-system"
|