PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.14
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.14
2.0.14 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 / value-proposition / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.14, at blocks/value-proposition/index.js

454 lines 24.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 RichText = wp.blockEditor.RichText;
5 var __ = wp.i18n.__;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
10 var PanelBody = wp.components.PanelBody;
11 var Button = wp.components.Button;
12 var TextControl = wp.components.TextControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var RangeControl = wp.components.RangeControl;
15 var SelectControl = wp.components.SelectControl;
16
17 // Resolve the shared components lazily without defining globals for each block.
18 function _tc(label, key, attrs, setA) {
19 var Control = window.bkbgTypographyControl;
20 return Control ? el(Control, {
21 label: label,
22 value: attrs[key] || {},
23 onChange: function (value) { var update = {}; update[key] = value; setA(update); }
24 }) : null;
25 }
26 function _tvf(vars, key, attrs, prefix) {
27 var cssVars = window.bkbgTypoCssVars;
28 if (cssVars) Object.assign(vars, cssVars(attrs[key] || {}, prefix));
29 return vars;
30 }
31 function getTypoControl(label, key, attrs, setA) { return _tc(label, key, attrs, setA); }
32 function getTypoCssVars(attrs) {
33 var v = {};
34 _tvf(v, 'headlineTypo', attrs, '--bkvp-hl-');
35 _tvf(v, 'subTypo', attrs, '--bkvp-sb-');
36 _tvf(v, 'benefitTitleTypo', attrs, '--bkvp-bt-');
37 _tvf(v, 'benefitTextTypo', attrs, '--bkvp-bd-');
38 return v;
39 }
40
41 function updateItem(arr, idx, field, val) {
42 return arr.map(function (e, i) {
43 if (i !== idx) return e;
44 var u = {}; u[field] = val;
45 return Object.assign({}, e, u);
46 });
47 }
48
49 registerBlockType('blockenberg/value-proposition', {
50 title: __('Value Proposition', 'blockenberg'),
51 icon: 'star-filled',
52 category: 'bkbg-marketing',
53 description: __('Compelling value prop section with headline, USP benefits, proof badges, and CTA.', 'blockenberg'),
54
55 edit: function (props) {
56 var a = props.attributes;
57 var set = props.setAttributes;
58
59 var layoutOptions = [
60 { label: __('Centered', 'blockenberg'), value: 'center' },
61 { label: __('Left aligned', 'blockenberg'), value: 'left' }
62 ];
63 var styleOptions = [
64 { label: __('Clean', 'blockenberg'), value: 'clean' },
65 { label: __('Card', 'blockenberg'), value: 'card' },
66 { label: __('Bordered', 'blockenberg'), value: 'bordered' }
67 ];
68 var colOptions = [
69 { label: '1 column', value: 1 },
70 { label: '2 columns', value: 2 },
71 { label: '3 columns', value: 3 }
72 ];
73 var fontWeightOptions = [
74 { label: '400', value: 400 }, { label: '500', value: 500 },
75 { label: '600', value: 600 }, { label: '700', value: 700 },
76 { label: '800', value: 800 }, { label: '900', value: 900 }
77 ];
78
79 var textAlign = a.layout === 'center' ? 'center' : 'left';
80 var justifyContent = a.layout === 'center' ? 'center' : 'flex-start';
81
82 var inspector = el(InspectorControls, {},
83 // Structure
84 el(PanelBody, { title: __('Structure', 'blockenberg'), initialOpen: true },
85 el(SelectControl, {
86 label: __('Layout', 'blockenberg'),
87 value: a.layout, options: layoutOptions, __nextHasNoMarginBottom: true,
88 onChange: function (v) { set({ layout: v }); }
89 }),
90 el(SelectControl, {
91 label: __('Benefit columns', 'blockenberg'),
92 value: a.benefitColumns, options: colOptions, __nextHasNoMarginBottom: true,
93 onChange: function (v) { set({ benefitColumns: parseInt(v, 10) }); }
94 }),
95 el(SelectControl, {
96 label: __('Style', 'blockenberg'),
97 value: a.style, options: styleOptions, __nextHasNoMarginBottom: true,
98 onChange: function (v) { set({ style: v }); }
99 }),
100 el(ToggleControl, {
101 label: __('Show eyebrow label', 'blockenberg'),
102 checked: a.showEyebrow, __nextHasNoMarginBottom: true,
103 onChange: function (v) { set({ showEyebrow: v }); }
104 }),
105 el(ToggleControl, {
106 label: __('Show subheadline', 'blockenberg'),
107 checked: a.showSubheadline, __nextHasNoMarginBottom: true,
108 onChange: function (v) { set({ showSubheadline: v }); }
109 }),
110 el(ToggleControl, {
111 label: __('Show proof badges', 'blockenberg'),
112 checked: a.showBadges, __nextHasNoMarginBottom: true,
113 onChange: function (v) { set({ showBadges: v }); }
114 }),
115 el(ToggleControl, {
116 label: __('Show primary CTA', 'blockenberg'),
117 checked: a.showCta, __nextHasNoMarginBottom: true,
118 onChange: function (v) { set({ showCta: v }); }
119 }),
120 el(ToggleControl, {
121 label: __('Show secondary CTA', 'blockenberg'),
122 checked: a.showSecondaryCta, __nextHasNoMarginBottom: true,
123 onChange: function (v) { set({ showSecondaryCta: v }); }
124 })
125 ),
126
127 // CTA Links
128 el(PanelBody, { title: __('CTA Links', 'blockenberg'), initialOpen: false },
129 el(TextControl, {
130 label: __('Primary CTA URL', 'blockenberg'),
131 value: a.ctaUrl, type: 'url', __nextHasNoMarginBottom: true,
132 onChange: function (v) { set({ ctaUrl: v }); }
133 }),
134 el(TextControl, {
135 label: __('Secondary CTA URL', 'blockenberg'),
136 value: a.ctaSecondaryUrl, type: 'url', __nextHasNoMarginBottom: true,
137 onChange: function (v) { set({ ctaSecondaryUrl: v }); }
138 })
139 ),
140
141 // Badges
142 el(PanelBody, { title: __('Proof Badges', 'blockenberg'), initialOpen: false },
143 a.badges.map(function (badge, i) {
144 return el('div', { key: 'badge-' + i, style: { marginBottom: '12px', padding: '10px', background: '#f8fafc', borderRadius: '6px' } },
145 el('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '6px' } },
146 el('strong', {}, __('Badge', 'blockenberg') + ' ' + (i + 1)),
147 el(Button, { isDestructive: true, isSmall: true, icon: 'trash',
148 onClick: function () { set({ badges: a.badges.filter(function (_, j) { return j !== i; }) }); }
149 })
150 ),
151 el(TextControl, {
152 label: __('Icon / Emoji', 'blockenberg'), value: badge.icon, __nextHasNoMarginBottom: true,
153 onChange: function (v) { set({ badges: updateItem(a.badges, i, 'icon', v) }); }
154 }),
155 el(TextControl, {
156 label: __('Text', 'blockenberg'), value: badge.text, __nextHasNoMarginBottom: true,
157 onChange: function (v) { set({ badges: updateItem(a.badges, i, 'text', v) }); }
158 })
159 );
160 }),
161 el(Button, {
162 variant: 'secondary', isSmall: true, icon: 'plus-alt2',
163 onClick: function () { set({ badges: a.badges.concat([{ icon: '✨', text: 'New Badge' }]) }); }
164 }, __('Add Badge', 'blockenberg'))
165 ),
166
167 // Benefits (managed in sidebar for icon/description, inline for title)
168 el(PanelBody, { title: __('Benefits', 'blockenberg'), initialOpen: false },
169 a.benefits.map(function (ben, i) {
170 return el('div', { key: 'ben-' + i, style: { marginBottom: '12px', padding: '10px', background: '#f8fafc', borderRadius: '6px' } },
171 el('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '6px' } },
172 el('strong', {}, __('Benefit', 'blockenberg') + ' ' + (i + 1)),
173 el(Button, { isDestructive: true, isSmall: true, icon: 'trash',
174 onClick: function () { set({ benefits: a.benefits.filter(function (_, j) { return j !== i; }) }); }
175 })
176 ),
177 el(TextControl, {
178 label: __('Icon / Emoji', 'blockenberg'), value: ben.icon, __nextHasNoMarginBottom: true,
179 onChange: function (v) { set({ benefits: updateItem(a.benefits, i, 'icon', v) }); }
180 }),
181 el(TextControl, {
182 label: __('Title', 'blockenberg'), value: ben.title, __nextHasNoMarginBottom: true,
183 onChange: function (v) { set({ benefits: updateItem(a.benefits, i, 'title', v) }); }
184 }),
185 el(TextControl, {
186 label: __('Description', 'blockenberg'), value: ben.description, __nextHasNoMarginBottom: true,
187 onChange: function (v) { set({ benefits: updateItem(a.benefits, i, 'description', v) }); }
188 })
189 );
190 }),
191 el(Button, {
192 variant: 'secondary', isSmall: true, icon: 'plus-alt2',
193 onClick: function () {
194 set({ benefits: a.benefits.concat([{ icon: '✨', title: 'New Benefit', description: 'Describe this benefit here.' }]) });
195 }
196 }, __('Add Benefit', 'blockenberg'))
197 ),
198
199 // Spacing
200 el(PanelBody, { title: __('Spacing & Shape', 'blockenberg'), initialOpen: false },
201 el(RangeControl, {
202 label: __('Section padding (vertical)', 'blockenberg'),
203 value: a.paddingV, min: 16, max: 120, __nextHasNoMarginBottom: true,
204 onChange: function (v) { set({ paddingV: v }); }
205 }),
206 el(RangeControl, {
207 label: __('Section padding (horizontal)', 'blockenberg'),
208 value: a.paddingH, min: 0, max: 80, __nextHasNoMarginBottom: true,
209 onChange: function (v) { set({ paddingH: v }); }
210 }),
211 el(RangeControl, {
212 label: __('Benefit card gap', 'blockenberg'),
213 value: a.gap, min: 8, max: 48, __nextHasNoMarginBottom: true,
214 onChange: function (v) { set({ gap: v }); }
215 }),
216 el(RangeControl, {
217 label: __('Border radius', 'blockenberg'),
218 value: a.borderRadius, min: 0, max: 32, __nextHasNoMarginBottom: true,
219 onChange: function (v) { set({ borderRadius: v }); }
220 })
221 ),
222
223 // Typography
224 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
225 getTypoControl(__('Headline', 'blockenberg'), 'headlineTypo', a, set),
226 getTypoControl(__('Subheadline', 'blockenberg'), 'subTypo', a, set),
227 getTypoControl(__('Benefit Title', 'blockenberg'), 'benefitTitleTypo', a, set),
228 getTypoControl(__('Benefit Text', 'blockenberg'), 'benefitTextTypo', a, set)
229 ),
230
231 // Colors
232 el(PanelBody, { title: __('Colors', 'blockenberg'), initialOpen: false },
233 el(PanelColorSettings, {
234 title: __('Header Colors', 'blockenberg'), initialOpen: false,
235 colorSettings: [
236 { value: a.bgColor, label: __('Section background', 'blockenberg'), onChange: function (c) { set({ bgColor: c }); } },
237 { value: a.accentColor, label: __('Accent', 'blockenberg'), onChange: function (c) { set({ accentColor: c }); } },
238 { value: a.eyebrowColor, label: __('Eyebrow', 'blockenberg'), onChange: function (c) { set({ eyebrowColor: c }); } },
239 { value: a.headlineColor, label: __('Headline', 'blockenberg'), onChange: function (c) { set({ headlineColor: c }); } },
240 { value: a.subColor, label: __('Subheadline', 'blockenberg'), onChange: function (c) { set({ subColor: c }); } }
241 ]
242 }),
243 el(PanelColorSettings, {
244 title: __('Benefit Card Colors', 'blockenberg'), initialOpen: false,
245 colorSettings: [
246 { value: a.benefitBg, label: __('Card background', 'blockenberg'), onChange: function (c) { set({ benefitBg: c }); } },
247 { value: a.benefitBorderColor, label: __('Card border', 'blockenberg'), onChange: function (c) { set({ benefitBorderColor: c }); } },
248 { value: a.iconBg, label: __('Icon background', 'blockenberg'), onChange: function (c) { set({ iconBg: c }); } },
249 { value: a.benefitTitleColor, label: __('Benefit title', 'blockenberg'), onChange: function (c) { set({ benefitTitleColor: c }); } },
250 { value: a.benefitTextColor, label: __('Benefit text', 'blockenberg'), onChange: function (c) { set({ benefitTextColor: c }); } }
251 ]
252 }),
253 el(PanelColorSettings, {
254 title: __('CTA & Badge Colors', 'blockenberg'), initialOpen: false,
255 colorSettings: [
256 { value: a.ctaBg, label: __('CTA background', 'blockenberg'), onChange: function (c) { set({ ctaBg: c }); } },
257 { value: a.ctaColor, label: __('CTA text', 'blockenberg'), onChange: function (c) { set({ ctaColor: c }); } },
258 { value: a.ctaSecondaryColor, label: __('Secondary CTA', 'blockenberg'), onChange: function (c) { set({ ctaSecondaryColor: c }); } },
259 { value: a.badgeBg, label: __('Badge background', 'blockenberg'), onChange: function (c) { set({ badgeBg: c }); } },
260 { value: a.badgeColor, label: __('Badge text', 'blockenberg'), onChange: function (c) { set({ badgeColor: c }); } }
261 ]
262 })
263 )
264 );
265
266 // ── Preview ──────────────────────────────────────────────
267 var colTemplate = a.benefitColumns === 1 ? '1fr' : a.benefitColumns === 3 ? '1fr 1fr 1fr' : '1fr 1fr';
268
269 var benefitsGrid = el('div', {
270 style: {
271 display: 'grid', gridTemplateColumns: colTemplate,
272 gap: a.gap + 'px', marginTop: '32px'
273 }
274 },
275 a.benefits.map(function (ben, i) {
276 var cardStyle = {
277 padding: '20px',
278 background: a.benefitBg,
279 borderRadius: a.borderRadius + 'px'
280 };
281 if (a.style === 'card') {
282 cardStyle.boxShadow = '0 2px 12px rgba(0,0,0,0.07)';
283 cardStyle.border = '1px solid ' + a.benefitBorderColor;
284 } else if (a.style === 'bordered') {
285 cardStyle.border = '1px solid ' + a.benefitBorderColor;
286 }
287
288 return el('div', { key: 'ben-' + i, style: cardStyle },
289 el('div', {
290 style: {
291 width: '44px', height: '44px', borderRadius: '10px',
292 background: a.iconBg, display: 'flex', alignItems: 'center',
293 justifyContent: 'center', fontSize: '22px', marginBottom: '12px'
294 }
295 }, ben.icon),
296 el('div', {
297 className: 'bkbg-vp-benefit-title',
298 style: {
299 color: a.benefitTitleColor
300 }
301 }, ben.title),
302 el('div', {
303 className: 'bkbg-vp-benefit-text',
304 style: { color: a.benefitTextColor }
305 }, ben.description)
306 );
307 })
308 );
309
310 var blockProps = useBlockProps((function () {
311 var s = getTypoCssVars(a);
312 return { className: 'bkbg-editor-wrap', 'data-block-label': 'Value Proposition', style: s };
313 })());
314
315 return el('div', blockProps,
316 inspector,
317 el('div', {
318 className: 'bkbg-vp-block',
319 style: {
320 background: a.bgColor,
321 padding: a.paddingV + 'px ' + a.paddingH + 'px',
322 textAlign: textAlign
323 }
324 },
325 // Eyebrow
326 a.showEyebrow && el('div', {
327 style: {
328 display: 'inline-block', background: a.accentColor + '18',
329 color: a.eyebrowColor, fontWeight: 700, fontSize: '13px',
330 letterSpacing: '.07em', textTransform: 'uppercase',
331 padding: '4px 14px', borderRadius: '100px', marginBottom: '16px'
332 }
333 },
334 el('input', {
335 type: 'text', value: a.eyebrow,
336 style: {
337 background: 'transparent', border: 'none', outline: 'none',
338 color: 'inherit', fontWeight: 'inherit', fontSize: 'inherit',
339 letterSpacing: 'inherit', textAlign: textAlign, width: '100%'
340 },
341 onChange: function (e) { set({ eyebrow: e.target.value }); }
342 })
343 ),
344
345 // Headline
346 el('h2', {
347 className: 'bkbg-vp-headline',
348 style: {
349 color: a.headlineColor, maxWidth: '800px',
350 marginLeft: a.layout === 'center' ? 'auto' : '0',
351 marginRight: a.layout === 'center' ? 'auto' : '0'
352 }
353 },
354 el('textarea', {
355 value: a.headline, rows: 2,
356 style: {
357 width: '100%', background: 'transparent', border: 'none', outline: 'none',
358 resize: 'none', font: 'inherit', letterSpacing: 'inherit', wordSpacing: 'inherit',
359 textTransform: 'inherit', fontStyle: 'inherit', textDecoration: 'inherit',
360 color: 'inherit', textAlign: textAlign
361 },
362 onChange: function (e) { set({ headline: e.target.value }); }
363 })
364 ),
365
366 // Subheadline
367 a.showSubheadline && el('p', {
368 className: 'bkbg-vp-sub',
369 style: {
370 color: a.subColor, maxWidth: '640px',
371 marginLeft: a.layout === 'center' ? 'auto' : '0',
372 marginRight: a.layout === 'center' ? 'auto' : '0'
373 }
374 },
375 el('textarea', {
376 value: a.subheadline, rows: 3,
377 style: {
378 width: '100%', background: 'transparent', border: 'none', outline: 'none',
379 resize: 'none', font: 'inherit', letterSpacing: 'inherit', wordSpacing: 'inherit',
380 textTransform: 'inherit', fontStyle: 'inherit', textDecoration: 'inherit',
381 color: 'inherit', textAlign: textAlign
382 },
383 onChange: function (e) { set({ subheadline: e.target.value }); }
384 })
385 ),
386
387 // CTA buttons
388 (a.showCta || a.showSecondaryCta) && el('div', {
389 style: {
390 display: 'flex', gap: '12px', flexWrap: 'wrap',
391 justifyContent: justifyContent, marginBottom: '32px'
392 }
393 },
394 a.showCta && el('input', {
395 type: 'text', value: a.ctaText,
396 style: {
397 background: a.ctaBg, color: a.ctaColor, fontWeight: 700,
398 fontSize: '15px', padding: '12px 24px', borderRadius: a.borderRadius + 'px',
399 border: 'none', outline: 'none', cursor: 'text'
400 },
401 onChange: function (e) { set({ ctaText: e.target.value }); }
402 }),
403 a.showSecondaryCta && el('input', {
404 type: 'text', value: a.ctaSecondaryText,
405 style: {
406 background: 'transparent', color: a.ctaSecondaryColor, fontWeight: 600,
407 fontSize: '15px', padding: '12px 0', border: 'none', outline: 'none', cursor: 'text'
408 },
409 onChange: function (e) { set({ ctaSecondaryText: e.target.value }); }
410 })
411 ),
412
413 // Benefits grid
414 benefitsGrid,
415
416 // Badges
417 a.showBadges && el('div', {
418 style: {
419 display: 'flex', gap: '10px', flexWrap: 'wrap',
420 justifyContent: justifyContent, marginTop: '32px'
421 }
422 },
423 a.badges.map(function (badge, i) {
424 return el('div', {
425 key: 'badge-' + i,
426 style: {
427 display: 'flex', alignItems: 'center', gap: '6px',
428 background: a.badgeBg, color: a.badgeColor, fontSize: '13px',
429 fontWeight: 600, padding: '6px 14px', borderRadius: '100px',
430 border: '1px solid ' + a.benefitBorderColor
431 }
432 },
433 el('span', {}, badge.icon),
434 el('span', {}, badge.text)
435 );
436 })
437 )
438 )
439 );
440 },
441
442 save: function (props) {
443 var a = props.attributes;
444 var blockProps = wp.blockEditor.useBlockProps.save((function () { var _tv = getTypoCssVars(a); return { style: _tv }; })());
445 return el('div', blockProps,
446 el('div', {
447 className: 'bkbg-value-proposition-app',
448 'data-opts': JSON.stringify(props.attributes)
449 })
450 );
451 }
452 });
453 }() );
454