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 / speed-calculator / index.js

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

206 lines 13.3 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 RichText = wp.blockEditor.RichText;
11 var PanelBody = wp.components.PanelBody;
12 var RangeControl = wp.components.RangeControl;
13 var TextControl = wp.components.TextControl;
14 var ToggleControl = wp.components.ToggleControl;
15 var SelectControl = wp.components.SelectControl;
16
17 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
18 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
19
20 var SPEED_UNITS = ['km/h','mph','m/s','knots'];
21 var DIST_UNITS = ['km','miles','m','feet','nautical miles'];
22 var TIME_UNITS = ['seconds','minutes','hours','days'];
23
24 function EditorPreview(props) {
25 var a = props.attributes;
26 var solveFor = a.defaultSolveFor;
27
28 var wrapStyle = {
29 background: a.sectionBg, borderRadius:'14px', padding:'32px 24px',
30 maxWidth: a.contentMaxWidth+'px', margin:'0 auto', fontFamily:'inherit', boxSizing:'border-box'
31 };
32
33 var VARS = [
34 { key:'speed', label:'Speed', color:a.speedColor, icon:'', unit:a.defaultSpeedUnit, units:SPEED_UNITS },
35 { key:'dist', label:'Distance', color:a.distColor, icon:'📏', unit:a.defaultDistUnit, units:DIST_UNITS },
36 { key:'time', label:'Time', color:a.timeColor, icon:'⏱️', unit:a.defaultTimeUnit, units:TIME_UNITS }
37 ];
38
39 var tabStyle = function(k) {
40 var active = k === solveFor;
41 return {
42 padding:'7px 16px', borderRadius:'8px', border:'2px solid '+(active?a.accentColor:'#e5e7eb'),
43 background:active?a.accentColor:'transparent', color:active?'#fff':a.labelColor,
44 fontWeight:active?'700':'500', fontSize:'13px', cursor:'pointer'
45 };
46 };
47
48 var inputBlockStyle = function(v) {
49 var disabled = v.key === solveFor;
50 return {
51 background: disabled?a.resultBg:a.cardBg, borderRadius:'12px', padding:'16px',
52 border: '2px solid '+(disabled?v.color:'#e5e7eb'), opacity: disabled?0.85:1
53 };
54 };
55
56 return el('div', { className: 'bkbg-spd-wrap', style: { background: a.sectionBg, maxWidth: a.contentMaxWidth+'px', margin:'0 auto' } },
57 el(RichText, { tagName:'h3', value:a.title, onChange:function(v){ props.setAttributes({title:v}); },
58 className: 'bkbg-spd-title', style:{ color:a.titleColor, margin:'0 0 6px 0' }, placeholder:'Block title...' }),
59 el(RichText, { tagName:'p', value:a.subtitle, onChange:function(V){ props.setAttributes({subtitle:V}); },
60 className: 'bkbg-spd-subtitle', style:{ color:a.subtitleColor, margin:'0 0 22px 0' }, placeholder:'Subtitle...' }),
61
62 // Solve-for tabs
63 el('div', { style:{ marginBottom:'10px', fontSize:'12px', fontWeight:'700', textTransform:'uppercase', letterSpacing:'0.06em', color:a.labelColor } }, 'Solve for…'),
64 el('div', { style:{ display:'flex', gap:'8px', flexWrap:'wrap', marginBottom:'22px' } },
65 VARS.map(function(v) {
66 return el('button', { key:v.key, style:tabStyle(v.key) }, v.icon + ' ' + v.label);
67 })
68 ),
69
70 // 3 input/result blocks
71 el('div', { style:{ display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(180px,1fr))', gap:'12px', marginBottom:'22px' } },
72 VARS.map(function(v) {
73 var isResult = v.key === solveFor;
74 return el('div', { key:v.key, style:inputBlockStyle(v) },
75 el('div', { style:{ fontSize:'11px', fontWeight:'700', textTransform:'uppercase', letterSpacing:'0.06em', color:v.color, marginBottom:'6px' } },
76 v.icon + ' ' + v.label + (isResult?' (Result)':'')
77 ),
78 isResult ?
79 el('div', { style:{ fontSize:'28px', fontWeight:'700', color:v.color, margin:'4px 0 8px' } }, '') :
80 el('input', { type:'number', readOnly:true, style:{ width:'100%', boxSizing:'border-box', border:'1.5px solid #e5e7eb', borderRadius:'8px', padding:'8px 10px', fontSize:'16px', background:a.inputBg, color:a.labelColor, marginBottom:'8px' }, placeholder:'Enter value…' }),
81 el('select', { readOnly:true, style:{ width:'100%', border:'1.5px solid #e5e7eb', borderRadius:'7px', padding:'6px 8px', fontSize:'13px', background:a.inputBg, color:a.labelColor } },
82 v.units.map(function(u){ return el('option', { key:u, selected:u===v.unit }, u); })
83 )
84 );
85 })
86 ),
87
88 // Formula display
89 a.showFormula && el('div', { style:{ background:a.cardBg, borderRadius:'10px', padding:'12px 16px', border:'1.5px solid #e5e7eb', display:'flex', gap:'20px', flexWrap:'wrap', justifyContent:'center' } },
90 el('span', { style:{ fontSize:'13px', fontWeight:'600', color:a.speedColor } }, '⚡ Speed = Distance ÷ Time'),
91 el('span', { style:{ fontSize:'13px', fontWeight:'600', color:a.distColor } }, '📏 Distance = Speed × Time'),
92 el('span', { style:{ fontSize:'13px', fontWeight:'600', color:a.timeColor } }, '⏱️ Time = Distance ÷ Speed')
93 ),
94
95 // Unit conversions preview
96 a.showUnitConversions && el('div', { style:{ marginTop:'16px', background:a.cardBg, borderRadius:'10px', padding:'12px 16px', border:'1.5px solid #e5e7eb' } },
97 el('div', { style:{ fontSize:'12px', fontWeight:'700', textTransform:'uppercase', letterSpacing:'0.06em', color:a.labelColor, marginBottom:'8px' } }, 'Speed Conversions'),
98 el('div', { style:{ display:'flex', gap:'14px', flexWrap:'wrap' } },
99 ['1 km/h = 0.621 mph','1 mph = 1.609 km/h','1 m/s = 3.6 km/h','1 knot = 1.852 km/h'].map(function(s) {
100 return el('span', { key:s, style:{ fontSize:'12px', color:a.labelColor, background:'#f3f4f6', borderRadius:'6px', padding:'3px 9px' } }, s);
101 })
102 )
103 )
104 );
105 }
106
107 registerBlockType('blockenberg/speed-calculator', {
108 edit: function(props) {
109 var a = props.attributes;
110 var set = props.setAttributes;
111
112 var colorSettings = [
113 { value:a.accentColor, onChange:function(v){ set({accentColor: v||'#3b82f6'}); }, label:'Accent / tab color' },
114 { value:a.speedColor, onChange:function(v){ set({speedColor: v||'#8b5cf6'}); }, label:'Speed field color' },
115 { value:a.distColor, onChange:function(v){ set({distColor: v||'#0ea5e9'}); }, label:'Distance field color'},
116 { value:a.timeColor, onChange:function(v){ set({timeColor: v||'#22c55e'}); }, label:'Time field color' },
117 { value:a.sectionBg, onChange:function(v){ set({sectionBg: v||'#eff6ff'}); }, label:'Section background' },
118 { value:a.cardBg, onChange:function(v){ set({cardBg: v||'#ffffff'}); }, label:'Card background' },
119 { value:a.inputBg, onChange:function(v){ set({inputBg: v||'#f8fafc'}); }, label:'Input background' },
120 { value:a.resultBg, onChange:function(v){ set({resultBg: v||'#dbeafe'}); }, label:'Result background' },
121 { value:a.titleColor, onChange:function(v){ set({titleColor: v||'#111827'}); }, label:'Title color' },
122 { value:a.subtitleColor, onChange:function(v){ set({subtitleColor:v||'#6b7280'}); }, label:'Subtitle color' },
123 { value:a.labelColor, onChange:function(v){ set({labelColor: v||'#374151'}); }, label:'Label color' }
124 ];
125
126 return el(Fragment, null,
127 el(InspectorControls, null,
128 el(PanelBody, { title:'Calculator Settings', initialOpen:true },
129 el(SelectControl, { label:'Default: Solve for', value:a.defaultSolveFor,
130 options:[{label:'Speed',value:'speed'},{label:'Distance',value:'dist'},{label:'Time',value:'time'}],
131 onChange:function(v){ set({defaultSolveFor:v}); } }),
132 el(SelectControl, { label:'Default Speed Unit', value:a.defaultSpeedUnit,
133 options:SPEED_UNITS.map(function(u){ return {label:u,value:u}; }),
134 onChange:function(v){ set({defaultSpeedUnit:v}); } }),
135 el(SelectControl, { label:'Default Distance Unit', value:a.defaultDistUnit,
136 options:DIST_UNITS.map(function(u){ return {label:u,value:u}; }),
137 onChange:function(v){ set({defaultDistUnit:v}); } }),
138 el(SelectControl, { label:'Default Time Unit', value:a.defaultTimeUnit,
139 options:TIME_UNITS.map(function(u){ return {label:u,value:u}; }),
140 onChange:function(v){ set({defaultTimeUnit:v}); } })
141 ),
142 el(PanelBody, { title:'Display Options', initialOpen:false },
143 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show formula reference', checked:a.showFormula, onChange:function(v){ set({showFormula:v}); } }),
144 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show unit conversions', checked:a.showUnitConversions, onChange:function(v){ set({showUnitConversions:v}); } }),
145 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show real-world examples', checked:a.showExamples, onChange:function(v){ set({showExamples:v}); } })
146 ),
147 el(PanelBody, { title:'Sizing', initialOpen:false },
148 el(RangeControl, { label:'Max Width (px)', value:a.contentMaxWidth, min:400, max:1100, step:20, onChange:function(v){ set({contentMaxWidth:v}); } })
149 ),
150
151 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
152 getTypoControl() ? el(getTypoControl(), { label: __('Title Typography', 'blockenberg'), value: a.titleTypo || {}, onChange: function (v) { set({ titleTypo: v }); } }) : null,
153 getTypoControl() ? el(getTypoControl(), { label: __('Subtitle Typography', 'blockenberg'), value: a.subtitleTypo || {}, onChange: function (v) { set({ subtitleTypo: v }); } }) : null
154 ),
155 el(PanelColorSettings, { title:'Colors', initialOpen:false, disableCustomGradients:true, colorSettings:colorSettings })
156 ),
157 el('div', useBlockProps((function () {
158 var s = {};
159 var tv = getTypoCssVars();
160 if (tv) {
161 Object.assign(s, tv(a.titleTypo, '--bkspd-tt-'));
162 Object.assign(s, tv(a.subtitleTypo, '--bkspd-st-'));
163 }
164 return { style: s };
165 })()),
166 el(EditorPreview, { attributes:a, setAttributes:set })
167 )
168 );
169 },
170
171 save: function(props) {
172 var a = props.attributes;
173 return el('div', useBlockProps.save(),
174 el('div', {
175 className: 'bkbg-spd-app',
176 'data-opts': JSON.stringify({
177 title: a.title,
178 subtitle: a.subtitle,
179 defaultSolveFor: a.defaultSolveFor,
180 defaultSpeedUnit: a.defaultSpeedUnit,
181 defaultDistUnit: a.defaultDistUnit,
182 defaultTimeUnit: a.defaultTimeUnit,
183 showUnitConversions: a.showUnitConversions,
184 showFormula: a.showFormula,
185 showExamples: a.showExamples,
186 accentColor: a.accentColor,
187 speedColor: a.speedColor,
188 distColor: a.distColor,
189 timeColor: a.timeColor,
190 sectionBg: a.sectionBg,
191 cardBg: a.cardBg,
192 inputBg: a.inputBg,
193 resultBg: a.resultBg,
194 titleColor: a.titleColor,
195 subtitleColor: a.subtitleColor,
196 labelColor: a.labelColor,
197 titleTypo: a.titleTypo,
198 subtitleTypo: a.subtitleTypo,
199 contentMaxWidth: a.contentMaxWidth
200 })
201 })
202 );
203 }
204 });
205 }() );
206