carbon-react 125.1.0 → 125.2.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.
@@ -11,6 +11,8 @@ import createGuid from "../../__internal__/utils/helpers/guid";
11
11
  import { filterStyledSystemPaddingProps } from "../../style/utils";
12
12
  import useClickAwayListener from "../../hooks/__internal__/useClickAwayListener";
13
13
  import Events from "../../__internal__/utils/helpers/events";
14
+ import FocusTrap from "../../__internal__/focus-trap";
15
+ import { ModalContext } from "../modal";
14
16
  export const renderOpen = ({
15
17
  tabIndex,
16
18
  onClick,
@@ -81,19 +83,20 @@ export const PopoverContainer = ({
81
83
  const popoverContainerId = title ? `PopoverContainer_${guid.current}` : undefined;
82
84
  const isOpen = isControlled ? open : isOpenInternal;
83
85
  const reduceMotion = !useMediaQuery("screen and (prefers-reduced-motion: no-preference)");
84
- useEffect(() => {
85
- if (isOpen && closeButtonRef.current) setTimeout(() => closeButtonRef.current?.focus(), 0);
86
- }, [isOpen]);
87
86
  const closePopover = useCallback(ev => {
88
- if (!isControlled) setIsOpenInternal(!isOpen);
87
+ if (!isControlled) setIsOpenInternal(false);
89
88
  if (onClose) onClose(ev);
90
- if (isOpen && openButtonRef.current) openButtonRef.current.focus();
89
+ if (isOpen && openButtonRef.current) {
90
+ openButtonRef.current.focus();
91
+ }
91
92
  }, [isControlled, isOpen, onClose]);
92
93
  const handleEscKey = useCallback(ev => {
93
94
  const eventIsFromSelectInput = Events.composedPath(ev).find(element => {
94
95
  return element instanceof HTMLElement && element.getAttribute("data-element") === "input" && element.getAttribute("aria-expanded") === "true";
95
96
  });
96
- if (!eventIsFromSelectInput && Events.isEscKey(ev)) closePopover(ev);
97
+ if (!eventIsFromSelectInput && Events.isEscKey(ev)) {
98
+ closePopover(ev);
99
+ }
97
100
  }, [closePopover]);
98
101
  useEffect(() => {
99
102
  document.addEventListener("keydown", handleEscKey);
@@ -113,7 +116,7 @@ export const PopoverContainer = ({
113
116
  closePopover(e);
114
117
  };
115
118
  const renderOpenComponentProps = {
116
- tabIndex: isOpen ? -1 : 0,
119
+ tabIndex: 0,
117
120
  "aria-expanded": isOpen,
118
121
  "aria-haspopup": "dialog",
119
122
  isOpen,
@@ -135,12 +138,8 @@ export const PopoverContainer = ({
135
138
  if (onClose && isOpen) onClose(e);
136
139
  };
137
140
  const handleClick = useClickAwayListener(handleClickAway, "mousedown");
138
- return /*#__PURE__*/React.createElement(PopoverContainerWrapperStyle, {
139
- "data-component": "popover-container",
140
- onMouseDown: handleClick
141
- }, /*#__PURE__*/React.createElement("div", {
142
- ref: popoverReference
143
- }, renderOpenComponent(renderOpenComponentProps)), /*#__PURE__*/React.createElement(Transition, {
141
+ const [isAnimationComplete, setIsAnimationComplete] = useState(false);
142
+ const popover = /*#__PURE__*/React.createElement(Transition, {
144
143
  in: isOpen,
145
144
  timeout: {
146
145
  exit: 300
@@ -148,11 +147,14 @@ export const PopoverContainer = ({
148
147
  appear: true,
149
148
  mountOnEnter: true,
150
149
  unmountOnExit: true,
151
- nodeRef: popoverContentNodeRef
150
+ nodeRef: popoverContentNodeRef,
151
+ onEntered: shouldCoverButton ? /* istanbul ignore next */() => setIsAnimationComplete(true) : undefined,
152
+ onExiting: shouldCoverButton ? /* istanbul ignore next */() => setIsAnimationComplete(false) : undefined
152
153
  }, state => isOpen && /*#__PURE__*/React.createElement(Popover, _extends({
153
- popoverStrategy: disableAnimation || reduceMotion ? "fixed" : "absolute",
154
+ disablePortal: true,
154
155
  reference: popoverReference,
155
- placement: position === "right" ? "bottom-start" : "bottom-end"
156
+ placement: position === "right" ? "bottom-start" : "bottom-end",
157
+ popoverStrategy: disableAnimation || reduceMotion ? "fixed" : "absolute"
156
158
  }, shouldCoverButton && {
157
159
  middleware: popoverMiddleware
158
160
  }), /*#__PURE__*/React.createElement(PopoverContainerContentStyle, _extends({
@@ -164,10 +166,24 @@ export const PopoverContainer = ({
164
166
  "aria-describedby": ariaDescribedBy,
165
167
  p: "16px 24px",
166
168
  ref: popoverContentNodeRef,
169
+ tabIndex: shouldCoverButton ? -1 : undefined,
167
170
  disableAnimation: disableAnimation || reduceMotion
168
171
  }, filterStyledSystemPaddingProps(rest)), /*#__PURE__*/React.createElement(PopoverContainerHeaderStyle, null, /*#__PURE__*/React.createElement(PopoverContainerTitleStyle, {
169
172
  id: popoverContainerId,
170
173
  "data-element": "popover-container-title"
171
- }, title), renderCloseComponent(renderCloseComponentProps)), children))));
174
+ }, title), renderCloseComponent(renderCloseComponentProps)), children)));
175
+ return /*#__PURE__*/React.createElement(PopoverContainerWrapperStyle, {
176
+ "data-component": "popover-container",
177
+ onMouseDown: handleClick
178
+ }, /*#__PURE__*/React.createElement("div", {
179
+ ref: popoverReference
180
+ }, renderOpenComponent(renderOpenComponentProps)), shouldCoverButton ? /*#__PURE__*/React.createElement(ModalContext.Provider, {
181
+ value: {
182
+ isAnimationComplete
183
+ }
184
+ }, /*#__PURE__*/React.createElement(FocusTrap, {
185
+ wrapperRef: popoverContentNodeRef,
186
+ isOpen: isOpen
187
+ }, popover)) : popover);
172
188
  };
173
189
  export default PopoverContainer;
@@ -53,6 +53,10 @@ const PopoverContainerContentStyle = styled.div`
53
53
  }) => theme.zIndex.popover};
54
54
 
55
55
  ${animationToRender}
56
+
57
+ :focus {
58
+ outline: none;
59
+ }
56
60
  `;
57
61
  const PopoverContainerOpenIcon = styled(IconButton)`
58
62
  ${StyledIcon} {
@@ -16,6 +16,8 @@ var _guid = _interopRequireDefault(require("../../__internal__/utils/helpers/gui
16
16
  var _utils = require("../../style/utils");
17
17
  var _useClickAwayListener = _interopRequireDefault(require("../../hooks/__internal__/useClickAwayListener"));
18
18
  var _events = _interopRequireDefault(require("../../__internal__/utils/helpers/events"));
19
+ var _focusTrap = _interopRequireDefault(require("../../__internal__/focus-trap"));
20
+ var _modal = require("../modal");
19
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
22
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
21
23
  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; }
@@ -92,19 +94,20 @@ const PopoverContainer = ({
92
94
  const popoverContainerId = title ? `PopoverContainer_${guid.current}` : undefined;
93
95
  const isOpen = isControlled ? open : isOpenInternal;
94
96
  const reduceMotion = !(0, _useMediaQuery.default)("screen and (prefers-reduced-motion: no-preference)");
95
- (0, _react.useEffect)(() => {
96
- if (isOpen && closeButtonRef.current) setTimeout(() => closeButtonRef.current?.focus(), 0);
97
- }, [isOpen]);
98
97
  const closePopover = (0, _react.useCallback)(ev => {
99
- if (!isControlled) setIsOpenInternal(!isOpen);
98
+ if (!isControlled) setIsOpenInternal(false);
100
99
  if (onClose) onClose(ev);
101
- if (isOpen && openButtonRef.current) openButtonRef.current.focus();
100
+ if (isOpen && openButtonRef.current) {
101
+ openButtonRef.current.focus();
102
+ }
102
103
  }, [isControlled, isOpen, onClose]);
103
104
  const handleEscKey = (0, _react.useCallback)(ev => {
104
105
  const eventIsFromSelectInput = _events.default.composedPath(ev).find(element => {
105
106
  return element instanceof HTMLElement && element.getAttribute("data-element") === "input" && element.getAttribute("aria-expanded") === "true";
106
107
  });
107
- if (!eventIsFromSelectInput && _events.default.isEscKey(ev)) closePopover(ev);
108
+ if (!eventIsFromSelectInput && _events.default.isEscKey(ev)) {
109
+ closePopover(ev);
110
+ }
108
111
  }, [closePopover]);
109
112
  (0, _react.useEffect)(() => {
110
113
  document.addEventListener("keydown", handleEscKey);
@@ -124,7 +127,7 @@ const PopoverContainer = ({
124
127
  closePopover(e);
125
128
  };
126
129
  const renderOpenComponentProps = {
127
- tabIndex: isOpen ? -1 : 0,
130
+ tabIndex: 0,
128
131
  "aria-expanded": isOpen,
129
132
  "aria-haspopup": "dialog",
130
133
  isOpen,
@@ -146,12 +149,8 @@ const PopoverContainer = ({
146
149
  if (onClose && isOpen) onClose(e);
147
150
  };
148
151
  const handleClick = (0, _useClickAwayListener.default)(handleClickAway, "mousedown");
149
- return /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerWrapperStyle, {
150
- "data-component": "popover-container",
151
- onMouseDown: handleClick
152
- }, /*#__PURE__*/_react.default.createElement("div", {
153
- ref: popoverReference
154
- }, renderOpenComponent(renderOpenComponentProps)), /*#__PURE__*/_react.default.createElement(_reactTransitionGroup.Transition, {
152
+ const [isAnimationComplete, setIsAnimationComplete] = (0, _react.useState)(false);
153
+ const popover = /*#__PURE__*/_react.default.createElement(_reactTransitionGroup.Transition, {
155
154
  in: isOpen,
156
155
  timeout: {
157
156
  exit: 300
@@ -159,11 +158,14 @@ const PopoverContainer = ({
159
158
  appear: true,
160
159
  mountOnEnter: true,
161
160
  unmountOnExit: true,
162
- nodeRef: popoverContentNodeRef
161
+ nodeRef: popoverContentNodeRef,
162
+ onEntered: shouldCoverButton ? /* istanbul ignore next */() => setIsAnimationComplete(true) : undefined,
163
+ onExiting: shouldCoverButton ? /* istanbul ignore next */() => setIsAnimationComplete(false) : undefined
163
164
  }, state => isOpen && /*#__PURE__*/_react.default.createElement(_popover.default, _extends({
164
- popoverStrategy: disableAnimation || reduceMotion ? "fixed" : "absolute",
165
+ disablePortal: true,
165
166
  reference: popoverReference,
166
- placement: position === "right" ? "bottom-start" : "bottom-end"
167
+ placement: position === "right" ? "bottom-start" : "bottom-end",
168
+ popoverStrategy: disableAnimation || reduceMotion ? "fixed" : "absolute"
167
169
  }, shouldCoverButton && {
168
170
  middleware: popoverMiddleware
169
171
  }), /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerContentStyle, _extends({
@@ -175,11 +177,25 @@ const PopoverContainer = ({
175
177
  "aria-describedby": ariaDescribedBy,
176
178
  p: "16px 24px",
177
179
  ref: popoverContentNodeRef,
180
+ tabIndex: shouldCoverButton ? -1 : undefined,
178
181
  disableAnimation: disableAnimation || reduceMotion
179
182
  }, (0, _utils.filterStyledSystemPaddingProps)(rest)), /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerHeaderStyle, null, /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerTitleStyle, {
180
183
  id: popoverContainerId,
181
184
  "data-element": "popover-container-title"
182
- }, title), renderCloseComponent(renderCloseComponentProps)), children))));
185
+ }, title), renderCloseComponent(renderCloseComponentProps)), children)));
186
+ return /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerWrapperStyle, {
187
+ "data-component": "popover-container",
188
+ onMouseDown: handleClick
189
+ }, /*#__PURE__*/_react.default.createElement("div", {
190
+ ref: popoverReference
191
+ }, renderOpenComponent(renderOpenComponentProps)), shouldCoverButton ? /*#__PURE__*/_react.default.createElement(_modal.ModalContext.Provider, {
192
+ value: {
193
+ isAnimationComplete
194
+ }
195
+ }, /*#__PURE__*/_react.default.createElement(_focusTrap.default, {
196
+ wrapperRef: popoverContentNodeRef,
197
+ isOpen: isOpen
198
+ }, popover)) : popover);
183
199
  };
184
200
  exports.PopoverContainer = PopoverContainer;
185
201
  var _default = exports.default = PopoverContainer;
@@ -60,6 +60,10 @@ const PopoverContainerContentStyle = exports.PopoverContainerContentStyle = _sty
60
60
  }) => theme.zIndex.popover};
61
61
 
62
62
  ${animationToRender}
63
+
64
+ :focus {
65
+ outline: none;
66
+ }
63
67
  `;
64
68
  const PopoverContainerOpenIcon = exports.PopoverContainerOpenIcon = (0, _styledComponents.default)(_iconButton.default)`
65
69
  ${_icon.default} {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "125.1.0",
3
+ "version": "125.2.0",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "files": [
6
6
  "lib",