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 / gradient-hero / index.js

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

373 lines 21.1 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 useState = wp.element.useState;
4 var __ = wp.i18n.__;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var RichText = wp.blockEditor.RichText;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
10 var PanelBody = wp.components.PanelBody;
11 var RangeControl = wp.components.RangeControl;
12 var SelectControl = wp.components.SelectControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var TextControl = wp.components.TextControl;
15 var MediaUpload = wp.blockEditor.MediaUpload;
16 var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
17 var Fragment = wp.element.Fragment;
18 var Button = wp.components.Button;
19
20 /* ── typography lazy-getters ── */
21 function _tc() { return window.bkbgTypographyControl || null; }
22 function _tv() { return window.bkbgTypoCssVars || function () { return {}; }; }
23
24 function wrapStyle(a) {
25 return Object.assign({
26 '--bkbg-gh-pt': a.paddingTop + 'px',
27 '--bkbg-gh-pb': a.paddingBottom + 'px',
28 '--bkbg-gh-bg': a.bgColor,
29 '--bkbg-gh-color-a': a.colorA,
30 '--bkbg-gh-color-b': a.colorB,
31 '--bkbg-gh-color-c': a.colorC,
32 '--bkbg-gh-text': a.textColor,
33 '--bkbg-gh-sub-c': a.subColor,
34 '--bkbg-gh-badge-bg': a.badgeBg,
35 '--bkbg-gh-badge-color': a.badgeColor,
36 '--bkbg-gh-btn-bg': a.btnBg,
37 '--bkbg-gh-btn-text': a.btnText,
38 '--bkbg-gh-btn2-bg': a.btn2Bg,
39 '--bkbg-gh-btn2-text': a.btn2Text,
40 '--bkbg-gh-proof': a.proofColor,
41 '--bkbg-gh-proof-hl': a.proofHighlight,
42 '--bkbg-gh-cta-sz': a.ctaSize + 'px',
43 '--bkbg-gh-cta-r': a.ctaRadius + 'px',
44 '--bkbg-gh-max-w': a.maxWidth + 'px',
45 }, _tv()(a.typoHeading, '--bkbg-gh-hl-'), _tv()(a.typoSub, '--bkbg-gh-sub-'), _tv()(a.typoBadge, '--bkbg-gh-bg-'));
46 }
47
48 registerBlockType('blockenberg/gradient-hero', {
49 title: __('Gradient Hero', 'blockenberg'),
50 icon: 'cover-image',
51 category: 'bkbg-layout',
52
53 edit: function (props) {
54 var a = props.attributes;
55 var set = props.setAttributes;
56
57 var styleOptions = [
58 { label: __('Mesh Gradient', 'blockenberg'), value: 'mesh' },
59 { label: __('Linear Gradient', 'blockenberg'), value: 'gradient' },
60 { label: __('Solid', 'blockenberg'), value: 'solid' },
61 { label: __('Aurora', 'blockenberg'), value: 'aurora' },
62 ];
63 var alignOptions = [
64 { label: __('Center', 'blockenberg'), value: 'center' },
65 { label: __('Left', 'blockenberg'), value: 'left' },
66 ];
67 var weightOptions = [
68 { label: '700', value: 700 },
69 { label: '800', value: 800 },
70 { label: '900', value: 900 },
71 ];
72
73 // Build avatar images
74 function renderAvatars(avatars) {
75 return el('div', { className: 'bkbg-gh-avatars' },
76 (avatars || []).map(function (av, i) {
77 return av.imageUrl
78 ? el('img', { key: i, className: 'bkbg-gh-avatar', src: av.imageUrl, alt: av.imageAlt || '', style: { marginLeft: i > 0 ? '-8px' : '0' } })
79 : el('span', { key: i, className: 'bkbg-gh-avatar bkbg-gh-avatar--empty', style: { marginLeft: i > 0 ? '-8px' : '0' } });
80 })
81 );
82 }
83
84 var blockProps = useBlockProps({
85 className: 'bkbg-gh-wrap bkbg-gh-style--' + a.style + ' bkbg-gh-align--' + a.contentAlign,
86 style: wrapStyle(a)
87 });
88
89 var inspector = el(InspectorControls, {},
90 el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
91 el(ToggleControl, {
92 label: __('Show Badge', 'blockenberg'),
93 checked: a.showBadge,
94 __nextHasNoMarginBottom: true,
95 onChange: function (v) { set({ showBadge: v }); }
96 }),
97 a.showBadge && el(TextControl, {
98 label: __('Badge Text', 'blockenberg'),
99 value: a.badge,
100 onChange: function (v) { set({ badge: v }); }
101 }),
102 el(ToggleControl, {
103 label: __('Show Subheading', 'blockenberg'),
104 checked: a.showSubheading,
105 __nextHasNoMarginBottom: true,
106 onChange: function (v) { set({ showSubheading: v }); }
107 }),
108 el('p', { className: 'components-base-control__label' }, __('Primary CTA', 'blockenberg')),
109 el(TextControl, {
110 label: __('Button Text', 'blockenberg'),
111 value: a.ctaText,
112 onChange: function (v) { set({ ctaText: v }); }
113 }),
114 el(TextControl, {
115 label: __('Button URL', 'blockenberg'),
116 value: a.ctaUrl,
117 onChange: function (v) { set({ ctaUrl: v }); }
118 }),
119 el(ToggleControl, {
120 label: __('Show Secondary CTA', 'blockenberg'),
121 checked: a.showSecondaryCta,
122 __nextHasNoMarginBottom: true,
123 onChange: function (v) { set({ showSecondaryCta: v }); }
124 }),
125 a.showSecondaryCta && el(TextControl, {
126 label: __('Secondary Text', 'blockenberg'),
127 value: a.ctaSecondaryText,
128 onChange: function (v) { set({ ctaSecondaryText: v }); }
129 }),
130 a.showSecondaryCta && el(TextControl, {
131 label: __('Secondary URL', 'blockenberg'),
132 value: a.ctaSecondaryUrl,
133 onChange: function (v) { set({ ctaSecondaryUrl: v }); }
134 })
135 ),
136 el(PanelBody, { title: __('Social Proof', 'blockenberg'), initialOpen: false },
137 el(ToggleControl, {
138 label: __('Show Social Proof', 'blockenberg'),
139 checked: a.showSocialProof,
140 __nextHasNoMarginBottom: true,
141 onChange: function (v) { set({ showSocialProof: v }); }
142 }),
143 a.showSocialProof && el(TextControl, {
144 label: __('Proof Text', 'blockenberg'),
145 value: a.socialProofText,
146 onChange: function (v) { set({ socialProofText: v }); }
147 }),
148 a.showSocialProof && el('div', { style: { marginTop: '8px' } },
149 el('p', { style: { margin: '0 0 8px', fontSize: '12px', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '.05em' } }, __('Avatars', 'blockenberg')),
150 (a.avatars || []).map(function (av, i) {
151 return el(PanelBody, { key: i, title: __('Avatar', 'blockenberg') + ' ' + (i + 1), initialOpen: false, style: { borderTop: '1px solid #e0e0e0' } },
152 el(MediaUploadCheck, null,
153 el(MediaUpload, {
154 onSelect: function (m) {
155 var next = (a.avatars || []).map(function (x, j) {
156 return j === i ? { imageUrl: m.url, imageId: m.id, imageAlt: m.alt || '' } : x;
157 });
158 set({ avatars: next });
159 },
160 allowedTypes: ['image'],
161 value: av.imageId,
162 render: function (r) {
163 return el(Fragment, null,
164 av.imageUrl && el('img', { src: av.imageUrl, style: { width: '48px', height: '48px', borderRadius: '50%', objectFit: 'cover', display: 'block', marginBottom: '6px', border: '2px solid #6c3fb5' } }),
165 el(Button, { onClick: r.open, variant: 'secondary', style: { width: '100%', marginBottom: av.imageUrl ? '4px' : '0' } },
166 av.imageUrl ? __('Change image', 'blockenberg') : __('Select image', 'blockenberg')
167 ),
168 av.imageUrl && el(Button, {
169 onClick: function () {
170 var next = (a.avatars || []).map(function (x, j) {
171 return j === i ? { imageUrl: '', imageId: 0, imageAlt: '' } : x;
172 });
173 set({ avatars: next });
174 },
175 variant: 'link', isDestructive: true, style: { width: '100%' }
176 }, __('Remove', 'blockenberg'))
177 );
178 }
179 })
180 )
181 );
182 }),
183 el(Button, {
184 variant: 'secondary',
185 style: { width: '100%', marginTop: '8px' },
186 onClick: function () { set({ avatars: (a.avatars || []).concat([{ imageUrl: '', imageId: 0, imageAlt: '' }]) }); },
187 disabled: (a.avatars || []).length >= 8
188 }, __('+ Add avatar', 'blockenberg')),
189 (a.avatars || []).length > 1 && el(Button, {
190 variant: 'link', isDestructive: true,
191 style: { width: '100%', marginTop: '4px' },
192 onClick: function () { set({ avatars: (a.avatars || []).slice(0, -1) }); }
193 }, __('− Remove last', 'blockenberg'))
194 )
195 ),
196 el(PanelBody, { title: __('Background Style', 'blockenberg'), initialOpen: false },
197 el(SelectControl, {
198 label: __('Background Style', 'blockenberg'),
199 value: a.style,
200 options: styleOptions,
201 onChange: function (v) { set({ style: v }); }
202 })
203 ),
204 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: false },
205 el(SelectControl, {
206 label: __('Content Alignment', 'blockenberg'),
207 value: a.contentAlign,
208 options: alignOptions,
209 onChange: function (v) { set({ contentAlign: v }); }
210 }),
211 el(RangeControl, {
212 label: __('Max Content Width (px)', 'blockenberg'),
213 value: a.maxWidth,
214 onChange: function (v) { set({ maxWidth: v }); },
215 min: 480,
216 max: 1200,
217 step: 20
218 }),
219 el(RangeControl, {
220 label: __('Padding Top (px)', 'blockenberg'),
221 value: a.paddingTop,
222 onChange: function (v) { set({ paddingTop: v }); },
223 min: 0,
224 max: 240
225 }),
226 el(RangeControl, {
227 label: __('Padding Bottom (px)', 'blockenberg'),
228 value: a.paddingBottom,
229 onChange: function (v) { set({ paddingBottom: v }); },
230 min: 0,
231 max: 240
232 }),
233 el(RangeControl, {
234 label: __('Button Radius (px)', 'blockenberg'),
235 value: a.ctaRadius,
236 onChange: function (v) { set({ ctaRadius: v }); },
237 min: 0,
238 max: 40
239 })
240 ),
241 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
242 _tc() && el(_tc(), { label:__('Heading','blockenberg'), value:a.typoHeading, onChange:function(v){ set({typoHeading:v}); } }),
243 _tc() && el(_tc(), { label:__('Subheading','blockenberg'), value:a.typoSub, onChange:function(v){ set({typoSub:v}); } }),
244 _tc() && el(_tc(), { label:__('Badge','blockenberg'), value:a.typoBadge, onChange:function(v){ set({typoBadge:v}); } }),
245 el(RangeControl, {
246 label: __('CTA Button Size (px)', 'blockenberg'),
247 value: a.ctaSize,
248 onChange: function (v) { set({ ctaSize: v }); },
249 min: 13,
250 max: 22
251 })
252 ),
253 el(PanelColorSettings, {
254 title: __('Colors', 'blockenberg'),
255 initialOpen: false,
256 colorSettings: [
257 { label: __('Background', 'blockenberg'), value: a.bgColor, onChange: function (v) { set({ bgColor: v || '#0f172a' }); } },
258 { label: __('Gradient Color A', 'blockenberg'), value: a.colorA, onChange: function (v) { set({ colorA: v || '#6c3fb5' }); } },
259 { label: __('Gradient Color B', 'blockenberg'), value: a.colorB, onChange: function (v) { set({ colorB: v || '#3b82f6' }); } },
260 { label: __('Gradient Color C', 'blockenberg'), value: a.colorC, onChange: function (v) { set({ colorC: v || '#ec4899' }); } },
261 { label: __('Heading Text', 'blockenberg'), value: a.textColor, onChange: function (v) { set({ textColor: v || '#ffffff' }); } },
262 { label: __('Subheading Text', 'blockenberg'), value: a.subColor, onChange: function (v) { set({ subColor: v || 'rgba(255,255,255,0.65)' }); } },
263 { label: __('Badge Background', 'blockenberg'), value: a.badgeBg, onChange: function (v) { set({ badgeBg: v || 'rgba(108,63,181,0.18)' }); } },
264 { label: __('Badge Text', 'blockenberg'), value: a.badgeColor, onChange: function (v) { set({ badgeColor: v || '#c4b5fd' }); } },
265 { label: __('Primary Button', 'blockenberg'), value: a.btnBg, onChange: function (v) { set({ btnBg: v || '#6c3fb5' }); } },
266 { label: __('Primary Button Text', 'blockenberg'), value: a.btnText, onChange: function (v) { set({ btnText: v || '#ffffff' }); } },
267 { label: __('Secondary Button', 'blockenberg'), value: a.btn2Bg, onChange: function (v) { set({ btn2Bg: v || 'rgba(255,255,255,0.08)' }); } },
268 { label: __('Secondary Button Text', 'blockenberg'), value: a.btn2Text, onChange: function (v) { set({ btn2Text: v || '#ffffff' }); } },
269 ]
270 })
271 );
272
273 var canvas = el('div', blockProps,
274 el('div', { className: 'bkbg-gh-bg-layer' }),
275 el('div', { className: 'bkbg-gh-content' },
276 a.showBadge && a.badge && el('div', { className: 'bkbg-gh-badge' },
277 el('span', { className: 'bkbg-gh-badge-text' }, a.badge)
278 ),
279 el(RichText, {
280 tagName: 'h1',
281 className: 'bkbg-gh-heading',
282 value: a.heading,
283 onChange: function (v) { set({ heading: v }); },
284 placeholder: __('Enter headline…', 'blockenberg'),
285 allowedFormats: ['core/bold', 'core/italic']
286 }),
287 a.showSubheading && el(RichText, {
288 tagName: 'p',
289 className: 'bkbg-gh-sub',
290 value: a.subheading,
291 onChange: function (v) { set({ subheading: v }); },
292 placeholder: __('Enter subheading…', 'blockenberg'),
293 allowedFormats: ['core/bold', 'core/italic']
294 }),
295 el('div', { className: 'bkbg-gh-ctas' },
296 el('a', { className: 'bkbg-gh-btn bkbg-gh-btn--primary', href: '#', onClick: function (e) { e.preventDefault(); } }, a.ctaText),
297 a.showSecondaryCta && el('a', { className: 'bkbg-gh-btn bkbg-gh-btn--secondary', href: '#', onClick: function (e) { e.preventDefault(); } },
298 el('span', { className: 'bkbg-gh-play-icon' }, ''),
299 el('span', {}, a.ctaSecondaryText)
300 )
301 ),
302 a.showSocialProof && el('div', { className: 'bkbg-gh-proof' },
303 renderAvatars(a.avatars),
304 el('span', { className: 'bkbg-gh-proof-text' }, a.socialProofText)
305 )
306 )
307 );
308
309 return el('div', {}, inspector, canvas);
310 },
311
312 save: function (props) {
313 var a = props.attributes;
314 var blockProps = useBlockProps.save({
315 className: 'bkbg-gh-wrap bkbg-gh-style--' + a.style + ' bkbg-gh-align--' + a.contentAlign,
316 style: Object.assign({
317 '--bkbg-gh-pt': a.paddingTop + 'px',
318 '--bkbg-gh-pb': a.paddingBottom + 'px',
319 '--bkbg-gh-bg': a.bgColor,
320 '--bkbg-gh-color-a': a.colorA,
321 '--bkbg-gh-color-b': a.colorB,
322 '--bkbg-gh-color-c': a.colorC,
323 '--bkbg-gh-text': a.textColor,
324 '--bkbg-gh-sub-c': a.subColor,
325 '--bkbg-gh-badge-bg': a.badgeBg,
326 '--bkbg-gh-badge-color': a.badgeColor,
327 '--bkbg-gh-btn-bg': a.btnBg,
328 '--bkbg-gh-btn-text': a.btnText,
329 '--bkbg-gh-btn2-bg': a.btn2Bg,
330 '--bkbg-gh-btn2-text': a.btn2Text,
331 '--bkbg-gh-proof': a.proofColor,
332 '--bkbg-gh-proof-hl': a.proofHighlight,
333 '--bkbg-gh-cta-sz': a.ctaSize + 'px',
334 '--bkbg-gh-cta-r': a.ctaRadius + 'px',
335 '--bkbg-gh-max-w': a.maxWidth + 'px',
336 }, _tv()(a.typoHeading, '--bkbg-gh-hl-'), _tv()(a.typoSub, '--bkbg-gh-sub-'), _tv()(a.typoBadge, '--bkbg-gh-bg-'))
337 });
338
339 function saveAvatars(avatars) {
340 return el('div', { className: 'bkbg-gh-avatars' },
341 (avatars || []).map(function (av, i) {
342 return av.imageUrl
343 ? el('img', { key: i, className: 'bkbg-gh-avatar', src: av.imageUrl, alt: av.imageAlt || '', style: { marginLeft: i > 0 ? '-8px' : '0' } })
344 : el('span', { key: i, className: 'bkbg-gh-avatar bkbg-gh-avatar--empty', style: { marginLeft: i > 0 ? '-8px' : '0' } });
345 })
346 );
347 }
348
349 return el('div', blockProps,
350 el('div', { className: 'bkbg-gh-bg-layer' }),
351 el('div', { className: 'bkbg-gh-content' },
352 a.showBadge && a.badge && el('div', { className: 'bkbg-gh-badge' },
353 el('span', { className: 'bkbg-gh-badge-text' }, a.badge)
354 ),
355 el(RichText.Content, { tagName: 'h1', className: 'bkbg-gh-heading', value: a.heading }),
356 a.showSubheading && el(RichText.Content, { tagName: 'p', className: 'bkbg-gh-sub', value: a.subheading }),
357 el('div', { className: 'bkbg-gh-ctas' },
358 el('a', { className: 'bkbg-gh-btn bkbg-gh-btn--primary', href: a.ctaUrl }, a.ctaText),
359 a.showSecondaryCta && el('a', { className: 'bkbg-gh-btn bkbg-gh-btn--secondary', href: a.ctaSecondaryUrl },
360 el('span', { className: 'bkbg-gh-play-icon' }, ''),
361 el('span', {}, a.ctaSecondaryText)
362 )
363 ),
364 a.showSocialProof && el('div', { className: 'bkbg-gh-proof' },
365 saveAvatars(a.avatars),
366 el('span', { className: 'bkbg-gh-proof-text' }, a.socialProofText)
367 )
368 )
369 );
370 }
371 });
372 }() );
373