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

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

354 lines 17.6 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 useState = wp.element.useState;
5 var __ = wp.i18n.__;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
11 var PanelBody = wp.components.PanelBody;
12 var ToggleControl = wp.components.ToggleControl;
13 var RangeControl = wp.components.RangeControl;
14 var SelectControl = wp.components.SelectControl;
15 var TextControl = wp.components.TextControl;
16 var Button = wp.components.Button;
17
18 var _TypographyControl, _typoCssVars;
19 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
20 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
21
22 var ICON_PRESETS = [
23 { group: 'Stars & Awards', icons: ['⭐','🌟','✨','🏆','🥇','🎖️','�
24 ','👑'] },
25 { group: 'Arrows & Nav', icons: ['→','←','↑','↓','↗','↘','➡️','�
26 ','','','',''] },
27 { group: 'Checks & Status', icons: ['�
28 ','✔️','','⚠️','','','','🔴','🟡','🟢'] },
29 { group: 'Tech & Work', icons: ['💡','🔧','⚙️','🖥️','📱','💻','🔒','🔑','📊','📈','📉','🗂️'] },
30 { group: 'People & Social', icons: ['👋','🤝','👥','🧑‍💼','💬','📣','💌','📩','🔔','🎯'] },
31 { group: 'Nature', icons: ['🌱','🌿','🌲','🌸','🌊','☀️','🌙','','🔥','❄️'] },
32 { group: 'Commerce', icons: ['🛒','💳','💰','💎','🎁','🚀','📦','🏷️','🤑','💸'] },
33 { group: 'Learning', icons: ['📚','✏️','🎓','🔬','🧪','🔭','🎨','🎵','📝','🗺️'] },
34 ];
35
36 var SHAPE_OPTIONS = [
37 { label: 'Circle', value: 'circle' },
38 { label: 'Square', value: 'square' },
39 { label: 'Rounded', value: 'rounded' },
40 { label: 'Pill', value: 'pill' },
41 { label: 'No shape', value: 'none' },
42 ];
43
44 var ANIM_OPTIONS = [
45 { label: 'None', value: 'none' },
46 { label: 'Bounce', value: 'bounce' },
47 { label: 'Pulse', value: 'pulse' },
48 { label: 'Float', value: 'float' },
49 { label: 'Spin', value: 'spin' },
50 { label: 'Shake', value: 'shake' },
51 ];
52
53 var ALIGN_OPTIONS = [
54 { label: 'Left', value: 'left' },
55 { label: 'Center', value: 'center' },
56 { label: 'Right', value: 'right' },
57 ];
58
59 function getShapeStyle(a) {
60 var r = a.shape === 'circle' ? '50%'
61 : a.shape === 'square' ? '4px'
62 : a.shape === 'rounded' ? '16px'
63 : a.shape === 'pill' ? '999px'
64 : '0';
65 return {
66 display: 'inline-flex',
67 alignItems: 'center',
68 justifyContent: 'center',
69 width: a.shape !== 'none' && a.showBg ? a.bgSize + 'px' : 'auto',
70 height: a.shape !== 'none' && a.showBg ? a.bgSize + 'px' : 'auto',
71 borderRadius: a.shape !== 'none' ? r : '0',
72 background: a.showBg && a.shape !== 'none' ? a.bgColor : 'transparent',
73 border: a.borderWidth > 0 ? a.borderWidth + 'px solid ' + a.borderColor : 'none',
74 boxShadow: a.shadow ? '0 8px 24px rgba(0,0,0,0.18)' : 'none',
75 fontSize: a.iconSize + 'px',
76 lineHeight: '1',
77 padding: a.shape === 'none' ? '0' : '8px',
78 cursor: a.linkUrl ? 'pointer' : 'default',
79 flexShrink: 0,
80 transition: 'transform 0.2s',
81 };
82 }
83
84 registerBlockType('blockenberg/icon', {
85 title: __('Icon', 'blockenberg'),
86 icon: 'star-filled',
87 category: 'bkbg-content',
88 description: __('Standalone styled icon with label, animation, link, and rich customization.', 'blockenberg'),
89
90 edit: function (props) {
91 var a = props.attributes;
92 var set = props.setAttributes;
93 var bpStyle = { padding: '12px', background: a.containerBg || 'transparent' };
94 var _tv = getTypoCssVars();
95 if (_tv) {
96 Object.assign(bpStyle, _tv(a.labelTypo, '--bkbg-ico-lb-'));
97 Object.assign(bpStyle, _tv(a.subLabelTypo, '--bkbg-ico-sl-'));
98 }
99 bpStyle['--bkbg-ico-lb-sz'] = (a.labelSize || 16) + 'px';
100 bpStyle['--bkbg-ico-lb-fw'] = a.labelFontWeight || '600';
101 bpStyle['--bkbg-ico-lb-lh'] = a.labelLineHeight || 1.3;
102 bpStyle['--bkbg-ico-sl-sz'] = (a.subLabelSize || 13) + 'px';
103 bpStyle['--bkbg-ico-sl-fw'] = a.subLabelFontWeight || '400';
104 bpStyle['--bkbg-ico-sl-lh'] = a.subLabelLineHeight || 1.4;
105 var blockProps = useBlockProps({ style: bpStyle });
106
107 var wrapStyle = {
108 display: 'flex',
109 flexDirection: 'column',
110 alignItems: a.align === 'left' ? 'flex-start' : a.align === 'right' ? 'flex-end' : 'center',
111 gap: a.gap + 'px',
112 padding: a.containerPadding + 'px',
113 };
114
115 var iconStyle = getShapeStyle(a);
116 if (a.bgColor && a.showBg && a.shape !== 'none') {
117 // use filter to colorize if it's pure text - handled via color style
118 }
119
120 return el(Fragment, null,
121 el(InspectorControls, null,
122 // Icon Panel
123 el(PanelBody, { title: 'Icon', initialOpen: true },
124 el(TextControl, {
125 label: 'Icon (emoji or symbol)',
126 value: a.icon,
127 onChange: function (v) { set({ icon: v }); },
128 __nextHasNoMarginBottom: true,
129 }),
130 el('div', { style: { marginTop: 8 } },
131 el('p', { style: { fontSize: 11, color: '#757575', marginBottom: 6, textTransform: 'uppercase', fontWeight: 600, letterSpacing: '0.5px' } },
132 'Quick Presets'
133 ),
134 ICON_PRESETS.map(function (group) {
135 return el('div', { key: group.group, style: { marginBottom: 6 } },
136 el('p', { style: { fontSize: 11, color: '#9ca3af', marginBottom: 3 } }, group.group),
137 el('div', { style: { display: 'flex', flexWrap: 'wrap', gap: 4 } },
138 group.icons.map(function (ic) {
139 return el('button', {
140 key: ic,
141 onClick: function () { set({ icon: ic }); },
142 style: {
143 background: a.icon === ic ? '#6366f1' : '#f3f4f6',
144 border: 'none',
145 borderRadius: 6,
146 width: 32,
147 height: 32,
148 fontSize: 16,
149 cursor: 'pointer',
150 display: 'flex',
151 alignItems: 'center',
152 justifyContent: 'center',
153 },
154 title: ic,
155 }, ic);
156 })
157 )
158 );
159 })
160 )
161 ),
162
163 // Shape Panel
164 el(PanelBody, { title: 'Shape & Size', initialOpen: false },
165 el(SelectControl, {
166 label: 'Shape',
167 value: a.shape,
168 options: SHAPE_OPTIONS,
169 onChange: function (v) { set({ shape: v }); },
170 __nextHasNoMarginBottom: true,
171 }),
172 el('div', { style: { height: 12 } }),
173 el(RangeControl, {
174 label: 'Icon Size (px)',
175 value: a.iconSize,
176 min: 16, max: 140,
177 onChange: function (v) { set({ iconSize: v }); },
178 __nextHasNoMarginBottom: true,
179 }),
180 a.shape !== 'none' && el(Fragment, null,
181 el('div', { style: { height: 12 } }),
182 el(ToggleControl, {
183 label: 'Show Background',
184 checked: a.showBg,
185 onChange: function (v) { set({ showBg: v }); },
186 __nextHasNoMarginBottom: true,
187 }),
188 a.showBg && el(RangeControl, {
189 label: 'Background Size (px)',
190 value: a.bgSize,
191 min: 32, max: 200,
192 onChange: function (v) { set({ bgSize: v }); },
193 __nextHasNoMarginBottom: true,
194 })
195 ),
196 el('div', { style: { height: 12 } }),
197 el(RangeControl, {
198 label: 'Border Width (px)',
199 value: a.borderWidth,
200 min: 0, max: 8,
201 onChange: function (v) { set({ borderWidth: v }); },
202 __nextHasNoMarginBottom: true,
203 }),
204 el('div', { style: { height: 12 } }),
205 el(ToggleControl, {
206 label: 'Drop Shadow',
207 checked: a.shadow,
208 onChange: function (v) { set({ shadow: v }); },
209 __nextHasNoMarginBottom: true,
210 })
211 ),
212
213 // Label Panel
214 el(PanelBody, { title: 'Label & Sub-Label', initialOpen: false },
215 el(ToggleControl, {
216 label: 'Show Label',
217 checked: a.showLabel,
218 onChange: function (v) { set({ showLabel: v }); },
219 __nextHasNoMarginBottom: true,
220 }),
221 a.showLabel && el(Fragment, null,
222 el(TextControl, {
223 label: 'Label Text',
224 value: a.label,
225 onChange: function (v) { set({ label: v }); },
226 __nextHasNoMarginBottom: true,
227 })
228 ),
229 el('div', { style: { height: 12 } }),
230 el(ToggleControl, {
231 label: 'Show Sub-Label',
232 checked: a.showSubLabel,
233 onChange: function (v) { set({ showSubLabel: v }); },
234 __nextHasNoMarginBottom: true,
235 }),
236 a.showSubLabel && el(Fragment, null,
237 el(TextControl, {
238 label: 'Sub-Label Text',
239 value: a.subLabel,
240 onChange: function (v) { set({ subLabel: v }); },
241 __nextHasNoMarginBottom: true,
242 })
243 )
244 ),
245
246 // Link Panel
247 el(PanelBody, { title: 'Link', initialOpen: false },
248 el(TextControl, {
249 label: 'URL',
250 value: a.linkUrl,
251 placeholder: 'https://',
252 onChange: function (v) { set({ linkUrl: v }); },
253 __nextHasNoMarginBottom: true,
254 }),
255 el('div', { style: { height: 12 } }),
256 el(ToggleControl, {
257 label: 'Open in new tab',
258 checked: a.linkNewTab,
259 onChange: function (v) { set({ linkNewTab: v }); },
260 __nextHasNoMarginBottom: true,
261 })
262 ),
263
264 // Animation & Layout Panel
265 el(PanelBody, { title: 'Animation & Layout', initialOpen: false },
266 el(SelectControl, {
267 label: 'Animation',
268 value: a.animation,
269 options: ANIM_OPTIONS,
270 onChange: function (v) { set({ animation: v }); },
271 __nextHasNoMarginBottom: true,
272 }),
273 el('div', { style: { height: 12 } }),
274 el(SelectControl, {
275 label: 'Alignment',
276 value: a.align,
277 options: ALIGN_OPTIONS,
278 onChange: function (v) { set({ align: v }); },
279 __nextHasNoMarginBottom: true,
280 }),
281 el('div', { style: { height: 12 } }),
282 el(RangeControl, {
283 label: 'Container Padding (px)',
284 value: a.containerPadding,
285 min: 0, max: 80,
286 onChange: function (v) { set({ containerPadding: v }); },
287 __nextHasNoMarginBottom: true,
288 }),
289 el('div', { style: { height: 12 } }),
290 el(RangeControl, {
291 label: 'Gap between elements (px)',
292 value: a.gap,
293 min: 0, max: 40,
294 onChange: function (v) { set({ gap: v }); },
295 __nextHasNoMarginBottom: true,
296 })
297 ),
298
299 // Colors Panel
300 el(PanelColorSettings, {
301 title: 'Colors',
302 initialOpen: false,
303 colorSettings: [
304 { label: 'Container Background', value: a.containerBg, onChange: function (v) { set({ containerBg: v || '' }); } },
305 { label: 'Icon Background', value: a.bgColor, onChange: function (v) { set({ bgColor: v || '#6366f1' }); } },
306 { label: 'Border Color', value: a.borderColor, onChange: function (v) { set({ borderColor: v || '#6366f1' }); } },
307 { label: 'Label Color', value: a.labelColor, onChange: function (v) { set({ labelColor: v || '#111827' }); } },
308 { label: 'Sub-Label Color', value: a.subLabelColor, onChange: function (v) { set({ subLabelColor: v || '#6b7280' }); } },
309 ]
310 }),
311
312 // Typography
313 el(PanelBody, { title: 'Typography', initialOpen: false },
314 getTypographyControl() && el(getTypographyControl(), { label: __('Label', 'blockenberg'), typo: a.labelTypo || {}, onChange: function(v){ set({ labelTypo: v }); } }),
315 getTypographyControl() && el(getTypographyControl(), { label: __('Sub-Label', 'blockenberg'), typo: a.subLabelTypo || {}, onChange: function(v){ set({ subLabelTypo: v }); } })
316 )
317 ),
318
319 // Editor Preview
320 el('div', blockProps,
321 el('div', { style: wrapStyle },
322 el('div', { className: 'bkbg-icon-shape bkbg-icon-anim-' + a.animation, style: iconStyle },
323 el('span', { style: { fontSize: a.iconSize + 'px', lineHeight: '1', display: 'block' } }, a.icon)
324 ),
325 a.showLabel && a.label && el('div', {
326 className: 'bkbg-icon-label',
327 style: {
328 color: a.labelColor,
329 textAlign: a.align,
330 }
331 }, a.label),
332 a.showSubLabel && a.subLabel && el('div', {
333 className: 'bkbg-icon-sublabel',
334 style: {
335 color: a.subLabelColor,
336 textAlign: a.align,
337 }
338 }, a.subLabel)
339 )
340 )
341 );
342 },
343
344 save: function (props) {
345 return el('div', useBlockProps.save(),
346 el('div', {
347 className: 'bkbg-icon-app',
348 'data-opts': JSON.stringify(props.attributes),
349 })
350 );
351 }
352 });
353 }() );
354