@atlaskit/navigation-system 5.1.0 → 5.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 (32) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/cjs/ui/menu-item/button-menu-item.js +9 -6
  3. package/dist/cjs/ui/menu-item/menu-item.compiled.css +2 -0
  4. package/dist/cjs/ui/menu-item/menu-item.js +1 -1
  5. package/dist/cjs/ui/page-layout/side-nav/side-nav.js +57 -8
  6. package/dist/cjs/ui/page-layout/side-nav/toggle-button.js +27 -1
  7. package/dist/cjs/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.js +4 -4
  8. package/dist/es2019/ui/menu-item/button-menu-item.js +34 -30
  9. package/dist/es2019/ui/menu-item/menu-item.compiled.css +2 -0
  10. package/dist/es2019/ui/menu-item/menu-item.js +1 -1
  11. package/dist/es2019/ui/page-layout/side-nav/side-nav.js +52 -4
  12. package/dist/es2019/ui/page-layout/side-nav/toggle-button.js +28 -1
  13. package/dist/es2019/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.js +4 -4
  14. package/dist/esm/ui/menu-item/button-menu-item.js +9 -7
  15. package/dist/esm/ui/menu-item/menu-item.compiled.css +2 -0
  16. package/dist/esm/ui/menu-item/menu-item.js +1 -1
  17. package/dist/esm/ui/page-layout/side-nav/side-nav.js +57 -8
  18. package/dist/esm/ui/page-layout/side-nav/toggle-button.js +27 -1
  19. package/dist/esm/ui/page-layout/side-nav/use-side-nav-visibility-callbacks.js +4 -4
  20. package/dist/types/ui/menu-item/button-menu-item.d.ts +14 -5
  21. package/dist/types/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.d.ts +0 -4
  22. package/dist/types/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.d.ts +0 -4
  23. package/dist/types/ui/menu-item/menu-item.d.ts +0 -1
  24. package/dist/types/ui/menu-item/types.d.ts +4 -0
  25. package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +2 -2
  26. package/dist/types-ts4.5/ui/menu-item/button-menu-item.d.ts +14 -5
  27. package/dist/types-ts4.5/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.d.ts +0 -4
  28. package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.d.ts +0 -4
  29. package/dist/types-ts4.5/ui/menu-item/menu-item.d.ts +0 -1
  30. package/dist/types-ts4.5/ui/menu-item/types.d.ts +4 -0
  31. package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav.d.ts +2 -2
  32. package/package.json +7 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @atlassian/navigation-system
2
2
 
3
+ ## 5.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`c8cb0a09979c1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c8cb0a09979c1) -
8
+ Adds instrumentation to the side navigation behind the `platform_dst_nav4_fhs_instrumentation_1`
9
+ feature gate.
10
+ - [`c8cb0a09979c1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c8cb0a09979c1) -
11
+ Changes the `trigger` property in the side nav `onExpand` and `onCollapse` callbacks to be exposed
12
+ behind the `platform_dst_nav4_fhs_instrumentation_1` feature gate instead of the
13
+ `navx-full-height-sidebar` feature gate. The `platform_dst_nav4_fhs_instrumentation_1` feature
14
+ gate is intended to roll out sooner.
15
+ - [`f942d05c8a8f2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f942d05c8a8f2) -
16
+ Adds support for selected state in ButtonMenuItem component (under feature gate
17
+ platform-dst-buttonmenuitem-selected-state-support)
18
+
19
+ ## 5.2.0
20
+
21
+ ### Minor Changes
22
+
23
+ - [`fef4ccb6af01f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fef4ccb6af01f) -
24
+ Cleans up the `platform_dst_nav4_side_nav_default_collapsed_api` feature gate. Default side nav
25
+ collapsed state can now be passed into the `Root` component via the `defaultSideNavCollapsed`
26
+ prop. This is the preferred API, and the legacy API will be removed at some point in the future.
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies
31
+
3
32
  ## 5.1.0
4
33
 
5
34
  ### Minor Changes
@@ -6,15 +6,10 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.ButtonMenuItem = void 0;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
9
10
  var _menuItem = require("./menu-item");
10
11
  var _menuListItem = require("./menu-list-item");
11
12
  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); }
12
- /**
13
- * We intentionally do not support the `isSelected` prop (which other menu item components
14
- * support) because `ButtonMenuItem`s do not correspond to a "page", so can't be navigated
15
- * to and become in a selected state.
16
- */
17
-
18
13
  /**
19
14
  * __ButtonMenuItem__
20
15
  *
@@ -27,9 +22,13 @@ var ButtonMenuItem = exports.ButtonMenuItem = /*#__PURE__*/(0, _react.forwardRef
27
22
  description = _ref.description,
28
23
  elemAfter = _ref.elemAfter,
29
24
  isDisabled = _ref.isDisabled,
25
+ isSelected = _ref.isSelected,
30
26
  elemBefore = _ref.elemBefore,
31
27
  actionsOnHover = _ref.actionsOnHover,
32
28
  onClick = _ref.onClick,
29
+ ariaControls = _ref['aria-controls'],
30
+ ariaExpanded = _ref['aria-expanded'],
31
+ ariaHasPopup = _ref['aria-haspopup'],
33
32
  interactionName = _ref.interactionName,
34
33
  isContentTooltipDisabled = _ref.isContentTooltipDisabled,
35
34
  visualContentRef = _ref.visualContentRef,
@@ -52,6 +51,10 @@ var ButtonMenuItem = exports.ButtonMenuItem = /*#__PURE__*/(0, _react.forwardRef
52
51
  actions: isDisabled ? undefined : actions,
53
52
  actionsOnHover: isDisabled ? undefined : actionsOnHover,
54
53
  onClick: onClick,
54
+ ariaControls: (0, _platformFeatureFlags.fg)('platform-dst-buttonmenuitem-selected-state-support') ? ariaControls : undefined,
55
+ ariaExpanded: (0, _platformFeatureFlags.fg)('platform-dst-buttonmenuitem-selected-state-support') ? ariaExpanded : undefined,
56
+ ariaHasPopup: (0, _platformFeatureFlags.fg)('platform-dst-buttonmenuitem-selected-state-support') ? ariaHasPopup : undefined,
57
+ isSelected: (0, _platformFeatureFlags.fg)('platform-dst-buttonmenuitem-selected-state-support') ? isSelected : undefined,
55
58
  ref: forwardedRef,
56
59
  visualContentRef: visualContentRef,
57
60
  interactionName: interactionName,
@@ -57,6 +57,7 @@
57
57
  ._bfhk1o0g{background-color:var(--notch-color)}
58
58
  ._bfhkcdhy{background-color:var(--ds-background-neutral-bold,#44546f)}
59
59
  ._bfhkfg4m{background-color:var(--ds-background-selected,#e9f2ff)}
60
+ ._bfhkn7od{background-color:unset}
60
61
  ._bozg12x7{padding-inline-start:var(--ds-space-075,6px)}
61
62
  ._bozg1b66{padding-inline-start:var(--ds-space-050,4px)}
62
63
  ._db801b66{--actions-on-hover-padding:var(--ds-space-050,4px)}
@@ -96,6 +97,7 @@
96
97
  ._11om6b4r:hover{animation-name:k1xyysw3}
97
98
  ._1sjuglyw:hover{--elem-after-display:none}
98
99
  ._1uy01amc:hover{animation-delay:.8s}
100
+ ._30l31lh4:hover{color:var(--ds-text-disabled,#091e424f)}
99
101
  ._30l3aqb7:hover{color:var(--ds-text-selected,#0c66e4)}
100
102
  ._7psyru3m:hover{animation-duration:0s}
101
103
  ._bir2q7pw:hover{animation-fill-mode:forwards}
@@ -154,7 +154,7 @@ var containerStyles = {
154
154
  showHoverActions: "_uomdkb7n _pmxp1wug _db801b66",
155
155
  removeElemAfterOnHoverOrOpenNestedPopup: "_1djyglyw _1mfcglyw _1sjuglyw",
156
156
  selected: "_bfhkfg4m _syazaqb7 _1yyu1fvw _1swvi1yw _30l3aqb7 _irr3i1yw",
157
- disabled: "_syaz1lh4 _irr3n7od",
157
+ disabled: "_syaz1lh4 _bfhkn7od _irr3n7od _30l31lh4",
158
158
  hasDescription: "_4t3i1wto",
159
159
  dragging: "_tzy41ou4"
160
160
  };
@@ -17,6 +17,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
17
17
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
18
18
  var _bindEventListener = require("bind-event-listener");
19
19
  var _reactDom = require("react-dom");
20
+ var _analyticsNext = require("@atlaskit/analytics-next");
20
21
  var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
21
22
  var _useStableRef = _interopRequireDefault(require("@atlaskit/ds-lib/use-stable-ref"));
22
23
  var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
@@ -144,15 +145,43 @@ function SideNavInternal(_ref) {
144
145
  var _useState = (0, _react.useState)(defaultCollapsed),
145
146
  _useState2 = (0, _slicedToArray2.default)(_useState, 1),
146
147
  initialDefaultCollapsed = _useState2[0];
148
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
149
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
150
+ var _useState3 = (0, _react.useState)(isExpandedOnDesktop),
151
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 1),
152
+ initialIsExpandedOnDesktop = _useState4[0];
153
+
154
+ /**
155
+ * Captures the initial collapsed/expanded state of the side nav.
156
+ *
157
+ * Only firing on desktop because the nav is never open by default on mobile.
158
+ */
159
+ (0, _react.useEffect)(function () {
160
+ if (initialIsExpandedOnDesktop && (0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
161
+ var isDesktop = window.matchMedia('(min-width: 64rem)').matches;
162
+ if (isDesktop) {
163
+ var navigationAnalyticsEvent = createAnalyticsEvent({
164
+ source: 'topNav',
165
+ actionSubject: 'sideNav',
166
+ action: 'viewed',
167
+ actionSubjectId: 'sideNavMenu',
168
+ attributes: {
169
+ screen: 'desktop'
170
+ }
171
+ });
172
+ navigationAnalyticsEvent.fire('navigation');
173
+ }
174
+ }
175
+ }, [createAnalyticsEvent, initialIsExpandedOnDesktop]);
147
176
  var defaultWidth = (0, _useSafeDefaultWidth.useSafeDefaultWidth)({
148
177
  defaultWidthProp: defaultWidthProp,
149
178
  fallbackDefaultWidth: fallbackDefaultWidth,
150
179
  slotName: 'SideNav'
151
180
  });
152
- var _useState3 = (0, _react.useState)(defaultWidth),
153
- _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
154
- width = _useState4[0],
155
- setWidth = _useState4[1];
181
+ var _useState5 = (0, _react.useState)(defaultWidth),
182
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
183
+ width = _useState6[0],
184
+ setWidth = _useState6[1];
156
185
  var clampedWidth = "clamp(".concat(widthResizeBounds.min, ", ").concat(width, "px, ").concat(widthResizeBounds.max, ")");
157
186
  var dangerouslyHoistSlotSizes = (0, _react.useContext)(_hoistSlotSizesContext.DangerouslyHoistSlotSizes);
158
187
  var navRef = (0, _react.useRef)(null);
@@ -344,11 +373,21 @@ function SideNavInternal(_ref) {
344
373
  var handleExpand = (0, _react.useCallback)(function (_ref2) {
345
374
  var screen = _ref2.screen,
346
375
  trigger = _ref2.trigger;
347
- if ((0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
376
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
348
377
  onExpand === null || onExpand === void 0 || onExpand({
349
378
  screen: screen,
350
379
  trigger: trigger
351
380
  });
381
+ var navigationAnalyticsEvent = createAnalyticsEvent({
382
+ source: 'topNav',
383
+ actionSubject: 'sideNav',
384
+ action: 'expanded',
385
+ actionSubjectId: 'sideNavMenu',
386
+ attributes: {
387
+ trigger: trigger
388
+ }
389
+ });
390
+ navigationAnalyticsEvent.fire('navigation');
352
391
  } else {
353
392
  onExpand === null || onExpand === void 0 || onExpand({
354
393
  screen: screen
@@ -358,15 +397,25 @@ function SideNavInternal(_ref) {
358
397
  // When the side nav gets expanded, we close the flyout to reset it.
359
398
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to expand.
360
399
  updateFlyoutState('force-close');
361
- }, [onExpand, updateFlyoutState]);
400
+ }, [onExpand, updateFlyoutState, createAnalyticsEvent]);
362
401
  var handleCollapse = (0, _react.useCallback)(function (_ref3) {
363
402
  var screen = _ref3.screen,
364
403
  trigger = _ref3.trigger;
365
- if ((0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
404
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
366
405
  onCollapse === null || onCollapse === void 0 || onCollapse({
367
406
  screen: screen,
368
407
  trigger: trigger
369
408
  });
409
+ var navigationAnalyticsEvent = createAnalyticsEvent({
410
+ source: 'topNav',
411
+ actionSubject: 'sideNav',
412
+ action: 'collapsed',
413
+ actionSubjectId: 'sideNavMenu',
414
+ attributes: {
415
+ trigger: trigger
416
+ }
417
+ });
418
+ navigationAnalyticsEvent.fire('navigation');
370
419
  } else {
371
420
  onCollapse === null || onCollapse === void 0 || onCollapse({
372
421
  screen: screen
@@ -376,7 +425,7 @@ function SideNavInternal(_ref) {
376
425
  // When the side nav gets collapsed, we close the flyout to reset it.
377
426
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to collapse.
378
427
  updateFlyoutState('force-close');
379
- }, [onCollapse, updateFlyoutState]);
428
+ }, [onCollapse, updateFlyoutState, createAnalyticsEvent]);
380
429
  (0, _useSideNavVisibilityCallbacks.useSideNavVisibilityCallbacks)({
381
430
  onExpand: handleExpand,
382
431
  onCollapse: handleCollapse,
@@ -13,6 +13,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
13
13
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
14
  var _react = _interopRequireWildcard(require("react"));
15
15
  var _bindEventListener = require("bind-event-listener");
16
+ var _analyticsNext = require("@atlaskit/analytics-next");
16
17
  var _sidebarCollapse = _interopRequireDefault(require("@atlaskit/icon/core/sidebar-collapse"));
17
18
  var _sidebarExpand = _interopRequireDefault(require("@atlaskit/icon/core/sidebar-expand"));
18
19
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
@@ -105,12 +106,36 @@ var SideNavToggleButton = exports.SideNavToggleButton = function SideNavToggleBu
105
106
  var toggleVisibility = (0, _useToggleSideNav.useToggleSideNav)({
106
107
  trigger: 'toggle-button'
107
108
  });
109
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
110
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
108
111
  var handleClick = (0, _react.useCallback)(function (event, analyticsEvent) {
109
112
  onClick === null || onClick === void 0 || onClick(event, analyticsEvent, {
110
113
  isSideNavVisible: isSideNavExpanded
111
114
  });
112
115
  toggleVisibility();
113
- }, [onClick, toggleVisibility, isSideNavExpanded]);
116
+ }, [onClick, isSideNavExpanded, toggleVisibility]);
117
+ var handlePointerEnter = (0, _react.useCallback)(function () {
118
+ if (!(0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
119
+ return;
120
+ }
121
+
122
+ // Hovers don't do anything on mobile, so not capturing
123
+ var isDesktop = window.matchMedia('(min-width: 64rem)').matches;
124
+ if (!isDesktop) {
125
+ return;
126
+ }
127
+ var navigationAnalyticsEvent = createAnalyticsEvent({
128
+ source: 'topNav',
129
+ actionSubject: 'sideNav',
130
+ action: 'hovered',
131
+ actionSubjectId: 'sideNavButton',
132
+ attributes: {
133
+ itemState: isSideNavExpanded ? 'expanded' : 'collapsed',
134
+ screen: 'desktop'
135
+ }
136
+ });
137
+ navigationAnalyticsEvent.fire('navigation');
138
+ }, [createAnalyticsEvent, isSideNavExpanded]);
114
139
 
115
140
  /**
116
141
  * ## Behaviour
@@ -145,6 +170,7 @@ var SideNavToggleButton = exports.SideNavToggleButton = function SideNavToggleBu
145
170
  label: isSideNavExpanded ? collapseLabel : expandLabel,
146
171
  icon: icon,
147
172
  onClick: handleClick,
173
+ onPointerEnter: handlePointerEnter,
148
174
  testId: testId,
149
175
  isTooltipDisabled: false,
150
176
  interactionName: interactionName,
@@ -38,7 +38,7 @@ function useSideNavVisibilityCallbacks(_ref) {
38
38
  return;
39
39
  }
40
40
  if (isExpandedOnDesktop) {
41
- if ((0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
41
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
42
42
  var _onExpandRef$current;
43
43
  (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 || _onExpandRef$current.call(onExpandRef, {
44
44
  screen: 'desktop',
@@ -51,7 +51,7 @@ function useSideNavVisibilityCallbacks(_ref) {
51
51
  });
52
52
  }
53
53
  } else {
54
- if ((0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
54
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
55
55
  var _onCollapseRef$curren;
56
56
  (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 || _onCollapseRef$curren.call(onCollapseRef, {
57
57
  screen: 'desktop',
@@ -78,7 +78,7 @@ function useSideNavVisibilityCallbacks(_ref) {
78
78
  return;
79
79
  }
80
80
  if (isExpandedOnMobile) {
81
- if ((0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
81
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
82
82
  var _onExpandRef$current3;
83
83
  (_onExpandRef$current3 = onExpandRef.current) === null || _onExpandRef$current3 === void 0 || _onExpandRef$current3.call(onExpandRef, {
84
84
  screen: 'mobile',
@@ -91,7 +91,7 @@ function useSideNavVisibilityCallbacks(_ref) {
91
91
  });
92
92
  }
93
93
  } else {
94
- if ((0, _platformFeatureFlags.fg)('navx-full-height-sidebar')) {
94
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_fhs_instrumentation_1')) {
95
95
  var _onCollapseRef$curren3;
96
96
  (_onCollapseRef$curren3 = onCollapseRef.current) === null || _onCollapseRef$curren3 === void 0 || _onCollapseRef$curren3.call(onCollapseRef, {
97
97
  screen: 'mobile',
@@ -1,13 +1,7 @@
1
1
  import React, { forwardRef } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { MenuItemBase } from './menu-item';
3
4
  import { MenuListItem } from './menu-list-item';
4
-
5
- /**
6
- * We intentionally do not support the `isSelected` prop (which other menu item components
7
- * support) because `ButtonMenuItem`s do not correspond to a "page", so can't be navigated
8
- * to and become in a selected state.
9
- */
10
-
11
5
  /**
12
6
  * __ButtonMenuItem__
13
7
  *
@@ -20,9 +14,13 @@ export const ButtonMenuItem = /*#__PURE__*/forwardRef(({
20
14
  description,
21
15
  elemAfter,
22
16
  isDisabled,
17
+ isSelected,
23
18
  elemBefore,
24
19
  actionsOnHover,
25
20
  onClick,
21
+ 'aria-controls': ariaControls,
22
+ 'aria-expanded': ariaExpanded,
23
+ 'aria-haspopup': ariaHasPopup,
26
24
  interactionName,
27
25
  isContentTooltipDisabled,
28
26
  visualContentRef,
@@ -30,26 +28,32 @@ export const ButtonMenuItem = /*#__PURE__*/forwardRef(({
30
28
  isDragging,
31
29
  hasDragIndicator,
32
30
  dropIndicator
33
- }, forwardedRef) => /*#__PURE__*/React.createElement(MenuListItem, {
34
- ref: listItemRef
35
- }, /*#__PURE__*/React.createElement(MenuItemBase, {
36
- testId: testId,
37
- description: description,
38
- elemAfter: elemAfter,
39
- elemBefore: elemBefore,
40
- isDisabled: isDisabled
41
- /**
42
- * Not passing `actions` and `actionsOnHover` to MenuItemBase when `isDisabled`,
43
- * so they aren't rendered in the disabled state.
44
- */,
45
- actions: isDisabled ? undefined : actions,
46
- actionsOnHover: isDisabled ? undefined : actionsOnHover,
47
- onClick: onClick,
48
- ref: forwardedRef,
49
- visualContentRef: visualContentRef,
50
- interactionName: interactionName,
51
- isContentTooltipDisabled: isContentTooltipDisabled,
52
- isDragging: isDragging,
53
- hasDragIndicator: hasDragIndicator,
54
- dropIndicator: dropIndicator
55
- }, children)));
31
+ }, forwardedRef) => {
32
+ return /*#__PURE__*/React.createElement(MenuListItem, {
33
+ ref: listItemRef
34
+ }, /*#__PURE__*/React.createElement(MenuItemBase, {
35
+ testId: testId,
36
+ description: description,
37
+ elemAfter: elemAfter,
38
+ elemBefore: elemBefore,
39
+ isDisabled: isDisabled
40
+ /**
41
+ * Not passing `actions` and `actionsOnHover` to MenuItemBase when `isDisabled`,
42
+ * so they aren't rendered in the disabled state.
43
+ */,
44
+ actions: isDisabled ? undefined : actions,
45
+ actionsOnHover: isDisabled ? undefined : actionsOnHover,
46
+ onClick: onClick,
47
+ ariaControls: fg('platform-dst-buttonmenuitem-selected-state-support') ? ariaControls : undefined,
48
+ ariaExpanded: fg('platform-dst-buttonmenuitem-selected-state-support') ? ariaExpanded : undefined,
49
+ ariaHasPopup: fg('platform-dst-buttonmenuitem-selected-state-support') ? ariaHasPopup : undefined,
50
+ isSelected: fg('platform-dst-buttonmenuitem-selected-state-support') ? isSelected : undefined,
51
+ ref: forwardedRef,
52
+ visualContentRef: visualContentRef,
53
+ interactionName: interactionName,
54
+ isContentTooltipDisabled: isContentTooltipDisabled,
55
+ isDragging: isDragging,
56
+ hasDragIndicator: hasDragIndicator,
57
+ dropIndicator: dropIndicator
58
+ }, children));
59
+ });
@@ -57,6 +57,7 @@
57
57
  ._bfhk1o0g{background-color:var(--notch-color)}
58
58
  ._bfhkcdhy{background-color:var(--ds-background-neutral-bold,#44546f)}
59
59
  ._bfhkfg4m{background-color:var(--ds-background-selected,#e9f2ff)}
60
+ ._bfhkn7od{background-color:unset}
60
61
  ._bozg12x7{padding-inline-start:var(--ds-space-075,6px)}
61
62
  ._bozg1b66{padding-inline-start:var(--ds-space-050,4px)}
62
63
  ._db801b66{--actions-on-hover-padding:var(--ds-space-050,4px)}
@@ -96,6 +97,7 @@
96
97
  ._11om6b4r:hover{animation-name:k1xyysw3}
97
98
  ._1sjuglyw:hover{--elem-after-display:none}
98
99
  ._1uy01amc:hover{animation-delay:.8s}
100
+ ._30l31lh4:hover{color:var(--ds-text-disabled,#091e424f)}
99
101
  ._30l3aqb7:hover{color:var(--ds-text-selected,#0c66e4)}
100
102
  ._7psyru3m:hover{animation-duration:0s}
101
103
  ._bir2q7pw:hover{animation-fill-mode:forwards}
@@ -137,7 +137,7 @@ const containerStyles = {
137
137
  showHoverActions: "_uomdkb7n _pmxp1wug _db801b66",
138
138
  removeElemAfterOnHoverOrOpenNestedPopup: "_1djyglyw _1mfcglyw _1sjuglyw",
139
139
  selected: "_bfhkfg4m _syazaqb7 _1yyu1fvw _1swvi1yw _30l3aqb7 _irr3i1yw",
140
- disabled: "_syaz1lh4 _irr3n7od",
140
+ disabled: "_syaz1lh4 _bfhkn7od _irr3n7od _30l31lh4",
141
141
  hasDescription: "_4t3i1wto",
142
142
  dragging: "_tzy41ou4"
143
143
  };
@@ -6,6 +6,7 @@ import { ax, ix } from "@compiled/react/runtime";
6
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
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
9
10
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
10
11
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
11
12
  import { OpenLayerObserverNamespaceProvider, useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
@@ -127,6 +128,33 @@ function SideNavInternal({
127
128
  // This is so we can use it in an effect _that only runs once_, after the initial render on the client,
128
129
  // to sync the side nav context (provided in `<Root>`) with the `defaultCollapsed` prop provided to `<SideNav>`.
129
130
  const [initialDefaultCollapsed] = useState(defaultCollapsed);
131
+ const {
132
+ createAnalyticsEvent
133
+ } = useAnalyticsEvents();
134
+ const [initialIsExpandedOnDesktop] = useState(isExpandedOnDesktop);
135
+
136
+ /**
137
+ * Captures the initial collapsed/expanded state of the side nav.
138
+ *
139
+ * Only firing on desktop because the nav is never open by default on mobile.
140
+ */
141
+ useEffect(() => {
142
+ if (initialIsExpandedOnDesktop && fg('platform_dst_nav4_fhs_instrumentation_1')) {
143
+ const isDesktop = window.matchMedia('(min-width: 64rem)').matches;
144
+ if (isDesktop) {
145
+ const navigationAnalyticsEvent = createAnalyticsEvent({
146
+ source: 'topNav',
147
+ actionSubject: 'sideNav',
148
+ action: 'viewed',
149
+ actionSubjectId: 'sideNavMenu',
150
+ attributes: {
151
+ screen: 'desktop'
152
+ }
153
+ });
154
+ navigationAnalyticsEvent.fire('navigation');
155
+ }
156
+ }
157
+ }, [createAnalyticsEvent, initialIsExpandedOnDesktop]);
130
158
  const defaultWidth = useSafeDefaultWidth({
131
159
  defaultWidthProp,
132
160
  fallbackDefaultWidth,
@@ -327,11 +355,21 @@ function SideNavInternal({
327
355
  screen,
328
356
  trigger
329
357
  }) => {
330
- if (fg('navx-full-height-sidebar')) {
358
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
331
359
  onExpand === null || onExpand === void 0 ? void 0 : onExpand({
332
360
  screen,
333
361
  trigger
334
362
  });
363
+ const navigationAnalyticsEvent = createAnalyticsEvent({
364
+ source: 'topNav',
365
+ actionSubject: 'sideNav',
366
+ action: 'expanded',
367
+ actionSubjectId: 'sideNavMenu',
368
+ attributes: {
369
+ trigger
370
+ }
371
+ });
372
+ navigationAnalyticsEvent.fire('navigation');
335
373
  } else {
336
374
  onExpand === null || onExpand === void 0 ? void 0 : onExpand({
337
375
  screen
@@ -341,16 +379,26 @@ function SideNavInternal({
341
379
  // When the side nav gets expanded, we close the flyout to reset it.
342
380
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to expand.
343
381
  updateFlyoutState('force-close');
344
- }, [onExpand, updateFlyoutState]);
382
+ }, [onExpand, updateFlyoutState, createAnalyticsEvent]);
345
383
  const handleCollapse = useCallback(({
346
384
  screen,
347
385
  trigger
348
386
  }) => {
349
- if (fg('navx-full-height-sidebar')) {
387
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
350
388
  onCollapse === null || onCollapse === void 0 ? void 0 : onCollapse({
351
389
  screen,
352
390
  trigger
353
391
  });
392
+ const navigationAnalyticsEvent = createAnalyticsEvent({
393
+ source: 'topNav',
394
+ actionSubject: 'sideNav',
395
+ action: 'collapsed',
396
+ actionSubjectId: 'sideNavMenu',
397
+ attributes: {
398
+ trigger
399
+ }
400
+ });
401
+ navigationAnalyticsEvent.fire('navigation');
354
402
  } else {
355
403
  onCollapse === null || onCollapse === void 0 ? void 0 : onCollapse({
356
404
  screen
@@ -360,7 +408,7 @@ function SideNavInternal({
360
408
  // When the side nav gets collapsed, we close the flyout to reset it.
361
409
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to collapse.
362
410
  updateFlyoutState('force-close');
363
- }, [onCollapse, updateFlyoutState]);
411
+ }, [onCollapse, updateFlyoutState, createAnalyticsEvent]);
364
412
  useSideNavVisibilityCallbacks({
365
413
  onExpand: handleExpand,
366
414
  onCollapse: handleCollapse,
@@ -3,6 +3,7 @@ import "./toggle-button.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { bind } from 'bind-event-listener';
6
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
6
7
  import SidebarCollapseIcon from '@atlaskit/icon/core/sidebar-collapse';
7
8
  import SidebarExpandIcon from '@atlaskit/icon/core/sidebar-expand';
8
9
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -88,12 +89,37 @@ export const SideNavToggleButton = ({
88
89
  const toggleVisibility = useToggleSideNav({
89
90
  trigger: 'toggle-button'
90
91
  });
92
+ const {
93
+ createAnalyticsEvent
94
+ } = useAnalyticsEvents();
91
95
  const handleClick = useCallback((event, analyticsEvent) => {
92
96
  onClick === null || onClick === void 0 ? void 0 : onClick(event, analyticsEvent, {
93
97
  isSideNavVisible: isSideNavExpanded
94
98
  });
95
99
  toggleVisibility();
96
- }, [onClick, toggleVisibility, isSideNavExpanded]);
100
+ }, [onClick, isSideNavExpanded, toggleVisibility]);
101
+ const handlePointerEnter = useCallback(() => {
102
+ if (!fg('platform_dst_nav4_fhs_instrumentation_1')) {
103
+ return;
104
+ }
105
+
106
+ // Hovers don't do anything on mobile, so not capturing
107
+ const isDesktop = window.matchMedia('(min-width: 64rem)').matches;
108
+ if (!isDesktop) {
109
+ return;
110
+ }
111
+ const navigationAnalyticsEvent = createAnalyticsEvent({
112
+ source: 'topNav',
113
+ actionSubject: 'sideNav',
114
+ action: 'hovered',
115
+ actionSubjectId: 'sideNavButton',
116
+ attributes: {
117
+ itemState: isSideNavExpanded ? 'expanded' : 'collapsed',
118
+ screen: 'desktop'
119
+ }
120
+ });
121
+ navigationAnalyticsEvent.fire('navigation');
122
+ }, [createAnalyticsEvent, isSideNavExpanded]);
97
123
 
98
124
  /**
99
125
  * ## Behaviour
@@ -127,6 +153,7 @@ export const SideNavToggleButton = ({
127
153
  label: isSideNavExpanded ? collapseLabel : expandLabel,
128
154
  icon: icon,
129
155
  onClick: handleClick,
156
+ onPointerEnter: handlePointerEnter,
130
157
  testId: testId,
131
158
  isTooltipDisabled: false,
132
159
  interactionName: interactionName,
@@ -32,7 +32,7 @@ export function useSideNavVisibilityCallbacks({
32
32
  return;
33
33
  }
34
34
  if (isExpandedOnDesktop) {
35
- if (fg('navx-full-height-sidebar')) {
35
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
36
36
  var _onExpandRef$current;
37
37
  (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 ? void 0 : _onExpandRef$current.call(onExpandRef, {
38
38
  screen: 'desktop',
@@ -45,7 +45,7 @@ export function useSideNavVisibilityCallbacks({
45
45
  });
46
46
  }
47
47
  } else {
48
- if (fg('navx-full-height-sidebar')) {
48
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
49
49
  var _onCollapseRef$curren;
50
50
  (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 ? void 0 : _onCollapseRef$curren.call(onCollapseRef, {
51
51
  screen: 'desktop',
@@ -72,7 +72,7 @@ export function useSideNavVisibilityCallbacks({
72
72
  return;
73
73
  }
74
74
  if (isExpandedOnMobile) {
75
- if (fg('navx-full-height-sidebar')) {
75
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
76
76
  var _onExpandRef$current3;
77
77
  (_onExpandRef$current3 = onExpandRef.current) === null || _onExpandRef$current3 === void 0 ? void 0 : _onExpandRef$current3.call(onExpandRef, {
78
78
  screen: 'mobile',
@@ -85,7 +85,7 @@ export function useSideNavVisibilityCallbacks({
85
85
  });
86
86
  }
87
87
  } else {
88
- if (fg('navx-full-height-sidebar')) {
88
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
89
89
  var _onCollapseRef$curren3;
90
90
  (_onCollapseRef$curren3 = onCollapseRef.current) === null || _onCollapseRef$curren3 === void 0 ? void 0 : _onCollapseRef$curren3.call(onCollapseRef, {
91
91
  screen: 'mobile',
@@ -1,13 +1,7 @@
1
1
  import React, { forwardRef } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { MenuItemBase } from './menu-item';
3
4
  import { MenuListItem } from './menu-list-item';
4
-
5
- /**
6
- * We intentionally do not support the `isSelected` prop (which other menu item components
7
- * support) because `ButtonMenuItem`s do not correspond to a "page", so can't be navigated
8
- * to and become in a selected state.
9
- */
10
-
11
5
  /**
12
6
  * __ButtonMenuItem__
13
7
  *
@@ -20,9 +14,13 @@ export var ButtonMenuItem = /*#__PURE__*/forwardRef(function (_ref, forwardedRef
20
14
  description = _ref.description,
21
15
  elemAfter = _ref.elemAfter,
22
16
  isDisabled = _ref.isDisabled,
17
+ isSelected = _ref.isSelected,
23
18
  elemBefore = _ref.elemBefore,
24
19
  actionsOnHover = _ref.actionsOnHover,
25
20
  onClick = _ref.onClick,
21
+ ariaControls = _ref['aria-controls'],
22
+ ariaExpanded = _ref['aria-expanded'],
23
+ ariaHasPopup = _ref['aria-haspopup'],
26
24
  interactionName = _ref.interactionName,
27
25
  isContentTooltipDisabled = _ref.isContentTooltipDisabled,
28
26
  visualContentRef = _ref.visualContentRef,
@@ -45,6 +43,10 @@ export var ButtonMenuItem = /*#__PURE__*/forwardRef(function (_ref, forwardedRef
45
43
  actions: isDisabled ? undefined : actions,
46
44
  actionsOnHover: isDisabled ? undefined : actionsOnHover,
47
45
  onClick: onClick,
46
+ ariaControls: fg('platform-dst-buttonmenuitem-selected-state-support') ? ariaControls : undefined,
47
+ ariaExpanded: fg('platform-dst-buttonmenuitem-selected-state-support') ? ariaExpanded : undefined,
48
+ ariaHasPopup: fg('platform-dst-buttonmenuitem-selected-state-support') ? ariaHasPopup : undefined,
49
+ isSelected: fg('platform-dst-buttonmenuitem-selected-state-support') ? isSelected : undefined,
48
50
  ref: forwardedRef,
49
51
  visualContentRef: visualContentRef,
50
52
  interactionName: interactionName,
@@ -57,6 +57,7 @@
57
57
  ._bfhk1o0g{background-color:var(--notch-color)}
58
58
  ._bfhkcdhy{background-color:var(--ds-background-neutral-bold,#44546f)}
59
59
  ._bfhkfg4m{background-color:var(--ds-background-selected,#e9f2ff)}
60
+ ._bfhkn7od{background-color:unset}
60
61
  ._bozg12x7{padding-inline-start:var(--ds-space-075,6px)}
61
62
  ._bozg1b66{padding-inline-start:var(--ds-space-050,4px)}
62
63
  ._db801b66{--actions-on-hover-padding:var(--ds-space-050,4px)}
@@ -96,6 +97,7 @@
96
97
  ._11om6b4r:hover{animation-name:k1xyysw3}
97
98
  ._1sjuglyw:hover{--elem-after-display:none}
98
99
  ._1uy01amc:hover{animation-delay:.8s}
100
+ ._30l31lh4:hover{color:var(--ds-text-disabled,#091e424f)}
99
101
  ._30l3aqb7:hover{color:var(--ds-text-selected,#0c66e4)}
100
102
  ._7psyru3m:hover{animation-duration:0s}
101
103
  ._bir2q7pw:hover{animation-fill-mode:forwards}
@@ -143,7 +143,7 @@ var containerStyles = {
143
143
  showHoverActions: "_uomdkb7n _pmxp1wug _db801b66",
144
144
  removeElemAfterOnHoverOrOpenNestedPopup: "_1djyglyw _1mfcglyw _1sjuglyw",
145
145
  selected: "_bfhkfg4m _syazaqb7 _1yyu1fvw _1swvi1yw _30l3aqb7 _irr3i1yw",
146
- disabled: "_syaz1lh4 _irr3n7od",
146
+ disabled: "_syaz1lh4 _bfhkn7od _irr3n7od _30l31lh4",
147
147
  hasDescription: "_4t3i1wto",
148
148
  dragging: "_tzy41ou4"
149
149
  };
@@ -10,6 +10,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
10
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
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
13
14
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
14
15
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
15
16
  import { OpenLayerObserverNamespaceProvider, useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
@@ -134,15 +135,43 @@ function SideNavInternal(_ref) {
134
135
  var _useState = useState(defaultCollapsed),
135
136
  _useState2 = _slicedToArray(_useState, 1),
136
137
  initialDefaultCollapsed = _useState2[0];
138
+ var _useAnalyticsEvents = useAnalyticsEvents(),
139
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
140
+ var _useState3 = useState(isExpandedOnDesktop),
141
+ _useState4 = _slicedToArray(_useState3, 1),
142
+ initialIsExpandedOnDesktop = _useState4[0];
143
+
144
+ /**
145
+ * Captures the initial collapsed/expanded state of the side nav.
146
+ *
147
+ * Only firing on desktop because the nav is never open by default on mobile.
148
+ */
149
+ useEffect(function () {
150
+ if (initialIsExpandedOnDesktop && fg('platform_dst_nav4_fhs_instrumentation_1')) {
151
+ var isDesktop = window.matchMedia('(min-width: 64rem)').matches;
152
+ if (isDesktop) {
153
+ var navigationAnalyticsEvent = createAnalyticsEvent({
154
+ source: 'topNav',
155
+ actionSubject: 'sideNav',
156
+ action: 'viewed',
157
+ actionSubjectId: 'sideNavMenu',
158
+ attributes: {
159
+ screen: 'desktop'
160
+ }
161
+ });
162
+ navigationAnalyticsEvent.fire('navigation');
163
+ }
164
+ }
165
+ }, [createAnalyticsEvent, initialIsExpandedOnDesktop]);
137
166
  var defaultWidth = useSafeDefaultWidth({
138
167
  defaultWidthProp: defaultWidthProp,
139
168
  fallbackDefaultWidth: fallbackDefaultWidth,
140
169
  slotName: 'SideNav'
141
170
  });
142
- var _useState3 = useState(defaultWidth),
143
- _useState4 = _slicedToArray(_useState3, 2),
144
- width = _useState4[0],
145
- setWidth = _useState4[1];
171
+ var _useState5 = useState(defaultWidth),
172
+ _useState6 = _slicedToArray(_useState5, 2),
173
+ width = _useState6[0],
174
+ setWidth = _useState6[1];
146
175
  var clampedWidth = "clamp(".concat(widthResizeBounds.min, ", ").concat(width, "px, ").concat(widthResizeBounds.max, ")");
147
176
  var dangerouslyHoistSlotSizes = useContext(DangerouslyHoistSlotSizes);
148
177
  var navRef = useRef(null);
@@ -334,11 +363,21 @@ function SideNavInternal(_ref) {
334
363
  var handleExpand = useCallback(function (_ref2) {
335
364
  var screen = _ref2.screen,
336
365
  trigger = _ref2.trigger;
337
- if (fg('navx-full-height-sidebar')) {
366
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
338
367
  onExpand === null || onExpand === void 0 || onExpand({
339
368
  screen: screen,
340
369
  trigger: trigger
341
370
  });
371
+ var navigationAnalyticsEvent = createAnalyticsEvent({
372
+ source: 'topNav',
373
+ actionSubject: 'sideNav',
374
+ action: 'expanded',
375
+ actionSubjectId: 'sideNavMenu',
376
+ attributes: {
377
+ trigger: trigger
378
+ }
379
+ });
380
+ navigationAnalyticsEvent.fire('navigation');
342
381
  } else {
343
382
  onExpand === null || onExpand === void 0 || onExpand({
344
383
  screen: screen
@@ -348,15 +387,25 @@ function SideNavInternal(_ref) {
348
387
  // When the side nav gets expanded, we close the flyout to reset it.
349
388
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to expand.
350
389
  updateFlyoutState('force-close');
351
- }, [onExpand, updateFlyoutState]);
390
+ }, [onExpand, updateFlyoutState, createAnalyticsEvent]);
352
391
  var handleCollapse = useCallback(function (_ref3) {
353
392
  var screen = _ref3.screen,
354
393
  trigger = _ref3.trigger;
355
- if (fg('navx-full-height-sidebar')) {
394
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
356
395
  onCollapse === null || onCollapse === void 0 || onCollapse({
357
396
  screen: screen,
358
397
  trigger: trigger
359
398
  });
399
+ var navigationAnalyticsEvent = createAnalyticsEvent({
400
+ source: 'topNav',
401
+ actionSubject: 'sideNav',
402
+ action: 'collapsed',
403
+ actionSubjectId: 'sideNavMenu',
404
+ attributes: {
405
+ trigger: trigger
406
+ }
407
+ });
408
+ navigationAnalyticsEvent.fire('navigation');
360
409
  } else {
361
410
  onCollapse === null || onCollapse === void 0 || onCollapse({
362
411
  screen: screen
@@ -366,7 +415,7 @@ function SideNavInternal(_ref) {
366
415
  // When the side nav gets collapsed, we close the flyout to reset it.
367
416
  // This prevents the flyout from staying open and ensures we are respecting the user's intent to collapse.
368
417
  updateFlyoutState('force-close');
369
- }, [onCollapse, updateFlyoutState]);
418
+ }, [onCollapse, updateFlyoutState, createAnalyticsEvent]);
370
419
  useSideNavVisibilityCallbacks({
371
420
  onExpand: handleExpand,
372
421
  onCollapse: handleCollapse,
@@ -7,6 +7,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
7
7
  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; }
8
8
  import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
9
9
  import { bind } from 'bind-event-listener';
10
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
10
11
  import SidebarCollapseIcon from '@atlaskit/icon/core/sidebar-collapse';
11
12
  import SidebarExpandIcon from '@atlaskit/icon/core/sidebar-expand';
12
13
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -96,12 +97,36 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
96
97
  var toggleVisibility = useToggleSideNav({
97
98
  trigger: 'toggle-button'
98
99
  });
100
+ var _useAnalyticsEvents = useAnalyticsEvents(),
101
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
99
102
  var handleClick = useCallback(function (event, analyticsEvent) {
100
103
  onClick === null || onClick === void 0 || onClick(event, analyticsEvent, {
101
104
  isSideNavVisible: isSideNavExpanded
102
105
  });
103
106
  toggleVisibility();
104
- }, [onClick, toggleVisibility, isSideNavExpanded]);
107
+ }, [onClick, isSideNavExpanded, toggleVisibility]);
108
+ var handlePointerEnter = useCallback(function () {
109
+ if (!fg('platform_dst_nav4_fhs_instrumentation_1')) {
110
+ return;
111
+ }
112
+
113
+ // Hovers don't do anything on mobile, so not capturing
114
+ var isDesktop = window.matchMedia('(min-width: 64rem)').matches;
115
+ if (!isDesktop) {
116
+ return;
117
+ }
118
+ var navigationAnalyticsEvent = createAnalyticsEvent({
119
+ source: 'topNav',
120
+ actionSubject: 'sideNav',
121
+ action: 'hovered',
122
+ actionSubjectId: 'sideNavButton',
123
+ attributes: {
124
+ itemState: isSideNavExpanded ? 'expanded' : 'collapsed',
125
+ screen: 'desktop'
126
+ }
127
+ });
128
+ navigationAnalyticsEvent.fire('navigation');
129
+ }, [createAnalyticsEvent, isSideNavExpanded]);
105
130
 
106
131
  /**
107
132
  * ## Behaviour
@@ -136,6 +161,7 @@ export var SideNavToggleButton = function SideNavToggleButton(_ref) {
136
161
  label: isSideNavExpanded ? collapseLabel : expandLabel,
137
162
  icon: icon,
138
163
  onClick: handleClick,
164
+ onPointerEnter: handlePointerEnter,
139
165
  testId: testId,
140
166
  isTooltipDisabled: false,
141
167
  interactionName: interactionName,
@@ -31,7 +31,7 @@ export function useSideNavVisibilityCallbacks(_ref) {
31
31
  return;
32
32
  }
33
33
  if (isExpandedOnDesktop) {
34
- if (fg('navx-full-height-sidebar')) {
34
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
35
35
  var _onExpandRef$current;
36
36
  (_onExpandRef$current = onExpandRef.current) === null || _onExpandRef$current === void 0 || _onExpandRef$current.call(onExpandRef, {
37
37
  screen: 'desktop',
@@ -44,7 +44,7 @@ export function useSideNavVisibilityCallbacks(_ref) {
44
44
  });
45
45
  }
46
46
  } else {
47
- if (fg('navx-full-height-sidebar')) {
47
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
48
48
  var _onCollapseRef$curren;
49
49
  (_onCollapseRef$curren = onCollapseRef.current) === null || _onCollapseRef$curren === void 0 || _onCollapseRef$curren.call(onCollapseRef, {
50
50
  screen: 'desktop',
@@ -71,7 +71,7 @@ export function useSideNavVisibilityCallbacks(_ref) {
71
71
  return;
72
72
  }
73
73
  if (isExpandedOnMobile) {
74
- if (fg('navx-full-height-sidebar')) {
74
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
75
75
  var _onExpandRef$current3;
76
76
  (_onExpandRef$current3 = onExpandRef.current) === null || _onExpandRef$current3 === void 0 || _onExpandRef$current3.call(onExpandRef, {
77
77
  screen: 'mobile',
@@ -84,7 +84,7 @@ export function useSideNavVisibilityCallbacks(_ref) {
84
84
  });
85
85
  }
86
86
  } else {
87
- if (fg('navx-full-height-sidebar')) {
87
+ if (fg('platform_dst_nav4_fhs_instrumentation_1')) {
88
88
  var _onCollapseRef$curren3;
89
89
  (_onCollapseRef$curren3 = onCollapseRef.current) === null || _onCollapseRef$curren3 === void 0 || _onCollapseRef$curren3.call(onCollapseRef, {
90
90
  screen: 'mobile',
@@ -1,10 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { MenuItemLinkOrButtonCommonProps, MenuItemOnClick } from './types';
3
- /**
4
- * We intentionally do not support the `isSelected` prop (which other menu item components
5
- * support) because `ButtonMenuItem`s do not correspond to a "page", so can't be navigated
6
- * to and become in a selected state.
7
- */
8
3
  export type ButtonMenuItemProps = MenuItemLinkOrButtonCommonProps & {
9
4
  /**
10
5
  * We are not using a discriminated union to enforce that the `actions` and `actionsOnHover`
@@ -24,6 +19,20 @@ export type ButtonMenuItemProps = MenuItemLinkOrButtonCommonProps & {
24
19
  * Called when the user has clicked on the trigger content.
25
20
  */
26
21
  onClick?: MenuItemOnClick<HTMLButtonElement>;
22
+ /**
23
+ * Identifies the popup element that this element controls when it is used as a popup trigger.
24
+ * Should match the `id` of the popup content for screen readers to understand the relationship.
25
+ */
26
+ 'aria-controls'?: string;
27
+ /**
28
+ * Announces to assistive technology whether the popup is currently open or closed,
29
+ * when this element is used as a popup trigger.
30
+ */
31
+ 'aria-expanded'?: boolean;
32
+ /**
33
+ * Informs assistive technology that this element triggers a popup.
34
+ */
35
+ 'aria-haspopup'?: boolean | 'dialog';
27
36
  };
28
37
  /**
29
38
  * __ButtonMenuItem__
@@ -34,10 +34,6 @@ export type ExpandableMenuItemTriggerProps = MenuItemCommonProps & Omit<MenuItem
34
34
  * will always be displayed.
35
35
  */
36
36
  elemBefore?: ReactNode;
37
- /**
38
- * Indicates that the menu item is selected.
39
- */
40
- isSelected?: boolean;
41
37
  /**
42
38
  * If provided, the chevron icon (expand/collapse symbol) will be rendered within a separate
43
39
  * icon button element. Clicking on this icon button will not trigger the `onClick` event. It
@@ -37,10 +37,6 @@ export type FlyoutMenuItemTriggerProps = MenuItemCommonProps & {
37
37
  * If you are controlling the open state of the flyout menu, use this to update your state.
38
38
  */
39
39
  onClick?: MenuItemOnClick<HTMLButtonElement>;
40
- /**
41
- * Indicates that the menu item is selected.
42
- */
43
- isSelected?: boolean;
44
40
  };
45
41
  /**
46
42
  * __FlyoutMenuItemTrigger__
@@ -34,7 +34,6 @@ type MenuItemBaseProps<T extends HTMLAnchorElement | HTMLButtonElement> = MenuIt
34
34
  href?: string | Record<string, any>;
35
35
  target?: HTMLAnchorElement['target'];
36
36
  isDisabled?: boolean;
37
- isSelected?: boolean;
38
37
  ariaControls?: string;
39
38
  ariaExpanded?: boolean;
40
39
  ariaHasPopup?: boolean | 'dialog';
@@ -33,6 +33,10 @@ export type MenuItemCommonProps = {
33
33
  * to display the full menu content and description of a menu item close by (eg with another popup)
34
34
  */
35
35
  isContentTooltipDisabled?: boolean;
36
+ /**
37
+ * Indicates that the menu item is selected.
38
+ */
39
+ isSelected?: boolean;
36
40
  /**
37
41
  * Exposes the visually complete menu item, including:
38
42
  *
@@ -44,13 +44,13 @@ type SideNavProps = CommonSlotProps & {
44
44
  /**
45
45
  * Called when the side nav is expanded.
46
46
  *
47
- * Note: The trigger parameter is only provided when the `navx-full-height-sidebar` feature flag is enabled.
47
+ * Note: The trigger parameter is only provided when the `platform_dst_nav4_fhs_instrumentation_1` feature flag is enabled.
48
48
  */
49
49
  onExpand?: VisibilityCallback;
50
50
  /**
51
51
  * Called when the side nav is collapsed.
52
52
  *
53
- * Note: The trigger parameter is only provided when the `navx-full-height-sidebar` feature flag is enabled.
53
+ * Note: The trigger parameter is only provided when the `platform_dst_nav4_fhs_instrumentation_1` feature flag is enabled.
54
54
  */
55
55
  onCollapse?: VisibilityCallback;
56
56
  /**
@@ -1,10 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { MenuItemLinkOrButtonCommonProps, MenuItemOnClick } from './types';
3
- /**
4
- * We intentionally do not support the `isSelected` prop (which other menu item components
5
- * support) because `ButtonMenuItem`s do not correspond to a "page", so can't be navigated
6
- * to and become in a selected state.
7
- */
8
3
  export type ButtonMenuItemProps = MenuItemLinkOrButtonCommonProps & {
9
4
  /**
10
5
  * We are not using a discriminated union to enforce that the `actions` and `actionsOnHover`
@@ -24,6 +19,20 @@ export type ButtonMenuItemProps = MenuItemLinkOrButtonCommonProps & {
24
19
  * Called when the user has clicked on the trigger content.
25
20
  */
26
21
  onClick?: MenuItemOnClick<HTMLButtonElement>;
22
+ /**
23
+ * Identifies the popup element that this element controls when it is used as a popup trigger.
24
+ * Should match the `id` of the popup content for screen readers to understand the relationship.
25
+ */
26
+ 'aria-controls'?: string;
27
+ /**
28
+ * Announces to assistive technology whether the popup is currently open or closed,
29
+ * when this element is used as a popup trigger.
30
+ */
31
+ 'aria-expanded'?: boolean;
32
+ /**
33
+ * Informs assistive technology that this element triggers a popup.
34
+ */
35
+ 'aria-haspopup'?: boolean | 'dialog';
27
36
  };
28
37
  /**
29
38
  * __ButtonMenuItem__
@@ -34,10 +34,6 @@ export type ExpandableMenuItemTriggerProps = MenuItemCommonProps & Omit<MenuItem
34
34
  * will always be displayed.
35
35
  */
36
36
  elemBefore?: ReactNode;
37
- /**
38
- * Indicates that the menu item is selected.
39
- */
40
- isSelected?: boolean;
41
37
  /**
42
38
  * If provided, the chevron icon (expand/collapse symbol) will be rendered within a separate
43
39
  * icon button element. Clicking on this icon button will not trigger the `onClick` event. It
@@ -37,10 +37,6 @@ export type FlyoutMenuItemTriggerProps = MenuItemCommonProps & {
37
37
  * If you are controlling the open state of the flyout menu, use this to update your state.
38
38
  */
39
39
  onClick?: MenuItemOnClick<HTMLButtonElement>;
40
- /**
41
- * Indicates that the menu item is selected.
42
- */
43
- isSelected?: boolean;
44
40
  };
45
41
  /**
46
42
  * __FlyoutMenuItemTrigger__
@@ -34,7 +34,6 @@ type MenuItemBaseProps<T extends HTMLAnchorElement | HTMLButtonElement> = MenuIt
34
34
  href?: string | Record<string, any>;
35
35
  target?: HTMLAnchorElement['target'];
36
36
  isDisabled?: boolean;
37
- isSelected?: boolean;
38
37
  ariaControls?: string;
39
38
  ariaExpanded?: boolean;
40
39
  ariaHasPopup?: boolean | 'dialog';
@@ -33,6 +33,10 @@ export type MenuItemCommonProps = {
33
33
  * to display the full menu content and description of a menu item close by (eg with another popup)
34
34
  */
35
35
  isContentTooltipDisabled?: boolean;
36
+ /**
37
+ * Indicates that the menu item is selected.
38
+ */
39
+ isSelected?: boolean;
36
40
  /**
37
41
  * Exposes the visually complete menu item, including:
38
42
  *
@@ -44,13 +44,13 @@ type SideNavProps = CommonSlotProps & {
44
44
  /**
45
45
  * Called when the side nav is expanded.
46
46
  *
47
- * Note: The trigger parameter is only provided when the `navx-full-height-sidebar` feature flag is enabled.
47
+ * Note: The trigger parameter is only provided when the `platform_dst_nav4_fhs_instrumentation_1` feature flag is enabled.
48
48
  */
49
49
  onExpand?: VisibilityCallback;
50
50
  /**
51
51
  * Called when the side nav is collapsed.
52
52
  *
53
- * Note: The trigger parameter is only provided when the `navx-full-height-sidebar` feature flag is enabled.
53
+ * Note: The trigger parameter is only provided when the `platform_dst_nav4_fhs_instrumentation_1` feature flag is enabled.
54
54
  */
55
55
  onCollapse?: VisibilityCallback;
56
56
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/navigation-system",
3
- "version": "5.1.0",
3
+ "version": "5.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",
@@ -147,6 +147,9 @@
147
147
  }
148
148
  },
149
149
  "platform-feature-flags": {
150
+ "platform_dst_nav4_fhs_instrumentation_1": {
151
+ "type": "boolean"
152
+ },
150
153
  "platform_dst_nav4_side_nav_default_collapsed_api": {
151
154
  "type": "boolean"
152
155
  },
@@ -192,6 +195,9 @@
192
195
  },
193
196
  "platform_dst_button_chevron_sizing": {
194
197
  "type": "boolean"
198
+ },
199
+ "platform-dst-buttonmenuitem-selected-state-support": {
200
+ "type": "boolean"
195
201
  }
196
202
  },
197
203
  "homepage": "https://atlassian.design/components/navigation-system"