UNPKG

ghost

Version:

The professional publishing platform

213 lines (178 loc) 9.18 kB
const {renderEmailButton} = require('../render-partials/email-button'); const {addCreateDocumentOption} = require('../render-utils/add-create-document-option'); const {slugify} = require('../render-utils/slugify'); const {getSrcsetAttribute} = require('../render-utils/srcset-attribute'); // TODO: nodeData.buttonTextColor should be calculated on the fly here rather than hardcoded by the editor function cardTemplate(nodeData, options = {}) { const cardClasses = getCardClasses(nodeData).join(' '); const backgroundAccent = nodeData.backgroundColor === 'accent' ? 'kg-style-accent' : ''; const buttonAccent = nodeData.buttonColor === 'accent' ? 'kg-style-accent' : ''; const buttonStyle = nodeData.buttonColor !== 'accent' ? `background-color: ${nodeData.buttonColor};` : ``; const alignment = nodeData.alignment === 'center' ? 'kg-align-center' : ''; const backgroundImageStyle = nodeData.backgroundColor !== 'accent' && (!nodeData.backgroundImageSrc || nodeData.layout === 'split') ? `background-color: ${nodeData.backgroundColor}` : ''; let imgTemplate = ''; if (nodeData.backgroundImageSrc) { const bgImage = { src: nodeData.backgroundImageSrc, width: nodeData.backgroundImageWidth, height: nodeData.backgroundImageHeight }; const srcsetValue = getSrcsetAttribute({...bgImage, options}); const srcset = srcsetValue ? `srcset="${srcsetValue}"` : ''; imgTemplate = ` <picture><img class="kg-header-card-image" src="${bgImage.src}" ${srcset} loading="lazy" alt="" /></picture> `; } const header = () => { if (nodeData.header) { return `<h2 id="${slugify(nodeData.header)}" class="kg-header-card-heading" style="color: ${nodeData.textColor};" data-text-color="${nodeData.textColor}">${nodeData.header}</h2>`; } return ''; }; const subheader = () => { if (nodeData.subheader) { return `<p id="${slugify(nodeData.subheader)}" class="kg-header-card-subheading" style="color: ${nodeData.textColor};" data-text-color="${nodeData.textColor}">${nodeData.subheader}</p>`; } return ''; }; const button = () => { if (nodeData.buttonEnabled && nodeData.buttonUrl && nodeData.buttonUrl.trim() !== '') { return `<a href="${nodeData.buttonUrl}" class="kg-header-card-button ${buttonAccent}" style="${buttonStyle}color: ${nodeData.buttonTextColor};" data-button-color="${nodeData.buttonColor}" data-button-text-color="${nodeData.buttonTextColor}">${nodeData.buttonText}</a>`; } return ''; }; const wrapperStyle = backgroundImageStyle ? `style="${backgroundImageStyle};"` : ''; return ` <div class="${cardClasses} ${backgroundAccent}" ${wrapperStyle} data-background-color="${nodeData.backgroundColor}"> ${nodeData.layout !== 'split' ? imgTemplate : ''} <div class="kg-header-card-content"> ${nodeData.layout === 'split' ? imgTemplate : ''} <div class="kg-header-card-text ${alignment}"> ${header()} ${subheader()} ${button()} </div> </div> </div> `; } function emailTemplate(nodeData, options) { const backgroundAccent = nodeData.backgroundColor === 'accent' ? `background-color: ${nodeData.accentColor};` : ''; const alignment = nodeData.alignment === 'center' ? 'text-align: center;' : ''; const backgroundImageStyle = nodeData.backgroundImageSrc ? (nodeData.layout !== 'split' ? `background-image: url(${nodeData.backgroundImageSrc}); background-size: cover; background-position: center center;` : `background-color: ${nodeData.backgroundColor};`) : `background-color: ${nodeData.backgroundColor};`; const splitImageStyle = `background-image: url(${nodeData.backgroundImageSrc}); background-size: ${nodeData.backgroundSize !== 'contain' ? 'cover' : '50%'}; background-position: center`; const showButton = nodeData.buttonEnabled && nodeData.buttonUrl && nodeData.buttonUrl.trim() !== ''; const buttonHtml = renderEmailButton({ url: nodeData.buttonUrl, text: nodeData.buttonText, alignment: nodeData.alignment, color: nodeData.buttonColor, style: options?.design?.buttonStyle }); const hasDarkBg = nodeData.textColor?.toLowerCase() === '#ffffff'; return ( ` <div class="kg-header-card kg-v2${hasDarkBg ? ' kg-header-card-dark-bg' : 'kg-header-card-light-bg'}" style="color:${nodeData.textColor}; ${alignment} ${backgroundImageStyle} ${backgroundAccent}"> ${nodeData.layout === 'split' && nodeData.backgroundImageSrc ? ` <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td background="${nodeData.backgroundImageSrc}" style="${splitImageStyle}" class="kg-header-card-image"></td> </tr> </table> ` : ''} <table border="0" cellpadding="0" cellspacing="0" width="100%" style="color:${nodeData.textColor}; ${alignment} ${backgroundImageStyle} ${backgroundAccent}"> <tr> <td class="kg-header-card-content" style="${nodeData.layout === 'split' && nodeData.backgroundSize === 'contain' ? 'padding-top: 0;' : ''}"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td align="${nodeData.alignment}"> <h2 class="kg-header-card-heading" style="color:${nodeData.textColor};">${nodeData.header}</h2> </td> </tr> <tr> <td class="kg-header-card-subheading-wrapper" align="${nodeData.alignment}"> <p class="kg-header-card-subheading" style="color:${nodeData.textColor};">${nodeData.subheader}</p> </td> </tr> <tr> ${showButton ? ` <td class="kg-header-button-wrapper"> ${buttonHtml} </td> ` : ''} </tr> </table> </td> </tr> </table> </div> ` ); } function renderHeaderNodeV2(dataset, options = {}) { addCreateDocumentOption(options); const document = options.createDocument(); const node = { alignment: dataset.__alignment, buttonText: dataset.__buttonText, buttonEnabled: dataset.__buttonEnabled, buttonUrl: dataset.__buttonUrl, header: dataset.__header, subheader: dataset.__subheader, backgroundImageSrc: dataset.__backgroundImageSrc, backgroundImageWidth: dataset.__backgroundImageWidth, backgroundImageHeight: dataset.__backgroundImageHeight, backgroundSize: dataset.__backgroundSize, backgroundColor: dataset.__backgroundColor, buttonColor: dataset.__buttonColor, layout: dataset.__layout, textColor: dataset.__textColor, buttonTextColor: dataset.__buttonTextColor, swapped: dataset.__swapped, accentColor: dataset.__accentColor }; if (options.target === 'email') { const emailDoc = options.createDocument(); const emailDiv = emailDoc.createElement('div'); emailDiv.innerHTML = emailTemplate(node, options)?.trim(); return {element: emailDiv.firstElementChild}; } const htmlString = cardTemplate(node, options); const element = document.createElement('div'); element.innerHTML = htmlString?.trim(); if (node.header === '') { const h2Element = element.querySelector('.kg-header-card-heading'); if (h2Element) { h2Element.remove(); } } if (node.subheader === '') { const pElement = element.querySelector('.kg-header-card-subheading'); if (pElement) { pElement.remove(); } } return {element: element.firstElementChild}; } function getCardClasses(nodeData) { let cardClasses = ['kg-card kg-header-card kg-v2']; if (nodeData.layout && nodeData.layout !== 'split') { cardClasses.push(`kg-width-${nodeData.layout}`); } if (nodeData.layout === 'split') { cardClasses.push('kg-layout-split kg-width-full'); } if (nodeData.swapped && nodeData.layout === 'split') { cardClasses.push('kg-swapped'); } if (nodeData.layout && nodeData.layout === 'full') { cardClasses.push(`kg-content-wide`); } if (nodeData.layout === 'split') { if (nodeData.backgroundSize === 'contain') { cardClasses.push('kg-content-wide'); } } return cardClasses; } module.exports = renderHeaderNodeV2;