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 / trust-bar / index.js

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

253 lines 18.9 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 MediaUpload = wp.blockEditor.MediaUpload;
10 var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
11 var PanelBody = wp.components.PanelBody;
12 var RangeControl = wp.components.RangeControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var TextControl = wp.components.TextControl;
15 var SelectControl = wp.components.SelectControl;
16 var Button = wp.components.Button;
17
18 // Resolve the shared components lazily without defining globals for each block.
19 function _tc(props, key, label) {
20 var Control = window.bkbgTypographyControl;
21 return Control ? el(Control, {
22 label: label,
23 value: props.attributes[key] || {},
24 onChange: function (value) { var update = {}; update[key] = value; props.setAttributes(update); }
25 }) : null;
26 }
27 function _tvf(typo, prefix) {
28 var cssVars = window.bkbgTypoCssVars;
29 return cssVars ? cssVars(typo || {}, prefix) : {};
30 }
31 function getTypoControl(p, key, label) { return _tc ? _tc(p, key, label) : null; }
32 function getTypoCssVars(a) {
33 if (!_tvf) return {};
34 var v = {};
35 Object.assign(v, _tvf(a.labelTypo || {}, '--bktb-lb-'));
36 Object.assign(v, _tvf(a.sublabelTypo || {}, '--bktb-sl-'));
37 return v;
38 }
39
40 var LAYOUT_OPTIONS = [
41 { label: 'Single row', value: 'row' },
42 { label: '2-column grid', value: 'grid-2' },
43 { label: '3-column grid', value: 'grid-3' },
44 ];
45 var CARD_STYLE_OPTIONS = [
46 { label: 'Plain', value: 'plain' },
47 { label: 'Card', value: 'card' },
48 { label: 'Bordered', value: 'bordered' },
49 ];
50 var TEXT_ALIGN_OPTIONS = [
51 { label: 'Left', value: 'left' },
52 { label: 'Center', value: 'center' },
53 { label: 'Right', value: 'right' },
54 ];
55
56 /* Inline SVG icons */
57 var ICONS = {
58 shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',
59 lock: 'M19 11H5a2 2 0 00-2 2v7a2 2 0 002 2h14a2 2 0 002-2v-7a2 2 0 00-2-2zM12 7a3 3 0 016 0v4H6V7a3 3 0 016 0z',
60 check: 'M22 11.08V12a10 10 0 11-5.93-9.14M22 4L12 14.01l-3-3',
61 bolt: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z',
62 headphones: 'M3 18v-6a9 9 0 0118 0v6M3 18a2 2 0 002 2h1a2 2 0 002-2v-3a2 2 0 00-2-2H3v5zM21 18a2 2 0 01-2 2h-1a2 2 0 01-2-2v-3a2 2 0 012-2h3v5z',
63 star: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z',
64 award: 'M12 15a7 7 0 100-14 7 7 0 000 14zM8.21 13.89L7 23l5-3 5 3-1.21-9.12',
65 users: 'M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2M9 11a4 4 0 100-8 4 4 0 000 8zM23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75',
66 cloud: 'M18 10h-1.26A8 8 0 109 20h9a5 5 0 000-10z',
67 eye: 'M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 9a3 3 0 100 6 3 3 0 000-6z',
68 };
69 var ICON_OPTIONS = [
70 { label: 'Shield', value: 'shield' },
71 { label: 'Lock', value: 'lock' },
72 { label: 'Checkmark', value: 'check' },
73 { label: 'Lightning', value: 'bolt' },
74 { label: 'Headphones', value: 'headphones' },
75 { label: 'Star', value: 'star' },
76 { label: 'Award', value: 'award' },
77 { label: 'Users', value: 'users' },
78 { label: 'Cloud', value: 'cloud' },
79 { label: 'Eye', value: 'eye' },
80 { label: 'Custom image',value: 'image' },
81 ];
82
83 function makeId() { return 'tb' + Math.random().toString(36).substr(2, 6); }
84
85 function renderIcon(item, a) {
86 if (item.icon === 'image' && item.imageUrl) {
87 return el('img', { src: item.imageUrl, alt: item.label, style: { width: a.iconSize + 'px', height: a.iconSize + 'px', objectFit: 'contain', display: 'block' } });
88 }
89 var path = ICONS[item.icon] || ICONS.shield;
90 var iconEl = el('svg', {
91 viewBox: '0 0 24 24', width: a.iconSize, height: a.iconSize,
92 fill: 'none', stroke: a.iconColor || '#6c3fb5', strokeWidth: 2,
93 strokeLinecap: 'round', strokeLinejoin: 'round',
94 style: { display: 'block', flexShrink: 0 }
95 }, el('path', { d: path }));
96 if (a.iconBgSize > 0) {
97 return el('div', { style: { width: a.iconBgSize + 'px', height: a.iconBgSize + 'px', borderRadius: a.iconBgRadius + 'px', background: a.iconBg || 'rgba(108,63,181,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, iconEl);
98 }
99 return iconEl;
100 }
101
102 function gridStyle(layout, gap) {
103 if (layout === 'row') return { display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center', gap: gap + 'px' };
104 var cols = layout === 'grid-2' ? 2 : 3;
105 return { display: 'grid', gridTemplateColumns: 'repeat(' + cols + ', 1fr)', gap: gap + 'px' };
106 }
107
108 function itemBoxStyle(a) {
109 var base = { display: 'flex', flexDirection: 'column', alignItems: a.textAlign === 'center' ? 'center' : (a.textAlign === 'right' ? 'flex-end' : 'flex-start'), textAlign: a.textAlign, padding: a.cardPadding + 'px', gap: '8px', borderRadius: a.cardRadius + 'px' };
110 if (a.cardStyle === 'card') return Object.assign({}, base, { background: a.cardBg || '#fff', boxShadow: '0 2px 12px rgba(0,0,0,0.08)' });
111 if (a.cardStyle === 'bordered') return Object.assign({}, base, { background: a.cardBg || 'transparent', border: '1.5px solid rgba(108,63,181,0.15)' });
112 return base;
113 }
114
115 registerBlockType('blockenberg/trust-bar', {
116 edit: function (props) {
117 var attributes = props.attributes;
118 var setAttributes = props.setAttributes;
119 var items = attributes.items;
120 var blockProps = useBlockProps((function () {
121 var _tv = getTypoCssVars(attributes);
122 var s = { paddingTop: attributes.paddingTop + 'px', paddingBottom: attributes.paddingBottom + 'px', backgroundColor: attributes.bgColor || undefined };
123 Object.assign(s, _tv);
124 return { className: 'bkbg-trust-bar-wrap', style: s };
125 })());
126
127 function setItem(id, patch) { setAttributes({ items: items.map(function (it) { return it.id === id ? Object.assign({}, it, patch) : it; }) }); }
128 function addItem() { setAttributes({ items: items.concat([{ id: makeId(), icon: 'shield', label: 'Security', sublabel: 'Grade A', imageUrl: '', imageId: 0 }]) }); }
129 function removeItem(id) { if (items.length <= 1) return; setAttributes({ items: items.filter(function (it) { return it.id !== id; }) }); }
130
131 return el(Fragment, null,
132 el(InspectorControls, null,
133 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: true },
134 el(SelectControl, { label: __('Layout', 'blockenberg'), value: attributes.layout, options: LAYOUT_OPTIONS, onChange: function (v) { setAttributes({ layout: v }); } }),
135 el(SelectControl, { label: __('Card style', 'blockenberg'), value: attributes.cardStyle, options: CARD_STYLE_OPTIONS, onChange: function (v) { setAttributes({ cardStyle: v }); } }),
136 el(SelectControl, { label: __('Text alignment', 'blockenberg'), value: attributes.textAlign, options: TEXT_ALIGN_OPTIONS, onChange: function (v) { setAttributes({ textAlign: v }); } }),
137 el(ToggleControl, { label: __('Show sublabel', 'blockenberg'), checked: attributes.showSublabel, onChange: function (v) { setAttributes({ showSublabel: v }); }, __nextHasNoMarginBottom: true }),
138 el(ToggleControl, { label: __('Show divider between items', 'blockenberg'), checked: attributes.showDivider, onChange: function (v) { setAttributes({ showDivider: v }); }, __nextHasNoMarginBottom: true }),
139 el(RangeControl, { label: __('Gap (px)', 'blockenberg'), value: attributes.gap, min: 0, max: 80, onChange: function (v) { setAttributes({ gap: v }); } })
140 ),
141 el(PanelBody, { title: __('Icon', 'blockenberg'), initialOpen: false },
142 el(RangeControl, { label: __('Icon size (px)', 'blockenberg'), value: attributes.iconSize, min: 16, max: 64, onChange: function (v) { setAttributes({ iconSize: v }); } }),
143 el(RangeControl, { label: __('Icon bg size (px, 0 = none)', 'blockenberg'), value: attributes.iconBgSize, min: 0, max: 120, onChange: function (v) { setAttributes({ iconBgSize: v }); } }),
144 el(RangeControl, { label: __('Icon bg radius (px)', 'blockenberg'), value: attributes.iconBgRadius, min: 0, max: 60, onChange: function (v) { setAttributes({ iconBgRadius: v }); } })
145 ),
146 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
147 getTypoControl(props, 'labelTypo', __('Label', 'blockenberg')),
148 getTypoControl(props, 'sublabelTypo', __('Sublabel', 'blockenberg'))
149 ),
150 el(PanelBody, { title: __('Appearance', 'blockenberg'), initialOpen: false },
151 el(RangeControl, { label: __('Card radius (px)', 'blockenberg'), value: attributes.cardRadius, min: 0, max: 32, onChange: function (v) { setAttributes({ cardRadius: v }); } }),
152 el(RangeControl, { label: __('Card padding (px)', 'blockenberg'), value: attributes.cardPadding, min: 4, max: 48, onChange: function (v) { setAttributes({ cardPadding: v }); } })
153 ),
154 el(PanelColorSettings, {
155 title: __('Colors', 'blockenberg'), initialOpen: false,
156 colorSettings: [
157 { value: attributes.iconColor, onChange: function (v) { setAttributes({ iconColor: v || '' }); }, label: __('Icon', 'blockenberg') },
158 { value: attributes.iconBg, onChange: function (v) { setAttributes({ iconBg: v || '' }); }, label: __('Icon background', 'blockenberg') },
159 { value: attributes.labelColor, onChange: function (v) { setAttributes({ labelColor: v || '' }); }, label: __('Label', 'blockenberg') },
160 { value: attributes.sublabelColor,onChange: function (v) { setAttributes({ sublabelColor: v || '' }); },label: __('Sublabel', 'blockenberg') },
161 { value: attributes.dividerColor, onChange: function (v) { setAttributes({ dividerColor: v || '' }); }, label: __('Divider', 'blockenberg') },
162 { value: attributes.cardBg, onChange: function (v) { setAttributes({ cardBg: v || '' }); }, label: __('Card background', 'blockenberg') },
163 { value: attributes.bgColor, onChange: function (v) { setAttributes({ bgColor: v || '' }); }, label: __('Section background', 'blockenberg') },
164 ]
165 }),
166 el(PanelBody, { title: __('Spacing', 'blockenberg'), initialOpen: false },
167 el(RangeControl, { label: __('Padding top (px)', 'blockenberg'), value: attributes.paddingTop, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingTop: v }); } }),
168 el(RangeControl, { label: __('Padding bottom (px)', 'blockenberg'), value: attributes.paddingBottom, min: 0, max: 200, onChange: function (v) { setAttributes({ paddingBottom: v }); } })
169 ),
170 el(PanelBody, { title: __('Items', 'blockenberg'), initialOpen: false },
171 items.map(function (item, idx) {
172 return el(PanelBody, { key: item.id, title: (item.label || 'Item') + ' #' + (idx + 1), initialOpen: false },
173 el(SelectControl, { label: __('Icon', 'blockenberg'), value: item.icon, options: ICON_OPTIONS, onChange: function (v) { setItem(item.id, { icon: v }); } }),
174 item.icon === 'image' && el(Fragment, null,
175 el(MediaUploadCheck, null,
176 el(MediaUpload, {
177 onSelect: function (media) { setItem(item.id, { imageUrl: media.url, imageId: media.id }); },
178 allowedTypes: ['image'],
179 value: item.imageId,
180 render: function (ref) { return el(Button, { onClick: ref.open, variant: 'secondary', size: 'compact', style: { marginBottom: '6px' } }, item.imageUrl ? __('Change image', 'blockenberg') : __('Upload image', 'blockenberg')); }
181 })
182 ),
183 item.imageUrl && el(Button, { onClick: function () { setItem(item.id, { imageUrl: '', imageId: 0 }); }, variant: 'tertiary', size: 'compact', isDestructive: true, style: { display: 'block', marginBottom: '6px' } }, __('Remove image', 'blockenberg'))
184 ),
185 el(TextControl, { label: __('Label', 'blockenberg'), value: item.label, onChange: function (v) { setItem(item.id, { label: v }); } }),
186 el(TextControl, { label: __('Sublabel', 'blockenberg'), value: item.sublabel, onChange: function (v) { setItem(item.id, { sublabel: v }); } }),
187 items.length > 1 && el(Button, { onClick: function () { removeItem(item.id); }, variant: 'tertiary', size: 'compact', isDestructive: true }, __('Remove item', 'blockenberg'))
188 );
189 }),
190 el(Button, { onClick: addItem, variant: 'primary', style: { marginTop: '8px' } }, __('+ Add Item', 'blockenberg'))
191 )
192 ),
193
194 el('div', blockProps,
195 el('div', { className: 'bkbg-trust-bar', style: gridStyle(attributes.layout, attributes.gap) },
196 items.map(function (item, idx) {
197 return el(Fragment, { key: item.id },
198 attributes.showDivider && idx > 0 && attributes.layout === 'row' && el('div', { style: { width: '1px', height: '40px', background: attributes.dividerColor || '#e5e7eb', flexShrink: 0 } }),
199 el('div', { className: 'bkbg-trust-bar-item', style: itemBoxStyle(attributes) },
200 renderIcon(item, attributes),
201 el('div', null,
202 el('p', { className: 'bkbg-tb-label', style: { margin: 0, color: attributes.labelColor || undefined } }, item.label),
203 attributes.showSublabel && item.sublabel && el('p', { className: 'bkbg-tb-sublabel', style: { margin: 0, color: attributes.sublabelColor || undefined, opacity: 0.7 } }, item.sublabel)
204 )
205 )
206 );
207 })
208 )
209 )
210 );
211 },
212
213 save: function (props) {
214 var a = props.attributes;
215 var blockProps = wp.blockEditor.useBlockProps.save((function () {
216 var _tv = getTypoCssVars(a);
217 var s = { paddingTop: a.paddingTop + 'px', paddingBottom: a.paddingBottom + 'px', backgroundColor: a.bgColor || undefined };
218 Object.assign(s, _tv);
219 return { className: 'bkbg-trust-bar-wrap', style: s };
220 })());
221
222 function iconSVG(item) {
223 if (item.icon === 'image' && item.imageUrl) {
224 return el('img', { src: item.imageUrl, alt: item.label, style: { width: a.iconSize + 'px', height: a.iconSize + 'px', objectFit: 'contain', display: 'block' } });
225 }
226 var path = ICONS[item.icon] || ICONS.shield;
227 var iconEl = el('svg', { viewBox: '0 0 24 24', width: a.iconSize, height: a.iconSize, fill: 'none', stroke: a.iconColor || '#6c3fb5', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': 'true', style: { display: 'block', flexShrink: 0 } }, el('path', { d: path }));
228 if (a.iconBgSize > 0) {
229 return el('div', { style: { width: a.iconBgSize + 'px', height: a.iconBgSize + 'px', borderRadius: a.iconBgRadius + 'px', background: a.iconBg || 'rgba(108,63,181,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 } }, iconEl);
230 }
231 return iconEl;
232 }
233
234 return el('div', blockProps,
235 el('div', { className: 'bkbg-trust-bar', style: gridStyle(a.layout, a.gap) },
236 a.items.map(function (item, idx) {
237 return el(Fragment, { key: item.id },
238 a.showDivider && idx > 0 && a.layout === 'row' && el('div', { className: 'bkbg-trust-bar-divider', style: { width: '1px', height: '40px', background: a.dividerColor || '#e5e7eb', flexShrink: 0 } }),
239 el('div', { className: 'bkbg-trust-bar-item', style: itemBoxStyle(a) },
240 iconSVG(item),
241 el('div', null,
242 el('p', { className: 'bkbg-tb-label', style: { margin: 0, color: a.labelColor || undefined } }, item.label),
243 a.showSublabel && item.sublabel && el('p', { className: 'bkbg-tb-sublabel', style: { margin: 0, color: a.sublabelColor || undefined, opacity: 0.7 } }, item.sublabel)
244 )
245 )
246 );
247 })
248 )
249 );
250 }
251 });
252 }());
253