@atlaskit/navigation-system 2.1.3 → 2.3.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cjs/ui/menu-section/menu-section-heading.js +5 -1
  3. package/dist/cjs/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +3 -1
  4. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +48 -24
  5. package/dist/cjs/ui/page-layout/side-nav/toggle-button.js +3 -1
  6. package/dist/cjs/ui/page-layout/side-nav/use-expand-side-nav.js +8 -3
  7. package/dist/cjs/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.js +53 -19
  8. package/dist/cjs/ui/page-layout/side-nav/use-toggle-side-nav.js +9 -4
  9. package/dist/es2019/ui/menu-section/menu-section-heading.js +5 -1
  10. package/dist/es2019/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +3 -1
  11. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +44 -20
  12. package/dist/es2019/ui/page-layout/side-nav/toggle-button.js +3 -1
  13. package/dist/es2019/ui/page-layout/side-nav/use-expand-side-nav.js +8 -4
  14. package/dist/es2019/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.js +53 -19
  15. package/dist/es2019/ui/page-layout/side-nav/use-toggle-side-nav.js +9 -5
  16. package/dist/esm/ui/menu-section/menu-section-heading.js +5 -1
  17. package/dist/esm/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +3 -1
  18. package/dist/esm/ui/page-layout/side-nav/side-nav.js +48 -24
  19. package/dist/esm/ui/page-layout/side-nav/toggle-button.js +3 -1
  20. package/dist/esm/ui/page-layout/side-nav/use-expand-side-nav.js +8 -3
  21. package/dist/esm/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.js +53 -19
  22. package/dist/esm/ui/page-layout/side-nav/use-toggle-side-nav.js +9 -4
  23. package/dist/types/ui/page-layout/side-nav/types.d.ts +19 -0
  24. package/dist/types/ui/page-layout/side-nav/use-expand-side-nav.d.ts +5 -1
  25. package/dist/types/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.d.ts +4 -1
  26. package/dist/types/ui/page-layout/side-nav/use-toggle-side-nav.d.ts +6 -2
  27. package/dist/types-ts4.5/ui/page-layout/side-nav/types.d.ts +19 -0
  28. package/dist/types-ts4.5/ui/page-layout/side-nav/use-expand-side-nav.d.ts +5 -1
  29. package/dist/types-ts4.5/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.d.ts +4 -1
  30. package/dist/types-ts4.5/ui/page-layout/side-nav/use-toggle-side-nav.d.ts +6 -2
  31. package/package.json +7 -1
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  /**
4
5
  * Calls the `onExpand` and `onCollapse` callbacks as required.
5
6
  * This is used for both user-provided callbacks, as well as internal callbacks to respond to visibility state changes.
@@ -8,7 +9,8 @@ export function useSideNavVisibilityCallbacks({
8
9
  onExpand,
9
10
  onCollapse,
10
11
  isExpandedOnDesktop,
11
- isExpandedOnMobile
12
+ isExpandedOnMobile,
13
+ lastTrigger
12
14
  }) {
13
15
  // Wrapping in refs so we can call them in `useEffect` without changes to them triggering the `useEffect`
14
16
  const onExpandRef = useRef(onExpand);
@@ -30,17 +32,33 @@ export function useSideNavVisibilityCallbacks({
30
32
  return;
31
33
  }
32
34
  if (isExpandedOnDesktop) {
33
- var _onExpandRef$current;
34
- (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 ? void 0 : _onExpandRef$current.call(onExpandRef, {
35
- screen: 'desktop'
36
- });
35
+ if (fg('navx-full-height-sidebar')) {
36
+ var _onExpandRef$current;
37
+ (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 ? void 0 : _onExpandRef$current.call(onExpandRef, {
38
+ screen: 'desktop',
39
+ trigger: lastTrigger
40
+ });
41
+ } else {
42
+ var _onExpandRef$current2;
43
+ (_onExpandRef$current2 = onExpandRef.current) === null || _onExpandRef$current2 === void 0 ? void 0 : _onExpandRef$current2.call(onExpandRef, {
44
+ screen: 'desktop'
45
+ });
46
+ }
37
47
  } else {
38
- var _onCollapseRef$curren;
39
- (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 ? void 0 : _onCollapseRef$curren.call(onCollapseRef, {
40
- screen: 'desktop'
41
- });
48
+ if (fg('navx-full-height-sidebar')) {
49
+ var _onCollapseRef$curren;
50
+ (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 ? void 0 : _onCollapseRef$curren.call(onCollapseRef, {
51
+ screen: 'desktop',
52
+ trigger: lastTrigger
53
+ });
54
+ } else {
55
+ var _onCollapseRef$curren2;
56
+ (_onCollapseRef$curren2 = onCollapseRef.current) === null || _onCollapseRef$curren2 === void 0 ? void 0 : _onCollapseRef$curren2.call(onCollapseRef, {
57
+ screen: 'desktop'
58
+ });
59
+ }
42
60
  }
43
- }, [previousIsExpandedOnDesktop, isExpandedOnDesktop]);
61
+ }, [previousIsExpandedOnDesktop, isExpandedOnDesktop, lastTrigger]);
44
62
  const previousIsExpandedOnMobile = usePreviousValue(isExpandedOnMobile);
45
63
  useEffect(() => {
46
64
  if (previousIsExpandedOnMobile === undefined || previousIsExpandedOnMobile === isExpandedOnMobile) {
@@ -54,15 +72,31 @@ export function useSideNavVisibilityCallbacks({
54
72
  return;
55
73
  }
56
74
  if (isExpandedOnMobile) {
57
- var _onExpandRef$current2;
58
- (_onExpandRef$current2 = onExpandRef.current) === null || _onExpandRef$current2 === void 0 ? void 0 : _onExpandRef$current2.call(onExpandRef, {
59
- screen: 'mobile'
60
- });
75
+ if (fg('navx-full-height-sidebar')) {
76
+ var _onExpandRef$current3;
77
+ (_onExpandRef$current3 = onExpandRef.current) === null || _onExpandRef$current3 === void 0 ? void 0 : _onExpandRef$current3.call(onExpandRef, {
78
+ screen: 'mobile',
79
+ trigger: lastTrigger
80
+ });
81
+ } else {
82
+ var _onExpandRef$current4;
83
+ (_onExpandRef$current4 = onExpandRef.current) === null || _onExpandRef$current4 === void 0 ? void 0 : _onExpandRef$current4.call(onExpandRef, {
84
+ screen: 'mobile'
85
+ });
86
+ }
61
87
  } else {
62
- var _onCollapseRef$curren2;
63
- (_onCollapseRef$curren2 = onCollapseRef.current) === null || _onCollapseRef$curren2 === void 0 ? void 0 : _onCollapseRef$curren2.call(onCollapseRef, {
64
- screen: 'mobile'
65
- });
88
+ if (fg('navx-full-height-sidebar')) {
89
+ var _onCollapseRef$curren3;
90
+ (_onCollapseRef$curren3 = onCollapseRef.current) === null || _onCollapseRef$curren3 === void 0 ? void 0 : _onCollapseRef$curren3.call(onCollapseRef, {
91
+ screen: 'mobile',
92
+ trigger: lastTrigger
93
+ });
94
+ } else {
95
+ var _onCollapseRef$curren4;
96
+ (_onCollapseRef$curren4 = onCollapseRef.current) === null || _onCollapseRef$curren4 === void 0 ? void 0 : _onCollapseRef$curren4.call(onCollapseRef, {
97
+ screen: 'mobile'
98
+ });
99
+ }
66
100
  }
67
- }, [previousIsExpandedOnMobile, isExpandedOnMobile]);
101
+ }, [previousIsExpandedOnMobile, isExpandedOnMobile, lastTrigger]);
68
102
  }
@@ -7,9 +7,11 @@ import { SetSideNavVisibilityState } from './visibility-context';
7
7
  *
8
8
  * It will toggle the appropriate internal desktop or mobile side nav visibility state based on the current screen size.
9
9
  *
10
- * If you need a function to make the side nav visible, use `useShowSideNav` instead.
10
+ * If you need a function to make the side nav visible, use `useExpandSideNav` instead.
11
11
  */
12
- export function useToggleSideNav() {
12
+ export function useToggleSideNav({
13
+ trigger = 'programmatic'
14
+ } = {}) {
13
15
  const setSideNavState = useContext(SetSideNavVisibilityState);
14
16
  const toggleSideNav = useCallback(() => {
15
17
  const {
@@ -25,7 +27,8 @@ export function useToggleSideNav() {
25
27
  return {
26
28
  mobile: currentState.mobile,
27
29
  desktop: currentState.desktop === 'expanded' ? 'collapsed' : 'expanded',
28
- flyout: 'closed'
30
+ flyout: 'closed',
31
+ lastTrigger: trigger
29
32
  };
30
33
  });
31
34
  } else {
@@ -38,10 +41,11 @@ export function useToggleSideNav() {
38
41
  return {
39
42
  desktop: currentState.desktop,
40
43
  mobile: currentState.mobile === 'expanded' ? 'collapsed' : 'expanded',
41
- flyout: 'closed'
44
+ flyout: 'closed',
45
+ lastTrigger: trigger
42
46
  };
43
47
  });
44
48
  }
45
- }, [setSideNavState]);
49
+ }, [setSideNavState, trigger]);
46
50
  return toggleSideNav;
47
51
  }
@@ -2,6 +2,7 @@
2
2
  import "./menu-section-heading.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import { useMenuSectionContext } from './menu-section-context';
6
7
  var styles = {
7
8
  root: "_11c81vhk _1rjcu2gc _syaz131l _bozg12x7"
@@ -15,7 +16,10 @@ var styles = {
15
16
  export var MenuSectionHeading = function MenuSectionHeading(_ref) {
16
17
  var children = _ref.children;
17
18
  var id = useMenuSectionContext();
18
- return /*#__PURE__*/React.createElement("h2", {
19
+ return fg('platform_dst_nav4_menu_section_heading_a11y') ? /*#__PURE__*/React.createElement("p", {
20
+ id: "".concat(id, "-heading"),
21
+ className: ax([styles.root])
22
+ }, children) : /*#__PURE__*/React.createElement("h2", {
19
23
  id: "".concat(id, "-heading"),
20
24
  className: ax([styles.root])
21
25
  }, children);
@@ -26,7 +26,9 @@ export var SideNavPanelSplitter = function SideNavPanelSplitter(_ref) {
26
26
  shouldCollapseOnDoubleClick = _ref$shouldCollapseOn === void 0 ? true : _ref$shouldCollapseOn;
27
27
  var context = useContext(PanelSplitterContext);
28
28
  invariant((context === null || context === void 0 ? void 0 : context.panelId) === sideNavPanelSplitterId, 'SideNavPanelSplitter must be rendered as a child of <SideNav />.');
29
- var toggleSideNav = useToggleSideNav();
29
+ var toggleSideNav = useToggleSideNav({
30
+ trigger: 'double-click'
31
+ });
30
32
  return /*#__PURE__*/React.createElement(OnDoubleClickContext.Provider, {
31
33
  value: shouldCollapseOnDoubleClick ? toggleSideNav : undefined
32
34
  }, /*#__PURE__*/React.createElement(PanelSplitter, {
@@ -5,6 +5,8 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  import "./side-nav.compiled.css";
6
6
  import * as React from 'react';
7
7
  import { ax, ix } from "@compiled/react/runtime";
8
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
10
  import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
9
11
  import { bind } from 'bind-event-listener';
10
12
  import { flushSync } from 'react-dom';
@@ -58,6 +60,7 @@ var fallbackDefaultWidth = 320;
58
60
  * context value.
59
61
  */
60
62
  function SideNavInternal(_ref) {
63
+ var _sideNavState$lastTri;
61
64
  var children = _ref.children,
62
65
  defaultCollapsed = _ref.defaultCollapsed,
63
66
  _ref$defaultWidth = _ref.defaultWidth,
@@ -73,7 +76,9 @@ function SideNavInternal(_ref) {
73
76
  var id = useLayoutId({
74
77
  providedId: providedId
75
78
  });
76
- var expandSideNav = useExpandSideNav();
79
+ var expandSideNav = useExpandSideNav({
80
+ trigger: 'skip-link'
81
+ });
77
82
  /**
78
83
  * Called after clicking on the side nav skip link, and ensures the side nav is expanded so that it is focusable.
79
84
  *
@@ -146,11 +151,9 @@ function SideNavInternal(_ref) {
146
151
  };
147
152
  setSideNavState(function (currentState) {
148
153
  if ((currentState === null || currentState === void 0 ? void 0 : currentState.desktop) === 'collapsed' && (currentState === null || currentState === void 0 ? void 0 : currentState.flyout) !== 'open') {
149
- return {
150
- desktop: currentState.desktop,
151
- mobile: currentState.mobile,
154
+ return _objectSpread(_objectSpread({}, currentState), {}, {
152
155
  flyout: 'open'
153
- };
156
+ });
154
157
  }
155
158
  return currentState;
156
159
  });
@@ -162,11 +165,9 @@ function SideNavInternal(_ref) {
162
165
  };
163
166
  setSideNavState(function (currentState) {
164
167
  if ((currentState === null || currentState === void 0 ? void 0 : currentState.desktop) === 'collapsed' && (currentState === null || currentState === void 0 ? void 0 : currentState.flyout) === 'open') {
165
- return {
166
- desktop: currentState.desktop,
167
- mobile: currentState.mobile,
168
+ return _objectSpread(_objectSpread({}, currentState), {}, {
168
169
  flyout: 'triggered-animate-close'
169
- };
170
+ });
170
171
  }
171
172
  return currentState;
172
173
  });
@@ -229,31 +230,53 @@ function SideNavInternal(_ref) {
229
230
  }
230
231
  };
231
232
  }, [openLayerObserver, setSideNavState]);
232
- var toggleVisibility = useToggleSideNav();
233
+ var toggleVisibilityByScreenResize = useToggleSideNav({
234
+ trigger: 'screen-resize'
235
+ });
236
+ var toggleVisibilityByClickOutsideOnMobile = useToggleSideNav({
237
+ trigger: 'click-outside-on-mobile'
238
+ });
233
239
  useEffect(function () {
234
240
  // Sync the visibility in context (provided in `<Root>`) with the local `defaultCollapsed` prop provided to `SideNav`
235
241
  // after SSR hydration. This should only run once, after the initial render on the client.
236
242
  setSideNavState({
237
243
  desktop: initialDefaultCollapsed ? 'collapsed' : 'expanded',
238
244
  mobile: 'collapsed',
239
- flyout: 'closed'
245
+ flyout: 'closed',
246
+ lastTrigger: null
240
247
  });
241
248
  }, [initialDefaultCollapsed, setSideNavState]);
242
249
  var handleExpand = useCallback(function (_ref2) {
243
- var screen = _ref2.screen;
244
- onExpand === null || onExpand === void 0 || onExpand({
245
- screen: screen
246
- });
250
+ var screen = _ref2.screen,
251
+ trigger = _ref2.trigger;
252
+ if (fg('navx-full-height-sidebar')) {
253
+ onExpand === null || onExpand === void 0 || onExpand({
254
+ screen: screen,
255
+ trigger: trigger
256
+ });
257
+ } else {
258
+ onExpand === null || onExpand === void 0 || onExpand({
259
+ screen: screen
260
+ });
261
+ }
247
262
 
248
263
  // When the side nav gets expanded, we close the flyout to reset it.
249
264
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to expand.
250
265
  updateFlyoutState('force-close');
251
266
  }, [onExpand, updateFlyoutState]);
252
267
  var handleCollapse = useCallback(function (_ref3) {
253
- var screen = _ref3.screen;
254
- onCollapse === null || onCollapse === void 0 || onCollapse({
255
- screen: screen
256
- });
268
+ var screen = _ref3.screen,
269
+ trigger = _ref3.trigger;
270
+ if (fg('navx-full-height-sidebar')) {
271
+ onCollapse === null || onCollapse === void 0 || onCollapse({
272
+ screen: screen,
273
+ trigger: trigger
274
+ });
275
+ } else {
276
+ onCollapse === null || onCollapse === void 0 || onCollapse({
277
+ screen: screen
278
+ });
279
+ }
257
280
 
258
281
  // When the side nav gets collapsed, we close the flyout to reset it.
259
282
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to collapse.
@@ -263,7 +286,8 @@ function SideNavInternal(_ref) {
263
286
  onExpand: handleExpand,
264
287
  onCollapse: handleCollapse,
265
288
  isExpandedOnDesktop: isExpandedOnDesktop,
266
- isExpandedOnMobile: isExpandedOnMobile
289
+ isExpandedOnMobile: isExpandedOnMobile,
290
+ lastTrigger: (_sideNavState$lastTri = sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.lastTrigger) !== null && _sideNavState$lastTri !== void 0 ? _sideNavState$lastTri : null
267
291
  });
268
292
  useEffect(function () {
269
293
  var mediaQueryList = window.matchMedia('(min-width: 64rem)');
@@ -274,12 +298,12 @@ function SideNavInternal(_ref) {
274
298
  // We're transitioning from tablet to desktop viewport size.
275
299
  // We forcibly show the side nav if it was shown on mobile.
276
300
  if (isExpandedOnMobile && !isExpandedOnDesktop) {
277
- toggleVisibility();
301
+ toggleVisibilityByScreenResize();
278
302
  }
279
303
  }
280
304
  }
281
305
  });
282
- }, [toggleVisibility, isExpandedOnDesktop, isExpandedOnMobile]);
306
+ }, [toggleVisibilityByScreenResize, isExpandedOnDesktop, isExpandedOnMobile]);
283
307
 
284
308
  /**
285
309
  * Close the mobile side nav if there is a click outside.
@@ -336,10 +360,10 @@ function SideNavInternal(_ref) {
336
360
  // In either case keeping the SideNav expanded makes sense.
337
361
  return;
338
362
  }
339
- toggleVisibility();
363
+ toggleVisibilityByClickOutsideOnMobile();
340
364
  }
341
365
  });
342
- }, [id, isExpandedOnMobile, toggleButtonElement, toggleVisibility]);
366
+ }, [id, isExpandedOnMobile, toggleButtonElement, toggleVisibilityByClickOutsideOnMobile]);
343
367
  useEffect(function () {
344
368
  if (!toggleButtonElement) {
345
369
  return;
@@ -64,7 +64,9 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
64
64
  }
65
65
  });
66
66
  }, [isSideNavExpandedOnDesktop, isSideNavExpandedOnMobile]);
67
- var toggleVisibility = useToggleSideNav();
67
+ var toggleVisibility = useToggleSideNav({
68
+ trigger: 'toggle-button'
69
+ });
68
70
  var handleClick = useCallback(function (event, analyticsEvent) {
69
71
  onClick === null || onClick === void 0 || onClick(event, analyticsEvent, {
70
72
  isSideNavVisible: isSideNavExpanded
@@ -10,6 +10,9 @@ import { SetSideNavVisibilityState } from './visibility-context';
10
10
  * If you need a function to toggle the side nav, use `useToggleSideNav` instead.
11
11
  */
12
12
  export function useExpandSideNav() {
13
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
14
+ _ref$trigger = _ref.trigger,
15
+ trigger = _ref$trigger === void 0 ? 'programmatic' : _ref$trigger;
13
16
  var setSideNavState = useContext(SetSideNavVisibilityState);
14
17
  var expandSideNav = useCallback(function () {
15
18
  var _window$matchMedia = window.matchMedia('(min-width: 64rem)'),
@@ -29,7 +32,8 @@ export function useExpandSideNav() {
29
32
  return {
30
33
  mobile: currentState.mobile,
31
34
  desktop: 'expanded',
32
- flyout: 'closed'
35
+ flyout: 'closed',
36
+ lastTrigger: trigger
33
37
  };
34
38
  });
35
39
  } else {
@@ -47,10 +51,11 @@ export function useExpandSideNav() {
47
51
  return {
48
52
  desktop: currentState.desktop,
49
53
  mobile: 'expanded',
50
- flyout: 'closed'
54
+ flyout: 'closed',
55
+ lastTrigger: trigger
51
56
  };
52
57
  });
53
58
  }
54
- }, [setSideNavState]);
59
+ }, [setSideNavState, trigger]);
55
60
  return expandSideNav;
56
61
  }
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  /**
4
5
  * Calls the `onExpand` and `onCollapse` callbacks as required.
5
6
  * This is used for both user-provided callbacks, as well as internal callbacks to respond to visibility state changes.
@@ -8,7 +9,8 @@ export function useSideNavVisibilityCallbacks(_ref) {
8
9
  var onExpand = _ref.onExpand,
9
10
  onCollapse = _ref.onCollapse,
10
11
  isExpandedOnDesktop = _ref.isExpandedOnDesktop,
11
- isExpandedOnMobile = _ref.isExpandedOnMobile;
12
+ isExpandedOnMobile = _ref.isExpandedOnMobile,
13
+ lastTrigger = _ref.lastTrigger;
12
14
  // Wrapping in refs so we can call them in `useEffect` without changes to them triggering the `useEffect`
13
15
  var onExpandRef = useRef(onExpand);
14
16
  var onCollapseRef = useRef(onCollapse);
@@ -29,17 +31,33 @@ export function useSideNavVisibilityCallbacks(_ref) {
29
31
  return;
30
32
  }
31
33
  if (isExpandedOnDesktop) {
32
- var _onExpandRef$current;
33
- (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 || _onExpandRef$current.call(onExpandRef, {
34
- screen: 'desktop'
35
- });
34
+ if (fg('navx-full-height-sidebar')) {
35
+ var _onExpandRef$current;
36
+ (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 || _onExpandRef$current.call(onExpandRef, {
37
+ screen: 'desktop',
38
+ trigger: lastTrigger
39
+ });
40
+ } else {
41
+ var _onExpandRef$current2;
42
+ (_onExpandRef$current2 = onExpandRef.current) === null || _onExpandRef$current2 === void 0 || _onExpandRef$current2.call(onExpandRef, {
43
+ screen: 'desktop'
44
+ });
45
+ }
36
46
  } else {
37
- var _onCollapseRef$curren;
38
- (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 || _onCollapseRef$curren.call(onCollapseRef, {
39
- screen: 'desktop'
40
- });
47
+ if (fg('navx-full-height-sidebar')) {
48
+ var _onCollapseRef$curren;
49
+ (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 || _onCollapseRef$curren.call(onCollapseRef, {
50
+ screen: 'desktop',
51
+ trigger: lastTrigger
52
+ });
53
+ } else {
54
+ var _onCollapseRef$curren2;
55
+ (_onCollapseRef$curren2 = onCollapseRef.current) === null || _onCollapseRef$curren2 === void 0 || _onCollapseRef$curren2.call(onCollapseRef, {
56
+ screen: 'desktop'
57
+ });
58
+ }
41
59
  }
42
- }, [previousIsExpandedOnDesktop, isExpandedOnDesktop]);
60
+ }, [previousIsExpandedOnDesktop, isExpandedOnDesktop, lastTrigger]);
43
61
  var previousIsExpandedOnMobile = usePreviousValue(isExpandedOnMobile);
44
62
  useEffect(function () {
45
63
  if (previousIsExpandedOnMobile === undefined || previousIsExpandedOnMobile === isExpandedOnMobile) {
@@ -53,15 +71,31 @@ export function useSideNavVisibilityCallbacks(_ref) {
53
71
  return;
54
72
  }
55
73
  if (isExpandedOnMobile) {
56
- var _onExpandRef$current2;
57
- (_onExpandRef$current2 = onExpandRef.current) === null || _onExpandRef$current2 === void 0 || _onExpandRef$current2.call(onExpandRef, {
58
- screen: 'mobile'
59
- });
74
+ if (fg('navx-full-height-sidebar')) {
75
+ var _onExpandRef$current3;
76
+ (_onExpandRef$current3 = onExpandRef.current) === null || _onExpandRef$current3 === void 0 || _onExpandRef$current3.call(onExpandRef, {
77
+ screen: 'mobile',
78
+ trigger: lastTrigger
79
+ });
80
+ } else {
81
+ var _onExpandRef$current4;
82
+ (_onExpandRef$current4 = onExpandRef.current) === null || _onExpandRef$current4 === void 0 || _onExpandRef$current4.call(onExpandRef, {
83
+ screen: 'mobile'
84
+ });
85
+ }
60
86
  } else {
61
- var _onCollapseRef$curren2;
62
- (_onCollapseRef$curren2 = onCollapseRef.current) === null || _onCollapseRef$curren2 === void 0 || _onCollapseRef$curren2.call(onCollapseRef, {
63
- screen: 'mobile'
64
- });
87
+ if (fg('navx-full-height-sidebar')) {
88
+ var _onCollapseRef$curren3;
89
+ (_onCollapseRef$curren3 = onCollapseRef.current) === null || _onCollapseRef$curren3 === void 0 || _onCollapseRef$curren3.call(onCollapseRef, {
90
+ screen: 'mobile',
91
+ trigger: lastTrigger
92
+ });
93
+ } else {
94
+ var _onCollapseRef$curren4;
95
+ (_onCollapseRef$curren4 = onCollapseRef.current) === null || _onCollapseRef$curren4 === void 0 || _onCollapseRef$curren4.call(onCollapseRef, {
96
+ screen: 'mobile'
97
+ });
98
+ }
65
99
  }
66
- }, [previousIsExpandedOnMobile, isExpandedOnMobile]);
100
+ }, [previousIsExpandedOnMobile, isExpandedOnMobile, lastTrigger]);
67
101
  }
@@ -7,9 +7,12 @@ import { SetSideNavVisibilityState } from './visibility-context';
7
7
  *
8
8
  * It will toggle the appropriate internal desktop or mobile side nav visibility state based on the current screen size.
9
9
  *
10
- * If you need a function to make the side nav visible, use `useShowSideNav` instead.
10
+ * If you need a function to make the side nav visible, use `useExpandSideNav` instead.
11
11
  */
12
12
  export function useToggleSideNav() {
13
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
14
+ _ref$trigger = _ref.trigger,
15
+ trigger = _ref$trigger === void 0 ? 'programmatic' : _ref$trigger;
13
16
  var setSideNavState = useContext(SetSideNavVisibilityState);
14
17
  var toggleSideNav = useCallback(function () {
15
18
  var _window$matchMedia = window.matchMedia('(min-width: 64rem)'),
@@ -24,7 +27,8 @@ export function useToggleSideNav() {
24
27
  return {
25
28
  mobile: currentState.mobile,
26
29
  desktop: currentState.desktop === 'expanded' ? 'collapsed' : 'expanded',
27
- flyout: 'closed'
30
+ flyout: 'closed',
31
+ lastTrigger: trigger
28
32
  };
29
33
  });
30
34
  } else {
@@ -37,10 +41,11 @@ export function useToggleSideNav() {
37
41
  return {
38
42
  desktop: currentState.desktop,
39
43
  mobile: currentState.mobile === 'expanded' ? 'collapsed' : 'expanded',
40
- flyout: 'closed'
44
+ flyout: 'closed',
45
+ lastTrigger: trigger
41
46
  };
42
47
  });
43
48
  }
44
- }, [setSideNavState]);
49
+ }, [setSideNavState, trigger]);
45
50
  return toggleSideNav;
46
51
  }
@@ -11,32 +11,51 @@ export type SideNavState = {
11
11
  desktop: 'expanded';
12
12
  mobile: 'expanded';
13
13
  flyout: 'closed';
14
+ lastTrigger: SideNavTrigger | null;
14
15
  } | {
15
16
  desktop: 'expanded';
16
17
  mobile: 'collapsed';
17
18
  flyout: 'closed';
19
+ lastTrigger: SideNavTrigger | null;
18
20
  } | {
19
21
  desktop: 'collapsed';
20
22
  mobile: 'expanded';
21
23
  flyout: 'closed';
24
+ lastTrigger: SideNavTrigger | null;
22
25
  } | {
23
26
  desktop: 'collapsed';
24
27
  mobile: 'expanded';
25
28
  flyout: 'open';
29
+ lastTrigger: SideNavTrigger | null;
26
30
  } | {
27
31
  desktop: 'collapsed';
28
32
  mobile: 'expanded';
29
33
  flyout: 'triggered-animate-close';
34
+ lastTrigger: SideNavTrigger | null;
30
35
  } | {
31
36
  desktop: 'collapsed';
32
37
  mobile: 'collapsed';
33
38
  flyout: 'closed';
39
+ lastTrigger: SideNavTrigger | null;
34
40
  } | {
35
41
  desktop: 'collapsed';
36
42
  mobile: 'collapsed';
37
43
  flyout: 'open';
44
+ lastTrigger: SideNavTrigger | null;
38
45
  } | {
39
46
  desktop: 'collapsed';
40
47
  mobile: 'collapsed';
41
48
  flyout: 'triggered-animate-close';
49
+ lastTrigger: SideNavTrigger | null;
42
50
  };
51
+ /**
52
+ * The type of trigger that caused the side nav to be toggled.
53
+ * - `click-outside-on-mobile` - toggled by clicking outside of the side nav (mobile only)
54
+ * - `double-click` - toggled by double clicking on the side nav panel splitter
55
+ * - `keyboard` - toggled by a keyboard action
56
+ * - `programmatic` - toggled by a custom action, this is the default value when using the `useToggleSideNav` hook without specifying a trigger
57
+ * - `screen-resize` - toggled by a screen resize action
58
+ * - `skip-link` - toggled by a skip link action
59
+ * - `toggle-button` - toggled by the `SideNavToggleButton` component
60
+ */
61
+ export type SideNavTrigger = 'click-outside-on-mobile' | 'double-click' | 'keyboard' | 'programmatic' | 'screen-resize' | 'skip-link' | 'toggle-button';
@@ -1,4 +1,8 @@
1
+ import { type SideNavTrigger } from './types';
1
2
  type ExpandSideNav = () => void;
3
+ type UseExpandSideNavOptions = {
4
+ trigger?: SideNavTrigger;
5
+ };
2
6
  /**
3
7
  * __useExpandSideNav__
4
8
  *
@@ -8,5 +12,5 @@ type ExpandSideNav = () => void;
8
12
  *
9
13
  * If you need a function to toggle the side nav, use `useToggleSideNav` instead.
10
14
  */
11
- export declare function useExpandSideNav(): ExpandSideNav;
15
+ export declare function useExpandSideNav({ trigger, }?: UseExpandSideNavOptions): ExpandSideNav;
12
16
  export {};
@@ -1,13 +1,16 @@
1
+ import { type SideNavTrigger } from './types';
1
2
  export type VisibilityCallback = (args: {
2
3
  screen: 'mobile' | 'desktop';
4
+ trigger?: SideNavTrigger | null;
3
5
  }) => void;
4
6
  /**
5
7
  * Calls the `onExpand` and `onCollapse` callbacks as required.
6
8
  * This is used for both user-provided callbacks, as well as internal callbacks to respond to visibility state changes.
7
9
  */
8
- export declare function useSideNavVisibilityCallbacks({ onExpand, onCollapse, isExpandedOnDesktop, isExpandedOnMobile, }: {
10
+ export declare function useSideNavVisibilityCallbacks({ onExpand, onCollapse, isExpandedOnDesktop, isExpandedOnMobile, lastTrigger, }: {
9
11
  onExpand?: VisibilityCallback;
10
12
  onCollapse?: VisibilityCallback;
11
13
  isExpandedOnDesktop: boolean;
12
14
  isExpandedOnMobile: boolean;
15
+ lastTrigger: SideNavTrigger | null;
13
16
  }): void;
@@ -1,4 +1,8 @@
1
+ import { type SideNavTrigger } from './types';
1
2
  type ToggleSideNav = () => void;
3
+ type UseToggleSideNavOptions = {
4
+ trigger?: SideNavTrigger;
5
+ };
2
6
  /**
3
7
  * __useToggleSideNav__
4
8
  *
@@ -6,7 +10,7 @@ type ToggleSideNav = () => void;
6
10
  *
7
11
  * It will toggle the appropriate internal desktop or mobile side nav visibility state based on the current screen size.
8
12
  *
9
- * If you need a function to make the side nav visible, use `useShowSideNav` instead.
13
+ * If you need a function to make the side nav visible, use `useExpandSideNav` instead.
10
14
  */
11
- export declare function useToggleSideNav(): ToggleSideNav;
15
+ export declare function useToggleSideNav({ trigger, }?: UseToggleSideNavOptions): ToggleSideNav;
12
16
  export {};