@atlaskit/navigation-system 5.15.0 → 5.17.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 (78) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-header.js +3 -1
  3. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item-content.js +8 -3
  4. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item-context.js +21 -2
  5. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item.js +3 -1
  6. package/dist/cjs/ui/page-layout/banner.compiled.css +1 -0
  7. package/dist/cjs/ui/page-layout/banner.js +6 -2
  8. package/dist/cjs/ui/page-layout/constants.js +16 -2
  9. package/dist/cjs/ui/page-layout/panel-splitter/provider.js +5 -3
  10. package/dist/cjs/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +59 -0
  11. package/dist/cjs/ui/page-layout/root.compiled.css +1 -0
  12. package/dist/cjs/ui/page-layout/root.js +7 -2
  13. package/dist/cjs/ui/page-layout/side-nav/side-nav-content.compiled.css +2 -1
  14. package/dist/cjs/ui/page-layout/side-nav/side-nav-content.js +8 -2
  15. package/dist/cjs/ui/page-layout/side-nav/side-nav-header.js +17 -0
  16. package/dist/cjs/ui/page-layout/side-nav/side-nav.compiled.css +3 -0
  17. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +28 -17
  18. package/dist/cjs/ui/page-layout/top-nav/top-nav-end.js +3 -2
  19. package/dist/cjs/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  20. package/dist/cjs/ui/page-layout/top-nav/top-nav-start.compiled.css +2 -1
  21. package/dist/cjs/ui/page-layout/top-nav/top-nav-start.js +30 -3
  22. package/dist/cjs/ui/page-layout/top-nav/top-nav.compiled.css +11 -0
  23. package/dist/cjs/ui/page-layout/top-nav/top-nav.js +44 -5
  24. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-header.js +4 -2
  25. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item-content.js +10 -5
  26. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item-context.js +18 -1
  27. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item.js +3 -1
  28. package/dist/es2019/ui/page-layout/banner.compiled.css +1 -0
  29. package/dist/es2019/ui/page-layout/banner.js +6 -2
  30. package/dist/es2019/ui/page-layout/constants.js +15 -1
  31. package/dist/es2019/ui/page-layout/panel-splitter/provider.js +5 -3
  32. package/dist/es2019/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +57 -2
  33. package/dist/es2019/ui/page-layout/root.compiled.css +1 -0
  34. package/dist/es2019/ui/page-layout/root.js +7 -2
  35. package/dist/es2019/ui/page-layout/side-nav/side-nav-content.compiled.css +2 -1
  36. package/dist/es2019/ui/page-layout/side-nav/side-nav-content.js +9 -2
  37. package/dist/es2019/ui/page-layout/side-nav/side-nav-header.js +17 -0
  38. package/dist/es2019/ui/page-layout/side-nav/side-nav.compiled.css +3 -0
  39. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +19 -8
  40. package/dist/es2019/ui/page-layout/top-nav/top-nav-end.js +3 -2
  41. package/dist/es2019/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  42. package/dist/es2019/ui/page-layout/top-nav/top-nav-start.compiled.css +2 -1
  43. package/dist/es2019/ui/page-layout/top-nav/top-nav-start.js +30 -3
  44. package/dist/es2019/ui/page-layout/top-nav/top-nav.compiled.css +11 -0
  45. package/dist/es2019/ui/page-layout/top-nav/top-nav.js +42 -7
  46. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-header.js +4 -2
  47. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item-content.js +10 -5
  48. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item-context.js +20 -1
  49. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item.js +3 -1
  50. package/dist/esm/ui/page-layout/banner.compiled.css +1 -0
  51. package/dist/esm/ui/page-layout/banner.js +6 -2
  52. package/dist/esm/ui/page-layout/constants.js +15 -1
  53. package/dist/esm/ui/page-layout/panel-splitter/provider.js +5 -3
  54. package/dist/esm/ui/page-layout/panel-splitter/side-nav-panel-splitter.js +61 -2
  55. package/dist/esm/ui/page-layout/root.compiled.css +1 -0
  56. package/dist/esm/ui/page-layout/root.js +7 -2
  57. package/dist/esm/ui/page-layout/side-nav/side-nav-content.compiled.css +2 -1
  58. package/dist/esm/ui/page-layout/side-nav/side-nav-content.js +8 -2
  59. package/dist/esm/ui/page-layout/side-nav/side-nav-header.js +17 -0
  60. package/dist/esm/ui/page-layout/side-nav/side-nav.compiled.css +3 -0
  61. package/dist/esm/ui/page-layout/side-nav/side-nav.js +19 -8
  62. package/dist/esm/ui/page-layout/top-nav/top-nav-end.js +3 -2
  63. package/dist/esm/ui/page-layout/top-nav/top-nav-middle.js +2 -1
  64. package/dist/esm/ui/page-layout/top-nav/top-nav-start.compiled.css +2 -1
  65. package/dist/esm/ui/page-layout/top-nav/top-nav-start.js +30 -3
  66. package/dist/esm/ui/page-layout/top-nav/top-nav.compiled.css +11 -0
  67. package/dist/esm/ui/page-layout/top-nav/top-nav.js +46 -7
  68. package/dist/types/ui/menu-item/flyout-menu-item/flyout-menu-item-context.d.ts +15 -0
  69. package/dist/types/ui/page-layout/constants.d.ts +10 -0
  70. package/dist/types/ui/page-layout/panel-splitter/context.d.ts +7 -2
  71. package/dist/types/ui/page-layout/panel-splitter/provider.d.ts +20 -2
  72. package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +6 -0
  73. package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/flyout-menu-item-context.d.ts +15 -0
  74. package/dist/types-ts4.5/ui/page-layout/constants.d.ts +10 -0
  75. package/dist/types-ts4.5/ui/page-layout/panel-splitter/context.d.ts +7 -2
  76. package/dist/types-ts4.5/ui/page-layout/panel-splitter/provider.d.ts +20 -2
  77. package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav.d.ts +6 -0
  78. package/package.json +8 -5
@@ -9,6 +9,7 @@ exports.TopNavMiddle = TopNavMiddle;
9
9
  require("./top-nav-middle.compiled.css");
10
10
  var _runtime = require("@compiled/react/runtime");
11
11
  var _react = _interopRequireDefault(require("react"));
12
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
13
  var _useIsFhsEnabled = require("../../fhs-rollout/use-is-fhs-enabled");
13
14
  var styles = {
14
15
  root: "_zulpu2gc _yyhycs5v _1bsb1osq _4cvr1h6o _1e0c1txw _1bahh9n0 _181n11p5 _1j8b15b0 _lagd1bp4 _1t4c1ris _12e8h9n0",
@@ -27,6 +28,6 @@ function TopNavMiddle(_ref) {
27
28
  var children = _ref.children;
28
29
  var isFhsEnabled = (0, _useIsFhsEnabled.useIsFhsEnabled)();
29
30
  return /*#__PURE__*/_react.default.createElement("div", {
30
- className: (0, _runtime.ax)([styles.root, isFhsEnabled && styles.fullHeightSidebar])
31
+ className: (0, _runtime.ax)([styles.root, isFhsEnabled && !(0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && styles.fullHeightSidebar])
31
32
  }, children);
32
33
  }
@@ -13,4 +13,5 @@
13
13
  ._vchhusvi{box-sizing:border-box}
14
14
  [dir=rtl] ._65m41mrw{--animation-direction:-1}
15
15
  @media (prefers-reduced-motion:no-preference){._10t81e03{transition-property:transform}._10t81rjc{transition-property:transform,opacity}._1xq51ytf{transition-timing-function:ease-in-out}._1xq55ucs{transition-timing-function:ease}._mjvc1efy{transform:translateX(calc(100%*var(--animation-direction)))}._bgpzidpf{opacity:0}._mjvc1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}._mjvco0k7{transform:translateX(calc((-2rem + var(--ds-space-050, 4px)*-1)*var(--animation-direction)))}._mjvcyrjp{transform:translateX(calc((2rem + var(--ds-space-050, 4px))*var(--animation-direction)))}._mjvcz12g{transform:translateX(0)}._xrrpfnf5{transition-duration:.2s}._bgpzkb7n{opacity:1}}
16
- @media (min-width:64rem){._15rin7od{min-width:unset}._glte1osq{width:100%}._15rip2n4{min-width:330px}._glte1ris{width:max-content}._15ri1mjv{min-width:300px}._1gs5usvi{box-sizing:border-box}._glte93mn{width:var(--n_sNvlw,100%)}._exxmpxbi{padding-inline-end:var(--ds-space-200,1pc)}}
16
+ @media (min-width:64rem){._13wnh2mm{position:relative}._1l3vb3bt:after{content:""}._juxdstnw:after{position:absolute}._1vinidpf:after{inset-block-start:0}._1719idpf:after{inset-block-end:0}._e6znidpf:after{inset-inline-end:0}._1kyhe4h9:after{border-inline-end-width:var(--ds-border-width,1px)}._4cwynqa1:after{border-inline-end-style:solid}._435s1l7x:after{border-inline-end-color:var(--ds-border,#0b120e24)}._m7c3idpf:after{opacity:0}._15rin7od{min-width:unset}._glte1osq{width:100%}._15rip2n4{min-width:330px}@supports (scroll-timeline-axis:block){html:not(:has([data-private-side-nav-header])) ._1kilgc9s{animation-timeline:--sNcst}html:not(:has([data-private-side-nav-header])) ._1m3l1ybg{animation-name:khj1qz3}html:not(:has([data-private-side-nav-header])) ._12g81hrf{animation-fill-mode:both}}._4ap3vuon{background-color:var(--ds-surface,#fff)}._m7c3kb7n:after{opacity:1}._glte1ris{width:max-content}._15ri1mjv{min-width:300px}._1gs5usvi{box-sizing:border-box}._glte93mn{width:var(--n_sNvlw,100%)}._exxmpxbi{padding-inline-end:var(--ds-space-200,1pc)}@supports (scroll-timeline-axis:block){@keyframes khj1qz3{0%{box-shadow:inset 0 -1px 0 0 transparent}0.1%{box-shadow:inset 0 -1px 0 0 var(--ds-border,#0b120e24)}to{box-shadow:inset 0 -1px 0 0 var(--ds-border,#0b120e24)}}}}
17
+ @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._n8qabrmi:after{transition-property:opacity}._wc72fnf5:after{transition-duration:.2s}._j3mr1v42:after{transition-timing-function:ease-in}}
@@ -16,6 +16,7 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
16
  var _compiled = require("@atlaskit/primitives/compiled");
17
17
  var _topNavStartContext = require("../../../context/top-nav-start/top-nav-start-context");
18
18
  var _useIsFhsEnabled = require("../../fhs-rollout/use-is-fhs-enabled");
19
+ var _constants = require("../constants");
19
20
  var _useSideNavVisibility3 = require("../side-nav/use-side-nav-visibility");
20
21
  var _visibilityContext = require("../side-nav/visibility-context");
21
22
  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); }
@@ -44,6 +45,12 @@ var innerStyles = {
44
45
  fullHeightSidebarExpanded: "_15rin7od _glte1osq"
45
46
  };
46
47
 
48
+ /**
49
+ * The scroll indicator is usually applied in SideNavContent, but if there is no SideNavHeader it is
50
+ * applied in TopNavStart instead for layering reasons. See the comment in SideNavHeader for more details.
51
+ */
52
+ var scrolledShadow = null;
53
+
47
54
  /**
48
55
  * Styles for the outer element, that does not have re-enabled pointer events and spans the entire
49
56
  * width of the TopNavStart area.
@@ -52,7 +59,10 @@ var innerStyles = {
52
59
  */
53
60
  var wrapperStyles = {
54
61
  root: "_vchhusvi _bozgutpp _4t3i1osq",
55
- fullHeightSidebarExpanded: "_glte93mn _exxmpxbi"
62
+ fullHeightSidebarExpanded: "_glte93mn _exxmpxbi",
63
+ fullHeightSidebarWithLayeringFixes: "_13wnh2mm _1l3vb3bt _juxdstnw _1vinidpf _1719idpf _e6znidpf _1kyhe4h9 _4cwynqa1 _435s1l7x _m7c3idpf",
64
+ fullHeightSidebarExpandedWithLayeringFixes: "_4ap3vuon _1kilgc9s _1m3l1ybg _12g81hrf _m7c3kb7n",
65
+ fullHeightSidebarBorderTransition: "_n8qabrmi _wc72fnf5 _j3mr1v42"
56
66
  };
57
67
 
58
68
  /**
@@ -120,12 +130,29 @@ var TopNavStartInnerFHS = /*#__PURE__*/(0, _react.forwardRef)(function TopNavSta
120
130
  defaultCollapsed: true
121
131
  }),
122
132
  isExpandedOnDesktop = _useSideNavVisibility.isExpandedOnDesktop;
133
+ var sideNavState = (0, _react.useContext)(_visibilityContext.SideNavVisibilityState);
134
+ var isFirstRenderRef = (0, _react.useRef)(true);
135
+ (0, _react.useEffect)(function () {
136
+ if (!(0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes')) {
137
+ return;
138
+ }
139
+
140
+ // Ignore renders until the side nav state is initialized
141
+ // So that apps using the legacy API for setting side nav default state do not see
142
+ // animations when they shouldn't
143
+ if (sideNavState === null) {
144
+ return;
145
+ }
146
+ if (isFirstRenderRef.current) {
147
+ isFirstRenderRef.current = false;
148
+ }
149
+ }, [sideNavState]);
123
150
  return /*#__PURE__*/_react.default.createElement("div", {
124
- className: (0, _runtime.ax)([wrapperStyles.root, isExpandedOnDesktop && wrapperStyles.fullHeightSidebarExpanded])
151
+ className: (0, _runtime.ax)([wrapperStyles.root, isExpandedOnDesktop && wrapperStyles.fullHeightSidebarExpanded, (0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && wrapperStyles.fullHeightSidebarWithLayeringFixes, !isFirstRenderRef.current && isExpandedOnDesktop && (0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && wrapperStyles.fullHeightSidebarBorderTransition, isExpandedOnDesktop && (0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && wrapperStyles.fullHeightSidebarExpandedWithLayeringFixes])
125
152
  }, /*#__PURE__*/_react.default.createElement("div", {
126
153
  ref: ref,
127
154
  "data-testid": testId,
128
- className: (0, _runtime.ax)([innerStyles.root, innerStyles.fullHeightSidebar, (0, _platformFeatureFlags.fg)('team25-eu-jira-logo-updates-csm-jsm') && innerStyles.jiraProductLogoUpdate, isExpandedOnDesktop && innerStyles.fullHeightSidebarExpanded])
155
+ className: (0, _runtime.ax)([innerStyles.root, !(0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && innerStyles.fullHeightSidebar, (0, _platformFeatureFlags.fg)('team25-eu-jira-logo-updates-csm-jsm') && innerStyles.jiraProductLogoUpdate, isExpandedOnDesktop && innerStyles.fullHeightSidebarExpanded])
129
156
  }, children));
130
157
  });
131
158
 
@@ -5,17 +5,28 @@
5
5
  ._18zrze3t{padding-inline:var(--ds-space-0,0)}
6
6
  ._179rglyw{border-block-end:none}
7
7
  ._179ria51{border-block-end:var(--ds-border-width,1px) solid var(--ds-border,#0b120e24)}._152t1nws{inset-block-start:var(--n_bnrM,0)}
8
+ ._18postnw:after{position:absolute}
9
+ ._1beue4h9:after{border-block-end-width:var(--ds-border-width,1px)}
8
10
  ._1bsb1osq{width:100%}
11
+ ._1cte1l7x:after{border-block-end-color:var(--ds-border,#0b120e24)}
12
+ ._1czdidpf:after{inset-inline-end:0}
9
13
  ._1e0c11p5{display:grid}
14
+ ._1gufidpf:after{inset-block-end:0}
15
+ ._1pby11wp{z-index:3}
16
+ ._1pbycs5v{z-index:2}
10
17
  ._1pbyegat{z-index:4}
11
18
  ._4cvr1h6o{align-items:center}
12
19
  ._4t3i1dgc{height:var(--n_tNvM)}
13
20
  ._4t3i1osq{height:100%}
21
+ ._aetrb3bt:after{content:""}
14
22
  ._bfhkglyw{background-color:none}
15
23
  ._bfhkvuon{background-color:var(--ds-surface,#fff)}
16
24
  ._d6vu1bgi >span[data-ep-placeholder-id=top_navigation_skeleton]{display:contents}
25
+ ._g0nf3tht:after{inset-inline-start:var(--n_sNvlw,0)}
17
26
  ._kqsw1if8{position:sticky}
27
+ ._lcxv1wug{pointer-events:auto}
18
28
  ._lcxvglyw{pointer-events:none}
29
+ ._uaeunqa1:after{border-block-end-style:solid}
19
30
  ._vchhusvi{box-sizing:border-box}
20
31
  ._yv0e1mfv{grid-template-columns:auto 1fr auto}
21
32
  @media (min-width:48rem){._1j8b18ax{grid-template-columns:1fr minmax(min-content,max-content) 1fr}}
@@ -11,7 +11,10 @@ require("./top-nav.compiled.css");
11
11
  var _react = _interopRequireWildcard(require("react"));
12
12
  var React = _react;
13
13
  var _runtime = require("@compiled/react/runtime");
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
15
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
16
+ var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
17
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
18
  var _skipLinksContext = require("../../../context/skip-links/skip-links-context");
16
19
  var _useIsFhsEnabled = require("../../fhs-rollout/use-is-fhs-enabled");
17
20
  var _hasCustomThemeContext = require("../../top-nav-items/themed/has-custom-theme-context");
@@ -34,7 +37,9 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
34
37
  var styles = {
35
38
  root: "_nd5l8cbt _zulpu2gc _18zrutpp _179ria51 _1e0c11p5 _yv0e1mfv _4cvr1h6o _bfhkvuon _vchhusvi _4t3i1dgc _152t1nws _kqsw1if8 _1pbyegat _d6vu1bgi _1j8b18ax",
36
39
  fullHeightSidebar: "_18zrze3t _179rglyw _bfhkglyw _lcxvglyw _pdlmutpp",
37
- fullHeightSidebarExpanded: "_1rqt16a9 _jh1g18ax"
40
+ fullHeightSidebarExpanded: "_1rqt16a9 _jh1g18ax",
41
+ fullHeightSidebarWithLayeringFixes: "_1pbycs5v _lcxv1wug _bfhkvuon _aetrb3bt _18postnw _1gufidpf _1czdidpf _g0nf3tht _1beue4h9 _uaeunqa1 _1cte1l7x",
42
+ fullHeightSidebarWithLayeringFixesAndOpenLayer: "_1pby11wp"
38
43
  };
39
44
 
40
45
  /**
@@ -69,6 +74,8 @@ function TopNav(_ref) {
69
74
  var customTheme = (0, _useCustomTheme.useCustomTheme)(UNSAFE_theme);
70
75
 
71
76
  /**
77
+ * Note: this is no longer the case when fg('platform-dst-side-nav-layering-fixes') is enabled.
78
+ *
72
79
  * With the full height sidebar we have a foreground and background element,
73
80
  * so we need to apply the custom theme styles to the correct element.
74
81
  *
@@ -96,9 +103,37 @@ function TopNav(_ref) {
96
103
  foregroundStyle = _useMemo.foregroundStyle;
97
104
  var _useSideNavVisibility = (0, _useSideNavVisibility2.useSideNavVisibility)(),
98
105
  isExpandedOnDesktop = _useSideNavVisibility.isExpandedOnDesktop;
106
+ var openLayerObserver = (0, _openLayerObserver.useOpenLayerObserver)();
107
+ // Setting the initial state to false, as it is unlikely that the top nav would have an open popup when the app starts.
108
+ var _useState = (0, _react.useState)(false),
109
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
110
+ hasOpenPopup = _useState2[0],
111
+ setHasOpenPopup = _useState2[1];
112
+ (0, _react.useLayoutEffect)(function () {
113
+ if (!openLayerObserver || !isFhsEnabled || !(0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes')) {
114
+ return;
115
+ }
116
+ function checkAndSetState() {
117
+ if (!openLayerObserver) {
118
+ return;
119
+ }
120
+ setHasOpenPopup(openLayerObserver.getCount({
121
+ namespace: _constants.openLayerObserverTopNavNamespace,
122
+ type: 'popup'
123
+ }) > 0);
124
+ }
125
+
126
+ // Initial check
127
+ checkAndSetState();
128
+
129
+ // Check again whenever number of layers in the top nav change
130
+ return openLayerObserver.onChange(checkAndSetState, {
131
+ namespace: _constants.openLayerObserverTopNavNamespace
132
+ });
133
+ }, [isFhsEnabled, openLayerObserver]);
99
134
  return /*#__PURE__*/React.createElement(_hasCustomThemeContext.HasCustomThemeContext.Provider, {
100
135
  value: customTheme.isEnabled
101
- }, isFhsEnabled && /*#__PURE__*/React.createElement("div", {
136
+ }, isFhsEnabled && !(0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && /*#__PURE__*/React.createElement("div", {
102
137
  "data-layout-slot": true,
103
138
  "aria-hidden": true
104
139
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
@@ -108,11 +143,13 @@ function TopNav(_ref) {
108
143
  }), /*#__PURE__*/React.createElement("header", {
109
144
  id: id,
110
145
  "data-layout-slot": true,
111
- className: (0, _runtime.ax)([styles.root, isFhsEnabled && styles.fullHeightSidebar, isExpandedOnDesktop && isFhsEnabled && styles.fullHeightSidebarExpanded, xcss]),
146
+ className: (0, _runtime.ax)([styles.root, isFhsEnabled && styles.fullHeightSidebar, isFhsEnabled && (0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && styles.fullHeightSidebarWithLayeringFixes, hasOpenPopup && isFhsEnabled && (0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') && styles.fullHeightSidebarWithLayeringFixesAndOpenLayer, isExpandedOnDesktop && isFhsEnabled && styles.fullHeightSidebarExpanded, xcss]),
112
147
  "data-testid": testId
113
148
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
114
149
  ,
115
- style: isFhsEnabled ? foregroundStyle : customTheme.isEnabled ? customTheme.style : undefined
150
+ style:
151
+ // When the layering fixes are enabled, we no longer have separate elements for the foreground and background.
152
+ isFhsEnabled && !(0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') ? foregroundStyle : customTheme.isEnabled ? customTheme.style : undefined
116
153
  }, /*#__PURE__*/React.createElement(_hoistUtils.HoistCssVarToLocalGrid, {
117
154
  variableName: _constants.topNavMountedVar,
118
155
  value: height
@@ -126,5 +163,7 @@ function TopNav(_ref) {
126
163
  value: height
127
164
  })
128
165
  // ------ END UNSAFE STYLES ------
129
- , children));
166
+ , (0, _platformFeatureFlags.fg)('platform-dst-side-nav-layering-fixes') ? /*#__PURE__*/React.createElement(_openLayerObserver.OpenLayerObserverNamespaceProvider, {
167
+ namespace: _constants.openLayerObserverTopNavNamespace
168
+ }, children) : children));
130
169
  }
@@ -5,7 +5,7 @@ import React, { useCallback, useContext } from 'react';
5
5
  import Heading from '@atlaskit/heading';
6
6
  import { Flex } from '@atlaskit/primitives/compiled';
7
7
  import { CloseButton } from './close-button';
8
- import { OnCloseContext, SetIsOpenContext } from './flyout-menu-item-context';
8
+ import { OnCloseContext, SetIsOpenContext, useTitleId } from './flyout-menu-item-context';
9
9
  const headerStyles = {
10
10
  root: "_zulp12x7 _bozg1b66 _85i512x7 _1e0c1txw _2lx21bp4",
11
11
  flex: "_zulppxbi _1bah1yb4 _2lx21sbv _4cvr1h6o _1bsb1osq _bozgv77o"
@@ -24,6 +24,7 @@ export const FlyoutHeader = props => {
24
24
  title,
25
25
  closeButtonLabel
26
26
  } = props;
27
+ const id = useTitleId();
27
28
  const setIsOpen = useContext(SetIsOpenContext);
28
29
  const onClose = useContext(OnCloseContext);
29
30
  const handleClose = useCallback(() => {
@@ -41,6 +42,7 @@ export const FlyoutHeader = props => {
41
42
  testId: testId && `${testId}--close-button`
42
43
  }), /*#__PURE__*/React.createElement(Heading, {
43
44
  size: "xsmall",
44
- as: "span"
45
+ as: "span",
46
+ id: id
45
47
  }, title)), children);
46
48
  };
@@ -1,11 +1,11 @@
1
1
  /* flyout-menu-item-content.tsx generated by @compiled/babel-plugin v0.38.1 */
2
2
  import "./flyout-menu-item-content.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
- import React, { forwardRef, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
4
+ import React, { forwardRef, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';
5
5
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
6
6
  import { fg } from '@atlaskit/platform-feature-flags';
7
7
  import { PopupContent } from '@atlaskit/popup/experimental';
8
- import { OnCloseProvider, SetIsOpenContext } from './flyout-menu-item-context';
8
+ import { OnCloseProvider, SetIsOpenContext, TitleIdContextProvider } from './flyout-menu-item-context';
9
9
 
10
10
  /**
11
11
  * The vertical offset in px to ensure the flyout container does not exceed the bounds of
@@ -42,6 +42,7 @@ export const FlyoutMenuItemContent = /*#__PURE__*/forwardRef(({
42
42
  onClose === null || onClose === void 0 ? void 0 : onClose();
43
43
  setIsOpen(false);
44
44
  }, [setIsOpen, onClose]);
45
+ const titleId = useId();
45
46
  return /*#__PURE__*/React.createElement(PopupContent, {
46
47
  appearance: "UNSAFE_modal-below-sm",
47
48
  onClose: handleClose,
@@ -54,7 +55,9 @@ export const FlyoutMenuItemContent = /*#__PURE__*/forwardRef(({
54
55
  shouldFitViewport: true,
55
56
  testId: containerTestId,
56
57
  xcss: flyoutMenuItemContentStyles.root,
57
- autoFocus: autoFocus
58
+ autoFocus: autoFocus,
59
+ role: fg("platform_dst_nav4_flyout_menu_slots_close_button") ? "dialog" : undefined,
60
+ titleId: fg("platform_dst_nav4_flyout_menu_slots_close_button") ? titleId : undefined
58
61
  /**
59
62
  * Disabling GPU acceleration removes the use of `transform` by popper.js for this popup.
60
63
  *
@@ -75,11 +78,13 @@ export const FlyoutMenuItemContent = /*#__PURE__*/forwardRef(({
75
78
  }) => /*#__PURE__*/React.createElement(UpdatePopperOnContentResize, {
76
79
  ref: forwardedRef,
77
80
  update: update
78
- }, fg("platform_dst_nav4_flyout_menu_slots_close_button") ? /*#__PURE__*/React.createElement(OnCloseProvider, {
81
+ }, fg("platform_dst_nav4_flyout_menu_slots_close_button") ? /*#__PURE__*/React.createElement(TitleIdContextProvider, {
82
+ value: titleId
83
+ }, /*#__PURE__*/React.createElement(OnCloseProvider, {
79
84
  value: () => onClose
80
85
  }, /*#__PURE__*/React.createElement("div", {
81
86
  className: ax([flyoutMenuItemContentContainerStyles.container])
82
- }, children)) : children));
87
+ }, children))) : children));
83
88
  });
84
89
  function createResizeObserver(update) {
85
90
  return new ResizeObserver(update);
@@ -29,4 +29,21 @@ export const OnCloseContext = /*#__PURE__*/createContext(null);
29
29
  *
30
30
  * A context provider for supplying the onClose function to the FlyoutHeader.
31
31
  */
32
- export const OnCloseProvider = OnCloseContext.Provider;
32
+ export const OnCloseProvider = OnCloseContext.Provider;
33
+
34
+ /**
35
+ * __Title id context__
36
+ *
37
+ * A context for storing the title id of the FlyoutMenuItem that is displayed in
38
+ * FlyoutHeader, and used as the aria-labelledby on the FlyoutMenuItemContent
39
+ * container.
40
+ */
41
+ export const TitleIdContext = /*#__PURE__*/createContext(undefined);
42
+ export const useTitleId = () => useContext(TitleIdContext);
43
+
44
+ /**
45
+ * __Title id provider__
46
+ *
47
+ * A context provider for supplying the title id to the FlyoutHeader.
48
+ */
49
+ export const TitleIdContextProvider = TitleIdContext.Provider;
@@ -1,6 +1,7 @@
1
1
  import React, { forwardRef, useEffect } from 'react';
2
2
  import useControlled from '@atlaskit/ds-lib/use-controlled';
3
3
  import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  import { Popup } from '@atlaskit/popup/experimental';
5
6
  import { MenuListItem } from '../menu-list-item';
6
7
  import { IsOpenContext, SetIsOpenContext } from './flyout-menu-item-context';
@@ -54,6 +55,7 @@ export const FlyoutMenuItem = /*#__PURE__*/forwardRef(({
54
55
  ref: forwardedRef
55
56
  }, /*#__PURE__*/React.createElement(Popup, {
56
57
  id: id,
57
- isOpen: isOpen
58
+ isOpen: isOpen,
59
+ role: fg('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : undefined
58
60
  }, children))));
59
61
  });
@@ -1,6 +1,7 @@
1
1
 
2
2
  ._nd5ldkfm{grid-area:banner}._152tidpf{inset-block-start:0}
3
3
  ._18m915vq{overflow-y:hidden}
4
+ ._1pbycs5v{z-index:2}
4
5
  ._1pbyegat{z-index:4}
5
6
  ._1reo15vq{overflow-x:hidden}
6
7
  ._4t3iutvi{height:var(--n_bnrM)}
@@ -3,13 +3,16 @@ import "./banner.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
5
  import { useContext } from 'react';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { useSkipLinkInternal } from '../../context/skip-links/skip-links-context';
8
+ import { useIsFhsEnabled } from '../fhs-rollout/use-is-fhs-enabled';
7
9
  import { bannerMountedVar, localSlotLayers, UNSAFE_bannerVar } from './constants';
8
10
  import { DangerouslyHoistSlotSizes } from './hoist-slot-sizes-context';
9
11
  import { DangerouslyHoistCssVarToDocumentRoot, HoistCssVarToLocalGrid } from './hoist-utils';
10
12
  import { useLayoutId } from './id-utils';
11
13
  const styles = {
12
- root: "_nd5ldkfm _1reo15vq _18m915vq _4t3iutvi _152tidpf _kqsw1if8 _1pbyegat"
14
+ root: "_nd5ldkfm _1reo15vq _18m915vq _4t3iutvi _152tidpf _kqsw1if8 _1pbyegat",
15
+ fullHeightSidebarWithLayeringFixes: "_1pbycs5v"
13
16
  };
14
17
 
15
18
  /**
@@ -30,6 +33,7 @@ export function Banner({
30
33
  const id = useLayoutId({
31
34
  providedId
32
35
  });
36
+ const isFhsEnabled = useIsFhsEnabled();
33
37
 
34
38
  /**
35
39
  * Don't show the skip link if the slot has 0 height.
@@ -42,7 +46,7 @@ export function Banner({
42
46
  return /*#__PURE__*/React.createElement("div", {
43
47
  id: id,
44
48
  "data-layout-slot": true,
45
- className: ax([styles.root, xcss]),
49
+ className: ax([styles.root, isFhsEnabled && fg('platform-dst-side-nav-layering-fixes') && styles.fullHeightSidebarWithLayeringFixes, xcss]),
46
50
  "data-testid": testId
47
51
  }, /*#__PURE__*/React.createElement(HoistCssVarToLocalGrid, {
48
52
  variableName: bannerMountedVar,
@@ -50,6 +50,20 @@ export const UNSAFE_MAIN_INLINE_END_FOR_LEGACY_PAGES_ONLY = `calc(var(${UNSAFE_a
50
50
  export const localSlotLayers = {
51
51
  topBar: 4,
52
52
  banner: 4,
53
+ // With the FHS layering refactors, the banner and top nav have a lower z-index to allow layers from the side nav to overlay them.
54
+ // When they all have equal z-index values, the DOM order determines the layering - meaning the side nav will be layered above the rest.
55
+ // But, when the top bar contains an open layer, it needs to be layered above the side nav, so has a higher value.
56
+ topNavFHSWithOpenLayer: 3,
57
+ bannerFHS: 2,
58
+ topNavFHS: 2,
53
59
  sideNav: 2,
54
60
  panelSmallViewports: 1
55
- };
61
+ };
62
+ export const openLayerObserverSideNavNamespace = 'side-nav';
63
+ export const openLayerObserverTopNavNamespace = 'top-nav';
64
+
65
+ /**
66
+ * CSS scroll timeline variable for the side nav content scroll indicator.
67
+ * The scroll timeline is created in SideNavContent, and then used by TopNavStart to apply the scroll indicator line.
68
+ */
69
+ export const sideNavContentScrollTimelineVar = '--sNcst';
@@ -1,4 +1,5 @@
1
1
  import React, { Fragment, useMemo, useRef } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { PanelSplitterContext } from './context';
3
4
  /**
4
5
  * Provides the context required for the panel splitter to work within a page layout slot.
@@ -12,6 +13,7 @@ export const PanelSplitterProvider = ({
12
13
  getResizeBounds,
13
14
  resizingCssVar,
14
15
  panelRef,
16
+ portalRef: providedPortalRef,
15
17
  position = 'end',
16
18
  isEnabled = true,
17
19
  shortcut,
@@ -27,12 +29,12 @@ export const PanelSplitterProvider = ({
27
29
  position,
28
30
  panelRef,
29
31
  isEnabled,
30
- portalRef,
32
+ portalRef: typeof providedPortalRef !== 'undefined' && fg('platform-dst-side-nav-layering-fixes') ? providedPortalRef : portalRef,
31
33
  shortcut
32
- }), [panelId, panelWidth, onCompleteResize, getResizeBounds, resizingCssVar, position, portalRef, panelRef, isEnabled, shortcut]);
34
+ }), [panelId, panelWidth, onCompleteResize, getResizeBounds, resizingCssVar, position, panelRef, isEnabled, providedPortalRef, shortcut]);
33
35
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(PanelSplitterContext.Provider, {
34
36
  value: context
35
- }, children), /*#__PURE__*/React.createElement("div", {
37
+ }, children), typeof providedPortalRef !== 'undefined' && fg('platform-dst-side-nav-layering-fixes') ? null : /*#__PURE__*/React.createElement("div", {
36
38
  ref: portalRef
37
39
  }));
38
40
  };
@@ -1,6 +1,9 @@
1
- import React, { useContext } from 'react';
1
+ import React, { useContext, useEffect, useState } from 'react';
2
2
  import invariant from 'tiny-invariant';
3
- import { sideNavPanelSplitterId } from '../constants';
3
+ import { useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
5
+ import { useIsFhsEnabled } from '../../fhs-rollout/use-is-fhs-enabled';
6
+ import { openLayerObserverSideNavNamespace, openLayerObserverTopNavNamespace, sideNavPanelSplitterId } from '../constants';
4
7
  import { useToggleSideNav } from '../side-nav/use-toggle-side-nav';
5
8
  import { OnDoubleClickContext, PanelSplitterContext } from './context';
6
9
  import { PanelSplitter } from './panel-splitter';
@@ -30,6 +33,58 @@ export const SideNavPanelSplitter = ({
30
33
  const toggleSideNav = useToggleSideNav({
31
34
  trigger: 'double-click'
32
35
  });
36
+ const isFhsEnabled = useIsFhsEnabled();
37
+
38
+ // The logic and state for disabling the panel splitter when there are open popups
39
+ // in the side nav or top nav is being placed here, instead of in `SideNav`, to prevent
40
+ // re-rendering the side nav anytime the number of open popups changes.
41
+ const [isEnabled, setIsEnabled] = useState(true);
42
+ const openLayerObserver = useOpenLayerObserver();
43
+ useEffect(() => {
44
+ if (!openLayerObserver || !isFhsEnabled || !fg('platform-dst-side-nav-layering-fixes')) {
45
+ return;
46
+ }
47
+ function checkAndSetState() {
48
+ if (!openLayerObserver) {
49
+ return;
50
+ }
51
+
52
+ // We don't technically need to check the side nav for open layers, as they wouldn't overlay the
53
+ // panel splitter, as it sits within the same stacking context as the side nav. For consistency however,
54
+ // we check it as well.
55
+ const openPopupsInSideNav = openLayerObserver.getCount({
56
+ namespace: openLayerObserverSideNavNamespace,
57
+ type: 'popup'
58
+ });
59
+
60
+ // When there is an open layer in the top nav, the top nav is given a higher z-index than the side nav.
61
+ // This means the part of the side nav panel splitter that was sitting above the top nav will no longer
62
+ // be interactive (as it is now behind the top nav). So, we need to disable the entire panel splitter.
63
+ const openPopupsInTopNav = openLayerObserver.getCount({
64
+ namespace: openLayerObserverTopNavNamespace,
65
+ type: 'popup'
66
+ });
67
+ setIsEnabled(openPopupsInSideNav + openPopupsInTopNav === 0);
68
+ }
69
+
70
+ // Initial check, in case the app has loaded with an open popup.
71
+ checkAndSetState();
72
+
73
+ // Creating separate listeners for each namespace, to avoid running them when layers in other parts of the app change.
74
+ const cleanupSideNavListener = openLayerObserver.onChange(checkAndSetState, {
75
+ namespace: openLayerObserverSideNavNamespace
76
+ });
77
+ const cleanupTopNavListener = openLayerObserver.onChange(checkAndSetState, {
78
+ namespace: openLayerObserverTopNavNamespace
79
+ });
80
+ return function cleanup() {
81
+ cleanupSideNavListener();
82
+ cleanupTopNavListener();
83
+ };
84
+ }, [isFhsEnabled, openLayerObserver]);
85
+ if (!isEnabled && isFhsEnabled && fg('platform-dst-side-nav-layering-fixes')) {
86
+ return null;
87
+ }
33
88
  return /*#__PURE__*/React.createElement(OnDoubleClickContext.Provider, {
34
89
  value: shouldCollapseOnDoubleClick ? toggleSideNav : undefined
35
90
  }, /*#__PURE__*/React.createElement(PanelSplitter, {
@@ -1,3 +1,4 @@
1
+ ._10iwgc9s{timeline-scope:--sNcst}
1
2
  ._1ciragmp >:not([data-layout-slot]){display:none!important}
2
3
  ._1e0c11p5{display:grid}
3
4
  ._1lmcq9em{grid-template-areas:"banner" "top-bar" "main" "aside"}
@@ -3,8 +3,11 @@ import "./root.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useEffect, useRef } from 'react';
5
5
  import { OpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { SkipLinksProvider } from '../../context/skip-links/skip-links-provider';
7
8
  import { TopNavStartProvider } from '../../context/top-nav-start/top-nav-start-context-provider';
9
+ import { useIsFhsEnabled } from '../fhs-rollout/use-is-fhs-enabled';
10
+ import { sideNavContentScrollTimelineVar } from './constants';
8
11
  import { DangerouslyHoistSlotSizes } from './hoist-slot-sizes-context';
9
12
  import { SideNavElementProvider } from './side-nav/element-context';
10
13
  import { IsSideNavShortcutEnabledProvider } from './side-nav/is-side-nav-shortcut-enabled-context';
@@ -14,7 +17,8 @@ import { SideNavVisibilityProvider } from './side-nav/visibility-provider';
14
17
  // ID of the root element that the banner and top bar slots hoist their sizes to. Only internally exported.
15
18
  export const gridRootId = 'unsafe-design-system-page-layout-root';
16
19
  const styles = {
17
- root: "_1e0c11p5 _1tke1kxc _1lmcq9em _yv0ei47z _2z0516ab _1ciragmp _12fkuz0r _12qzrxre _1rqt70if _xkmgbaui _jbc7rxre _tyve1jg8"
20
+ root: "_1e0c11p5 _1tke1kxc _1lmcq9em _yv0ei47z _2z0516ab _1ciragmp _12fkuz0r _12qzrxre _1rqt70if _xkmgbaui _jbc7rxre _tyve1jg8",
21
+ sideNavScrollTimeline: "_10iwgc9s"
18
22
  };
19
23
 
20
24
  /**
@@ -31,6 +35,7 @@ export function Root({
31
35
  isSideNavShortcutEnabled = false
32
36
  }) {
33
37
  const ref = useRef(null);
38
+ const isFhsEnabled = useIsFhsEnabled();
34
39
  useEffect(() => {
35
40
  if (process.env.NODE_ENV !== 'production') {
36
41
  const IGNORED_ELEMENTS = ['SCRIPT', 'STYLE'];
@@ -64,7 +69,7 @@ This message will not be displayed in production.
64
69
  testId: testId
65
70
  }, /*#__PURE__*/React.createElement("div", {
66
71
  ref: ref,
67
- className: ax([styles.root, xcss]),
72
+ className: ax([styles.root, isFhsEnabled && fg('platform-dst-side-nav-layering-fixes') && styles.sideNavScrollTimeline, xcss]),
68
73
  id: gridRootId,
69
74
  "data-testid": testId
70
75
  }, children)))))))));
@@ -10,4 +10,5 @@
10
10
  ._i0dlf1ug{flex-basis:0%}
11
11
  ._j7hq13ly{animation-name:k1ywrstg}
12
12
  ._y4tiutpp{padding-inline-end:var(--ds-space-150,9pt)}
13
- @keyframes k1ywrstg{0%{box-shadow:none}0.1%{box-shadow:0 -1px var(--ds-border,#0b120e24)}to{box-shadow:0 -1px var(--ds-border,#0b120e24)}}
13
+ @keyframes k1ywrstg{0%{box-shadow:none}0.1%{box-shadow:0 -1px var(--ds-border,#0b120e24)}to{box-shadow:0 -1px var(--ds-border,#0b120e24)}}
14
+ @media (min-width:64rem){@supports (scroll-timeline-axis:block){._1sfqgc9s{scroll-timeline-name:--sNcst}._1q1x1ule{scroll-timeline-axis:block}html:has([data-private-side-nav-header]) ._8pm2gc9s{animation-timeline:--sNcst}html:has([data-private-side-nav-header]) ._1gd913ly{animation-name:k1ywrstg}}@supports (scroll-timeline-axis:block){@keyframes k1ywrstg{0%{box-shadow:none}0.1%{box-shadow:0 -1px var(--ds-border,#0b120e24)}to{box-shadow:0 -1px var(--ds-border,#0b120e24)}}}}
@@ -3,7 +3,10 @@ import "./side-nav-content.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { forwardRef, useMemo, useRef } from 'react';
5
5
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { useIsFhsEnabled } from '../../fhs-rollout/use-is-fhs-enabled';
8
+ import { sideNavContentScrollTimelineVar } from '../constants';
9
+ import { useSideNavVisibility } from './use-side-nav-visibility';
7
10
 
8
11
  /**
9
12
  * The main content of the side nav, filling up the middle section. It acts as a scroll container.
@@ -31,7 +34,8 @@ const styles = {
31
34
  const scrolledBorder = null;
32
35
  const scrollTimelineVar = '--sNcst';
33
36
  const fullHeightSidebarStyles = {
34
- scrollContainer: "_1un9baqb _21o1gc9s _j7hq13ly"
37
+ scrollContainer: "_1un9baqb _21o1gc9s _j7hq13ly",
38
+ scrollContainerWithLayeringFixes: "_1sfqgc9s _1q1x1ule _8pm2gc9s _1gd913ly"
35
39
  };
36
40
  function _SideNavContent({
37
41
  children,
@@ -40,10 +44,13 @@ function _SideNavContent({
40
44
  const isFhsEnabled = useIsFhsEnabled();
41
45
  const internalRef = useRef(null);
42
46
  const mergedRef = useMemo(() => mergeRefs([internalRef, forwardedRef]), [forwardedRef]);
47
+ const {
48
+ isExpandedOnDesktop
49
+ } = useSideNavVisibility();
43
50
  return /*#__PURE__*/React.createElement("div", {
44
51
  ref: isFhsEnabled ? mergedRef : forwardedRef,
45
52
  "data-testid": testId,
46
- className: ax([styles.scrollContainer, isFhsEnabled && fullHeightSidebarStyles.scrollContainer])
53
+ className: ax([styles.scrollContainer, isFhsEnabled && !fg('platform-dst-side-nav-layering-fixes') && fullHeightSidebarStyles.scrollContainer, isFhsEnabled && isExpandedOnDesktop && fg('platform-dst-side-nav-layering-fixes') && fullHeightSidebarStyles.scrollContainerWithLayeringFixes])
47
54
  }, /*#__PURE__*/React.createElement("div", {
48
55
  className: ax([styles.paddingContainer])
49
56
  }, children));
@@ -2,6 +2,7 @@
2
2
  import "./side-nav-header.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
  const styles = {
6
7
  root: "_18zrutpp _1q51utpp _85i51b66"
7
8
  };
@@ -13,6 +14,22 @@ export const SideNavHeader = ({
13
14
  children
14
15
  }) => {
15
16
  return /*#__PURE__*/React.createElement("div", {
17
+ /**
18
+ * This attribute is used to identify whether the SideNavHeader is mounted, to determine where the
19
+ * SideNavContent's scroll indicator line should be applied. This is for layering reasons -
20
+ * if the scroll indicator line intersects with the top nav, it could incorrectly be hidden beneath
21
+ * the top nav (depending on if a layer is open, which raises the top nav'z z-index).
22
+ *
23
+ * We are using a data attribute and CSS for this logic to ensure it is SSR safe.
24
+ *
25
+ * - If SideNavHeader exists, the scroll indicator line is applied to the SideNavContent. This is safe
26
+ * because the SideNavHeader is between the SideNavContent and TopNavStart, so the scroll indicator line
27
+ * will not intersect with the top nav.
28
+ *
29
+ * - If SideNavHeader does not exist, the scroll indicator line is applied to TopNavStart. This ensures
30
+ * the scroll indicator line is visible even when the top nav has a z-index higher than the side nav.
31
+ */
32
+ "data-private-side-nav-header": fg('platform-dst-side-nav-layering-fixes') ? 'true' : undefined,
16
33
  className: ax([styles.root])
17
34
  }, children);
18
35
  };
@@ -14,6 +14,9 @@
14
14
  ._4t3ieqxy{height:calc(100vh - var(--n_bnrM, 0px) - var(--n_tNvM, 0px))}
15
15
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
16
16
  ._kqsw1if8{position:sticky}
17
+ ._kqswstnw{position:absolute}
18
+ ._rjxpidpf{inset-inline-end:0}
19
+ ._u7coidpf{inset-block-end:0}
17
20
  ._vchhusvi{box-sizing:border-box}
18
21
  [dir=rtl] ._65m41mrw{--animation-direction:-1}
19
22
  @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrpfnf5{transition-duration:.2s}._1lh81gzg{grid-area:main}._1xq51mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}@starting-style{._1nu51p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}._1xq51ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}}