@atlaskit/navigation-system 5.24.0 → 5.26.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 (31) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-header.js +6 -7
  3. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item-content.js +43 -7
  4. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item-context.js +7 -10
  5. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.js +15 -1
  6. package/dist/cjs/ui/menu-item/flyout-menu-item/flyout-menu-item.js +20 -2
  7. package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.compiled.css +3 -0
  8. package/dist/cjs/ui/page-layout/panel-splitter/panel-splitter.js +7 -4
  9. package/dist/es2019/ui/menu-item/flyout-menu-item/close-button.js +2 -2
  10. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-header.js +7 -8
  11. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item-content.js +45 -7
  12. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item-context.js +6 -10
  13. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.js +45 -29
  14. package/dist/es2019/ui/menu-item/flyout-menu-item/flyout-menu-item.js +23 -4
  15. package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.compiled.css +3 -0
  16. package/dist/es2019/ui/page-layout/panel-splitter/panel-splitter.js +7 -4
  17. package/dist/esm/ui/menu-item/flyout-menu-item/close-button.js +2 -2
  18. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-header.js +7 -8
  19. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item-content.js +44 -9
  20. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item-context.js +6 -10
  21. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.js +16 -2
  22. package/dist/esm/ui/menu-item/flyout-menu-item/flyout-menu-item.js +22 -4
  23. package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.compiled.css +3 -0
  24. package/dist/esm/ui/page-layout/panel-splitter/panel-splitter.js +7 -4
  25. package/dist/types/ui/menu-item/flyout-menu-item/close-button.d.ts +1 -1
  26. package/dist/types/ui/menu-item/flyout-menu-item/flyout-menu-item-content.d.ts +1 -0
  27. package/dist/types/ui/menu-item/flyout-menu-item/flyout-menu-item-context.d.ts +5 -8
  28. package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/close-button.d.ts +1 -1
  29. package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/flyout-menu-item-content.d.ts +1 -0
  30. package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/flyout-menu-item-context.d.ts +5 -8
  31. package/package.json +4 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlassian/navigation-system
2
2
 
3
+ ## 5.26.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`05a04a1bfd2f9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/05a04a1bfd2f9) -
8
+ Panel splitter tooltips will now always fade in when the
9
+ `platform_dst_nav4_side_nav_resize_tooltip_feedback` gate is enabled.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 5.25.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [`e7b6c5d52b32e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e7b6c5d52b32e) -
20
+ Adds analytics tracking for flyout menu opening and closing, including the close source (close
21
+ button, escape key, outside click, other). These additional analytics are behind the
22
+ `platform_dst_nav4_flyout_menu_slots_close_button` feature gate.
23
+
3
24
  ## 5.24.0
4
25
 
5
26
  ### Minor Changes
@@ -32,12 +32,11 @@ var FlyoutHeader = exports.FlyoutHeader = function FlyoutHeader(props) {
32
32
  title = props.title,
33
33
  closeButtonLabel = props.closeButtonLabel;
34
34
  var id = (0, _flyoutMenuItemContext.useTitleId)();
35
- var setIsOpen = (0, _react.useContext)(_flyoutMenuItemContext.SetIsOpenContext);
36
- var onClose = (0, _react.useContext)(_flyoutMenuItemContext.OnCloseContext);
37
- var handleClose = (0, _react.useCallback)(function () {
38
- onClose === null || onClose === void 0 || onClose();
39
- setIsOpen(false);
40
- }, [setIsOpen, onClose]);
35
+ var onCloseRef = (0, _react.useContext)(_flyoutMenuItemContext.OnCloseContext);
36
+ var handleClose = (0, _react.useCallback)(function (event) {
37
+ var _onCloseRef$current;
38
+ (_onCloseRef$current = onCloseRef.current) === null || _onCloseRef$current === void 0 || _onCloseRef$current.call(onCloseRef, event, 'close-button');
39
+ }, [onCloseRef]);
41
40
  return /*#__PURE__*/_react.default.createElement("div", {
42
41
  "data-testid": testId,
43
42
  className: (0, _runtime.ax)([headerStyles.root])
@@ -49,7 +48,7 @@ var FlyoutHeader = exports.FlyoutHeader = function FlyoutHeader(props) {
49
48
  testId: testId && "".concat(testId, "--close-button")
50
49
  }), /*#__PURE__*/_react.default.createElement(_heading.default, {
51
50
  size: "xsmall",
52
- as: "span",
51
+ as: "h2",
53
52
  id: id
54
53
  }, title)), children);
55
54
  };
@@ -11,6 +11,7 @@ require("./flyout-menu-item-content.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 _analyticsNext = require("@atlaskit/analytics-next");
14
15
  var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
15
16
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
17
  var _experimental = require("@atlaskit/popup/experimental");
@@ -46,10 +47,49 @@ var FlyoutMenuItemContent = exports.FlyoutMenuItemContent = /*#__PURE__*/(0, _re
46
47
  onClose = _ref.onClose,
47
48
  autoFocus = _ref.autoFocus;
48
49
  var setIsOpen = (0, _react.useContext)(_flyoutMenuItemContext.SetIsOpenContext);
49
- var handleClose = (0, _react.useCallback)(function () {
50
+ var onCloseRef = (0, _react.useContext)(_flyoutMenuItemContext.OnCloseContext);
51
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
52
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
53
+
54
+ // The source of the close is not accessible to the consumer, it is determined within the
55
+ // handleClose function, or passed in as a parameter in FlyoutMenuItemTrigger (outside-click),
56
+ // or FlyoutHeader (close-button).
57
+ var handleClose = (0, _react.useCallback)(function (event, source) {
58
+ if ((0, _platformFeatureFlags.fg)("platform_dst_nav4_flyout_menu_slots_close_button")) {
59
+ // Use the passed source if provided, otherwise determine from event
60
+ var determinedSource = source || 'other';
61
+ if (!source) {
62
+ if (event instanceof KeyboardEvent) {
63
+ var keyboardEvent = event;
64
+ if (keyboardEvent.key === 'Escape' || keyboardEvent.key === 'Esc') {
65
+ determinedSource = 'escape-key';
66
+ }
67
+ } else if (event instanceof MouseEvent) {
68
+ if (event && 'type' in event && event.type === 'click') {
69
+ determinedSource = 'outside-click';
70
+ }
71
+ }
72
+ }
73
+
74
+ // When flyout menu is closed, fire analytics event
75
+ var navigationAnalyticsEvent = createAnalyticsEvent({
76
+ source: 'sideNav',
77
+ actionSubject: 'flyoutMenu',
78
+ action: 'closed',
79
+ attributes: {
80
+ closeSource: determinedSource
81
+ }
82
+ });
83
+ navigationAnalyticsEvent.fire('navigation');
84
+ }
50
85
  onClose === null || onClose === void 0 || onClose();
51
86
  setIsOpen(false);
52
- }, [setIsOpen, onClose]);
87
+ }, [setIsOpen, onClose, createAnalyticsEvent]);
88
+
89
+ // Register handleClose in the ref to allow the FlyoutMenuItemTrigger to access it
90
+ (0, _react.useEffect)(function () {
91
+ onCloseRef.current = handleClose;
92
+ }, [handleClose, onCloseRef]);
53
93
  var titleId = (0, _react.useId)();
54
94
  return /*#__PURE__*/_react.default.createElement(_experimental.PopupContent, {
55
95
  appearance: "UNSAFE_modal-below-sm",
@@ -88,13 +128,9 @@ var FlyoutMenuItemContent = exports.FlyoutMenuItemContent = /*#__PURE__*/(0, _re
88
128
  update: update
89
129
  }, (0, _platformFeatureFlags.fg)("platform_dst_nav4_flyout_menu_slots_close_button") ? /*#__PURE__*/_react.default.createElement(_flyoutMenuItemContext.TitleIdContextProvider, {
90
130
  value: titleId
91
- }, /*#__PURE__*/_react.default.createElement(_flyoutMenuItemContext.OnCloseProvider, {
92
- value: function value() {
93
- return onClose;
94
- }
95
131
  }, /*#__PURE__*/_react.default.createElement("div", {
96
132
  className: (0, _runtime.ax)([flyoutMenuItemContentContainerStyles.container])
97
- }, children))) : children);
133
+ }, children)) : children);
98
134
  });
99
135
  });
100
136
  function createResizeObserver(update) {
@@ -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.useTitleId = exports.useSetFlyoutMenuOpen = exports.useFlyoutMenuOpen = exports.TitleIdContextProvider = exports.TitleIdContext = exports.SetIsOpenContext = exports.OnCloseProvider = exports.OnCloseContext = exports.IsOpenContext = void 0;
7
+ exports.useTitleId = exports.useSetFlyoutMenuOpen = exports.useFlyoutMenuOpen = exports.TitleIdContextProvider = exports.TitleIdContext = exports.SetIsOpenContext = exports.OnCloseContext = exports.IsOpenContext = void 0;
8
8
  var _react = require("react");
9
9
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
10
10
  /**
@@ -30,16 +30,13 @@ var useSetFlyoutMenuOpen = exports.useSetFlyoutMenuOpen = function useSetFlyoutM
30
30
  /**
31
31
  * __On close context__
32
32
  *
33
- * A context for storing the onClose value of the FlyoutMenuItem.
33
+ * A context for storing a ref to the onClose handler with source information.This
34
+ * is used by FlyoutMenuItemContent, FlyoutMenuItemTrigger and FlyoutHeader to store
35
+ * the on close function and source information for closing the flyout menu.
34
36
  */
35
- var OnCloseContext = exports.OnCloseContext = /*#__PURE__*/(0, _react.createContext)(null);
36
-
37
- /**
38
- * __On close provider__
39
- *
40
- * A context provider for supplying the onClose function to the FlyoutHeader.
41
- */
42
- var OnCloseProvider = exports.OnCloseProvider = OnCloseContext.Provider;
37
+ var OnCloseContext = exports.OnCloseContext = /*#__PURE__*/(0, _react.createContext)({
38
+ current: null
39
+ });
43
40
 
44
41
  /**
45
42
  * __Title id context__
@@ -13,8 +13,10 @@ var React = _react;
13
13
  var _runtime = require("@compiled/react/runtime");
14
14
  var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
15
15
  var _chevronRight = _interopRequireDefault(require("@atlaskit/icon/core/chevron-right"));
16
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
17
  var _experimental = require("@atlaskit/popup/experimental");
17
18
  var _menuItem = require("../menu-item");
19
+ var _flyoutMenuItemContext = require("./flyout-menu-item-context");
18
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); }
19
21
  var elemAfterStyles = {
20
22
  root: "_18zr12x7 _1tz3r0mg"
@@ -36,6 +38,18 @@ var FlyoutMenuItemTrigger = exports.FlyoutMenuItemTrigger = /*#__PURE__*/(0, _re
36
38
  isDragging = _ref.isDragging,
37
39
  hasDragIndicator = _ref.hasDragIndicator,
38
40
  dropIndicator = _ref.dropIndicator;
41
+ var isOpen = (0, _react.useContext)(_flyoutMenuItemContext.IsOpenContext);
42
+ var onCloseRef = (0, _react.useContext)(_flyoutMenuItemContext.OnCloseContext);
43
+ var handleClick = (0, _react.useCallback)(function (event, analyticsEvent) {
44
+ // If the flyout is open and the trigger is clicked, close the flyout and call the onClick
45
+ // handler with the source information set to 'outside-click'.
46
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_flyout_menu_slots_close_button')) {
47
+ if (isOpen && onCloseRef.current) {
48
+ onCloseRef.current(event, 'outside-click');
49
+ }
50
+ }
51
+ onClick === null || onClick === void 0 || onClick(event, analyticsEvent);
52
+ }, [isOpen, onCloseRef, onClick]);
39
53
  return /*#__PURE__*/React.createElement(_experimental.PopupTrigger, null, function (_ref2) {
40
54
  var ref = _ref2.ref,
41
55
  ariaControls = _ref2['aria-controls'],
@@ -53,7 +67,7 @@ var FlyoutMenuItemTrigger = exports.FlyoutMenuItemTrigger = /*#__PURE__*/(0, _re
53
67
  color: "currentColor",
54
68
  size: "small"
55
69
  })),
56
- onClick: onClick,
70
+ onClick: handleClick,
57
71
  ariaControls: ariaControls,
58
72
  ariaExpanded: ariaExpanded,
59
73
  ariaHasPopup: ariaHasPopup,
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.FlyoutMenuItem = void 0;
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
10
  var _react = _interopRequireWildcard(require("react"));
11
+ var _analyticsNext = require("@atlaskit/analytics-next");
11
12
  var _useControlled3 = _interopRequireDefault(require("@atlaskit/ds-lib/use-controlled"));
12
13
  var _usePreviousValue = _interopRequireDefault(require("@atlaskit/ds-lib/use-previous-value"));
13
14
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
@@ -49,6 +50,9 @@ var FlyoutMenuItem = exports.FlyoutMenuItem = /*#__PURE__*/(0, _react.forwardRef
49
50
  isOpen = _useControlled2[0],
50
51
  setIsOpen = _useControlled2[1];
51
52
  var previousIsOpen = (0, _usePreviousValue.default)(isOpen);
53
+ var onCloseRef = (0, _react.useRef)(null);
54
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
55
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
52
56
  (0, _react.useEffect)(function () {
53
57
  if (previousIsOpen === undefined || previousIsOpen === isOpen) {
54
58
  /**
@@ -60,17 +64,31 @@ var FlyoutMenuItem = exports.FlyoutMenuItem = /*#__PURE__*/(0, _react.forwardRef
60
64
  */
61
65
  return;
62
66
  }
67
+
68
+ // When flyout menu is opened, fire analytics event
69
+ if (isOpen && previousIsOpen === false) {
70
+ if ((0, _platformFeatureFlags.fg)('platform_dst_nav4_flyout_menu_slots_close_button')) {
71
+ var navigationAnalyticsEvent = createAnalyticsEvent({
72
+ source: 'sideNav',
73
+ actionSubject: 'flyoutMenu',
74
+ action: 'opened'
75
+ });
76
+ navigationAnalyticsEvent.fire('navigation');
77
+ }
78
+ }
63
79
  onOpenChange === null || onOpenChange === void 0 || onOpenChange(isOpen);
64
- }, [isOpen, onOpenChange, previousIsOpen]);
80
+ }, [isOpen, onOpenChange, previousIsOpen, createAnalyticsEvent]);
65
81
  return /*#__PURE__*/_react.default.createElement(_flyoutMenuItemContext.IsOpenContext.Provider, {
66
82
  value: isOpen
67
83
  }, /*#__PURE__*/_react.default.createElement(_flyoutMenuItemContext.SetIsOpenContext.Provider, {
68
84
  value: setIsOpen
85
+ }, /*#__PURE__*/_react.default.createElement(_flyoutMenuItemContext.OnCloseContext.Provider, {
86
+ value: onCloseRef
69
87
  }, /*#__PURE__*/_react.default.createElement(_menuListItem.MenuListItem, {
70
88
  ref: forwardedRef
71
89
  }, /*#__PURE__*/_react.default.createElement(_experimental.Popup, {
72
90
  id: id,
73
91
  isOpen: isOpen,
74
92
  role: (0, _platformFeatureFlags.fg)('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : undefined
75
- }, children))));
93
+ }, children)))));
76
94
  });
@@ -7,12 +7,15 @@
7
7
  ._1e02zeo2{inset-inline-start:-9px}
8
8
  ._1e0c1ule{display:block}
9
9
  ._1e0cglyw{display:none}
10
+ ._1lww188d{transition-delay:.3s}
10
11
  ._1lww5cps{transition-delay:0ms}
11
12
  ._1oec1yx9{transition-duration:.1s}
13
+ ._1oec6ebc{transition-duration:.15s}
12
14
  ._1pbykb7n{z-index:1}
13
15
  ._1q51ze3t{padding-block-start:var(--ds-space-0,0)}
14
16
  ._1qu2glyw{outline-style:none}
15
17
  ._4t3i1osq{height:100%}
18
+ ._6fl41ytf{transition-timing-function:ease-in-out}
16
19
  ._85i5ze3t{padding-block-end:var(--ds-space-0,0)}
17
20
  ._ahbq196n{margin-inline-start:var(--ds-space-negative-075,-6px)}
18
21
  ._bfhk1j28{background-color:transparent}
@@ -48,8 +48,10 @@ var containerStyles = {
48
48
  positionStart: "_1e02zeo2"
49
49
  };
50
50
  var grabAreaStyles = {
51
- root: "_1bsbl52n _4t3i1osq _kqswstnw _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _syaz1j28 _bfhk1j28 _k8m01ylx _1oec1yx9 _1lww5cps _d0aluf7j _1gavfnf5 _vp7g6x5g _30l36x5g _1dr21ylx _1s5z1ylx _1cg4fnf5 _le1bfnf5 _1gglglyw _9h8h12zz",
52
- fullHeightSidebar: "_d0al11mm"
51
+ root: "_1bsbl52n _4t3i1osq _kqswstnw _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _syaz1j28 _bfhk1j28 _k8m01ylx _d0aluf7j _vp7g6x5g _30l36x5g _1gglglyw _9h8h12zz",
52
+ fullHeightSidebar: "_d0al11mm",
53
+ oldTransition: "_1oec1yx9 _1lww5cps _1gavfnf5 _1dr21ylx _1s5z1ylx _1cg4fnf5 _le1bfnf5",
54
+ newTransition: "_1oec6ebc _1lww188d _6fl41ytf"
53
55
  };
54
56
  var lineStyles = {
55
57
  root: "_kqswstnw _1e0c1ule _1bsb1l7b _4t3i1osq _syaz1kw7 _bfhk1r31 _1e021v6z"
@@ -90,7 +92,8 @@ var MaybeTooltip = function MaybeTooltip(_ref2) {
90
92
  position: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? 'mouse-y' : 'mouse',
91
93
  mousePosition: "right",
92
94
  isScreenReaderAnnouncementDisabled: true,
93
- component: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? PanelSplitterTooltip : undefined
95
+ component: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? PanelSplitterTooltip : undefined,
96
+ UNSAFE_shouldAlwaysFadeIn: (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback')
94
97
  }, children);
95
98
  }
96
99
  return children;
@@ -372,7 +375,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
372
375
  ref: splitterRef,
373
376
  "data-testid": testId,
374
377
  onDoubleClick: onDoubleClick,
375
- className: (0, _runtime.ax)([grabAreaStyles.root, isFhsEnabled && grabAreaStyles.fullHeightSidebar])
378
+ className: (0, _runtime.ax)([grabAreaStyles.root, isFhsEnabled && grabAreaStyles.fullHeightSidebar, (0, _platformFeatureFlags.fg)('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? grabAreaStyles.newTransition : grabAreaStyles.oldTransition])
376
379
  }, /*#__PURE__*/React.createElement(_visuallyHidden.default, null, /*#__PURE__*/React.createElement("input", {
377
380
  type: "range",
378
381
  value: rangeInputValue,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { IconButton } from "@atlaskit/button/new";
3
- import CrossIcon from "@atlaskit/icon/core/cross";
2
+ import { IconButton } from '@atlaskit/button/new';
3
+ import CrossIcon from '@atlaskit/icon/core/cross';
4
4
  /**
5
5
  * __Close button__
6
6
  *
@@ -5,7 +5,7 @@ import React, { useCallback, useContext } from 'react';
5
5
  import Heading from '@atlaskit/heading';
6
6
  import { Flex } from '@atlaskit/primitives/compiled';
7
7
  import { CloseButton } from './close-button';
8
- import { OnCloseContext, SetIsOpenContext, useTitleId } from './flyout-menu-item-context';
8
+ import { OnCloseContext, useTitleId } from './flyout-menu-item-context';
9
9
  const headerStyles = {
10
10
  root: "_zulp12x7 _bozg1b66 _85i512x7 _1e0c1txw _2lx21bp4",
11
11
  flex: "_zulppxbi _1bah1yb4 _2lx21sbv _4cvr1h6o _1bsb1osq _bozgv77o"
@@ -25,12 +25,11 @@ export const FlyoutHeader = props => {
25
25
  closeButtonLabel
26
26
  } = props;
27
27
  const id = useTitleId();
28
- const setIsOpen = useContext(SetIsOpenContext);
29
- const onClose = useContext(OnCloseContext);
30
- const handleClose = useCallback(() => {
31
- onClose === null || onClose === void 0 ? void 0 : onClose();
32
- setIsOpen(false);
33
- }, [setIsOpen, onClose]);
28
+ const onCloseRef = useContext(OnCloseContext);
29
+ const handleClose = useCallback(event => {
30
+ var _onCloseRef$current;
31
+ (_onCloseRef$current = onCloseRef.current) === null || _onCloseRef$current === void 0 ? void 0 : _onCloseRef$current.call(onCloseRef, event, 'close-button');
32
+ }, [onCloseRef]);
34
33
  return /*#__PURE__*/React.createElement("div", {
35
34
  "data-testid": testId,
36
35
  className: ax([headerStyles.root])
@@ -42,7 +41,7 @@ export const FlyoutHeader = props => {
42
41
  testId: testId && `${testId}--close-button`
43
42
  }), /*#__PURE__*/React.createElement(Heading, {
44
43
  size: "xsmall",
45
- as: "span",
44
+ as: "h2",
46
45
  id: id
47
46
  }, title)), children);
48
47
  };
@@ -2,11 +2,11 @@
2
2
  import "./flyout-menu-item-content.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { forwardRef, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';
5
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
5
6
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
6
7
  import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { PopupContent } from '@atlaskit/popup/experimental';
8
- import { OnCloseProvider, SetIsOpenContext, TitleIdContextProvider } from './flyout-menu-item-context';
9
-
9
+ import { OnCloseContext, SetIsOpenContext, TitleIdContextProvider } from './flyout-menu-item-context';
10
10
  /**
11
11
  * The vertical offset in px to ensure the flyout container does not exceed the bounds of
12
12
  * the window. This matches the padding of the content container, and it's position within
@@ -38,10 +38,50 @@ export const FlyoutMenuItemContent = /*#__PURE__*/forwardRef(({
38
38
  autoFocus
39
39
  }, forwardedRef) => {
40
40
  const setIsOpen = useContext(SetIsOpenContext);
41
- const handleClose = useCallback(() => {
41
+ const onCloseRef = useContext(OnCloseContext);
42
+ const {
43
+ createAnalyticsEvent
44
+ } = useAnalyticsEvents();
45
+
46
+ // The source of the close is not accessible to the consumer, it is determined within the
47
+ // handleClose function, or passed in as a parameter in FlyoutMenuItemTrigger (outside-click),
48
+ // or FlyoutHeader (close-button).
49
+ const handleClose = useCallback((event, source) => {
50
+ if (fg("platform_dst_nav4_flyout_menu_slots_close_button")) {
51
+ // Use the passed source if provided, otherwise determine from event
52
+ let determinedSource = source || 'other';
53
+ if (!source) {
54
+ if (event instanceof KeyboardEvent) {
55
+ const keyboardEvent = event;
56
+ if (keyboardEvent.key === 'Escape' || keyboardEvent.key === 'Esc') {
57
+ determinedSource = 'escape-key';
58
+ }
59
+ } else if (event instanceof MouseEvent) {
60
+ if (event && 'type' in event && event.type === 'click') {
61
+ determinedSource = 'outside-click';
62
+ }
63
+ }
64
+ }
65
+
66
+ // When flyout menu is closed, fire analytics event
67
+ const navigationAnalyticsEvent = createAnalyticsEvent({
68
+ source: 'sideNav',
69
+ actionSubject: 'flyoutMenu',
70
+ action: 'closed',
71
+ attributes: {
72
+ closeSource: determinedSource
73
+ }
74
+ });
75
+ navigationAnalyticsEvent.fire('navigation');
76
+ }
42
77
  onClose === null || onClose === void 0 ? void 0 : onClose();
43
78
  setIsOpen(false);
44
- }, [setIsOpen, onClose]);
79
+ }, [setIsOpen, onClose, createAnalyticsEvent]);
80
+
81
+ // Register handleClose in the ref to allow the FlyoutMenuItemTrigger to access it
82
+ useEffect(() => {
83
+ onCloseRef.current = handleClose;
84
+ }, [handleClose, onCloseRef]);
45
85
  const titleId = useId();
46
86
  return /*#__PURE__*/React.createElement(PopupContent, {
47
87
  appearance: "UNSAFE_modal-below-sm",
@@ -80,11 +120,9 @@ export const FlyoutMenuItemContent = /*#__PURE__*/forwardRef(({
80
120
  update: update
81
121
  }, fg("platform_dst_nav4_flyout_menu_slots_close_button") ? /*#__PURE__*/React.createElement(TitleIdContextProvider, {
82
122
  value: titleId
83
- }, /*#__PURE__*/React.createElement(OnCloseProvider, {
84
- value: () => onClose
85
123
  }, /*#__PURE__*/React.createElement("div", {
86
124
  className: ax([flyoutMenuItemContentContainerStyles.container])
87
- }, children))) : children));
125
+ }, children)) : children));
88
126
  });
89
127
  function createResizeObserver(update) {
90
128
  return new ResizeObserver(update);
@@ -1,6 +1,5 @@
1
1
  import { createContext, useContext } from 'react';
2
2
  import noop from '@atlaskit/ds-lib/noop';
3
-
4
3
  /**
5
4
  * __Is open context__
6
5
  *
@@ -20,16 +19,13 @@ export const useSetFlyoutMenuOpen = () => useContext(SetIsOpenContext);
20
19
  /**
21
20
  * __On close context__
22
21
  *
23
- * A context for storing the onClose value of the FlyoutMenuItem.
24
- */
25
- export const OnCloseContext = /*#__PURE__*/createContext(null);
26
-
27
- /**
28
- * __On close provider__
29
- *
30
- * A context provider for supplying the onClose function to the FlyoutHeader.
22
+ * A context for storing a ref to the onClose handler with source information.This
23
+ * is used by FlyoutMenuItemContent, FlyoutMenuItemTrigger and FlyoutHeader to store
24
+ * the on close function and source information for closing the flyout menu.
31
25
  */
32
- export const OnCloseProvider = OnCloseContext.Provider;
26
+ export const OnCloseContext = /*#__PURE__*/createContext({
27
+ current: null
28
+ });
33
29
 
34
30
  /**
35
31
  * __Title id context__
@@ -2,11 +2,13 @@
2
2
  import "./flyout-menu-item-trigger.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
- import { forwardRef } from 'react';
5
+ import { forwardRef, useCallback, useContext } from 'react';
6
6
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
7
7
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { PopupTrigger } from '@atlaskit/popup/experimental';
9
10
  import { MenuItemBase } from '../menu-item';
11
+ import { IsOpenContext, OnCloseContext } from './flyout-menu-item-context';
10
12
  const elemAfterStyles = {
11
13
  root: "_18zr12x7 _1tz3r0mg"
12
14
  };
@@ -27,31 +29,45 @@ export const FlyoutMenuItemTrigger = /*#__PURE__*/forwardRef(({
27
29
  isDragging,
28
30
  hasDragIndicator,
29
31
  dropIndicator
30
- }, forwardedRef) => /*#__PURE__*/React.createElement(PopupTrigger, null, ({
31
- ref,
32
- 'aria-controls': ariaControls,
33
- 'aria-expanded': ariaExpanded,
34
- 'aria-haspopup': ariaHasPopup
35
- }) => /*#__PURE__*/React.createElement(MenuItemBase, {
36
- testId: testId,
37
- ref: mergeRefs([ref, forwardedRef]),
38
- visualContentRef: visualContentRef,
39
- elemBefore: elemBefore,
40
- elemAfter: /*#__PURE__*/React.createElement("div", {
41
- className: ax([elemAfterStyles.root])
42
- }, /*#__PURE__*/React.createElement(ChevronRightIcon, {
43
- label: "",
44
- color: "currentColor",
45
- size: "small"
46
- })),
47
- onClick: onClick,
48
- ariaControls: ariaControls,
49
- ariaExpanded: ariaExpanded,
50
- ariaHasPopup: ariaHasPopup,
51
- interactionName: interactionName,
52
- isContentTooltipDisabled: isContentTooltipDisabled,
53
- isSelected: isSelected,
54
- isDragging: isDragging,
55
- hasDragIndicator: hasDragIndicator,
56
- dropIndicator: dropIndicator
57
- }, children)));
32
+ }, forwardedRef) => {
33
+ const isOpen = useContext(IsOpenContext);
34
+ const onCloseRef = useContext(OnCloseContext);
35
+ const handleClick = useCallback((event, analyticsEvent) => {
36
+ // If the flyout is open and the trigger is clicked, close the flyout and call the onClick
37
+ // handler with the source information set to 'outside-click'.
38
+ if (fg('platform_dst_nav4_flyout_menu_slots_close_button')) {
39
+ if (isOpen && onCloseRef.current) {
40
+ onCloseRef.current(event, 'outside-click');
41
+ }
42
+ }
43
+ onClick === null || onClick === void 0 ? void 0 : onClick(event, analyticsEvent);
44
+ }, [isOpen, onCloseRef, onClick]);
45
+ return /*#__PURE__*/React.createElement(PopupTrigger, null, ({
46
+ ref,
47
+ 'aria-controls': ariaControls,
48
+ 'aria-expanded': ariaExpanded,
49
+ 'aria-haspopup': ariaHasPopup
50
+ }) => /*#__PURE__*/React.createElement(MenuItemBase, {
51
+ testId: testId,
52
+ ref: mergeRefs([ref, forwardedRef]),
53
+ visualContentRef: visualContentRef,
54
+ elemBefore: elemBefore,
55
+ elemAfter: /*#__PURE__*/React.createElement("div", {
56
+ className: ax([elemAfterStyles.root])
57
+ }, /*#__PURE__*/React.createElement(ChevronRightIcon, {
58
+ label: "",
59
+ color: "currentColor",
60
+ size: "small"
61
+ })),
62
+ onClick: handleClick,
63
+ ariaControls: ariaControls,
64
+ ariaExpanded: ariaExpanded,
65
+ ariaHasPopup: ariaHasPopup,
66
+ interactionName: interactionName,
67
+ isContentTooltipDisabled: isContentTooltipDisabled,
68
+ isSelected: isSelected,
69
+ isDragging: isDragging,
70
+ hasDragIndicator: hasDragIndicator,
71
+ dropIndicator: dropIndicator
72
+ }, children));
73
+ });
@@ -1,10 +1,11 @@
1
- import React, { forwardRef, useEffect } from 'react';
1
+ import React, { forwardRef, useEffect, useRef } from 'react';
2
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
2
3
  import useControlled from '@atlaskit/ds-lib/use-controlled';
3
4
  import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
4
5
  import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import { Popup } from '@atlaskit/popup/experimental';
6
7
  import { MenuListItem } from '../menu-list-item';
7
- import { IsOpenContext, SetIsOpenContext } from './flyout-menu-item-context';
8
+ import { IsOpenContext, OnCloseContext, SetIsOpenContext } from './flyout-menu-item-context';
8
9
  /**
9
10
  * __FlyoutMenuItem__
10
11
  *
@@ -34,6 +35,10 @@ export const FlyoutMenuItem = /*#__PURE__*/forwardRef(({
34
35
  }, forwardedRef) => {
35
36
  const [isOpen, setIsOpen] = useControlled(isOpenControlled, () => isDefaultOpen);
36
37
  const previousIsOpen = usePreviousValue(isOpen);
38
+ const onCloseRef = useRef(null);
39
+ const {
40
+ createAnalyticsEvent
41
+ } = useAnalyticsEvents();
37
42
  useEffect(() => {
38
43
  if (previousIsOpen === undefined || previousIsOpen === isOpen) {
39
44
  /**
@@ -45,17 +50,31 @@ export const FlyoutMenuItem = /*#__PURE__*/forwardRef(({
45
50
  */
46
51
  return;
47
52
  }
53
+
54
+ // When flyout menu is opened, fire analytics event
55
+ if (isOpen && previousIsOpen === false) {
56
+ if (fg('platform_dst_nav4_flyout_menu_slots_close_button')) {
57
+ const navigationAnalyticsEvent = createAnalyticsEvent({
58
+ source: 'sideNav',
59
+ actionSubject: 'flyoutMenu',
60
+ action: 'opened'
61
+ });
62
+ navigationAnalyticsEvent.fire('navigation');
63
+ }
64
+ }
48
65
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(isOpen);
49
- }, [isOpen, onOpenChange, previousIsOpen]);
66
+ }, [isOpen, onOpenChange, previousIsOpen, createAnalyticsEvent]);
50
67
  return /*#__PURE__*/React.createElement(IsOpenContext.Provider, {
51
68
  value: isOpen
52
69
  }, /*#__PURE__*/React.createElement(SetIsOpenContext.Provider, {
53
70
  value: setIsOpen
71
+ }, /*#__PURE__*/React.createElement(OnCloseContext.Provider, {
72
+ value: onCloseRef
54
73
  }, /*#__PURE__*/React.createElement(MenuListItem, {
55
74
  ref: forwardedRef
56
75
  }, /*#__PURE__*/React.createElement(Popup, {
57
76
  id: id,
58
77
  isOpen: isOpen,
59
78
  role: fg('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : undefined
60
- }, children))));
79
+ }, children)))));
61
80
  });
@@ -7,12 +7,15 @@
7
7
  ._1e02zeo2{inset-inline-start:-9px}
8
8
  ._1e0c1ule{display:block}
9
9
  ._1e0cglyw{display:none}
10
+ ._1lww188d{transition-delay:.3s}
10
11
  ._1lww5cps{transition-delay:0ms}
11
12
  ._1oec1yx9{transition-duration:.1s}
13
+ ._1oec6ebc{transition-duration:.15s}
12
14
  ._1pbykb7n{z-index:1}
13
15
  ._1q51ze3t{padding-block-start:var(--ds-space-0,0)}
14
16
  ._1qu2glyw{outline-style:none}
15
17
  ._4t3i1osq{height:100%}
18
+ ._6fl41ytf{transition-timing-function:ease-in-out}
16
19
  ._85i5ze3t{padding-block-end:var(--ds-space-0,0)}
17
20
  ._ahbq196n{margin-inline-start:var(--ds-space-negative-075,-6px)}
18
21
  ._bfhk1j28{background-color:transparent}
@@ -32,8 +32,10 @@ const containerStyles = {
32
32
  positionStart: "_1e02zeo2"
33
33
  };
34
34
  const grabAreaStyles = {
35
- root: "_1bsbl52n _4t3i1osq _kqswstnw _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _syaz1j28 _bfhk1j28 _k8m01ylx _1oec1yx9 _1lww5cps _d0aluf7j _1gavfnf5 _vp7g6x5g _30l36x5g _1dr21ylx _1s5z1ylx _1cg4fnf5 _le1bfnf5 _1gglglyw _9h8h12zz",
36
- fullHeightSidebar: "_d0al11mm"
35
+ root: "_1bsbl52n _4t3i1osq _kqswstnw _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _syaz1j28 _bfhk1j28 _k8m01ylx _d0aluf7j _vp7g6x5g _30l36x5g _1gglglyw _9h8h12zz",
36
+ fullHeightSidebar: "_d0al11mm",
37
+ oldTransition: "_1oec1yx9 _1lww5cps _1gavfnf5 _1dr21ylx _1s5z1ylx _1cg4fnf5 _le1bfnf5",
38
+ newTransition: "_1oec6ebc _1lww188d _6fl41ytf"
37
39
  };
38
40
  const lineStyles = {
39
41
  root: "_kqswstnw _1e0c1ule _1bsb1l7b _4t3i1osq _syaz1kw7 _bfhk1r31 _1e021v6z"
@@ -79,7 +81,8 @@ const MaybeTooltip = ({
79
81
  position: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? 'mouse-y' : 'mouse',
80
82
  mousePosition: "right",
81
83
  isScreenReaderAnnouncementDisabled: true,
82
- component: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? PanelSplitterTooltip : undefined
84
+ component: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? PanelSplitterTooltip : undefined,
85
+ UNSAFE_shouldAlwaysFadeIn: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')
83
86
  }, children);
84
87
  }
85
88
  return children;
@@ -350,7 +353,7 @@ const PortaledPanelSplitter = ({
350
353
  ref: splitterRef,
351
354
  "data-testid": testId,
352
355
  onDoubleClick: onDoubleClick,
353
- className: ax([grabAreaStyles.root, isFhsEnabled && grabAreaStyles.fullHeightSidebar])
356
+ className: ax([grabAreaStyles.root, isFhsEnabled && grabAreaStyles.fullHeightSidebar, fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? grabAreaStyles.newTransition : grabAreaStyles.oldTransition])
354
357
  }, /*#__PURE__*/React.createElement(VisuallyHidden, null, /*#__PURE__*/React.createElement("input", {
355
358
  type: "range",
356
359
  value: rangeInputValue,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { IconButton } from "@atlaskit/button/new";
3
- import CrossIcon from "@atlaskit/icon/core/cross";
2
+ import { IconButton } from '@atlaskit/button/new';
3
+ import CrossIcon from '@atlaskit/icon/core/cross';
4
4
  /**
5
5
  * __Close button__
6
6
  *
@@ -5,7 +5,7 @@ import React, { useCallback, useContext } from 'react';
5
5
  import Heading from '@atlaskit/heading';
6
6
  import { Flex } from '@atlaskit/primitives/compiled';
7
7
  import { CloseButton } from './close-button';
8
- import { OnCloseContext, SetIsOpenContext, useTitleId } from './flyout-menu-item-context';
8
+ import { OnCloseContext, useTitleId } from './flyout-menu-item-context';
9
9
  var headerStyles = {
10
10
  root: "_zulp12x7 _bozg1b66 _85i512x7 _1e0c1txw _2lx21bp4",
11
11
  flex: "_zulppxbi _1bah1yb4 _2lx21sbv _4cvr1h6o _1bsb1osq _bozgv77o"
@@ -23,12 +23,11 @@ export var FlyoutHeader = function FlyoutHeader(props) {
23
23
  title = props.title,
24
24
  closeButtonLabel = props.closeButtonLabel;
25
25
  var id = useTitleId();
26
- var setIsOpen = useContext(SetIsOpenContext);
27
- var onClose = useContext(OnCloseContext);
28
- var handleClose = useCallback(function () {
29
- onClose === null || onClose === void 0 || onClose();
30
- setIsOpen(false);
31
- }, [setIsOpen, onClose]);
26
+ var onCloseRef = useContext(OnCloseContext);
27
+ var handleClose = useCallback(function (event) {
28
+ var _onCloseRef$current;
29
+ (_onCloseRef$current = onCloseRef.current) === null || _onCloseRef$current === void 0 || _onCloseRef$current.call(onCloseRef, event, 'close-button');
30
+ }, [onCloseRef]);
32
31
  return /*#__PURE__*/React.createElement("div", {
33
32
  "data-testid": testId,
34
33
  className: ax([headerStyles.root])
@@ -40,7 +39,7 @@ export var FlyoutHeader = function FlyoutHeader(props) {
40
39
  testId: testId && "".concat(testId, "--close-button")
41
40
  }), /*#__PURE__*/React.createElement(Heading, {
42
41
  size: "xsmall",
43
- as: "span",
42
+ as: "h2",
44
43
  id: id
45
44
  }, title)), children);
46
45
  };
@@ -3,11 +3,11 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import "./flyout-menu-item-content.compiled.css";
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
5
  import React, { forwardRef, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';
6
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
6
7
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
7
8
  import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { PopupContent } from '@atlaskit/popup/experimental';
9
- import { OnCloseProvider, SetIsOpenContext, TitleIdContextProvider } from './flyout-menu-item-context';
10
-
10
+ import { OnCloseContext, SetIsOpenContext, TitleIdContextProvider } from './flyout-menu-item-context';
11
11
  /**
12
12
  * The vertical offset in px to ensure the flyout container does not exceed the bounds of
13
13
  * the window. This matches the padding of the content container, and it's position within
@@ -38,10 +38,49 @@ export var FlyoutMenuItemContent = /*#__PURE__*/forwardRef(function (_ref, forwa
38
38
  onClose = _ref.onClose,
39
39
  autoFocus = _ref.autoFocus;
40
40
  var setIsOpen = useContext(SetIsOpenContext);
41
- var handleClose = useCallback(function () {
41
+ var onCloseRef = useContext(OnCloseContext);
42
+ var _useAnalyticsEvents = useAnalyticsEvents(),
43
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
44
+
45
+ // The source of the close is not accessible to the consumer, it is determined within the
46
+ // handleClose function, or passed in as a parameter in FlyoutMenuItemTrigger (outside-click),
47
+ // or FlyoutHeader (close-button).
48
+ var handleClose = useCallback(function (event, source) {
49
+ if (fg("platform_dst_nav4_flyout_menu_slots_close_button")) {
50
+ // Use the passed source if provided, otherwise determine from event
51
+ var determinedSource = source || 'other';
52
+ if (!source) {
53
+ if (event instanceof KeyboardEvent) {
54
+ var keyboardEvent = event;
55
+ if (keyboardEvent.key === 'Escape' || keyboardEvent.key === 'Esc') {
56
+ determinedSource = 'escape-key';
57
+ }
58
+ } else if (event instanceof MouseEvent) {
59
+ if (event && 'type' in event && event.type === 'click') {
60
+ determinedSource = 'outside-click';
61
+ }
62
+ }
63
+ }
64
+
65
+ // When flyout menu is closed, fire analytics event
66
+ var navigationAnalyticsEvent = createAnalyticsEvent({
67
+ source: 'sideNav',
68
+ actionSubject: 'flyoutMenu',
69
+ action: 'closed',
70
+ attributes: {
71
+ closeSource: determinedSource
72
+ }
73
+ });
74
+ navigationAnalyticsEvent.fire('navigation');
75
+ }
42
76
  onClose === null || onClose === void 0 || onClose();
43
77
  setIsOpen(false);
44
- }, [setIsOpen, onClose]);
78
+ }, [setIsOpen, onClose, createAnalyticsEvent]);
79
+
80
+ // Register handleClose in the ref to allow the FlyoutMenuItemTrigger to access it
81
+ useEffect(function () {
82
+ onCloseRef.current = handleClose;
83
+ }, [handleClose, onCloseRef]);
45
84
  var titleId = useId();
46
85
  return /*#__PURE__*/React.createElement(PopupContent, {
47
86
  appearance: "UNSAFE_modal-below-sm",
@@ -80,13 +119,9 @@ export var FlyoutMenuItemContent = /*#__PURE__*/forwardRef(function (_ref, forwa
80
119
  update: update
81
120
  }, fg("platform_dst_nav4_flyout_menu_slots_close_button") ? /*#__PURE__*/React.createElement(TitleIdContextProvider, {
82
121
  value: titleId
83
- }, /*#__PURE__*/React.createElement(OnCloseProvider, {
84
- value: function value() {
85
- return onClose;
86
- }
87
122
  }, /*#__PURE__*/React.createElement("div", {
88
123
  className: ax([flyoutMenuItemContentContainerStyles.container])
89
- }, children))) : children);
124
+ }, children)) : children);
90
125
  });
91
126
  });
92
127
  function createResizeObserver(update) {
@@ -1,6 +1,5 @@
1
1
  import { createContext, useContext } from 'react';
2
2
  import noop from '@atlaskit/ds-lib/noop';
3
-
4
3
  /**
5
4
  * __Is open context__
6
5
  *
@@ -24,16 +23,13 @@ export var useSetFlyoutMenuOpen = function useSetFlyoutMenuOpen() {
24
23
  /**
25
24
  * __On close context__
26
25
  *
27
- * A context for storing the onClose value of the FlyoutMenuItem.
28
- */
29
- export var OnCloseContext = /*#__PURE__*/createContext(null);
30
-
31
- /**
32
- * __On close provider__
33
- *
34
- * A context provider for supplying the onClose function to the FlyoutHeader.
26
+ * A context for storing a ref to the onClose handler with source information.This
27
+ * is used by FlyoutMenuItemContent, FlyoutMenuItemTrigger and FlyoutHeader to store
28
+ * the on close function and source information for closing the flyout menu.
35
29
  */
36
- export var OnCloseProvider = OnCloseContext.Provider;
30
+ export var OnCloseContext = /*#__PURE__*/createContext({
31
+ current: null
32
+ });
37
33
 
38
34
  /**
39
35
  * __Title id context__
@@ -2,11 +2,13 @@
2
2
  import "./flyout-menu-item-trigger.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
- import { forwardRef } from 'react';
5
+ import { forwardRef, useCallback, useContext } from 'react';
6
6
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
7
7
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { PopupTrigger } from '@atlaskit/popup/experimental';
9
10
  import { MenuItemBase } from '../menu-item';
11
+ import { IsOpenContext, OnCloseContext } from './flyout-menu-item-context';
10
12
  var elemAfterStyles = {
11
13
  root: "_18zr12x7 _1tz3r0mg"
12
14
  };
@@ -27,6 +29,18 @@ export var FlyoutMenuItemTrigger = /*#__PURE__*/forwardRef(function (_ref, forwa
27
29
  isDragging = _ref.isDragging,
28
30
  hasDragIndicator = _ref.hasDragIndicator,
29
31
  dropIndicator = _ref.dropIndicator;
32
+ var isOpen = useContext(IsOpenContext);
33
+ var onCloseRef = useContext(OnCloseContext);
34
+ var handleClick = useCallback(function (event, analyticsEvent) {
35
+ // If the flyout is open and the trigger is clicked, close the flyout and call the onClick
36
+ // handler with the source information set to 'outside-click'.
37
+ if (fg('platform_dst_nav4_flyout_menu_slots_close_button')) {
38
+ if (isOpen && onCloseRef.current) {
39
+ onCloseRef.current(event, 'outside-click');
40
+ }
41
+ }
42
+ onClick === null || onClick === void 0 || onClick(event, analyticsEvent);
43
+ }, [isOpen, onCloseRef, onClick]);
30
44
  return /*#__PURE__*/React.createElement(PopupTrigger, null, function (_ref2) {
31
45
  var ref = _ref2.ref,
32
46
  ariaControls = _ref2['aria-controls'],
@@ -44,7 +58,7 @@ export var FlyoutMenuItemTrigger = /*#__PURE__*/forwardRef(function (_ref, forwa
44
58
  color: "currentColor",
45
59
  size: "small"
46
60
  })),
47
- onClick: onClick,
61
+ onClick: handleClick,
48
62
  ariaControls: ariaControls,
49
63
  ariaExpanded: ariaExpanded,
50
64
  ariaHasPopup: ariaHasPopup,
@@ -1,11 +1,12 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { forwardRef, useEffect } from 'react';
2
+ import React, { forwardRef, useEffect, useRef } from 'react';
3
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
3
4
  import useControlled from '@atlaskit/ds-lib/use-controlled';
4
5
  import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
5
6
  import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { Popup } from '@atlaskit/popup/experimental';
7
8
  import { MenuListItem } from '../menu-list-item';
8
- import { IsOpenContext, SetIsOpenContext } from './flyout-menu-item-context';
9
+ import { IsOpenContext, OnCloseContext, SetIsOpenContext } from './flyout-menu-item-context';
9
10
  /**
10
11
  * __FlyoutMenuItem__
11
12
  *
@@ -40,6 +41,9 @@ export var FlyoutMenuItem = /*#__PURE__*/forwardRef(function (_ref, forwardedRef
40
41
  isOpen = _useControlled2[0],
41
42
  setIsOpen = _useControlled2[1];
42
43
  var previousIsOpen = usePreviousValue(isOpen);
44
+ var onCloseRef = useRef(null);
45
+ var _useAnalyticsEvents = useAnalyticsEvents(),
46
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
43
47
  useEffect(function () {
44
48
  if (previousIsOpen === undefined || previousIsOpen === isOpen) {
45
49
  /**
@@ -51,17 +55,31 @@ export var FlyoutMenuItem = /*#__PURE__*/forwardRef(function (_ref, forwardedRef
51
55
  */
52
56
  return;
53
57
  }
58
+
59
+ // When flyout menu is opened, fire analytics event
60
+ if (isOpen && previousIsOpen === false) {
61
+ if (fg('platform_dst_nav4_flyout_menu_slots_close_button')) {
62
+ var navigationAnalyticsEvent = createAnalyticsEvent({
63
+ source: 'sideNav',
64
+ actionSubject: 'flyoutMenu',
65
+ action: 'opened'
66
+ });
67
+ navigationAnalyticsEvent.fire('navigation');
68
+ }
69
+ }
54
70
  onOpenChange === null || onOpenChange === void 0 || onOpenChange(isOpen);
55
- }, [isOpen, onOpenChange, previousIsOpen]);
71
+ }, [isOpen, onOpenChange, previousIsOpen, createAnalyticsEvent]);
56
72
  return /*#__PURE__*/React.createElement(IsOpenContext.Provider, {
57
73
  value: isOpen
58
74
  }, /*#__PURE__*/React.createElement(SetIsOpenContext.Provider, {
59
75
  value: setIsOpen
76
+ }, /*#__PURE__*/React.createElement(OnCloseContext.Provider, {
77
+ value: onCloseRef
60
78
  }, /*#__PURE__*/React.createElement(MenuListItem, {
61
79
  ref: forwardedRef
62
80
  }, /*#__PURE__*/React.createElement(Popup, {
63
81
  id: id,
64
82
  isOpen: isOpen,
65
83
  role: fg('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : undefined
66
- }, children))));
84
+ }, children)))));
67
85
  });
@@ -7,12 +7,15 @@
7
7
  ._1e02zeo2{inset-inline-start:-9px}
8
8
  ._1e0c1ule{display:block}
9
9
  ._1e0cglyw{display:none}
10
+ ._1lww188d{transition-delay:.3s}
10
11
  ._1lww5cps{transition-delay:0ms}
11
12
  ._1oec1yx9{transition-duration:.1s}
13
+ ._1oec6ebc{transition-duration:.15s}
12
14
  ._1pbykb7n{z-index:1}
13
15
  ._1q51ze3t{padding-block-start:var(--ds-space-0,0)}
14
16
  ._1qu2glyw{outline-style:none}
15
17
  ._4t3i1osq{height:100%}
18
+ ._6fl41ytf{transition-timing-function:ease-in-out}
16
19
  ._85i5ze3t{padding-block-end:var(--ds-space-0,0)}
17
20
  ._ahbq196n{margin-inline-start:var(--ds-space-negative-075,-6px)}
18
21
  ._bfhk1j28{background-color:transparent}
@@ -38,8 +38,10 @@ var containerStyles = {
38
38
  positionStart: "_1e02zeo2"
39
39
  };
40
40
  var grabAreaStyles = {
41
- root: "_1bsbl52n _4t3i1osq _kqswstnw _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _syaz1j28 _bfhk1j28 _k8m01ylx _1oec1yx9 _1lww5cps _d0aluf7j _1gavfnf5 _vp7g6x5g _30l36x5g _1dr21ylx _1s5z1ylx _1cg4fnf5 _le1bfnf5 _1gglglyw _9h8h12zz",
42
- fullHeightSidebar: "_d0al11mm"
41
+ root: "_1bsbl52n _4t3i1osq _kqswstnw _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _syaz1j28 _bfhk1j28 _k8m01ylx _d0aluf7j _vp7g6x5g _30l36x5g _1gglglyw _9h8h12zz",
42
+ fullHeightSidebar: "_d0al11mm",
43
+ oldTransition: "_1oec1yx9 _1lww5cps _1gavfnf5 _1dr21ylx _1s5z1ylx _1cg4fnf5 _le1bfnf5",
44
+ newTransition: "_1oec6ebc _1lww188d _6fl41ytf"
43
45
  };
44
46
  var lineStyles = {
45
47
  root: "_kqswstnw _1e0c1ule _1bsb1l7b _4t3i1osq _syaz1kw7 _bfhk1r31 _1e021v6z"
@@ -80,7 +82,8 @@ var MaybeTooltip = function MaybeTooltip(_ref2) {
80
82
  position: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? 'mouse-y' : 'mouse',
81
83
  mousePosition: "right",
82
84
  isScreenReaderAnnouncementDisabled: true,
83
- component: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? PanelSplitterTooltip : undefined
85
+ component: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? PanelSplitterTooltip : undefined,
86
+ UNSAFE_shouldAlwaysFadeIn: fg('platform_dst_nav4_side_nav_resize_tooltip_feedback')
84
87
  }, children);
85
88
  }
86
89
  return children;
@@ -362,7 +365,7 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
362
365
  ref: splitterRef,
363
366
  "data-testid": testId,
364
367
  onDoubleClick: onDoubleClick,
365
- className: ax([grabAreaStyles.root, isFhsEnabled && grabAreaStyles.fullHeightSidebar])
368
+ className: ax([grabAreaStyles.root, isFhsEnabled && grabAreaStyles.fullHeightSidebar, fg('platform_dst_nav4_side_nav_resize_tooltip_feedback') ? grabAreaStyles.newTransition : grabAreaStyles.oldTransition])
366
369
  }, /*#__PURE__*/React.createElement(VisuallyHidden, null, /*#__PURE__*/React.createElement("input", {
367
370
  type: "range",
368
371
  value: rangeInputValue,
@@ -12,7 +12,7 @@ type CloseButtonProps = {
12
12
  * should trigger the same close logic as the top-level flyout menu
13
13
  * component.
14
14
  */
15
- onClick?: () => void;
15
+ onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
16
16
  /**
17
17
  * A unique string that appears as data attribute data-testid in the
18
18
  * rendered code, serving as a hook for automated tests.
@@ -3,6 +3,7 @@
3
3
  * @jsx jsx
4
4
  */
5
5
  import React from 'react';
6
+ export type FlyoutCloseSource = 'close-button' | 'escape-key' | 'outside-click' | 'other';
6
7
  export type FlyoutMenuItemContentProps = {
7
8
  /**
8
9
  * The contents of the flyout menu.
@@ -1,3 +1,4 @@
1
+ import type { FlyoutCloseSource } from './flyout-menu-item-content';
1
2
  /**
2
3
  * __Is open context__
3
4
  *
@@ -15,15 +16,11 @@ export declare const useSetFlyoutMenuOpen: () => (value: boolean) => void;
15
16
  /**
16
17
  * __On close context__
17
18
  *
18
- * A context for storing the onClose value of the FlyoutMenuItem.
19
+ * A context for storing a ref to the onClose handler with source information.This
20
+ * is used by FlyoutMenuItemContent, FlyoutMenuItemTrigger and FlyoutHeader to store
21
+ * the on close function and source information for closing the flyout menu.
19
22
  */
20
- export declare const OnCloseContext: import("react").Context<(() => void) | null | undefined>;
21
- /**
22
- * __On close provider__
23
- *
24
- * A context provider for supplying the onClose function to the FlyoutHeader.
25
- */
26
- export declare const OnCloseProvider: import("react").Provider<(() => void) | null | undefined>;
23
+ export declare const OnCloseContext: import("react").Context<import("react").MutableRefObject<((event: Event | React.MouseEvent<HTMLButtonElement> | KeyboardEvent | MouseEvent | null, source?: FlyoutCloseSource) => void) | null>>;
27
24
  /**
28
25
  * __Title id context__
29
26
  *
@@ -12,7 +12,7 @@ type CloseButtonProps = {
12
12
  * should trigger the same close logic as the top-level flyout menu
13
13
  * component.
14
14
  */
15
- onClick?: () => void;
15
+ onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
16
16
  /**
17
17
  * A unique string that appears as data attribute data-testid in the
18
18
  * rendered code, serving as a hook for automated tests.
@@ -3,6 +3,7 @@
3
3
  * @jsx jsx
4
4
  */
5
5
  import React from 'react';
6
+ export type FlyoutCloseSource = 'close-button' | 'escape-key' | 'outside-click' | 'other';
6
7
  export type FlyoutMenuItemContentProps = {
7
8
  /**
8
9
  * The contents of the flyout menu.
@@ -1,3 +1,4 @@
1
+ import type { FlyoutCloseSource } from './flyout-menu-item-content';
1
2
  /**
2
3
  * __Is open context__
3
4
  *
@@ -15,15 +16,11 @@ export declare const useSetFlyoutMenuOpen: () => (value: boolean) => void;
15
16
  /**
16
17
  * __On close context__
17
18
  *
18
- * A context for storing the onClose value of the FlyoutMenuItem.
19
+ * A context for storing a ref to the onClose handler with source information.This
20
+ * is used by FlyoutMenuItemContent, FlyoutMenuItemTrigger and FlyoutHeader to store
21
+ * the on close function and source information for closing the flyout menu.
19
22
  */
20
- export declare const OnCloseContext: import("react").Context<(() => void) | null | undefined>;
21
- /**
22
- * __On close provider__
23
- *
24
- * A context provider for supplying the onClose function to the FlyoutHeader.
25
- */
26
- export declare const OnCloseProvider: import("react").Provider<(() => void) | null | undefined>;
23
+ export declare const OnCloseContext: import("react").Context<import("react").MutableRefObject<((event: Event | React.MouseEvent<HTMLButtonElement> | KeyboardEvent | MouseEvent | null, source?: FlyoutCloseSource) => void) | null>>;
27
24
  /**
28
25
  * __Title id context__
29
26
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/navigation-system",
3
- "version": "5.24.0",
3
+ "version": "5.26.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",
@@ -82,7 +82,7 @@
82
82
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
83
83
  "@atlaskit/primitives": "^17.0.0",
84
84
  "@atlaskit/tokens": "^9.1.0",
85
- "@atlaskit/tooltip": "^20.12.0",
85
+ "@atlaskit/tooltip": "^20.13.0",
86
86
  "@atlaskit/visually-hidden": "^3.0.0",
87
87
  "@babel/runtime": "^7.0.0",
88
88
  "@compiled/react": "^0.18.6",
@@ -98,7 +98,7 @@
98
98
  "@af/accessibility-testing": "workspace:^",
99
99
  "@af/integration-testing": "workspace:^",
100
100
  "@af/visual-regression": "workspace:^",
101
- "@atlaskit/app-provider": "^3.2.0",
101
+ "@atlaskit/app-provider": "^3.3.0",
102
102
  "@atlaskit/badge": "^18.3.0",
103
103
  "@atlaskit/banner": "^14.0.0",
104
104
  "@atlaskit/breadcrumbs": "^15.3.0",
@@ -122,8 +122,7 @@
122
122
  "@atlassian/test-utils": "^1.0.0",
123
123
  "@atlassian/testing-library": "^0.4.0",
124
124
  "@axe-core/playwright": "^4.8.0",
125
- "@testing-library/react": "^13.4.0",
126
- "@testing-library/react-hooks": "^8.0.1",
125
+ "@testing-library/react": "^16.3.0",
127
126
  "@testing-library/user-event": "^14.4.3",
128
127
  "raf-stub": "^2.0.1",
129
128
  "react-dom": "^18.2.0"