@atlaskit/dropdown-menu 12.14.2 → 12.15.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,14 @@
1
1
  # @atlaskit/dropdown-menu
2
2
 
3
+ ## 12.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#126129](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/126129)
8
+ [`75d153a575b4d`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/75d153a575b4d) -
9
+ Accessibility changes. Add a new optional prop `returnFocusRef` for cases when we need to focus an
10
+ interactive element after closing DropdownMenu.
11
+
3
12
  ## 12.14.2
4
13
 
5
14
  ### Patch Changes
@@ -91,6 +91,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
91
91
  shouldFlip = _ref$shouldFlip === void 0 ? true : _ref$shouldFlip,
92
92
  _ref$shouldRenderToPa = _ref.shouldRenderToParent,
93
93
  shouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
94
+ returnFocusRef = _ref.returnFocusRef,
94
95
  spacing = _ref.spacing,
95
96
  statusLabel = _ref.statusLabel,
96
97
  testId = _ref.testId,
@@ -154,7 +155,16 @@ var DropdownMenu = function DropdownMenu(_ref) {
154
155
  // Dropdown can be closed by pressing Escape, Tab or Shift + Tab
155
156
  return;
156
157
  }
157
- if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
158
+
159
+ // transfer focus to the element specified by ref
160
+ // if ref is not provided, use old behavior:
161
+ // focus on trigger when <Esc> or <Shift+Tab> is pressed
162
+ if (returnFocusRef) {
163
+ requestAnimationFrame(function () {
164
+ var _returnFocusRef$curre;
165
+ (_returnFocusRef$curre = returnFocusRef.current) === null || _returnFocusRef$curre === void 0 || _returnFocusRef$curre.focus();
166
+ });
167
+ } else if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
158
168
  requestAnimationFrame(function () {
159
169
  var _itemRef$current2;
160
170
  (_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
@@ -166,7 +176,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
166
176
  isOpen: newValue,
167
177
  event: event
168
178
  });
169
- }, [onOpenChange, setLocalIsOpen, itemRef]);
179
+ }, [itemRef, onOpenChange, returnFocusRef, setLocalIsOpen]);
170
180
  var _useFocus = (0, _useFocusEvent.default)(),
171
181
  isFocused = _useFocus.isFocused,
172
182
  bindFocus = _useFocus.bindFocus;
@@ -9,8 +9,8 @@ var _colors = require("@atlaskit/theme/colors");
9
9
  var _typography = require("@atlaskit/theme/typography");
10
10
  /**
11
11
  * @jsxRuntime classic
12
+ * @jsx jsx
12
13
  */
13
- /** @jsx jsx */
14
14
 
15
15
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
16
16
 
@@ -15,8 +15,8 @@ var _isCheckboxItem = _interopRequireDefault(require("../utils/is-checkbox-item"
15
15
  var _isRadioItem = _interopRequireDefault(require("../utils/is-radio-item"));
16
16
  /**
17
17
  * @jsxRuntime classic
18
+ * @jsx jsx
18
19
  */
19
- /** @jsx jsx */
20
20
 
21
21
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
22
22
 
@@ -67,6 +67,7 @@ const DropdownMenu = ({
67
67
  shouldFitContainer = false,
68
68
  shouldFlip = true,
69
69
  shouldRenderToParent = false,
70
+ returnFocusRef,
70
71
  spacing,
71
72
  statusLabel,
72
73
  testId,
@@ -122,7 +123,16 @@ const DropdownMenu = ({
122
123
  // Dropdown can be closed by pressing Escape, Tab or Shift + Tab
123
124
  return;
124
125
  }
125
- if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
126
+
127
+ // transfer focus to the element specified by ref
128
+ // if ref is not provided, use old behavior:
129
+ // focus on trigger when <Esc> or <Shift+Tab> is pressed
130
+ if (returnFocusRef) {
131
+ requestAnimationFrame(() => {
132
+ var _returnFocusRef$curre;
133
+ (_returnFocusRef$curre = returnFocusRef.current) === null || _returnFocusRef$curre === void 0 ? void 0 : _returnFocusRef$curre.focus();
134
+ });
135
+ } else if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
126
136
  requestAnimationFrame(() => {
127
137
  var _itemRef$current2;
128
138
  (_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 ? void 0 : _itemRef$current2.focus();
@@ -134,7 +144,7 @@ const DropdownMenu = ({
134
144
  isOpen: newValue,
135
145
  event
136
146
  });
137
- }, [onOpenChange, setLocalIsOpen, itemRef]);
147
+ }, [itemRef, onOpenChange, returnFocusRef, setLocalIsOpen]);
138
148
  const {
139
149
  isFocused,
140
150
  bindFocus
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @jsxRuntime classic
3
+ * @jsx jsx
3
4
  */
4
- /** @jsx jsx */
5
5
 
6
6
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
7
7
  import { css, jsx } from '@emotion/react';
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @jsxRuntime classic
3
+ * @jsx jsx
3
4
  */
4
- /** @jsx jsx */
5
5
  import { useContext, useEffect, useLayoutEffect } from 'react';
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
@@ -81,6 +81,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
81
81
  shouldFlip = _ref$shouldFlip === void 0 ? true : _ref$shouldFlip,
82
82
  _ref$shouldRenderToPa = _ref.shouldRenderToParent,
83
83
  shouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
84
+ returnFocusRef = _ref.returnFocusRef,
84
85
  spacing = _ref.spacing,
85
86
  statusLabel = _ref.statusLabel,
86
87
  testId = _ref.testId,
@@ -144,7 +145,16 @@ var DropdownMenu = function DropdownMenu(_ref) {
144
145
  // Dropdown can be closed by pressing Escape, Tab or Shift + Tab
145
146
  return;
146
147
  }
147
- if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
148
+
149
+ // transfer focus to the element specified by ref
150
+ // if ref is not provided, use old behavior:
151
+ // focus on trigger when <Esc> or <Shift+Tab> is pressed
152
+ if (returnFocusRef) {
153
+ requestAnimationFrame(function () {
154
+ var _returnFocusRef$curre;
155
+ (_returnFocusRef$curre = returnFocusRef.current) === null || _returnFocusRef$curre === void 0 || _returnFocusRef$curre.focus();
156
+ });
157
+ } else if (event.key === 'Tab' && event.shiftKey || event.key === 'Escape') {
148
158
  requestAnimationFrame(function () {
149
159
  var _itemRef$current2;
150
160
  (_itemRef$current2 = itemRef.current) === null || _itemRef$current2 === void 0 || _itemRef$current2.focus();
@@ -156,7 +166,7 @@ var DropdownMenu = function DropdownMenu(_ref) {
156
166
  isOpen: newValue,
157
167
  event: event
158
168
  });
159
- }, [onOpenChange, setLocalIsOpen, itemRef]);
169
+ }, [itemRef, onOpenChange, returnFocusRef, setLocalIsOpen]);
160
170
  var _useFocus = useFocus(),
161
171
  isFocused = _useFocus.isFocused,
162
172
  bindFocus = _useFocus.bindFocus;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @jsxRuntime classic
3
+ * @jsx jsx
3
4
  */
4
- /** @jsx jsx */
5
5
 
6
6
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
7
7
  import { css, jsx } from '@emotion/react';
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @jsxRuntime classic
3
+ * @jsx jsx
3
4
  */
4
- /** @jsx jsx */
5
5
  import { useContext, useEffect, useLayoutEffect } from 'react';
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
@@ -9,5 +9,5 @@ import type { DropdownMenuProps } from './types';
9
9
  * - [Code](https://atlassian.design/components/dropdown-menu/code)
10
10
  * - [Usage](https://atlassian.design/components/dropdown-menu/usage)
11
11
  */
12
- declare const DropdownMenu: <T extends HTMLElement = any>({ autoFocus, children, defaultOpen, isLoading, isOpen, onOpenChange, placement, shouldFitContainer, shouldFlip, shouldRenderToParent, spacing, statusLabel, testId, trigger, zIndex, label, }: DropdownMenuProps<T>) => JSX.Element;
12
+ declare const DropdownMenu: <T extends HTMLElement = any>({ autoFocus, children, defaultOpen, isLoading, isOpen, onOpenChange, placement, shouldFitContainer, shouldFlip, shouldRenderToParent, returnFocusRef, spacing, statusLabel, testId, trigger, zIndex, label, }: DropdownMenuProps<T>) => JSX.Element;
13
13
  export default DropdownMenu;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @jsxRuntime classic
3
+ * @jsx jsx
3
4
  */
4
- /** @jsx jsx */
5
5
  import { jsx } from '@emotion/react';
6
6
  /**
7
7
  * __Group title__
@@ -1,4 +1,4 @@
1
- import { type KeyboardEvent, type MouseEvent, type ReactElement, type ReactNode, type Ref } from 'react';
1
+ import { type KeyboardEvent, type MouseEvent, type ReactElement, type ReactNode, type Ref, type RefObject } from 'react';
2
2
  import type { CustomItemComponentProps, CustomItemProps, MenuGroupProps, SectionProps } from '@atlaskit/menu/types';
3
3
  import type { ContentProps, TriggerProps } from '@atlaskit/popup/types';
4
4
  export type FocusableElement = HTMLAnchorElement | HTMLButtonElement;
@@ -150,6 +150,10 @@ interface InternalDropdownMenuProps<TriggerElement extends HTMLElement = any> {
150
150
  * Provide an accessible label via `aria-label` for assistive technology.
151
151
  */
152
152
  label?: string;
153
+ /**
154
+ * If ref is passed, focus returns to that specific ref element after dropdown dismissed.
155
+ */
156
+ returnFocusRef?: RefObject<HTMLElement>;
153
157
  }
154
158
  type StandardDropdownMenuProps<TriggerElement extends HTMLElement = any> = InternalDropdownMenuProps<TriggerElement> & {
155
159
  shouldFitContainer?: false;
@@ -9,5 +9,5 @@ import type { DropdownMenuProps } from './types';
9
9
  * - [Code](https://atlassian.design/components/dropdown-menu/code)
10
10
  * - [Usage](https://atlassian.design/components/dropdown-menu/usage)
11
11
  */
12
- declare const DropdownMenu: <T extends HTMLElement = any>({ autoFocus, children, defaultOpen, isLoading, isOpen, onOpenChange, placement, shouldFitContainer, shouldFlip, shouldRenderToParent, spacing, statusLabel, testId, trigger, zIndex, label, }: DropdownMenuProps<T>) => JSX.Element;
12
+ declare const DropdownMenu: <T extends HTMLElement = any>({ autoFocus, children, defaultOpen, isLoading, isOpen, onOpenChange, placement, shouldFitContainer, shouldFlip, shouldRenderToParent, returnFocusRef, spacing, statusLabel, testId, trigger, zIndex, label, }: DropdownMenuProps<T>) => JSX.Element;
13
13
  export default DropdownMenu;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @jsxRuntime classic
3
+ * @jsx jsx
3
4
  */
4
- /** @jsx jsx */
5
5
  import { jsx } from '@emotion/react';
6
6
  /**
7
7
  * __Group title__
@@ -1,4 +1,4 @@
1
- import { type KeyboardEvent, type MouseEvent, type ReactElement, type ReactNode, type Ref } from 'react';
1
+ import { type KeyboardEvent, type MouseEvent, type ReactElement, type ReactNode, type Ref, type RefObject } from 'react';
2
2
  import type { CustomItemComponentProps, CustomItemProps, MenuGroupProps, SectionProps } from '@atlaskit/menu/types';
3
3
  import type { ContentProps, TriggerProps } from '@atlaskit/popup/types';
4
4
  export type FocusableElement = HTMLAnchorElement | HTMLButtonElement;
@@ -150,6 +150,10 @@ interface InternalDropdownMenuProps<TriggerElement extends HTMLElement = any> {
150
150
  * Provide an accessible label via `aria-label` for assistive technology.
151
151
  */
152
152
  label?: string;
153
+ /**
154
+ * If ref is passed, focus returns to that specific ref element after dropdown dismissed.
155
+ */
156
+ returnFocusRef?: RefObject<HTMLElement>;
153
157
  }
154
158
  type StandardDropdownMenuProps<TriggerElement extends HTMLElement = any> = InternalDropdownMenuProps<TriggerElement> & {
155
159
  shouldFitContainer?: false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/dropdown-menu",
3
- "version": "12.14.2",
3
+ "version": "12.15.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,14 +27,14 @@
27
27
  "runReact18": true
28
28
  },
29
29
  "dependencies": {
30
- "@atlaskit/button": "^19.0.0",
30
+ "@atlaskit/button": "^19.1.0",
31
31
  "@atlaskit/codemod-utils": "^4.2.0",
32
32
  "@atlaskit/ds-lib": "^2.3.0",
33
- "@atlaskit/icon": "^22.6.0",
33
+ "@atlaskit/icon": "^22.8.0",
34
34
  "@atlaskit/layering": "^0.3.0",
35
- "@atlaskit/menu": "^2.8.0",
35
+ "@atlaskit/menu": "^2.9.0",
36
36
  "@atlaskit/popup": "^1.20.0",
37
- "@atlaskit/primitives": "^11.0.0",
37
+ "@atlaskit/primitives": "^11.1.0",
38
38
  "@atlaskit/spinner": "^16.2.0",
39
39
  "@atlaskit/theme": "^12.11.0",
40
40
  "@atlaskit/tokens": "^1.56.0",