@shopify/polaris
Version:
Shopify’s product component library
149 lines (136 loc) • 4.95 kB
JavaScript
import React$1, { useState, useRef, useCallback } from 'react';
import { useUniqueId } from '../../utilities/unique-id/hooks.js';
import { useI18n } from '../../utilities/i18n/hooks.js';
import { focusFirstFocusableNode } from '../../utilities/focus.js';
import { Spinner as Spinner$1 } from '../Spinner/Spinner.js';
import { Portal as Portal$1 } from '../Portal/Portal.js';
import { wrapWithComponent } from '../../utilities/components.js';
import { Scrollable as Scrollable$1 } from '../Scrollable/Scrollable.js';
import { WithinContentContext } from '../../utilities/within-content-context.js';
import { Backdrop as Backdrop$1 } from '../Backdrop/Backdrop.js';
import { TransitionGroup } from 'react-transition-group';
import { Dialog as Dialog$1 } from './components/Dialog/Dialog.js';
import { Footer as Footer$1 } from './components/Footer/Footer.js';
import { CloseButton as CloseButton$1 } from './components/CloseButton/CloseButton.js';
import { Header as Header$1 } from './components/Header/Header.js';
import { Section as Section$1 } from './components/Section/Section.js';
import styles from './Modal.scss.js';
var IFRAME_LOADING_HEIGHT = 200;
var DEFAULT_IFRAME_CONTENT_HEIGHT = 400;
var _ref = /*#__PURE__*/React$1.createElement(Spinner$1, null);
var _ref2 = /*#__PURE__*/React$1.createElement(Backdrop$1, null);
var Modal = function Modal({
children,
title,
src,
iFrameName,
open,
instant,
sectioned,
loading,
large,
limitHeight,
footer,
primaryAction,
secondaryActions,
onScrolledToBottom,
activator,
onClose,
onIFrameLoad,
onTransitionEnd
}) {
var [iframeHeight, setIframeHeight] = useState(IFRAME_LOADING_HEIGHT);
var headerId = useUniqueId('modal-header');
var activatorRef = useRef(null);
var i18n = useI18n();
var iframeTitle = i18n.translate('Polaris.Modal.iFrameTitle');
var dialog;
var backdrop;
var handleEntered = useCallback(() => {
if (onTransitionEnd) {
onTransitionEnd();
}
}, [onTransitionEnd]);
var handleExited = useCallback(() => {
setIframeHeight(IFRAME_LOADING_HEIGHT);
var activatorElement = activator && isRef(activator) ? activator && activator.current : activatorRef.current;
if (activatorElement) {
requestAnimationFrame(() => focusFirstFocusableNode(activatorElement));
}
}, [activator]);
var handleIFrameLoad = useCallback(evt => {
var iframe = evt.target;
if (iframe && iframe.contentWindow) {
try {
setIframeHeight(iframe.contentWindow.document.body.scrollHeight);
} catch (_unused) {
setIframeHeight(DEFAULT_IFRAME_CONTENT_HEIGHT);
}
}
if (onIFrameLoad != null) {
onIFrameLoad(evt);
}
}, [onIFrameLoad]);
if (open) {
var footerMarkup = !footer && !primaryAction && !secondaryActions ? null : /*#__PURE__*/React$1.createElement(Footer$1, {
primaryAction: primaryAction,
secondaryActions: secondaryActions
}, footer);
var content = sectioned ? wrapWithComponent(children, Section$1, {}) : children;
var body = loading ? /*#__PURE__*/React$1.createElement("div", {
className: styles.Spinner
}, _ref) : content;
var bodyMarkup = src ? /*#__PURE__*/React$1.createElement("iframe", {
name: iFrameName,
title: iframeTitle,
src: src,
className: styles.IFrame,
onLoad: handleIFrameLoad,
style: {
height: "".concat(iframeHeight, "px")
}
}) : /*#__PURE__*/React$1.createElement(Scrollable$1, {
shadow: true,
className: styles.Body,
onScrolledToBottom: onScrolledToBottom
}, body);
var headerMarkup = title ? /*#__PURE__*/React$1.createElement(Header$1, {
id: headerId,
onClose: onClose
}, title) : /*#__PURE__*/React$1.createElement(CloseButton$1, {
onClick: onClose,
title: false
});
var labelledBy = title ? headerId : undefined;
dialog = /*#__PURE__*/React$1.createElement(Dialog$1, {
instant: instant,
labelledBy: labelledBy,
onClose: onClose,
onEntered: handleEntered,
onExited: handleExited,
large: large,
limitHeight: limitHeight
}, headerMarkup, /*#__PURE__*/React$1.createElement("div", {
className: styles.BodyWrapper
}, bodyMarkup), footerMarkup);
backdrop = _ref2;
}
var animated = !instant;
var activatorMarkup = activator && !isRef(activator) ? /*#__PURE__*/React$1.createElement("div", {
ref: activatorRef
}, activator) : null;
return /*#__PURE__*/React$1.createElement(WithinContentContext.Provider, {
value: true
}, activatorMarkup, /*#__PURE__*/React$1.createElement(Portal$1, {
idPrefix: "modal"
}, /*#__PURE__*/React$1.createElement(TransitionGroup, {
appear: animated,
enter: animated,
exit: animated
}, dialog), backdrop));
};
function isRef(ref) {
return Object.prototype.hasOwnProperty.call(ref, 'current');
}
Modal.Section = Section$1;
export { Modal };