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 / split-price-cta / index.js

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

232 lines 17.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* ====================================================
2 Split Price CTA — editor (index.js)
3 Block: blockenberg/split-price-cta
4 ==================================================== */
5 ( function () {
6 var el = wp.element.createElement;
7 var useState = wp.element.useState;
8 var Fragment = wp.element.Fragment;
9 var RichText = wp.blockEditor.RichText;
10 var registerBlockType = wp.blocks.registerBlockType;
11 var InspectorControls = wp.blockEditor.InspectorControls;
12 var useBlockProps = wp.blockEditor.useBlockProps;
13 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
14 var PanelBody = wp.components.PanelBody;
15 var RangeControl = wp.components.RangeControl;
16 var SelectControl = wp.components.SelectControl;
17 var ToggleControl = wp.components.ToggleControl;
18 var TextControl = wp.components.TextControl;
19 var Button = wp.components.Button;
20 var GradientPicker = wp.components.__experimentalGradientPicker;
21 var __ = wp.i18n.__;
22
23 function uid() { return Math.random().toString(36).slice(2,9); }
24
25 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
26 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
27
28 function getLeftBg(a) {
29 return a.leftStyle === 'gradient' ? a.leftGradient : a.leftBg;
30 }
31
32 function wrapStyle(a) {
33 var s = {
34 '--bkbg-spc-pt': a.paddingTop + 'px',
35 '--bkbg-spc-pb': a.paddingBottom + 'px',
36 '--bkbg-spc-r': a.blockRadius + 'px',
37 '--bkbg-spc-btn-r': a.btnRadius + 'px',
38 '--bkbg-spc-chk-c': a.checkColor,
39 '--bkbg-spc-price-lbl-c': a.priceLabelColor,
40 '--bkbg-spc-price-val-c': a.priceValueColor,
41 '--bkbg-spc-price-note-c':a.priceNoteColor,
42 '--bkbg-spc-feat-c': a.featureColor,
43 '--bkbg-spc-right-bg': a.rightBg,
44 '--bkbg-spc-ttl-c': a.ctaHeadingColor,
45 '--bkbg-spc-sub-c': a.ctaSubtitleColor,
46 '--bkbg-spc-primary-bg': a.primaryBg,
47 '--bkbg-spc-primary-c': a.primaryColor,
48 '--bkbg-spc-proof-c': a.proofColor,
49 '--bkbg-spc-bd': a.borderColor,
50 '--bkbg-spc-price-sz': a.priceSize + 'px',
51 '--bkbg-spc-pv-w': a.priceFontWeight,
52 '--bkbg-spc-ttl-sz': a.ctaHeadingSize + 'px',
53 '--bkbg-spc-hd-w': a.ctaHeadingFontWeight,
54 };
55 var fn = getTypoCssVars();
56 if (fn) {
57 Object.assign(s, fn(a.priceTypo, '--bkspc-pv'));
58 Object.assign(s, fn(a.headingTypo, '--bkspc-hd'));
59 Object.assign(s, fn(a.subtitleTypo, '--bkspc-st'));
60 Object.assign(s, fn(a.badgeTypo, '--bkspc-bd'));
61 Object.assign(s, fn(a.featureTypo, '--bkspc-ft'));
62 Object.assign(s, fn(a.btnTypo, '--bkspc-bt'));
63 }
64 return s;
65 }
66
67 registerBlockType('blockenberg/split-price-cta', {
68 edit: function (props) {
69 var a = props.attributes;
70 var setAttr = props.setAttributes;
71
72 function updateFeature(idx, text) {
73 var arr = a.features.map(function(f,i){ return i===idx ? Object.assign({},f,{text:text}) : f; });
74 setAttr({ features: arr });
75 }
76 function deleteFeature(idx) { setAttr({ features: a.features.filter(function(_,i){ return i!==idx; }) }); }
77 function addFeature() { setAttr({ features: a.features.concat([{id:uid(), text:'New feature'}]) }); }
78 function moveFeature(from, to) {
79 var arr = a.features.slice(); arr.splice(to, 0, arr.splice(from, 1)[0]); setAttr({ features: arr });
80 }
81
82 var blockProps = useBlockProps({ className:'bkbg-spc-outer', style:wrapStyle(a) });
83
84 var inspector = el(InspectorControls, null,
85 el(PanelBody, { title:__('Price (left panel)','blockenberg'), initialOpen:true },
86 el(TextControl, { label:__('Price label','blockenberg'), value:a.priceLabel, onChange:function(v){ setAttr({priceLabel:v}); } }),
87 el(TextControl, { label:__('Price value','blockenberg'), value:a.priceValue, onChange:function(v){ setAttr({priceValue:v}); } }),
88 el(TextControl, { label:__('Price period','blockenberg'), value:a.pricePeriod, onChange:function(v){ setAttr({pricePeriod:v}); } }),
89 el(TextControl, { label:__('Price note','blockenberg'), value:a.priceNote, onChange:function(v){ setAttr({priceNote:v}); } }),
90 el(ToggleControl, { label:__('Show old/crossed price','blockenberg'), checked:a.showOldPrice, onChange:function(v){ setAttr({showOldPrice:v}); } }),
91 a.showOldPrice ? el(TextControl, { label:__('Old price','blockenberg'), value:a.oldPrice, onChange:function(v){ setAttr({oldPrice:v}); } }) : null,
92 el(ToggleControl, { label:__('Show offer badge','blockenberg'), checked:a.showBadge, onChange:function(v){ setAttr({showBadge:v}); } }),
93 a.showBadge ? el(TextControl, { label:__('Badge text','blockenberg'), value:a.badge, onChange:function(v){ setAttr({badge:v}); } }) : null,
94 el('p', { style:{ fontWeight:600, fontSize:11, margin:'10px 0 4px' } }, __('Included features','blockenberg')),
95 a.features.map(function(f, i) {
96 return el('div', { key:f.id, style:{ display:'flex', gap:4, marginBottom:4, alignItems:'center' } },
97 el(TextControl, { value:f.text, onChange:function(v){ updateFeature(i,v); }, placeholder:'Feature…' }),
98 el(Button, { isSmall:true, variant:'tertiary', disabled:i===0, onClick:function(){ moveFeature(i,i-1); } }, ''),
99 el(Button, { isSmall:true, isDestructive:true, onClick:function(){ deleteFeature(i); } }, '')
100 );
101 }),
102 el(Button, { isSmall:true, variant:'tertiary', onClick:addFeature, style:{marginTop:4} }, __('+ Feature','blockenberg'))
103 ),
104 el(PanelBody, { title:__('CTA (right panel)','blockenberg'), initialOpen:false },
105 el(TextControl, { label:__('Heading','blockenberg'), value:a.ctaHeading, onChange:function(v){ setAttr({ctaHeading:v}); } }),
106 el(TextControl, { label:__('Subtitle','blockenberg'), value:a.ctaSubtitle, onChange:function(v){ setAttr({ctaSubtitle:v}); } }),
107 el(TextControl, { label:__('Primary button','blockenberg'), value:a.primaryLabel, onChange:function(v){ setAttr({primaryLabel:v}); } }),
108 el(TextControl, { label:__('Primary URL','blockenberg'), value:a.primaryUrl, onChange:function(v){ setAttr({primaryUrl:v}); } }),
109 el(ToggleControl, { label:__('Show secondary link','blockenberg'), checked:a.showSecondary, onChange:function(v){ setAttr({showSecondary:v}); } }),
110 a.showSecondary ? el(TextControl, { label:__('Secondary label','blockenberg'), value:a.secondaryLabel, onChange:function(v){ setAttr({secondaryLabel:v}); } }) : null,
111 a.showSecondary ? el(TextControl, { label:__('Secondary URL','blockenberg'), value:a.secondaryUrl, onChange:function(v){ setAttr({secondaryUrl:v}); } }) : null,
112 el(ToggleControl, { label:__('Show social proof quote','blockenberg'), checked:a.showSocialProof, onChange:function(v){ setAttr({showSocialProof:v}); } }),
113 a.showSocialProof ? el(TextControl, { label:__('Quote text','blockenberg'), value:a.socialProofText, onChange:function(v){ setAttr({socialProofText:v}); } }) : null,
114 a.showSocialProof ? el(TextControl, { label:__('Quote author','blockenberg'), value:a.socialProofAuthor, onChange:function(v){ setAttr({socialProofAuthor:v}); } }) : null
115 ),
116 el(PanelBody, { title:__('Style','blockenberg'), initialOpen:false },
117 el(SelectControl, { label:__('Left panel style','blockenberg'), value:a.leftStyle, options:[{label:'Gradient',value:'gradient'},{label:'Solid color',value:'solid'}], onChange:function(v){ setAttr({leftStyle:v}); } }),
118 a.leftStyle === 'gradient' ? el('div', { style:{ marginBottom:'12px' } },
119 el('p', { style:{ fontSize:'11px', fontWeight:600, margin:'0 0 6px', textTransform:'uppercase', color:'#757575' } }, __('Gradient','blockenberg')),
120 el(GradientPicker, { value: a.leftGradient, onChange:function(v){ setAttr({leftGradient:v}); } })
121 ) : null,
122 el(RangeControl, { label:__('Block radius (px)','blockenberg'), value:a.blockRadius, min:0, max:32, onChange:function(v){ setAttr({blockRadius:v}); } }),
123 el(RangeControl, { label:__('Button radius (px)','blockenberg'), value:a.btnRadius, min:0, max:50, onChange:function(v){ setAttr({btnRadius:v}); } }),
124 ),
125 el(PanelBody, { title:__('Spacing','blockenberg'), initialOpen:false },
126 el(RangeControl, { label:__('Padding top (px)','blockenberg'), value:a.paddingTop, min:0, max:160, onChange:function(v){ setAttr({paddingTop:v}); } }),
127 el(RangeControl, { label:__('Padding bottom (px)','blockenberg'), value:a.paddingBottom, min:0, max:160, onChange:function(v){ setAttr({paddingBottom:v}); } })
128 ),
129
130 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
131 getTypoControl() ? el(getTypoControl(), { label:__('Price','blockenberg'), value:a.priceTypo, onChange:function(v){ setAttr({priceTypo:v}); } }) : null,
132 getTypoControl() ? el(getTypoControl(), { label:__('CTA heading','blockenberg'), value:a.headingTypo, onChange:function(v){ setAttr({headingTypo:v}); } }) : null,
133 getTypoControl() ? el(getTypoControl(), { label:__('CTA subtitle','blockenberg'), value:a.subtitleTypo, onChange:function(v){ setAttr({subtitleTypo:v}); } }) : null,
134 getTypoControl() ? el(getTypoControl(), { label:__('Badge','blockenberg'), value:a.badgeTypo, onChange:function(v){ setAttr({badgeTypo:v}); } }) : null,
135 getTypoControl() ? el(getTypoControl(), { label:__('Feature','blockenberg'), value:a.featureTypo, onChange:function(v){ setAttr({featureTypo:v}); } }) : null,
136 getTypoControl() ? el(getTypoControl(), { label:__('Primary button','blockenberg'), value:a.btnTypo, onChange:function(v){ setAttr({btnTypo:v}); } }) : null
137 ),
138 el(PanelColorSettings, { title:__('Colors','blockenberg'), initialOpen:false, colorSettings:[
139 {label:__('Check icon','blockenberg'), value:a.checkColor, onChange:function(v){ setAttr({checkColor:v||''}); }},
140 {label:__('Price label','blockenberg'), value:a.priceLabelColor, onChange:function(v){ setAttr({priceLabelColor:v||''}); }},
141 {label:__('Price value','blockenberg'), value:a.priceValueColor, onChange:function(v){ setAttr({priceValueColor:v||''}); }},
142 {label:__('Price note','blockenberg'), value:a.priceNoteColor, onChange:function(v){ setAttr({priceNoteColor:v||''}); }},
143 {label:__('Feature text','blockenberg'), value:a.featureColor, onChange:function(v){ setAttr({featureColor:v||''}); }},
144 {label:__('Right panel bg','blockenberg'), value:a.rightBg, onChange:function(v){ setAttr({rightBg:v||''}); }},
145 {label:__('CTA heading','blockenberg'), value:a.ctaHeadingColor, onChange:function(v){ setAttr({ctaHeadingColor:v||''}); }},
146 {label:__('CTA subtitle','blockenberg'), value:a.ctaSubtitleColor,onChange:function(v){ setAttr({ctaSubtitleColor:v||''}); }},
147 {label:__('Primary button bg','blockenberg'), value:a.primaryBg, onChange:function(v){ setAttr({primaryBg:v||''}); }},
148 {label:__('Primary button text','blockenberg'),value:a.primaryColor, onChange:function(v){ setAttr({primaryColor:v||''}); }},
149 {label:__('Quote text','blockenberg'), value:a.proofColor, onChange:function(v){ setAttr({proofColor:v||''}); }},
150 {label:__('Block border','blockenberg'), value:a.borderColor, onChange:function(v){ setAttr({borderColor:v||''}); }},
151 ] })
152 );
153
154 return el(Fragment, null,
155 inspector,
156 el('div', blockProps,
157 el('div', { className:'bkbg-spc-wrap' },
158 /* Left — price panel */
159 el('div', { className:'bkbg-spc-left', style:{ background: getLeftBg(a) } },
160 a.showBadge ? el('span', { className:'bkbg-spc-badge' }, a.badge) : null,
161 el('div', { className:'bkbg-spc-price-label' }, a.priceLabel),
162 el('div', { className:'bkbg-spc-price-row' },
163 a.showOldPrice ? el('span', { className:'bkbg-spc-old-price' }, a.oldPrice) : null,
164 el('span', { className:'bkbg-spc-price' }, a.priceValue),
165 el('span', { className:'bkbg-spc-period' }, ' / ' + a.pricePeriod)
166 ),
167 el('div', { className:'bkbg-spc-price-note' }, a.priceNote),
168 el('ul', { className:'bkbg-spc-features' },
169 a.features.map(function(f) {
170 return el('li', { key:f.id },
171 el('span', { className:'bkbg-spc-check' }, ''),
172 f.text
173 );
174 })
175 )
176 ),
177 /* Right — CTA panel */
178 el('div', { className:'bkbg-spc-right' },
179 el(RichText, { tagName:'h3', className:'bkbg-spc-heading', value:a.ctaHeading, onChange:function(v){ setAttr({ctaHeading:v}); }, placeholder:__('CTA heading…','blockenberg') }),
180 el(RichText, { tagName:'p', className:'bkbg-spc-subtitle', value:a.ctaSubtitle, onChange:function(v){ setAttr({ctaSubtitle:v}); }, placeholder:__('Subtitle…','blockenberg') }),
181 el('div', { className:'bkbg-spc-actions' },
182 el('a', { href:'#', className:'bkbg-spc-btn-primary', onClick:function(e){ e.preventDefault(); } }, a.primaryLabel),
183 a.showSecondary ? el('a', { href:'#', className:'bkbg-spc-btn-secondary', onClick:function(e){ e.preventDefault(); } }, a.secondaryLabel) : null
184 ),
185 a.showSocialProof ? el('div', { className:'bkbg-spc-proof' },
186 el('p', { className:'bkbg-spc-proof-text' }, a.socialProofText),
187 el('p', { className:'bkbg-spc-proof-author' }, a.socialProofAuthor)
188 ) : null
189 )
190 )
191 )
192 );
193 },
194
195 save: function (props) {
196 var a = props.attributes;
197 var blockProps = wp.blockEditor.useBlockProps.save({ className:'bkbg-spc-outer', style:wrapStyle(a) });
198 return el('div', blockProps,
199 el('div', { className:'bkbg-spc-wrap' },
200 el('div', { className:'bkbg-spc-left', style:{ background: getLeftBg(a) } },
201 a.showBadge ? el('span', { className:'bkbg-spc-badge' }, a.badge) : null,
202 el('div', { className:'bkbg-spc-price-label' }, a.priceLabel),
203 el('div', { className:'bkbg-spc-price-row' },
204 a.showOldPrice ? el('span', { className:'bkbg-spc-old-price' }, a.oldPrice) : null,
205 el('span', { className:'bkbg-spc-price' }, a.priceValue),
206 el('span', { className:'bkbg-spc-period' }, ' / ' + a.pricePeriod)
207 ),
208 el('div', { className:'bkbg-spc-price-note' }, a.priceNote),
209 el('ul', { className:'bkbg-spc-features' },
210 a.features.map(function(f) {
211 return el('li', { key:f.id }, el('span', { className:'bkbg-spc-check' }, ''), f.text);
212 })
213 )
214 ),
215 el('div', { className:'bkbg-spc-right' },
216 el(RichText.Content, { tagName:'h3', className:'bkbg-spc-heading', value:a.ctaHeading }),
217 el(RichText.Content, { tagName:'p', className:'bkbg-spc-subtitle', value:a.ctaSubtitle }),
218 el('div', { className:'bkbg-spc-actions' },
219 el('a', { href:a.primaryUrl, className:'bkbg-spc-btn-primary', target:a.primaryTarget, rel:a.primaryTarget==='_blank'?'noopener noreferrer':undefined }, a.primaryLabel),
220 a.showSecondary ? el('a', { href:a.secondaryUrl, className:'bkbg-spc-btn-secondary', target:a.secondaryTarget, rel:a.secondaryTarget==='_blank'?'noopener noreferrer':undefined }, a.secondaryLabel) : null
221 ),
222 a.showSocialProof ? el('div', { className:'bkbg-spc-proof' },
223 el('p', { className:'bkbg-spc-proof-text' }, a.socialProofText),
224 el('p', { className:'bkbg-spc-proof-author' }, a.socialProofAuthor)
225 ) : null
226 )
227 )
228 );
229 }
230 });
231 }() );
232