UNPKG

@mirrormedia/lilith-draft-renderer

Version:
338 lines (311 loc) 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImageBlock = ImageBlock; var _react = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _reactImage = _interopRequireDefault(require("@readr-media/react-image")); var _sharedStyle = require("../shared-style"); var _bodyScrollLock = require("body-scroll-lock"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } //REMINDER: DO NOT REMOVE className which has prefix `GTM-`, since it is used for collecting data of Google Analytics event. const defaultImage = "https://unpkg.com/@mirrormedia/lilith-draft-renderer@1.4.0/lib/public/a3f3e41061aaaa6e12b4d1e5a07f280c.png"; const loadingImage = "https://unpkg.com/@mirrormedia/lilith-draft-renderer@1.4.0/lib/public/845924188760371aa28efbb3dea99d01.gif"; const imageFigureLayoutNormal = (0, _styledComponents.css)` .readr-media-react-image { width: 100%; } `; const imageFigureLayoutWide = (0, _styledComponents.css)` .readr-media-react-image { position: relative; max-width: calc(100% + 20px + 20px); width: 100vw; transform: translateX(-20px); @media (min-width: 680px) { max-width: 100%; transform: translateX(0px); } } `; const imageFigureLayoutPremium = (0, _styledComponents.css)` .readr-media-react-image { position: relative; max-width: calc(100% + 20px + 20px); width: 100vw; transform: translateX(-20px); @media (min-width: 680px) { max-width: 100%; transform: translateX(0px); } } `; const AmpImgWrapper = _styledComponents.default.section` margin-top: 20px; width: 100%; height: 50vw; position: relative; display: flex; justify-content: center; amp-img img { object-fit: contain; } `; const figcaptionLayoutNormal = (0, _styledComponents.css)` margin-top: 12px; ${({ theme }) => theme.breakpoint.md} { margin-top: 20px; } `; const figcaptionLayoutWide = (0, _styledComponents.css)` font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; padding-top: 12px; margin-top: 16px; position: relative; border-top: 1px solid rgba(0, 0, 0, 0.1); `; const Figure = _styledComponents.default.figure` /* margin-block: unset; */ /* margin-inline: unset; */ ${_sharedStyle.defaultMarginTop} ${_sharedStyle.defaultMarginBottom} .readr-media-react-image { cursor: pointer; aspect-ratio: ${({ aspectRatio }) => aspectRatio ? aspectRatio : 'inherit'}; } `; const ImageFigure = (0, _styledComponents.default)(Figure)` ${({ contentLayout }) => { switch (contentLayout) { case 'normal': return imageFigureLayoutNormal; case 'wide': return imageFigureLayoutWide; case 'premium': return imageFigureLayoutPremium; default: return imageFigureLayoutNormal; } }} `; const ImageWrapper = _styledComponents.default.div` position: relative; width: 100%; `; const AdWrapper = _styledComponents.default.div` position: absolute; bottom: 0; left: 0; `; const Figcaption = _styledComponents.default.figcaption` font-size: 14px; line-height: 1.8; font-weight: 400; color: rgba(0, 0, 0, 0.5); ${({ contentLayout }) => { switch (contentLayout) { case 'normal': return figcaptionLayoutNormal; case 'wide': return figcaptionLayoutWide; default: return figcaptionLayoutNormal; } }} `; const Anchor = _styledComponents.default.a` text-decoration: none; `; const LightBoxWrapper = _styledComponents.default.div` width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); position: fixed; top: 0; left: 0; z-index: 819; display: flex; justify-content: center; align-items: center; user-select: none; cursor: pointer; button { width: 36px; height: 36px; padding: 4px; display: flex; position: absolute; top: 0px; right: 0px; flex-direction: column; align-items: center; justify-content: center; &:focus { outline: none; } .close { border-radius: 50%; height: 20px; width: 20px; margin: 0 5px 0 0; position: relative; &:before, :after { position: absolute; left: 8.5px; top: 5px; transform: translate(-50%, -50%); content: ' '; height: 25.5px; width: 1.2px; background-color: #fff; } &:before { transform: rotate(45deg); } &:after { transform: rotate(-45deg); } } } .readr-media-react-image { max-width: 90vw; max-height: 90vh; margin: 0 auto; cursor: auto; } `; function ImageBlock(props) { const { block, contentState, blockProps } = props; const entityKey = block.getEntityAt(0); const entity = contentState.getEntity(entityKey); const { contentLayout = 'normal', firstImageAdComponent } = blockProps; const lightBoxRef = (0, _react.useRef)(null); const isAmp = contentLayout === 'amp'; const [shouldOpenLightBox, setShouldOpenLightBox] = (0, _react.useState)(false); const { name, desc, resized, url, resizedWebp = null, imageFile = {}, isFirstImage } = entity.getData(); //imageFile in possibly a `null` const aspectRatio = imageFile && imageFile !== null && imageFile !== void 0 && imageFile.width && imageFile !== null && imageFile !== void 0 && imageFile.height ? `${imageFile.width} / ${imageFile.height}` : 'inherit'; const hasDescription = Boolean(desc); (0, _react.useEffect)(() => { if (lightBoxRef && lightBoxRef.current) { const lightBox = lightBoxRef.current; if (shouldOpenLightBox) { (0, _bodyScrollLock.disableBodyScroll)(lightBox); } else { (0, _bodyScrollLock.enableBodyScroll)(lightBox); } } return () => { (0, _bodyScrollLock.clearAllBodyScrollLocks)(); }; }, [shouldOpenLightBox]); const handleOpen = () => { if (url) { return; } setShouldOpenLightBox(true); }; const imageJsx = isAmp ? /*#__PURE__*/ /** * The rules for fallback of the heroImage: * 1. Show w1600 first. * 2. If the URL of w1600 is an empty string or an invalid URL, then show the original by using <amp-img> with `fallback` attribute. * 3. If the URL of original is an empty string, then show the default image url by replacing src of <amp-img>. */ _react.default.createElement(AmpImgWrapper, null, resized ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("amp-img", { src: resized === null || resized === void 0 ? void 0 : resized.w1600, alt: name, layout: "fill" }, /*#__PURE__*/_react.default.createElement("amp-img", { fallback: "", src: resized !== null && resized !== void 0 && resized.original ? resized === null || resized === void 0 ? void 0 : resized.original : defaultImage, alt: name, layout: "fill" }))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("amp-img", { src: defaultImage, alt: name, layout: "fill" }))) : /*#__PURE__*/_react.default.createElement(ImageWrapper, { contentLayout: contentLayout }, /*#__PURE__*/_react.default.createElement(_reactImage.default, { images: resized, imagesWebP: resizedWebp, defaultImage: defaultImage, loadingImage: loadingImage, width: '', height: 'auto', objectFit: 'contain', alt: name, rwd: { mobile: '100vw', tablet: '640px', default: '640px' }, priority: false }), isFirstImage ? /*#__PURE__*/_react.default.createElement(AdWrapper, null, firstImageAdComponent) : null); const imageFigureJsx = /*#__PURE__*/_react.default.createElement(ImageFigure, { key: resized.original, contentLayout: contentLayout, aspectRatio: aspectRatio, onClick: handleOpen }, imageJsx, hasDescription && /*#__PURE__*/_react.default.createElement(Figcaption, { contentLayout: contentLayout, onClick: e => e.stopPropagation() }, desc)); const lightBox = /*#__PURE__*/_react.default.createElement(LightBoxWrapper, { onClick: () => setShouldOpenLightBox(false) }, /*#__PURE__*/_react.default.createElement(Figure, { ref: lightBoxRef, onClick: e => e.stopPropagation() }, /*#__PURE__*/_react.default.createElement(_reactImage.default, { images: resized, imagesWebP: resizedWebp, defaultImage: defaultImage, loadingImage: loadingImage, alt: name, rwd: { mobile: '90vw', default: '90vw' }, width: '', height: '', priority: false })), /*#__PURE__*/_react.default.createElement("button", null, /*#__PURE__*/_react.default.createElement("i", { className: "close" }))); const renderImageBlockJsx = url ? /*#__PURE__*/_react.default.createElement(Anchor, { href: url, target: "_blank", className: "GTM-story-image" }, imageFigureJsx) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, shouldOpenLightBox && lightBox, imageFigureJsx); return renderImageBlockJsx; }