@atlaskit/navigation-system 11.3.2 → 11.3.4

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 (44) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/constellation/layout/images/layout-anatomy-dark.png +0 -0
  3. package/constellation/layout/images/layout-anatomy-light.png +0 -0
  4. package/constellation/layout/images/layout-do-dark.png +0 -0
  5. package/constellation/layout/images/layout-do-light.png +0 -0
  6. package/constellation/layout/images/layout-dont-dark.png +0 -0
  7. package/constellation/layout/images/layout-dont-light.png +0 -0
  8. package/constellation/layout/images/layout-example-dark.png +0 -0
  9. package/constellation/layout/images/layout-example-light.png +0 -0
  10. package/constellation/layout/images/layout-example-sideNav-dark.png +0 -0
  11. package/constellation/layout/images/layout-example-sideNav-light.png +0 -0
  12. package/constellation/layout/images/layout-example-topNav-1-dark.png +0 -0
  13. package/constellation/layout/images/layout-example-topNav-1-light.png +0 -0
  14. package/constellation/layout/images/layout-example-topNav-2-dark.png +0 -0
  15. package/constellation/layout/images/layout-example-topNav-2-light.png +0 -0
  16. package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.js +8 -1
  17. package/dist/cjs/ui/page-layout/panel.js +10 -3
  18. package/dist/cjs/ui/page-layout/root.js +3 -1
  19. package/dist/cjs/ui/page-layout/side-nav/bind-open-layer-change.js +56 -0
  20. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +166 -56
  21. package/dist/cjs/ui/page-layout/side-nav/toggle-button.js +8 -1
  22. package/dist/cjs/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +15 -1
  23. package/dist/cjs/ui/page-layout/top-nav/top-nav-end.js +3 -2
  24. package/dist/cjs/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  25. package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.js +8 -1
  26. package/dist/es2019/ui/page-layout/panel.js +10 -3
  27. package/dist/es2019/ui/page-layout/root.js +3 -1
  28. package/dist/es2019/ui/page-layout/side-nav/bind-open-layer-change.js +51 -0
  29. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +121 -8
  30. package/dist/es2019/ui/page-layout/side-nav/toggle-button.js +8 -1
  31. package/dist/es2019/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +15 -1
  32. package/dist/es2019/ui/page-layout/top-nav/top-nav-end.js +3 -2
  33. package/dist/es2019/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  34. package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.js +8 -1
  35. package/dist/esm/ui/page-layout/panel.js +10 -3
  36. package/dist/esm/ui/page-layout/root.js +3 -1
  37. package/dist/esm/ui/page-layout/side-nav/bind-open-layer-change.js +50 -0
  38. package/dist/esm/ui/page-layout/side-nav/side-nav.js +166 -56
  39. package/dist/esm/ui/page-layout/side-nav/toggle-button.js +8 -1
  40. package/dist/esm/ui/page-layout/side-nav/use-side-nav-toggle-keyboard-shortcut.js +15 -1
  41. package/dist/esm/ui/page-layout/top-nav/top-nav-end.js +3 -2
  42. package/dist/esm/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  43. package/dist/types/ui/page-layout/side-nav/bind-open-layer-change.d.ts +17 -0
  44. package/package.json +8 -8
@@ -18,6 +18,7 @@ import { fg } from '@atlaskit/platform-feature-flags/fg';
18
18
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element-adapter';
19
19
  // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- TODO: migrate to @atlaskit/primitives/compiled
20
20
 
21
+ import { hasOpenDialogOrPopover } from '@atlaskit/top-layer/page-surface/has-open-dialog-or-popover';
21
22
  import { useSkipLinkInternal } from '../../../context/skip-links/use-skip-link-internal';
22
23
  import { TopNavStartElement } from '../../../context/top-nav-start/top-nav-start-element';
23
24
  import { UNSAFE_sideNavLayoutVar, mainMinimumWidthVar, openLayerObserverSideNavNamespace, sideNavLiveWidthVar, sideNavPanelSplitterId, sideNavVar } from '../constants';
@@ -31,6 +32,7 @@ import { useLayoutAreaSizing } from '../use-layout-area-sizing';
31
32
  import { useLayoutId } from '../use-layout-id';
32
33
  import { useResizingWidthCssVarOnRootElement } from '../use-resizing-width-css-var-on-root-element';
33
34
  import { useSafeDefaultWidth } from '../use-safe-default-width';
35
+ import { bindOpenLayerChange } from './bind-open-layer-change';
34
36
  import { sideNavFlyoutCloseDelayMs } from './flyout-close-delay-ms';
35
37
  import { SetSideNavVisibilityState } from './set-side-nav-visibility-state';
36
38
  import { SideNavToggleButtonElement } from './side-nav-toggle-button-element';
@@ -57,6 +59,51 @@ function getPixelCustomProperty(element, propertyName, fallback) {
57
59
  * Avoiding nesting the `@supports` at-rule inside of `@media` means Compiled can remove duplicate styles from the generated CSS.
58
60
  */
59
61
  var isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
62
+ var textEntryInputTypes = new Set(['text', 'search', 'email', 'url', 'tel', 'password', 'number']);
63
+ function isEditableContent(_ref) {
64
+ var element = _ref.element;
65
+ if (element instanceof HTMLElement && typeof element.isContentEditable === 'boolean') {
66
+ return element.isContentEditable;
67
+ }
68
+ // Fallback for DOM implementations without `isContentEditable`.
69
+ var editingHost = element.closest('[contenteditable]');
70
+ return editingHost !== null && editingHost.getAttribute('contenteditable') !== 'false';
71
+ }
72
+
73
+ /**
74
+ * Returns `true` for an element that the user can type text into.
75
+ */
76
+ function isTextEntryElement(_ref2) {
77
+ var element = _ref2.element;
78
+ if (element instanceof HTMLInputElement) {
79
+ return textEntryInputTypes.has(element.type) && !element.readOnly && !element.disabled;
80
+ }
81
+ if (element instanceof HTMLTextAreaElement) {
82
+ return !element.readOnly && !element.disabled;
83
+ }
84
+ return isEditableContent({
85
+ element: element
86
+ });
87
+ }
88
+
89
+ /**
90
+ * Used when the `platform-dst-top-layer` gate is on.
91
+ *
92
+ * The flyout stays open while a layer opened from the side nav is open, or while the user
93
+ * is typing in a text field inside the side nav (for example while renaming an item inline).
94
+ */
95
+ function isFlyoutHeldOpen(_ref3) {
96
+ var nav = _ref3.nav;
97
+ if (hasOpenDialogOrPopover({
98
+ within: nav
99
+ })) {
100
+ return true;
101
+ }
102
+ var activeElement = nav.ownerDocument.activeElement;
103
+ return activeElement !== null && nav.contains(activeElement) && isTextEntryElement({
104
+ element: activeElement
105
+ });
106
+ }
60
107
  var styles = {
61
108
  root: "_191wglyw _t51zglyw _bfhk1bhr _16qs130s _vchhusvi _4t3ieqxy _152timx3 _kqsw1if8 _1bsb1ego _1pbycs5v _14b5hc79 _qilnk0mc _p5clia51 _4ap3vuon _scbpglyw _89fi1b6c",
62
109
  chatPanelSizing: "_1bsbhc79",
@@ -98,26 +145,26 @@ export var onPeekStartDelayMs = 500;
98
145
  * We need an additional component layer so we can wrap the side nav in a `OpenLayerObserver` and have access to the
99
146
  * context value.
100
147
  */
101
- function SideNavInternal(_ref) {
148
+ function SideNavInternal(_ref4) {
102
149
  var _managedSizing$mode, _managedSizing$width, _sideNavState$lastTri;
103
- var children = _ref.children,
104
- defaultCollapsed = _ref.defaultCollapsed,
105
- _ref$defaultWidth = _ref.defaultWidth,
106
- defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
107
- _ref$minWidth = _ref.minWidth,
108
- minWidth = _ref$minWidth === void 0 ? fallbackMinWidth : _ref$minWidth,
109
- maxWidth = _ref.maxWidth,
110
- testId = _ref.testId,
111
- _ref$label = _ref.label,
112
- label = _ref$label === void 0 ? 'Sidebar' : _ref$label,
113
- _ref$skipLinkLabel = _ref.skipLinkLabel,
114
- skipLinkLabel = _ref$skipLinkLabel === void 0 ? label : _ref$skipLinkLabel,
115
- onExpand = _ref.onExpand,
116
- onCollapse = _ref.onCollapse,
117
- onPeekStart = _ref.onPeekStart,
118
- onPeekEnd = _ref.onPeekEnd,
119
- providedId = _ref.id,
120
- canToggleWithShortcut = _ref.canToggleWithShortcut;
150
+ var children = _ref4.children,
151
+ defaultCollapsed = _ref4.defaultCollapsed,
152
+ _ref4$defaultWidth = _ref4.defaultWidth,
153
+ defaultWidthProp = _ref4$defaultWidth === void 0 ? fallbackDefaultWidth : _ref4$defaultWidth,
154
+ _ref4$minWidth = _ref4.minWidth,
155
+ minWidth = _ref4$minWidth === void 0 ? fallbackMinWidth : _ref4$minWidth,
156
+ maxWidth = _ref4.maxWidth,
157
+ testId = _ref4.testId,
158
+ _ref4$label = _ref4.label,
159
+ label = _ref4$label === void 0 ? 'Sidebar' : _ref4$label,
160
+ _ref4$skipLinkLabel = _ref4.skipLinkLabel,
161
+ skipLinkLabel = _ref4$skipLinkLabel === void 0 ? label : _ref4$skipLinkLabel,
162
+ onExpand = _ref4.onExpand,
163
+ onCollapse = _ref4.onCollapse,
164
+ onPeekStart = _ref4.onPeekStart,
165
+ onPeekEnd = _ref4.onPeekEnd,
166
+ providedId = _ref4.id,
167
+ canToggleWithShortcut = _ref4.canToggleWithShortcut;
121
168
  var isChatPanelLayoutEnabled = fg('platform-dst-chat-panel-layout');
122
169
  var id = useLayoutId({
123
170
  providedId: providedId
@@ -343,7 +390,9 @@ function SideNavInternal(_ref) {
343
390
  var toggleButtonElement = useContext(SideNavToggleButtonElement);
344
391
  var topNavStartElement = useContext(TopNavStartElement);
345
392
  var devTimeOnlyAttributes = {};
346
- var openLayerObserver = useOpenLayerObserver();
393
+ var openLayerObserver = useOpenLayerObserver({
394
+ isEnabled: !fg('platform-dst-top-layer')
395
+ });
347
396
  var flyoutStateRef = useRef({
348
397
  type: 'not-active'
349
398
  });
@@ -421,6 +470,17 @@ function SideNavInternal(_ref) {
421
470
  });
422
471
  }
423
472
  }
473
+ function canClose() {
474
+ if (!fg('platform-dst-top-layer')) {
475
+ return (openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.getCount({
476
+ namespace: openLayerObserverSideNavNamespace
477
+ })) === 0;
478
+ }
479
+ var nav = navRef.current;
480
+ return !(nav && isFlyoutHeldOpen({
481
+ nav: nav
482
+ }));
483
+ }
424
484
  return function onAction(action) {
425
485
  if (action === 'drag-from-flyout-started') {
426
486
  open();
@@ -462,9 +522,7 @@ function SideNavInternal(_ref) {
462
522
  }
463
523
  if (action === 'ready-to-close') {
464
524
  // If there are no open layers, we can close the flyout.
465
- if ((openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.getCount({
466
- namespace: openLayerObserverSideNavNamespace
467
- })) === 0) {
525
+ if (canClose()) {
468
526
  close();
469
527
  return;
470
528
  }
@@ -505,9 +563,9 @@ function SideNavInternal(_ref) {
505
563
  });
506
564
  });
507
565
  }, [initialDefaultCollapsed, setSideNavState, sideNavState]);
508
- var handleExpand = useCallback(function (_ref2) {
509
- var screen = _ref2.screen,
510
- trigger = _ref2.trigger;
566
+ var handleExpand = useCallback(function (_ref5) {
567
+ var screen = _ref5.screen,
568
+ trigger = _ref5.trigger;
511
569
  onExpand === null || onExpand === void 0 || onExpand({
512
570
  screen: screen,
513
571
  trigger: trigger
@@ -527,9 +585,9 @@ function SideNavInternal(_ref) {
527
585
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to expand.
528
586
  updateFlyoutState('force-close');
529
587
  }, [onExpand, updateFlyoutState, createAnalyticsEvent]);
530
- var handleCollapse = useCallback(function (_ref3) {
531
- var screen = _ref3.screen,
532
- trigger = _ref3.trigger;
588
+ var handleCollapse = useCallback(function (_ref6) {
589
+ var screen = _ref6.screen,
590
+ trigger = _ref6.trigger;
533
591
  onCollapse === null || onCollapse === void 0 || onCollapse({
534
592
  screen: screen,
535
593
  trigger: trigger
@@ -722,15 +780,15 @@ function SideNavInternal(_ref) {
722
780
  // we are just interested in listening to events within an element
723
781
  // - We do not want to impact `location.{*}.dropTargets` in events
724
782
  return monitorForElements({
725
- canMonitor: function canMonitor(_ref4) {
726
- var source = _ref4.source;
783
+ canMonitor: function canMonitor(_ref7) {
784
+ var source = _ref7.source;
727
785
  return nav.contains(source.element);
728
786
  },
729
787
  onGenerateDragPreview: function onGenerateDragPreview() {
730
788
  updateFlyoutState('drag-from-flyout-started');
731
789
  },
732
- onDrop: function onDrop(_ref5) {
733
- var location = _ref5.location;
790
+ onDrop: function onDrop(_ref8) {
791
+ var location = _ref8.location;
734
792
  // Always marking the drag and done
735
793
  updateFlyoutState('drag-from-flyout-finished');
736
794
 
@@ -791,8 +849,8 @@ function SideNavInternal(_ref) {
791
849
  // Close the flyout if there are no more layers open and the user is not mousing over the
792
850
  // flyout areas (side nav, TopNavStart element)
793
851
 
794
- return openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.onChange(function (_ref6) {
795
- var count = _ref6.count;
852
+ return openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.onChange(function (_ref9) {
853
+ var count = _ref9.count;
796
854
  if (flyoutStateRef.current.type === 'ready-to-close' && count === 0) {
797
855
  updateFlyoutState('force-close');
798
856
  }
@@ -800,6 +858,52 @@ function SideNavInternal(_ref) {
800
858
  namespace: openLayerObserverSideNavNamespace
801
859
  });
802
860
  }, [openLayerObserver, updateFlyoutState]);
861
+ var focusOutTimeoutIdRef = useRef(undefined);
862
+ useEffect(function () {
863
+ // The same as the open layer observer `onChange` above, for when the `platform-dst-top-layer`
864
+ // gate is on. Top-layer surfaces opened from the side nav are DOM descendants of it.
865
+ var nav = navRef.current;
866
+ if (!nav || !fg('platform-dst-top-layer')) {
867
+ return;
868
+ }
869
+ function closeIfReady() {
870
+ if (flyoutStateRef.current.type !== 'ready-to-close' || !nav) {
871
+ return;
872
+ }
873
+ if (isFlyoutHeldOpen({
874
+ nav: nav
875
+ })) {
876
+ return;
877
+ }
878
+ updateFlyoutState('force-close');
879
+ }
880
+ var unbindLayerChange = bindOpenLayerChange({
881
+ within: nav,
882
+ onChange: closeIfReady
883
+ });
884
+ var unbindFocusOut = bind(nav, {
885
+ type: 'focusout',
886
+ listener: function listener() {
887
+ // Wait for focus to move before checking where it went.
888
+ clearTimeout(focusOutTimeoutIdRef.current);
889
+ focusOutTimeoutIdRef.current = setTimeout(closeIfReady, 0);
890
+ }
891
+ });
892
+
893
+ // Removing the focused text field (for example when an inline rename ends) fires no
894
+ // `focusout` in some browsers, so also check again when content inside the side nav changes.
895
+ var removalObserver = new MutationObserver(closeIfReady);
896
+ removalObserver.observe(nav, {
897
+ childList: true,
898
+ subtree: true
899
+ });
900
+ return function cleanup() {
901
+ unbindLayerChange();
902
+ unbindFocusOut();
903
+ removalObserver.disconnect();
904
+ clearTimeout(focusOutTimeoutIdRef.current);
905
+ };
906
+ }, [updateFlyoutState]);
803
907
  useEffect(function () {
804
908
  // Clear flyout close timer if being unmounted
805
909
  return function cleanupPendingFlyoutClose() {
@@ -936,26 +1040,24 @@ function SideNavInternal(_ref) {
936
1040
  *
937
1041
  * You can optionally render a `PanelSplitter` as a child to make the side navigation slot resizable.
938
1042
  */
939
- export function SideNav(_ref8) {
940
- var children = _ref8.children,
941
- defaultCollapsed = _ref8.defaultCollapsed,
942
- _ref8$defaultWidth = _ref8.defaultWidth,
943
- defaultWidth = _ref8$defaultWidth === void 0 ? 320 : _ref8$defaultWidth,
944
- minWidth = _ref8.minWidth,
945
- maxWidth = _ref8.maxWidth,
946
- testId = _ref8.testId,
947
- label = _ref8.label,
948
- _ref8$skipLinkLabel = _ref8.skipLinkLabel,
949
- skipLinkLabel = _ref8$skipLinkLabel === void 0 ? label : _ref8$skipLinkLabel,
950
- onExpand = _ref8.onExpand,
951
- onCollapse = _ref8.onCollapse,
952
- onPeekStart = _ref8.onPeekStart,
953
- onPeekEnd = _ref8.onPeekEnd,
954
- canToggleWithShortcut = _ref8.canToggleWithShortcut,
955
- id = _ref8.id;
956
- return /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
957
- namespace: openLayerObserverSideNavNamespace
958
- }, /*#__PURE__*/React.createElement(SideNavInternal, {
1043
+ export function SideNav(_ref1) {
1044
+ var children = _ref1.children,
1045
+ defaultCollapsed = _ref1.defaultCollapsed,
1046
+ _ref1$defaultWidth = _ref1.defaultWidth,
1047
+ defaultWidth = _ref1$defaultWidth === void 0 ? 320 : _ref1$defaultWidth,
1048
+ minWidth = _ref1.minWidth,
1049
+ maxWidth = _ref1.maxWidth,
1050
+ testId = _ref1.testId,
1051
+ label = _ref1.label,
1052
+ _ref1$skipLinkLabel = _ref1.skipLinkLabel,
1053
+ skipLinkLabel = _ref1$skipLinkLabel === void 0 ? label : _ref1$skipLinkLabel,
1054
+ onExpand = _ref1.onExpand,
1055
+ onCollapse = _ref1.onCollapse,
1056
+ onPeekStart = _ref1.onPeekStart,
1057
+ onPeekEnd = _ref1.onPeekEnd,
1058
+ canToggleWithShortcut = _ref1.canToggleWithShortcut,
1059
+ id = _ref1.id;
1060
+ var sideNav = /*#__PURE__*/React.createElement(SideNavInternal, {
959
1061
  defaultCollapsed: defaultCollapsed,
960
1062
  defaultWidth: defaultWidth,
961
1063
  minWidth: minWidth,
@@ -969,5 +1071,13 @@ export function SideNav(_ref8) {
969
1071
  onPeekEnd: onPeekEnd,
970
1072
  id: id,
971
1073
  canToggleWithShortcut: canToggleWithShortcut
972
- }, children));
1074
+ }, children);
1075
+
1076
+ // Top-layer surfaces are found through the DOM, so the namespace is only needed when the gate is off.
1077
+ if (fg('platform-dst-top-layer')) {
1078
+ return sideNav;
1079
+ }
1080
+ return /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
1081
+ namespace: openLayerObserverSideNavNamespace
1082
+ }, sideNav);
973
1083
  }
@@ -11,6 +11,8 @@ import { useAnalyticsEvents } from '@atlaskit/analytics-next/useAnalyticsEvents'
11
11
  import SidebarCollapseIcon from '@atlaskit/icon/core/sidebar-collapse';
12
12
  import SidebarExpandIcon from '@atlaskit/icon/core/sidebar-expand';
13
13
  import { useOpenLayerObserver } from '@atlaskit/layering/use-open-layer-observer';
14
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
15
+ import { requestClosePopovers } from '@atlaskit/top-layer/page-surface/request-close-popovers';
14
16
  import { IconButton } from '../../top-nav-items/themed/icon-button';
15
17
  import { SideNavToggleButtonAttachRef } from './side-nav-toggle-button-attach-ref';
16
18
  import { sideNavToggleTooltipKeyboardShortcut } from './side-nav-toggle-tooltip-keyboard-shortcut';
@@ -93,12 +95,17 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
93
95
  });
94
96
  var _useAnalyticsEvents = useAnalyticsEvents(),
95
97
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
96
- var openLayerObserver = useOpenLayerObserver();
98
+ var openLayerObserver = useOpenLayerObserver({
99
+ isEnabled: !fg('platform-dst-top-layer')
100
+ });
97
101
  var handleClick = useCallback(function (event, analyticsEvent) {
98
102
  onClick === null || onClick === void 0 || onClick(event, analyticsEvent, {
99
103
  isSideNavVisible: isSideNavExpanded
100
104
  });
101
105
  toggleVisibility();
106
+
107
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
108
+ requestClosePopovers();
102
109
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
103
110
  }, [isSideNavExpanded, onClick, openLayerObserver, toggleVisibility]);
104
111
  var handlePointerEnter = useCallback(function () {
@@ -2,6 +2,9 @@ import { useEffect } from 'react';
2
2
  import { bind } from 'bind-event-listener';
3
3
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
4
4
  import { useOpenLayerObserver } from '@atlaskit/layering/use-open-layer-observer';
5
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
+ import { hasOpenDialogOrPopover } from '@atlaskit/top-layer/page-surface/has-open-dialog-or-popover';
7
+ import { requestClosePopovers } from '@atlaskit/top-layer/page-surface/request-close-popovers';
5
8
  import { useIsSideNavShortcutEnabled } from './use-is-side-nav-shortcut-enabled';
6
9
  import { useToggleSideNav } from './use-toggle-side-nav';
7
10
 
@@ -10,7 +13,9 @@ import { useToggleSideNav } from './use-toggle-side-nav';
10
13
  */
11
14
  export function useSideNavToggleKeyboardShortcut(_ref) {
12
15
  var canToggleWithShortcut = _ref.canToggleWithShortcut;
13
- var openLayerObserver = useOpenLayerObserver();
16
+ var openLayerObserver = useOpenLayerObserver({
17
+ isEnabled: !fg('platform-dst-top-layer')
18
+ });
14
19
  var toggleVisibilityByShortcut = useToggleSideNav({
15
20
  trigger: 'keyboard'
16
21
  });
@@ -33,12 +38,21 @@ export function useSideNavToggleKeyboardShortcut(_ref) {
33
38
  // Ignore repeated keydown events from holding down the keys
34
39
  return;
35
40
  }
41
+ if (fg('platform-dst-top-layer') && hasOpenDialogOrPopover({
42
+ type: 'modal'
43
+ })) {
44
+ // Return early if there are any open modal dialogs
45
+ return;
46
+ }
36
47
  if (openLayerObserver && openLayerObserver.getCount({
37
48
  type: 'modal'
38
49
  }) > 0) {
39
50
  // Return early if there are any open modals
40
51
  return;
41
52
  }
53
+
54
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
55
+ requestClosePopovers();
42
56
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
43
57
  toggleVisibilityByShortcut();
44
58
  }
@@ -66,7 +66,8 @@ export function TopNavEnd(_ref) {
66
66
 
67
67
  // The shared provider also covers the mobile overflow popup itself. Keep the
68
68
  // previous content-only namespace coverage when the layout gate is disabled.
69
- var actions = fg('platform-dst-chat-panel-layout') ? children : /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
69
+ // The observer is not used when the top-layer gate is on, so no provider is needed.
70
+ var actions = fg('platform-dst-chat-panel-layout') || fg('platform-dst-top-layer') ? children : /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
70
71
  namespace: openLayerObserverTopNavEndNamespace
71
72
  }, children);
72
73
  var content = /*#__PURE__*/React.createElement("nav", {
@@ -104,7 +105,7 @@ export function TopNavEnd(_ref) {
104
105
  }) : /*#__PURE__*/React.createElement(List, {
105
106
  xcss: cx(listStyles.root, listStyles.hideOnSmallViewport)
106
107
  }, actions), hasPersistentItems && persistentItems);
107
- return fg('platform-dst-chat-panel-layout') ? /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
108
+ return fg('platform-dst-chat-panel-layout') && !fg('platform-dst-top-layer') ? /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
108
109
  namespace: openLayerObserverTopNavEndNamespace
109
110
  }, content) : content;
110
111
  }
@@ -3,6 +3,7 @@ import "./top-nav-middle.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React from 'react';
5
5
  import { OpenLayerObserverNamespaceProvider } from '@atlaskit/layering/open-layer-observer-namespace-provider';
6
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
7
  import { openLayerObserverTopNavMiddleNamespace } from '../constants';
7
8
  var styles = {
8
9
  root: "_zulpu2gc _yyhycs5v _1bsb1osq _4cvr1h6o _1e0c1txw _1bahh9n0 _181n11p5 _1j8b15b0 _lagd1bp4 _1t4c1ris _12e8h9n0"
@@ -20,7 +21,7 @@ export function TopNavMiddle(_ref) {
20
21
  var children = _ref.children;
21
22
  return /*#__PURE__*/React.createElement("div", {
22
23
  className: ax([styles.root])
23
- }, /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
24
+ }, fg('platform-dst-top-layer') ? children : /*#__PURE__*/React.createElement(OpenLayerObserverNamespaceProvider, {
24
25
  namespace: openLayerObserverTopNavMiddleNamespace
25
26
  }, children));
26
27
  }
@@ -0,0 +1,17 @@
1
+ type TCleanupFn = () => void;
2
+ /**
3
+ * Calls `onChange` after any popover or dialog inside `within` opens or closes.
4
+ * Read the new state with `hasOpenDialogOrPopover`.
5
+ *
6
+ * `beforetoggle`, `toggle` and `close` do not bubble, so they are observed in the capture phase.
7
+ *
8
+ * `toggle` and `close` are queued tasks. When a surface closes because it unmounts,
9
+ * they fire after the element has left the DOM, so they never reach `within`.
10
+ * `beforetoggle` fires synchronously while the element is still inside `within`,
11
+ * so it also schedules `onChange` in a microtask, after the state has changed.
12
+ */
13
+ export declare function bindOpenLayerChange({ within, onChange, }: {
14
+ within: Element | Document;
15
+ onChange: () => void;
16
+ }): TCleanupFn;
17
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/navigation-system",
3
- "version": "11.3.2",
3
+ "version": "11.3.4",
4
4
  "description": "The latest navigation system for Atlassian apps.",
5
5
  "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
6
6
  "license": "Apache-2.0",
@@ -58,13 +58,13 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@atlaskit/analytics-next": "^12.6.0",
61
- "@atlaskit/app-provider": "^8.1.0",
61
+ "@atlaskit/app-provider": "^8.2.0",
62
62
  "@atlaskit/avatar": "^30.0.0",
63
- "@atlaskit/button": "^25.5.0",
63
+ "@atlaskit/button": "^25.6.0",
64
64
  "@atlaskit/css": "^1.1.0",
65
65
  "@atlaskit/ds-lib": "^8.0.0",
66
66
  "@atlaskit/icon": "^38.0.0",
67
- "@atlaskit/layering": "^6.0.0",
67
+ "@atlaskit/layering": "^6.1.0",
68
68
  "@atlaskit/logo": "^23.3.0",
69
69
  "@atlaskit/motion": "^9.4.0",
70
70
  "@atlaskit/platform-feature-flags": "^2.2.0",
@@ -73,9 +73,10 @@
73
73
  "@atlaskit/pragmatic-drag-and-drop": "^4.0.0",
74
74
  "@atlaskit/primitives": "^22.6.0",
75
75
  "@atlaskit/react-compiler-gating": "^0.2.0",
76
- "@atlaskit/side-nav-items": "^2.5.0",
76
+ "@atlaskit/side-nav-items": "^2.6.0",
77
77
  "@atlaskit/tokens": "^20.6.0",
78
78
  "@atlaskit/tooltip": "^24.4.0",
79
+ "@atlaskit/top-layer": "^6.6.0",
79
80
  "@atlaskit/visually-hidden": "^4.4.0",
80
81
  "@babel/runtime": "^7.0.0",
81
82
  "@compiled/react": "^1.0.2",
@@ -123,13 +124,12 @@
123
124
  "@atlaskit/tag": "^17.0.0",
124
125
  "@atlaskit/textarea": "^10.2.0",
125
126
  "@atlaskit/textfield": "^10.2.0",
126
- "@atlaskit/top-layer": "^6.3.0",
127
127
  "@atlassian/feature-flags-test-utils": "^1.3.0",
128
128
  "@atlassian/gemini": "^1.54.0",
129
- "@atlassian/panel-system": "^1.14.0",
129
+ "@atlassian/panel-system": "^1.15.0",
130
130
  "@atlassian/react-async": "^0.23.0",
131
131
  "@atlassian/react-entrypoint": "^1.1.0",
132
- "@atlassian/search-dialog": "^10.22.0",
132
+ "@atlassian/search-dialog": "^10.23.0",
133
133
  "@atlassian/ssr-tests": "workspace:^",
134
134
  "@atlassian/test-utils": "^1.1.0",
135
135
  "@atlassian/testing-library": "^0.12.0",