@atlaskit/popup 4.10.0 → 4.11.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,17 @@
1
1
  # @atlaskit/popup
2
2
 
3
+ ## 4.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`6f95ec25daa67`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6f95ec25daa67) -
8
+ Fixes to accessibility issues for the flyout menu.
9
+
10
+ This includes changing the `aria-haspopup` value from `"true"` to `"dialog"`, setting the `role`
11
+ of the popup container to `"dialog"`, adding an `aria-labelledby` to the popup container to
12
+ reference the `id` of the title in the header slot, and ensuring that escape dismisses the dialog
13
+ and places focus back on the trigger.
14
+
3
15
  ## 4.10.0
4
16
 
5
17
  ### Minor Changes
@@ -13,6 +13,7 @@ var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
13
13
  var _useId = require("@atlaskit/ds-lib/use-id");
14
14
  var _layering = require("@atlaskit/layering");
15
15
  var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
16
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
17
  var _popper = require("@atlaskit/popper");
17
18
  var _portal = _interopRequireDefault(require("@atlaskit/portal"));
18
19
  var _popperWrapper = _interopRequireDefault(require("../popper-wrapper"));
@@ -24,6 +25,7 @@ var IdContext = /*#__PURE__*/(0, _react.createContext)(undefined);
24
25
  var TriggerRefContext = /*#__PURE__*/(0, _react.createContext)(null);
25
26
  var SetTriggerRefContext = /*#__PURE__*/(0, _react.createContext)(_noop.default);
26
27
  var EnsureIsInsidePopupContext = /*#__PURE__*/(0, _react.createContext)(false);
28
+ var RoleContext = /*#__PURE__*/(0, _react.createContext)(undefined);
27
29
 
28
30
  // Used to ensure popup sub-components are used within a Popup
29
31
  // and provide a useful error message if not.
@@ -54,14 +56,17 @@ var Popup = exports.Popup = function Popup(_ref) {
54
56
  var children = _ref.children,
55
57
  providedId = _ref.id,
56
58
  _ref$isOpen = _ref.isOpen,
57
- isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen;
59
+ isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen,
60
+ role = _ref.role;
58
61
  var _useState = (0, _react.useState)(null),
59
62
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
60
63
  triggerRef = _useState2[0],
61
64
  setTriggerRef = _useState2[1];
62
65
  var generatedId = (0, _useId.useId)();
63
66
  var id = providedId || generatedId;
64
- return /*#__PURE__*/_react.default.createElement(EnsureIsInsidePopupContext.Provider, {
67
+ return /*#__PURE__*/_react.default.createElement(RoleContext.Provider, {
68
+ value: role
69
+ }, /*#__PURE__*/_react.default.createElement(EnsureIsInsidePopupContext.Provider, {
65
70
  value: true
66
71
  }, /*#__PURE__*/_react.default.createElement(IdContext.Provider, {
67
72
  value: id
@@ -71,7 +76,7 @@ var Popup = exports.Popup = function Popup(_ref) {
71
76
  value: setTriggerRef
72
77
  }, /*#__PURE__*/_react.default.createElement(IsOpenContext.Provider, {
73
78
  value: isOpen
74
- }, /*#__PURE__*/_react.default.createElement(_popper.Manager, null, children))))));
79
+ }, /*#__PURE__*/_react.default.createElement(_popper.Manager, null, children)))))));
75
80
  };
76
81
  /**
77
82
  * __Popup trigger__
@@ -87,13 +92,14 @@ var PopupTrigger = exports.PopupTrigger = function PopupTrigger(_ref2) {
87
92
  var setTriggerRef = (0, _react.useContext)(SetTriggerRefContext);
88
93
  var isOpen = (0, _react.useContext)(IsOpenContext);
89
94
  var getMergedTriggerRef = (0, _useGetMemoizedMergedTriggerRefNew.useGetMemoizedMergedTriggerRefNew)();
95
+ var role = (0, _react.useContext)(RoleContext);
90
96
  return /*#__PURE__*/_react.default.createElement(_popper.Reference, null, function (_ref3) {
91
97
  var ref = _ref3.ref;
92
98
  return children({
93
99
  ref: getMergedTriggerRef(ref, setTriggerRef),
94
100
  'aria-controls': id,
95
101
  'aria-expanded': isOpen,
96
- 'aria-haspopup': true
102
+ 'aria-haspopup': role === 'dialog' && (0, _platformFeatureFlags.fg)('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : true
97
103
  });
98
104
  });
99
105
  };
@@ -148,7 +154,9 @@ var PopupContent = exports.PopupContent = function PopupContent(_ref4) {
148
154
  shouldFitContainer = _ref4.shouldFitContainer,
149
155
  shouldFitViewport = _ref4.shouldFitViewport,
150
156
  _ref4$shouldDisableGp = _ref4.shouldDisableGpuAcceleration,
151
- shouldDisableGpuAcceleration = _ref4$shouldDisableGp === void 0 ? false : _ref4$shouldDisableGp;
157
+ shouldDisableGpuAcceleration = _ref4$shouldDisableGp === void 0 ? false : _ref4$shouldDisableGp,
158
+ role = _ref4.role,
159
+ titleId = _ref4.titleId;
152
160
  useEnsureIsInsidePopup();
153
161
  var isOpen = (0, _react.useContext)(IsOpenContext);
154
162
  var id = (0, _react.useContext)(IdContext);
@@ -195,7 +203,9 @@ var PopupContent = exports.PopupContent = function PopupContent(_ref4) {
195
203
  triggerRef: triggerRef,
196
204
  strategy: strategy,
197
205
  shouldFitViewport: shouldFitViewport,
198
- modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined
206
+ modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined,
207
+ role: role,
208
+ titleId: titleId
199
209
  }));
200
210
  if (shouldRenderToParent) {
201
211
  return popperWrapper;
@@ -4,6 +4,7 @@ import noop from '@atlaskit/ds-lib/noop';
4
4
  import { useId } from '@atlaskit/ds-lib/use-id';
5
5
  import { Layering } from '@atlaskit/layering';
6
6
  import { useNotifyOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
7
+ import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { Manager, Reference } from '@atlaskit/popper';
8
9
  import Portal from '@atlaskit/portal';
9
10
  import PopperWrapper from '../popper-wrapper';
@@ -14,6 +15,7 @@ const IdContext = /*#__PURE__*/createContext(undefined);
14
15
  const TriggerRefContext = /*#__PURE__*/createContext(null);
15
16
  const SetTriggerRefContext = /*#__PURE__*/createContext(noop);
16
17
  const EnsureIsInsidePopupContext = /*#__PURE__*/createContext(false);
18
+ const RoleContext = /*#__PURE__*/createContext(undefined);
17
19
 
18
20
  // Used to ensure popup sub-components are used within a Popup
19
21
  // and provide a useful error message if not.
@@ -43,12 +45,15 @@ const useEnsureIsInsidePopup = () => {
43
45
  export const Popup = ({
44
46
  children,
45
47
  id: providedId,
46
- isOpen = false
48
+ isOpen = false,
49
+ role
47
50
  }) => {
48
51
  const [triggerRef, setTriggerRef] = useState(null);
49
52
  const generatedId = useId();
50
53
  const id = providedId || generatedId;
51
- return /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
54
+ return /*#__PURE__*/React.createElement(RoleContext.Provider, {
55
+ value: role
56
+ }, /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
52
57
  value: true
53
58
  }, /*#__PURE__*/React.createElement(IdContext.Provider, {
54
59
  value: id
@@ -58,7 +63,7 @@ export const Popup = ({
58
63
  value: setTriggerRef
59
64
  }, /*#__PURE__*/React.createElement(IsOpenContext.Provider, {
60
65
  value: isOpen
61
- }, /*#__PURE__*/React.createElement(Manager, null, children))))));
66
+ }, /*#__PURE__*/React.createElement(Manager, null, children)))))));
62
67
  };
63
68
  /**
64
69
  * __Popup trigger__
@@ -75,13 +80,14 @@ export const PopupTrigger = ({
75
80
  const setTriggerRef = useContext(SetTriggerRefContext);
76
81
  const isOpen = useContext(IsOpenContext);
77
82
  const getMergedTriggerRef = useGetMemoizedMergedTriggerRefNew();
83
+ const role = useContext(RoleContext);
78
84
  return /*#__PURE__*/React.createElement(Reference, null, ({
79
85
  ref
80
86
  }) => children({
81
87
  ref: getMergedTriggerRef(ref, setTriggerRef),
82
88
  'aria-controls': id,
83
89
  'aria-expanded': isOpen,
84
- 'aria-haspopup': true
90
+ 'aria-haspopup': role === 'dialog' && fg('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : true
85
91
  }));
86
92
  };
87
93
  const defaultLayer = 400;
@@ -126,7 +132,9 @@ export const PopupContent = ({
126
132
  shouldDisableFocusLock = false,
127
133
  shouldFitContainer,
128
134
  shouldFitViewport,
129
- shouldDisableGpuAcceleration = false
135
+ shouldDisableGpuAcceleration = false,
136
+ role,
137
+ titleId
130
138
  }) => {
131
139
  useEnsureIsInsidePopup();
132
140
  const isOpen = useContext(IsOpenContext);
@@ -175,7 +183,9 @@ export const PopupContent = ({
175
183
  triggerRef: triggerRef,
176
184
  strategy: strategy,
177
185
  shouldFitViewport: shouldFitViewport,
178
- modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined
186
+ modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined,
187
+ role: role,
188
+ titleId: titleId
179
189
  }));
180
190
  if (shouldRenderToParent) {
181
191
  return popperWrapper;
@@ -5,6 +5,7 @@ import noop from '@atlaskit/ds-lib/noop';
5
5
  import { useId } from '@atlaskit/ds-lib/use-id';
6
6
  import { Layering } from '@atlaskit/layering';
7
7
  import { useNotifyOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { Manager, Reference } from '@atlaskit/popper';
9
10
  import Portal from '@atlaskit/portal';
10
11
  import PopperWrapper from '../popper-wrapper';
@@ -15,6 +16,7 @@ var IdContext = /*#__PURE__*/createContext(undefined);
15
16
  var TriggerRefContext = /*#__PURE__*/createContext(null);
16
17
  var SetTriggerRefContext = /*#__PURE__*/createContext(noop);
17
18
  var EnsureIsInsidePopupContext = /*#__PURE__*/createContext(false);
19
+ var RoleContext = /*#__PURE__*/createContext(undefined);
18
20
 
19
21
  // Used to ensure popup sub-components are used within a Popup
20
22
  // and provide a useful error message if not.
@@ -45,14 +47,17 @@ export var Popup = function Popup(_ref) {
45
47
  var children = _ref.children,
46
48
  providedId = _ref.id,
47
49
  _ref$isOpen = _ref.isOpen,
48
- isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen;
50
+ isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen,
51
+ role = _ref.role;
49
52
  var _useState = useState(null),
50
53
  _useState2 = _slicedToArray(_useState, 2),
51
54
  triggerRef = _useState2[0],
52
55
  setTriggerRef = _useState2[1];
53
56
  var generatedId = useId();
54
57
  var id = providedId || generatedId;
55
- return /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
58
+ return /*#__PURE__*/React.createElement(RoleContext.Provider, {
59
+ value: role
60
+ }, /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
56
61
  value: true
57
62
  }, /*#__PURE__*/React.createElement(IdContext.Provider, {
58
63
  value: id
@@ -62,7 +67,7 @@ export var Popup = function Popup(_ref) {
62
67
  value: setTriggerRef
63
68
  }, /*#__PURE__*/React.createElement(IsOpenContext.Provider, {
64
69
  value: isOpen
65
- }, /*#__PURE__*/React.createElement(Manager, null, children))))));
70
+ }, /*#__PURE__*/React.createElement(Manager, null, children)))))));
66
71
  };
67
72
  /**
68
73
  * __Popup trigger__
@@ -78,13 +83,14 @@ export var PopupTrigger = function PopupTrigger(_ref2) {
78
83
  var setTriggerRef = useContext(SetTriggerRefContext);
79
84
  var isOpen = useContext(IsOpenContext);
80
85
  var getMergedTriggerRef = useGetMemoizedMergedTriggerRefNew();
86
+ var role = useContext(RoleContext);
81
87
  return /*#__PURE__*/React.createElement(Reference, null, function (_ref3) {
82
88
  var ref = _ref3.ref;
83
89
  return children({
84
90
  ref: getMergedTriggerRef(ref, setTriggerRef),
85
91
  'aria-controls': id,
86
92
  'aria-expanded': isOpen,
87
- 'aria-haspopup': true
93
+ 'aria-haspopup': role === 'dialog' && fg('platform_dst_nav4_flyout_menu_slots_close_button') ? 'dialog' : true
88
94
  });
89
95
  });
90
96
  };
@@ -139,7 +145,9 @@ export var PopupContent = function PopupContent(_ref4) {
139
145
  shouldFitContainer = _ref4.shouldFitContainer,
140
146
  shouldFitViewport = _ref4.shouldFitViewport,
141
147
  _ref4$shouldDisableGp = _ref4.shouldDisableGpuAcceleration,
142
- shouldDisableGpuAcceleration = _ref4$shouldDisableGp === void 0 ? false : _ref4$shouldDisableGp;
148
+ shouldDisableGpuAcceleration = _ref4$shouldDisableGp === void 0 ? false : _ref4$shouldDisableGp,
149
+ role = _ref4.role,
150
+ titleId = _ref4.titleId;
143
151
  useEnsureIsInsidePopup();
144
152
  var isOpen = useContext(IsOpenContext);
145
153
  var id = useContext(IdContext);
@@ -186,7 +194,9 @@ export var PopupContent = function PopupContent(_ref4) {
186
194
  triggerRef: triggerRef,
187
195
  strategy: strategy,
188
196
  shouldFitViewport: shouldFitViewport,
189
- modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined
197
+ modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined,
198
+ role: role,
199
+ titleId: titleId
190
200
  }));
191
201
  if (shouldRenderToParent) {
192
202
  return popperWrapper;
@@ -4,6 +4,7 @@ export type PopupProps = {
4
4
  children: React.ReactNode;
5
5
  isOpen?: boolean;
6
6
  id?: string;
7
+ role?: 'dialog';
7
8
  };
8
9
  /**
9
10
  * __Popup__
@@ -24,7 +25,7 @@ export type PopupProps = {
24
25
  * </Popup>
25
26
  * ```
26
27
  */
27
- export declare const Popup: ({ children, id: providedId, isOpen, }: PopupProps) => React.JSX.Element;
28
+ export declare const Popup: ({ children, id: providedId, isOpen, role }: PopupProps) => React.JSX.Element;
28
29
  export type PopupTriggerProps = {
29
30
  children: (props: TriggerProps) => React.ReactNode;
30
31
  };
@@ -36,7 +37,7 @@ export type PopupTriggerProps = {
36
37
  * It must be a child of the Popup component.
37
38
  */
38
39
  export declare const PopupTrigger: ({ children }: PopupTriggerProps) => React.JSX.Element;
39
- type CommonContentPopupProps = Pick<LegacyPopupProps, 'xcss' | 'appearance' | 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport'> & {
40
+ type CommonContentPopupProps = Pick<LegacyPopupProps, 'xcss' | 'appearance' | 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport' | 'role' | 'titleId'> & {
40
41
  children: (props: ContentProps) => React.ReactNode;
41
42
  /**
42
43
  * ___Use with caution___
@@ -67,5 +68,5 @@ export type PopupContentProps = ShouldFitContainerContentPopupProps | StandardPo
67
68
  *
68
69
  * It must be a child of the Popup component.
69
70
  */
70
- export declare const PopupContent: ({ xcss, appearance: inAppearance, children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent: inShouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, shouldDisableGpuAcceleration, }: PopupContentProps) => React.JSX.Element | null;
71
+ export declare const PopupContent: ({ xcss, appearance: inAppearance, children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent: inShouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, shouldDisableGpuAcceleration, role, titleId }: PopupContentProps) => React.JSX.Element | null;
71
72
  export {};
@@ -4,6 +4,7 @@ export type PopupProps = {
4
4
  children: React.ReactNode;
5
5
  isOpen?: boolean;
6
6
  id?: string;
7
+ role?: 'dialog';
7
8
  };
8
9
  /**
9
10
  * __Popup__
@@ -24,7 +25,7 @@ export type PopupProps = {
24
25
  * </Popup>
25
26
  * ```
26
27
  */
27
- export declare const Popup: ({ children, id: providedId, isOpen, }: PopupProps) => React.JSX.Element;
28
+ export declare const Popup: ({ children, id: providedId, isOpen, role }: PopupProps) => React.JSX.Element;
28
29
  export type PopupTriggerProps = {
29
30
  children: (props: TriggerProps) => React.ReactNode;
30
31
  };
@@ -36,7 +37,7 @@ export type PopupTriggerProps = {
36
37
  * It must be a child of the Popup component.
37
38
  */
38
39
  export declare const PopupTrigger: ({ children }: PopupTriggerProps) => React.JSX.Element;
39
- type CommonContentPopupProps = Pick<LegacyPopupProps, 'xcss' | 'appearance' | 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport'> & {
40
+ type CommonContentPopupProps = Pick<LegacyPopupProps, 'xcss' | 'appearance' | 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport' | 'role' | 'titleId'> & {
40
41
  children: (props: ContentProps) => React.ReactNode;
41
42
  /**
42
43
  * ___Use with caution___
@@ -67,5 +68,5 @@ export type PopupContentProps = ShouldFitContainerContentPopupProps | StandardPo
67
68
  *
68
69
  * It must be a child of the Popup component.
69
70
  */
70
- export declare const PopupContent: ({ xcss, appearance: inAppearance, children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent: inShouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, shouldDisableGpuAcceleration, }: PopupContentProps) => React.JSX.Element | null;
71
+ export declare const PopupContent: ({ xcss, appearance: inAppearance, children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent: inShouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, shouldDisableGpuAcceleration, role, titleId }: PopupContentProps) => React.JSX.Element | null;
71
72
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/popup",
3
- "version": "4.10.0",
3
+ "version": "4.11.0",
4
4
  "description": "A popup displays brief content in an overlay.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -61,7 +61,7 @@
61
61
  "@atlaskit/form": "^15.2.0",
62
62
  "@atlaskit/heading": "^5.2.0",
63
63
  "@atlaskit/icon": "^29.3.0",
64
- "@atlaskit/link": "^3.2.0",
64
+ "@atlaskit/link": "^3.3.0",
65
65
  "@atlaskit/modal-dialog": "^14.9.0",
66
66
  "@atlaskit/section-message": "^8.11.0",
67
67
  "@atlaskit/textfield": "^8.2.0",
@@ -116,6 +116,9 @@
116
116
  },
117
117
  "platform-dst-shape-theme-default": {
118
118
  "type": "boolean"
119
+ },
120
+ "platform_dst_nav4_flyout_menu_slots_close_button": {
121
+ "type": "boolean"
119
122
  }
120
123
  },
121
124
  "homepage": "https://atlassian.design/components/popup/"