PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / open-graph-preview / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/open-graph-preview/index.js

362 lines 20.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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