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

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

269 lines 18.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* ====================================================
2 Client Showcase Block — editor (index.js)
3 Block: blockenberg/client-showcase
4 ==================================================== */
5 ( function () {
6 var el = wp.element.createElement;
7 var Fragment = wp.element.Fragment;
8 var useState = wp.element.useState;
9 var RichText = wp.blockEditor.RichText;
10 var MediaUpload = wp.blockEditor.MediaUpload;
11 var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
12 var registerBlockType = wp.blocks.registerBlockType;
13 var InspectorControls = wp.blockEditor.InspectorControls;
14 var useBlockProps = wp.blockEditor.useBlockProps;
15 var PanelBody = wp.components.PanelBody;
16 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
17 var RangeControl = wp.components.RangeControl;
18 var SelectControl = wp.components.SelectControl;
19 var ToggleControl = wp.components.ToggleControl;
20 var TextControl = wp.components.TextControl;
21 var Button = wp.components.Button;
22 var __ = wp.i18n.__;
23
24 function getTypographyControl() { return (window.bkbgTypographyControl || function () { return null; }); }
25 function _tv() { var fn = window.bkbgTypoCssVars; return fn ? fn.apply(null, arguments) : {}; }
26
27 function uid() { return 'l' + Math.random().toString(36).slice(2,7); }
28 function move(arr, from, to) { var a=arr.slice(); a.splice(to,0,a.splice(from,1)[0]); return a; }
29
30 function buildWrapStyle(a) {
31 var s = {
32 '--bkbg-cshw-cols': a.columns,
33 '--bkbg-cshw-gap': a.gap + 'px',
34 '--bkbg-cshw-h-gap': a.headerGap + 'px',
35 '--bkbg-cshw-q-gap': a.quoteGap + 'px',
36 '--bkbg-cshw-logo-h': a.logoHeight + 'px',
37 '--bkbg-cshw-logo-r': a.logoRadius + 'px',
38 '--bkbg-cshw-logo-pad': a.logoPadding + 'px',
39 '--bkbg-cshw-pt': a.paddingTop + 'px',
40 '--bkbg-cshw-pb': a.paddingBottom + 'px',
41 '--bkbg-cshw-h-color': a.headlineColor,
42 '--bkbg-cshw-sub-color': a.subColor,
43 '--bkbg-cshw-logo-bg': a.logoBgColor,
44 '--bkbg-cshw-logo-brd': a.logoBorderColor,
45 '--bkbg-cshw-logo-tint': a.logoTintColor,
46 '--bkbg-cshw-q-bg': a.quoteBg,
47 '--bkbg-cshw-q-brd': a.quoteBorder,
48 '--bkbg-cshw-q-text': a.quoteTextColor,
49 '--bkbg-cshw-q-meta': a.quoteMetaColor,
50 '--bkbg-cshw-accent': a.accentColor,
51 background: a.sectionBg || undefined,
52 };
53 Object.assign(s, _tv(a.typoHeadline, '--bkbg-cshw-hl'));
54 Object.assign(s, _tv(a.typoSubhead, '--bkbg-cshw-sh'));
55 Object.assign(s, _tv(a.typoQuote, '--bkbg-cshw-qt'));
56 return s;
57 }
58
59 /* ── Logo item (editor) ── */
60 function LogoItem(props) {
61 var logo = props.logo;
62 var a = props.a;
63 var onChange = props.onChange;
64
65 var imgEl = logo.imageUrl
66 ? el('img', { src: logo.imageUrl, alt: logo.name, className: 'bkbg-cshw-logo-img' })
67 : el('span', { className: 'bkbg-cshw-logo-placeholder' }, logo.name || 'Logo');
68
69 var uploadBtn = el(MediaUploadCheck, null,
70 el(MediaUpload, {
71 onSelect: function(m){ onChange({ imageUrl: m.url, imageId: m.id }); },
72 allowedTypes: ['image'],
73 value: logo.imageId,
74 render: function(o){ return el(Button, { onClick: o.open, className: 'bkbg-cshw-logo-upload-btn', isSmall: true }, logo.imageUrl ? __('Replace','blockenberg') : __('Upload','blockenberg')); }
75 })
76 );
77
78 return el('div', { className: 'bkbg-cshw-logo-item' + (a.logoBg ? ' bkbg-cshw-logo-bg' : '') + (a.logoGrayscale ? ' bkbg-cshw-grayscale' : ''), title: logo.name },
79 imgEl,
80 uploadBtn
81 );
82 }
83
84 /* ── REGISTER ── */
85 registerBlockType('blockenberg/client-showcase', {
86 edit: function (props) {
87 var a = props.attributes;
88 var setAttr = props.setAttributes;
89 var logos = a.logos;
90
91 var _act = useState(null);
92 var activeId = _act[0]; var setActiveId = _act[1];
93
94 function updateLogo(id, patch) {
95 setAttr({ logos: logos.map(function(l){ return l.id===id ? Object.assign({},l,patch) : l; }) });
96 }
97
98 var blockProps = useBlockProps({
99 className: 'bkbg-cshw-wrap bkbg-cshw-layout--' + a.layout,
100 style: buildWrapStyle(a)
101 });
102
103 var inspector = el(InspectorControls, null,
104 /* Logos */
105 el(PanelBody, { title:__('Logos','blockenberg'), initialOpen:true },
106 logos.map(function(logo, idx) {
107 var isActive = activeId === logo.id;
108 return el('div', { key: logo.id },
109 el('div', {
110 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' },
111 onClick: function(){ setActiveId(isActive ? null : logo.id); }
112 },
113 logo.imageUrl ? el('img', { src:logo.imageUrl, style:{ height:'20px', objectFit:'contain', marginRight:'4px' } }) : null,
114 el('span', { style:{ flex:1, fontSize:'13px' } }, logo.name || '(untitled)'),
115 el(Button, { icon:'arrow-up', isSmall:true, disabled:idx===0, onClick:function(e){ e.stopPropagation(); setAttr({logos:move(logos,idx,idx-1)}); } }),
116 el(Button, { icon:'arrow-down', isSmall:true, disabled:idx===logos.length-1, onClick:function(e){ e.stopPropagation(); setAttr({logos:move(logos,idx,idx+1)}); } }),
117 el(Button, { icon:'no-alt', isSmall:true, isDestructive:true, onClick:function(e){ e.stopPropagation(); setAttr({logos:logos.filter(function(_,i){ return i!==idx; })}); if(activeId===logo.id) setActiveId(null); } })
118 ),
119 isActive ? el('div', { style:{ padding:'8px', background:'#faf8ff', border:'1px solid #6c3fb5', borderTop:'none', borderRadius:'0 0 6px 6px', marginBottom:'4px' }},
120 el(TextControl, { label:__('Company name','blockenberg'), value:logo.name, onChange:function(v){ updateLogo(logo.id,{name:v}); } }),
121 el(MediaUploadCheck, null,
122 el(MediaUpload, {
123 onSelect: function(m){ updateLogo(logo.id,{imageUrl:m.url,imageId:m.id}); },
124 allowedTypes:['image'], value:logo.imageId,
125 render:function(o){ return el(Button, { onClick:o.open, variant:'secondary', isSmall:true }, logo.imageUrl ? __('Change logo','blockenberg') : __('Upload logo','blockenberg')); }
126 })
127 ),
128 logo.imageUrl ? el(Button, { isDestructive:true, variant:'tertiary', isSmall:true, style:{marginTop:'4px'}, onClick:function(){ updateLogo(logo.id,{imageUrl:'',imageId:0}); } }, __('Remove image','blockenberg')) : null
129 ) : null
130 );
131 }),
132 el(Button, { variant:'primary', style:{ marginTop:'8px', width:'100%' },
133 onClick:function(){ var n={id:uid(),name:'New Client',imageUrl:'',imageId:0}; setAttr({logos:logos.concat([n])}); setActiveId(n.id); }
134 }, __('+ Add Logo','blockenberg'))
135 ),
136
137 /* Header / layout */
138 el(PanelBody, { title:__('Header & Layout','blockenberg'), initialOpen:false },
139 el(ToggleControl, { label:__('Show section header','blockenberg'), checked:a.showHeader, onChange:function(v){ setAttr({showHeader:v}); } }),
140 el(ToggleControl, { label:__('Show pull-quote','blockenberg'), checked:a.showQuote, onChange:function(v){ setAttr({showQuote:v}); } }),
141 el(SelectControl, { label:__('Layout','blockenberg'), value:a.layout, options:[
142 {label:__('Row (centered)','blockenberg'), value:'row'},
143 {label:__('Grid (fixed columns)','blockenberg'), value:'grid'},
144 ], onChange:function(v){ setAttr({layout:v}); } }),
145 el(SelectControl, { label:__('Header alignment','blockenberg'), value:a.headerAlign, options:[
146 {label:'Left',value:'left'},{label:'Center',value:'center'},{label:'Right',value:'right'}
147 ], onChange:function(v){ setAttr({headerAlign:v}); } }),
148 el(RangeControl, { label:__('Columns','blockenberg'), value:a.columns, min:2, max:8, onChange:function(v){ setAttr({columns:v}); } }),
149 el(RangeControl, { label:__('Logo gap (px)','blockenberg'), value:a.gap, min:8, max:80, onChange:function(v){ setAttr({gap:v}); } }),
150 el(RangeControl, { label:__('Logo height (px)','blockenberg'), value:a.logoHeight, min:20, max:100, onChange:function(v){ setAttr({logoHeight:v}); } }),
151 el(RangeControl, { label:__('Logo padding (px)','blockenberg'), value:a.logoPadding, min:0, max:40, onChange:function(v){ setAttr({logoPadding:v}); } }),
152 el(RangeControl, { label:__('Logo border radius (px)','blockenberg'), value:a.logoRadius, min:0, max:20, onChange:function(v){ setAttr({logoRadius:v}); } }),
153 el(ToggleControl, { label:__('Logo background box','blockenberg'), checked:a.logoBg, onChange:function(v){ setAttr({logoBg:v}); } }),
154 el(ToggleControl, { label:__('Grayscale logos','blockenberg'), checked:a.logoGrayscale, onChange:function(v){ setAttr({logoGrayscale:v}); } }),
155 el(ToggleControl, { label:__('Color on hover','blockenberg'), checked:a.logoHoverColor, onChange:function(v){ setAttr({logoHoverColor:v}); } })
156 ),
157
158 /* Quote */
159 a.showQuote ? el(PanelBody, { title:__('Pull Quote','blockenberg'), initialOpen:false },
160 el(TextControl, { label:__('Quote text','blockenberg'), value:a.quoteText, onChange:function(v){ setAttr({quoteText:v}); } }),
161 el(TextControl, { label:__('Author name','blockenberg'), value:a.quoteAuthor, onChange:function(v){ setAttr({quoteAuthor:v}); } }),
162 el(TextControl, { label:__('Author role','blockenberg'), value:a.quoteRole, onChange:function(v){ setAttr({quoteRole:v}); } }),
163 el(MediaUploadCheck, null,
164 el(MediaUpload, {
165 onSelect:function(m){ setAttr({quoteAvatarUrl:m.url,quoteAvatarId:m.id}); },
166 allowedTypes:['image'], value:a.quoteAvatarId,
167 render:function(o){ return el(Button, { onClick:o.open, variant:'secondary', isSmall:true }, a.quoteAvatarUrl ? __('Change avatar','blockenberg') : __('Upload avatar','blockenberg')); }
168 })
169 )
170 ) : null,
171
172 /* Spacing */
173 el(PanelBody, { title:__('Spacing','blockenberg'), initialOpen:false },
174 el(RangeControl, { label:__('Padding top (px)','blockenberg'), value:a.paddingTop, min:0, max:160, onChange:function(v){ setAttr({paddingTop:v}); } }),
175 el(RangeControl, { label:__('Padding bottom (px)','blockenberg'), value:a.paddingBottom, min:0, max:160, onChange:function(v){ setAttr({paddingBottom:v}); } }),
176 el(RangeControl, { label:__('Header gap (px)','blockenberg'), value:a.headerGap, min:0, max:80, onChange:function(v){ setAttr({headerGap:v}); } }),
177 el(RangeControl, { label:__('Quote gap (px)','blockenberg'), value:a.quoteGap, min:0, max:80, onChange:function(v){ setAttr({quoteGap:v}); } })
178 ),
179
180 /* Typography */
181 el(PanelBody, { title:__('Typography','blockenberg'), initialOpen:false },
182 el(getTypographyControl(), { label:__('Headline','blockenberg'), value:a.typoHeadline, onChange:function(v){ setAttr({typoHeadline:v}); } }),
183 el(getTypographyControl(), { label:__('Subheadline','blockenberg'), value:a.typoSubhead, onChange:function(v){ setAttr({typoSubhead:v}); } }),
184 el(getTypographyControl(), { label:__('Quote Text','blockenberg'), value:a.typoQuote, onChange:function(v){ setAttr({typoQuote:v}); } })
185 ),
186
187 /* Colors */
188 el(PanelColorSettings, { title:__('Colors','blockenberg'), initialOpen:false, colorSettings:[
189 {label:__('Section background','blockenberg'), value:a.sectionBg, onChange:function(v){ setAttr({sectionBg:v||''}); }},
190 {label:__('Headline color','blockenberg'), value:a.headlineColor, onChange:function(v){ setAttr({headlineColor:v||''}); }},
191 {label:__('Subhead color','blockenberg'), value:a.subColor, onChange:function(v){ setAttr({subColor:v||''}); }},
192 {label:__('Logo box bg','blockenberg'), value:a.logoBgColor, onChange:function(v){ setAttr({logoBgColor:v||''}); }},
193 {label:__('Logo box border','blockenberg'), value:a.logoBorderColor,onChange:function(v){ setAttr({logoBorderColor:v||''}); }},
194 {label:__('Logo tint (grayscale)','blockenberg'), value:a.logoTintColor, onChange:function(v){ setAttr({logoTintColor:v||''}); }},
195 {label:__('Quote background','blockenberg'), value:a.quoteBg, onChange:function(v){ setAttr({quoteBg:v||''}); }},
196 {label:__('Quote border','blockenberg'), value:a.quoteBorder, onChange:function(v){ setAttr({quoteBorder:v||''}); }},
197 {label:__('Quote text','blockenberg'), value:a.quoteTextColor, onChange:function(v){ setAttr({quoteTextColor:v||''}); }},
198 {label:__('Quote meta','blockenberg'), value:a.quoteMetaColor, onChange:function(v){ setAttr({quoteMetaColor:v||''}); }},
199 {label:__('Accent (quote mark)','blockenberg'),value:a.accentColor, onChange:function(v){ setAttr({accentColor:v||''}); }},
200 ] })
201 );
202
203 /* Header */
204 var headerEl = a.showHeader ? el('div', { className:'bkbg-cshw-header', style:{ textAlign:a.headerAlign, marginBottom: a.headerGap + 'px' } },
205 el(RichText, { tagName:'p', className:'bkbg-cshw-headline', value:a.headline, onChange:function(v){ setAttr({headline:v}); }, placeholder:__('Trusted by…','blockenberg') }),
206 el(RichText, { tagName:'p', className:'bkbg-cshw-subhead', value:a.subheadline, onChange:function(v){ setAttr({subheadline:v}); }, placeholder:__('Subtitle…','blockenberg') })
207 ) : null;
208
209 /* Logo grid */
210 var logoGrid = el('div', { className:'bkbg-cshw-logos' + (a.logoHoverColor && a.logoGrayscale ? ' bkbg-cshw-hover-color' : '') },
211 logos.map(function(logo) {
212 return el(LogoItem, { key:logo.id, logo:logo, a:a, onChange:function(patch){ updateLogo(logo.id,patch); } });
213 })
214 );
215
216 /* Quote */
217 var quoteEl = a.showQuote ? el('figure', { className:'bkbg-cshw-quote', style:{ marginTop: a.quoteGap + 'px' } },
218 el('blockquote', { className:'bkbg-cshw-quote-text' }, el('p', null, a.quoteText)),
219 el('figcaption', { className:'bkbg-cshw-quote-author' },
220 a.quoteAvatarUrl ? el('img', { src:a.quoteAvatarUrl, alt:a.quoteAuthor, className:'bkbg-cshw-quote-avatar' }) : null,
221 el('span', { className:'bkbg-cshw-quote-meta' },
222 el('strong', { className:'bkbg-cshw-quote-name' }, a.quoteAuthor),
223 el('span', { className:'bkbg-cshw-quote-role' }, a.quoteRole)
224 )
225 )
226 ) : null;
227
228 return el(Fragment, null,
229 inspector,
230 el('div', blockProps, headerEl, logoGrid, quoteEl)
231 );
232 },
233
234 save: function (props) {
235 var a = props.attributes;
236 var blockProps = wp.blockEditor.useBlockProps.save({
237 className: 'bkbg-cshw-wrap bkbg-cshw-layout--' + a.layout,
238 style: buildWrapStyle(a)
239 });
240
241 var headerEl = a.showHeader ? el('div', { className:'bkbg-cshw-header', style:{ textAlign:a.headerAlign, marginBottom:a.headerGap+'px' } },
242 el(RichText.Content, { tagName:'p', className:'bkbg-cshw-headline', value:a.headline }),
243 el(RichText.Content, { tagName:'p', className:'bkbg-cshw-subhead', value:a.subheadline })
244 ) : null;
245
246 var logoGrid = el('div', { className:'bkbg-cshw-logos' + (a.logoHoverColor && a.logoGrayscale ? ' bkbg-cshw-hover-color' : '') },
247 a.logos.map(function(logo) {
248 return el('div', { key:logo.id, className:'bkbg-cshw-logo-item' + (a.logoBg ? ' bkbg-cshw-logo-bg' : '') + (a.logoGrayscale ? ' bkbg-cshw-grayscale' : ''), title:logo.name },
249 logo.imageUrl ? el('img', { src:logo.imageUrl, alt:logo.name, className:'bkbg-cshw-logo-img', loading:'lazy' }) : el('span', { className:'bkbg-cshw-logo-placeholder' }, logo.name)
250 );
251 })
252 );
253
254 var quoteEl = a.showQuote ? el('figure', { className:'bkbg-cshw-quote', style:{ marginTop:a.quoteGap+'px' } },
255 el('blockquote', { className:'bkbg-cshw-quote-text' }, el('p', null, a.quoteText)),
256 el('figcaption', { className:'bkbg-cshw-quote-author' },
257 a.quoteAvatarUrl ? el('img', { src:a.quoteAvatarUrl, alt:a.quoteAuthor, className:'bkbg-cshw-quote-avatar', loading:'lazy' }) : null,
258 el('span', { className:'bkbg-cshw-quote-meta' },
259 el('strong', { className:'bkbg-cshw-quote-name' }, a.quoteAuthor),
260 el('span', { className:'bkbg-cshw-quote-role' }, a.quoteRole)
261 )
262 )
263 ) : null;
264
265 return el('div', blockProps, headerEl, logoGrid, quoteEl);
266 }
267 });
268 }() );
269