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

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

270 lines 15.7 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 Fragment = wp.element.Fragment;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var __ = wp.i18n.__;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var useBlockProps = wp.blockEditor.useBlockProps;
10 var PanelBody = wp.components.PanelBody;
11 var RangeControl = wp.components.RangeControl;
12 var SelectControl = wp.components.SelectControl;
13 var TextControl = wp.components.TextControl;
14 var ToggleControl = wp.components.ToggleControl;
15 var Button = wp.components.Button;
16
17 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
18 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
19 var IP = function () { return window.bkbgIconPicker; };
20
21 var LAYOUT_OPTIONS = [
22 { value: 'two-col', label: 'Two Columns (side by side)' },
23 { value: 'stacked', label: 'Stacked (pros then cons)' },
24 ];
25
26 /* ── Single editable column ──────────────────────────────────────────── */
27 function Column(props) {
28 var heading = props.heading;
29 var headBg = props.headBg;
30 var headColor = props.headColor;
31 var colBg = props.colBg;
32 var border = props.border;
33 var bulletClr = props.bulletClr;
34 var itemColor = props.itemColor;
35 var icon = props.icon;
36 var iconType = props.iconType || 'custom-char';
37 var iconDash = props.iconDash;
38 var iconImg = props.iconImg;
39 var iconDashColor = props.iconDashColor;
40 var items = props.items;
41 var onUpdate = props.onUpdate;
42 var showIcons = props.showIcons;
43 var itemGap = props.itemGap;
44 var colRadius = props.colRadius;
45
46 return el('div', {
47 style: {
48 flex: 1, background: colBg, borderRadius: colRadius + 'px',
49 border: '1.5px solid ' + border, overflow: 'hidden',
50 display: 'flex', flexDirection: 'column',
51 }
52 },
53 /* Column header */
54 el('div', {
55 className: 'bkbg-pc-col-head',
56 style: {
57 background: headBg, color: headColor,
58 padding: '12px 18px',
59 display: 'flex', alignItems: 'center', gap: '8px',
60 }
61 },
62 showIcons && el('span', { style: { fontWeight: 800 } }, iconType !== 'custom-char' ? IP().buildEditorIcon(iconType, icon, iconDash, iconImg, iconDashColor) : icon),
63 heading
64 ),
65
66 /* Items body */
67 el('ul', {
68 style: {
69 listStyle: 'none', margin: 0,
70 padding: '16px 18px',
71 display: 'flex', flexDirection: 'column', gap: itemGap + 'px',
72 flex: 1,
73 }
74 },
75 items.map(function (item, idx) {
76 return el('li', { key: idx, style: { display: 'flex', alignItems: 'flex-start', gap: '8px' } },
77 showIcons && el('span', { className: 'bkbg-pc-item-icon', style: { color: bulletClr, flexShrink: 0 } }, iconType !== 'custom-char' ? IP().buildEditorIcon(iconType, icon, iconDash, iconImg, iconDashColor) : icon),
78 el('span', {
79 className: 'bkbg-pc-item-text',
80 contentEditable: true, suppressContentEditableWarning: true,
81 onBlur: function (e) {
82 var arr = items.slice(); arr[idx] = e.target.innerText; onUpdate(arr);
83 },
84 style: { color: itemColor, flex: 1, outline: 'none', cursor: 'text' }
85 }, item)
86 );
87 }),
88 /* Add button */
89 el('li', null,
90 el(Button, {
91 variant: 'tertiary',
92 onClick: function () { onUpdate(items.concat('')); },
93 style: { fontSize: '12px', color: bulletClr, padding: '2px 4px' }
94 }, '+ ' + __('Add', 'blockenberg'))
95 )
96 )
97 );
98 }
99
100 /* ── Preview ────────────────────────────────────────────────────────── */
101 function ProsConsPreview(props) {
102 var a = props.attrs;
103 var setA = props.setAttrs;
104
105 var wrapStyle = {
106 maxWidth: (a.maxWidth || 860) + 'px',
107 margin: '0 auto',
108 padding: (a.paddingV || 0) + 'px ' + (a.paddingH || 0) + 'px',
109 background: a.cardBg || undefined,
110 boxSizing: 'border-box',
111 };
112
113 var colProps = {
114 itemGap: a.itemGap || 12,
115 colRadius: a.colRadius || 12,
116 showIcons: a.showIcons !== false,
117 };
118
119 return el('div', { style: wrapStyle },
120 a.showHeading && el('h3', {
121 className: 'bkbg-pc-heading',
122 style: {
123 color: a.headingColor || '#1e1b4b',
124 textAlign: 'center', marginTop: 0, marginBottom: '20px',
125 }
126 }, a.heading || __('Pros & Cons', 'blockenberg')),
127
128 el('div', {
129 style: {
130 display: a.layout === 'stacked' ? 'flex' : 'flex',
131 flexDirection: a.layout === 'stacked' ? 'column' : 'row',
132 gap: (a.columnGap || 16) + 'px',
133 }
134 },
135 el(Column, Object.assign({}, colProps, {
136 heading: a.prosHeading || 'Pros',
137 headBg: a.prosHeadBg || '#dcfce7',
138 headColor: a.prosHeadColor|| '#15803d',
139 colBg: a.prosBg || '#f0fdf4',
140 border: a.prosBorder || '#bbf7d0',
141 bulletClr: a.prosBulletColor || '#16a34a',
142 itemColor: a.prosItemColor|| '#166534',
143 icon: a.prosIcon || '',
144 iconType: a.prosIconType || 'custom-char',
145 iconDash: a.prosIconDashicon,
146 iconImg: a.prosIconImageUrl,
147 iconDashColor: a.prosIconDashiconColor,
148 items: a.pros || [],
149 onUpdate: function (v) { setA({ pros: v }); },
150 })),
151
152 el(Column, Object.assign({}, colProps, {
153 heading: a.consHeading || 'Cons',
154 headBg: a.consHeadBg || '#fee2e2',
155 headColor: a.consHeadColor|| '#b91c1c',
156 colBg: a.consBg || '#fef2f2',
157 border: a.consBorder || '#fecaca',
158 bulletClr: a.consBulletColor || '#dc2626',
159 itemColor: a.consItemColor|| '#991b1b',
160 icon: a.consIcon || '',
161 iconType: a.consIconType || 'custom-char',
162 iconDash: a.consIconDashicon,
163 iconImg: a.consIconImageUrl,
164 iconDashColor: a.consIconDashiconColor,
165 items: a.cons || [],
166 onUpdate: function (v) { setA({ cons: v }); },
167 }))
168 )
169 );
170 }
171
172 registerBlockType('blockenberg/pros-cons', {
173 edit: function (props) {
174 var a = props.attributes;
175 var setAttr = props.setAttributes;
176 var TC = getTypoControl();
177 var blockProps = useBlockProps((function () {
178 var _tv = getTypoCssVars();
179 var s = {};
180 if (_tv) {
181 Object.assign(s, _tv(a.headingTypo || {}, '--bkpc-h-'));
182 Object.assign(s, _tv(a.colHeadTypo || {}, '--bkpc-ch-'));
183 Object.assign(s, _tv(a.itemTypo || {}, '--bkpc-it-'));
184 }
185 return { style: s };
186 })());
187
188 return el(Fragment, null,
189 el(InspectorControls, null,
190
191 el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
192 el(ToggleControl, { label: __('Show Block Heading', 'blockenberg'), checked: a.showHeading, onChange: function (v) { setAttr({ showHeading: v }); }, __nextHasNoMarginBottom: true }),
193 a.showHeading && el(TextControl, { label: __('Heading', 'blockenberg'), value: a.heading, onChange: function (v) { setAttr({ heading: v }); } }),
194 el(TextControl, { label: __('Pros Column Heading', 'blockenberg'), value: a.prosHeading, onChange: function (v) { setAttr({ prosHeading: v }); } }),
195 el(TextControl, { label: __('Cons Column Heading', 'blockenberg'), value: a.consHeading, onChange: function (v) { setAttr({ consHeading: v }); } }),
196 el(ToggleControl, { label: __('Show Icons', 'blockenberg'), checked: a.showIcons, onChange: function (v) { setAttr({ showIcons: v }); }, __nextHasNoMarginBottom: true }),
197 a.showIcons && el(IP().IconPickerControl, IP().iconPickerProps(a, setAttr, { charAttr: 'prosIcon', typeAttr: 'prosIconType', dashiconAttr: 'prosIconDashicon', imageUrlAttr: 'prosIconImageUrl', colorAttr: 'prosIconDashiconColor' })),
198 a.showIcons && el(IP().IconPickerControl, IP().iconPickerProps(a, setAttr, { charAttr: 'consIcon', typeAttr: 'consIconType', dashiconAttr: 'consIconDashicon', imageUrlAttr: 'consIconImageUrl', colorAttr: 'consIconDashiconColor' }))
199 ),
200
201 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: false },
202 el(SelectControl, { label: __('Layout', 'blockenberg'), value: a.layout, options: LAYOUT_OPTIONS, onChange: function (v) { setAttr({ layout: v }); } }),
203 el(RangeControl, { label: __('Column Gap (px)', 'blockenberg'), value: a.columnGap, min: 0, max: 60, onChange: function (v) { setAttr({ columnGap: v }); } })
204 ),
205
206
207 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
208 TC && el(TC, { label: __('Heading', 'blockenberg'), value: a.headingTypo || {}, onChange: function(v) { setAttr({ headingTypo: v }); } }),
209 TC && el(TC, { label: __('Column Heading', 'blockenberg'), value: a.colHeadTypo || {}, onChange: function(v) { setAttr({ colHeadTypo: v }); } }),
210 TC && el(TC, { label: __('Item Text', 'blockenberg'), value: a.itemTypo || {}, onChange: function(v) { setAttr({ itemTypo: v }); } })
211 ),
212 el(PanelColorSettings, {
213 title: __('Pros Colors', 'blockenberg'), initialOpen: false,
214 colorSettings: [
215 { label: __('Header Background', 'blockenberg'), value: a.prosHeadBg, onChange: function (v) { setAttr({ prosHeadBg: v || '#dcfce7' }); } },
216 { label: __('Header Text Color', 'blockenberg'), value: a.prosHeadColor, onChange: function (v) { setAttr({ prosHeadColor: v || '#15803d' }); } },
217 { label: __('Column Background', 'blockenberg'), value: a.prosBg, onChange: function (v) { setAttr({ prosBg: v || '#f0fdf4' }); } },
218 { label: __('Border Color', 'blockenberg'), value: a.prosBorder, onChange: function (v) { setAttr({ prosBorder: v || '#bbf7d0' }); } },
219 { label: __('Bullet Color', 'blockenberg'), value: a.prosBulletColor, onChange: function (v) { setAttr({ prosBulletColor: v || '#16a34a' }); } },
220 { label: __('Item Text Color', 'blockenberg'), value: a.prosItemColor, onChange: function (v) { setAttr({ prosItemColor: v || '#166534' }); } },
221 ]
222 }),
223
224 el(PanelColorSettings, {
225 title: __('Cons Colors', 'blockenberg'), initialOpen: false,
226 colorSettings: [
227 { label: __('Header Background', 'blockenberg'), value: a.consHeadBg, onChange: function (v) { setAttr({ consHeadBg: v || '#fee2e2' }); } },
228 { label: __('Header Text Color', 'blockenberg'), value: a.consHeadColor, onChange: function (v) { setAttr({ consHeadColor: v || '#b91c1c' }); } },
229 { label: __('Column Background', 'blockenberg'), value: a.consBg, onChange: function (v) { setAttr({ consBg: v || '#fef2f2' }); } },
230 { label: __('Border Color', 'blockenberg'), value: a.consBorder, onChange: function (v) { setAttr({ consBorder: v || '#fecaca' }); } },
231 { label: __('Bullet Color', 'blockenberg'), value: a.consBulletColor, onChange: function (v) { setAttr({ consBulletColor: v || '#dc2626' }); } },
232 { label: __('Item Text Color', 'blockenberg'), value: a.consItemColor, onChange: function (v) { setAttr({ consItemColor: v || '#991b1b' }); } },
233 ]
234 }),
235
236 el(PanelColorSettings, {
237 title: __('General Colors', 'blockenberg'), initialOpen: false,
238 colorSettings: [
239 { label: __('Heading Color', 'blockenberg'), value: a.headingColor, onChange: function (v) { setAttr({ headingColor: v || '#1e1b4b' }); } },
240 { label: __('Block Background', 'blockenberg'), value: a.cardBg, onChange: function (v) { setAttr({ cardBg: v || '' }); } },
241 ]
242 }),
243
244 el(PanelBody, { title: __('Sizing', 'blockenberg'), initialOpen: false },
245 el(RangeControl, { label: __('Item Gap (px)', 'blockenberg'), value: a.itemGap, min: 4, max: 32, onChange: function (v) { setAttr({ itemGap: v }); } }),
246 el(RangeControl, { label: __('Column Radius (px)', 'blockenberg'), value: a.colRadius, min: 0, max: 32, onChange: function (v) { setAttr({ colRadius: v }); } }),
247 el(RangeControl, { label: __('Padding Vertical (px)', 'blockenberg'), value: a.paddingV, min: 0, max: 80, onChange: function (v) { setAttr({ paddingV: v }); } }),
248 el(RangeControl, { label: __('Padding Horizontal (px)', 'blockenberg'),value: a.paddingH, min: 0, max: 80, onChange: function (v) { setAttr({ paddingH: v }); } }),
249 el(RangeControl, { label: __('Max Width (px)', 'blockenberg'), value: a.maxWidth, min: 320,max: 1400,onChange: function (v) { setAttr({ maxWidth: v }); } })
250 )
251 ),
252
253 el('div', blockProps,
254 el(ProsConsPreview, { attrs: a, setAttrs: setAttr })
255 )
256 );
257 },
258
259 save: function (props) {
260 var a = props.attributes;
261 var blockProps = wp.blockEditor.useBlockProps.save();
262 return el('div', blockProps,
263 el('div', { className: 'bkbg-pc-app', 'data-opts': JSON.stringify(a) },
264 el('p', { className: 'bkbg-pc-loading' }, '')
265 )
266 );
267 }
268 });
269 }() );
270