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

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

374 lines 19.4 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 __ = wp.i18n.__;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var useBlockProps = wp.blockEditor.useBlockProps;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var PanelBody = wp.components.PanelBody;
10 var Button = wp.components.Button;
11 var TextControl = wp.components.TextControl;
12 var TextareaControl = wp.components.TextareaControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var RangeControl = wp.components.RangeControl;
15 var SelectControl = wp.components.SelectControl;
16
17 function hexToRgba(hex, alpha) {
18 if (!hex || hex.length < 7) return 'rgba(180,180,180,' + alpha + ')';
19 var r = parseInt(hex.slice(1, 3), 16);
20 var g = parseInt(hex.slice(3, 5), 16);
21 var b = parseInt(hex.slice(5, 7), 16);
22 return 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
23 }
24
25 var _dbTC, _dbTV;
26 function _tc() { return _dbTC || (_dbTC = window.bkbgTypographyControl); }
27 function _tv(t, p) { return (_dbTV || (_dbTV = window.bkbgTypoCssVars)) ? _dbTV(t, p) : {}; }
28
29 function renderSideEditor(a, set, side) {
30 var isLeft = side === 'left';
31 var label = isLeft ? a.leftLabel : a.rightLabel;
32 var icon = isLeft ? a.leftIcon : a.rightIcon;
33 var points = isLeft ? a.leftPoints : a.rightPoints;
34 var color = isLeft ? a.leftColor : a.rightColor;
35 var bg = isLeft ? a.leftBg : a.rightBg;
36 var labelKey = isLeft ? 'leftLabel' : 'rightLabel';
37 var iconKey = isLeft ? 'leftIcon' : 'rightIcon';
38 var ptsKey = isLeft ? 'leftPoints' : 'rightPoints';
39
40 var headerBg = color;
41 var bodyBg = hexToRgba(color, 0.07);
42 var borderCol= hexToRgba(color, 0.35);
43
44 var cardStyle = {
45 overflow: 'hidden',
46 border: '1px solid ' + borderCol,
47 borderRadius: a.borderRadius + 'px',
48 flexShrink: '0',
49 flex: '1',
50 minWidth: '0',
51 boxShadow: a.style === 'card' ? '0 2px 12px rgba(0,0,0,.07)' : 'none',
52 background: a.style === 'minimal' ? 'transparent' : bg
53 };
54
55 function updatePoint(idx, val) {
56 var newPts = points.map(function (p, i) { return i === idx ? val : p; });
57 var u = {}; u[ptsKey] = newPts;
58 set(u);
59 }
60
61 function removePoint(idx) {
62 var newPts = points.filter(function (_, i) { return i !== idx; });
63 var u = {}; u[ptsKey] = newPts;
64 set(u);
65 }
66
67 function addPoint() {
68 var u = {}; u[ptsKey] = points.concat(['New argument point']);
69 set(u);
70 }
71
72 return el('div', { key: 'side-' + side, style: cardStyle },
73 // Header
74 el('div', {
75 style: {
76 background: headerBg,
77 padding: '14px ' + a.gap + 'px',
78 display: 'flex', alignItems: 'center', gap: '10px'
79 }
80 },
81 a.showIcons && el('span', { style: { fontSize: '22px' } }, icon),
82 el('input', {
83 type: 'text', value: label,
84 className: 'bkbg-db-side-label',
85 style: {
86 background: 'transparent', border: 'none', outline: 'none',
87 color: a.headerTextColor, flex: '1'
88 },
89 onChange: function (e) { var u = {}; u[labelKey] = e.target.value; set(u); }
90 })
91 ),
92 // Points list
93 el('div', { style: { padding: '16px ' + a.gap + 'px' } },
94 points.map(function (point, idx) {
95 return el('div', {
96 key: 'pt-' + idx,
97 style: {
98 display: 'flex', alignItems: 'flex-start', gap: '8px',
99 marginBottom: '10px'
100 }
101 },
102 a.showBullets && el('span', {
103 style: {
104 color: color, fontWeight: 800, fontSize: '18px',
105 lineHeight: '1', flexShrink: 0, paddingTop: '1px'
106 }
107 }, isLeft ? '' : ''),
108 el('input', {
109 type: 'text',
110 value: point,
111 className: 'bkbg-db-point-text',
112 style: {
113 flex: '1', border: 'none', outline: 'none',
114 background: 'transparent',
115 color: a.textColor, fontFamily: 'inherit'
116 },
117 onChange: function (e) { updatePoint(idx, e.target.value); }
118 }),
119 el('button', {
120 onClick: function () { removePoint(idx); },
121 title: __('Remove', 'blockenberg'),
122 style: {
123 background: 'none', border: 'none', cursor: 'pointer',
124 color: '#94a3b8', fontSize: '13px', padding: '0 2px',
125 flexShrink: 0
126 }
127 }, '')
128 );
129 }),
130 el('button', {
131 onClick: addPoint,
132 style: {
133 background: 'none', border: '1px dashed ' + borderCol,
134 borderRadius: '6px', cursor: 'pointer', color: color,
135 fontSize: '12px', padding: '5px 12px', width: '100%',
136 textAlign: 'center', fontWeight: 600, marginTop: '4px'
137 }
138 }, '+ ' + __('Add point', 'blockenberg'))
139 )
140 );
141 }
142
143 registerBlockType('blockenberg/debate-block', {
144 title: __('Debate Block', 'blockenberg'),
145 icon: 'editor-justify',
146 category: 'bkbg-content',
147 description: __('Two-column argument block: Pro vs Con, Side A vs Side B, and more.', 'blockenberg'),
148
149 edit: function (props) {
150 var a = props.attributes;
151 var set = props.setAttributes;
152
153 var styleOptions = [
154 { label: __('Card (shadow)', 'blockenberg'), value: 'card' },
155 { label: __('Bordered', 'blockenberg'), value: 'bordered' },
156 { label: __('Minimal', 'blockenberg'), value: 'minimal' }
157 ];
158 var layoutOptions = [
159 { label: __('Two columns', 'blockenberg'), value: 'columns' },
160 { label: __('Stacked', 'blockenberg'), value: 'stacked' }
161 ];
162 var fontWeightOptions = [
163 { label: '400', value: 400 }, { label: '600', value: 600 }, { label: '700', value: 700 }
164 ];
165
166 var inspector = el(InspectorControls, {},
167 // Title
168 el(PanelBody, { title: __('Title', 'blockenberg'), initialOpen: true },
169 el(ToggleControl, {
170 label: __('Show title', 'blockenberg'), checked: a.showTitle, __nextHasNoMarginBottom: true,
171 onChange: function (v) { set({ showTitle: v }); }
172 }),
173 a.showTitle && el(TextControl, {
174 label: __('Title', 'blockenberg'), value: a.blockTitle, __nextHasNoMarginBottom: true,
175 onChange: function (v) { set({ blockTitle: v }); }
176 }),
177 el(ToggleControl, {
178 label: __('Show subtitle', 'blockenberg'), checked: a.showSubtitle, __nextHasNoMarginBottom: true,
179 onChange: function (v) { set({ showSubtitle: v }); }
180 }),
181 a.showSubtitle && el(TextControl, {
182 label: __('Subtitle', 'blockenberg'), value: a.blockSubtitle, __nextHasNoMarginBottom: true,
183 onChange: function (v) { set({ blockSubtitle: v }); }
184 })
185 ),
186
187 // Side Labels
188 el(PanelBody, { title: __('Side Labels & Icons', 'blockenberg'), initialOpen: false },
189 el(TextControl, {
190 label: __('Left side icon', 'blockenberg'), value: a.leftIcon, __nextHasNoMarginBottom: true,
191 onChange: function (v) { set({ leftIcon: v }); }
192 }),
193 el(TextControl, {
194 label: __('Left side label', 'blockenberg'), value: a.leftLabel, __nextHasNoMarginBottom: true,
195 onChange: function (v) { set({ leftLabel: v }); }
196 }),
197 el(TextControl, {
198 label: __('Right side icon', 'blockenberg'), value: a.rightIcon, __nextHasNoMarginBottom: true,
199 onChange: function (v) { set({ rightIcon: v }); }
200 }),
201 el(TextControl, {
202 label: __('Right side label', 'blockenberg'), value: a.rightLabel, __nextHasNoMarginBottom: true,
203 onChange: function (v) { set({ rightLabel: v }); }
204 })
205 ),
206
207 // Verdict
208 el(PanelBody, { title: __('Verdict', 'blockenberg'), initialOpen: false },
209 el(ToggleControl, {
210 label: __('Show verdict', 'blockenberg'), checked: a.showVerdict, __nextHasNoMarginBottom: true,
211 onChange: function (v) { set({ showVerdict: v }); }
212 }),
213 a.showVerdict && el(TextControl, {
214 label: __('Verdict label', 'blockenberg'), value: a.verdictLabel, __nextHasNoMarginBottom: true,
215 onChange: function (v) { set({ verdictLabel: v }); }
216 }),
217 a.showVerdict && el(TextareaControl, {
218 label: __('Verdict text', 'blockenberg'), value: a.verdict, rows: 4, __nextHasNoMarginBottom: true,
219 onChange: function (v) { set({ verdict: v }); }
220 })
221 ),
222
223 // Display
224 el(PanelBody, { title: __('Display', 'blockenberg'), initialOpen: false },
225 el(SelectControl, {
226 label: __('Layout', 'blockenberg'), value: a.layout, options: layoutOptions, __nextHasNoMarginBottom: true,
227 onChange: function (v) { set({ layout: v }); }
228 }),
229 el(SelectControl, {
230 label: __('Style', 'blockenberg'), value: a.style, options: styleOptions, __nextHasNoMarginBottom: true,
231 onChange: function (v) { set({ style: v }); }
232 }),
233 el(ToggleControl, {
234 label: __('Show icons', 'blockenberg'), checked: a.showIcons, __nextHasNoMarginBottom: true,
235 onChange: function (v) { set({ showIcons: v }); }
236 }),
237 el(ToggleControl, {
238 label: __('Show ✓/✗ bullets', 'blockenberg'), checked: a.showBullets, __nextHasNoMarginBottom: true,
239 onChange: function (v) { set({ showBullets: v }); }
240 })
241 ),
242
243 // Spacing & Shape
244 el(PanelBody, { title: __('Spacing & Shape', 'blockenberg'), initialOpen: false },
245 el(RangeControl, {
246 label: __('Border radius', 'blockenberg'), value: a.borderRadius, min: 0, max: 32, __nextHasNoMarginBottom: true,
247 onChange: function (v) { set({ borderRadius: v }); }
248 }),
249 el(RangeControl, {
250 label: __('Gap / padding', 'blockenberg'), value: a.gap, min: 8, max: 48, __nextHasNoMarginBottom: true,
251 onChange: function (v) { set({ gap: v }); }
252 }),
253 ),
254
255 // Colors
256
257 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
258 _tc() && _tc()({ label: __('Title typography', 'blockenberg'), value: a.typoTitle || {}, onChange: function (v) { set({ typoTitle: v }); } }),
259 _tc() && _tc()({ label: __('Subtitle typography', 'blockenberg'), value: a.typoSubtitle || {}, onChange: function (v) { set({ typoSubtitle: v }); } }),
260 _tc() && _tc()({ label: __('Header typography', 'blockenberg'), value: a.typoHeader || {}, onChange: function (v) { set({ typoHeader: v }); } }),
261 _tc() && _tc()({ label: __('Point typography', 'blockenberg'), value: a.typoPoint || {}, onChange: function (v) { set({ typoPoint: v }); } })
262 ),
263 el(PanelBody, { title: __('Colors', 'blockenberg'), initialOpen: false },
264 el(PanelColorSettings, {
265 title: __('Side Colors', 'blockenberg'), initialOpen: false,
266 colorSettings: [
267 { value: a.leftColor, label: __('Left header', 'blockenberg'), onChange: function (c) { set({ leftColor: c }); } },
268 { value: a.leftBg, label: __('Left body bg', 'blockenberg'), onChange: function (c) { set({ leftBg: c }); } },
269 { value: a.rightColor, label: __('Right header', 'blockenberg'), onChange: function (c) { set({ rightColor: c }); } },
270 { value: a.rightBg, label: __('Right body bg', 'blockenberg'),onChange: function (c) { set({ rightBg: c }); } }
271 ]
272 }),
273 el(PanelColorSettings, {
274 title: __('General', 'blockenberg'), initialOpen: false,
275 colorSettings: [
276 { value: a.bgColor, label: __('Block background', 'blockenberg'), onChange: function (c) { set({ bgColor: c }); } },
277 { value: a.textColor, label: __('Text', 'blockenberg'), onChange: function (c) { set({ textColor: c }); } },
278 { value: a.headerTextColor, label: __('Header text', 'blockenberg'), onChange: function (c) { set({ headerTextColor: c }); } },
279 { value: a.titleColor, label: __('Title', 'blockenberg'), onChange: function (c) { set({ titleColor: c }); } },
280 { value: a.subtitleColor, label: __('Subtitle', 'blockenberg'), onChange: function (c) { set({ subtitleColor: c }); } }
281 ]
282 }),
283 el(PanelColorSettings, {
284 title: __('Verdict', 'blockenberg'), initialOpen: false,
285 colorSettings: [
286 { value: a.verdictBg, label: __('Verdict background', 'blockenberg'), onChange: function (c) { set({ verdictBg: c }); } },
287 { value: a.verdictColor, label: __('Verdict text', 'blockenberg'), onChange: function (c) { set({ verdictColor: c }); } },
288 { value: a.verdictBorderColor, label: __('Verdict border', 'blockenberg'), onChange: function (c) { set({ verdictBorderColor: c }); } }
289 ]
290 })
291 )
292 );
293
294 var isColumns = a.layout === 'columns';
295 var blockProps = useBlockProps({ className: 'bkbg-editor-wrap', 'data-block-label': 'Debate Block',
296 style: Object.assign(
297 { '--bkbg-db-ttl-fs': (a.blockTitleFontSize || 22) + 'px',
298 '--bkbg-db-sub-fs': (a.blockSubtitleFontSize || 14) + 'px',
299 '--bkbg-db-hdr-fs': (a.headerFontSize || 18) + 'px',
300 '--bkbg-db-pt-fs': (a.fontSize || 14) + 'px' },
301 _tv(a.typoTitle||{}, '--bkbg-db-ttl-'),
302 _tv(a.typoSubtitle||{}, '--bkbg-db-sub-'),
303 _tv(a.typoHeader||{}, '--bkbg-db-hdr-'),
304 _tv(a.typoPoint||{}, '--bkbg-db-pt-')
305 )
306 });
307
308 return el('div', blockProps,
309 inspector,
310 el('div', { className: 'bkbg-db-block', style: { background: a.bgColor, borderRadius: a.borderRadius + 'px', overflow: 'hidden' } },
311 // Title area
312 (a.showTitle || a.showSubtitle) && el('div', { style: { textAlign: 'center', padding: '28px ' + a.gap + 'px ' + (a.gap) + 'px', borderBottom: '1px solid #f1f5f9' } },
313 a.showTitle && el('h3', {
314 className: 'bkbg-db-title',
315 style: { margin: 0, color: a.titleColor }
316 }, a.blockTitle),
317 a.showSubtitle && el('p', {
318 className: 'bkbg-db-subtitle',
319 style: { margin: '8px 0 0', color: a.subtitleColor }
320 }, a.blockSubtitle)
321 ),
322
323 // Sides
324 el('div', {
325 style: {
326 display: isColumns ? 'flex' : 'block',
327 gap: isColumns ? '0' : '0',
328 flexWrap: 'wrap'
329 }
330 },
331 renderSideEditor(a, set, 'left'),
332 // VS divider
333 isColumns && el('div', {
334 style: {
335 display: 'flex', alignItems: 'center', justifyContent: 'center',
336 width: '48px', flexShrink: 0, background: '#f1f5f9',
337 color: '#64748b', fontWeight: 900, fontSize: '13px',
338 letterSpacing: '.05em'
339 }
340 }, 'VS'),
341 renderSideEditor(a, set, 'right')
342 ),
343
344 // Verdict
345 a.showVerdict && el('div', {
346 style: {
347 margin: a.gap + 'px',
348 background: a.verdictBg,
349 border: '1px solid ' + a.verdictBorderColor,
350 borderRadius: a.borderRadius + 'px',
351 padding: '16px ' + (a.gap) + 'px'
352 }
353 },
354 el('div', {
355 style: { fontWeight: 700, color: a.verdictColor, marginBottom: '8px', fontSize: '15px' }
356 }, a.verdictLabel),
357 el('div', { className: 'bkbg-db-verdict-text', style: { color: a.verdictColor, lineHeight: '1.65' } }, a.verdict)
358 )
359 )
360 );
361 },
362
363 save: function (props) {
364 var useBlockProps = wp.blockEditor.useBlockProps;
365 return el('div', useBlockProps.save(),
366 el('div', {
367 className: 'bkbg-debate-block-app',
368 'data-opts': JSON.stringify(props.attributes)
369 })
370 );
371 }
372 });
373 }() );
374