@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @atlassian/navigation-system
2
2
 
3
+ ## 11.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0cc2e73141eea`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0cc2e73141eea) -
8
+ Behind the `platform-dst-top-layer` feature gate, no longer uses `@atlaskit/layering`. Open
9
+ overlays are found with the `@atlaskit/top-layer/page-surface` entry points instead
10
+ (`platform-dst-top-layer-tooltip` for tooltip). Behaviour with the gate off is unchanged.
11
+ - Updated dependencies
12
+
13
+ ## 11.3.3
14
+
15
+ ### Patch Changes
16
+
17
+ - [`7ddc892892fda`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7ddc892892fda) -
18
+ Gate panel content-switch motion behind platform-dst-motion-uplift-panel-content independently of
19
+ panel open/close motion, and retain the navigation panel motion boundary when its content key is
20
+ cleared.
21
+ - Updated dependencies
22
+
3
23
  ## 11.3.2
4
24
 
5
25
  ### Patch Changes
@@ -31,6 +31,7 @@ var _disableNativeDragPreview = require("@atlaskit/pragmatic-drag-and-drop/utils
31
31
  var _preventUnhandled = require("@atlaskit/pragmatic-drag-and-drop/utils/prevent-unhandled");
32
32
  var _Tooltip = _interopRequireDefault(require("@atlaskit/tooltip/Tooltip"));
33
33
  var _TooltipContainer = _interopRequireDefault(require("@atlaskit/tooltip/TooltipContainer"));
34
+ var _requestClosePopovers = require("@atlaskit/top-layer/page-surface/request-close-popovers");
34
35
  var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden/visually-hidden"));
35
36
  var _constants = require("../constants");
36
37
  var _convertResizeBoundToPixels = require("./convert-resize-bound-to-pixels");
@@ -177,7 +178,9 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
177
178
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
178
179
  rangeInputBounds = _useState4[0],
179
180
  setRangeInputBounds = _useState4[1];
180
- var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)();
181
+ var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)({
182
+ isEnabled: !(0, _fg.fg)('platform-dst-top-layer')
183
+ });
181
184
 
182
185
  /**
183
186
  * This is a temporary workaround to enable the `SideNavPanelSplitter` component
@@ -268,6 +271,8 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
268
271
  onResizeStart === null || onResizeStart === void 0 || onResizeStart(resizeStartData);
269
272
 
270
273
  // Close any open layers when the user starts resizing
274
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
275
+ (0, _requestClosePopovers.requestClosePopovers)();
271
276
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
272
277
  },
273
278
  onDrag: function onDrag(_ref6) {
@@ -383,6 +388,8 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
383
388
  onResizeStart: function onResizeStart() {
384
389
  var _onResizeStartStableR;
385
390
  // Close any open layers when the user starts resizing with keyboard
391
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
392
+ (0, _requestClosePopovers.requestClosePopovers)();
386
393
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
387
394
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
388
395
  args[_key] = arguments[_key];
@@ -88,6 +88,13 @@ function Panel(_ref2) {
88
88
  providedId: providedId
89
89
  });
90
90
  var isMotionUpliftEnabled = (0, _fg.fg)('platform-dst-motion-uplift-panel');
91
+ var isContentMotionEnabled = (0, _fg.fg)('platform-dst-motion-uplift-panel-content');
92
+ var prevContentKeyRef = (0, _react.useRef)(contentKey);
93
+ (0, _react.useEffect)(function () {
94
+ if (isContentMotionEnabled && contentKey !== undefined) {
95
+ prevContentKeyRef.current = contentKey;
96
+ }
97
+ }, [contentKey, isContentMotionEnabled]);
91
98
  var defaultWidth = (0, _useSafeDefaultWidth.useSafeDefaultWidth)({
92
99
  defaultWidthProp: defaultWidthProp,
93
100
  fallbackDefaultWidth: fallbackDefaultWidth,
@@ -238,9 +245,9 @@ function Panel(_ref2) {
238
245
  position: "start"
239
246
  }, /*#__PURE__*/React.createElement("div", {
240
247
  className: (0, _runtime.ax)([styles.scrollContainer, isMotionUpliftEnabled && state === 'entering' && styles.contentEntering, isMotionUpliftEnabled && state === 'exiting' && styles.contentExiting])
241
- }, isMotionUpliftEnabled && contentKey !== undefined ? /*#__PURE__*/React.createElement(_exitingPersistence.default, {
242
- exitThenEnter: true
248
+ }, isContentMotionEnabled ? /*#__PURE__*/React.createElement(_exitingPersistence.default, {
249
+ exitThenEnter: contentKey !== undefined
243
250
  }, /*#__PURE__*/React.createElement(PanelContentMotion, {
244
- key: contentKey
251
+ key: contentKey === undefined ? prevContentKeyRef.current : contentKey
245
252
  }, children)) : children)));
246
253
  }
@@ -77,6 +77,8 @@ function Root(_ref2) {
77
77
  var isChatPanelLayoutEnabled = (0, _fg.fg)('platform-dst-chat-panel-layout');
78
78
  var LayoutProvider = isChatPanelLayoutEnabled ? _layoutAreaSizingProvider.LayoutAreaSizingProvider : _react.default.Fragment;
79
79
  var WidthContainer = isChatPanelLayoutEnabled ? LayoutFitContainers : _react.default.Fragment;
80
+ // Top-layer surfaces are found through the DOM, so the observer is only needed when the gate is off.
81
+ var LayerObserverProvider = (0, _fg.fg)('platform-dst-top-layer') ? _react.default.Fragment : _openLayerObserver.OpenLayerObserver;
80
82
  (0, _react.useEffect)(function () {
81
83
  if (process.env.NODE_ENV !== 'production') {
82
84
  var IGNORED_ELEMENTS = ['SCRIPT', 'STYLE'];
@@ -99,7 +101,7 @@ function Root(_ref2) {
99
101
  isSideNavShortcutEnabled: isSideNavShortcutEnabled
100
102
  }, /*#__PURE__*/_react.default.createElement(_topNavStartContextProvider.TopNavStartProvider, null, /*#__PURE__*/_react.default.createElement(LayoutProvider, isChatPanelLayoutEnabled ? {
101
103
  layoutRef: ref
102
- } : {}, /*#__PURE__*/_react.default.createElement(_openLayerObserver.OpenLayerObserver, null, /*#__PURE__*/_react.default.createElement(_hoistSlotSizesContext.DangerouslyHoistSlotSizes.Provider, {
104
+ } : {}, /*#__PURE__*/_react.default.createElement(LayerObserverProvider, null, /*#__PURE__*/_react.default.createElement(_hoistSlotSizesContext.DangerouslyHoistSlotSizes.Provider, {
103
105
  value: UNSAFE_dangerouslyHoistSlotSizes
104
106
  }, /*#__PURE__*/_react.default.createElement(_skipLinksProvider.SkipLinksProvider, {
105
107
  label: skipLinksLabel,
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.bindOpenLayerChange = bindOpenLayerChange;
7
+ var _bindEventListener = require("bind-event-listener");
8
+ /**
9
+ * Calls `onChange` after any popover or dialog inside `within` opens or closes.
10
+ * Read the new state with `hasOpenDialogOrPopover`.
11
+ *
12
+ * `beforetoggle`, `toggle` and `close` do not bubble, so they are observed in the capture phase.
13
+ *
14
+ * `toggle` and `close` are queued tasks. When a surface closes because it unmounts,
15
+ * they fire after the element has left the DOM, so they never reach `within`.
16
+ * `beforetoggle` fires synchronously while the element is still inside `within`,
17
+ * so it also schedules `onChange` in a microtask, after the state has changed.
18
+ */
19
+ function bindOpenLayerChange(_ref) {
20
+ var within = _ref.within,
21
+ onChange = _ref.onChange;
22
+ var isBound = true;
23
+ function listener() {
24
+ onChange();
25
+ }
26
+ function deferredListener() {
27
+ queueMicrotask(function () {
28
+ if (isBound) {
29
+ onChange();
30
+ }
31
+ });
32
+ }
33
+ var unbind = (0, _bindEventListener.bindAll)(within, [{
34
+ type: 'beforetoggle',
35
+ listener: deferredListener,
36
+ options: {
37
+ capture: true
38
+ }
39
+ }, {
40
+ type: 'toggle',
41
+ listener: listener,
42
+ options: {
43
+ capture: true
44
+ }
45
+ }, {
46
+ type: 'close',
47
+ listener: listener,
48
+ options: {
49
+ capture: true
50
+ }
51
+ }]);
52
+ return function cleanup() {
53
+ isBound = false;
54
+ unbind();
55
+ };
56
+ }
@@ -23,6 +23,7 @@ var _openLayerObserverNamespaceProvider = require("@atlaskit/layering/open-layer
23
23
  var _useOpenLayerObserver = require("@atlaskit/layering/use-open-layer-observer");
24
24
  var _fg = require("@atlaskit/platform-feature-flags/fg");
25
25
  var _elementAdapter = require("@atlaskit/pragmatic-drag-and-drop/adapter/element-adapter");
26
+ var _hasOpenDialogOrPopover = require("@atlaskit/top-layer/page-surface/has-open-dialog-or-popover");
26
27
  var _useSkipLinkInternal = require("../../../context/skip-links/use-skip-link-internal");
27
28
  var _topNavStartElement = require("../../../context/top-nav-start/top-nav-start-element");
28
29
  var _constants = require("../constants");
@@ -36,6 +37,7 @@ var _useLayoutAreaSizing2 = require("../use-layout-area-sizing");
36
37
  var _useLayoutId = require("../use-layout-id");
37
38
  var _useResizingWidthCssVarOnRootElement = require("../use-resizing-width-css-var-on-root-element");
38
39
  var _useSafeDefaultWidth = require("../use-safe-default-width");
40
+ var _bindOpenLayerChange = require("./bind-open-layer-change");
39
41
  var _flyoutCloseDelayMs = require("./flyout-close-delay-ms");
40
42
  var _setSideNavVisibilityState = require("./set-side-nav-visibility-state");
41
43
  var _sideNavToggleButtonElement = require("./side-nav-toggle-button-element");
@@ -65,6 +67,51 @@ function getPixelCustomProperty(element, propertyName, fallback) {
65
67
  * Avoiding nesting the `@supports` at-rule inside of `@media` means Compiled can remove duplicate styles from the generated CSS.
66
68
  */
67
69
  var isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
70
+ var textEntryInputTypes = new Set(['text', 'search', 'email', 'url', 'tel', 'password', 'number']);
71
+ function isEditableContent(_ref) {
72
+ var element = _ref.element;
73
+ if (element instanceof HTMLElement && typeof element.isContentEditable === 'boolean') {
74
+ return element.isContentEditable;
75
+ }
76
+ // Fallback for DOM implementations without `isContentEditable`.
77
+ var editingHost = element.closest('[contenteditable]');
78
+ return editingHost !== null && editingHost.getAttribute('contenteditable') !== 'false';
79
+ }
80
+
81
+ /**
82
+ * Returns `true` for an element that the user can type text into.
83
+ */
84
+ function isTextEntryElement(_ref2) {
85
+ var element = _ref2.element;
86
+ if (element instanceof HTMLInputElement) {
87
+ return textEntryInputTypes.has(element.type) && !element.readOnly && !element.disabled;
88
+ }
89
+ if (element instanceof HTMLTextAreaElement) {
90
+ return !element.readOnly && !element.disabled;
91
+ }
92
+ return isEditableContent({
93
+ element: element
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Used when the `platform-dst-top-layer` gate is on.
99
+ *
100
+ * The flyout stays open while a layer opened from the side nav is open, or while the user
101
+ * is typing in a text field inside the side nav (for example while renaming an item inline).
102
+ */
103
+ function isFlyoutHeldOpen(_ref3) {
104
+ var nav = _ref3.nav;
105
+ if ((0, _hasOpenDialogOrPopover.hasOpenDialogOrPopover)({
106
+ within: nav
107
+ })) {
108
+ return true;
109
+ }
110
+ var activeElement = nav.ownerDocument.activeElement;
111
+ return activeElement !== null && nav.contains(activeElement) && isTextEntryElement({
112
+ element: activeElement
113
+ });
114
+ }
68
115
  var styles = {
69
116
  root: "_191wglyw _t51zglyw _bfhk1bhr _16qs130s _vchhusvi _4t3ieqxy _152timx3 _kqsw1if8 _1bsb1ego _1pbycs5v _14b5hc79 _qilnk0mc _p5clia51 _4ap3vuon _scbpglyw _89fi1b6c",
70
117
  chatPanelSizing: "_1bsbhc79",
@@ -106,26 +153,26 @@ var onPeekStartDelayMs = exports.onPeekStartDelayMs = 500;
106
153
  * We need an additional component layer so we can wrap the side nav in a `OpenLayerObserver` and have access to the
107
154
  * context value.
108
155
  */
109
- function SideNavInternal(_ref) {
156
+ function SideNavInternal(_ref4) {
110
157
  var _managedSizing$mode, _managedSizing$width, _sideNavState$lastTri;
111
- var children = _ref.children,
112
- defaultCollapsed = _ref.defaultCollapsed,
113
- _ref$defaultWidth = _ref.defaultWidth,
114
- defaultWidthProp = _ref$defaultWidth === void 0 ? fallbackDefaultWidth : _ref$defaultWidth,
115
- _ref$minWidth = _ref.minWidth,
116
- minWidth = _ref$minWidth === void 0 ? fallbackMinWidth : _ref$minWidth,
117
- maxWidth = _ref.maxWidth,
118
- testId = _ref.testId,
119
- _ref$label = _ref.label,
120
- label = _ref$label === void 0 ? 'Sidebar' : _ref$label,
121
- _ref$skipLinkLabel = _ref.skipLinkLabel,
122
- skipLinkLabel = _ref$skipLinkLabel === void 0 ? label : _ref$skipLinkLabel,
123
- onExpand = _ref.onExpand,
124
- onCollapse = _ref.onCollapse,
125
- onPeekStart = _ref.onPeekStart,
126
- onPeekEnd = _ref.onPeekEnd,
127
- providedId = _ref.id,
128
- canToggleWithShortcut = _ref.canToggleWithShortcut;
158
+ var children = _ref4.children,
159
+ defaultCollapsed = _ref4.defaultCollapsed,
160
+ _ref4$defaultWidth = _ref4.defaultWidth,
161
+ defaultWidthProp = _ref4$defaultWidth === void 0 ? fallbackDefaultWidth : _ref4$defaultWidth,
162
+ _ref4$minWidth = _ref4.minWidth,
163
+ minWidth = _ref4$minWidth === void 0 ? fallbackMinWidth : _ref4$minWidth,
164
+ maxWidth = _ref4.maxWidth,
165
+ testId = _ref4.testId,
166
+ _ref4$label = _ref4.label,
167
+ label = _ref4$label === void 0 ? 'Sidebar' : _ref4$label,
168
+ _ref4$skipLinkLabel = _ref4.skipLinkLabel,
169
+ skipLinkLabel = _ref4$skipLinkLabel === void 0 ? label : _ref4$skipLinkLabel,
170
+ onExpand = _ref4.onExpand,
171
+ onCollapse = _ref4.onCollapse,
172
+ onPeekStart = _ref4.onPeekStart,
173
+ onPeekEnd = _ref4.onPeekEnd,
174
+ providedId = _ref4.id,
175
+ canToggleWithShortcut = _ref4.canToggleWithShortcut;
129
176
  var isChatPanelLayoutEnabled = (0, _fg.fg)('platform-dst-chat-panel-layout');
130
177
  var id = (0, _useLayoutId.useLayoutId)({
131
178
  providedId: providedId
@@ -351,7 +398,9 @@ function SideNavInternal(_ref) {
351
398
  var toggleButtonElement = (0, _react.useContext)(_sideNavToggleButtonElement.SideNavToggleButtonElement);
352
399
  var topNavStartElement = (0, _react.useContext)(_topNavStartElement.TopNavStartElement);
353
400
  var devTimeOnlyAttributes = {};
354
- var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)();
401
+ var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)({
402
+ isEnabled: !(0, _fg.fg)('platform-dst-top-layer')
403
+ });
355
404
  var flyoutStateRef = (0, _react.useRef)({
356
405
  type: 'not-active'
357
406
  });
@@ -429,6 +478,17 @@ function SideNavInternal(_ref) {
429
478
  });
430
479
  }
431
480
  }
481
+ function canClose() {
482
+ if (!(0, _fg.fg)('platform-dst-top-layer')) {
483
+ return (openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.getCount({
484
+ namespace: _constants.openLayerObserverSideNavNamespace
485
+ })) === 0;
486
+ }
487
+ var nav = navRef.current;
488
+ return !(nav && isFlyoutHeldOpen({
489
+ nav: nav
490
+ }));
491
+ }
432
492
  return function onAction(action) {
433
493
  if (action === 'drag-from-flyout-started') {
434
494
  open();
@@ -470,9 +530,7 @@ function SideNavInternal(_ref) {
470
530
  }
471
531
  if (action === 'ready-to-close') {
472
532
  // If there are no open layers, we can close the flyout.
473
- if ((openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.getCount({
474
- namespace: _constants.openLayerObserverSideNavNamespace
475
- })) === 0) {
533
+ if (canClose()) {
476
534
  close();
477
535
  return;
478
536
  }
@@ -513,9 +571,9 @@ function SideNavInternal(_ref) {
513
571
  });
514
572
  });
515
573
  }, [initialDefaultCollapsed, setSideNavState, sideNavState]);
516
- var handleExpand = (0, _react.useCallback)(function (_ref2) {
517
- var screen = _ref2.screen,
518
- trigger = _ref2.trigger;
574
+ var handleExpand = (0, _react.useCallback)(function (_ref5) {
575
+ var screen = _ref5.screen,
576
+ trigger = _ref5.trigger;
519
577
  onExpand === null || onExpand === void 0 || onExpand({
520
578
  screen: screen,
521
579
  trigger: trigger
@@ -535,9 +593,9 @@ function SideNavInternal(_ref) {
535
593
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to expand.
536
594
  updateFlyoutState('force-close');
537
595
  }, [onExpand, updateFlyoutState, createAnalyticsEvent]);
538
- var handleCollapse = (0, _react.useCallback)(function (_ref3) {
539
- var screen = _ref3.screen,
540
- trigger = _ref3.trigger;
596
+ var handleCollapse = (0, _react.useCallback)(function (_ref6) {
597
+ var screen = _ref6.screen,
598
+ trigger = _ref6.trigger;
541
599
  onCollapse === null || onCollapse === void 0 || onCollapse({
542
600
  screen: screen,
543
601
  trigger: trigger
@@ -730,15 +788,15 @@ function SideNavInternal(_ref) {
730
788
  // we are just interested in listening to events within an element
731
789
  // - We do not want to impact `location.{*}.dropTargets` in events
732
790
  return (0, _elementAdapter.monitorForElements)({
733
- canMonitor: function canMonitor(_ref4) {
734
- var source = _ref4.source;
791
+ canMonitor: function canMonitor(_ref7) {
792
+ var source = _ref7.source;
735
793
  return nav.contains(source.element);
736
794
  },
737
795
  onGenerateDragPreview: function onGenerateDragPreview() {
738
796
  updateFlyoutState('drag-from-flyout-started');
739
797
  },
740
- onDrop: function onDrop(_ref5) {
741
- var location = _ref5.location;
798
+ onDrop: function onDrop(_ref8) {
799
+ var location = _ref8.location;
742
800
  // Always marking the drag and done
743
801
  updateFlyoutState('drag-from-flyout-finished');
744
802
 
@@ -799,8 +857,8 @@ function SideNavInternal(_ref) {
799
857
  // Close the flyout if there are no more layers open and the user is not mousing over the
800
858
  // flyout areas (side nav, TopNavStart element)
801
859
 
802
- return openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.onChange(function (_ref6) {
803
- var count = _ref6.count;
860
+ return openLayerObserver === null || openLayerObserver === void 0 ? void 0 : openLayerObserver.onChange(function (_ref9) {
861
+ var count = _ref9.count;
804
862
  if (flyoutStateRef.current.type === 'ready-to-close' && count === 0) {
805
863
  updateFlyoutState('force-close');
806
864
  }
@@ -808,6 +866,52 @@ function SideNavInternal(_ref) {
808
866
  namespace: _constants.openLayerObserverSideNavNamespace
809
867
  });
810
868
  }, [openLayerObserver, updateFlyoutState]);
869
+ var focusOutTimeoutIdRef = (0, _react.useRef)(undefined);
870
+ (0, _react.useEffect)(function () {
871
+ // The same as the open layer observer `onChange` above, for when the `platform-dst-top-layer`
872
+ // gate is on. Top-layer surfaces opened from the side nav are DOM descendants of it.
873
+ var nav = navRef.current;
874
+ if (!nav || !(0, _fg.fg)('platform-dst-top-layer')) {
875
+ return;
876
+ }
877
+ function closeIfReady() {
878
+ if (flyoutStateRef.current.type !== 'ready-to-close' || !nav) {
879
+ return;
880
+ }
881
+ if (isFlyoutHeldOpen({
882
+ nav: nav
883
+ })) {
884
+ return;
885
+ }
886
+ updateFlyoutState('force-close');
887
+ }
888
+ var unbindLayerChange = (0, _bindOpenLayerChange.bindOpenLayerChange)({
889
+ within: nav,
890
+ onChange: closeIfReady
891
+ });
892
+ var unbindFocusOut = (0, _bindEventListener.bind)(nav, {
893
+ type: 'focusout',
894
+ listener: function listener() {
895
+ // Wait for focus to move before checking where it went.
896
+ clearTimeout(focusOutTimeoutIdRef.current);
897
+ focusOutTimeoutIdRef.current = setTimeout(closeIfReady, 0);
898
+ }
899
+ });
900
+
901
+ // Removing the focused text field (for example when an inline rename ends) fires no
902
+ // `focusout` in some browsers, so also check again when content inside the side nav changes.
903
+ var removalObserver = new MutationObserver(closeIfReady);
904
+ removalObserver.observe(nav, {
905
+ childList: true,
906
+ subtree: true
907
+ });
908
+ return function cleanup() {
909
+ unbindLayerChange();
910
+ unbindFocusOut();
911
+ removalObserver.disconnect();
912
+ clearTimeout(focusOutTimeoutIdRef.current);
913
+ };
914
+ }, [updateFlyoutState]);
811
915
  (0, _react.useEffect)(function () {
812
916
  // Clear flyout close timer if being unmounted
813
917
  return function cleanupPendingFlyoutClose() {
@@ -944,26 +1048,24 @@ function SideNavInternal(_ref) {
944
1048
  *
945
1049
  * You can optionally render a `PanelSplitter` as a child to make the side navigation slot resizable.
946
1050
  */
947
- function SideNav(_ref8) {
948
- var children = _ref8.children,
949
- defaultCollapsed = _ref8.defaultCollapsed,
950
- _ref8$defaultWidth = _ref8.defaultWidth,
951
- defaultWidth = _ref8$defaultWidth === void 0 ? 320 : _ref8$defaultWidth,
952
- minWidth = _ref8.minWidth,
953
- maxWidth = _ref8.maxWidth,
954
- testId = _ref8.testId,
955
- label = _ref8.label,
956
- _ref8$skipLinkLabel = _ref8.skipLinkLabel,
957
- skipLinkLabel = _ref8$skipLinkLabel === void 0 ? label : _ref8$skipLinkLabel,
958
- onExpand = _ref8.onExpand,
959
- onCollapse = _ref8.onCollapse,
960
- onPeekStart = _ref8.onPeekStart,
961
- onPeekEnd = _ref8.onPeekEnd,
962
- canToggleWithShortcut = _ref8.canToggleWithShortcut,
963
- id = _ref8.id;
964
- return /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
965
- namespace: _constants.openLayerObserverSideNavNamespace
966
- }, /*#__PURE__*/_react.default.createElement(SideNavInternal, {
1051
+ function SideNav(_ref1) {
1052
+ var children = _ref1.children,
1053
+ defaultCollapsed = _ref1.defaultCollapsed,
1054
+ _ref1$defaultWidth = _ref1.defaultWidth,
1055
+ defaultWidth = _ref1$defaultWidth === void 0 ? 320 : _ref1$defaultWidth,
1056
+ minWidth = _ref1.minWidth,
1057
+ maxWidth = _ref1.maxWidth,
1058
+ testId = _ref1.testId,
1059
+ label = _ref1.label,
1060
+ _ref1$skipLinkLabel = _ref1.skipLinkLabel,
1061
+ skipLinkLabel = _ref1$skipLinkLabel === void 0 ? label : _ref1$skipLinkLabel,
1062
+ onExpand = _ref1.onExpand,
1063
+ onCollapse = _ref1.onCollapse,
1064
+ onPeekStart = _ref1.onPeekStart,
1065
+ onPeekEnd = _ref1.onPeekEnd,
1066
+ canToggleWithShortcut = _ref1.canToggleWithShortcut,
1067
+ id = _ref1.id;
1068
+ var sideNav = /*#__PURE__*/_react.default.createElement(SideNavInternal, {
967
1069
  defaultCollapsed: defaultCollapsed,
968
1070
  defaultWidth: defaultWidth,
969
1071
  minWidth: minWidth,
@@ -977,5 +1079,13 @@ function SideNav(_ref8) {
977
1079
  onPeekEnd: onPeekEnd,
978
1080
  id: id,
979
1081
  canToggleWithShortcut: canToggleWithShortcut
980
- }, children));
1082
+ }, children);
1083
+
1084
+ // Top-layer surfaces are found through the DOM, so the namespace is only needed when the gate is off.
1085
+ if ((0, _fg.fg)('platform-dst-top-layer')) {
1086
+ return sideNav;
1087
+ }
1088
+ return /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
1089
+ namespace: _constants.openLayerObserverSideNavNamespace
1090
+ }, sideNav);
981
1091
  }
@@ -17,6 +17,8 @@ var _useAnalyticsEvents2 = require("@atlaskit/analytics-next/useAnalyticsEvents"
17
17
  var _sidebarCollapse = _interopRequireDefault(require("@atlaskit/icon/core/sidebar-collapse"));
18
18
  var _sidebarExpand = _interopRequireDefault(require("@atlaskit/icon/core/sidebar-expand"));
19
19
  var _useOpenLayerObserver = require("@atlaskit/layering/use-open-layer-observer");
20
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
21
+ var _requestClosePopovers = require("@atlaskit/top-layer/page-surface/request-close-popovers");
20
22
  var _iconButton = require("../../top-nav-items/themed/icon-button");
21
23
  var _sideNavToggleButtonAttachRef = require("./side-nav-toggle-button-attach-ref");
22
24
  var _sideNavToggleTooltipKeyboardShortcut = require("./side-nav-toggle-tooltip-keyboard-shortcut");
@@ -102,12 +104,17 @@ var SideNavToggleButton = exports.SideNavToggleButton = function SideNavToggleBu
102
104
  });
103
105
  var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(),
104
106
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
105
- var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)();
107
+ var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)({
108
+ isEnabled: !(0, _fg.fg)('platform-dst-top-layer')
109
+ });
106
110
  var handleClick = (0, _react.useCallback)(function (event, analyticsEvent) {
107
111
  onClick === null || onClick === void 0 || onClick(event, analyticsEvent, {
108
112
  isSideNavVisible: isSideNavExpanded
109
113
  });
110
114
  toggleVisibility();
115
+
116
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
117
+ (0, _requestClosePopovers.requestClosePopovers)();
111
118
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
112
119
  }, [isSideNavExpanded, onClick, openLayerObserver, toggleVisibility]);
113
120
  var handlePointerEnter = (0, _react.useCallback)(function () {
@@ -9,6 +9,9 @@ var _react = require("react");
9
9
  var _bindEventListener = require("bind-event-listener");
10
10
  var _useStableRef = _interopRequireDefault(require("@atlaskit/ds-lib/use-stable-ref"));
11
11
  var _useOpenLayerObserver = require("@atlaskit/layering/use-open-layer-observer");
12
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
13
+ var _hasOpenDialogOrPopover = require("@atlaskit/top-layer/page-surface/has-open-dialog-or-popover");
14
+ var _requestClosePopovers = require("@atlaskit/top-layer/page-surface/request-close-popovers");
12
15
  var _useIsSideNavShortcutEnabled = require("./use-is-side-nav-shortcut-enabled");
13
16
  var _useToggleSideNav = require("./use-toggle-side-nav");
14
17
  /**
@@ -16,7 +19,9 @@ var _useToggleSideNav = require("./use-toggle-side-nav");
16
19
  */
17
20
  function useSideNavToggleKeyboardShortcut(_ref) {
18
21
  var canToggleWithShortcut = _ref.canToggleWithShortcut;
19
- var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)();
22
+ var openLayerObserver = (0, _useOpenLayerObserver.useOpenLayerObserver)({
23
+ isEnabled: !(0, _fg.fg)('platform-dst-top-layer')
24
+ });
20
25
  var toggleVisibilityByShortcut = (0, _useToggleSideNav.useToggleSideNav)({
21
26
  trigger: 'keyboard'
22
27
  });
@@ -39,12 +44,21 @@ function useSideNavToggleKeyboardShortcut(_ref) {
39
44
  // Ignore repeated keydown events from holding down the keys
40
45
  return;
41
46
  }
47
+ if ((0, _fg.fg)('platform-dst-top-layer') && (0, _hasOpenDialogOrPopover.hasOpenDialogOrPopover)({
48
+ type: 'modal'
49
+ })) {
50
+ // Return early if there are any open modal dialogs
51
+ return;
52
+ }
42
53
  if (openLayerObserver && openLayerObserver.getCount({
43
54
  type: 'modal'
44
55
  }) > 0) {
45
56
  // Return early if there are any open modals
46
57
  return;
47
58
  }
59
+
60
+ // Not gated. Top-layer tooltips (`platform-dst-top-layer-tooltip`) are not known to the observer.
61
+ (0, _requestClosePopovers.requestClosePopovers)();
48
62
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
49
63
  toggleVisibilityByShortcut();
50
64
  }
@@ -75,7 +75,8 @@ function TopNavEnd(_ref) {
75
75
 
76
76
  // The shared provider also covers the mobile overflow popup itself. Keep the
77
77
  // previous content-only namespace coverage when the layout gate is disabled.
78
- var actions = (0, _fg.fg)('platform-dst-chat-panel-layout') ? children : /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
78
+ // The observer is not used when the top-layer gate is on, so no provider is needed.
79
+ var actions = (0, _fg.fg)('platform-dst-chat-panel-layout') || (0, _fg.fg)('platform-dst-top-layer') ? children : /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
79
80
  namespace: _constants.openLayerObserverTopNavEndNamespace
80
81
  }, children);
81
82
  var content = /*#__PURE__*/_react.default.createElement("nav", {
@@ -113,7 +114,7 @@ function TopNavEnd(_ref) {
113
114
  }) : /*#__PURE__*/_react.default.createElement(_list.List, {
114
115
  xcss: (0, _react2.cx)(listStyles.root, listStyles.hideOnSmallViewport)
115
116
  }, actions), hasPersistentItems && persistentItems);
116
- return (0, _fg.fg)('platform-dst-chat-panel-layout') ? /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
117
+ return (0, _fg.fg)('platform-dst-chat-panel-layout') && !(0, _fg.fg)('platform-dst-top-layer') ? /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
117
118
  namespace: _constants.openLayerObserverTopNavEndNamespace
118
119
  }, content) : content;
119
120
  }
@@ -10,6 +10,7 @@ require("./top-nav-middle.compiled.css");
10
10
  var _runtime = require("@compiled/react/runtime");
11
11
  var _react = _interopRequireDefault(require("react"));
12
12
  var _openLayerObserverNamespaceProvider = require("@atlaskit/layering/open-layer-observer-namespace-provider");
13
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
13
14
  var _constants = require("../constants");
14
15
  var styles = {
15
16
  root: "_zulpu2gc _yyhycs5v _1bsb1osq _4cvr1h6o _1e0c1txw _1bahh9n0 _181n11p5 _1j8b15b0 _lagd1bp4 _1t4c1ris _12e8h9n0"
@@ -27,7 +28,7 @@ function TopNavMiddle(_ref) {
27
28
  var children = _ref.children;
28
29
  return /*#__PURE__*/_react.default.createElement("div", {
29
30
  className: (0, _runtime.ax)([styles.root])
30
- }, /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
31
+ }, (0, _fg.fg)('platform-dst-top-layer') ? children : /*#__PURE__*/_react.default.createElement(_openLayerObserverNamespaceProvider.OpenLayerObserverNamespaceProvider, {
31
32
  namespace: _constants.openLayerObserverTopNavMiddleNamespace
32
33
  }, children));
33
34
  }