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 / comparison-table / index.js

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

153 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 const el = window.wp.element.createElement;
3 const { registerBlockType } = window.wp.blocks;
4 const { InspectorControls, PanelColorSettings } = window.wp.blockEditor;
5 const { PanelBody, TextControl, ToggleControl, Button, RangeControl } = window.wp.components;
6 const { __ } = window.wp.i18n;
7
8 function getTypographyControl() { return (window.bkbgTypographyControl || function () { return null; }); }
9 function getTypoCssVars() { return (window.bkbgTypoCssVars || function () { return {}; }); }
10 function _tv(typo, prefix) { var fn = getTypoCssVars(); return fn(typo || {}, prefix); }
11
12 function CellValue({ val, checkColor, crossColor }) {
13 if ( val === 'true' ) return el('span',{className:'bkct-check',style:{color:checkColor}},'');
14 if ( val === 'false' ) return el('span',{className:'bkct-cross',style:{color:crossColor}},'');
15 return el('span',{className:'bkct-text'}, val);
16 }
17
18 registerBlockType('blockenberg/comparison-table', {
19 edit: function(props) {
20 const {attributes:attr,setAttributes}=props;
21
22 function updatePlan(i,key,val){ const p=attr.plans.slice();p[i]=Object.assign({},p[i],{[key]:val});setAttributes({plans:p}); }
23 function addPlan(){ setAttributes({plans:[...attr.plans,{name:'New Plan',subtitle:'',highlighted:false}],features:attr.features.map(f=>({...f,values:[...f.values,'']}))}); }
24 function removePlan(i){ setAttributes({plans:attr.plans.filter((_,x)=>x!==i),features:attr.features.map(f=>({...f,values:f.values.filter((_,x)=>x!==i)}))}); }
25
26 function updateFeature(i,key,val){ const f=attr.features.slice();f[i]=Object.assign({},f[i],{[key]:val});setAttributes({features:f}); }
27 function updateCell(fi,pi,val){ const f=attr.features.slice();const v=f[fi].values.slice();v[pi]=val;f[fi]={...f[fi],values:v};setAttributes({features:f}); }
28 function addFeature(){ setAttributes({features:[...attr.features,{label:'New Feature',values:attr.plans.map(()=>'')}]}); }
29 function removeFeature(i){ setAttributes({features:attr.features.filter((_,x)=>x!==i)}); }
30
31 const tableStyle=Object.assign({
32 '--bkct-header-bg':attr.headerBg,'--bkct-header-text':attr.headerText,
33 '--bkct-hl-bg':attr.highlightBg,'--bkct-hl-border':attr.highlightBorder,
34 '--bkct-check':attr.checkColor,'--bkct-cross':attr.crossColor,
35 '--bkct-radius':attr.borderRadius+'px',
36 borderRadius:attr.borderRadius+'px',overflow:'hidden',
37 }, _tv(attr.typoHeader, '--bkct-th-'), _tv(attr.typoCell, '--bkct-td-'));
38
39 return el('div',{className:'bkct-wrap',style:tableStyle},
40
41 el(InspectorControls,null,
42 el(PanelBody,{title:__('Plans (Columns)'),initialOpen:true},
43 attr.plans.map((plan,i)=>el('div',{key:i,style:{border:'1px solid #ddd',borderRadius:'8px',padding:'10px',marginBottom:'8px',background:'#fafafa'}},
44 el(TextControl,{label:__('Plan Name'),value:plan.name,onChange:v=>updatePlan(i,'name',v)}),
45 el(TextControl,{label:__('Subtitle / Price'),value:plan.subtitle,onChange:v=>updatePlan(i,'subtitle',v)}),
46 el(ToggleControl,{label:__('Highlighted (Popular)'),checked:plan.highlighted,onChange:v=>updatePlan(i,'highlighted',v),__nextHasNoMarginBottom:true}),
47 el(Button,{isDestructive:true,isSmall:true,onClick:()=>removePlan(i)},__('Remove Plan'))
48 )),
49 el(Button,{variant:'secondary',onClick:addPlan,style:{width:'100%',justifyContent:'center',marginTop:'8px'}},__('+ Add Plan'))
50 ),
51 el(PanelBody,{title:__('Features (Rows)'),initialOpen:false},
52 el('p',{style:{fontSize:'12px',color:'#888',marginTop:0}},__('Use "true" / "false" for ✓ / ✕, or type any text value.')),
53 attr.features.map((feat,fi)=>el('div',{key:fi,style:{border:'1px solid #ddd',borderRadius:'8px',padding:'10px',marginBottom:'8px',background:'#fafafa'}},
54 el(TextControl,{label:__('Feature Label'),value:feat.label,onChange:v=>updateFeature(fi,'label',v)}),
55 attr.plans.map((plan,pi)=>el(TextControl,{key:pi,label:plan.name+' value',value:feat.values[pi]||'',onChange:v=>updateCell(fi,pi,v)})),
56 el(Button,{isDestructive:true,isSmall:true,onClick:()=>removeFeature(fi)},__('Remove Feature'))
57 )),
58 el(Button,{variant:'secondary',onClick:addFeature,style:{width:'100%',justifyContent:'center',marginTop:'8px'}},__('+ Add Feature'))
59 ),
60 el(PanelBody,{title:__('Style'),initialOpen:false},
61 el(RangeControl,{label:__('Border Radius'),value:attr.borderRadius,min:0,max:32,onChange:v=>setAttributes({borderRadius:v})}),
62 el(ToggleControl,{label:__('Zebra Stripes'),checked:attr.zebraStripe,onChange:v=>setAttributes({zebraStripe:v}),__nextHasNoMarginBottom:true}),
63 el(ToggleControl,{label:__('Sticky Header'),checked:attr.stickyHeader,onChange:v=>setAttributes({stickyHeader:v}),__nextHasNoMarginBottom:true})
64 ),
65 el(PanelBody,{title:__('Typography'),initialOpen:false},
66 el(getTypographyControl(), { label: __('Header Typography'), value: attr.typoHeader, onChange: v => setAttributes({ typoHeader: v }) }),
67 el(getTypographyControl(), { label: __('Cell Typography'), value: attr.typoCell, onChange: v => setAttributes({ typoCell: v }) })
68 ),
69 el(PanelColorSettings,{title:__('Colors'),initialOpen:false,colorSettings:[
70 {label:__('Header Background'),value:attr.headerBg,onChange:v=>setAttributes({headerBg:v||'#6c3fb5'})},
71 {label:__('Header Text'),value:attr.headerText,onChange:v=>setAttributes({headerText:v||'#ffffff'})},
72 {label:__('Highlight Background'),value:attr.highlightBg,onChange:v=>setAttributes({highlightBg:v||'#f3eeff'})},
73 {label:__('Highlight Border'),value:attr.highlightBorder,onChange:v=>setAttributes({highlightBorder:v||'#6c3fb5'})},
74 {label:__('Check Color'),value:attr.checkColor,onChange:v=>setAttributes({checkColor:v||'#22c55e'})},
75 {label:__('Cross Color'),value:attr.crossColor,onChange:v=>setAttributes({crossColor:v||'#ef4444'})},
76 ]})
77 ),
78
79 el('div',{className:'bkct-scroll'},
80 el('table',{className:'bkct-table'+(attr.zebraStripe?' bkct-zebra':'')},
81 el('thead',null,
82 el('tr',null,
83 el('th',{className:'bkct-feature-col'},__('Features')),
84 attr.plans.map((plan,i)=>
85 el('th',{key:i,className:'bkct-plan-col'+(plan.highlighted?' bkct-highlight':'')},
86 el('div',{className:'bkct-plan-name'},plan.name),
87 plan.subtitle&&el('div',{className:'bkct-plan-sub'},plan.subtitle)
88 )
89 )
90 )
91 ),
92 el('tbody',null,
93 attr.features.map((feat,fi)=>
94 el('tr',{key:fi,className:'bkct-row'},
95 el('td',{className:'bkct-label'},feat.label),
96 attr.plans.map((plan,pi)=>
97 el('td',{key:pi,className:'bkct-cell'+(plan.highlighted?' bkct-highlight':'')},
98 el(CellValue,{val:feat.values[pi]||'',checkColor:attr.checkColor,crossColor:attr.crossColor})
99 )
100 )
101 )
102 )
103 )
104 )
105 )
106 );
107 },
108
109 save: function({attributes:attr}) {
110 const wrapStyle=Object.assign({
111 '--bkct-header-bg':attr.headerBg,'--bkct-header-text':attr.headerText,
112 '--bkct-hl-bg':attr.highlightBg,'--bkct-hl-border':attr.highlightBorder,
113 '--bkct-check':attr.checkColor,'--bkct-cross':attr.crossColor,
114 '--bkct-radius':attr.borderRadius+'px',
115 }, _tv(attr.typoHeader, '--bkct-th-'), _tv(attr.typoCell, '--bkct-td-'));
116 function CVal({val}) {
117 if (val==='true') return el('span',{className:'bkct-check'},'');
118 if (val==='false') return el('span',{className:'bkct-cross'},'');
119 return el('span',{className:'bkct-text'},val);
120 }
121 return el('div',{className:'bkct-wrap',style:wrapStyle},
122 el('div',{className:'bkct-scroll'},
123 el('table',{className:'bkct-table'+(attr.zebraStripe?' bkct-zebra':'')},
124 el('thead',{className:attr.stickyHeader?'bkct-sticky':''},
125 el('tr',null,
126 el('th',{className:'bkct-feature-col'}),
127 attr.plans.map((plan,i)=>
128 el('th',{key:i,className:'bkct-plan-col'+(plan.highlighted?' bkct-highlight':'')},
129 el('div',{className:'bkct-plan-name'},plan.name),
130 plan.subtitle&&el('div',{className:'bkct-plan-sub'},plan.subtitle)
131 )
132 )
133 )
134 ),
135 el('tbody',null,
136 attr.features.map((feat,fi)=>
137 el('tr',{key:fi,className:'bkct-row'},
138 el('td',{className:'bkct-label'},feat.label),
139 attr.plans.map((plan,pi)=>
140 el('td',{key:pi,className:'bkct-cell'+(plan.highlighted?' bkct-highlight':'')},
141 el(CVal,{val:feat.values[pi]||''})
142 )
143 )
144 )
145 )
146 )
147 )
148 )
149 );
150 }
151 });
152 }() );
153