@atlaskit/dropdown-menu 12.17.2 → 12.18.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/dropdown-menu
2
2
 
3
+ ## 12.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#133919](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/133919)
8
+ [`8b25fdc44ca38`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/8b25fdc44ca38) -
9
+ Added return focus to trigger after item selection
10
+
11
+ ## 12.17.3
12
+
13
+ ### Patch Changes
14
+
15
+ - [#133182](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/133182)
16
+ [`063ecc7968c68`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/063ecc7968c68) -
17
+ We are testing an internal change to use an ID generator compatible with both React 16 and
18
+ React 18. If these changes are successful, it will be rolled out in a later release.
19
+
3
20
  ## 12.17.2
4
21
 
5
22
  ### Patch Changes
@@ -8,7 +8,7 @@ exports.default = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
10
10
  var _react = _interopRequireDefault(require("react"));
11
- var _reactUid = require("react-uid");
11
+ var _reactUid = require("@atlaskit/ds-lib/react-uid");
12
12
  var _section = _interopRequireDefault(require("@atlaskit/menu/section"));
13
13
  var _groupTitle = _interopRequireDefault(require("../internal/components/group-title"));
14
14
  var _checkboxGroupContext = require("../internal/context/checkbox-group-context");
@@ -29,7 +29,7 @@ var DropdownItemCheckboxGroup = function DropdownItemCheckboxGroup(_ref) {
29
29
  testId = _ref.testId,
30
30
  title = _ref.title,
31
31
  rest = (0, _objectWithoutProperties2.default)(_ref, _excluded);
32
- var uid = (0, _reactUid.useUID)();
32
+ var uid = (0, _reactUid.useId)();
33
33
  var titleId = "dropdown-menu-item-checkbox-group-title-".concat(uid);
34
34
  return /*#__PURE__*/_react.default.createElement(_checkboxGroupContext.CheckboxGroupContext.Provider, {
35
35
  value: id
@@ -9,7 +9,7 @@ exports.default = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
11
  var _react = _interopRequireWildcard(require("react"));
12
- var _reactUid = require("react-uid");
12
+ var _reactUid = require("@atlaskit/ds-lib/react-uid");
13
13
  var _menu = require("@atlaskit/menu");
14
14
  var _groupTitle = _interopRequireDefault(require("./internal/components/group-title"));
15
15
  var _excluded = ["children", "id", "isList", "isScrollable", "title", "testId", "hasSeparator", "overrides"];
@@ -31,7 +31,7 @@ var DropdownMenuItemGroup = /*#__PURE__*/(0, _react.forwardRef)(function (_ref,
31
31
  hasSeparator = _ref.hasSeparator,
32
32
  overrides = _ref.overrides,
33
33
  rest = (0, _objectWithoutProperties2.default)(_ref, _excluded);
34
- var uid = (0, _reactUid.useUID)();
34
+ var uid = (0, _reactUid.useId)();
35
35
  var titleId = "dropdown-menu-item-group-title-".concat(uid);
36
36
  return /*#__PURE__*/_react.default.createElement(_menu.Section, (0, _extends2.default)({
37
37
  id: id,
@@ -14,7 +14,7 @@ var _buttonItem = _interopRequireDefault(require("@atlaskit/menu/button-item"));
14
14
  var _customItem = _interopRequireDefault(require("@atlaskit/menu/custom-item"));
15
15
  var _linkItem = _interopRequireDefault(require("@atlaskit/menu/link-item"));
16
16
  var _useRegisterItemWithFocusManager = _interopRequireDefault(require("./internal/hooks/use-register-item-with-focus-manager"));
17
- var _excluded = ["children", "component", "description", "elemAfter", "elemBefore", "href", "isDisabled", "isSelected", "onClick", "rel", "shouldDescriptionWrap", "shouldTitleWrap", "target", "testId", "UNSAFE_shouldDisableRouterLink"];
17
+ var _excluded = ["children", "component", "description", "elemAfter", "elemBefore", "href", "isDisabled", "isSelected", "onClick", "rel", "shouldDescriptionWrap", "shouldTitleWrap", "target", "testId", "UNSAFE_shouldDisableRouterLink", "returnFocusRef"];
18
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
19
19
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
20
20
  /**
@@ -44,8 +44,17 @@ var DropdownMenuItem = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref)
44
44
  target = _ref.target,
45
45
  testId = _ref.testId,
46
46
  UNSAFE_shouldDisableRouterLink = _ref.UNSAFE_shouldDisableRouterLink,
47
+ returnFocusRef = _ref.returnFocusRef,
47
48
  rest = (0, _objectWithoutProperties2.default)(_ref, _excluded);
48
49
  var itemRef = (0, _useRegisterItemWithFocusManager.default)();
50
+ var handleItemClick = (0, _react.useCallback)(function (event) {
51
+ if (returnFocusRef !== null && returnFocusRef !== void 0 && returnFocusRef.current) {
52
+ returnFocusRef.current.focus();
53
+ }
54
+ if (onClick) {
55
+ onClick(event);
56
+ }
57
+ }, [onClick, returnFocusRef]);
49
58
  if (component) {
50
59
  return /*#__PURE__*/_react.default.createElement(_customItem.default, (0, _extends2.default)({
51
60
  component: component,
@@ -54,7 +63,7 @@ var DropdownMenuItem = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref)
54
63
  iconBefore: elemBefore,
55
64
  isDisabled: isDisabled,
56
65
  isSelected: isSelected,
57
- onClick: onClick,
66
+ onClick: handleItemClick,
58
67
  ref: (0, _mergeRefs.default)([ref, itemRef]),
59
68
  shouldDescriptionWrap: shouldDescriptionWrap,
60
69
  shouldTitleWrap: shouldTitleWrap,
@@ -76,7 +85,7 @@ var DropdownMenuItem = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref)
76
85
  iconBefore: elemBefore,
77
86
  isDisabled: isDisabled,
78
87
  isSelected: isSelected,
79
- onClick: onClick,
88
+ onClick: handleItemClick,
80
89
  ref: (0, _mergeRefs.default)([ref, itemRef]),
81
90
  rel: rel,
82
91
  role: "menuitem",
@@ -94,7 +103,7 @@ var DropdownMenuItem = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref)
94
103
  iconBefore: elemBefore,
95
104
  isDisabled: isDisabled,
96
105
  isSelected: isSelected,
97
- onClick: onClick,
106
+ onClick: handleItemClick,
98
107
  ref: (0, _mergeRefs.default)([ref, itemRef]),
99
108
  role: "menuitem",
100
109
  shouldDescriptionWrap: shouldDescriptionWrap,
@@ -23,12 +23,11 @@ var _popup = _interopRequireDefault(require("@atlaskit/popup"));
23
23
  var _constants = require("@atlaskit/theme/constants");
24
24
  var _focusManager = _interopRequireDefault(require("./internal/components/focus-manager"));
25
25
  var _menuWrapper = _interopRequireDefault(require("./internal/components/menu-wrapper"));
26
+ var _dropdownMenuContext = require("./internal/context/dropdown-menu-context");
26
27
  var _selectionStore = _interopRequireDefault(require("./internal/context/selection-store"));
27
28
  var _useRegisterItemWithFocusManager = _interopRequireDefault(require("./internal/hooks/use-register-item-with-focus-manager"));
28
29
  var _useGeneratedId = _interopRequireWildcard(require("./internal/utils/use-generated-id"));
29
- var _excluded = ["ref", "aria-controls", "aria-expanded", "aria-haspopup"];
30
- /* eslint-disable import/order */
31
- // eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
30
+ var _excluded = ["ref", "aria-controls", "aria-expanded", "aria-haspopup"]; // eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
32
31
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
33
32
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
34
33
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -105,6 +104,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
105
104
  _useControlledState2 = (0, _slicedToArray2.default)(_useControlledState, 2),
106
105
  isLocalOpen = _useControlledState2[0],
107
106
  setLocalIsOpen = _useControlledState2[1];
107
+ var triggerRef = (0, _react.useRef)(null);
108
108
  var _useState = (0, _react.useState)(false),
109
109
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
110
110
  isTriggeredUsingKeyboard = _useState2[0],
@@ -169,6 +169,11 @@ var DropdownMenu = function DropdownMenu(_ref) {
169
169
  var _itemRef$current2;
170
170
  (_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
171
171
  });
172
+ } else if (triggerRef.current) {
173
+ requestAnimationFrame(function () {
174
+ var _triggerRef$current;
175
+ (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 || _triggerRef$current.focus();
176
+ });
172
177
  }
173
178
  var newValue = false;
174
179
  setLocalIsOpen(newValue);
@@ -233,7 +238,11 @@ var DropdownMenu = function DropdownMenu(_ref) {
233
238
  } : {
234
239
  shouldRenderToParent: shouldRenderToParent
235
240
  };
236
- return /*#__PURE__*/_react.default.createElement(_selectionStore.default, null, /*#__PURE__*/_react.default.createElement(_popup.default, (0, _extends2.default)({
241
+ return /*#__PURE__*/_react.default.createElement(_selectionStore.default, null, /*#__PURE__*/_react.default.createElement(_dropdownMenuContext.DropdownMenuProvider, {
242
+ value: {
243
+ returnFocusRef: triggerRef
244
+ }
245
+ }, /*#__PURE__*/_react.default.createElement(_popup.default, (0, _extends2.default)({
237
246
  id: isLocalOpen ? id : undefined,
238
247
  shouldFlip: shouldFlip,
239
248
  isOpen: isLocalOpen,
@@ -257,14 +266,14 @@ var DropdownMenu = function DropdownMenu(_ref) {
257
266
  'aria-expanded': ariaExpanded,
258
267
  'aria-haspopup': ariaHasPopup
259
268
  }, rest), bindFocus), {}, {
260
- triggerRef: (0, _mergeRefs.default)([ref, itemRef]),
269
+ triggerRef: (0, _mergeRefs.default)([ref, triggerRef, itemRef]),
261
270
  isSelected: isLocalOpen,
262
271
  onClick: handleTriggerClicked,
263
272
  testId: testId && "".concat(testId, "--trigger")
264
273
  }));
265
274
  }
266
275
  return /*#__PURE__*/_react.default.createElement(_new.default, (0, _extends2.default)({}, bindFocus, {
267
- ref: (0, _mergeRefs.default)([ref, itemRef]),
276
+ ref: (0, _mergeRefs.default)([ref, triggerRef, itemRef]),
268
277
  "aria-controls": ariaControls,
269
278
  "aria-expanded": ariaExpanded,
270
279
  "aria-haspopup": ariaHasPopup,
@@ -295,6 +304,6 @@ var DropdownMenu = function DropdownMenu(_ref) {
295
304
  testId: testId && "".concat(testId, "--menu-wrapper")
296
305
  }, children));
297
306
  }
298
- })));
307
+ }))));
299
308
  };
300
309
  var _default = exports.default = DropdownMenu;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DropdownMenuProvider = void 0;
7
+ var _react = require("react");
8
+ var DropdownMenuContext = /*#__PURE__*/(0, _react.createContext)(undefined);
9
+
10
+ // TODO: Fill in the component {description} and ensure links point to the correct {packageName} location.
11
+ // Remove links that the component does not have (such as usage). If there are no links remove them all.
12
+ /**
13
+ * __Dropdown menu provider__
14
+ *
15
+ * A dropdown menu provider {description}.
16
+ *
17
+ * - [Examples](https://atlassian.design/components/{packageName}/examples)
18
+ * - [Code](https://atlassian.design/components/{packageName}/code)
19
+ * - [Usage](https://atlassian.design/components/{packageName}/usage)
20
+ */
21
+ var DropdownMenuProvider = exports.DropdownMenuProvider = DropdownMenuContext.Provider;
@@ -11,8 +11,8 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
11
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
12
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
13
  var _react = _interopRequireWildcard(require("react"));
14
- var _reactUid = require("react-uid");
15
14
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
15
+ var _reactUid = require("@atlaskit/ds-lib/react-uid");
16
16
  var _menu = require("@atlaskit/menu");
17
17
  var _groupTitle = _interopRequireDefault(require("../internal/components/group-title"));
18
18
  var _selectionStore = require("../internal/context/selection-store");
@@ -51,7 +51,7 @@ var DropdownItemRadioGroup = function DropdownItemRadioGroup(_ref) {
51
51
  var _useContext = (0, _react.useContext)(_selectionStore.SelectionStoreContext),
52
52
  setGroupState = _useContext.setGroupState,
53
53
  getGroupState = _useContext.getGroupState;
54
- var uid = (0, _reactUid.useUID)();
54
+ var uid = (0, _reactUid.useId)();
55
55
  var titleId = "dropdown-menu-item-radio-group-title-".concat(uid);
56
56
 
57
57
  /**
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import React from 'react';
3
- import { useUID } from 'react-uid';
3
+ import { useId } from '@atlaskit/ds-lib/react-uid';
4
4
  import Section from '@atlaskit/menu/section';
5
5
  import GroupTitle from '../internal/components/group-title';
6
6
  import { CheckboxGroupContext } from '../internal/context/checkbox-group-context';
@@ -22,7 +22,7 @@ const DropdownItemCheckboxGroup = ({
22
22
  // DSP-13312 TODO: remove spread props in future major release
23
23
  ...rest
24
24
  }) => {
25
- const uid = useUID();
25
+ const uid = useId();
26
26
  const titleId = `dropdown-menu-item-checkbox-group-title-${uid}`;
27
27
  return /*#__PURE__*/React.createElement(CheckboxGroupContext.Provider, {
28
28
  value: id
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { forwardRef } from 'react';
3
- import { useUID } from 'react-uid';
3
+ import { useId } from '@atlaskit/ds-lib/react-uid';
4
4
  import { Section } from '@atlaskit/menu';
5
5
  import GroupTitle from './internal/components/group-title';
6
6
 
@@ -21,7 +21,7 @@ const DropdownMenuItemGroup = /*#__PURE__*/forwardRef(({
21
21
  overrides,
22
22
  ...rest
23
23
  }, ref) => {
24
- const uid = useUID();
24
+ const uid = useId();
25
25
  const titleId = `dropdown-menu-item-group-title-${uid}`;
26
26
  return /*#__PURE__*/React.createElement(Section, _extends({
27
27
  id: id,
@@ -1,5 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React, { forwardRef } from 'react';
2
+ import React, { forwardRef, useCallback } from 'react';
3
3
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
4
4
  import ButtonItem from '@atlaskit/menu/button-item';
5
5
  import CustomItem from '@atlaskit/menu/custom-item';
@@ -30,9 +30,18 @@ const DropdownMenuItem = /*#__PURE__*/forwardRef(({
30
30
  target,
31
31
  testId,
32
32
  UNSAFE_shouldDisableRouterLink,
33
+ returnFocusRef,
33
34
  ...rest
34
35
  }, ref) => {
35
36
  const itemRef = useRegisterItemWithFocusManager();
37
+ const handleItemClick = useCallback(event => {
38
+ if (returnFocusRef !== null && returnFocusRef !== void 0 && returnFocusRef.current) {
39
+ returnFocusRef.current.focus();
40
+ }
41
+ if (onClick) {
42
+ onClick(event);
43
+ }
44
+ }, [onClick, returnFocusRef]);
36
45
  if (component) {
37
46
  return /*#__PURE__*/React.createElement(CustomItem, _extends({
38
47
  component: component,
@@ -41,7 +50,7 @@ const DropdownMenuItem = /*#__PURE__*/forwardRef(({
41
50
  iconBefore: elemBefore,
42
51
  isDisabled: isDisabled,
43
52
  isSelected: isSelected,
44
- onClick: onClick,
53
+ onClick: handleItemClick,
45
54
  ref: mergeRefs([ref, itemRef]),
46
55
  shouldDescriptionWrap: shouldDescriptionWrap,
47
56
  shouldTitleWrap: shouldTitleWrap,
@@ -63,7 +72,7 @@ const DropdownMenuItem = /*#__PURE__*/forwardRef(({
63
72
  iconBefore: elemBefore,
64
73
  isDisabled: isDisabled,
65
74
  isSelected: isSelected,
66
- onClick: onClick,
75
+ onClick: handleItemClick,
67
76
  ref: mergeRefs([ref, itemRef]),
68
77
  rel: rel,
69
78
  role: "menuitem",
@@ -81,7 +90,7 @@ const DropdownMenuItem = /*#__PURE__*/forwardRef(({
81
90
  iconBefore: elemBefore,
82
91
  isDisabled: isDisabled,
83
92
  isSelected: isSelected,
84
- onClick: onClick,
93
+ onClick: handleItemClick,
85
94
  ref: mergeRefs([ref, itemRef]),
86
95
  role: "menuitem",
87
96
  shouldDescriptionWrap: shouldDescriptionWrap,
@@ -1,6 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- /* eslint-disable import/order */
3
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
3
  import { bind } from 'bind-event-listener';
5
4
  import Button from '@atlaskit/button/new';
6
5
  import { KEY_DOWN, KEY_ENTER, KEY_SPACE, KEY_TAB } from '@atlaskit/ds-lib/keycodes';
@@ -14,6 +13,7 @@ import Popup from '@atlaskit/popup';
14
13
  import { gridSize as gridSizeFn, layers } from '@atlaskit/theme/constants';
15
14
  import FocusManager from './internal/components/focus-manager';
16
15
  import MenuWrapper from './internal/components/menu-wrapper';
16
+ import { DropdownMenuProvider } from './internal/context/dropdown-menu-context';
17
17
  import SelectionStore from './internal/context/selection-store';
18
18
  import useRegisterItemWithFocusManager from './internal/hooks/use-register-item-with-focus-manager';
19
19
  import useGeneratedId, { PREFIX } from './internal/utils/use-generated-id';
@@ -76,6 +76,7 @@ const DropdownMenu = ({
76
76
  label
77
77
  }) => {
78
78
  const [isLocalOpen, setLocalIsOpen] = useControlledState(isOpen, () => defaultOpen);
79
+ const triggerRef = useRef(null);
79
80
  const [isTriggeredUsingKeyboard, setTriggeredUsingKeyboard] = useState(false);
80
81
  const id = useGeneratedId();
81
82
  const itemRef = useRegisterItemWithFocusManager();
@@ -137,6 +138,11 @@ const DropdownMenu = ({
137
138
  var _itemRef$current2;
138
139
  (_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 ? void 0 : _itemRef$current2.focus();
139
140
  });
141
+ } else if (triggerRef.current) {
142
+ requestAnimationFrame(() => {
143
+ var _triggerRef$current;
144
+ (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : _triggerRef$current.focus();
145
+ });
140
146
  }
141
147
  const newValue = false;
142
148
  setLocalIsOpen(newValue);
@@ -202,7 +208,11 @@ const DropdownMenu = ({
202
208
  } : {
203
209
  shouldRenderToParent
204
210
  };
205
- return /*#__PURE__*/React.createElement(SelectionStore, null, /*#__PURE__*/React.createElement(Popup, _extends({
211
+ return /*#__PURE__*/React.createElement(SelectionStore, null, /*#__PURE__*/React.createElement(DropdownMenuProvider, {
212
+ value: {
213
+ returnFocusRef: triggerRef
214
+ }
215
+ }, /*#__PURE__*/React.createElement(Popup, _extends({
206
216
  id: isLocalOpen ? id : undefined,
207
217
  shouldFlip: shouldFlip,
208
218
  isOpen: isLocalOpen,
@@ -229,14 +239,14 @@ const DropdownMenu = ({
229
239
  'aria-haspopup': ariaHasPopup,
230
240
  ...rest,
231
241
  ...bindFocus,
232
- triggerRef: mergeRefs([ref, itemRef]),
242
+ triggerRef: mergeRefs([ref, triggerRef, itemRef]),
233
243
  isSelected: isLocalOpen,
234
244
  onClick: handleTriggerClicked,
235
245
  testId: testId && `${testId}--trigger`
236
246
  });
237
247
  }
238
248
  return /*#__PURE__*/React.createElement(Button, _extends({}, bindFocus, {
239
- ref: mergeRefs([ref, itemRef]),
249
+ ref: mergeRefs([ref, triggerRef, itemRef]),
240
250
  "aria-controls": ariaControls,
241
251
  "aria-expanded": ariaExpanded,
242
252
  "aria-haspopup": ariaHasPopup,
@@ -266,6 +276,6 @@ const DropdownMenu = ({
266
276
  autoFocus: autoFocus,
267
277
  testId: testId && `${testId}--menu-wrapper`
268
278
  }, children))
269
- })));
279
+ }))));
270
280
  };
271
281
  export default DropdownMenu;
@@ -0,0 +1,15 @@
1
+ import { createContext } from 'react';
2
+ const DropdownMenuContext = /*#__PURE__*/createContext(undefined);
3
+
4
+ // TODO: Fill in the component {description} and ensure links point to the correct {packageName} location.
5
+ // Remove links that the component does not have (such as usage). If there are no links remove them all.
6
+ /**
7
+ * __Dropdown menu provider__
8
+ *
9
+ * A dropdown menu provider {description}.
10
+ *
11
+ * - [Examples](https://atlassian.design/components/{packageName}/examples)
12
+ * - [Code](https://atlassian.design/components/{packageName}/code)
13
+ * - [Usage](https://atlassian.design/components/{packageName}/usage)
14
+ */
15
+ export const DropdownMenuProvider = DropdownMenuContext.Provider;
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { createContext, useContext, useState } from 'react';
3
- import { useUID } from 'react-uid';
4
3
  import noop from '@atlaskit/ds-lib/noop';
4
+ import { useId } from '@atlaskit/ds-lib/react-uid';
5
5
  import { Section } from '@atlaskit/menu';
6
6
  import GroupTitle from '../internal/components/group-title';
7
7
  import { SelectionStoreContext } from '../internal/context/selection-store';
@@ -38,7 +38,7 @@ const DropdownItemRadioGroup = ({
38
38
  setGroupState,
39
39
  getGroupState
40
40
  } = useContext(SelectionStoreContext);
41
- const uid = useUID();
41
+ const uid = useId();
42
42
  const titleId = `dropdown-menu-item-radio-group-title-${uid}`;
43
43
 
44
44
  /**
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
3
  var _excluded = ["children", "hasSeparator", "id", "isList", "isScrollable", "overrides", "testId", "title"];
4
4
  import React from 'react';
5
- import { useUID } from 'react-uid';
5
+ import { useId } from '@atlaskit/ds-lib/react-uid';
6
6
  import Section from '@atlaskit/menu/section';
7
7
  import GroupTitle from '../internal/components/group-title';
8
8
  import { CheckboxGroupContext } from '../internal/context/checkbox-group-context';
@@ -22,7 +22,7 @@ var DropdownItemCheckboxGroup = function DropdownItemCheckboxGroup(_ref) {
22
22
  testId = _ref.testId,
23
23
  title = _ref.title,
24
24
  rest = _objectWithoutProperties(_ref, _excluded);
25
- var uid = useUID();
25
+ var uid = useId();
26
26
  var titleId = "dropdown-menu-item-checkbox-group-title-".concat(uid);
27
27
  return /*#__PURE__*/React.createElement(CheckboxGroupContext.Provider, {
28
28
  value: id
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
3
  var _excluded = ["children", "id", "isList", "isScrollable", "title", "testId", "hasSeparator", "overrides"];
4
4
  import React, { forwardRef } from 'react';
5
- import { useUID } from 'react-uid';
5
+ import { useId } from '@atlaskit/ds-lib/react-uid';
6
6
  import { Section } from '@atlaskit/menu';
7
7
  import GroupTitle from './internal/components/group-title';
8
8
 
@@ -22,7 +22,7 @@ var DropdownMenuItemGroup = /*#__PURE__*/forwardRef(function (_ref, ref) {
22
22
  hasSeparator = _ref.hasSeparator,
23
23
  overrides = _ref.overrides,
24
24
  rest = _objectWithoutProperties(_ref, _excluded);
25
- var uid = useUID();
25
+ var uid = useId();
26
26
  var titleId = "dropdown-menu-item-group-title-".concat(uid);
27
27
  return /*#__PURE__*/React.createElement(Section, _extends({
28
28
  id: id,
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["children", "component", "description", "elemAfter", "elemBefore", "href", "isDisabled", "isSelected", "onClick", "rel", "shouldDescriptionWrap", "shouldTitleWrap", "target", "testId", "UNSAFE_shouldDisableRouterLink"];
4
- import React, { forwardRef } from 'react';
3
+ var _excluded = ["children", "component", "description", "elemAfter", "elemBefore", "href", "isDisabled", "isSelected", "onClick", "rel", "shouldDescriptionWrap", "shouldTitleWrap", "target", "testId", "UNSAFE_shouldDisableRouterLink", "returnFocusRef"];
4
+ import React, { forwardRef, useCallback } from 'react';
5
5
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
6
6
  import ButtonItem from '@atlaskit/menu/button-item';
7
7
  import CustomItem from '@atlaskit/menu/custom-item';
@@ -34,8 +34,17 @@ var DropdownMenuItem = /*#__PURE__*/forwardRef(function (_ref, ref) {
34
34
  target = _ref.target,
35
35
  testId = _ref.testId,
36
36
  UNSAFE_shouldDisableRouterLink = _ref.UNSAFE_shouldDisableRouterLink,
37
+ returnFocusRef = _ref.returnFocusRef,
37
38
  rest = _objectWithoutProperties(_ref, _excluded);
38
39
  var itemRef = useRegisterItemWithFocusManager();
40
+ var handleItemClick = useCallback(function (event) {
41
+ if (returnFocusRef !== null && returnFocusRef !== void 0 && returnFocusRef.current) {
42
+ returnFocusRef.current.focus();
43
+ }
44
+ if (onClick) {
45
+ onClick(event);
46
+ }
47
+ }, [onClick, returnFocusRef]);
39
48
  if (component) {
40
49
  return /*#__PURE__*/React.createElement(CustomItem, _extends({
41
50
  component: component,
@@ -44,7 +53,7 @@ var DropdownMenuItem = /*#__PURE__*/forwardRef(function (_ref, ref) {
44
53
  iconBefore: elemBefore,
45
54
  isDisabled: isDisabled,
46
55
  isSelected: isSelected,
47
- onClick: onClick,
56
+ onClick: handleItemClick,
48
57
  ref: mergeRefs([ref, itemRef]),
49
58
  shouldDescriptionWrap: shouldDescriptionWrap,
50
59
  shouldTitleWrap: shouldTitleWrap,
@@ -66,7 +75,7 @@ var DropdownMenuItem = /*#__PURE__*/forwardRef(function (_ref, ref) {
66
75
  iconBefore: elemBefore,
67
76
  isDisabled: isDisabled,
68
77
  isSelected: isSelected,
69
- onClick: onClick,
78
+ onClick: handleItemClick,
70
79
  ref: mergeRefs([ref, itemRef]),
71
80
  rel: rel,
72
81
  role: "menuitem",
@@ -84,7 +93,7 @@ var DropdownMenuItem = /*#__PURE__*/forwardRef(function (_ref, ref) {
84
93
  iconBefore: elemBefore,
85
94
  isDisabled: isDisabled,
86
95
  isSelected: isSelected,
87
- onClick: onClick,
96
+ onClick: handleItemClick,
88
97
  ref: mergeRefs([ref, itemRef]),
89
98
  role: "menuitem",
90
99
  shouldDescriptionWrap: shouldDescriptionWrap,
@@ -5,8 +5,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  var _excluded = ["ref", "aria-controls", "aria-expanded", "aria-haspopup"];
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
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
- /* eslint-disable import/order */
9
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
8
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
10
9
  import { bind } from 'bind-event-listener';
11
10
  import Button from '@atlaskit/button/new';
12
11
  import { KEY_DOWN, KEY_ENTER, KEY_SPACE, KEY_TAB } from '@atlaskit/ds-lib/keycodes';
@@ -20,6 +19,7 @@ import Popup from '@atlaskit/popup';
20
19
  import { gridSize as gridSizeFn, layers } from '@atlaskit/theme/constants';
21
20
  import FocusManager from './internal/components/focus-manager';
22
21
  import MenuWrapper from './internal/components/menu-wrapper';
22
+ import { DropdownMenuProvider } from './internal/context/dropdown-menu-context';
23
23
  import SelectionStore from './internal/context/selection-store';
24
24
  import useRegisterItemWithFocusManager from './internal/hooks/use-register-item-with-focus-manager';
25
25
  import useGeneratedId, { PREFIX } from './internal/utils/use-generated-id';
@@ -95,6 +95,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
95
95
  _useControlledState2 = _slicedToArray(_useControlledState, 2),
96
96
  isLocalOpen = _useControlledState2[0],
97
97
  setLocalIsOpen = _useControlledState2[1];
98
+ var triggerRef = useRef(null);
98
99
  var _useState = useState(false),
99
100
  _useState2 = _slicedToArray(_useState, 2),
100
101
  isTriggeredUsingKeyboard = _useState2[0],
@@ -159,6 +160,11 @@ var DropdownMenu = function DropdownMenu(_ref) {
159
160
  var _itemRef$current2;
160
161
  (_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
161
162
  });
163
+ } else if (triggerRef.current) {
164
+ requestAnimationFrame(function () {
165
+ var _triggerRef$current;
166
+ (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 || _triggerRef$current.focus();
167
+ });
162
168
  }
163
169
  var newValue = false;
164
170
  setLocalIsOpen(newValue);
@@ -223,7 +229,11 @@ var DropdownMenu = function DropdownMenu(_ref) {
223
229
  } : {
224
230
  shouldRenderToParent: shouldRenderToParent
225
231
  };
226
- return /*#__PURE__*/React.createElement(SelectionStore, null, /*#__PURE__*/React.createElement(Popup, _extends({
232
+ return /*#__PURE__*/React.createElement(SelectionStore, null, /*#__PURE__*/React.createElement(DropdownMenuProvider, {
233
+ value: {
234
+ returnFocusRef: triggerRef
235
+ }
236
+ }, /*#__PURE__*/React.createElement(Popup, _extends({
227
237
  id: isLocalOpen ? id : undefined,
228
238
  shouldFlip: shouldFlip,
229
239
  isOpen: isLocalOpen,
@@ -247,14 +257,14 @@ var DropdownMenu = function DropdownMenu(_ref) {
247
257
  'aria-expanded': ariaExpanded,
248
258
  'aria-haspopup': ariaHasPopup
249
259
  }, rest), bindFocus), {}, {
250
- triggerRef: mergeRefs([ref, itemRef]),
260
+ triggerRef: mergeRefs([ref, triggerRef, itemRef]),
251
261
  isSelected: isLocalOpen,
252
262
  onClick: handleTriggerClicked,
253
263
  testId: testId && "".concat(testId, "--trigger")
254
264
  }));
255
265
  }
256
266
  return /*#__PURE__*/React.createElement(Button, _extends({}, bindFocus, {
257
- ref: mergeRefs([ref, itemRef]),
267
+ ref: mergeRefs([ref, triggerRef, itemRef]),
258
268
  "aria-controls": ariaControls,
259
269
  "aria-expanded": ariaExpanded,
260
270
  "aria-haspopup": ariaHasPopup,
@@ -285,6 +295,6 @@ var DropdownMenu = function DropdownMenu(_ref) {
285
295
  testId: testId && "".concat(testId, "--menu-wrapper")
286
296
  }, children));
287
297
  }
288
- })));
298
+ }))));
289
299
  };
290
300
  export default DropdownMenu;
@@ -0,0 +1,15 @@
1
+ import { createContext } from 'react';
2
+ var DropdownMenuContext = /*#__PURE__*/createContext(undefined);
3
+
4
+ // TODO: Fill in the component {description} and ensure links point to the correct {packageName} location.
5
+ // Remove links that the component does not have (such as usage). If there are no links remove them all.
6
+ /**
7
+ * __Dropdown menu provider__
8
+ *
9
+ * A dropdown menu provider {description}.
10
+ *
11
+ * - [Examples](https://atlassian.design/components/{packageName}/examples)
12
+ * - [Code](https://atlassian.design/components/{packageName}/code)
13
+ * - [Usage](https://atlassian.design/components/{packageName}/usage)
14
+ */
15
+ export var DropdownMenuProvider = DropdownMenuContext.Provider;
@@ -6,8 +6,8 @@ var _excluded = ["children", "hasSeparator", "id", "isList", "isScrollable", "ov
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
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, { createContext, useContext, useState } from 'react';
9
- import { useUID } from 'react-uid';
10
9
  import noop from '@atlaskit/ds-lib/noop';
10
+ import { useId } from '@atlaskit/ds-lib/react-uid';
11
11
  import { Section } from '@atlaskit/menu';
12
12
  import GroupTitle from '../internal/components/group-title';
13
13
  import { SelectionStoreContext } from '../internal/context/selection-store';
@@ -41,7 +41,7 @@ var DropdownItemRadioGroup = function DropdownItemRadioGroup(_ref) {
41
41
  var _useContext = useContext(SelectionStoreContext),
42
42
  setGroupState = _useContext.setGroupState,
43
43
  getGroupState = _useContext.getGroupState;
44
- var uid = useUID();
44
+ var uid = useId();
45
45
  var titleId = "dropdown-menu-item-radio-group-title-".concat(uid);
46
46
 
47
47
  /**
@@ -0,0 +1,16 @@
1
+ import { type RefObject } from 'react';
2
+ interface DropdownMenuContext {
3
+ returnFocusRef: RefObject<HTMLElement> | null;
4
+ }
5
+ declare const DropdownMenuContext: import("react").Context<DropdownMenuContext | undefined>;
6
+ /**
7
+ * __Dropdown menu provider__
8
+ *
9
+ * A dropdown menu provider {description}.
10
+ *
11
+ * - [Examples](https://atlassian.design/components/{packageName}/examples)
12
+ * - [Code](https://atlassian.design/components/{packageName}/code)
13
+ * - [Usage](https://atlassian.design/components/{packageName}/usage)
14
+ */
15
+ export declare const DropdownMenuProvider: import("react").Provider<DropdownMenuContext | undefined>;
16
+ export {};
@@ -238,6 +238,10 @@ export interface DropdownItemProps {
238
238
  * Marked as "unsafe" because ideally, router links should be used for all internal links.
239
239
  */
240
240
  UNSAFE_shouldDisableRouterLink?: boolean;
241
+ /**
242
+ * If ref is passed, focus returns to that specific ref element after dropdown item clicked.
243
+ */
244
+ returnFocusRef?: RefObject<HTMLElement>;
241
245
  }
242
246
  export interface DropdownItemCheckboxProps {
243
247
  /**
@@ -0,0 +1,16 @@
1
+ import { type RefObject } from 'react';
2
+ interface DropdownMenuContext {
3
+ returnFocusRef: RefObject<HTMLElement> | null;
4
+ }
5
+ declare const DropdownMenuContext: import("react").Context<DropdownMenuContext | undefined>;
6
+ /**
7
+ * __Dropdown menu provider__
8
+ *
9
+ * A dropdown menu provider {description}.
10
+ *
11
+ * - [Examples](https://atlassian.design/components/{packageName}/examples)
12
+ * - [Code](https://atlassian.design/components/{packageName}/code)
13
+ * - [Usage](https://atlassian.design/components/{packageName}/usage)
14
+ */
15
+ export declare const DropdownMenuProvider: import("react").Provider<DropdownMenuContext | undefined>;
16
+ export {};
@@ -238,6 +238,10 @@ export interface DropdownItemProps {
238
238
  * Marked as "unsafe" because ideally, router links should be used for all internal links.
239
239
  */
240
240
  UNSAFE_shouldDisableRouterLink?: boolean;
241
+ /**
242
+ * If ref is passed, focus returns to that specific ref element after dropdown item clicked.
243
+ */
244
+ returnFocusRef?: RefObject<HTMLElement>;
241
245
  }
242
246
  export interface DropdownItemCheckboxProps {
243
247
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/dropdown-menu",
3
- "version": "12.17.2",
3
+ "version": "12.18.0",
4
4
  "description": "A dropdown menu displays a list of actions or options to a user.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -27,21 +27,20 @@
27
27
  "runReact18": true
28
28
  },
29
29
  "dependencies": {
30
- "@atlaskit/button": "^20.0.0",
30
+ "@atlaskit/button": "^20.1.0",
31
31
  "@atlaskit/codemod-utils": "^4.2.0",
32
- "@atlaskit/ds-lib": "^2.4.0",
33
- "@atlaskit/icon": "^22.13.0",
32
+ "@atlaskit/ds-lib": "^2.5.0",
33
+ "@atlaskit/icon": "^22.15.0",
34
34
  "@atlaskit/layering": "^0.4.0",
35
35
  "@atlaskit/menu": "^2.12.0",
36
- "@atlaskit/popup": "^1.22.0",
36
+ "@atlaskit/popup": "^1.23.0",
37
37
  "@atlaskit/primitives": "^12.0.0",
38
38
  "@atlaskit/spinner": "^16.3.0",
39
39
  "@atlaskit/theme": "^13.0.0",
40
- "@atlaskit/tokens": "^1.58.0",
40
+ "@atlaskit/tokens": "^1.59.0",
41
41
  "@babel/runtime": "^7.0.0",
42
42
  "@emotion/react": "^11.7.1",
43
- "bind-event-listener": "^3.0.0",
44
- "react-uid": "^2.2.0"
43
+ "bind-event-listener": "^3.0.0"
45
44
  },
46
45
  "peerDependencies": {
47
46
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0",