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

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

250 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* ====================================================
2 Info Cards Block — editor (index.js)
3 Block: blockenberg/info-cards
4 ==================================================== */
5 ( function () {
6 var el = wp.element.createElement;
7 var Fragment = wp.element.Fragment;
8 var useState = wp.element.useState;
9 var registerBlockType = wp.blocks.registerBlockType;
10 var InspectorControls = wp.blockEditor.InspectorControls;
11 var useBlockProps = wp.blockEditor.useBlockProps;
12 var PanelBody = wp.components.PanelBody;
13 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
14 var RangeControl = wp.components.RangeControl;
15 var SelectControl = wp.components.SelectControl;
16 var ToggleControl = wp.components.ToggleControl;
17 var TextControl = wp.components.TextControl;
18 var Button = wp.components.Button;
19 var ColorPicker = wp.components.ColorPicker;
20 var Popover = wp.components.Popover;
21 var __ = wp.i18n.__;
22
23 var _TypographyControl, _typoCssVars;
24 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
25 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
26
27 var IP = function () { return window.bkbgIconPicker; };
28
29 function uid() { return 'i' + Math.random().toString(36).slice(2,7); }
30 function move(arr, from, to) { var a=arr.slice(); a.splice(to,0,a.splice(from,1)[0]); return a; }
31
32 function wrapStyle(a) {
33 var _tv = getTypoCssVars();
34 var s = {
35 '--bkbg-infc-cols': a.columns,
36 '--bkbg-infc-gap': a.gap + 'px',
37 '--bkbg-infc-r': a.cardRadius + 'px',
38 '--bkbg-infc-pad': a.cardPadding + 'px',
39 '--bkbg-infc-icon-sz': a.iconSize + 'px',
40 '--bkbg-infc-icon-bg-sz': a.iconBgSize + 'px',
41 '--bkbg-infc-title-sz':a.titleSize + 'px',
42 '--bkbg-infc-desc-sz': a.descSize + 'px',
43 '--bkbg-infc-pt': a.paddingTop + 'px',
44 '--bkbg-infc-pb': a.paddingBottom + 'px',
45 '--bkbg-infc-card-bg': a.cardBg,
46 '--bkbg-infc-brd': a.cardBorderColor,
47 '--bkbg-infc-title-c': a.titleColor,
48 '--bkbg-infc-desc-c': a.descColor,
49 background: a.sectionBg || undefined,
50 };
51 Object.assign(s, _tv(a.titleTypo, '--bkbg-infc-tt-'));
52 Object.assign(s, _tv(a.descTypo, '--bkbg-infc-ds-'));
53 return s;
54 }
55
56 function renderIconContent(item, size) {
57 if ((item.iconType || 'custom-char') !== 'custom-char') return IP().buildEditorIcon(item.iconType, item.icon, item.iconDashicon, item.iconImageUrl, item.iconDashiconColor);
58 return item.icon;
59 }
60
61 function renderCard(item, a) {
62 var iconEl;
63 if (a.iconStyle === 'circle-bg') {
64 iconEl = el('div', { className:'bkbg-infc-icon-wrap', style:{ background: item.accentColor+'22', width: a.iconBgSize+'px', height: a.iconBgSize+'px' } },
65 el('span', { className:'bkbg-infc-icon', style:{ fontSize: a.iconSize+'px', color: item.accentColor } }, renderIconContent(item, a.iconSize))
66 );
67 } else if (a.iconStyle === 'square-bg') {
68 iconEl = el('div', { className:'bkbg-infc-icon-wrap bkbg-infc-icon-wrap--square', style:{ background: item.accentColor+'22', width: a.iconBgSize+'px', height: a.iconBgSize+'px' } },
69 el('span', { className:'bkbg-infc-icon', style:{ fontSize: a.iconSize+'px', color: item.accentColor } }, renderIconContent(item, a.iconSize))
70 );
71 } else {
72 iconEl = el('span', { className:'bkbg-infc-icon bkbg-infc-icon--plain', style:{ fontSize: a.iconSize+'px' } }, renderIconContent(item, a.iconSize));
73 }
74
75 var accentBar = a.cardStyle === 'accent-left'
76 ? el('div', { className:'bkbg-infc-accent-bar', style:{ background: item.accentColor } })
77 : null;
78
79 return el('div', { className:'bkbg-infc-card bkbg-infc-card--' + a.cardStyle, style:{ textAlign: a.textAlign }, 'data-id': item.id },
80 accentBar,
81 iconEl,
82 el('h3', { className:'bkbg-infc-title' }, item.title),
83 el('p', { className:'bkbg-infc-desc' }, item.description),
84 a.showCta && item.ctaLabel ? el('a', { href:item.ctaUrl||'#', className:'bkbg-infc-cta', style:{ color:item.accentColor }, onClick:function(e){ e.preventDefault(); } }, item.ctaLabel, '') : null
85 );
86 }
87
88 var BkbgColorSwatch = function (props) {
89 var _st = useState(false); var isOpen = _st[0]; var setOpen = _st[1];
90 return el(Fragment, {},
91 el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '8px' } },
92 el('span', { style: { fontSize: '11px', fontWeight: 500, textTransform: 'uppercase', color: '#1e1e1e' } }, props.label),
93 el('button', {
94 type: 'button',
95 onClick: function () { setOpen(!isOpen); },
96 style: { width: '28px', height: '28px', borderRadius: '4px', border: '1px solid #ccc', background: props.value || '#ffffff', cursor: 'pointer', padding: 0 }
97 })
98 ),
99 isOpen && el(Popover, { onClose: function () { setOpen(false); } },
100 el('div', { style: { padding: '8px' } },
101 el(ColorPicker, { color: props.value, onChangeComplete: function (c) { props.onChange(c.hex); }, enableAlpha: true })
102 )
103 )
104 );
105 };
106
107 registerBlockType('blockenberg/info-cards', {
108 edit: function (props) {
109 var a = props.attributes;
110 var setAttr = props.setAttributes;
111 var items = a.items;
112
113 var _act = useState(null);
114 var activeId = _act[0]; var setActiveId = _act[1];
115
116 function update(id, patch) {
117 setAttr({ items: items.map(function(it){ return it.id===id ? Object.assign({},it,patch) : it; }) });
118 }
119
120 var blockProps = useBlockProps({ className:'bkbg-infc-wrap', style:wrapStyle(a) });
121
122 function itemRow(item, idx) {
123 var isActive = activeId === item.id;
124 return el('div', { key:item.id },
125 el('div', {
126 style:{ display:'flex', alignItems:'center', gap:'6px', background:isActive?'#f3f0ff':'#f8f9fa', border:isActive?'1px solid #6c3fb5':'1px solid #e2e8f0', borderRadius:'6px', padding:'6px 8px', marginBottom:'4px', cursor:'pointer' },
127 onClick:function(){ setActiveId(isActive?null:item.id); }
128 },
129 el('span', { style:{fontSize:'18px',marginRight:'4px'} }, item.icon),
130 el('span', { style:{flex:1,fontSize:'13px',fontWeight:500,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'} }, item.title||'(untitled)'),
131 el(Button, { icon:'arrow-up', isSmall:true, disabled:idx===0, onClick:function(e){ e.stopPropagation(); setAttr({items:move(items,idx,idx-1)}); } }),
132 el(Button, { icon:'arrow-down', isSmall:true, disabled:idx===items.length-1, onClick:function(e){ e.stopPropagation(); setAttr({items:move(items,idx,idx+1)}); } }),
133 el(Button, { icon:'no-alt', isSmall:true, isDestructive:true, onClick:function(e){ e.stopPropagation(); setAttr({items:items.filter(function(_,i){ return i!==idx; })}); if(activeId===item.id) setActiveId(null); } })
134 ),
135 isActive ? el('div', { style:{padding:'10px',background:'#faf8ff',border:'1px solid #6c3fb5',borderTop:'none',borderRadius:'0 0 6px 6px',marginBottom:'4px'} },
136 el(IP().IconPickerControl, { iconType: item.iconType || 'custom-char', customChar: item.icon, dashicon: item.iconDashicon || '', imageUrl: item.iconImageUrl || '',
137 onChangeType: function(v){ update(item.id,{iconType:v}); }, onChangeChar: function(v){ update(item.id,{icon:v}); },
138 onChangeDashicon: function(v){ update(item.id,{iconDashicon:v}); }, onChangeImageUrl: function(v){ update(item.id,{iconImageUrl:v}); } }),
139 el(TextControl, { label:__('Title','blockenberg'), value:item.title, onChange:function(v){ update(item.id,{title:v}); } }),
140 el(TextControl, { label:__('Description','blockenberg'), value:item.description, onChange:function(v){ update(item.id,{description:v}); } }),
141 el(BkbgColorSwatch, { label:__('Accent color','blockenberg'), value:item.accentColor, onChange:function(v){ update(item.id,{accentColor:v}); } }),
142 a.showCta ? el(Fragment, null,
143 el(TextControl, { label:__('CTA label','blockenberg'), value:item.ctaLabel, onChange:function(v){ update(item.id,{ctaLabel:v}); } }),
144 el(TextControl, { label:__('CTA URL','blockenberg'), value:item.ctaUrl, onChange:function(v){ update(item.id,{ctaUrl:v}); } })
145 ) : null
146 ) : null
147 );
148 }
149
150 var inspector = el(InspectorControls, null,
151 el(PanelBody, { title:__('Cards','blockenberg'), initialOpen:true },
152 items.map(function(it,i){ return itemRow(it,i); }),
153 el(Button, { variant:'primary', style:{marginTop:'8px',width:'100%'},
154 onClick:function(){
155 var n={id:uid(),icon:'',iconType:'custom-char',iconDashicon:'',iconImageUrl:'',title:'New Feature',description:'Describe this feature succinctly.',ctaLabel:'',ctaUrl:'#',accentColor:'#6c3fb5'};
156 setAttr({items:items.concat([n])});
157 setActiveId(n.id);
158 }
159 }, __('+ Add Card','blockenberg'))
160 ),
161 el(PanelBody, { title:__('Style & Layout','blockenberg'), initialOpen:false },
162 el(SelectControl, { label:__('Card style','blockenberg'), value:a.cardStyle, options:[
163 {label:'Icon top (flat)',value:'icon-top'},
164 {label:'Icon top (card)',value:'icon-top-card'},
165 {label:'Icon left (inline)',value:'icon-left'},
166 {label:'Accent left border',value:'accent-left'},
167 {label:'Dark card',value:'dark'},
168 ], onChange:function(v){ setAttr({cardStyle:v}); } }),
169 el(SelectControl, { label:__('Icon style','blockenberg'), value:a.iconStyle, options:[
170 {label:'Circle bg',value:'circle-bg'},
171 {label:'Square bg',value:'square-bg'},
172 {label:'Plain emoji',value:'plain'},
173 ], onChange:function(v){ setAttr({iconStyle:v}); } }),
174 el(SelectControl, { label:__('Text align','blockenberg'), value:a.textAlign, options:[
175 {label:'Left',value:'left'},{label:'Center',value:'center'}
176 ], onChange:function(v){ setAttr({textAlign:v}); } }),
177 el(RangeControl, { label:__('Columns','blockenberg'), value:a.columns, min:1, max:6, onChange:function(v){ setAttr({columns:v}); } }),
178 el(RangeControl, { label:__('Gap (px)','blockenberg'), value:a.gap, min:8, max:72, onChange:function(v){ setAttr({gap:v}); } }),
179 el(RangeControl, { label:__('Card radius (px)','blockenberg'), value:a.cardRadius, min:0, max:32, onChange:function(v){ setAttr({cardRadius:v}); } }),
180 el(RangeControl, { label:__('Card padding (px)','blockenberg'), value:a.cardPadding, min:12, max:60, onChange:function(v){ setAttr({cardPadding:v}); } }),
181 el(RangeControl, { label:__('Icon size (px)','blockenberg'), value:a.iconSize, min:16, max:64, onChange:function(v){ setAttr({iconSize:v}); } }),
182 el(RangeControl, { label:__('Icon bg size (px)','blockenberg'), value:a.iconBgSize, min:32, max:100, onChange:function(v){ setAttr({iconBgSize:v}); } }),
183 el(ToggleControl, { label:__('Show CTA link','blockenberg'), checked:a.showCta, onChange:function(v){ setAttr({showCta:v}); } })
184 ),
185 el(PanelBody, { title:__('Typography','blockenberg'), initialOpen:false },
186 el(getTypographyControl(), { label: 'Title', value: a.titleTypo, onChange: function(v){ setAttr({ titleTypo: v }); } }),
187 el(getTypographyControl(), { label: 'Description', value: a.descTypo, onChange: function(v){ setAttr({ descTypo: v }); } })
188 ),
189 el(PanelBody, { title:__('Spacing','blockenberg'), initialOpen:false },
190 el(RangeControl, { label:__('Padding top (px)','blockenberg'), value:a.paddingTop, min:0, max:160, onChange:function(v){ setAttr({paddingTop:v}); } }),
191 el(RangeControl, { label:__('Padding bottom (px)','blockenberg'), value:a.paddingBottom, min:0, max:160, onChange:function(v){ setAttr({paddingBottom:v}); } })
192 ),
193 el(PanelColorSettings, { title:__('Colors','blockenberg'), initialOpen:false, colorSettings:[
194 {label:__('Section bg','blockenberg'), value:a.sectionBg, onChange:function(v){ setAttr({sectionBg:v||''}); }},
195 {label:__('Card bg','blockenberg'), value:a.cardBg, onChange:function(v){ setAttr({cardBg:v||''}); }},
196 {label:__('Card border','blockenberg'), value:a.cardBorderColor, onChange:function(v){ setAttr({cardBorderColor:v||''}); }},
197 {label:__('Title','blockenberg'), value:a.titleColor, onChange:function(v){ setAttr({titleColor:v||''}); }},
198 {label:__('Description','blockenberg'), value:a.descColor, onChange:function(v){ setAttr({descColor:v||''}); }},
199 ] })
200 );
201
202 return el(Fragment, null,
203 inspector,
204 el('div', blockProps,
205 el('div', { className:'bkbg-infc-grid' },
206 items.map(function(item){ return renderCard(item, a); })
207 )
208 )
209 );
210 },
211
212 save: function (props) {
213 var a = props.attributes;
214 var _tv = getTypoCssVars();
215 var saveStyle = {
216 '--bkbg-infc-cols':a.columns,'--bkbg-infc-gap':a.gap+'px','--bkbg-infc-r':a.cardRadius+'px','--bkbg-infc-pad':a.cardPadding+'px','--bkbg-infc-icon-sz':a.iconSize+'px','--bkbg-infc-icon-bg-sz':a.iconBgSize+'px','--bkbg-infc-title-sz':a.titleSize+'px','--bkbg-infc-desc-sz':a.descSize+'px','--bkbg-infc-pt':a.paddingTop+'px','--bkbg-infc-pb':a.paddingBottom+'px','--bkbg-infc-card-bg':a.cardBg,'--bkbg-infc-brd':a.cardBorderColor,'--bkbg-infc-title-c':a.titleColor,'--bkbg-infc-desc-c':a.descColor,background:a.sectionBg||undefined,
217 };
218 Object.assign(saveStyle, _tv(a.titleTypo, '--bkbg-infc-tt-'));
219 Object.assign(saveStyle, _tv(a.descTypo, '--bkbg-infc-ds-'));
220 var blockProps = wp.blockEditor.useBlockProps.save({ className:'bkbg-infc-wrap', style: saveStyle });
221
222 function saveIcon(item) {
223 function saveIconContent(item) {
224 if ((item.iconType || 'custom-char') !== 'custom-char') return IP().buildSaveIcon(item.iconType, item.icon, item.iconDashicon, item.iconImageUrl, item.iconDashiconColor);
225 return item.icon;
226 }
227 if (a.iconStyle === 'plain') return el('span', { className:'bkbg-infc-icon bkbg-infc-icon--plain', style:{ fontSize:a.iconSize+'px' } }, saveIconContent(item));
228 var cls = a.iconStyle==='square-bg' ? 'bkbg-infc-icon-wrap bkbg-infc-icon-wrap--square' : 'bkbg-infc-icon-wrap';
229 return el('div', { className:cls, style:{ background:item.accentColor+'22', width:a.iconBgSize+'px', height:a.iconBgSize+'px' } },
230 el('span', { className:'bkbg-infc-icon', style:{ fontSize:a.iconSize+'px', color:item.accentColor } }, saveIconContent(item))
231 );
232 }
233
234 return el('div', blockProps,
235 el('div', { className:'bkbg-infc-grid' },
236 a.items.map(function(item) {
237 return el('div', { key:item.id, className:'bkbg-infc-card bkbg-infc-card--'+a.cardStyle, style:{ textAlign:a.textAlign } },
238 a.cardStyle==='accent-left' ? el('div', { className:'bkbg-infc-accent-bar', style:{ background:item.accentColor } }) : null,
239 saveIcon(item),
240 el('h3', { className:'bkbg-infc-title' }, item.title),
241 el('p', { className:'bkbg-infc-desc' }, item.description),
242 a.showCta && item.ctaLabel ? el('a', { href:item.ctaUrl||'#', className:'bkbg-infc-cta', style:{ color:item.accentColor } }, item.ctaLabel, '') : null
243 );
244 })
245 )
246 );
247 }
248 });
249 }() );
250