UNPKG

wix-style-react

Version:
251 lines (211 loc) • 9.92 kB
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } import React from 'react'; import PropTypes from 'prop-types'; import ReactModal from 'react-modal'; import X from 'wix-ui-icons-common/X'; import defaultTo from 'lodash/defaultTo'; import { st, classes } from './Modal.st.css'; import { flexPositions } from './constants'; import { ZIndex } from '../ZIndex'; import { FontUpgradeContext } from '../FontUpgrade/context'; import FontUpgrade from '../FontUpgrade'; import { ThemeProviderConsumerBackwardCompatible } from '../ThemeProvider/ThemeProviderConsumerBackwardCompatible'; import uniqueId from 'lodash/uniqueId'; var Modal = /*#__PURE__*/function (_React$PureComponent) { _inherits(Modal, _React$PureComponent); var _super = _createSuper(Modal); function Modal(props) { var _this; _classCallCheck(this, Modal); _this = _super.call(this, props); _defineProperty(_assertThisInitialized(_this), "handleOverlayClick", function (event) { var _this$props = _this.props, shouldCloseOnOverlayClick = _this$props.shouldCloseOnOverlayClick, onRequestClose = _this$props.onRequestClose; if (shouldCloseOnOverlayClick && event.target.id === _this.CHILDREN_WRAPPER_DIV_ID && onRequestClose) { onRequestClose(); } }); _defineProperty(_assertThisInitialized(_this), "renderCloseButton", function () { return /*#__PURE__*/React.createElement("div", { onClick: _this.props.onRequestClose, className: classes.closeButton, "data-hook": "modal-close-button" }, /*#__PURE__*/React.createElement(X, { size: "18px" })); }); _this.CHILDREN_WRAPPER_DIV_ID = uniqueId('wsr-modal'); return _this; } _createClass(Modal, [{ key: "render", value: function render() { var _this2 = this; var _this$props2 = this.props, dataHook = _this$props2.dataHook, horizontalPosition = _this$props2.horizontalPosition, verticalPosition = _this$props2.verticalPosition, height = _this$props2.height, scrollableContent = _this$props2.scrollableContent, borderRadius = _this$props2.borderRadius, zIndex = _this$props2.zIndex, scrollable = _this$props2.scrollable, isOpen = _this$props2.isOpen, shouldCloseOnOverlayClick = _this$props2.shouldCloseOnOverlayClick, shouldDisplayCloseButton = _this$props2.shouldDisplayCloseButton, onRequestClose = _this$props2.onRequestClose, onAfterOpen = _this$props2.onAfterOpen, contentLabel = _this$props2.contentLabel, closeTimeoutMS = _this$props2.closeTimeoutMS, children = _this$props2.children, appElement = _this$props2.appElement, overlayPosition = _this$props2.overlayPosition, parentSelector = _this$props2.parentSelector, screen = _this$props2.screen; var maxHeight = this.props.maxHeight; var justifyContent = flexPositions[horizontalPosition]; var alignItems = flexPositions[verticalPosition]; maxHeight = scrollableContent && maxHeight === 'auto' ? '100vh' : maxHeight; var modalStyles = { overlay: { // Overriding defaults position: overlayPosition, top: 0, left: 0, right: 0, bottom: 0, zIndex: defaultTo(zIndex, ZIndex('Modal')), backgroundColor: null, // null disables the property, use css instead // Overriding defaults - END display: 'flex', justifyContent: justifyContent, alignItems: alignItems, overflowY: scrollable ? 'auto' : 'hidden' }, content: { // Overriding defaults border: 'none', overflowY: scrollableContent ? 'auto' : 'initial', overflowX: scrollableContent ? 'hidden' : 'initial', height: height, maxHeight: maxHeight, width: '100%', WebkitOverflowScrolling: 'touch', outline: 'none', borderRadius: borderRadius, padding: '0px', // Overriding defaults - END backgroundColor: 'transparent', marginBottom: '0px', position: 'relative' } }; if (appElement) { ReactModal.setAppElement(appElement); } else { ReactModal.setAppElement('body'); } return /*#__PURE__*/React.createElement("div", { "data-hook": dataHook }, /*#__PURE__*/React.createElement(FontUpgradeContext.Consumer, null, function (_ref) { var active = _ref.active; return /*#__PURE__*/React.createElement(ThemeProviderConsumerBackwardCompatible, null, function (_ref2) { var themeClassName = _ref2.className; return /*#__PURE__*/React.createElement(ReactModal, { portalClassName: st(classes.root, { scrollable: scrollable }, "portal portal-".concat(dataHook), themeClassName), isOpen: isOpen, shouldCloseOnOverlayClick: shouldCloseOnOverlayClick, onRequestClose: onRequestClose, onAfterOpen: onAfterOpen, style: modalStyles, className: classes.modal, contentLabel: contentLabel, closeTimeoutMS: closeTimeoutMS, parentSelector: parentSelector }, /*#__PURE__*/React.createElement(FontUpgrade, { active: !!active }, isOpen && shouldDisplayCloseButton && _this2.renderCloseButton(), /*#__PURE__*/React.createElement("div", { "data-scrollable": scrollable || null, id: _this2.CHILDREN_WRAPPER_DIV_ID, className: st(classes.childrenContainer, { screen: screen }), onClick: _this2.handleOverlayClick }, children))); }); })); } }]); return Modal; }(React.PureComponent); _defineProperty(Modal, "propTypes", { /** Applied as data-hook HTML attribute that can be used to create driver in testing */ dataHook: PropTypes.string, /** Controls if modal is open or closed */ isOpen: PropTypes.bool.isRequired, /** Border radius of modal */ borderRadius: PropTypes.number, /** a11y: The value of contentLabel is set as an aria-label on the modal element. This helps assistive technology, like screen readers, to add a label to an element that would otherwise be anonymous */ contentLabel: PropTypes.string, /** Renders modal content */ children: PropTypes.any, /** Controls z-index of the modal overlay */ zIndex: PropTypes.number, /** Enables to close modal when mouse clicked on overlay area */ shouldCloseOnOverlayClick: PropTypes.bool, /** Displays a close button on the top right corner of the overlay */ shouldDisplayCloseButton: PropTypes.bool, /** Callback that will be executed when the modal is requested to be closed, prior to actually closing */ onRequestClose: PropTypes.func, /** Callback that will be executed after the modal has been opened */ onAfterOpen: PropTypes.func, /** Horizontal position of the modal */ horizontalPosition: PropTypes.oneOf(['start', 'center', 'end']), /** Vertical position of the modal */ verticalPosition: PropTypes.oneOf(['start', 'center', 'end']), /** Number indicating the milliseconds to wait before closing the modal */ closeTimeoutMS: PropTypes.number, /** Specifies if modal portal supports scroll */ scrollable: PropTypes.bool, /** Specifies if modal content should become scrollable when modal size will fit the window */ scrollableContent: PropTypes.bool, /** Sets the maximum height for a scrollable content */ maxHeight: PropTypes.string, /** Sets the height for modal's content container */ height: PropTypes.string, /** css position of the modal overlay */ overlayPosition: PropTypes.oneOf(['static', 'relative', 'absolute', 'fixed', 'sticky']), /** A function that returns a DOM element on which the modal should be appended to */ parentSelector: PropTypes.func, /** Selector specifying where to apply the aria-hidden attribute */ appElement: PropTypes.string, /** Specifies minimum spacing between full viewport and modal content */ screen: PropTypes.oneOf(['full', 'desktop', 'mobile']) }); _defineProperty(Modal, "defaultProps", { borderRadius: 0, shouldCloseOnOverlayClick: false, shouldDisplayCloseButton: false, horizontalPosition: 'center', verticalPosition: 'center', closeTimeoutMS: 500, scrollable: true, scrollableContent: false, height: '100%', maxHeight: 'auto', overlayPosition: 'fixed', screen: 'full' }); export default Modal;