@openedx/paragon 22.6.0 → 22.6.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.
@@ -37,6 +37,12 @@ function ModalPopup(_ref) {
37
37
  }
38
38
  }
39
39
  }];
40
+ var handleOnClickOutside = function handleOnClickOutside(e) {
41
+ if (e.type === 'touchstart') {
42
+ return;
43
+ }
44
+ onClose();
45
+ };
40
46
  return /*#__PURE__*/React.createElement(ModalContextProvider, {
41
47
  onClose: onClose,
42
48
  isOpen: isOpen,
@@ -49,7 +55,7 @@ function ModalPopup(_ref) {
49
55
  scrollLock: false,
50
56
  enabled: isOpen,
51
57
  onEscapeKey: onClose,
52
- onClickOutside: onClose
58
+ onClickOutside: handleOnClickOutside
53
59
  }, isOpen && /*#__PURE__*/React.createElement("div", {
54
60
  className: "pgn__modal-popup__tooltip"
55
61
  }, children, hasArrow && /*#__PURE__*/React.createElement("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"ModalPopup.js","names":["React","PropTypes","FocusOn","Portal","PopperElement","ModalContextProvider","PLACEMENT_OFFSETS","right","left","ModalPopup","_ref","children","onClose","isOpen","positionRef","isBlocking","withPortal","placement","hasArrow","popperProps","_objectWithoutProperties","_excluded","RootComponent","Fragment","placementOffsetValue","popperParams","name","options","scroll","offset","createElement","_extends","modifiers","target","scrollLock","enabled","onEscapeKey","onClickOutside","className","id","concat","propTypes","node","isRequired","func","bool","oneOfType","shape","current","defaultProps"],"sources":["../../src/Modal/ModalPopup.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { FocusOn } from 'react-focus-on';\nimport Portal from './Portal';\nimport PopperElement from './PopperElement';\nimport { ModalContextProvider } from './ModalContext';\n\nconst PLACEMENT_OFFSETS = { right: [-2, 10], left: [-2, 10] };\n\nfunction ModalPopup({\n children,\n onClose,\n isOpen,\n positionRef,\n isBlocking,\n withPortal,\n placement,\n hasArrow,\n ...popperProps\n}) {\n const RootComponent = withPortal ? Portal : React.Fragment;\n const placementOffsetValue = PLACEMENT_OFFSETS[placement] || [0, 10];\n\n const popperParams = [\n {\n name: 'eventListeners',\n options: { scroll: false },\n },\n {\n name: 'offset',\n options: {\n offset: () => placementOffsetValue,\n },\n },\n ];\n\n return (\n <ModalContextProvider onClose={onClose} isOpen={isOpen} isBlocking={isBlocking}>\n <RootComponent>\n <PopperElement\n modifiers={hasArrow ? popperParams : null}\n target={positionRef}\n placement={placement}\n {...popperProps}\n >\n <FocusOn\n scrollLock={false}\n enabled={isOpen}\n onEscapeKey={onClose}\n onClickOutside={onClose}\n >\n {isOpen && (\n <div className=\"pgn__modal-popup__tooltip\">\n {children}\n {hasArrow && (\n <div\n id=\"arrow\"\n data-testid=\"modal-popup-arrow\"\n className={`pgn__modal-popup__arrow pgn__modal-popup__arrow-${placement}`}\n data-popper-arrow=\"\"\n />\n )}\n </div>\n )}\n </FocusOn>\n </PopperElement>\n </RootComponent>\n </ModalContextProvider>\n );\n}\n\nModalPopup.propTypes = {\n /** Specifies the contents of the modal */\n children: PropTypes.node.isRequired,\n /** A callback function for when the modal is dismissed */\n onClose: PropTypes.func.isRequired,\n /** Is the modal dialog open or closed */\n isOpen: PropTypes.bool.isRequired,\n /** Prevent clicking on the backdrop or pressing Esc to close the modal */\n isBlocking: PropTypes.bool,\n /** Insert modal into a different location in the DOM */\n withPortal: PropTypes.bool,\n // This type: https://stackoverflow.com/questions/48007326/what-is-the-correct-proptype-for-a-ref-in-react\n /** Specifies an element near which the modal should be displayed */\n positionRef: PropTypes.oneOfType([\n PropTypes.func,\n PropTypes.shape({ current: PropTypes.shape({}) }),\n ]),\n /** Specifies position according to the element that the ``positionRef`` prop points to */\n placement: PopperElement.propTypes.placement,\n /** Caret to the modal popup pointing to the target */\n hasArrow: PropTypes.bool,\n};\n\nModalPopup.defaultProps = {\n isBlocking: false,\n withPortal: false,\n placement: 'bottom-start',\n positionRef: null,\n hasArrow: false,\n};\n\nexport default ModalPopup;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ModalPopup.js","names":["React","PropTypes","FocusOn","Portal","PopperElement","ModalContextProvider","PLACEMENT_OFFSETS","right","left","ModalPopup","_ref","children","onClose","isOpen","positionRef","isBlocking","withPortal","placement","hasArrow","popperProps","_objectWithoutProperties","_excluded","RootComponent","Fragment","placementOffsetValue","popperParams","name","options","scroll","offset","handleOnClickOutside","e","type","createElement","_extends","modifiers","target","scrollLock","enabled","onEscapeKey","onClickOutside","className","id","concat","propTypes","node","isRequired","func","bool","oneOfType","shape","current","defaultProps"],"sources":["../../src/Modal/ModalPopup.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { FocusOn } from 'react-focus-on';\nimport Portal from './Portal';\nimport PopperElement from './PopperElement';\nimport { ModalContextProvider } from './ModalContext';\n\nconst PLACEMENT_OFFSETS = { right: [-2, 10], left: [-2, 10] };\n\nfunction ModalPopup({\n children,\n onClose,\n isOpen,\n positionRef,\n isBlocking,\n withPortal,\n placement,\n hasArrow,\n ...popperProps\n}) {\n const RootComponent = withPortal ? Portal : React.Fragment;\n const placementOffsetValue = PLACEMENT_OFFSETS[placement] || [0, 10];\n\n const popperParams = [\n {\n name: 'eventListeners',\n options: { scroll: false },\n },\n {\n name: 'offset',\n options: {\n offset: () => placementOffsetValue,\n },\n },\n ];\n\n const handleOnClickOutside = (e) => {\n if (e.type === 'touchstart') {\n return;\n }\n\n onClose();\n };\n\n return (\n <ModalContextProvider onClose={onClose} isOpen={isOpen} isBlocking={isBlocking}>\n <RootComponent>\n <PopperElement\n modifiers={hasArrow ? popperParams : null}\n target={positionRef}\n placement={placement}\n {...popperProps}\n >\n <FocusOn\n scrollLock={false}\n enabled={isOpen}\n onEscapeKey={onClose}\n onClickOutside={handleOnClickOutside}\n >\n {isOpen && (\n <div className=\"pgn__modal-popup__tooltip\">\n {children}\n {hasArrow && (\n <div\n id=\"arrow\"\n data-testid=\"modal-popup-arrow\"\n className={`pgn__modal-popup__arrow pgn__modal-popup__arrow-${placement}`}\n data-popper-arrow=\"\"\n />\n )}\n </div>\n )}\n </FocusOn>\n </PopperElement>\n </RootComponent>\n </ModalContextProvider>\n );\n}\n\nModalPopup.propTypes = {\n /** Specifies the contents of the modal */\n children: PropTypes.node.isRequired,\n /** A callback function for when the modal is dismissed */\n onClose: PropTypes.func.isRequired,\n /** Is the modal dialog open or closed */\n isOpen: PropTypes.bool.isRequired,\n /** Prevent clicking on the backdrop or pressing Esc to close the modal */\n isBlocking: PropTypes.bool,\n /** Insert modal into a different location in the DOM */\n withPortal: PropTypes.bool,\n // This type: https://stackoverflow.com/questions/48007326/what-is-the-correct-proptype-for-a-ref-in-react\n /** Specifies an element near which the modal should be displayed */\n positionRef: PropTypes.oneOfType([\n PropTypes.func,\n PropTypes.shape({ current: PropTypes.shape({}) }),\n ]),\n /** Specifies position according to the element that the ``positionRef`` prop points to */\n placement: PopperElement.propTypes.placement,\n /** Caret to the modal popup pointing to the target */\n hasArrow: PropTypes.bool,\n};\n\nModalPopup.defaultProps = {\n isBlocking: false,\n withPortal: false,\n placement: 'bottom-start',\n positionRef: null,\n hasArrow: false,\n};\n\nexport default ModalPopup;\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedx/paragon",
3
- "version": "22.6.0",
3
+ "version": "22.6.1",
4
4
  "description": "Accessible, responsive UI component library based on Bootstrap.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -34,6 +34,14 @@ function ModalPopup({
34
34
  },
35
35
  ];
36
36
 
37
+ const handleOnClickOutside = (e) => {
38
+ if (e.type === 'touchstart') {
39
+ return;
40
+ }
41
+
42
+ onClose();
43
+ };
44
+
37
45
  return (
38
46
  <ModalContextProvider onClose={onClose} isOpen={isOpen} isBlocking={isBlocking}>
39
47
  <RootComponent>
@@ -47,7 +55,7 @@ function ModalPopup({
47
55
  scrollLock={false}
48
56
  enabled={isOpen}
49
57
  onEscapeKey={onClose}
50
- onClickOutside={onClose}
58
+ onClickOutside={handleOnClickOutside}
51
59
  >
52
60
  {isOpen && (
53
61
  <div className="pgn__modal-popup__tooltip">
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import ModalPopup from '../ModalPopup';
5
+
6
+ describe('<ModalPopup />', () => {
7
+ const mockPositionRef = React.createRef();
8
+
9
+ describe('when isOpen', () => {
10
+ const isOpen = true;
11
+ const closeFn = jest.fn();
12
+
13
+ it('calls close on click events but not touchstart events', async () => {
14
+ render(
15
+ <ModalPopup
16
+ positionRef={mockPositionRef}
17
+ isOpen={isOpen}
18
+ onClose={closeFn}
19
+ >
20
+ <div>Modal Contents</div>
21
+ </ModalPopup>,
22
+ );
23
+ await fireEvent.touchStart(document.body);
24
+ expect(closeFn).not.toHaveBeenCalled();
25
+ await userEvent.click(document.body);
26
+ expect(closeFn).toHaveBeenCalled();
27
+ });
28
+ });
29
+ });