@atlaskit/navigation-system 2.19.1 → 2.21.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 (30) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cjs/ui/page-layout/side-nav/side-nav.compiled.css +5 -3
  3. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +8 -7
  4. package/dist/cjs/ui/page-layout/side-nav/toggle-button-context.js +2 -7
  5. package/dist/cjs/ui/page-layout/side-nav/toggle-button-provider.js +1 -13
  6. package/dist/cjs/ui/page-layout/side-nav/toggle-button.compiled.css +1 -2
  7. package/dist/cjs/ui/page-layout/side-nav/toggle-button.js +1 -18
  8. package/dist/cjs/ui/page-layout/top-nav/top-nav-start.compiled.css +8 -1
  9. package/dist/cjs/ui/page-layout/top-nav/top-nav-start.js +124 -8
  10. package/dist/es2019/ui/page-layout/side-nav/side-nav.compiled.css +5 -3
  11. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +8 -7
  12. package/dist/es2019/ui/page-layout/side-nav/toggle-button-context.js +1 -6
  13. package/dist/es2019/ui/page-layout/side-nav/toggle-button-provider.js +1 -14
  14. package/dist/es2019/ui/page-layout/side-nav/toggle-button.compiled.css +1 -2
  15. package/dist/es2019/ui/page-layout/side-nav/toggle-button.js +2 -19
  16. package/dist/es2019/ui/page-layout/top-nav/top-nav-start.compiled.css +8 -1
  17. package/dist/es2019/ui/page-layout/top-nav/top-nav-start.js +121 -8
  18. package/dist/esm/ui/page-layout/side-nav/side-nav.compiled.css +5 -3
  19. package/dist/esm/ui/page-layout/side-nav/side-nav.js +8 -7
  20. package/dist/esm/ui/page-layout/side-nav/toggle-button-context.js +1 -6
  21. package/dist/esm/ui/page-layout/side-nav/toggle-button-provider.js +1 -13
  22. package/dist/esm/ui/page-layout/side-nav/toggle-button.compiled.css +1 -2
  23. package/dist/esm/ui/page-layout/side-nav/toggle-button.js +2 -19
  24. package/dist/esm/ui/page-layout/top-nav/top-nav-start.compiled.css +8 -1
  25. package/dist/esm/ui/page-layout/top-nav/top-nav-start.js +124 -8
  26. package/dist/types/ui/page-layout/side-nav/toggle-button-context.d.ts +0 -4
  27. package/dist/types/ui/page-layout/side-nav/toggle-button-provider.d.ts +0 -8
  28. package/dist/types-ts4.5/ui/page-layout/side-nav/toggle-button-context.d.ts +0 -4
  29. package/dist/types-ts4.5/ui/page-layout/side-nav/toggle-button-provider.d.ts +0 -8
  30. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @atlassian/navigation-system
2
2
 
3
+ ## 2.21.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`3476b9c121ef9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3476b9c121ef9) -
8
+ Side nav animations have been updated to support right-to-left (RTL) languages/text direction.
9
+ This change is behind the feature gate `navx-full-height-sidebar`.
10
+
11
+ This includes:
12
+
13
+ - `SideNav` peek animations
14
+ - `SideNav` expand and collapse animations
15
+ - `TopNavStart` reorder animations
16
+
17
+ ## 2.20.0
18
+
19
+ ### Minor Changes
20
+
21
+ - [`bfed073f1849d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bfed073f1849d) -
22
+ Animations have been added to the `TopNavStart` component, as part of the full height sidebar
23
+ animations. The reorder of `TopNavStart`'s children elements (toggle button, app switcher, app
24
+ logo) when the side nav is toggled (on desktop) will have slide animations.
25
+
26
+ These changes are behind the feature gate `navx-full-height-sidebar`.
27
+
3
28
  ## 2.19.1
4
29
 
5
30
  ### Patch Changes
@@ -2,6 +2,7 @@
2
2
  ._nd5l1b6c{grid-area:main/aside/aside/aside}
3
3
  ._191wglyw{border-inline-start:none}
4
4
  ._t51zglyw{border-inline-end:none}._152timx3{inset-block-start:calc(var(--n_bnrM, 0px) + var(--n_tNvM, 0px))}
5
+ ._15yekb7n{--animation-direction:1}
5
6
  ._16qs1cd0{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #091e4226,0 0 1px #091e424f)}
6
7
  ._1bah1yb4{justify-content:space-between}
7
8
  ._1bsb1ego{width:min(90%,20pc)}
@@ -14,9 +15,10 @@
14
15
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
15
16
  ._kqsw1if8{position:sticky}
16
17
  ._vchhusvi{box-sizing:border-box}
17
- @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrp188d{transition-duration:.3s}._1lh81gzg{grid-area:main}._1xq51mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}@starting-style{._1nu5jq3t{transform:translateX(-100%)}}._1xq51ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}}
18
+ [dir=rtl] ._65m41mrw{--animation-direction:-1}
19
+ @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrp188d{transition-duration:.3s}._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)}}
18
20
  @media (min-width:48rem){._14b5hc79{width:var(--n_snvRsz,var(--n_sNvw))}}
19
21
  @media (min-width:64rem){._165t56xv{height:calc(100vh - var(--n_bnrM, 0px))}._180k1wjm{inset-block-start:calc(var(--n_bnrM, 0px))}._26vxoned{padding-block-start:calc(var(--n_tNvM, 0px))}._1mt19dtb{margin-block-start:calc(var(--n_tNvM, 0px)*-1)}._dm2518uv{display:initial}._dm25glyw{display:none}._qiln1gzg{grid-area:main}._p5clglyw{border-inline-end:none}._4ap31bhr{background-color:var(--ds-surface-overlay,#fff)}._scbp1cd0{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #091e4226,0 0 1px #091e424f)}._qilnk0mc{grid-area:side-nav}._p5cl7r9e{border-inline-end:var(--ds-border-width,1px) solid var(--ds-border,#091e4224)}._4ap3vuon{background-color:var(--ds-surface,#fff)}._scbpglyw{box-shadow:none}}
20
- @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._17ly8iot{transition-property:transform,display}._177m1a5r{transition-behavior:allow-discrete}._1sg81gzg{grid-area:main}._vgub1mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}._hh1ujq3t{transform:translateX(-100%)}@starting-style{._s2egjq3t{transform:translateX(-100%)}}._1sg8k0mc{grid-area:side-nav}._vgub1ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}._hjoi188d{transition-duration:.3s}._hjoifnf5{transition-duration:.2s}}
21
- @media (prefers-reduced-motion:no-preference) and (not (min-width:64rem)){._aadijq3t{transform:translateX(-100%)}}
22
+ @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._17ly8iot{transition-property:transform,display}._177m1a5r{transition-behavior:allow-discrete}._1sg81gzg{grid-area:main}._vgub1mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}._hh1u1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}@starting-style{._s2eg1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}._1sg8k0mc{grid-area:side-nav}._vgub1ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}._hjoi188d{transition-duration:.3s}._hjoifnf5{transition-duration:.2s}}
23
+ @media (prefers-reduced-motion:no-preference) and (not (min-width:64rem)){._aadi1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}
22
24
  @supports not (-moz-appearance:none){@media (prefers-reduced-motion:no-preference){._139f8iot{transition-property:transform,display}._1tpvfnf5{transition-duration:.2s}._sylc1a5r{transition-behavior:allow-discrete}._1uwsjq3t{transform:translateX(-100%)}}@media (prefers-reduced-motion:no-preference){@starting-style{._oyeijq3t{transform:translateX(-100%)}}._139f8iot{transition-property:transform,display}._1tpvfnf5{transition-duration:.2s}._sylc1a5r{transition-behavior:allow-discrete}}}
@@ -61,18 +61,19 @@ var styles = {
61
61
  root: "_nd5l1b6c _191wglyw _t51zglyw _bfhk1bhr _16qs1cd0 _vchhusvi _4t3ieqxy _152timx3 _kqsw1if8 _1bsb1ego _1pbycs5v _14b5hc79 _qilnk0mc _p5cl7r9e _4ap3vuon _scbpglyw",
62
62
  flyoutOpen: "_qiln1gzg _p5clglyw _4ap31bhr _scbp1cd0 _139f8iot _1tpvfnf5 _sylc1a5r _oyeijq3t",
63
63
  flyoutAnimateClosed: "_1e0cglyw _qiln1gzg _139f8iot _1tpvfnf5 _sylc1a5r _1uwsjq3t",
64
+ animationRTLSupport: "_15yekb7n _65m41mrw",
64
65
  flyoutBaseStylesFullHeightSidebar: "_qiln1gzg _p5clglyw _4ap31bhr _scbp1cd0 _17ly8iot _177m1a5r",
65
- flyoutOpenFullHeightSidebar: "_hjoi188d _vgub1ku9 _s2egjq3t",
66
- flyoutAnimateClosedFullHeightSidebar: "_dm25glyw _hjoifnf5 _vgub1mm8 _hh1ujq3t",
66
+ flyoutOpenFullHeightSidebar: "_hjoi188d _vgub1ku9 _s2eg1p9u",
67
+ flyoutAnimateClosedFullHeightSidebar: "_dm25glyw _hjoifnf5 _vgub1mm8 _hh1u1p9u",
67
68
  flexContainer: "_4t3i1osq _1e0c1txw _2lx21bp4 _1bah1yb4",
68
69
  hiddenMobileAndDesktop: "_1e0cglyw",
69
70
  hiddenMobileOnly: "_1e0cglyw _dm2518uv",
70
71
  hiddenDesktopOnly: "_dm25glyw",
71
72
  animationBaseStyles: "_10t88iot _1vrh1a5r _xrrp188d",
72
- expandAnimationMobile: "_1xq51ku9 _1nu5jq3t",
73
- collapseAnimationMobile: "_1lh81gzg _1xq51mm8 _aadijq3t",
74
- expandAnimationDesktop: "_1sg8k0mc _vgub1ku9 _s2egjq3t",
75
- collapseAnimationDesktop: "_1sg81gzg _vgub1mm8 _hh1ujq3t",
73
+ expandAnimationMobile: "_1xq51ku9 _1nu51p9u",
74
+ collapseAnimationMobile: "_1lh81gzg _1xq51mm8 _aadi1p9u",
75
+ expandAnimationDesktop: "_1sg8k0mc _vgub1ku9 _s2eg1p9u",
76
+ collapseAnimationDesktop: "_1sg81gzg _vgub1mm8 _hh1u1p9u",
76
77
  fullHeightSidebar: "_165t56xv _180k1wjm _26vxoned _1mt19dtb"
77
78
  };
78
79
  var fallbackDefaultWidth = 320;
@@ -632,7 +633,7 @@ function SideNavInternal(_ref) {
632
633
  style: (0, _defineProperty2.default)({}, _constants.sideNavVar, clampedWidth),
633
634
  ref: mergedRef,
634
635
  "data-testid": testId,
635
- className: (0, _runtime.ax)([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !(0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !(0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, isFlyoutClosed && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.fullHeightSidebar])
636
+ className: (0, _runtime.ax)([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.animationRTLSupport, shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !(0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !(0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, isFlyoutClosed && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && styles.fullHeightSidebar])
636
637
  }), /*#__PURE__*/React.createElement(_hoistUtils.DangerouslyHoistCssVarToDocumentRoot, {
637
638
  variableName: _constants.sideNavLiveWidthVar,
638
639
  value: "0px",
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.SideNavToggleButtonSlotContext = exports.SideNavToggleButtonElement = exports.SideNavToggleButtonAttachRef = void 0;
7
+ exports.SideNavToggleButtonElement = exports.SideNavToggleButtonAttachRef = void 0;
8
8
  var _react = require("react");
9
9
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
10
10
  /**
@@ -23,9 +23,4 @@ var SideNavToggleButtonElement = exports.SideNavToggleButtonElement = /*#__PURE_
23
23
  * A callback ref is needed because the side nav can be mounted before the elements in the top bar (e.g. if the element
24
24
  * is lazy loaded, which happens in Jira and Confluence), which would prevent the event listeners from being set up.
25
25
  */
26
- var SideNavToggleButtonAttachRef = exports.SideNavToggleButtonAttachRef = /*#__PURE__*/(0, _react.createContext)(_noop.default);
27
-
28
- /**
29
- * Used to check if the SideNavToggleButton is rendered inside of its slot in `TopNavStart`.
30
- */
31
- var SideNavToggleButtonSlotContext = exports.SideNavToggleButtonSlotContext = /*#__PURE__*/(0, _react.createContext)(false);
26
+ var SideNavToggleButtonAttachRef = exports.SideNavToggleButtonAttachRef = /*#__PURE__*/(0, _react.createContext)(_noop.default);
@@ -5,7 +5,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.SideNavToggleButtonSlotProvider = exports.SideNavToggleButtonProvider = void 0;
8
+ exports.SideNavToggleButtonProvider = void 0;
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _toggleButtonContext = require("./toggle-button-context");
@@ -34,16 +34,4 @@ var SideNavToggleButtonProvider = exports.SideNavToggleButtonProvider = function
34
34
  }, /*#__PURE__*/_react.default.createElement(_toggleButtonContext.SideNavToggleButtonAttachRef.Provider, {
35
35
  value: setElement
36
36
  }, children));
37
- };
38
-
39
- /**
40
- * Provider for the side nav toggle button slot.
41
- *
42
- * This allows us to determine if the toggle button is rendered inside or outside of its slot.
43
- */
44
- var SideNavToggleButtonSlotProvider = exports.SideNavToggleButtonSlotProvider = function SideNavToggleButtonSlotProvider(_ref2) {
45
- var children = _ref2.children;
46
- return /*#__PURE__*/_react.default.createElement(_toggleButtonContext.SideNavToggleButtonSlotContext.Provider, {
47
- value: true
48
- }, children);
49
37
  };
@@ -1,3 +1,2 @@
1
1
  ._1e0c1bgi{display:contents}
2
- ._lcxvglyw{pointer-events:none}
3
- @media (min-width:64rem){._3l1a1wug{margin-inline-start:auto}}
2
+ ._lcxvglyw{pointer-events:none}
@@ -32,12 +32,6 @@ var toggleButtonTooltipOptions = {
32
32
  // For duplicate "mouseenter" issue when changing icons (see below)
33
33
  var silentIconStyles = null;
34
34
 
35
- /**
36
- * Wrapper styles to align the toggle button to the end of `TopNavStart`
37
- * when FHS is expanded.
38
- */
39
- var fullHeightSidebarExpandedWrapperStyles = null;
40
-
41
35
  /**
42
36
  * __SideNavToggleButton__
43
37
  *
@@ -144,7 +138,7 @@ var SideNavToggleButton = exports.SideNavToggleButton = function SideNavToggleBu
144
138
  }
145
139
  return toggleButtonTooltipOptions;
146
140
  }, [shortcut]);
147
- var iconButton = /*#__PURE__*/_react.default.createElement(_migration.IconButton, {
141
+ return /*#__PURE__*/_react.default.createElement(_migration.IconButton, {
148
142
  appearance: "subtle",
149
143
  label: isSideNavExpanded ? collapseLabel : expandLabel,
150
144
  icon: icon,
@@ -155,15 +149,4 @@ var SideNavToggleButton = exports.SideNavToggleButton = function SideNavToggleBu
155
149
  ref: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_toggle_ref_fix') ? setElement : elementRef,
156
150
  tooltip: tooltipProps
157
151
  });
158
- var isInsideSlot = (0, _react.useContext)(_toggleButtonContext.SideNavToggleButtonSlotContext);
159
-
160
- // Checking `isInsideSlot` in case an app isn't using the slot
161
- // We don't want to break existing non-slot usage with the left margin
162
- // This check can be removed in the future, after slot is required for a while.
163
- if (isInsideSlot && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
164
- return /*#__PURE__*/_react.default.createElement("div", {
165
- className: (0, _runtime.ax)([isSideNavExpandedOnDesktop && "_3l1a1wug"])
166
- }, iconButton);
167
- }
168
- return iconButton;
169
152
  };
@@ -1,9 +1,16 @@
1
1
 
2
2
  ._zulp1b66{gap:var(--ds-space-050,4px)}
3
- ._yyhykb7n{grid-column:1}._1e0c1txw{display:flex}
3
+ ._zulp1kw7{gap:inherit}
4
+ ._yyhykb7n{grid-column:1}._15yekb7n{--animation-direction:1}
5
+ ._1e0c1kw7{display:inherit}
6
+ ._1e0c1txw{display:flex}
7
+ ._1ul9idpf{min-width:0}
4
8
  ._4cvr1h6o{align-items:center}
5
9
  ._4t3i1osq{height:100%}
10
+ ._ahbq1wug{margin-inline-start:auto}
6
11
  ._bozgutpp{padding-inline-start:var(--ds-space-150,9pt)}
7
12
  ._lcxv1wug{pointer-events:auto}
8
13
  ._vchhusvi{box-sizing:border-box}
14
+ [dir=rtl] ._65m41mrw{--animation-direction:-1}
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)}._xrrp188d{transition-duration:.3s}._bgpzkb7n{opacity:1}}
9
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)}}
@@ -11,12 +11,24 @@ require("./top-nav-start.compiled.css");
11
11
  var _runtime = require("@compiled/react/runtime");
12
12
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
13
  var _react = _interopRequireWildcard(require("react"));
14
+ var _useStableRef = _interopRequireDefault(require("@atlaskit/ds-lib/use-stable-ref"));
14
15
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
16
  var _compiled = require("@atlaskit/primitives/compiled");
16
17
  var _topNavStartContext = require("../../../context/top-nav-start/top-nav-start-context");
17
- var _toggleButtonProvider = require("../side-nav/toggle-button-provider");
18
18
  var _useSideNavVisibility3 = require("../side-nav/use-side-nav-visibility");
19
19
  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); }
20
+ /**
21
+ * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
22
+ *
23
+ * We are using JS to detect Firefox and disable animations, instead of using CSS, as Compiled currently does not merge duplicate
24
+ * CSS at-rules when at-rules are nested: https://github.com/atlassian-labs/compiled/blob/e04a325915e1d13010205089e4915de0e53bc2d4/packages/css/src/plugins/merge-duplicate-at-rules.ts#L5
25
+ * Avoiding nesting the `@supports` at-rule inside of `@media` means Compiled can remove duplicate styles from the generated CSS.
26
+ */
27
+ var isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
28
+
29
+ // Placed in a variable, as the value is used in the translateX value for the children wrapper animation.
30
+ var flexGap = "var(--ds-space-050, 4px)";
31
+
20
32
  /**
21
33
  * Styles for the TopNavStart element.
22
34
  *
@@ -39,10 +51,48 @@ var innerStyles = {
39
51
  var wrapperStyles = {
40
52
  root: "_vchhusvi",
41
53
  fullHeightSidebar: "_bozgutpp",
42
- fullHeightSidebarCollapsed: "_15rip2n4",
43
54
  fullHeightSidebarExpanded: "_glte93mn _exxmpxbi"
44
55
  };
45
56
 
57
+ /**
58
+ * We use a fixed translateX offset for the slide animation (used when the TopNavStart children elements are reordered).
59
+ * This fixed offset makes the elements appear to animate smoothly from the old to the new position.
60
+ * This offset is calculated based on:
61
+ * - 32px (2rem) width of the side nav toggle button (IconButton)
62
+ * - 4px gap ('space.050' token) of the flex container
63
+ *
64
+ * The benefit of hardcoding this offset is that we don't need to calculate it using JS each time the sidebar is toggled.
65
+ * However, it could become out of sync if the width of IconButton changes.
66
+ *
67
+ * The alternative is using JS to store the previous position of the children wrapper element, and calculate the offset based on
68
+ * the new position, and then transforming using that offset. This would prevent the animation from going out of sync.
69
+ */
70
+ var childrenWrapperAnimationOffset = "calc(2rem + ".concat(flexGap, ")");
71
+ var childrenWrapperStyles = {
72
+ root: "_zulp1kw7 _1e0c1kw7 _1ul9idpf _15yekb7n _65m41mrw",
73
+ animationBaseStyles: "_10t81e03",
74
+ finalPosition: "_mjvcz12g _xrrp188d",
75
+ expandAnimationStartPosition: "_mjvcyrjp",
76
+ collapseAnimationStartPosition: "_mjvco0k7"
77
+ };
78
+
79
+ /**
80
+ * We use a fixed translateX offset for the toggle button slide animation (used when the TopNavStart children elements are reordered).
81
+ * The specific value doesn't matter too much for the toggle button animation, so we are using `100%`, which will match the toggle button width.
82
+ *
83
+ * By combining the `translateX` animation with an `opacity` fade, the feel and experience is actually quite similar to animating the
84
+ * element from the exact old position (offset), and it avoids the additional complexity of needing to track and calculate the exact offset.
85
+ */
86
+ var toggleButtonWrapperStyles = {
87
+ root: "_15yekb7n _65m41mrw _10t81rjc",
88
+ finalPosition: "_mjvcz12g _xrrp188d _bgpzkb7n",
89
+ expandAnimationStartPosition: "_mjvc1p9u _bgpzidpf",
90
+ collapseAnimationStartPosition: "_mjvc1efy _bgpzidpf",
91
+ expandAnimationTimingFunction: "_1xq51ytf",
92
+ collapseAnimationTimingFunction: "_1xq55ucs",
93
+ alignEnd: "_ahbq1wug"
94
+ };
95
+
46
96
  /**
47
97
  * The consistent key used for the side nav toggle button to ensure it does not get remounted
48
98
  * when it is reordered.
@@ -122,15 +172,81 @@ function TopNavStart(_ref3) {
122
172
  (0, _compiled.UNSAFE_useMediaQuery)('above.md', function (event) {
123
173
  setIsDesktop(event.matches);
124
174
  });
175
+ var _useState3 = (0, _react.useState)({
176
+ type: 'idle'
177
+ }),
178
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
179
+ animationState = _useState4[0],
180
+ setAnimationState = _useState4[1];
181
+
182
+ // Used to prevent the reorder animations from running on the initial render.
183
+ var isFirstRenderRef = (0, _react.useRef)(true);
184
+ (0, _react.useEffect)(function () {
185
+ if (!(0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
186
+ return;
187
+ }
188
+ if (isFirstRenderRef.current) {
189
+ isFirstRenderRef.current = false;
190
+ }
191
+ }, []);
192
+
193
+ // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
194
+ // can happen a lot (e.g. if the parent re-renders)
195
+ var sideNavToggleButtonStableRef = (0, _useStableRef.default)(sideNavToggleButton);
196
+ (0, _react.useLayoutEffect)(function () {
197
+ if (!(0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
198
+ return;
199
+ }
200
+
201
+ /**
202
+ * This layout effect is used to animate the TopNavStart children elements to their new position after being reordered.
203
+ * It is called when the sidebar's desktop expansion state changes.
204
+ *
205
+ * It works by first setting a translateX offset on the elements, used as the start position of the slide animation.
206
+ * - For the toggle button, it's a fixed offset. It's combined with an opacity, so the exact offset doesn't matter too much.
207
+ * - For the children wrapper (wrapping everything except the toggle button), an offset was chosen to make the animation
208
+ * start position the exact same as the element's old position. See comments for `childrenWrapperStyles` for more details.
209
+ *
210
+ * On the next frame, the translateX offset is cleared, triggering the animation to the new position.
211
+ */
212
+
213
+ if (isFirstRenderRef.current) {
214
+ // No animations on initial render.
215
+ return;
216
+ }
217
+ if (!sideNavToggleButtonStableRef.current) {
218
+ // If there is no toggle button, there should be no re-order animations.
219
+ return;
220
+ }
221
+
222
+ // Set the translateX offsets so elements are ready to animate to their actual new position after being reordered
223
+ setAnimationState({
224
+ type: isExpandedOnDesktop ? 'expand' : 'collapse'
225
+ });
226
+ requestAnimationFrame(function () {
227
+ // Clear translateX offsets on next frame to trigger animation to new position in a re-render
228
+ setAnimationState({
229
+ type: 'idle'
230
+ });
231
+ });
232
+
233
+ // This layout effect is called when the sidebar's desktop expansion state changes.
234
+ }, [isExpandedOnDesktop, sideNavToggleButtonStableRef]);
125
235
  var TopNavStartInner = (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') ? TopNavStartInnerFHS : TopNavStartInnerOld;
126
236
  return /*#__PURE__*/_react.default.createElement(TopNavStartInner, {
127
237
  ref: elementRef,
128
238
  testId: testId
129
- }, !(0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && /*#__PURE__*/_react.default.createElement(_toggleButtonProvider.SideNavToggleButtonSlotProvider, {
130
- key: sideNavToggleButtonKey
131
- }, sideNavToggleButton), sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && /*#__PURE__*/_react.default.createElement(_toggleButtonProvider.SideNavToggleButtonSlotProvider, {
132
- key: sideNavToggleButtonKey
133
- }, sideNavToggleButton), children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && /*#__PURE__*/_react.default.createElement(_toggleButtonProvider.SideNavToggleButtonSlotProvider, {
134
- key: sideNavToggleButtonKey
239
+ }, !(0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && sideNavToggleButton, sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && /*#__PURE__*/_react.default.createElement("div", {
240
+ key: sideNavToggleButtonKey,
241
+ className: (0, _runtime.ax)([!isFirefox && toggleButtonWrapperStyles.root, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
242
+ // Timing function is applied when the browser animates to the idle position.
243
+ animationState.type === 'idle' && toggleButtonWrapperStyles.collapseAnimationTimingFunction, !isFirefox && animationState.type === 'collapse' && toggleButtonWrapperStyles.collapseAnimationStartPosition])
244
+ }, sideNavToggleButton), (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') ? /*#__PURE__*/_react.default.createElement("div", {
245
+ className: (0, _runtime.ax)([childrenWrapperStyles.root, !isFirefox && childrenWrapperStyles.animationBaseStyles, !isFirefox && animationState.type === 'idle' && childrenWrapperStyles.finalPosition, !isFirefox && animationState.type === 'expand' && childrenWrapperStyles.expandAnimationStartPosition, !isFirefox && animationState.type === 'collapse' && childrenWrapperStyles.collapseAnimationStartPosition])
246
+ }, children) : children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && (0, _platformFeatureFlags.fg)('navx-full-height-sidebar') && /*#__PURE__*/_react.default.createElement("div", {
247
+ key: sideNavToggleButtonKey,
248
+ className: (0, _runtime.ax)([!isFirefox && toggleButtonWrapperStyles.root, toggleButtonWrapperStyles.alignEnd, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
249
+ // Timing function is applied when the browser animates to the idle position.
250
+ animationState.type === 'idle' && toggleButtonWrapperStyles.expandAnimationTimingFunction, !isFirefox && animationState.type === 'expand' && toggleButtonWrapperStyles.expandAnimationStartPosition])
135
251
  }, sideNavToggleButton));
136
252
  }
@@ -2,6 +2,7 @@
2
2
  ._nd5l1b6c{grid-area:main/aside/aside/aside}
3
3
  ._191wglyw{border-inline-start:none}
4
4
  ._t51zglyw{border-inline-end:none}._152timx3{inset-block-start:calc(var(--n_bnrM, 0px) + var(--n_tNvM, 0px))}
5
+ ._15yekb7n{--animation-direction:1}
5
6
  ._16qs1cd0{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #091e4226,0 0 1px #091e424f)}
6
7
  ._1bah1yb4{justify-content:space-between}
7
8
  ._1bsb1ego{width:min(90%,20pc)}
@@ -14,9 +15,10 @@
14
15
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
15
16
  ._kqsw1if8{position:sticky}
16
17
  ._vchhusvi{box-sizing:border-box}
17
- @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrp188d{transition-duration:.3s}._1lh81gzg{grid-area:main}._1xq51mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}@starting-style{._1nu5jq3t{transform:translateX(-100%)}}._1xq51ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}}
18
+ [dir=rtl] ._65m41mrw{--animation-direction:-1}
19
+ @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrp188d{transition-duration:.3s}._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)}}
18
20
  @media (min-width:48rem){._14b5hc79{width:var(--n_snvRsz,var(--n_sNvw))}}
19
21
  @media (min-width:64rem){._165t56xv{height:calc(100vh - var(--n_bnrM, 0px))}._180k1wjm{inset-block-start:calc(var(--n_bnrM, 0px))}._26vxoned{padding-block-start:calc(var(--n_tNvM, 0px))}._1mt19dtb{margin-block-start:calc(var(--n_tNvM, 0px)*-1)}._dm2518uv{display:initial}._dm25glyw{display:none}._qiln1gzg{grid-area:main}._p5clglyw{border-inline-end:none}._4ap31bhr{background-color:var(--ds-surface-overlay,#fff)}._scbp1cd0{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #091e4226,0 0 1px #091e424f)}._qilnk0mc{grid-area:side-nav}._p5cl7r9e{border-inline-end:var(--ds-border-width,1px) solid var(--ds-border,#091e4224)}._4ap3vuon{background-color:var(--ds-surface,#fff)}._scbpglyw{box-shadow:none}}
20
- @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._17ly8iot{transition-property:transform,display}._177m1a5r{transition-behavior:allow-discrete}._1sg81gzg{grid-area:main}._vgub1mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}._hh1ujq3t{transform:translateX(-100%)}@starting-style{._s2egjq3t{transform:translateX(-100%)}}._1sg8k0mc{grid-area:side-nav}._vgub1ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}._hjoi188d{transition-duration:.3s}._hjoifnf5{transition-duration:.2s}}
21
- @media (prefers-reduced-motion:no-preference) and (not (min-width:64rem)){._aadijq3t{transform:translateX(-100%)}}
22
+ @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._17ly8iot{transition-property:transform,display}._177m1a5r{transition-behavior:allow-discrete}._1sg81gzg{grid-area:main}._vgub1mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}._hh1u1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}@starting-style{._s2eg1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}._1sg8k0mc{grid-area:side-nav}._vgub1ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}._hjoi188d{transition-duration:.3s}._hjoifnf5{transition-duration:.2s}}
23
+ @media (prefers-reduced-motion:no-preference) and (not (min-width:64rem)){._aadi1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}
22
24
  @supports not (-moz-appearance:none){@media (prefers-reduced-motion:no-preference){._139f8iot{transition-property:transform,display}._1tpvfnf5{transition-duration:.2s}._sylc1a5r{transition-behavior:allow-discrete}._1uwsjq3t{transform:translateX(-100%)}}@media (prefers-reduced-motion:no-preference){@starting-style{._oyeijq3t{transform:translateX(-100%)}}._139f8iot{transition-property:transform,display}._1tpvfnf5{transition-duration:.2s}._sylc1a5r{transition-behavior:allow-discrete}}}
@@ -48,18 +48,19 @@ const styles = {
48
48
  root: "_nd5l1b6c _191wglyw _t51zglyw _bfhk1bhr _16qs1cd0 _vchhusvi _4t3ieqxy _152timx3 _kqsw1if8 _1bsb1ego _1pbycs5v _14b5hc79 _qilnk0mc _p5cl7r9e _4ap3vuon _scbpglyw",
49
49
  flyoutOpen: "_qiln1gzg _p5clglyw _4ap31bhr _scbp1cd0 _139f8iot _1tpvfnf5 _sylc1a5r _oyeijq3t",
50
50
  flyoutAnimateClosed: "_1e0cglyw _qiln1gzg _139f8iot _1tpvfnf5 _sylc1a5r _1uwsjq3t",
51
+ animationRTLSupport: "_15yekb7n _65m41mrw",
51
52
  flyoutBaseStylesFullHeightSidebar: "_qiln1gzg _p5clglyw _4ap31bhr _scbp1cd0 _17ly8iot _177m1a5r",
52
- flyoutOpenFullHeightSidebar: "_hjoi188d _vgub1ku9 _s2egjq3t",
53
- flyoutAnimateClosedFullHeightSidebar: "_dm25glyw _hjoifnf5 _vgub1mm8 _hh1ujq3t",
53
+ flyoutOpenFullHeightSidebar: "_hjoi188d _vgub1ku9 _s2eg1p9u",
54
+ flyoutAnimateClosedFullHeightSidebar: "_dm25glyw _hjoifnf5 _vgub1mm8 _hh1u1p9u",
54
55
  flexContainer: "_4t3i1osq _1e0c1txw _2lx21bp4 _1bah1yb4",
55
56
  hiddenMobileAndDesktop: "_1e0cglyw",
56
57
  hiddenMobileOnly: "_1e0cglyw _dm2518uv",
57
58
  hiddenDesktopOnly: "_dm25glyw",
58
59
  animationBaseStyles: "_10t88iot _1vrh1a5r _xrrp188d",
59
- expandAnimationMobile: "_1xq51ku9 _1nu5jq3t",
60
- collapseAnimationMobile: "_1lh81gzg _1xq51mm8 _aadijq3t",
61
- expandAnimationDesktop: "_1sg8k0mc _vgub1ku9 _s2egjq3t",
62
- collapseAnimationDesktop: "_1sg81gzg _vgub1mm8 _hh1ujq3t",
60
+ expandAnimationMobile: "_1xq51ku9 _1nu51p9u",
61
+ collapseAnimationMobile: "_1lh81gzg _1xq51mm8 _aadi1p9u",
62
+ expandAnimationDesktop: "_1sg8k0mc _vgub1ku9 _s2eg1p9u",
63
+ collapseAnimationDesktop: "_1sg81gzg _vgub1mm8 _hh1u1p9u",
63
64
  fullHeightSidebar: "_165t56xv _180k1wjm _26vxoned _1mt19dtb"
64
65
  };
65
66
  const fallbackDefaultWidth = 320;
@@ -624,7 +625,7 @@ function SideNavInternal({
624
625
  },
625
626
  ref: mergedRef,
626
627
  "data-testid": testId,
627
- className: ax([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !fg('navx-full-height-sidebar') && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !fg('navx-full-height-sidebar') && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, isFlyoutClosed && fg('navx-full-height-sidebar') && styles.fullHeightSidebar])
628
+ className: ax([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, fg('navx-full-height-sidebar') && styles.animationRTLSupport, shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !fg('navx-full-height-sidebar') && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !fg('navx-full-height-sidebar') && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, isFlyoutClosed && fg('navx-full-height-sidebar') && styles.fullHeightSidebar])
628
629
  }), /*#__PURE__*/React.createElement(DangerouslyHoistCssVarToDocumentRoot, {
629
630
  variableName: sideNavLiveWidthVar,
630
631
  value: "0px",
@@ -16,9 +16,4 @@ export const SideNavToggleButtonElement = /*#__PURE__*/createContext(null);
16
16
  * A callback ref is needed because the side nav can be mounted before the elements in the top bar (e.g. if the element
17
17
  * is lazy loaded, which happens in Jira and Confluence), which would prevent the event listeners from being set up.
18
18
  */
19
- export const SideNavToggleButtonAttachRef = /*#__PURE__*/createContext(__noop);
20
-
21
- /**
22
- * Used to check if the SideNavToggleButton is rendered inside of its slot in `TopNavStart`.
23
- */
24
- export const SideNavToggleButtonSlotContext = /*#__PURE__*/createContext(false);
19
+ export const SideNavToggleButtonAttachRef = /*#__PURE__*/createContext(__noop);
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from 'react';
2
- import { SideNavToggleButtonAttachRef, SideNavToggleButtonElement, SideNavToggleButtonSlotContext } from './toggle-button-context';
2
+ import { SideNavToggleButtonAttachRef, SideNavToggleButtonElement } from './toggle-button-context';
3
3
 
4
4
  /**
5
5
  * Provider for the side nav toggle button contexts.
@@ -23,17 +23,4 @@ export const SideNavToggleButtonProvider = ({
23
23
  }, /*#__PURE__*/React.createElement(SideNavToggleButtonAttachRef.Provider, {
24
24
  value: setElement
25
25
  }, children));
26
- };
27
-
28
- /**
29
- * Provider for the side nav toggle button slot.
30
- *
31
- * This allows us to determine if the toggle button is rendered inside or outside of its slot.
32
- */
33
- export const SideNavToggleButtonSlotProvider = ({
34
- children
35
- }) => {
36
- return /*#__PURE__*/React.createElement(SideNavToggleButtonSlotContext.Provider, {
37
- value: true
38
- }, children);
39
26
  };
@@ -1,3 +1,2 @@
1
1
  ._1e0c1bgi{display:contents}
2
- ._lcxvglyw{pointer-events:none}
3
- @media (min-width:64rem){._3l1a1wug{margin-inline-start:auto}}
2
+ ._lcxvglyw{pointer-events:none}
@@ -7,7 +7,7 @@ import SidebarCollapseIcon from '@atlaskit/icon/core/sidebar-collapse';
7
7
  import SidebarExpandIcon from '@atlaskit/icon/core/sidebar-expand';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { IconButton } from '../../top-nav-items/themed/migration';
10
- import { SideNavToggleButtonAttachRef, SideNavToggleButtonSlotContext } from './toggle-button-context';
10
+ import { SideNavToggleButtonAttachRef } from './toggle-button-context';
11
11
  import { useSideNavVisibility } from './use-side-nav-visibility';
12
12
  import { useToggleSideNav } from './use-toggle-side-nav';
13
13
  const toggleButtonTooltipOptions = {
@@ -19,12 +19,6 @@ const toggleButtonTooltipOptions = {
19
19
  // For duplicate "mouseenter" issue when changing icons (see below)
20
20
  const silentIconStyles = null;
21
21
 
22
- /**
23
- * Wrapper styles to align the toggle button to the end of `TopNavStart`
24
- * when FHS is expanded.
25
- */
26
- const fullHeightSidebarExpandedWrapperStyles = null;
27
-
28
22
  /**
29
23
  * __SideNavToggleButton__
30
24
  *
@@ -125,7 +119,7 @@ export const SideNavToggleButton = ({
125
119
  }
126
120
  return toggleButtonTooltipOptions;
127
121
  }, [shortcut]);
128
- const iconButton = /*#__PURE__*/React.createElement(IconButton, {
122
+ return /*#__PURE__*/React.createElement(IconButton, {
129
123
  appearance: "subtle",
130
124
  label: isSideNavExpanded ? collapseLabel : expandLabel,
131
125
  icon: icon,
@@ -136,15 +130,4 @@ export const SideNavToggleButton = ({
136
130
  ref: fg('platform_dst_nav4_side_nav_toggle_ref_fix') ? setElement : elementRef,
137
131
  tooltip: tooltipProps
138
132
  });
139
- const isInsideSlot = useContext(SideNavToggleButtonSlotContext);
140
-
141
- // Checking `isInsideSlot` in case an app isn't using the slot
142
- // We don't want to break existing non-slot usage with the left margin
143
- // This check can be removed in the future, after slot is required for a while.
144
- if (isInsideSlot && fg('navx-full-height-sidebar')) {
145
- return /*#__PURE__*/React.createElement("div", {
146
- className: ax([isSideNavExpandedOnDesktop && "_3l1a1wug"])
147
- }, iconButton);
148
- }
149
- return iconButton;
150
133
  };
@@ -1,9 +1,16 @@
1
1
 
2
2
  ._zulp1b66{gap:var(--ds-space-050,4px)}
3
- ._yyhykb7n{grid-column:1}._1e0c1txw{display:flex}
3
+ ._zulp1kw7{gap:inherit}
4
+ ._yyhykb7n{grid-column:1}._15yekb7n{--animation-direction:1}
5
+ ._1e0c1kw7{display:inherit}
6
+ ._1e0c1txw{display:flex}
7
+ ._1ul9idpf{min-width:0}
4
8
  ._4cvr1h6o{align-items:center}
5
9
  ._4t3i1osq{height:100%}
10
+ ._ahbq1wug{margin-inline-start:auto}
6
11
  ._bozgutpp{padding-inline-start:var(--ds-space-150,9pt)}
7
12
  ._lcxv1wug{pointer-events:auto}
8
13
  ._vchhusvi{box-sizing:border-box}
14
+ [dir=rtl] ._65m41mrw{--animation-direction:-1}
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)}._xrrp188d{transition-duration:.3s}._bgpzkb7n{opacity:1}}
9
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)}}
@@ -2,12 +2,24 @@
2
2
  import "./top-nav-start.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { forwardRef, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
5
+ import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
5
6
  import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { UNSAFE_useMediaQuery } from '@atlaskit/primitives/compiled';
7
8
  import { TopNavStartAttachRef } from '../../../context/top-nav-start/top-nav-start-context';
8
- import { SideNavToggleButtonSlotProvider } from '../side-nav/toggle-button-provider';
9
9
  import { useSideNavVisibility } from '../side-nav/use-side-nav-visibility';
10
10
 
11
+ /**
12
+ * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
13
+ *
14
+ * We are using JS to detect Firefox and disable animations, instead of using CSS, as Compiled currently does not merge duplicate
15
+ * CSS at-rules when at-rules are nested: https://github.com/atlassian-labs/compiled/blob/e04a325915e1d13010205089e4915de0e53bc2d4/packages/css/src/plugins/merge-duplicate-at-rules.ts#L5
16
+ * Avoiding nesting the `@supports` at-rule inside of `@media` means Compiled can remove duplicate styles from the generated CSS.
17
+ */
18
+ const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
19
+
20
+ // Placed in a variable, as the value is used in the translateX value for the children wrapper animation.
21
+ const flexGap = "var(--ds-space-050, 4px)";
22
+
11
23
  /**
12
24
  * Styles for the TopNavStart element.
13
25
  *
@@ -30,10 +42,48 @@ const innerStyles = {
30
42
  const wrapperStyles = {
31
43
  root: "_vchhusvi",
32
44
  fullHeightSidebar: "_bozgutpp",
33
- fullHeightSidebarCollapsed: "_15rip2n4",
34
45
  fullHeightSidebarExpanded: "_glte93mn _exxmpxbi"
35
46
  };
36
47
 
48
+ /**
49
+ * We use a fixed translateX offset for the slide animation (used when the TopNavStart children elements are reordered).
50
+ * This fixed offset makes the elements appear to animate smoothly from the old to the new position.
51
+ * This offset is calculated based on:
52
+ * - 32px (2rem) width of the side nav toggle button (IconButton)
53
+ * - 4px gap ('space.050' token) of the flex container
54
+ *
55
+ * The benefit of hardcoding this offset is that we don't need to calculate it using JS each time the sidebar is toggled.
56
+ * However, it could become out of sync if the width of IconButton changes.
57
+ *
58
+ * The alternative is using JS to store the previous position of the children wrapper element, and calculate the offset based on
59
+ * the new position, and then transforming using that offset. This would prevent the animation from going out of sync.
60
+ */
61
+ const childrenWrapperAnimationOffset = `calc(2rem + ${flexGap})`;
62
+ const childrenWrapperStyles = {
63
+ root: "_zulp1kw7 _1e0c1kw7 _1ul9idpf _15yekb7n _65m41mrw",
64
+ animationBaseStyles: "_10t81e03",
65
+ finalPosition: "_mjvcz12g _xrrp188d",
66
+ expandAnimationStartPosition: "_mjvcyrjp",
67
+ collapseAnimationStartPosition: "_mjvco0k7"
68
+ };
69
+
70
+ /**
71
+ * We use a fixed translateX offset for the toggle button slide animation (used when the TopNavStart children elements are reordered).
72
+ * The specific value doesn't matter too much for the toggle button animation, so we are using `100%`, which will match the toggle button width.
73
+ *
74
+ * By combining the `translateX` animation with an `opacity` fade, the feel and experience is actually quite similar to animating the
75
+ * element from the exact old position (offset), and it avoids the additional complexity of needing to track and calculate the exact offset.
76
+ */
77
+ const toggleButtonWrapperStyles = {
78
+ root: "_15yekb7n _65m41mrw _10t81rjc",
79
+ finalPosition: "_mjvcz12g _xrrp188d _bgpzkb7n",
80
+ expandAnimationStartPosition: "_mjvc1p9u _bgpzidpf",
81
+ collapseAnimationStartPosition: "_mjvc1efy _bgpzidpf",
82
+ expandAnimationTimingFunction: "_1xq51ytf",
83
+ collapseAnimationTimingFunction: "_1xq55ucs",
84
+ alignEnd: "_ahbq1wug"
85
+ };
86
+
37
87
  /**
38
88
  * The consistent key used for the side nav toggle button to ensure it does not get remounted
39
89
  * when it is reordered.
@@ -115,15 +165,78 @@ export function TopNavStart({
115
165
  UNSAFE_useMediaQuery('above.md', event => {
116
166
  setIsDesktop(event.matches);
117
167
  });
168
+ const [animationState, setAnimationState] = useState({
169
+ type: 'idle'
170
+ });
171
+
172
+ // Used to prevent the reorder animations from running on the initial render.
173
+ const isFirstRenderRef = useRef(true);
174
+ useEffect(() => {
175
+ if (!fg('navx-full-height-sidebar')) {
176
+ return;
177
+ }
178
+ if (isFirstRenderRef.current) {
179
+ isFirstRenderRef.current = false;
180
+ }
181
+ }, []);
182
+
183
+ // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
184
+ // can happen a lot (e.g. if the parent re-renders)
185
+ const sideNavToggleButtonStableRef = useStableRef(sideNavToggleButton);
186
+ useLayoutEffect(() => {
187
+ if (!fg('navx-full-height-sidebar')) {
188
+ return;
189
+ }
190
+
191
+ /**
192
+ * This layout effect is used to animate the TopNavStart children elements to their new position after being reordered.
193
+ * It is called when the sidebar's desktop expansion state changes.
194
+ *
195
+ * It works by first setting a translateX offset on the elements, used as the start position of the slide animation.
196
+ * - For the toggle button, it's a fixed offset. It's combined with an opacity, so the exact offset doesn't matter too much.
197
+ * - For the children wrapper (wrapping everything except the toggle button), an offset was chosen to make the animation
198
+ * start position the exact same as the element's old position. See comments for `childrenWrapperStyles` for more details.
199
+ *
200
+ * On the next frame, the translateX offset is cleared, triggering the animation to the new position.
201
+ */
202
+
203
+ if (isFirstRenderRef.current) {
204
+ // No animations on initial render.
205
+ return;
206
+ }
207
+ if (!sideNavToggleButtonStableRef.current) {
208
+ // If there is no toggle button, there should be no re-order animations.
209
+ return;
210
+ }
211
+
212
+ // Set the translateX offsets so elements are ready to animate to their actual new position after being reordered
213
+ setAnimationState({
214
+ type: isExpandedOnDesktop ? 'expand' : 'collapse'
215
+ });
216
+ requestAnimationFrame(() => {
217
+ // Clear translateX offsets on next frame to trigger animation to new position in a re-render
218
+ setAnimationState({
219
+ type: 'idle'
220
+ });
221
+ });
222
+
223
+ // This layout effect is called when the sidebar's desktop expansion state changes.
224
+ }, [isExpandedOnDesktop, sideNavToggleButtonStableRef]);
118
225
  const TopNavStartInner = fg('navx-full-height-sidebar') ? TopNavStartInnerFHS : TopNavStartInnerOld;
119
226
  return /*#__PURE__*/React.createElement(TopNavStartInner, {
120
227
  ref: elementRef,
121
228
  testId: testId
122
- }, !fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement(SideNavToggleButtonSlotProvider, {
123
- key: sideNavToggleButtonKey
124
- }, sideNavToggleButton), sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement(SideNavToggleButtonSlotProvider, {
125
- key: sideNavToggleButtonKey
126
- }, sideNavToggleButton), children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement(SideNavToggleButtonSlotProvider, {
127
- key: sideNavToggleButtonKey
229
+ }, !fg('navx-full-height-sidebar') && sideNavToggleButton, sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement("div", {
230
+ key: sideNavToggleButtonKey,
231
+ className: ax([!isFirefox && toggleButtonWrapperStyles.root, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
232
+ // Timing function is applied when the browser animates to the idle position.
233
+ animationState.type === 'idle' && toggleButtonWrapperStyles.collapseAnimationTimingFunction, !isFirefox && animationState.type === 'collapse' && toggleButtonWrapperStyles.collapseAnimationStartPosition])
234
+ }, sideNavToggleButton), fg('navx-full-height-sidebar') ? /*#__PURE__*/React.createElement("div", {
235
+ className: ax([childrenWrapperStyles.root, !isFirefox && childrenWrapperStyles.animationBaseStyles, !isFirefox && animationState.type === 'idle' && childrenWrapperStyles.finalPosition, !isFirefox && animationState.type === 'expand' && childrenWrapperStyles.expandAnimationStartPosition, !isFirefox && animationState.type === 'collapse' && childrenWrapperStyles.collapseAnimationStartPosition])
236
+ }, children) : children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement("div", {
237
+ key: sideNavToggleButtonKey,
238
+ className: ax([!isFirefox && toggleButtonWrapperStyles.root, toggleButtonWrapperStyles.alignEnd, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
239
+ // Timing function is applied when the browser animates to the idle position.
240
+ animationState.type === 'idle' && toggleButtonWrapperStyles.expandAnimationTimingFunction, !isFirefox && animationState.type === 'expand' && toggleButtonWrapperStyles.expandAnimationStartPosition])
128
241
  }, sideNavToggleButton));
129
242
  }
@@ -2,6 +2,7 @@
2
2
  ._nd5l1b6c{grid-area:main/aside/aside/aside}
3
3
  ._191wglyw{border-inline-start:none}
4
4
  ._t51zglyw{border-inline-end:none}._152timx3{inset-block-start:calc(var(--n_bnrM, 0px) + var(--n_tNvM, 0px))}
5
+ ._15yekb7n{--animation-direction:1}
5
6
  ._16qs1cd0{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #091e4226,0 0 1px #091e424f)}
6
7
  ._1bah1yb4{justify-content:space-between}
7
8
  ._1bsb1ego{width:min(90%,20pc)}
@@ -14,9 +15,10 @@
14
15
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
15
16
  ._kqsw1if8{position:sticky}
16
17
  ._vchhusvi{box-sizing:border-box}
17
- @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrp188d{transition-duration:.3s}._1lh81gzg{grid-area:main}._1xq51mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}@starting-style{._1nu5jq3t{transform:translateX(-100%)}}._1xq51ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}}
18
+ [dir=rtl] ._65m41mrw{--animation-direction:-1}
19
+ @media (prefers-reduced-motion:no-preference){._10t88iot{transition-property:transform,display}._1vrh1a5r{transition-behavior:allow-discrete}._xrrp188d{transition-duration:.3s}._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)}}
18
20
  @media (min-width:48rem){._14b5hc79{width:var(--n_snvRsz,var(--n_sNvw))}}
19
21
  @media (min-width:64rem){._165t56xv{height:calc(100vh - var(--n_bnrM, 0px))}._180k1wjm{inset-block-start:calc(var(--n_bnrM, 0px))}._26vxoned{padding-block-start:calc(var(--n_tNvM, 0px))}._1mt19dtb{margin-block-start:calc(var(--n_tNvM, 0px)*-1)}._dm2518uv{display:initial}._dm25glyw{display:none}._qiln1gzg{grid-area:main}._p5clglyw{border-inline-end:none}._4ap31bhr{background-color:var(--ds-surface-overlay,#fff)}._scbp1cd0{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #091e4226,0 0 1px #091e424f)}._qilnk0mc{grid-area:side-nav}._p5cl7r9e{border-inline-end:var(--ds-border-width,1px) solid var(--ds-border,#091e4224)}._4ap3vuon{background-color:var(--ds-surface,#fff)}._scbpglyw{box-shadow:none}}
20
- @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._17ly8iot{transition-property:transform,display}._177m1a5r{transition-behavior:allow-discrete}._1sg81gzg{grid-area:main}._vgub1mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}._hh1ujq3t{transform:translateX(-100%)}@starting-style{._s2egjq3t{transform:translateX(-100%)}}._1sg8k0mc{grid-area:side-nav}._vgub1ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}._hjoi188d{transition-duration:.3s}._hjoifnf5{transition-duration:.2s}}
21
- @media (prefers-reduced-motion:no-preference) and (not (min-width:64rem)){._aadijq3t{transform:translateX(-100%)}}
22
+ @media (prefers-reduced-motion:no-preference) and (min-width:64rem){._17ly8iot{transition-property:transform,display}._177m1a5r{transition-behavior:allow-discrete}._1sg81gzg{grid-area:main}._vgub1mm8{transition-timing-function:cubic-bezier(0,.4,0,1)}._hh1u1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}@starting-style{._s2eg1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}._1sg8k0mc{grid-area:side-nav}._vgub1ku9{transition-timing-function:cubic-bezier(.6,0,0,1)}._hjoi188d{transition-duration:.3s}._hjoifnf5{transition-duration:.2s}}
23
+ @media (prefers-reduced-motion:no-preference) and (not (min-width:64rem)){._aadi1p9u{transform:translateX(calc(-100%*var(--animation-direction)))}}
22
24
  @supports not (-moz-appearance:none){@media (prefers-reduced-motion:no-preference){._139f8iot{transition-property:transform,display}._1tpvfnf5{transition-duration:.2s}._sylc1a5r{transition-behavior:allow-discrete}._1uwsjq3t{transform:translateX(-100%)}}@media (prefers-reduced-motion:no-preference){@starting-style{._oyeijq3t{transform:translateX(-100%)}}._139f8iot{transition-property:transform,display}._1tpvfnf5{transition-duration:.2s}._sylc1a5r{transition-behavior:allow-discrete}}}
@@ -52,18 +52,19 @@ var styles = {
52
52
  root: "_nd5l1b6c _191wglyw _t51zglyw _bfhk1bhr _16qs1cd0 _vchhusvi _4t3ieqxy _152timx3 _kqsw1if8 _1bsb1ego _1pbycs5v _14b5hc79 _qilnk0mc _p5cl7r9e _4ap3vuon _scbpglyw",
53
53
  flyoutOpen: "_qiln1gzg _p5clglyw _4ap31bhr _scbp1cd0 _139f8iot _1tpvfnf5 _sylc1a5r _oyeijq3t",
54
54
  flyoutAnimateClosed: "_1e0cglyw _qiln1gzg _139f8iot _1tpvfnf5 _sylc1a5r _1uwsjq3t",
55
+ animationRTLSupport: "_15yekb7n _65m41mrw",
55
56
  flyoutBaseStylesFullHeightSidebar: "_qiln1gzg _p5clglyw _4ap31bhr _scbp1cd0 _17ly8iot _177m1a5r",
56
- flyoutOpenFullHeightSidebar: "_hjoi188d _vgub1ku9 _s2egjq3t",
57
- flyoutAnimateClosedFullHeightSidebar: "_dm25glyw _hjoifnf5 _vgub1mm8 _hh1ujq3t",
57
+ flyoutOpenFullHeightSidebar: "_hjoi188d _vgub1ku9 _s2eg1p9u",
58
+ flyoutAnimateClosedFullHeightSidebar: "_dm25glyw _hjoifnf5 _vgub1mm8 _hh1u1p9u",
58
59
  flexContainer: "_4t3i1osq _1e0c1txw _2lx21bp4 _1bah1yb4",
59
60
  hiddenMobileAndDesktop: "_1e0cglyw",
60
61
  hiddenMobileOnly: "_1e0cglyw _dm2518uv",
61
62
  hiddenDesktopOnly: "_dm25glyw",
62
63
  animationBaseStyles: "_10t88iot _1vrh1a5r _xrrp188d",
63
- expandAnimationMobile: "_1xq51ku9 _1nu5jq3t",
64
- collapseAnimationMobile: "_1lh81gzg _1xq51mm8 _aadijq3t",
65
- expandAnimationDesktop: "_1sg8k0mc _vgub1ku9 _s2egjq3t",
66
- collapseAnimationDesktop: "_1sg81gzg _vgub1mm8 _hh1ujq3t",
64
+ expandAnimationMobile: "_1xq51ku9 _1nu51p9u",
65
+ collapseAnimationMobile: "_1lh81gzg _1xq51mm8 _aadi1p9u",
66
+ expandAnimationDesktop: "_1sg8k0mc _vgub1ku9 _s2eg1p9u",
67
+ collapseAnimationDesktop: "_1sg81gzg _vgub1mm8 _hh1u1p9u",
67
68
  fullHeightSidebar: "_165t56xv _180k1wjm _26vxoned _1mt19dtb"
68
69
  };
69
70
  var fallbackDefaultWidth = 320;
@@ -623,7 +624,7 @@ function SideNavInternal(_ref) {
623
624
  style: _defineProperty({}, sideNavVar, clampedWidth),
624
625
  ref: mergedRef,
625
626
  "data-testid": testId,
626
- className: ax([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !fg('navx-full-height-sidebar') && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !fg('navx-full-height-sidebar') && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, isFlyoutClosed && fg('navx-full-height-sidebar') && styles.fullHeightSidebar])
627
+ className: ax([styles.root, isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileOnly, !isExpandedOnDesktop && isExpandedOnMobile && !isFlyoutVisible && styles.hiddenDesktopOnly, !isExpandedOnDesktop && !isExpandedOnMobile && !isFlyoutVisible && styles.hiddenMobileAndDesktop, fg('navx-full-height-sidebar') && styles.animationRTLSupport, shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.animationBaseStyles, isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationMobile, !isExpandedOnMobile && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationMobile, isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.expandAnimationDesktop, !isExpandedOnDesktop && shouldShowSidebarToggleAnimation && fg('navx-full-height-sidebar') && styles.collapseAnimationDesktop, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !fg('navx-full-height-sidebar') && styles.flyoutOpen, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !fg('navx-full-height-sidebar') && styles.flyoutAnimateClosed, ((sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' || (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close') && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutBaseStylesFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'open' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutOpenFullHeightSidebar, (sideNavState === null || sideNavState === void 0 ? void 0 : sideNavState.flyout) === 'triggered-animate-close' && !isFirefox && fg('navx-full-height-sidebar') && styles.flyoutAnimateClosedFullHeightSidebar, isFlyoutClosed && fg('navx-full-height-sidebar') && styles.fullHeightSidebar])
627
628
  }), /*#__PURE__*/React.createElement(DangerouslyHoistCssVarToDocumentRoot, {
628
629
  variableName: sideNavLiveWidthVar,
629
630
  value: "0px",
@@ -16,9 +16,4 @@ export var SideNavToggleButtonElement = /*#__PURE__*/createContext(null);
16
16
  * A callback ref is needed because the side nav can be mounted before the elements in the top bar (e.g. if the element
17
17
  * is lazy loaded, which happens in Jira and Confluence), which would prevent the event listeners from being set up.
18
18
  */
19
- export var SideNavToggleButtonAttachRef = /*#__PURE__*/createContext(__noop);
20
-
21
- /**
22
- * Used to check if the SideNavToggleButton is rendered inside of its slot in `TopNavStart`.
23
- */
24
- export var SideNavToggleButtonSlotContext = /*#__PURE__*/createContext(false);
19
+ export var SideNavToggleButtonAttachRef = /*#__PURE__*/createContext(__noop);
@@ -1,6 +1,6 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import React, { useState } from 'react';
3
- import { SideNavToggleButtonAttachRef, SideNavToggleButtonElement, SideNavToggleButtonSlotContext } from './toggle-button-context';
3
+ import { SideNavToggleButtonAttachRef, SideNavToggleButtonElement } from './toggle-button-context';
4
4
 
5
5
  /**
6
6
  * Provider for the side nav toggle button contexts.
@@ -26,16 +26,4 @@ export var SideNavToggleButtonProvider = function SideNavToggleButtonProvider(_r
26
26
  }, /*#__PURE__*/React.createElement(SideNavToggleButtonAttachRef.Provider, {
27
27
  value: setElement
28
28
  }, children));
29
- };
30
-
31
- /**
32
- * Provider for the side nav toggle button slot.
33
- *
34
- * This allows us to determine if the toggle button is rendered inside or outside of its slot.
35
- */
36
- export var SideNavToggleButtonSlotProvider = function SideNavToggleButtonSlotProvider(_ref2) {
37
- var children = _ref2.children;
38
- return /*#__PURE__*/React.createElement(SideNavToggleButtonSlotContext.Provider, {
39
- value: true
40
- }, children);
41
29
  };
@@ -1,3 +1,2 @@
1
1
  ._1e0c1bgi{display:contents}
2
- ._lcxvglyw{pointer-events:none}
3
- @media (min-width:64rem){._3l1a1wug{margin-inline-start:auto}}
2
+ ._lcxvglyw{pointer-events:none}
@@ -11,7 +11,7 @@ import SidebarCollapseIcon from '@atlaskit/icon/core/sidebar-collapse';
11
11
  import SidebarExpandIcon from '@atlaskit/icon/core/sidebar-expand';
12
12
  import { fg } from '@atlaskit/platform-feature-flags';
13
13
  import { IconButton } from '../../top-nav-items/themed/migration';
14
- import { SideNavToggleButtonAttachRef, SideNavToggleButtonSlotContext } from './toggle-button-context';
14
+ import { SideNavToggleButtonAttachRef } from './toggle-button-context';
15
15
  import { useSideNavVisibility } from './use-side-nav-visibility';
16
16
  import { useToggleSideNav } from './use-toggle-side-nav';
17
17
  var toggleButtonTooltipOptions = {
@@ -23,12 +23,6 @@ var toggleButtonTooltipOptions = {
23
23
  // For duplicate "mouseenter" issue when changing icons (see below)
24
24
  var silentIconStyles = null;
25
25
 
26
- /**
27
- * Wrapper styles to align the toggle button to the end of `TopNavStart`
28
- * when FHS is expanded.
29
- */
30
- var fullHeightSidebarExpandedWrapperStyles = null;
31
-
32
26
  /**
33
27
  * __SideNavToggleButton__
34
28
  *
@@ -135,7 +129,7 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
135
129
  }
136
130
  return toggleButtonTooltipOptions;
137
131
  }, [shortcut]);
138
- var iconButton = /*#__PURE__*/React.createElement(IconButton, {
132
+ return /*#__PURE__*/React.createElement(IconButton, {
139
133
  appearance: "subtle",
140
134
  label: isSideNavExpanded ? collapseLabel : expandLabel,
141
135
  icon: icon,
@@ -146,15 +140,4 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
146
140
  ref: fg('platform_dst_nav4_side_nav_toggle_ref_fix') ? setElement : elementRef,
147
141
  tooltip: tooltipProps
148
142
  });
149
- var isInsideSlot = useContext(SideNavToggleButtonSlotContext);
150
-
151
- // Checking `isInsideSlot` in case an app isn't using the slot
152
- // We don't want to break existing non-slot usage with the left margin
153
- // This check can be removed in the future, after slot is required for a while.
154
- if (isInsideSlot && fg('navx-full-height-sidebar')) {
155
- return /*#__PURE__*/React.createElement("div", {
156
- className: ax([isSideNavExpandedOnDesktop && "_3l1a1wug"])
157
- }, iconButton);
158
- }
159
- return iconButton;
160
143
  };
@@ -1,9 +1,16 @@
1
1
 
2
2
  ._zulp1b66{gap:var(--ds-space-050,4px)}
3
- ._yyhykb7n{grid-column:1}._1e0c1txw{display:flex}
3
+ ._zulp1kw7{gap:inherit}
4
+ ._yyhykb7n{grid-column:1}._15yekb7n{--animation-direction:1}
5
+ ._1e0c1kw7{display:inherit}
6
+ ._1e0c1txw{display:flex}
7
+ ._1ul9idpf{min-width:0}
4
8
  ._4cvr1h6o{align-items:center}
5
9
  ._4t3i1osq{height:100%}
10
+ ._ahbq1wug{margin-inline-start:auto}
6
11
  ._bozgutpp{padding-inline-start:var(--ds-space-150,9pt)}
7
12
  ._lcxv1wug{pointer-events:auto}
8
13
  ._vchhusvi{box-sizing:border-box}
14
+ [dir=rtl] ._65m41mrw{--animation-direction:-1}
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)}._xrrp188d{transition-duration:.3s}._bgpzkb7n{opacity:1}}
9
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)}}
@@ -3,12 +3,24 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import "./top-nav-start.compiled.css";
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
5
  import React, { forwardRef, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
6
+ import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
6
7
  import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { UNSAFE_useMediaQuery } from '@atlaskit/primitives/compiled';
8
9
  import { TopNavStartAttachRef } from '../../../context/top-nav-start/top-nav-start-context';
9
- import { SideNavToggleButtonSlotProvider } from '../side-nav/toggle-button-provider';
10
10
  import { useSideNavVisibility } from '../side-nav/use-side-nav-visibility';
11
11
 
12
+ /**
13
+ * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
14
+ *
15
+ * We are using JS to detect Firefox and disable animations, instead of using CSS, as Compiled currently does not merge duplicate
16
+ * CSS at-rules when at-rules are nested: https://github.com/atlassian-labs/compiled/blob/e04a325915e1d13010205089e4915de0e53bc2d4/packages/css/src/plugins/merge-duplicate-at-rules.ts#L5
17
+ * Avoiding nesting the `@supports` at-rule inside of `@media` means Compiled can remove duplicate styles from the generated CSS.
18
+ */
19
+ var isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
20
+
21
+ // Placed in a variable, as the value is used in the translateX value for the children wrapper animation.
22
+ var flexGap = "var(--ds-space-050, 4px)";
23
+
12
24
  /**
13
25
  * Styles for the TopNavStart element.
14
26
  *
@@ -31,10 +43,48 @@ var innerStyles = {
31
43
  var wrapperStyles = {
32
44
  root: "_vchhusvi",
33
45
  fullHeightSidebar: "_bozgutpp",
34
- fullHeightSidebarCollapsed: "_15rip2n4",
35
46
  fullHeightSidebarExpanded: "_glte93mn _exxmpxbi"
36
47
  };
37
48
 
49
+ /**
50
+ * We use a fixed translateX offset for the slide animation (used when the TopNavStart children elements are reordered).
51
+ * This fixed offset makes the elements appear to animate smoothly from the old to the new position.
52
+ * This offset is calculated based on:
53
+ * - 32px (2rem) width of the side nav toggle button (IconButton)
54
+ * - 4px gap ('space.050' token) of the flex container
55
+ *
56
+ * The benefit of hardcoding this offset is that we don't need to calculate it using JS each time the sidebar is toggled.
57
+ * However, it could become out of sync if the width of IconButton changes.
58
+ *
59
+ * The alternative is using JS to store the previous position of the children wrapper element, and calculate the offset based on
60
+ * the new position, and then transforming using that offset. This would prevent the animation from going out of sync.
61
+ */
62
+ var childrenWrapperAnimationOffset = "calc(2rem + ".concat(flexGap, ")");
63
+ var childrenWrapperStyles = {
64
+ root: "_zulp1kw7 _1e0c1kw7 _1ul9idpf _15yekb7n _65m41mrw",
65
+ animationBaseStyles: "_10t81e03",
66
+ finalPosition: "_mjvcz12g _xrrp188d",
67
+ expandAnimationStartPosition: "_mjvcyrjp",
68
+ collapseAnimationStartPosition: "_mjvco0k7"
69
+ };
70
+
71
+ /**
72
+ * We use a fixed translateX offset for the toggle button slide animation (used when the TopNavStart children elements are reordered).
73
+ * The specific value doesn't matter too much for the toggle button animation, so we are using `100%`, which will match the toggle button width.
74
+ *
75
+ * By combining the `translateX` animation with an `opacity` fade, the feel and experience is actually quite similar to animating the
76
+ * element from the exact old position (offset), and it avoids the additional complexity of needing to track and calculate the exact offset.
77
+ */
78
+ var toggleButtonWrapperStyles = {
79
+ root: "_15yekb7n _65m41mrw _10t81rjc",
80
+ finalPosition: "_mjvcz12g _xrrp188d _bgpzkb7n",
81
+ expandAnimationStartPosition: "_mjvc1p9u _bgpzidpf",
82
+ collapseAnimationStartPosition: "_mjvc1efy _bgpzidpf",
83
+ expandAnimationTimingFunction: "_1xq51ytf",
84
+ collapseAnimationTimingFunction: "_1xq55ucs",
85
+ alignEnd: "_ahbq1wug"
86
+ };
87
+
38
88
  /**
39
89
  * The consistent key used for the side nav toggle button to ensure it does not get remounted
40
90
  * when it is reordered.
@@ -114,15 +164,81 @@ export function TopNavStart(_ref3) {
114
164
  UNSAFE_useMediaQuery('above.md', function (event) {
115
165
  setIsDesktop(event.matches);
116
166
  });
167
+ var _useState3 = useState({
168
+ type: 'idle'
169
+ }),
170
+ _useState4 = _slicedToArray(_useState3, 2),
171
+ animationState = _useState4[0],
172
+ setAnimationState = _useState4[1];
173
+
174
+ // Used to prevent the reorder animations from running on the initial render.
175
+ var isFirstRenderRef = useRef(true);
176
+ useEffect(function () {
177
+ if (!fg('navx-full-height-sidebar')) {
178
+ return;
179
+ }
180
+ if (isFirstRenderRef.current) {
181
+ isFirstRenderRef.current = false;
182
+ }
183
+ }, []);
184
+
185
+ // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
186
+ // can happen a lot (e.g. if the parent re-renders)
187
+ var sideNavToggleButtonStableRef = useStableRef(sideNavToggleButton);
188
+ useLayoutEffect(function () {
189
+ if (!fg('navx-full-height-sidebar')) {
190
+ return;
191
+ }
192
+
193
+ /**
194
+ * This layout effect is used to animate the TopNavStart children elements to their new position after being reordered.
195
+ * It is called when the sidebar's desktop expansion state changes.
196
+ *
197
+ * It works by first setting a translateX offset on the elements, used as the start position of the slide animation.
198
+ * - For the toggle button, it's a fixed offset. It's combined with an opacity, so the exact offset doesn't matter too much.
199
+ * - For the children wrapper (wrapping everything except the toggle button), an offset was chosen to make the animation
200
+ * start position the exact same as the element's old position. See comments for `childrenWrapperStyles` for more details.
201
+ *
202
+ * On the next frame, the translateX offset is cleared, triggering the animation to the new position.
203
+ */
204
+
205
+ if (isFirstRenderRef.current) {
206
+ // No animations on initial render.
207
+ return;
208
+ }
209
+ if (!sideNavToggleButtonStableRef.current) {
210
+ // If there is no toggle button, there should be no re-order animations.
211
+ return;
212
+ }
213
+
214
+ // Set the translateX offsets so elements are ready to animate to their actual new position after being reordered
215
+ setAnimationState({
216
+ type: isExpandedOnDesktop ? 'expand' : 'collapse'
217
+ });
218
+ requestAnimationFrame(function () {
219
+ // Clear translateX offsets on next frame to trigger animation to new position in a re-render
220
+ setAnimationState({
221
+ type: 'idle'
222
+ });
223
+ });
224
+
225
+ // This layout effect is called when the sidebar's desktop expansion state changes.
226
+ }, [isExpandedOnDesktop, sideNavToggleButtonStableRef]);
117
227
  var TopNavStartInner = fg('navx-full-height-sidebar') ? TopNavStartInnerFHS : TopNavStartInnerOld;
118
228
  return /*#__PURE__*/React.createElement(TopNavStartInner, {
119
229
  ref: elementRef,
120
230
  testId: testId
121
- }, !fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement(SideNavToggleButtonSlotProvider, {
122
- key: sideNavToggleButtonKey
123
- }, sideNavToggleButton), sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement(SideNavToggleButtonSlotProvider, {
124
- key: sideNavToggleButtonKey
125
- }, sideNavToggleButton), children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement(SideNavToggleButtonSlotProvider, {
126
- key: sideNavToggleButtonKey
231
+ }, !fg('navx-full-height-sidebar') && sideNavToggleButton, sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement("div", {
232
+ key: sideNavToggleButtonKey,
233
+ className: ax([!isFirefox && toggleButtonWrapperStyles.root, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
234
+ // Timing function is applied when the browser animates to the idle position.
235
+ animationState.type === 'idle' && toggleButtonWrapperStyles.collapseAnimationTimingFunction, !isFirefox && animationState.type === 'collapse' && toggleButtonWrapperStyles.collapseAnimationStartPosition])
236
+ }, sideNavToggleButton), fg('navx-full-height-sidebar') ? /*#__PURE__*/React.createElement("div", {
237
+ className: ax([childrenWrapperStyles.root, !isFirefox && childrenWrapperStyles.animationBaseStyles, !isFirefox && animationState.type === 'idle' && childrenWrapperStyles.finalPosition, !isFirefox && animationState.type === 'expand' && childrenWrapperStyles.expandAnimationStartPosition, !isFirefox && animationState.type === 'collapse' && childrenWrapperStyles.collapseAnimationStartPosition])
238
+ }, children) : children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement("div", {
239
+ key: sideNavToggleButtonKey,
240
+ className: ax([!isFirefox && toggleButtonWrapperStyles.root, toggleButtonWrapperStyles.alignEnd, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
241
+ // Timing function is applied when the browser animates to the idle position.
242
+ animationState.type === 'idle' && toggleButtonWrapperStyles.expandAnimationTimingFunction, !isFirefox && animationState.type === 'expand' && toggleButtonWrapperStyles.expandAnimationStartPosition])
127
243
  }, sideNavToggleButton));
128
244
  }
@@ -14,7 +14,3 @@ export declare const SideNavToggleButtonElement: import("react").Context<HTMLBut
14
14
  * is lazy loaded, which happens in Jira and Confluence), which would prevent the event listeners from being set up.
15
15
  */
16
16
  export declare const SideNavToggleButtonAttachRef: import("react").Context<(newVal: HTMLButtonElement | null) => void>;
17
- /**
18
- * Used to check if the SideNavToggleButton is rendered inside of its slot in `TopNavStart`.
19
- */
20
- export declare const SideNavToggleButtonSlotContext: import("react").Context<boolean>;
@@ -15,11 +15,3 @@ import React from 'react';
15
15
  export declare const SideNavToggleButtonProvider: ({ children }: {
16
16
  children: React.ReactNode;
17
17
  }) => React.JSX.Element;
18
- /**
19
- * Provider for the side nav toggle button slot.
20
- *
21
- * This allows us to determine if the toggle button is rendered inside or outside of its slot.
22
- */
23
- export declare const SideNavToggleButtonSlotProvider: ({ children }: {
24
- children: React.ReactNode;
25
- }) => React.JSX.Element;
@@ -14,7 +14,3 @@ export declare const SideNavToggleButtonElement: import("react").Context<HTMLBut
14
14
  * is lazy loaded, which happens in Jira and Confluence), which would prevent the event listeners from being set up.
15
15
  */
16
16
  export declare const SideNavToggleButtonAttachRef: import("react").Context<(newVal: HTMLButtonElement | null) => void>;
17
- /**
18
- * Used to check if the SideNavToggleButton is rendered inside of its slot in `TopNavStart`.
19
- */
20
- export declare const SideNavToggleButtonSlotContext: import("react").Context<boolean>;
@@ -15,11 +15,3 @@ import React from 'react';
15
15
  export declare const SideNavToggleButtonProvider: ({ children }: {
16
16
  children: React.ReactNode;
17
17
  }) => React.JSX.Element;
18
- /**
19
- * Provider for the side nav toggle button slot.
20
- *
21
- * This allows us to determine if the toggle button is rendered inside or outside of its slot.
22
- */
23
- export declare const SideNavToggleButtonSlotProvider: ({ children }: {
24
- children: React.ReactNode;
25
- }) => React.JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/navigation-system",
3
- "version": "2.19.1",
3
+ "version": "2.21.0",
4
4
  "description": "The latest navigation system for Atlassian apps.",
5
5
  "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
6
6
  "author": "Atlassian Pty Ltd",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "dependencies": {
69
69
  "@atlaskit/analytics-next": "^11.1.0",
70
- "@atlaskit/avatar": "^25.3.0",
70
+ "@atlaskit/avatar": "^25.4.0",
71
71
  "@atlaskit/button": "^23.5.0",
72
72
  "@atlaskit/css": "^0.14.0",
73
73
  "@atlaskit/ds-lib": "^5.1.0",