UNPKG

@mirrormedia/lilith-draft-renderer

Version:
420 lines (374 loc) 12.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DraftRenderer; exports.noSpacingBetweenContent = exports.draftEditorLineHeight = void 0; var _react = _interopRequireDefault(require("react")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _draftJs = require("draft-js"); var _blockRendererFn = require("./block-renderer-fn"); var _entityDecorator = _interopRequireDefault(require("./entity-decorator")); var _const = require("../../draft-js/const"); var _sharedStyle = require("./shared-style"); var _theme = _interopRequireDefault(require("./theme")); 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; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const blockquoteDecoration = "https://unpkg.com/@mirrormedia/lilith-draft-renderer@1.4.5/lib/public/662d20f531567a273f99efc70e8c85a6.png"; const draftEditorLineHeight = 2; /** * Due to the data structure from draftjs, each default block contain one HTML element which class name is `public-DraftStyleDefault-block`. * So we use this behavior to create spacing between blocks by assign margin-bottom of which. * However, some block should not set spacing (e.g. block in <li> and <blockquote>), so we need to unset its margin-top. */ exports.draftEditorLineHeight = draftEditorLineHeight; const noSpacingBetweenContent = { blockquote: (0, _styledComponents.css)` margin-bottom: unset; `, list: (0, _styledComponents.css)` margin-bottom: 4px; ` }; exports.noSpacingBetweenContent = noSpacingBetweenContent; const draftEditorCssNormal = (0, _styledComponents.css)` color: black; 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'; font-weight: normal; .public-DraftStyleDefault-header-two { font-size: 36px; line-height: 1.5; } .public-DraftStyleDefault-header-three { font-size: 30px; line-height: 1.5; } .public-DraftStyleDefault-header-four { } .public-DraftStyleDefault-blockquote { color: rgba(97, 184, 198, 1); border-image: linear-gradient( to right, rgba(97, 184, 198, 1) 42.5%, transparent 42.5%, transparent 57.5%, rgba(97, 184, 198, 1) 57.5% ) 100% 1; &::before { background-color: rgba(97, 184, 198, 1); } } `; const draftEditorCssWide = (0, _styledComponents.css)` color: rgba(64, 64, 64, 0.87); font-family: 'Noto Serif TC', source-han-serif-tc, 'Songti TC', serif, PMingLiU; font-weight: 600; font-size: 18px; line-height: 2; [style*='font-weight:bold'] { font-weight: 900 !important; } .public-DraftStyleDefault-header-two { text-align: center; color: black; font-size: 36px; font-weight: 700; } .public-DraftStyleDefault-header-three { text-align: center; color: black; font-size: 32px; font-weight: 700; } .public-DraftStyleDefault-header-four { } .public-DraftStyleDefault-blockquote { color: rgba(0, 0, 0, 1); 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'; font-weight: 400; border-image: linear-gradient( to right, rgba(0, 0, 0, 1) 42.5%, transparent 42.5%, transparent 57.5%, rgba(0, 0, 0, 1) 57.5% ) 100% 1; &::before { background-color: rgba(0, 0, 0, 1); } } `; const draftEditorCssPremium = (0, _styledComponents.css)` color: black; 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'; font-weight: normal; .public-DraftStyleDefault-header-two { color: rgba(5, 79, 119, 1); font-weight: 500; text-align: center; font-size: 36px; line-height: 1.5; } .public-DraftStyleDefault-header-three { color: rgba(5, 79, 119, 1); text-align: center; font-weight: 500; font-size: 30px; line-height: 1.5; } .public-DraftStyleDefault-header-four { } .public-DraftStyleDefault-blockquote { color: rgba(5, 79, 119, 1); border-image: linear-gradient( to right, rgba(5, 79, 119, 1) 42.5%, transparent 42.5%, transparent 57.5%, rgba(5, 79, 119, 1) 57.5% ) 100% 1; &::before { background-color: rgba(5, 79, 119, 1); } } `; //目前 Photography 文末樣式僅支援:H2, H3, 粗體、底線、斜體、超連結 //目前 photography 裡的 <figure> 都會被隱藏(因此 video、infobox、colorbox,就算在 CMS 裡上稿也都無法呈現 ) // Todo: 新增一個 util function 篩選出 Image const draftEditorCssPhotography = (0, _styledComponents.css)` color: white; 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'; font-weight: normal; .public-DraftStyleDefault-header-two { font-weight: 500; text-align: center; font-size: 24px; line-height: 1.5; ${({ theme }) => theme.breakpoint.md} { font-size: 32px; } } .public-DraftStyleDefault-header-three { text-align: center; font-weight: 500; font-size: 18px; line-height: 1.5; ${({ theme }) => theme.breakpoint.md} { font-size: 24px; } } `; const DraftEditorWrapper = _styledComponents.default.div` width: 100%; height: 100%; border: 0; padding: 0px; font-size: 18px; line-height: ${draftEditorLineHeight}; .public-DraftStyleDefault-block { ${_sharedStyle.defaultMarginBottom} } //last item in raw-content block should not have margin-bottom .public-DraftEditor-content { > div { > *:last-child { > *:last-child { margin-bottom: 0; } } } } /* Draft built-in buttons' style */ .public-DraftStyleDefault-blockquote { position: relative; width: 100%; margin: 0 auto; max-width: 480px; text-align: left; margin: 48px auto; padding-top: 34px; border-top: 2px solid; &::before { content: ''; position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%); width: 100%; height: 20px; mask-image: url(${blockquoteDecoration}); mask-repeat: no-repeat; mask-position: center center; } ${noSpacingBetweenContent.blockquote} ${({ theme }) => theme.breakpoint.md} { padding-top: 26px; } } .public-DraftStyleDefault-ul { margin-left: 18px; list-style: none; ${_sharedStyle.defaultMarginBottom} .public-DraftStyleDefault-block { ${noSpacingBetweenContent.list} } } .public-DraftStyleDefault-unorderedListItem { position: relative; &::before { content: ''; position: absolute; top: calc((1rem * ${draftEditorLineHeight}) / 2); left: -12px; width: 6px; height: 6px; transform: translateX(-50%); border-radius: 50%; background-color: #054f77; } } .public-DraftStyleDefault-ol { margin-left: 18px; ${_sharedStyle.defaultMarginBottom} .public-DraftStyleDefault-block { ${noSpacingBetweenContent.list} } } .public-DraftStyleDefault-orderedListItem { position: relative; counter-increment: list; padding-left: 6px; &::before { content: counter(list) '.'; position: absolute; color: #054f77; left: -15px; width: auto; } } /* code-block */ .public-DraftStyleDefault-pre { } ${({ contentLayout }) => { switch (contentLayout) { case 'normal': return draftEditorCssNormal; case 'wide': return draftEditorCssWide; case 'premium': return draftEditorCssPremium; case 'photography': return draftEditorCssPhotography; default: return draftEditorCssNormal; } }} .alignCenter * { text-align: center; } .alignLeft * { text-align: left; } `; const customStyleMap = { CODE: { backgroundColor: 'rgba(0, 0, 0, 0.05)', fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace', fontSize: 16, padding: 2 } }; const customStyleFn = style => { return style.reduce((styles, styleName) => { if (styleName !== null && styleName !== void 0 && styleName.startsWith(_const.CUSTOM_STYLE_PREFIX_FONT_COLOR)) { styles['color'] = styleName.split(_const.CUSTOM_STYLE_PREFIX_FONT_COLOR)[1]; } if (styleName !== null && styleName !== void 0 && styleName.startsWith(_const.CUSTOM_STYLE_PREFIX_BACKGROUND_COLOR)) { styles['backgroundColor'] = styleName.split(_const.CUSTOM_STYLE_PREFIX_BACKGROUND_COLOR)[1]; } return styles; }, {}); }; const blockStyleFn = (editorState, block) => { var _entity$getData; const entityKey = block.getEntityAt(0); const entity = entityKey ? editorState.getCurrentContent().getEntity(entityKey) : null; let result = ''; const blockData = block.getData(); if (blockData) { const textAlign = blockData === null || blockData === void 0 ? void 0 : blockData.get('textAlign'); if (textAlign === 'center') { result += 'alignCenter '; } else if (textAlign === 'left') { result += 'alignLeft '; } } switch (block.getType()) { case 'header-two': case 'header-three': case 'header-four': case 'blockquote': result += 'public-DraftStyleDefault-' + block.getType(); break; case 'atomic': if ((_entity$getData = entity.getData()) !== null && _entity$getData !== void 0 && _entity$getData.alignment) { // support all atomic block to set alignment result += ' ' + entity.getData().alignment; } break; default: break; } return result; }; /** * TODO: add type of params `rawContentBlock` */ function DraftRenderer({ rawContentBlock, contentLayout = 'normal', firstImageAdComponent }) { const contentState = (0, _draftJs.convertFromRaw)(rawContentBlock); const decorators = (0, _entityDecorator.default)(contentLayout); const editorState = _draftJs.EditorState.createWithContent(contentState, decorators); const blockRendererFn = block => { const atomicBlockObj = (0, _blockRendererFn.atomicBlockRenderer)(block, contentLayout, firstImageAdComponent); return atomicBlockObj; }; return /*#__PURE__*/_react.default.createElement(_styledComponents.ThemeProvider, { theme: _theme.default }, /*#__PURE__*/_react.default.createElement(DraftEditorWrapper, { contentLayout: contentLayout }, /*#__PURE__*/_react.default.createElement(_draftJs.Editor, { editorState: editorState, customStyleMap: customStyleMap, blockStyleFn: blockStyleFn.bind(null, editorState), blockRendererFn: blockRendererFn, customStyleFn: customStyleFn, readOnly: true // eslint-disable-next-line @typescript-eslint/no-empty-function , onChange: () => {} }))); }