@atlaskit/navigation-system 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/ui/page-layout/root.js +1 -2
  3. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +24 -2
  4. package/dist/cjs/ui/page-layout/side-nav/toggle-button.js +5 -3
  5. package/dist/cjs/ui/page-layout/side-nav/visibility-provider.js +1 -1
  6. package/dist/cjs/ui/page-layout/top-nav/top-nav-start.js +10 -1
  7. package/dist/es2019/ui/page-layout/root.js +1 -1
  8. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +25 -3
  9. package/dist/es2019/ui/page-layout/side-nav/toggle-button.js +5 -3
  10. package/dist/es2019/ui/page-layout/side-nav/visibility-provider.js +1 -1
  11. package/dist/es2019/ui/page-layout/top-nav/top-nav-start.js +10 -1
  12. package/dist/esm/ui/page-layout/root.js +1 -2
  13. package/dist/esm/ui/page-layout/side-nav/side-nav.js +25 -3
  14. package/dist/esm/ui/page-layout/side-nav/toggle-button.js +5 -3
  15. package/dist/esm/ui/page-layout/side-nav/visibility-provider.js +1 -1
  16. package/dist/esm/ui/page-layout/top-nav/top-nav-start.js +10 -1
  17. package/dist/types/ui/page-layout/root.d.ts +1 -1
  18. package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +1 -1
  19. package/dist/types/ui/page-layout/side-nav/toggle-button.d.ts +1 -1
  20. package/dist/types/ui/page-layout/side-nav/visibility-provider.d.ts +1 -1
  21. package/dist/types/ui/page-layout/top-nav/top-nav-start.d.ts +1 -1
  22. package/dist/types-ts4.5/ui/page-layout/root.d.ts +1 -1
  23. package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav.d.ts +1 -1
  24. package/dist/types-ts4.5/ui/page-layout/side-nav/toggle-button.d.ts +1 -1
  25. package/dist/types-ts4.5/ui/page-layout/side-nav/visibility-provider.d.ts +1 -1
  26. package/dist/types-ts4.5/ui/page-layout/top-nav/top-nav-start.d.ts +1 -1
  27. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @atlassian/navigation-system
2
2
 
3
+ ## 4.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`4bb7b31bfda3b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4bb7b31bfda3b) -
8
+ Refactors changes that were previously behind `platform_dst_nav4_full_height_sidebar_api_changes`
9
+ to now be behind `platform_dst_nav4_side_nav_default_collapsed_api`. After rollout, both the new
10
+ and legacy APIs for defining side nav initial state will be supported.
11
+
3
12
  ## 4.2.0
4
13
 
5
14
  ### Minor Changes
@@ -36,8 +36,7 @@ function Root(_ref) {
36
36
  _ref$skipLinksLabel = _ref.skipLinksLabel,
37
37
  skipLinksLabel = _ref$skipLinksLabel === void 0 ? 'Skip to:' : _ref$skipLinksLabel,
38
38
  testId = _ref.testId,
39
- _ref$defaultSideNavCo = _ref.defaultSideNavCollapsed,
40
- defaultSideNavCollapsed = _ref$defaultSideNavCo === void 0 ? false : _ref$defaultSideNavCo;
39
+ defaultSideNavCollapsed = _ref.defaultSideNavCollapsed;
41
40
  var ref = (0, _react.useRef)(null);
42
41
  (0, _react.useEffect)(function () {
43
42
  if (process.env.NODE_ENV !== 'production') {
@@ -260,8 +260,8 @@ function SideNavInternal(_ref) {
260
260
  trigger: 'click-outside-on-mobile'
261
261
  });
262
262
  (0, _react.useEffect)(function () {
263
- if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_full_height_sidebar_api_changes')) {
264
- // We are passing initial state to the Root now, so no initial sync is required
263
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_default_collapsed_api')) {
264
+ // This is the old version of the hook, so we skip it when the flag is enabled
265
265
  return;
266
266
  }
267
267
 
@@ -274,6 +274,28 @@ function SideNavInternal(_ref) {
274
274
  lastTrigger: null
275
275
  });
276
276
  }, [initialDefaultCollapsed, setSideNavState]);
277
+
278
+ // Moving to `useLayoutEffect` so that there's no visual shift in non-SSR environments when using legacy API
279
+ // For SSR the new API is still necessary
280
+ (0, _react.useLayoutEffect)(function () {
281
+ if (!(0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_default_collapsed_api')) {
282
+ // This is the new version of the hook, so we skip it when the flag is disabled
283
+ return;
284
+ }
285
+ if (sideNavState !== null) {
286
+ // Only need to do an initial sync if it hasn't been initialized from Root
287
+ return;
288
+ }
289
+
290
+ // Sync the visibility in context (provided in `<Root>`) with the local `defaultCollapsed` prop provided to `SideNav`
291
+ // after SSR hydration. This should only run once, after the initial render on the client.
292
+ setSideNavState({
293
+ desktop: initialDefaultCollapsed ? 'collapsed' : 'expanded',
294
+ mobile: 'collapsed',
295
+ flyout: 'closed',
296
+ lastTrigger: null
297
+ });
298
+ }, [initialDefaultCollapsed, setSideNavState, sideNavState]);
277
299
  var handleExpand = (0, _react.useCallback)(function (_ref2) {
278
300
  var screen = _ref2.screen,
279
301
  trigger = _ref2.trigger;
@@ -20,6 +20,7 @@ var _migration = require("../../top-nav-items/themed/migration");
20
20
  var _toggleButtonContext = require("./toggle-button-context");
21
21
  var _useSideNavVisibility2 = require("./use-side-nav-visibility");
22
22
  var _useToggleSideNav = require("./use-toggle-side-nav");
23
+ var _visibilityContext = require("./visibility-context");
23
24
  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); }
24
25
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
25
26
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -51,10 +52,11 @@ var SideNavToggleButton = exports.SideNavToggleButton = function SideNavToggleBu
51
52
  }),
52
53
  isSideNavExpandedOnDesktop = _useSideNavVisibility.isExpandedOnDesktop,
53
54
  isSideNavExpandedOnMobile = _useSideNavVisibility.isExpandedOnMobile;
55
+ var sideNavState = (0, _react.useContext)(_visibilityContext.SideNavVisibilityState);
54
56
 
55
- // When `platform_dst_nav4_full_height_sidebar_api_changes` is enabled,
56
- // we default to the desktop state for SSR
57
- var _useState = (0, _react.useState)((0, _platformFeatureFlags.fg)('platform_dst_nav4_full_height_sidebar_api_changes') ? isSideNavExpandedOnDesktop : !defaultCollapsed),
57
+ // When default state is provided to `Root` the state in context will already be
58
+ // initialized in SSR
59
+ var _useState = (0, _react.useState)(sideNavState === null || !(0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_default_collapsed_api') ? !defaultCollapsed : isSideNavExpandedOnDesktop),
58
60
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
59
61
  isSideNavExpanded = _useState2[0],
60
62
  setIsSideNavExpanded = _useState2[1];
@@ -17,7 +17,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
17
17
  var SideNavVisibilityProvider = exports.SideNavVisibilityProvider = function SideNavVisibilityProvider(_ref) {
18
18
  var children = _ref.children,
19
19
  defaultCollapsed = _ref.defaultCollapsed;
20
- var initialState = (0, _platformFeatureFlags.fg)('platform_dst_nav4_full_height_sidebar_api_changes') ? {
20
+ var initialState = typeof defaultCollapsed === 'boolean' && (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_default_collapsed_api') ? {
21
21
  desktop: defaultCollapsed ? 'collapsed' : 'expanded',
22
22
  mobile: 'collapsed',
23
23
  flyout: 'closed',
@@ -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 _useSideNavVisibility3 = require("../side-nav/use-side-nav-visibility");
19
+ var _visibilityContext = require("../side-nav/visibility-context");
19
20
  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
  /**
21
22
  * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
@@ -180,14 +181,22 @@ function TopNavStart(_ref3) {
180
181
 
181
182
  // Used to prevent the reorder animations from running on the initial render.
182
183
  var isFirstRenderRef = (0, _react.useRef)(true);
184
+ var sideNavState = (0, _react.useContext)(_visibilityContext.SideNavVisibilityState);
183
185
  (0, _react.useEffect)(function () {
184
186
  if (!(0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
185
187
  return;
186
188
  }
189
+
190
+ // Ignore renders until the side nav state is initialized
191
+ // So that apps using the legacy API for setting side nav default state do not see
192
+ // animations when they shouldn't
193
+ if (sideNavState === null) {
194
+ return;
195
+ }
187
196
  if (isFirstRenderRef.current) {
188
197
  isFirstRenderRef.current = false;
189
198
  }
190
- }, []);
199
+ }, [sideNavState]);
191
200
 
192
201
  // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
193
202
  // can happen a lot (e.g. if the parent re-renders)
@@ -26,7 +26,7 @@ export function Root({
26
26
  UNSAFE_dangerouslyHoistSlotSizes = false,
27
27
  skipLinksLabel = 'Skip to:',
28
28
  testId,
29
- defaultSideNavCollapsed = false
29
+ defaultSideNavCollapsed
30
30
  }) {
31
31
  const ref = useRef(null);
32
32
  useEffect(() => {
@@ -3,7 +3,7 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  import "./side-nav.compiled.css";
4
4
  import * as React from 'react';
5
5
  import { ax, ix } from "@compiled/react/runtime";
6
- import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
6
+ import { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
7
7
  import { bind } from 'bind-event-listener';
8
8
  import { flushSync } from 'react-dom';
9
9
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
@@ -243,8 +243,8 @@ function SideNavInternal({
243
243
  trigger: 'click-outside-on-mobile'
244
244
  });
245
245
  useEffect(() => {
246
- if (fg('platform_dst_nav4_full_height_sidebar_api_changes')) {
247
- // We are passing initial state to the Root now, so no initial sync is required
246
+ if (fg('platform_dst_nav4_side_nav_default_collapsed_api')) {
247
+ // This is the old version of the hook, so we skip it when the flag is enabled
248
248
  return;
249
249
  }
250
250
 
@@ -257,6 +257,28 @@ function SideNavInternal({
257
257
  lastTrigger: null
258
258
  });
259
259
  }, [initialDefaultCollapsed, setSideNavState]);
260
+
261
+ // Moving to `useLayoutEffect` so that there's no visual shift in non-SSR environments when using legacy API
262
+ // For SSR the new API is still necessary
263
+ useLayoutEffect(() => {
264
+ if (!fg('platform_dst_nav4_side_nav_default_collapsed_api')) {
265
+ // This is the new version of the hook, so we skip it when the flag is disabled
266
+ return;
267
+ }
268
+ if (sideNavState !== null) {
269
+ // Only need to do an initial sync if it hasn't been initialized from Root
270
+ return;
271
+ }
272
+
273
+ // Sync the visibility in context (provided in `<Root>`) with the local `defaultCollapsed` prop provided to `SideNav`
274
+ // after SSR hydration. This should only run once, after the initial render on the client.
275
+ setSideNavState({
276
+ desktop: initialDefaultCollapsed ? 'collapsed' : 'expanded',
277
+ mobile: 'collapsed',
278
+ flyout: 'closed',
279
+ lastTrigger: null
280
+ });
281
+ }, [initialDefaultCollapsed, setSideNavState, sideNavState]);
260
282
  const handleExpand = useCallback(({
261
283
  screen,
262
284
  trigger
@@ -10,6 +10,7 @@ import { IconButton } from '../../top-nav-items/themed/migration';
10
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
+ import { SideNavVisibilityState } from './visibility-context';
13
14
  const toggleButtonTooltipOptions = {
14
15
  // We're disabling pointer events on the tooltip to prevent it from blocking mouse events, so that the side nav flyout stays open
15
16
  // when moving the mouse from the top bar to the side nav.
@@ -39,10 +40,11 @@ export const SideNavToggleButton = ({
39
40
  } = useSideNavVisibility({
40
41
  defaultCollapsed
41
42
  });
43
+ const sideNavState = useContext(SideNavVisibilityState);
42
44
 
43
- // When `platform_dst_nav4_full_height_sidebar_api_changes` is enabled,
44
- // we default to the desktop state for SSR
45
- const [isSideNavExpanded, setIsSideNavExpanded] = useState(fg('platform_dst_nav4_full_height_sidebar_api_changes') ? isSideNavExpandedOnDesktop : !defaultCollapsed);
45
+ // When default state is provided to `Root` the state in context will already be
46
+ // initialized in SSR
47
+ const [isSideNavExpanded, setIsSideNavExpanded] = useState(sideNavState === null || !fg('platform_dst_nav4_side_nav_default_collapsed_api') ? !defaultCollapsed : isSideNavExpandedOnDesktop);
46
48
  const ref = useContext(SideNavToggleButtonAttachRef);
47
49
  const elementRef = useRef(null);
48
50
 
@@ -9,7 +9,7 @@ export const SideNavVisibilityProvider = ({
9
9
  children,
10
10
  defaultCollapsed
11
11
  }) => {
12
- const initialState = fg('platform_dst_nav4_full_height_sidebar_api_changes') ? {
12
+ const initialState = typeof defaultCollapsed === 'boolean' && fg('platform_dst_nav4_side_nav_default_collapsed_api') ? {
13
13
  desktop: defaultCollapsed ? 'collapsed' : 'expanded',
14
14
  mobile: 'collapsed',
15
15
  flyout: 'closed',
@@ -7,6 +7,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
7
7
  import { UNSAFE_useMediaQuery } from '@atlaskit/primitives/compiled';
8
8
  import { TopNavStartAttachRef } from '../../../context/top-nav-start/top-nav-start-context';
9
9
  import { useSideNavVisibility } from '../side-nav/use-side-nav-visibility';
10
+ import { SideNavVisibilityState } from '../side-nav/visibility-context';
10
11
 
11
12
  /**
12
13
  * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
@@ -170,14 +171,22 @@ export function TopNavStart({
170
171
 
171
172
  // Used to prevent the reorder animations from running on the initial render.
172
173
  const isFirstRenderRef = useRef(true);
174
+ const sideNavState = useContext(SideNavVisibilityState);
173
175
  useEffect(() => {
174
176
  if (!fg('navx-full-height-sidebar')) {
175
177
  return;
176
178
  }
179
+
180
+ // Ignore renders until the side nav state is initialized
181
+ // So that apps using the legacy API for setting side nav default state do not see
182
+ // animations when they shouldn't
183
+ if (sideNavState === null) {
184
+ return;
185
+ }
177
186
  if (isFirstRenderRef.current) {
178
187
  isFirstRenderRef.current = false;
179
188
  }
180
- }, []);
189
+ }, [sideNavState]);
181
190
 
182
191
  // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
183
192
  // can happen a lot (e.g. if the parent re-renders)
@@ -28,8 +28,7 @@ export function Root(_ref) {
28
28
  _ref$skipLinksLabel = _ref.skipLinksLabel,
29
29
  skipLinksLabel = _ref$skipLinksLabel === void 0 ? 'Skip to:' : _ref$skipLinksLabel,
30
30
  testId = _ref.testId,
31
- _ref$defaultSideNavCo = _ref.defaultSideNavCollapsed,
32
- defaultSideNavCollapsed = _ref$defaultSideNavCo === void 0 ? false : _ref$defaultSideNavCo;
31
+ defaultSideNavCollapsed = _ref.defaultSideNavCollapsed;
33
32
  var ref = useRef(null);
34
33
  useEffect(function () {
35
34
  if (process.env.NODE_ENV !== 'production') {
@@ -7,7 +7,7 @@ import * as React from 'react';
7
7
  import { ax, ix } from "@compiled/react/runtime";
8
8
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
9
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
- import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
10
+ import { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
11
11
  import { bind } from 'bind-event-listener';
12
12
  import { flushSync } from 'react-dom';
13
13
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
@@ -251,8 +251,8 @@ function SideNavInternal(_ref) {
251
251
  trigger: 'click-outside-on-mobile'
252
252
  });
253
253
  useEffect(function () {
254
- if (fg('platform_dst_nav4_full_height_sidebar_api_changes')) {
255
- // We are passing initial state to the Root now, so no initial sync is required
254
+ if (fg('platform_dst_nav4_side_nav_default_collapsed_api')) {
255
+ // This is the old version of the hook, so we skip it when the flag is enabled
256
256
  return;
257
257
  }
258
258
 
@@ -265,6 +265,28 @@ function SideNavInternal(_ref) {
265
265
  lastTrigger: null
266
266
  });
267
267
  }, [initialDefaultCollapsed, setSideNavState]);
268
+
269
+ // Moving to `useLayoutEffect` so that there's no visual shift in non-SSR environments when using legacy API
270
+ // For SSR the new API is still necessary
271
+ useLayoutEffect(function () {
272
+ if (!fg('platform_dst_nav4_side_nav_default_collapsed_api')) {
273
+ // This is the new version of the hook, so we skip it when the flag is disabled
274
+ return;
275
+ }
276
+ if (sideNavState !== null) {
277
+ // Only need to do an initial sync if it hasn't been initialized from Root
278
+ return;
279
+ }
280
+
281
+ // Sync the visibility in context (provided in `<Root>`) with the local `defaultCollapsed` prop provided to `SideNav`
282
+ // after SSR hydration. This should only run once, after the initial render on the client.
283
+ setSideNavState({
284
+ desktop: initialDefaultCollapsed ? 'collapsed' : 'expanded',
285
+ mobile: 'collapsed',
286
+ flyout: 'closed',
287
+ lastTrigger: null
288
+ });
289
+ }, [initialDefaultCollapsed, setSideNavState, sideNavState]);
268
290
  var handleExpand = useCallback(function (_ref2) {
269
291
  var screen = _ref2.screen,
270
292
  trigger = _ref2.trigger;
@@ -14,6 +14,7 @@ import { IconButton } from '../../top-nav-items/themed/migration';
14
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
+ import { SideNavVisibilityState } from './visibility-context';
17
18
  var toggleButtonTooltipOptions = {
18
19
  // We're disabling pointer events on the tooltip to prevent it from blocking mouse events, so that the side nav flyout stays open
19
20
  // when moving the mouse from the top bar to the side nav.
@@ -42,10 +43,11 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
42
43
  }),
43
44
  isSideNavExpandedOnDesktop = _useSideNavVisibility.isExpandedOnDesktop,
44
45
  isSideNavExpandedOnMobile = _useSideNavVisibility.isExpandedOnMobile;
46
+ var sideNavState = useContext(SideNavVisibilityState);
45
47
 
46
- // When `platform_dst_nav4_full_height_sidebar_api_changes` is enabled,
47
- // we default to the desktop state for SSR
48
- var _useState = useState(fg('platform_dst_nav4_full_height_sidebar_api_changes') ? isSideNavExpandedOnDesktop : !defaultCollapsed),
48
+ // When default state is provided to `Root` the state in context will already be
49
+ // initialized in SSR
50
+ var _useState = useState(sideNavState === null || !fg('platform_dst_nav4_side_nav_default_collapsed_api') ? !defaultCollapsed : isSideNavExpandedOnDesktop),
49
51
  _useState2 = _slicedToArray(_useState, 2),
50
52
  isSideNavExpanded = _useState2[0],
51
53
  setIsSideNavExpanded = _useState2[1];
@@ -9,7 +9,7 @@ import { SetSideNavVisibilityState, SideNavVisibilityState } from './visibility-
9
9
  export var SideNavVisibilityProvider = function SideNavVisibilityProvider(_ref) {
10
10
  var children = _ref.children,
11
11
  defaultCollapsed = _ref.defaultCollapsed;
12
- var initialState = fg('platform_dst_nav4_full_height_sidebar_api_changes') ? {
12
+ var initialState = typeof defaultCollapsed === 'boolean' && fg('platform_dst_nav4_side_nav_default_collapsed_api') ? {
13
13
  desktop: defaultCollapsed ? 'collapsed' : 'expanded',
14
14
  mobile: 'collapsed',
15
15
  flyout: 'closed',
@@ -8,6 +8,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
8
8
  import { UNSAFE_useMediaQuery } from '@atlaskit/primitives/compiled';
9
9
  import { TopNavStartAttachRef } from '../../../context/top-nav-start/top-nav-start-context';
10
10
  import { useSideNavVisibility } from '../side-nav/use-side-nav-visibility';
11
+ import { SideNavVisibilityState } from '../side-nav/visibility-context';
11
12
 
12
13
  /**
13
14
  * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
@@ -172,14 +173,22 @@ export function TopNavStart(_ref3) {
172
173
 
173
174
  // Used to prevent the reorder animations from running on the initial render.
174
175
  var isFirstRenderRef = useRef(true);
176
+ var sideNavState = useContext(SideNavVisibilityState);
175
177
  useEffect(function () {
176
178
  if (!fg('navx-full-height-sidebar')) {
177
179
  return;
178
180
  }
181
+
182
+ // Ignore renders until the side nav state is initialized
183
+ // So that apps using the legacy API for setting side nav default state do not see
184
+ // animations when they shouldn't
185
+ if (sideNavState === null) {
186
+ return;
187
+ }
179
188
  if (isFirstRenderRef.current) {
180
189
  isFirstRenderRef.current = false;
181
190
  }
182
- }, []);
191
+ }, [sideNavState]);
183
192
 
184
193
  // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
185
194
  // can happen a lot (e.g. if the parent re-renders)
@@ -44,7 +44,7 @@ export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes,
44
44
  * persisted state using the `onCollapse` and `onExpand` callbacks, to ensure it is up to date
45
45
  * when the app is reloaded.
46
46
  *
47
- * __Note:__ This prop will only work when the `platform_dst_nav4_full_height_sidebar_api_changes` gate is enabled.
47
+ * __Note:__ When provided, the `defaultCollapsed` props on `SideNav` and `SideNavToggleButton` will be ignored.
48
48
  */
49
49
  defaultSideNavCollapsed?: boolean;
50
50
  }): JSX.Element;
@@ -15,7 +15,7 @@ type SideNavProps = CommonSlotProps & {
15
15
  * @deprecated
16
16
  *
17
17
  * This prop is being replaced by `defaultSideNavCollapsed` on the `Root` element,
18
- * and will be removed after `platform_dst_nav4_full_height_sidebar_api_changes` is cleaned up.
18
+ * and will be removed in the future.
19
19
  *
20
20
  * ---
21
21
  *
@@ -17,7 +17,7 @@ export declare const SideNavToggleButton: ({ defaultCollapsed, expandLabel, coll
17
17
  * @deprecated
18
18
  *
19
19
  * This prop is being replaced by `defaultSideNavCollapsed` on the `Root` element,
20
- * and will be removed after `platform_dst_nav4_full_height_sidebar_api_changes` is cleaned up.
20
+ * and will be removed in the future.
21
21
  *
22
22
  * ---
23
23
  *
@@ -4,5 +4,5 @@ import React from 'react';
4
4
  */
5
5
  export declare const SideNavVisibilityProvider: ({ children, defaultCollapsed, }: {
6
6
  children: React.ReactNode;
7
- defaultCollapsed: boolean;
7
+ defaultCollapsed?: boolean;
8
8
  }) => React.JSX.Element;
@@ -19,7 +19,7 @@ type TopNavStartProps = {
19
19
  *
20
20
  * You should only render `<SideNavToggleButton>` inside this slot, not as a child.
21
21
  *
22
- * After `platform_dst_nav4_full_height_sidebar_api_changes` rolls out,
22
+ * After `platform_dst_nav4_side_nav_toggle_button_slot` rolls out,
23
23
  * this prop will become required.
24
24
  *
25
25
  * Consumers that do not need a toggle button can explicitly pass `null`.
@@ -44,7 +44,7 @@ export declare function Root({ children, xcss, UNSAFE_dangerouslyHoistSlotSizes,
44
44
  * persisted state using the `onCollapse` and `onExpand` callbacks, to ensure it is up to date
45
45
  * when the app is reloaded.
46
46
  *
47
- * __Note:__ This prop will only work when the `platform_dst_nav4_full_height_sidebar_api_changes` gate is enabled.
47
+ * __Note:__ When provided, the `defaultCollapsed` props on `SideNav` and `SideNavToggleButton` will be ignored.
48
48
  */
49
49
  defaultSideNavCollapsed?: boolean;
50
50
  }): JSX.Element;
@@ -15,7 +15,7 @@ type SideNavProps = CommonSlotProps & {
15
15
  * @deprecated
16
16
  *
17
17
  * This prop is being replaced by `defaultSideNavCollapsed` on the `Root` element,
18
- * and will be removed after `platform_dst_nav4_full_height_sidebar_api_changes` is cleaned up.
18
+ * and will be removed in the future.
19
19
  *
20
20
  * ---
21
21
  *
@@ -17,7 +17,7 @@ export declare const SideNavToggleButton: ({ defaultCollapsed, expandLabel, coll
17
17
  * @deprecated
18
18
  *
19
19
  * This prop is being replaced by `defaultSideNavCollapsed` on the `Root` element,
20
- * and will be removed after `platform_dst_nav4_full_height_sidebar_api_changes` is cleaned up.
20
+ * and will be removed in the future.
21
21
  *
22
22
  * ---
23
23
  *
@@ -4,5 +4,5 @@ import React from 'react';
4
4
  */
5
5
  export declare const SideNavVisibilityProvider: ({ children, defaultCollapsed, }: {
6
6
  children: React.ReactNode;
7
- defaultCollapsed: boolean;
7
+ defaultCollapsed?: boolean;
8
8
  }) => React.JSX.Element;
@@ -19,7 +19,7 @@ type TopNavStartProps = {
19
19
  *
20
20
  * You should only render `<SideNavToggleButton>` inside this slot, not as a child.
21
21
  *
22
- * After `platform_dst_nav4_full_height_sidebar_api_changes` rolls out,
22
+ * After `platform_dst_nav4_side_nav_toggle_button_slot` rolls out,
23
23
  * this prop will become required.
24
24
  *
25
25
  * Consumers that do not need a toggle button can explicitly pass `null`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/navigation-system",
3
- "version": "4.2.0",
3
+ "version": "4.3.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",
@@ -145,6 +145,9 @@
145
145
  }
146
146
  },
147
147
  "platform-feature-flags": {
148
+ "platform_dst_nav4_side_nav_default_collapsed_api": {
149
+ "type": "boolean"
150
+ },
148
151
  "platform_dst_nav4_side_nav_toggle_ref_fix": {
149
152
  "type": "boolean"
150
153
  },
@@ -170,9 +173,6 @@
170
173
  "team25-eu-jira-logo-updates-csm-jsm": {
171
174
  "type": "boolean"
172
175
  },
173
- "platform_dst_nav4_full_height_sidebar_api_changes": {
174
- "type": "boolean"
175
- },
176
176
  "platform-dst-tooltip-shortcuts": {
177
177
  "type": "boolean"
178
178
  },