UNPKG

@shopify/polaris

Version:

Shopify’s admin product component library

156 lines (152 loc) 5.32 kB
'use strict'; var React = require('react'); var reactTransitionGroup = require('react-transition-group'); var focus = require('../../utilities/focus.js'); var withinContentContext = require('../../utilities/within-content-context.js'); var components = require('../../utilities/components.js'); var Modal_module = require('./Modal.css.js'); var Section = require('./components/Section/Section.js'); var Dialog = require('./components/Dialog/Dialog.js'); var Header = require('./components/Header/Header.js'); var Backdrop = require('../Backdrop/Backdrop.js'); var Footer = require('./components/Footer/Footer.js'); var hooks = require('../../utilities/i18n/hooks.js'); var Box = require('../Box/Box.js'); var Scrollable = require('../Scrollable/Scrollable.js'); var Portal = require('../Portal/Portal.js'); var InlineStack = require('../InlineStack/InlineStack.js'); var Spinner = require('../Spinner/Spinner.js'); const IFRAME_LOADING_HEIGHT = 200; const DEFAULT_IFRAME_CONTENT_HEIGHT = 400; const Modal = function Modal({ children, title, titleHidden = false, src, iFrameName, open, instant, sectioned, loading, size, limitHeight, footer, primaryAction, secondaryActions, onScrolledToBottom, activator, activatorWrapper = 'div', onClose, onIFrameLoad, onTransitionEnd, noScroll }) { const [iframeHeight, setIframeHeight] = React.useState(IFRAME_LOADING_HEIGHT); const [closing, setClosing] = React.useState(false); const headerId = React.useId(); const activatorRef = React.useRef(null); const i18n = hooks.useI18n(); const iframeTitle = i18n.translate('Polaris.Modal.iFrameTitle'); let dialog; let backdrop; const handleEntered = React.useCallback(() => { if (onTransitionEnd) { onTransitionEnd(); } }, [onTransitionEnd]); const handleExited = React.useCallback(() => { setIframeHeight(IFRAME_LOADING_HEIGHT); const activatorElement = activator && isRef(activator) ? activator && activator.current : activatorRef.current; if (activatorElement) { requestAnimationFrame(() => focus.focusFirstFocusableNode(activatorElement)); } }, [activator]); const handleIFrameLoad = React.useCallback(evt => { const iframe = evt.target; if (iframe && iframe.contentWindow) { try { setIframeHeight(iframe.contentWindow.document.body.scrollHeight); } catch (_error) { setIframeHeight(DEFAULT_IFRAME_CONTENT_HEIGHT); } } if (onIFrameLoad != null) { onIFrameLoad(evt); } }, [onIFrameLoad]); if (open) { const footerMarkup = !footer && !primaryAction && !secondaryActions ? null : /*#__PURE__*/React.createElement(Footer.Footer, { primaryAction: primaryAction, secondaryActions: secondaryActions }, footer); const content = sectioned ? components.wrapWithComponent(children, Section.Section, { titleHidden }) : children; const body = loading ? /*#__PURE__*/React.createElement(Box.Box, { padding: "400" }, /*#__PURE__*/React.createElement(InlineStack.InlineStack, { gap: "400", align: "center", blockAlign: "center" }, /*#__PURE__*/React.createElement(Spinner.Spinner, null))) : content; const scrollContainerMarkup = noScroll ? /*#__PURE__*/React.createElement("div", { className: Modal_module.default.NoScrollBody }, /*#__PURE__*/React.createElement(Box.Box, { width: "100%", overflowX: "hidden", overflowY: "hidden" }, body)) : /*#__PURE__*/React.createElement(Scrollable.Scrollable, { shadow: true, className: Modal_module.default.Body, onScrolledToBottom: onScrolledToBottom }, body); const bodyMarkup = src ? /*#__PURE__*/React.createElement("iframe", { name: iFrameName, title: iframeTitle, src: src, className: Modal_module.default.IFrame, onLoad: handleIFrameLoad, style: { height: `${iframeHeight}px` } }) : scrollContainerMarkup; dialog = /*#__PURE__*/React.createElement(Dialog.Dialog, { instant: instant, labelledBy: headerId, onClose: onClose, onEntered: handleEntered, onExited: handleExited, size: size, limitHeight: limitHeight, setClosing: setClosing }, /*#__PURE__*/React.createElement(Header.Header, { titleHidden: titleHidden, id: headerId, closing: closing, onClose: onClose }, title), bodyMarkup, footerMarkup); backdrop = /*#__PURE__*/React.createElement(Backdrop.Backdrop, { setClosing: setClosing, onClick: onClose }); } const animated = !instant; const activatorMarkup = activator && !isRef(activator) ? /*#__PURE__*/React.createElement(Box.Box, { ref: activatorRef, as: activatorWrapper }, activator) : null; return /*#__PURE__*/React.createElement(withinContentContext.WithinContentContext.Provider, { value: true }, activatorMarkup, /*#__PURE__*/React.createElement(Portal.Portal, { idPrefix: "modal" }, /*#__PURE__*/React.createElement(reactTransitionGroup.TransitionGroup, { appear: animated, enter: animated, exit: animated }, dialog), backdrop)); }; function isRef(ref) { return Object.prototype.hasOwnProperty.call(ref, 'current'); } Modal.Section = Section.Section; exports.Modal = Modal;