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

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

354 lines 17.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 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 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 var TextareaControl = wp.components.TextareaControl;
17
18 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
19 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
20
21 var QUADRANT_COLOR_KEYS = ['strengthsColor', 'weaknessesColor', 'opportunitiesColor', 'threatsColor'];
22 var QUADRANT_IDS = ['strengths', 'weaknesses', 'opportunities', 'threats'];
23
24 function getColor(a, idx) {
25 return a[QUADRANT_COLOR_KEYS[idx]] || '#3b82f6';
26 }
27
28 function updateQuadrant(quadrants, idx, field, val) {
29 return quadrants.map(function (q, i) {
30 if (i !== idx) return q;
31 var updated = {}; updated[field] = val;
32 return Object.assign({}, q, updated);
33 });
34 }
35
36 function updateItem(quadrants, qIdx, itemIdx, val) {
37 return quadrants.map(function (q, i) {
38 if (i !== qIdx) return q;
39 var newItems = q.items.map(function (it, j) { return j === itemIdx ? val : it; });
40 return Object.assign({}, q, { items: newItems });
41 });
42 }
43
44 function addItem(quadrants, qIdx) {
45 return quadrants.map(function (q, i) {
46 if (i !== qIdx) return q;
47 return Object.assign({}, q, { items: q.items.concat(['New item']) });
48 });
49 }
50
51 function removeItem(quadrants, qIdx, itemIdx) {
52 return quadrants.map(function (q, i) {
53 if (i !== qIdx) return q;
54 return Object.assign({}, q, { items: q.items.filter(function (_, j) { return j !== itemIdx; }) });
55 });
56 }
57
58 function hexToRgba(hex, alpha) {
59 var r = parseInt(hex.slice(1, 3), 16);
60 var g = parseInt(hex.slice(3, 5), 16);
61 var b = parseInt(hex.slice(5, 7), 16);
62 return 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
63 }
64
65 function getBullet(listStyle, idx) {
66 if (listStyle === 'number') return (idx + 1) + '.';
67 if (listStyle === 'check') return '';
68 if (listStyle === 'dash') return '';
69 return '';
70 }
71
72 registerBlockType('blockenberg/swot-analysis', {
73 title: __('SWOT Analysis', 'blockenberg'),
74 icon: 'grid-view',
75 category: 'bkbg-business',
76 description: __('2×2 SWOT matrix with per-quadrant item lists, colors, and icons.', 'blockenberg'),
77
78 edit: function (props) {
79 var a = props.attributes;
80 var setAttributes = props.setAttributes;
81 var q = a.quadrants;
82
83 var listStyleOptions = [
84 { label: __('Bullet •', 'blockenberg'), value: 'bullet' },
85 { label: __('Number 1.', 'blockenberg'), value: 'number' },
86 { label: __('Check ✓', 'blockenberg'), value: 'check' },
87 { label: __('Dash —', 'blockenberg'), value: 'dash' },
88 { label: __('None', 'blockenberg'), value: 'none' }
89 ];
90
91 var fontWeightOptions = [
92 { label: '400', value: 400 }, { label: '500', value: 500 },
93 { label: '600', value: 600 }, { label: '700', value: 700 }, { label: '800', value: 800 }
94 ];
95
96 // Inspector
97 var inspector = el(InspectorControls, {},
98 // Title
99 el(PanelBody, { title: __('Title', 'blockenberg'), initialOpen: true },
100 el(ToggleControl, {
101 label: __('Show block title', 'blockenberg'),
102 checked: a.showTitle, __nextHasNoMarginBottom: true,
103 onChange: function (v) { setAttributes({ showTitle: v }); }
104 }),
105 a.showTitle && el(TextControl, {
106 label: __('Title text', 'blockenberg'),
107 value: a.blockTitle, __nextHasNoMarginBottom: true,
108 onChange: function (v) { setAttributes({ blockTitle: v }); }
109 }),
110 ),
111
112 // Quadrant Labels
113 el(PanelBody, { title: __('Quadrant Labels', 'blockenberg'), initialOpen: false },
114 q.map(function (quad, i) {
115 return el('div', { key: 'label-' + i, style: { marginBottom: '12px' } },
116 el(TextControl, {
117 label: __('Q' + (i + 1) + ' label', 'blockenberg'),
118 value: quad.label, __nextHasNoMarginBottom: true,
119 onChange: function (v) { setAttributes({ quadrants: updateQuadrant(q, i, 'label', v) }); }
120 }),
121 a.showIcons && el(TextControl, {
122 label: __('Icon / Emoji', 'blockenberg'),
123 value: quad.icon, __nextHasNoMarginBottom: true,
124 onChange: function (v) { setAttributes({ quadrants: updateQuadrant(q, i, 'icon', v) }); }
125 })
126 );
127 })
128 ),
129
130 // Display
131 el(PanelBody, { title: __('Display', 'blockenberg'), initialOpen: false },
132 el(ToggleControl, {
133 label: __('Show icons / emojis', 'blockenberg'),
134 checked: a.showIcons, __nextHasNoMarginBottom: true,
135 onChange: function (v) { setAttributes({ showIcons: v }); }
136 }),
137 el(SelectControl, {
138 label: __('List style', 'blockenberg'),
139 value: a.listStyle, options: listStyleOptions, __nextHasNoMarginBottom: true,
140 onChange: function (v) { setAttributes({ listStyle: v }); }
141 }),
142 el(ToggleControl, {
143 label: __('Enable shadow', 'blockenberg'),
144 checked: a.enableShadow, __nextHasNoMarginBottom: true,
145 onChange: function (v) { setAttributes({ enableShadow: v }); }
146 })
147 ),
148
149 // Spacing
150 el(PanelBody, { title: __('Spacing & Shape', 'blockenberg'), initialOpen: false },
151 el(RangeControl, {
152 label: __('Border radius', 'blockenberg'),
153 value: a.borderRadius, min: 0, max: 32, __nextHasNoMarginBottom: true,
154 onChange: function (v) { setAttributes({ borderRadius: v }); }
155 }),
156 el(RangeControl, {
157 label: __('Gap between quadrants', 'blockenberg'),
158 value: a.gap, min: 0, max: 40, __nextHasNoMarginBottom: true,
159 onChange: function (v) { setAttributes({ gap: v }); }
160 }),
161 el(RangeControl, {
162 label: __('Header padding (vertical)', 'blockenberg'),
163 value: a.headerPaddingV, min: 8, max: 40, __nextHasNoMarginBottom: true,
164 onChange: function (v) { setAttributes({ headerPaddingV: v }); }
165 }),
166 el(RangeControl, {
167 label: __('Header padding (horizontal)', 'blockenberg'),
168 value: a.headerPaddingH, min: 8, max: 48, __nextHasNoMarginBottom: true,
169 onChange: function (v) { setAttributes({ headerPaddingH: v }); }
170 }),
171 el(RangeControl, {
172 label: __('Body padding (vertical)', 'blockenberg'),
173 value: a.bodyPaddingV, min: 8, max: 40, __nextHasNoMarginBottom: true,
174 onChange: function (v) { setAttributes({ bodyPaddingV: v }); }
175 }),
176 el(RangeControl, {
177 label: __('Body padding (horizontal)', 'blockenberg'),
178 value: a.bodyPaddingH, min: 8, max: 48, __nextHasNoMarginBottom: true,
179 onChange: function (v) { setAttributes({ bodyPaddingH: v }); }
180 })
181 ),
182
183 // Typography
184 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
185 getTypoControl()({ label: __('Title', 'blockenberg'), value: a.titleTypo, onChange: function (v) { setAttributes({ titleTypo: v }); } }),
186 getTypoControl()({ label: __('Header Label', 'blockenberg'), value: a.headerTypo, onChange: function (v) { setAttributes({ headerTypo: v }); } }),
187 getTypoControl()({ label: __('Item Text', 'blockenberg'), value: a.itemTypo, onChange: function (v) { setAttributes({ itemTypo: v }); } })
188 ),
189
190 // Colors
191 el(PanelBody, { title: __('Colors', 'blockenberg'), initialOpen: false },
192 el(PanelColorSettings, {
193 title: __('Quadrant Colors', 'blockenberg'), initialOpen: false,
194 colorSettings: [
195 { value: a.strengthsColor, label: __('Strengths', 'blockenberg'), onChange: function (c) { setAttributes({ strengthsColor: c }); } },
196 { value: a.weaknessesColor, label: __('Weaknesses', 'blockenberg'), onChange: function (c) { setAttributes({ weaknessesColor: c }); } },
197 { value: a.opportunitiesColor, label: __('Opportunities', 'blockenberg'), onChange: function (c) { setAttributes({ opportunitiesColor: c }); } },
198 { value: a.threatsColor, label: __('Threats', 'blockenberg'), onChange: function (c) { setAttributes({ threatsColor: c }); } }
199 ]
200 }),
201 el(PanelColorSettings, {
202 title: __('General Colors', 'blockenberg'), initialOpen: false,
203 colorSettings: [
204 { value: a.bgColor, label: __('Card background', 'blockenberg'), onChange: function (c) { setAttributes({ bgColor: c }); } },
205 { value: a.borderColor, label: __('Border', 'blockenberg'), onChange: function (c) { setAttributes({ borderColor: c }); } },
206 { value: a.titleColor, label: __('Block title', 'blockenberg'), onChange: function (c) { setAttributes({ titleColor: c }); } },
207 { value: a.textColor, label: __('Item text', 'blockenberg'), onChange: function (c) { setAttributes({ textColor: c }); } },
208 { value: a.headerTextColor, label: __('Header text', 'blockenberg'), onChange: function (c) { setAttributes({ headerTextColor: c }); } }
209 ]
210 })
211 )
212 );
213
214 // Render a single quadrant for the editor
215 function renderQuadrant(quad, i) {
216 var color = getColor(a, i);
217 var headerBg = color;
218 var bodyBg = hexToRgba(color, 0.06);
219 var borderCol = hexToRgba(color, 0.3);
220
221 return el('div', {
222 key: 'q-' + i,
223 className: 'bkbg-swot-quadrant',
224 style: {
225 background: a.bgColor,
226 border: '1px solid ' + borderCol,
227 borderRadius: a.borderRadius + 'px',
228 overflow: 'hidden',
229 boxShadow: a.enableShadow ? '0 2px 12px rgba(0,0,0,0.07)' : 'none'
230 }
231 },
232 // Header
233 el('div', {
234 className: 'bkbg-swot-header',
235 style: {
236 background: headerBg,
237 padding: a.headerPaddingV + 'px ' + a.headerPaddingH + 'px',
238 display: 'flex', alignItems: 'center', gap: '8px'
239 }
240 },
241 a.showIcons && el('span', { style: { fontSize: '20px', lineHeight: 1 } }, quad.icon),
242 el('input', {
243 type: 'text',
244 value: quad.label,
245 className: 'bkbg-swot-label',
246 style: {
247 background: 'transparent', border: 'none', outline: 'none',
248 color: a.headerTextColor,
249 flex: '1', cursor: 'text'
250 },
251 onChange: function (e) { setAttributes({ quadrants: updateQuadrant(q, i, 'label', e.target.value) }); }
252 })
253 ),
254 // Items
255 el('div', {
256 className: 'bkbg-swot-body',
257 style: {
258 background: bodyBg,
259 padding: a.bodyPaddingV + 'px ' + a.bodyPaddingH + 'px',
260 minHeight: '80px'
261 }
262 },
263 quad.items.map(function (item, itemIdx) {
264 return el('div', {
265 key: 'item-' + itemIdx,
266 style: { display: 'flex', alignItems: 'flex-start', gap: '8px', marginBottom: '6px' }
267 },
268 a.listStyle !== 'none' && el('span', {
269 className: 'bkbg-swot-bullet',
270 style: {
271 color: color, fontWeight: 700,
272 flexShrink: 0, minWidth: '16px', paddingTop: '1px'
273 }
274 }, getBullet(a.listStyle, itemIdx)),
275 el('input', {
276 type: 'text',
277 value: item,
278 className: 'bkbg-swot-item-text',
279 style: {
280 flex: 1, border: 'none', outline: 'none', background: 'transparent',
281 color: a.textColor, width: '100%'
282 },
283 onChange: function (e) {
284 setAttributes({ quadrants: updateItem(q, i, itemIdx, e.target.value) });
285 }
286 }),
287 el('button', {
288 onClick: function () { setAttributes({ quadrants: removeItem(q, i, itemIdx) }); },
289 style: {
290 background: 'none', border: 'none', cursor: 'pointer',
291 color: '#94a3b8', fontSize: '14px', padding: '0 2px', lineHeight: 1,
292 flexShrink: 0
293 },
294 title: __('Remove item', 'blockenberg')
295 }, '')
296 );
297 }),
298 el('button', {
299 onClick: function () { setAttributes({ quadrants: addItem(q, i) }); },
300 style: {
301 background: 'none', border: '1px dashed ' + borderCol, borderRadius: '6px',
302 cursor: 'pointer', color: color, fontSize: '12px', padding: '4px 10px',
303 marginTop: '6px', width: '100%', textAlign: 'center', fontWeight: 600
304 }
305 }, '+ ' + __('Add item', 'blockenberg'))
306 )
307 );
308 }
309
310 var blockProps = useBlockProps((function () {
311 var _tvf = getTypoCssVars();
312 var s = {};
313 if (_tvf) {
314 Object.assign(s, _tvf(a.titleTypo, '--bkswa-tt-'));
315 Object.assign(s, _tvf(a.headerTypo, '--bkswa-ht-'));
316 Object.assign(s, _tvf(a.itemTypo, '--bkswa-it-'));
317 }
318 return { className: 'bkbg-swot-block', 'data-block-label': 'SWOT Analysis', style: s };
319 })());
320
321 return el('div', blockProps,
322 inspector,
323 a.showTitle && el('h3', {
324 className: 'bkbg-swot-title',
325 style: {
326 textAlign: 'center', color: a.titleColor,
327 margin: '0 0 20px'
328 }
329 }, a.blockTitle),
330 el('div', {
331 className: 'bkbg-swot-grid',
332 style: {
333 display: 'grid',
334 gridTemplateColumns: '1fr 1fr',
335 gap: a.gap + 'px'
336 }
337 },
338 q.map(function (quad, i) { return renderQuadrant(quad, i); })
339 )
340 );
341 },
342
343 save: function (props) {
344 var useBlockProps = wp.blockEditor.useBlockProps;
345 return el('div', useBlockProps.save(),
346 el('div', {
347 className: 'bkbg-swot-analysis-app',
348 'data-opts': JSON.stringify(props.attributes)
349 })
350 );
351 }
352 });
353 }() );
354