carbon-react 109.1.0 → 109.1.1

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 (30) hide show
  1. package/esm/components/date/date.component.js +4 -7
  2. package/esm/components/menu/__internal__/submenu/submenu.component.js +4 -6
  3. package/esm/components/multi-action-button/multi-action-button.component.js +4 -13
  4. package/esm/components/popover-container/popover-container.component.d.ts +1 -1
  5. package/esm/components/popover-container/popover-container.component.js +5 -9
  6. package/esm/components/split-button/split-button.component.js +4 -11
  7. package/esm/hooks/__internal__/useClickAwayListener/index.d.ts +1 -0
  8. package/esm/hooks/__internal__/useClickAwayListener/index.js +1 -0
  9. package/esm/hooks/__internal__/useClickAwayListener/useClickAwayListener.d.ts +3 -0
  10. package/esm/hooks/__internal__/useClickAwayListener/useClickAwayListener.js +23 -0
  11. package/lib/components/date/date.component.js +4 -7
  12. package/lib/components/menu/__internal__/submenu/submenu.component.js +4 -6
  13. package/lib/components/multi-action-button/multi-action-button.component.js +5 -13
  14. package/lib/components/popover-container/popover-container.component.d.ts +1 -1
  15. package/lib/components/popover-container/popover-container.component.js +5 -9
  16. package/lib/components/split-button/split-button.component.js +5 -11
  17. package/lib/hooks/__internal__/useClickAwayListener/index.d.ts +1 -0
  18. package/lib/{__internal__/click-away-wrapper → hooks/__internal__/useClickAwayListener}/index.js +2 -2
  19. package/lib/hooks/__internal__/useClickAwayListener/package.json +6 -0
  20. package/lib/hooks/__internal__/useClickAwayListener/useClickAwayListener.d.ts +3 -0
  21. package/lib/hooks/__internal__/useClickAwayListener/useClickAwayListener.js +33 -0
  22. package/package.json +1 -1
  23. package/esm/__internal__/click-away-wrapper/click-away-wrapper.component.d.ts +0 -12
  24. package/esm/__internal__/click-away-wrapper/click-away-wrapper.component.js +0 -43
  25. package/esm/__internal__/click-away-wrapper/index.d.ts +0 -2
  26. package/esm/__internal__/click-away-wrapper/index.js +0 -1
  27. package/lib/__internal__/click-away-wrapper/click-away-wrapper.component.d.ts +0 -12
  28. package/lib/__internal__/click-away-wrapper/click-away-wrapper.component.js +0 -59
  29. package/lib/__internal__/click-away-wrapper/index.d.ts +0 -2
  30. package/lib/__internal__/click-away-wrapper/package.json +0 -6
@@ -12,7 +12,7 @@ import StyledDateInput from "./date.style";
12
12
  import Textbox from "../textbox";
13
13
  import DatePicker from "./__internal__/date-picker";
14
14
  import DateRangeContext from "../date-range/date-range.context";
15
- import ClickAwayWrapper from "../../__internal__/click-away-wrapper";
15
+ import useClickAwayListener from "../../hooks/__internal__/useClickAwayListener";
16
16
  const marginPropTypes = filterStyledSystemMarginProps(styledSystemPropTypes.space);
17
17
 
18
18
  const DateInput = ({
@@ -277,11 +277,8 @@ const DateInput = ({
277
277
  }
278
278
  };
279
279
 
280
- return /*#__PURE__*/React.createElement(ClickAwayWrapper, {
281
- handleClickAway: handleClickAway,
282
- eventTypeId: "mousedown",
283
- targets: [parentRef, pickerRef]
284
- }, /*#__PURE__*/React.createElement(StyledDateInput, _extends({
280
+ useClickAwayListener([parentRef, pickerRef], handleClickAway, "mousedown");
281
+ return /*#__PURE__*/React.createElement(StyledDateInput, _extends({
285
282
  ref: wrapperRef,
286
283
  role: "presentation",
287
284
  size: size,
@@ -321,7 +318,7 @@ const DateInput = ({
321
318
  ref: pickerRef,
322
319
  pickerMouseDown: handlePickerMouseDown,
323
320
  open: open
324
- })));
321
+ }));
325
322
  };
326
323
 
327
324
  DateInput.propTypes = { ...Textbox.propTypes,
@@ -12,7 +12,7 @@ import MenuItem from "../../menu-item";
12
12
  import { characterNavigation } from "../keyboard-navigation";
13
13
  import ScrollableBlock from "../../scrollable-block";
14
14
  import SubmenuContext from "./submenu.context";
15
- import ClickAwayWrapper from "../../../../__internal__/click-away-wrapper";
15
+ import useClickAwayListener from "../../../../hooks/__internal__/useClickAwayListener";
16
16
  const Submenu = /*#__PURE__*/React.forwardRef(({
17
17
  children,
18
18
  className,
@@ -205,6 +205,7 @@ const Submenu = /*#__PURE__*/React.forwardRef(({
205
205
  } // eslint-disable-next-line react-hooks/exhaustive-deps
206
206
 
207
207
  }, [characterString]);
208
+ useClickAwayListener([submenuRef], handleClickAway);
208
209
 
209
210
  if (inFullscreenView) {
210
211
  return /*#__PURE__*/React.createElement(StyledSubmenuWrapper, {
@@ -238,10 +239,7 @@ const Submenu = /*#__PURE__*/React.forwardRef(({
238
239
  }, child))));
239
240
  }
240
241
 
241
- return /*#__PURE__*/React.createElement(ClickAwayWrapper, {
242
- handleClickAway: handleClickAway,
243
- targets: [submenuRef]
244
- }, /*#__PURE__*/React.createElement(StyledSubmenuWrapper, {
242
+ return /*#__PURE__*/React.createElement(StyledSubmenuWrapper, {
245
243
  "data-component": "submenu-wrapper",
246
244
  onMouseOver: !clickToOpen ? () => openSubmenu() : undefined,
247
245
  onMouseLeave: () => closeSubmenu(),
@@ -279,7 +277,7 @@ const Submenu = /*#__PURE__*/React.forwardRef(({
279
277
  updateFocusIndex: setSubmenuFocusIndex,
280
278
  itemIndex: child.type === MenuItem ? index : undefined
281
279
  }
282
- }, child)))));
280
+ }, child))));
283
281
  });
284
282
  Submenu.propTypes = {
285
283
  /** Children elements */
@@ -2,6 +2,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
2
2
 
3
3
  import React, { useCallback, useEffect, useState, useRef, useMemo } from "react";
4
4
  import PropTypes from "prop-types";
5
+ import useClickAwayListener from "../../hooks/__internal__/useClickAwayListener";
5
6
  import { StyledMultiActionButton, StyledButtonChildrenContainer } from "./multi-action-button.style";
6
7
  import Button, { ButtonWithForwardRef } from "../button";
7
8
  import Events from "../../__internal__/utils/helpers/events";
@@ -105,31 +106,20 @@ const MultiActionButton = ({
105
106
  (_additionalButtons$cu = additionalButtons.current[nextIndex].current) === null || _additionalButtons$cu === void 0 ? void 0 : _additionalButtons$cu.focus();
106
107
  }
107
108
  }, [buttonChildren, hideButtons]);
108
- const handleClickOutside = useCallback(({
109
- target
110
- }) => {
111
- var _ref$current, _buttonContainer$curr;
112
-
113
- if (!((_ref$current = ref.current) !== null && _ref$current !== void 0 && _ref$current.contains(target)) && !((_buttonContainer$curr = buttonContainer.current) !== null && _buttonContainer$curr !== void 0 && _buttonContainer$curr.contains(target))) {
114
- hideButtons();
115
- }
116
- }, [hideButtons]);
117
109
  const addListeners = useCallback(() => {
118
110
  /* istanbul ignore else */
119
111
  if (!listening.current) {
120
- document.addEventListener("click", handleClickOutside);
121
112
  document.addEventListener("keydown", handleKeyDown);
122
113
  listening.current = true;
123
114
  }
124
- }, [handleKeyDown, handleClickOutside]);
115
+ }, [handleKeyDown]);
125
116
  const removeListeners = useCallback(() => {
126
117
  /* istanbul ignore else */
127
118
  if (listening.current) {
128
- document.removeEventListener("click", handleClickOutside);
129
119
  document.removeEventListener("keydown", handleKeyDown);
130
120
  listening.current = false;
131
121
  }
132
- }, [handleKeyDown, handleClickOutside]);
122
+ }, [handleKeyDown]);
133
123
  useEffect(() => {
134
124
  if (showAdditionalButtons) {
135
125
  addListeners();
@@ -200,6 +190,7 @@ const MultiActionButton = ({
200
190
  ref: buttonContainer
201
191
  }, childrenWithProps()));
202
192
 
193
+ useClickAwayListener([ref], hideButtons);
203
194
  return /*#__PURE__*/React.createElement(StyledMultiActionButton, _extends({
204
195
  "aria-haspopup": "true",
205
196
  onMouseLeave: hideButtons,
@@ -36,7 +36,7 @@ export interface PopoverContainerProps extends PaddingProps {
36
36
  /** Sets the popover container dialog header name */
37
37
  title?: string;
38
38
  /** Callback fires when close icon clicked */
39
- onClose?: (ev: React.MouseEvent<HTMLElement>) => void;
39
+ onClose?: (ev: React.MouseEvent<HTMLElement> | Event) => void;
40
40
  /** if `true` the popover-container is open */
41
41
  open?: boolean;
42
42
  /** Callback fires when open component is clicked */
@@ -7,7 +7,7 @@ import { PopoverContainerWrapperStyle, PopoverContainerHeaderStyle, PopoverConta
7
7
  import Icon from "../icon";
8
8
  import createGuid from "../../__internal__/utils/helpers/guid";
9
9
  import { filterStyledSystemPaddingProps } from "../../style/utils";
10
- import ClickAwayWrapper from "../../__internal__/click-away-wrapper";
10
+ import useClickAwayListener from "../../hooks/__internal__/useClickAwayListener";
11
11
 
12
12
  const renderOpen = ({
13
13
  tabIndex,
@@ -118,19 +118,15 @@ const PopoverContainer = ({
118
118
  onClick: handleCloseButtonClick,
119
119
  ref: closeButtonRef,
120
120
  "aria-label": closeButtonAriaLabel
121
- }; // TODO: Assign proper type after ClickAwayWrapper has been refactored
122
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
121
+ };
123
122
 
124
123
  const handleClickAway = e => {
125
124
  if (!isControlled) setIsOpenInternal(false);
126
125
  if (onClose) onClose(e);
127
126
  };
128
127
 
129
- return /*#__PURE__*/React.createElement(ClickAwayWrapper, {
130
- targets: [ref],
131
- handleClickAway: handleClickAway,
132
- eventTypeId: "mousedown"
133
- }, /*#__PURE__*/React.createElement(PopoverContainerWrapperStyle, {
128
+ useClickAwayListener([ref], handleClickAway, "mousedown");
129
+ return /*#__PURE__*/React.createElement(PopoverContainerWrapperStyle, {
134
130
  "data-component": "popover-container",
135
131
  role: "region",
136
132
  "aria-labelledby": popoverContainerId,
@@ -158,7 +154,7 @@ const PopoverContainer = ({
158
154
  }, filterStyledSystemPaddingProps(rest)), /*#__PURE__*/React.createElement(PopoverContainerHeaderStyle, null, /*#__PURE__*/React.createElement(PopoverContainerTitleStyle, {
159
155
  id: popoverContainerId,
160
156
  "data-element": "popover-container-title"
161
- }, title), renderCloseComponent(renderCloseComponentProps)), children))));
157
+ }, title), renderCloseComponent(renderCloseComponentProps)), children)));
162
158
  };
163
159
 
164
160
  PopoverContainer.propTypes = {
@@ -4,6 +4,7 @@ import React, { useRef, useState, useContext, useCallback, useEffect } from "rea
4
4
  import { ThemeContext } from "styled-components";
5
5
  import PropTypes from "prop-types";
6
6
  import styledSystemPropTypes from "@styled-system/prop-types";
7
+ import useClickAwayListener from "../../hooks/__internal__/useClickAwayListener";
7
8
  import Icon from "../icon";
8
9
  import Button, { ButtonWithForwardRef } from "../button";
9
10
  import StyledSplitButton from "./split-button.style";
@@ -49,13 +50,6 @@ const SplitButton = ({
49
50
  if (isToggleButtonFocused.current) return;
50
51
  setShowAdditionalButtons(false);
51
52
  }, []);
52
- const handleClickOutside = useCallback(({
53
- target
54
- }) => {
55
- if (!splitButtonNode.current.contains(target) && buttonContainer.current && !buttonContainer.current.contains(target)) {
56
- hideButtons();
57
- }
58
- }, [hideButtons]);
59
53
  const handleKeyDown = useCallback(ev => {
60
54
  const numOfChildren = children.length - 1;
61
55
  const currentIndex = additionalButtons.current.findIndex(node => node.current === document.activeElement);
@@ -88,19 +82,17 @@ const SplitButton = ({
88
82
  const addListeners = useCallback(() => {
89
83
  /* istanbul ignore else */
90
84
  if (!listening.current) {
91
- document.addEventListener("click", handleClickOutside);
92
85
  document.addEventListener("keydown", handleKeyDown);
93
86
  listening.current = true;
94
87
  }
95
- }, [handleKeyDown, handleClickOutside]);
88
+ }, [handleKeyDown]);
96
89
  const removeListeners = useCallback(() => {
97
90
  /* istanbul ignore else */
98
91
  if (listening.current) {
99
- document.removeEventListener("click", handleClickOutside);
100
92
  document.removeEventListener("keydown", handleKeyDown);
101
93
  listening.current = false;
102
94
  }
103
- }, [handleKeyDown, handleClickOutside]);
95
+ }, [handleKeyDown]);
104
96
  useEffect(() => {
105
97
  if (showAdditionalButtons) {
106
98
  addListeners();
@@ -260,6 +252,7 @@ const SplitButton = ({
260
252
  }, childrenWithProps()));
261
253
  }
262
254
 
255
+ useClickAwayListener([splitButtonNode], hideButtons);
263
256
  return /*#__PURE__*/React.createElement(StyledSplitButton, _extends({
264
257
  "aria-haspopup": "true",
265
258
  onMouseLeave: hideButtons,
@@ -0,0 +1 @@
1
+ export { default } from "./useClickAwayListener";
@@ -0,0 +1 @@
1
+ export { default } from "./useClickAwayListener";
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const _default: (targets: React.RefObject<HTMLElement>[], handleClickAway: (ev: Event) => void, eventTypeId?: "mousedown" | "click") => void;
3
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import { useEffect, useRef } from "react";
2
+ export default ((targets, handleClickAway, eventTypeId = "click") => {
3
+ const targetsRef = useRef(targets);
4
+ targetsRef.current = targets;
5
+ useEffect(() => {
6
+ const fnClickAway = ev => {
7
+ const clickedElements = targetsRef.current.filter(targetRef => {
8
+ var _targetRef$current;
9
+
10
+ return (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.contains(ev === null || ev === void 0 ? void 0 : ev.target);
11
+ });
12
+
13
+ if (!(clickedElements !== null && clickedElements !== void 0 && clickedElements.length)) {
14
+ handleClickAway(ev);
15
+ }
16
+ };
17
+
18
+ document.addEventListener(eventTypeId, fnClickAway);
19
+ return function cleanup() {
20
+ document.removeEventListener(eventTypeId, fnClickAway);
21
+ };
22
+ }, [handleClickAway, eventTypeId]);
23
+ });
@@ -29,7 +29,7 @@ var _datePicker = _interopRequireDefault(require("./__internal__/date-picker"));
29
29
 
30
30
  var _dateRange = _interopRequireDefault(require("../date-range/date-range.context"));
31
31
 
32
- var _clickAwayWrapper = _interopRequireDefault(require("../../__internal__/click-away-wrapper"));
32
+ var _useClickAwayListener = _interopRequireDefault(require("../../hooks/__internal__/useClickAwayListener"));
33
33
 
34
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
35
 
@@ -303,11 +303,8 @@ const DateInput = ({
303
303
  }
304
304
  };
305
305
 
306
- return /*#__PURE__*/_react.default.createElement(_clickAwayWrapper.default, {
307
- handleClickAway: handleClickAway,
308
- eventTypeId: "mousedown",
309
- targets: [parentRef, pickerRef]
310
- }, /*#__PURE__*/_react.default.createElement(_date.default, _extends({
306
+ (0, _useClickAwayListener.default)([parentRef, pickerRef], handleClickAway, "mousedown");
307
+ return /*#__PURE__*/_react.default.createElement(_date.default, _extends({
311
308
  ref: wrapperRef,
312
309
  role: "presentation",
313
310
  size: size,
@@ -347,7 +344,7 @@ const DateInput = ({
347
344
  ref: pickerRef,
348
345
  pickerMouseDown: handlePickerMouseDown,
349
346
  open: open
350
- })));
347
+ }));
351
348
  };
352
349
 
353
350
  DateInput.propTypes = { ..._textbox.default.propTypes,
@@ -27,7 +27,7 @@ var _scrollableBlock = _interopRequireDefault(require("../../scrollable-block"))
27
27
 
28
28
  var _submenu2 = _interopRequireDefault(require("./submenu.context"));
29
29
 
30
- var _clickAwayWrapper = _interopRequireDefault(require("../../../../__internal__/click-away-wrapper"));
30
+ var _useClickAwayListener = _interopRequireDefault(require("../../../../hooks/__internal__/useClickAwayListener"));
31
31
 
32
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
33
 
@@ -232,6 +232,7 @@ const Submenu = /*#__PURE__*/_react.default.forwardRef(({
232
232
  } // eslint-disable-next-line react-hooks/exhaustive-deps
233
233
 
234
234
  }, [characterString]);
235
+ (0, _useClickAwayListener.default)([submenuRef], handleClickAway);
235
236
 
236
237
  if (inFullscreenView) {
237
238
  return /*#__PURE__*/_react.default.createElement(_submenu.StyledSubmenuWrapper, {
@@ -265,10 +266,7 @@ const Submenu = /*#__PURE__*/_react.default.forwardRef(({
265
266
  }, child))));
266
267
  }
267
268
 
268
- return /*#__PURE__*/_react.default.createElement(_clickAwayWrapper.default, {
269
- handleClickAway: handleClickAway,
270
- targets: [submenuRef]
271
- }, /*#__PURE__*/_react.default.createElement(_submenu.StyledSubmenuWrapper, {
269
+ return /*#__PURE__*/_react.default.createElement(_submenu.StyledSubmenuWrapper, {
272
270
  "data-component": "submenu-wrapper",
273
271
  onMouseOver: !clickToOpen ? () => openSubmenu() : undefined,
274
272
  onMouseLeave: () => closeSubmenu(),
@@ -306,7 +304,7 @@ const Submenu = /*#__PURE__*/_react.default.forwardRef(({
306
304
  updateFocusIndex: setSubmenuFocusIndex,
307
305
  itemIndex: child.type === _menuItem2.default ? index : undefined
308
306
  }
309
- }, child)))));
307
+ }, child))));
310
308
  });
311
309
 
312
310
  Submenu.propTypes = {
@@ -9,6 +9,8 @@ var _react = _interopRequireWildcard(require("react"));
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
+ var _useClickAwayListener = _interopRequireDefault(require("../../hooks/__internal__/useClickAwayListener"));
13
+
12
14
  var _multiActionButton = require("./multi-action-button.style");
13
15
 
14
16
  var _button = _interopRequireWildcard(require("../button"));
@@ -125,31 +127,20 @@ const MultiActionButton = ({
125
127
  (_additionalButtons$cu = additionalButtons.current[nextIndex].current) === null || _additionalButtons$cu === void 0 ? void 0 : _additionalButtons$cu.focus();
126
128
  }
127
129
  }, [buttonChildren, hideButtons]);
128
- const handleClickOutside = (0, _react.useCallback)(({
129
- target
130
- }) => {
131
- var _ref$current, _buttonContainer$curr;
132
-
133
- if (!((_ref$current = ref.current) !== null && _ref$current !== void 0 && _ref$current.contains(target)) && !((_buttonContainer$curr = buttonContainer.current) !== null && _buttonContainer$curr !== void 0 && _buttonContainer$curr.contains(target))) {
134
- hideButtons();
135
- }
136
- }, [hideButtons]);
137
130
  const addListeners = (0, _react.useCallback)(() => {
138
131
  /* istanbul ignore else */
139
132
  if (!listening.current) {
140
- document.addEventListener("click", handleClickOutside);
141
133
  document.addEventListener("keydown", handleKeyDown);
142
134
  listening.current = true;
143
135
  }
144
- }, [handleKeyDown, handleClickOutside]);
136
+ }, [handleKeyDown]);
145
137
  const removeListeners = (0, _react.useCallback)(() => {
146
138
  /* istanbul ignore else */
147
139
  if (listening.current) {
148
- document.removeEventListener("click", handleClickOutside);
149
140
  document.removeEventListener("keydown", handleKeyDown);
150
141
  listening.current = false;
151
142
  }
152
- }, [handleKeyDown, handleClickOutside]);
143
+ }, [handleKeyDown]);
153
144
  (0, _react.useEffect)(() => {
154
145
  if (showAdditionalButtons) {
155
146
  addListeners();
@@ -220,6 +211,7 @@ const MultiActionButton = ({
220
211
  ref: buttonContainer
221
212
  }, childrenWithProps()));
222
213
 
214
+ (0, _useClickAwayListener.default)([ref], hideButtons);
223
215
  return /*#__PURE__*/_react.default.createElement(_multiActionButton.StyledMultiActionButton, _extends({
224
216
  "aria-haspopup": "true",
225
217
  onMouseLeave: hideButtons,
@@ -36,7 +36,7 @@ export interface PopoverContainerProps extends PaddingProps {
36
36
  /** Sets the popover container dialog header name */
37
37
  title?: string;
38
38
  /** Callback fires when close icon clicked */
39
- onClose?: (ev: React.MouseEvent<HTMLElement>) => void;
39
+ onClose?: (ev: React.MouseEvent<HTMLElement> | Event) => void;
40
40
  /** if `true` the popover-container is open */
41
41
  open?: boolean;
42
42
  /** Callback fires when open component is clicked */
@@ -19,7 +19,7 @@ var _guid = _interopRequireDefault(require("../../__internal__/utils/helpers/gui
19
19
 
20
20
  var _utils = require("../../style/utils");
21
21
 
22
- var _clickAwayWrapper = _interopRequireDefault(require("../../__internal__/click-away-wrapper"));
22
+ var _useClickAwayListener = _interopRequireDefault(require("../../hooks/__internal__/useClickAwayListener"));
23
23
 
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
25
 
@@ -138,19 +138,15 @@ const PopoverContainer = ({
138
138
  onClick: handleCloseButtonClick,
139
139
  ref: closeButtonRef,
140
140
  "aria-label": closeButtonAriaLabel
141
- }; // TODO: Assign proper type after ClickAwayWrapper has been refactored
142
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
+ };
143
142
 
144
143
  const handleClickAway = e => {
145
144
  if (!isControlled) setIsOpenInternal(false);
146
145
  if (onClose) onClose(e);
147
146
  };
148
147
 
149
- return /*#__PURE__*/_react.default.createElement(_clickAwayWrapper.default, {
150
- targets: [ref],
151
- handleClickAway: handleClickAway,
152
- eventTypeId: "mousedown"
153
- }, /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerWrapperStyle, {
148
+ (0, _useClickAwayListener.default)([ref], handleClickAway, "mousedown");
149
+ return /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerWrapperStyle, {
154
150
  "data-component": "popover-container",
155
151
  role: "region",
156
152
  "aria-labelledby": popoverContainerId,
@@ -178,7 +174,7 @@ const PopoverContainer = ({
178
174
  }, (0, _utils.filterStyledSystemPaddingProps)(rest)), /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerHeaderStyle, null, /*#__PURE__*/_react.default.createElement(_popoverContainer.PopoverContainerTitleStyle, {
179
175
  id: popoverContainerId,
180
176
  "data-element": "popover-container-title"
181
- }, title), renderCloseComponent(renderCloseComponentProps)), children))));
177
+ }, title), renderCloseComponent(renderCloseComponentProps)), children)));
182
178
  };
183
179
 
184
180
  exports.PopoverContainer = PopoverContainer;
@@ -13,6 +13,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
14
  var _propTypes2 = _interopRequireDefault(require("@styled-system/prop-types"));
15
15
 
16
+ var _useClickAwayListener = _interopRequireDefault(require("../../hooks/__internal__/useClickAwayListener"));
17
+
16
18
  var _icon = _interopRequireDefault(require("../icon"));
17
19
 
18
20
  var _button = _interopRequireWildcard(require("../button"));
@@ -80,13 +82,6 @@ const SplitButton = ({
80
82
  if (isToggleButtonFocused.current) return;
81
83
  setShowAdditionalButtons(false);
82
84
  }, []);
83
- const handleClickOutside = (0, _react.useCallback)(({
84
- target
85
- }) => {
86
- if (!splitButtonNode.current.contains(target) && buttonContainer.current && !buttonContainer.current.contains(target)) {
87
- hideButtons();
88
- }
89
- }, [hideButtons]);
90
85
  const handleKeyDown = (0, _react.useCallback)(ev => {
91
86
  const numOfChildren = children.length - 1;
92
87
  const currentIndex = additionalButtons.current.findIndex(node => node.current === document.activeElement);
@@ -119,19 +114,17 @@ const SplitButton = ({
119
114
  const addListeners = (0, _react.useCallback)(() => {
120
115
  /* istanbul ignore else */
121
116
  if (!listening.current) {
122
- document.addEventListener("click", handleClickOutside);
123
117
  document.addEventListener("keydown", handleKeyDown);
124
118
  listening.current = true;
125
119
  }
126
- }, [handleKeyDown, handleClickOutside]);
120
+ }, [handleKeyDown]);
127
121
  const removeListeners = (0, _react.useCallback)(() => {
128
122
  /* istanbul ignore else */
129
123
  if (listening.current) {
130
- document.removeEventListener("click", handleClickOutside);
131
124
  document.removeEventListener("keydown", handleKeyDown);
132
125
  listening.current = false;
133
126
  }
134
- }, [handleKeyDown, handleClickOutside]);
127
+ }, [handleKeyDown]);
135
128
  (0, _react.useEffect)(() => {
136
129
  if (showAdditionalButtons) {
137
130
  addListeners();
@@ -291,6 +284,7 @@ const SplitButton = ({
291
284
  }, childrenWithProps()));
292
285
  }
293
286
 
287
+ (0, _useClickAwayListener.default)([splitButtonNode], hideButtons);
294
288
  return /*#__PURE__*/_react.default.createElement(_splitButton.default, _extends({
295
289
  "aria-haspopup": "true",
296
290
  onMouseLeave: hideButtons,
@@ -0,0 +1 @@
1
+ export { default } from "./useClickAwayListener";
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", {
6
6
  Object.defineProperty(exports, "default", {
7
7
  enumerable: true,
8
8
  get: function () {
9
- return _clickAwayWrapper.default;
9
+ return _useClickAwayListener.default;
10
10
  }
11
11
  });
12
12
 
13
- var _clickAwayWrapper = _interopRequireDefault(require("./click-away-wrapper.component"));
13
+ var _useClickAwayListener = _interopRequireDefault(require("./useClickAwayListener"));
14
14
 
15
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "../../../../esm/hooks/__internal__/useClickAwayListener/index.js",
4
+ "main": "./index.js",
5
+ "types": "./index.d.ts"
6
+ }
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const _default: (targets: React.RefObject<HTMLElement>[], handleClickAway: (ev: Event) => void, eventTypeId?: "mousedown" | "click") => void;
3
+ export default _default;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = require("react");
9
+
10
+ var _default = (targets, handleClickAway, eventTypeId = "click") => {
11
+ const targetsRef = (0, _react.useRef)(targets);
12
+ targetsRef.current = targets;
13
+ (0, _react.useEffect)(() => {
14
+ const fnClickAway = ev => {
15
+ const clickedElements = targetsRef.current.filter(targetRef => {
16
+ var _targetRef$current;
17
+
18
+ return (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.contains(ev === null || ev === void 0 ? void 0 : ev.target);
19
+ });
20
+
21
+ if (!(clickedElements !== null && clickedElements !== void 0 && clickedElements.length)) {
22
+ handleClickAway(ev);
23
+ }
24
+ };
25
+
26
+ document.addEventListener(eventTypeId, fnClickAway);
27
+ return function cleanup() {
28
+ document.removeEventListener(eventTypeId, fnClickAway);
29
+ };
30
+ }, [handleClickAway, eventTypeId]);
31
+ };
32
+
33
+ exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "109.1.0",
3
+ "version": "109.1.1",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "engineStrict": true,
6
6
  "engines": {
@@ -1,12 +0,0 @@
1
- import React from "react";
2
- export interface ClickAwayWrapperProps {
3
- children: React.ReactNode;
4
- handleClickAway: (ev: CustomEvent) => void;
5
- eventTypeId?: "mousedown" | "click";
6
- targets: React.RefObject<HTMLElement>[];
7
- }
8
- declare const ClickAwayWrapper: {
9
- ({ children, handleClickAway, eventTypeId, targets, }: ClickAwayWrapperProps): JSX.Element;
10
- displayName: string;
11
- };
12
- export default ClickAwayWrapper;
@@ -1,43 +0,0 @@
1
- import React, { useEffect } from "react";
2
- import PropTypes from "prop-types";
3
- import Events from "../utils/helpers/events";
4
-
5
- const ClickAwayWrapper = ({
6
- children,
7
- handleClickAway,
8
- eventTypeId = "click",
9
- targets
10
- }) => {
11
- useEffect(() => {
12
- const fnClickAway = ev => {
13
- const clickedElements = targets.filter(ref => (ref === null || ref === void 0 ? void 0 : ref.current) && Events.composedPath(ev).includes(ref.current));
14
-
15
- if (!clickedElements || !clickedElements.length) {
16
- handleClickAway(ev);
17
- }
18
- };
19
-
20
- document.addEventListener(eventTypeId, fnClickAway);
21
- return function cleanup() {
22
- document.removeEventListener(eventTypeId, fnClickAway);
23
- };
24
- }, [handleClickAway, targets, eventTypeId]);
25
- return /*#__PURE__*/React.createElement(React.Fragment, null, children);
26
- };
27
-
28
- ClickAwayWrapper.propTypes = {
29
- "children": PropTypes.node,
30
- "eventTypeId": PropTypes.oneOf(["click", "mousedown"]),
31
- "handleClickAway": PropTypes.func.isRequired,
32
- "targets": PropTypes.arrayOf(PropTypes.shape({
33
- "current": PropTypes.oneOfType([PropTypes.oneOf([null]), function (props, propName) {
34
- if (props[propName] == null) {
35
- return new Error("Prop '" + propName + "' is required but wasn't specified");
36
- } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
37
- return new Error("Expected prop '" + propName + "' to be of type Element");
38
- }
39
- }]).isRequired
40
- })).isRequired
41
- };
42
- ClickAwayWrapper.displayName = "ClickAwayWrapper";
43
- export default ClickAwayWrapper;
@@ -1,2 +0,0 @@
1
- export { default } from "./click-away-wrapper.component";
2
- export type { ClickAwayWrapperProps } from "./click-away-wrapper.component";
@@ -1 +0,0 @@
1
- export { default } from "./click-away-wrapper.component";
@@ -1,12 +0,0 @@
1
- import React from "react";
2
- export interface ClickAwayWrapperProps {
3
- children: React.ReactNode;
4
- handleClickAway: (ev: CustomEvent) => void;
5
- eventTypeId?: "mousedown" | "click";
6
- targets: React.RefObject<HTMLElement>[];
7
- }
8
- declare const ClickAwayWrapper: {
9
- ({ children, handleClickAway, eventTypeId, targets, }: ClickAwayWrapperProps): JSX.Element;
10
- displayName: string;
11
- };
12
- export default ClickAwayWrapper;
@@ -1,59 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _react = _interopRequireWildcard(require("react"));
9
-
10
- var _propTypes = _interopRequireDefault(require("prop-types"));
11
-
12
- var _events = _interopRequireDefault(require("../utils/helpers/events"));
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
17
-
18
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
-
20
- const ClickAwayWrapper = ({
21
- children,
22
- handleClickAway,
23
- eventTypeId = "click",
24
- targets
25
- }) => {
26
- (0, _react.useEffect)(() => {
27
- const fnClickAway = ev => {
28
- const clickedElements = targets.filter(ref => (ref === null || ref === void 0 ? void 0 : ref.current) && _events.default.composedPath(ev).includes(ref.current));
29
-
30
- if (!clickedElements || !clickedElements.length) {
31
- handleClickAway(ev);
32
- }
33
- };
34
-
35
- document.addEventListener(eventTypeId, fnClickAway);
36
- return function cleanup() {
37
- document.removeEventListener(eventTypeId, fnClickAway);
38
- };
39
- }, [handleClickAway, targets, eventTypeId]);
40
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
41
- };
42
-
43
- ClickAwayWrapper.propTypes = {
44
- "children": _propTypes.default.node,
45
- "eventTypeId": _propTypes.default.oneOf(["click", "mousedown"]),
46
- "handleClickAway": _propTypes.default.func.isRequired,
47
- "targets": _propTypes.default.arrayOf(_propTypes.default.shape({
48
- "current": _propTypes.default.oneOfType([_propTypes.default.oneOf([null]), function (props, propName) {
49
- if (props[propName] == null) {
50
- return new Error("Prop '" + propName + "' is required but wasn't specified");
51
- } else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
52
- return new Error("Expected prop '" + propName + "' to be of type Element");
53
- }
54
- }]).isRequired
55
- })).isRequired
56
- };
57
- ClickAwayWrapper.displayName = "ClickAwayWrapper";
58
- var _default = ClickAwayWrapper;
59
- exports.default = _default;
@@ -1,2 +0,0 @@
1
- export { default } from "./click-away-wrapper.component";
2
- export type { ClickAwayWrapperProps } from "./click-away-wrapper.component";
@@ -1,6 +0,0 @@
1
- {
2
- "sideEffects": false,
3
- "module": "../../../esm/__internal__/click-away-wrapper/index.js",
4
- "main": "./index.js",
5
- "types": "./index.d.ts"
6
- }