| 1 |
(function () { |
| 2 |
var el = wp.element.createElement; |
| 3 |
var Fragment = wp.element.Fragment; |
| 4 |
var registerBlockType = wp.blocks.registerBlockType; |
| 5 |
var __ = wp.i18n.__; |
| 6 |
var InspectorControls = wp.blockEditor.InspectorControls; |
| 7 |
var PanelColorSettings = wp.blockEditor.PanelColorSettings; |
| 8 |
var useBlockProps = wp.blockEditor.useBlockProps; |
| 9 |
var PanelBody = wp.components.PanelBody; |
| 10 |
var TextControl = wp.components.TextControl; |
| 11 |
var TextareaControl = wp.components.TextareaControl; |
| 12 |
var ToggleControl = wp.components.ToggleControl; |
| 13 |
var RangeControl = wp.components.RangeControl; |
| 14 |
var SelectControl = wp.components.SelectControl; |
| 15 |
|
| 16 |
var _tc, _tv; |
| 17 |
function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); } |
| 18 |
function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); } |
| 19 |
|
| 20 |
// ── platform logos (SVG/text marks) ────────────────────────── |
| 21 |
function platformBadge(platform) { |
| 22 |
var styles = { |
| 23 |
display: 'inline-flex', alignItems: 'center', gap: '5px', |
| 24 |
fontSize: '11px', fontWeight: '800', letterSpacing: '0.04em', |
| 25 |
padding: '3px 10px', borderRadius: '20px', userSelect: 'none' |
| 26 |
}; |
| 27 |
if (platform === 'twitter') { |
| 28 |
return el('span', { style: Object.assign({}, styles, { background: '#15202b', color: '#1d9bf0' }) }, '𝕏 X / Twitter'); |
| 29 |
} |
| 30 |
if (platform === 'facebook') { |
| 31 |
return el('span', { style: Object.assign({}, styles, { background: '#1877f2', color: '#ffffff' }) }, 'f Facebook'); |
| 32 |
} |
| 33 |
if (platform === 'linkedin') { |
| 34 |
return el('span', { style: Object.assign({}, styles, { background: '#0a66c2', color: '#ffffff' }) }, 'in LinkedIn'); |
| 35 |
} |
| 36 |
if (platform === 'slack') { |
| 37 |
return el('span', { style: Object.assign({}, styles, { background: '#4a154b', color: '#36c5f0' }) }, '# Slack'); |
| 38 |
} |
| 39 |
return null; |
| 40 |
} |
| 41 |
|
| 42 |
// ── image placeholder ──────────────────────────────────────── |
| 43 |
function renderImagePlaceholder(a) { |
| 44 |
return el('div', { |
| 45 |
style: { |
| 46 |
height: a.imageHeight + 'px', |
| 47 |
background: a.imageBg, |
| 48 |
display: 'flex', alignItems: 'center', justifyContent: 'center', |
| 49 |
fontSize: Math.floor(a.imageHeight * 0.35) + 'px', |
| 50 |
userSelect: 'none' |
| 51 |
} |
| 52 |
}, a.imageEmoji || '🖼️'); |
| 53 |
} |
| 54 |
|
| 55 |
// ── card renderers ─────────────────────────────────────────── |
| 56 |
function renderTwitterCard(a) { |
| 57 |
var fs = (a.bodyTypo && a.bodyTypo.sizeDesktop) || a.fontSize || 14; |
| 58 |
return el('div', { |
| 59 |
style: { |
| 60 |
background: a.twitterBg, border: '1px solid ' + a.twitterBorder, |
| 61 |
borderRadius: '12px', overflow: 'hidden', maxWidth: '504px' |
| 62 |
} |
| 63 |
}, |
| 64 |
renderImagePlaceholder(a), |
| 65 |
el('div', { style: { padding: '12px 16px 14px' } }, |
| 66 |
el('div', { style: { color: a.twitterMeta, fontSize: (fs - 2) + 'px', marginBottom: '4px', textTransform: 'lowercase' } }, |
| 67 |
a.pageUrl |
| 68 |
), |
| 69 |
el('div', { style: { color: a.twitterTitle, fontWeight: '700', fontSize: (fs + 1) + 'px', lineHeight: '1.35', marginBottom: '4px' } }, |
| 70 |
a.pageTitle |
| 71 |
), |
| 72 |
a.showDescription ? el('div', { style: { color: a.twitterDesc, fontSize: (fs - 1) + 'px', lineHeight: '1.45', display: '-webkit-box', WebkitLineClamp: '2', WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, |
| 73 |
a.pageDescription |
| 74 |
) : null |
| 75 |
) |
| 76 |
); |
| 77 |
} |
| 78 |
|
| 79 |
function renderFacebookCard(a) { |
| 80 |
var fs = (a.bodyTypo && a.bodyTypo.sizeDesktop) || a.fontSize || 14; |
| 81 |
return el('div', { |
| 82 |
style: { |
| 83 |
background: a.facebookBg, border: '1px solid ' + a.facebookBorder, |
| 84 |
borderRadius: '4px', overflow: 'hidden', maxWidth: '504px' |
| 85 |
} |
| 86 |
}, |
| 87 |
renderImagePlaceholder(a), |
| 88 |
el('div', { style: { padding: '10px 12px 12px', borderTop: '1px solid ' + a.facebookBorder } }, |
| 89 |
el('div', { style: { color: a.facebookMeta, fontSize: '10px', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: '5px' } }, |
| 90 |
a.pageUrl |
| 91 |
), |
| 92 |
el('div', { style: { color: a.facebookTitle, fontWeight: '700', fontSize: fs + 'px', lineHeight: '1.3', marginBottom: '4px' } }, |
| 93 |
a.pageTitle |
| 94 |
), |
| 95 |
a.showDescription ? el('div', { style: { color: a.facebookDesc, fontSize: (fs - 1) + 'px', lineHeight: '1.45', display: '-webkit-box', WebkitLineClamp: '2', WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, |
| 96 |
a.pageDescription |
| 97 |
) : null, |
| 98 |
a.showSiteName ? el('div', { style: { color: a.facebookMeta, fontSize: '10px', textTransform: 'uppercase', letterSpacing: '0.05em', marginTop: '6px' } }, |
| 99 |
a.siteName |
| 100 |
) : null |
| 101 |
) |
| 102 |
); |
| 103 |
} |
| 104 |
|
| 105 |
function renderLinkedInCard(a) { |
| 106 |
var fs = (a.bodyTypo && a.bodyTypo.sizeDesktop) || a.fontSize || 14; |
| 107 |
return el('div', { |
| 108 |
style: { |
| 109 |
background: a.linkedinBg, border: '1px solid ' + a.linkedinBorder, |
| 110 |
borderRadius: '2px', overflow: 'hidden', maxWidth: '552px' |
| 111 |
} |
| 112 |
}, |
| 113 |
renderImagePlaceholder(a), |
| 114 |
el('div', { style: { padding: '12px 16px 14px' } }, |
| 115 |
el('div', { style: { color: a.linkedinTitle, fontWeight: '700', fontSize: (fs + 1) + 'px', lineHeight: '1.3', marginBottom: '4px' } }, |
| 116 |
a.pageTitle |
| 117 |
), |
| 118 |
a.showSiteName ? el('div', { style: { color: a.linkedinMeta, fontWeight: '600', fontSize: '12px', marginBottom: a.showDescription ? '4px' : '0' } }, |
| 119 |
a.siteName + ' › ' + a.pageUrl |
| 120 |
) : null, |
| 121 |
a.showDescription ? el('div', { style: { color: a.linkedinDesc, fontSize: (fs - 1) + 'px', lineHeight: '1.45', display: '-webkit-box', WebkitLineClamp: '3', WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, |
| 122 |
a.pageDescription |
| 123 |
) : null |
| 124 |
) |
| 125 |
); |
| 126 |
} |
| 127 |
|
| 128 |
function renderSlackCard(a) { |
| 129 |
var fs = (a.bodyTypo && a.bodyTypo.sizeDesktop) || a.fontSize || 14; |
| 130 |
return el('div', { |
| 131 |
style: { |
| 132 |
background: a.slackBg, border: '1px solid ' + a.slackBorder, |
| 133 |
borderRadius: '4px', overflow: 'hidden', maxWidth: '520px', |
| 134 |
display: 'flex' |
| 135 |
} |
| 136 |
}, |
| 137 |
// Colored left strip |
| 138 |
el('div', { style: { width: '4px', background: a.slackAccent, flexShrink: '0' } }), |
| 139 |
el('div', { style: { flex: '1', padding: '10px 12px 12px', display: 'flex', gap: '12px' } }, |
| 140 |
el('div', { style: { flex: '1' } }, |
| 141 |
a.showSiteName ? el('div', { style: { color: a.slackTitle, fontWeight: '700', fontSize: '12px', marginBottom: '4px' } }, |
| 142 |
a.siteName |
| 143 |
) : null, |
| 144 |
el('div', { style: { color: a.slackTitle, fontWeight: '700', fontSize: (fs - 1) + 'px', lineHeight: '1.3', marginBottom: '4px', textDecoration: 'underline', cursor: 'pointer' } }, |
| 145 |
a.pageTitle |
| 146 |
), |
| 147 |
a.showDescription ? el('div', { style: { color: a.slackDesc, fontSize: '12px', lineHeight: '1.5', display: '-webkit-box', WebkitLineClamp: '3', WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, |
| 148 |
a.pageDescription |
| 149 |
) : null, |
| 150 |
el('div', { style: { color: a.slackMeta, fontSize: '11px', marginTop: '6px' } }, a.pageUrl) |
| 151 |
), |
| 152 |
// Thumbnail |
| 153 |
el('div', { |
| 154 |
style: { |
| 155 |
width: '80px', height: '80px', flexShrink: '0', |
| 156 |
background: a.imageBg, borderRadius: '4px', |
| 157 |
display: 'flex', alignItems: 'center', justifyContent: 'center', |
| 158 |
fontSize: '28px', alignSelf: 'center' |
| 159 |
} |
| 160 |
}, a.imageEmoji || '🖼️') |
| 161 |
) |
| 162 |
); |
| 163 |
} |
| 164 |
|
| 165 |
// ── all platforms ──────────────────────────────────────────── |
| 166 |
function renderAllPlatforms(a) { |
| 167 |
var isGrid = a.layout === 'grid'; |
| 168 |
var platforms = [ |
| 169 |
{ key: 'twitter', label: 'Twitter / X', render: renderTwitterCard }, |
| 170 |
{ key: 'facebook', label: 'Facebook', render: renderFacebookCard }, |
| 171 |
{ key: 'linkedin', label: 'LinkedIn', render: renderLinkedInCard }, |
| 172 |
{ key: 'slack', label: 'Slack', render: renderSlackCard }, |
| 173 |
]; |
| 174 |
|
| 175 |
return el('div', { |
| 176 |
style: { |
| 177 |
display: isGrid ? 'grid' : 'flex', |
| 178 |
gridTemplateColumns: isGrid ? 'repeat(2, 1fr)' : undefined, |
| 179 |
flexDirection: isGrid ? undefined : 'column', |
| 180 |
gap: '20px' |
| 181 |
} |
| 182 |
}, |
| 183 |
platforms.map(function (p) { |
| 184 |
return el('div', { key: p.key }, |
| 185 |
el('div', { style: { marginBottom: '8px' } }, platformBadge(p.key)), |
| 186 |
p.render(a) |
| 187 |
); |
| 188 |
}) |
| 189 |
); |
| 190 |
} |
| 191 |
|
| 192 |
// ── edit ───────────────────────────────────────────────────── |
| 193 |
function Edit(props) { |
| 194 |
var a = props.attributes; |
| 195 |
var set = props.setAttributes; |
| 196 |
|
| 197 |
var platformOptions = [ |
| 198 |
{ value: 'all', label: 'All platforms' }, |
| 199 |
{ value: 'twitter', label: 'Twitter / X' }, |
| 200 |
{ value: 'facebook', label: 'Facebook' }, |
| 201 |
{ value: 'linkedin', label: 'LinkedIn' }, |
| 202 |
{ value: 'slack', label: 'Slack' }, |
| 203 |
]; |
| 204 |
|
| 205 |
var layoutOptions = [ |
| 206 |
{ value: 'stacked', label: 'Stacked (single column)' }, |
| 207 |
{ value: 'grid', label: 'Grid (2 columns)' }, |
| 208 |
]; |
| 209 |
|
| 210 |
function renderPreview() { |
| 211 |
if (a.platform === 'twitter') return renderTwitterCard(a); |
| 212 |
if (a.platform === 'facebook') return renderFacebookCard(a); |
| 213 |
if (a.platform === 'linkedin') return renderLinkedInCard(a); |
| 214 |
if (a.platform === 'slack') return renderSlackCard(a); |
| 215 |
return renderAllPlatforms(a); |
| 216 |
} |
| 217 |
|
| 218 |
var twitterColors = [ |
| 219 |
{ label: __('Card background'), value: a.twitterBg, onChange: function (v) { set({ twitterBg: v || '#15202b' }); } }, |
| 220 |
{ label: __('Border'), value: a.twitterBorder, onChange: function (v) { set({ twitterBorder: v || '#38444d' }); } }, |
| 221 |
{ label: __('Title'), value: a.twitterTitle, onChange: function (v) { set({ twitterTitle: v || '#ffffff' }); } }, |
| 222 |
{ label: __('Description'), value: a.twitterDesc, onChange: function (v) { set({ twitterDesc: v || '#8b98a5' }); } }, |
| 223 |
{ label: __('URL / meta'), value: a.twitterMeta, onChange: function (v) { set({ twitterMeta: v || '#6b7280' }); } }, |
| 224 |
]; |
| 225 |
|
| 226 |
var facebookColors = [ |
| 227 |
{ label: __('Card background'), value: a.facebookBg, onChange: function (v) { set({ facebookBg: v || '#ffffff' }); } }, |
| 228 |
{ label: __('Border'), value: a.facebookBorder, onChange: function (v) { set({ facebookBorder: v || '#dddfe2' }); } }, |
| 229 |
{ label: __('Title'), value: a.facebookTitle, onChange: function (v) { set({ facebookTitle: v || '#1c1e21' }); } }, |
| 230 |
{ label: __('Description'), value: a.facebookDesc, onChange: function (v) { set({ facebookDesc: v || '#606770' }); } }, |
| 231 |
{ label: __('URL / meta'), value: a.facebookMeta, onChange: function (v) { set({ facebookMeta: v || '#8a8d91' }); } }, |
| 232 |
]; |
| 233 |
|
| 234 |
var linkedinColors = [ |
| 235 |
{ label: __('Card background'), value: a.linkedinBg, onChange: function (v) { set({ linkedinBg: v || '#ffffff' }); } }, |
| 236 |
{ label: __('Border'), value: a.linkedinBorder, onChange: function (v) { set({ linkedinBorder: v || '#e0dfde' }); } }, |
| 237 |
{ label: __('Title'), value: a.linkedinTitle, onChange: function (v) { set({ linkedinTitle: v || '#000000' }); } }, |
| 238 |
{ label: __('Description'), value: a.linkedinDesc, onChange: function (v) { set({ linkedinDesc: v || '#434649' }); } }, |
| 239 |
{ label: __('URL / site name'), value: a.linkedinMeta, onChange: function (v) { set({ linkedinMeta: v || '#0a66c2' }); } }, |
| 240 |
]; |
| 241 |
|
| 242 |
var slackColors = [ |
| 243 |
{ label: __('Card background'), value: a.slackBg, onChange: function (v) { set({ slackBg: v || '#ffffff' }); } }, |
| 244 |
{ label: __('Border'), value: a.slackBorder, onChange: function (v) { set({ slackBorder: v || '#e8e8e8' }); } }, |
| 245 |
{ label: __('Accent strip'), value: a.slackAccent, onChange: function (v) { set({ slackAccent: v || '#36c5f0' }); } }, |
| 246 |
{ label: __('Title'), value: a.slackTitle, onChange: function (v) { set({ slackTitle: v || '#1d1c1d' }); } }, |
| 247 |
{ label: __('Description'), value: a.slackDesc, onChange: function (v) { set({ slackDesc: v || '#616061' }); } }, |
| 248 |
{ label: __('URL / meta'), value: a.slackMeta, onChange: function (v) { set({ slackMeta: v || '#868686' }); } }, |
| 249 |
]; |
| 250 |
|
| 251 |
var TypoCtrl = getTypoControl(); |
| 252 |
var blockProps = (function () { |
| 253 |
var bp = useBlockProps(); |
| 254 |
var _tvf = getTypoCssVars(); |
| 255 |
var s = { |
| 256 |
background: a.bgColor, |
| 257 |
borderRadius: a.borderRadius + 'px', |
| 258 |
padding: '24px', |
| 259 |
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' |
| 260 |
}; |
| 261 |
if (_tvf) { |
| 262 |
Object.assign(s, _tvf(a.bodyTypo, '--bkbg-ogp-bd-')); |
| 263 |
} |
| 264 |
bp.style = Object.assign(s, bp.style || {}); |
| 265 |
return bp; |
| 266 |
}()); |
| 267 |
|
| 268 |
var inspector = el(InspectorControls, {}, |
| 269 |
el(PanelBody, { title: __('Page Info'), initialOpen: true }, |
| 270 |
el(TextControl, { |
| 271 |
label: __('Page title'), value: a.pageTitle, __nextHasNoMarginBottom: true, |
| 272 |
onChange: function (v) { set({ pageTitle: v }); } |
| 273 |
}), |
| 274 |
el(TextareaControl, { |
| 275 |
label: __('Description'), value: a.pageDescription, rows: 3, __nextHasNoMarginBottom: true, |
| 276 |
onChange: function (v) { set({ pageDescription: v }); } |
| 277 |
}), |
| 278 |
el(TextControl, { |
| 279 |
label: __('URL (domain)'), value: a.pageUrl, __nextHasNoMarginBottom: true, |
| 280 |
onChange: function (v) { set({ pageUrl: v }); } |
| 281 |
}), |
| 282 |
el(TextControl, { |
| 283 |
label: __('Site name'), value: a.siteName, __nextHasNoMarginBottom: true, |
| 284 |
onChange: function (v) { set({ siteName: v }); } |
| 285 |
}), |
| 286 |
el(ToggleControl, { |
| 287 |
label: __('Show description'), checked: a.showDescription, __nextHasNoMarginBottom: true, |
| 288 |
onChange: function (v) { set({ showDescription: v }); } |
| 289 |
}), |
| 290 |
el(ToggleControl, { |
| 291 |
label: __('Show site name'), checked: a.showSiteName, __nextHasNoMarginBottom: true, |
| 292 |
onChange: function (v) { set({ showSiteName: v }); } |
| 293 |
}) |
| 294 |
), |
| 295 |
el(PanelBody, { title: __('Image Placeholder'), initialOpen: false }, |
| 296 |
el(TextControl, { |
| 297 |
label: __('Emoji'), value: a.imageEmoji, __nextHasNoMarginBottom: true, |
| 298 |
onChange: function (v) { set({ imageEmoji: v }); } |
| 299 |
}), |
| 300 |
el(RangeControl, { |
| 301 |
label: __('Image height'), value: a.imageHeight, min: 80, max: 320, __nextHasNoMarginBottom: true, |
| 302 |
onChange: function (v) { set({ imageHeight: v }); } |
| 303 |
}), |
| 304 |
el('div', { style: { marginBottom: '8px' } }, |
| 305 |
el('label', { style: { display: 'block', marginBottom: '6px', fontSize: '11px', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '.04em' } }, __('Image background color')), |
| 306 |
el('input', { |
| 307 |
type: 'color', value: a.imageBg, |
| 308 |
style: { width: '100%', height: '36px', border: '1px solid #ddd', borderRadius: '4px', cursor: 'pointer', padding: '2px' }, |
| 309 |
onChange: function (e) { set({ imageBg: e.target.value }); } |
| 310 |
}) |
| 311 |
) |
| 312 |
), |
| 313 |
el(PanelBody, { title: __('Display'), initialOpen: false }, |
| 314 |
el(SelectControl, { |
| 315 |
label: __('Show platform'), value: a.platform, options: platformOptions, __nextHasNoMarginBottom: true, |
| 316 |
onChange: function (v) { set({ platform: v }); } |
| 317 |
}), |
| 318 |
a.platform === 'all' ? el(SelectControl, { |
| 319 |
label: __('Layout'), value: a.layout, options: layoutOptions, __nextHasNoMarginBottom: true, |
| 320 |
onChange: function (v) { set({ layout: v }); } |
| 321 |
}) : null, |
| 322 |
el(RangeControl, { |
| 323 |
label: __('Wrapper border radius'), value: a.borderRadius, min: 0, max: 32, __nextHasNoMarginBottom: true, |
| 324 |
onChange: function (v) { set({ borderRadius: v }); } |
| 325 |
}), |
| 326 |
el('div', { style: { marginBottom: '8px' } }, |
| 327 |
el('label', { style: { display: 'block', marginBottom: '6px', fontSize: '11px', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '.04em' } }, __('Wrapper background')), |
| 328 |
el('input', { |
| 329 |
type: 'color', value: a.bgColor, |
| 330 |
style: { width: '100%', height: '36px', border: '1px solid #ddd', borderRadius: '4px', cursor: 'pointer', padding: '2px' }, |
| 331 |
onChange: function (e) { set({ bgColor: e.target.value }); } |
| 332 |
}) |
| 333 |
) |
| 334 |
), |
| 335 |
|
| 336 |
el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false }, |
| 337 |
TypoCtrl && el(TypoCtrl, { label: __('Body', 'blockenberg'), value: a.bodyTypo, onChange: function (v) { set({ bodyTypo: v }); } }) |
| 338 |
), |
| 339 |
el(PanelColorSettings, { title: __('Twitter / X Colors'), initialOpen: false, colorSettings: twitterColors }), |
| 340 |
el(PanelColorSettings, { title: __('Facebook Colors'), initialOpen: false, colorSettings: facebookColors }), |
| 341 |
el(PanelColorSettings, { title: __('LinkedIn Colors'), initialOpen: false, colorSettings: linkedinColors }), |
| 342 |
el(PanelColorSettings, { title: __('Slack Colors'), initialOpen: false, colorSettings: slackColors }) |
| 343 |
); |
| 344 |
|
| 345 |
return el(Fragment, {}, |
| 346 |
inspector, |
| 347 |
el('div', blockProps, |
| 348 |
renderPreview() |
| 349 |
) |
| 350 |
); |
| 351 |
} |
| 352 |
|
| 353 |
registerBlockType('blockenberg/open-graph-preview', { |
| 354 |
edit: Edit, |
| 355 |
save: function (props) { |
| 356 |
return el('div', useBlockProps.save(), |
| 357 |
el('div', { className: 'bkbg-open-graph-preview-app', 'data-opts': JSON.stringify(props.attributes) }) |
| 358 |
); |
| 359 |
} |
| 360 |
}); |
| 361 |
})(); |
| 362 |
|