UNPKG

@cimpress/react-components

Version:
206 lines (200 loc) 6.46 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import React, { useMemo } from 'react'; import ReactDOM from 'react-dom'; import { css, cx } from '@emotion/css'; import cvar from '../theme/cvar'; import { BREAKPOINT_L, BREAKPOINT_M, BREAKPOINT_S } from '../breakpoint'; import { Close, BlockButton } from '../internal'; import { granite, white } from '../colors'; const defaultSizeStyles = css ` max-height: 72vh; @media screen and (max-width: ${BREAKPOINT_S}) { width: 100%; } @media screen and (min-width: calc(${BREAKPOINT_S} + 1px)) and (max-width: ${BREAKPOINT_M}) { width: 58%; } @media screen and (min-width: calc(${BREAKPOINT_M} + 1px)) and (max-width: ${BREAKPOINT_L}) { width: 50%; } @media screen and (min-width: calc(${BREAKPOINT_L} + 1px)) { width: 38%; } `; const largeSizeStyles = css ` max-height: 84vh; @media screen and (max-width: ${BREAKPOINT_S}) { width: 100%; } @media screen and (min-width: calc(${BREAKPOINT_S} + 1px)) and (max-width: ${BREAKPOINT_M}) { width: 72%; } @media screen and (min-width: calc(${BREAKPOINT_M} + 1px)) and (max-width: ${BREAKPOINT_L}) { width: 60%; } @media screen and (min-width: calc(${BREAKPOINT_L} + 1px)) { width: 50%; } `; const xLargeSizeStyles = css ` max-height: 96vh; @media screen and (max-width: ${BREAKPOINT_S}) { width: 100%; } @media screen and (min-width: calc(${BREAKPOINT_S} + 1px)) and (max-width: ${BREAKPOINT_M}) { width: 84%; } @media screen and (min-width: calc(${BREAKPOINT_M} + 1px)) and (max-width: ${BREAKPOINT_L}) { width: 72%; } @media screen and (min-width: calc(${BREAKPOINT_L} + 1px)) { width: 72%; } `; const modalDialogCss = css ` position: relative; margin: 30px auto; z-index: 1050; `; const modalBackdrop = css ` position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000; opacity: 0.5; `; const modalCss = css ` position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1050; overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; &.modal-enter, &.modal-enter-active, &.modal-enter-done { display: block; } &.modal-enter > .fade-in { opacity: 0; transition: opacity 0.15s linear; } &.modal-enter.modal-enter-active > .fade-in, &.modal-enter-done > .fade-in { opacity: 0.5; } `; const modalTitle = css ` font-size: 24px; line-height: 1.3em; font-weight: normal; flex-grow: 1; `; const modalCloseButton = css ` color: ${cvar('color-icon-secondary')}; height: ${cvar('spacing-48')}; vertical-align: middle; margin-top: -10px; padding: 0; cursor: pointer; background: 0 0; border: 0; -webkit-appearance: none; appearance: none; &:hover, &:active { color: shale; opacity: 1; } `; const modalHeaderCss = css ` background-color: ${cvar('color-background')}; border-bottom: none; display: flex; justify-content: flex-end; flex-shrink: 0; `; const getModalInteractionCss = (status) => { let color = white; switch (status) { case 'success': { color = cvar('color-border-success'); break; } case 'danger': { color = cvar('color-border-error'); break; } case 'warning': { color = cvar('color-border-warning'); break; } case 'info': { color = cvar('color-border-info'); break; } default: { break; } } return css ` border-top: 4px solid ${color}; `; }; const modalContentCss = css ` background-color: ${cvar('color-background')}; border: 0; box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; border-radius: 4px; max-height: 90vh; padding: ${cvar('spacing-24')}; `; const modalBodyCss = css ` padding: ${cvar('spacing-24')} 0; overflow-y: auto; flex-grow: 1; `; const modalFooterCss = css ` border-top: none; padding: ${cvar('spacing-24')} 0 0; text-align: right; `; export const DisplayModal = (_a) => { var { title, closeButton, footer, size = 'md', onRequestHide, closeOnOutsideClick = false, style, className, status, wrapperStyle } = _a, rest = __rest(_a, ["title", "closeButton", "footer", "size", "onRequestHide", "closeOnOutsideClick", "style", "className", "status", "wrapperStyle"]); const modalStatusCss = useMemo(() => getModalInteractionCss(status), [status]); const ModalHeader = (React.createElement("div", { className: modalHeaderCss }, React.createElement("div", { className: modalTitle }, title), closeButton ? (React.createElement("button", { className: modalCloseButton, onClick: e => (onRequestHide ? onRequestHide(e) : null) }, React.createElement(Close, { width: "16px", color: granite.base, cropped: true, "aria-label": "Close modal" }))) : null)); const ModalFooter = footer && React.createElement("div", { className: modalFooterCss }, footer); const modalNode = (React.createElement(BlockButton, { onClick: e => e.stopPropagation(), onKeyDown: e => e.stopPropagation(), className: modalCss, tabIndex: -1 }, React.createElement("div", { className: cx('crc-modal', modalDialogCss, defaultSizeStyles, { [largeSizeStyles]: size === 'lg', [xLargeSizeStyles]: size === 'xl', }, className), style: Object.assign({}, style) }, React.createElement("div", Object.assign({ className: cx(modalContentCss, modalStatusCss) }, rest), ModalHeader, React.createElement("div", { className: modalBodyCss }, rest.children), ModalFooter)), React.createElement(BlockButton, { tabIndex: -1, className: cx(modalBackdrop, 'fade-in'), onClick: (e) => (closeOnOutsideClick && onRequestHide ? onRequestHide(e) : null) }))); return ReactDOM.createPortal(modalNode, document.body); }; //# sourceMappingURL=Modal.js.map