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

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

196 lines 10.7 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 SelectControl = wp.components.SelectControl;
14 var ToggleControl = wp.components.ToggleControl;
15
16 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
17 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
18
19 function EditorPreview(props) {
20 var a = props.attributes;
21
22 var wrapStyle = {
23 background: a.sectionBg,
24 borderRadius: '16px',
25 padding: '32px 24px',
26 maxWidth: a.contentMaxWidth + 'px',
27 margin: '0 auto',
28 fontFamily: 'inherit',
29 boxSizing: 'border-box',
30 textAlign: 'center'
31 };
32
33 var clockStyle = {
34 background: a.clockBg,
35 borderRadius: '20px',
36 padding: '28px 20px',
37 margin: '20px auto',
38 fontFamily: "'Courier New', Courier, monospace",
39 fontSize: a.clockFontSize + 'px',
40 fontWeight: '700',
41 color: a.clockColor,
42 letterSpacing: '0.06em',
43 lineHeight: '1'
44 };
45
46 var btnRowStyle = { display:'flex', gap:'10px', justifyContent:'center', flexWrap:'wrap', marginBottom:'18px' };
47
48 function actionBtn(label, bg) {
49 return el('button', {
50 style: { padding:'10px 22px', borderRadius:'10px', border:'none', background:bg, color:'#fff', fontWeight:'700', fontSize:'14px', cursor:'pointer' }
51 }, label);
52 }
53
54 var SAMPLE_LAPS = [
55 { num:1, split:'00:05.32', total:'00:05.32' },
56 { num:2, split:'00:04.87', total:'00:10.19' },
57 { num:3, split:'00:06.01', total:'00:16.20' }
58 ];
59
60 return el('div', { style: wrapStyle },
61 a.showTitle && el(RichText, {
62 tagName: 'h3',
63 className: 'bkbg-sw-title',
64 value: a.title,
65 onChange: function (v) { props.setAttributes({ title: v }); },
66 style: { color: a.titleColor, margin: '0 0 5px 0' },
67 placeholder: 'Title…'
68 }),
69 a.showSubtitle && el(RichText, {
70 tagName: 'p',
71 className: 'bkbg-sw-subtitle',
72 value: a.subtitle,
73 onChange: function (v) { props.setAttributes({ subtitle: v }); },
74 style: { color: a.subtitleColor, margin: '0 0 2px 0' },
75 placeholder: 'Subtitle…'
76 }),
77
78 el('div', { style: clockStyle },
79 a.showMilliseconds ? '00:00.00' : '00:00'
80 ),
81
82 el('div', { style: btnRowStyle },
83 actionBtn('▶ Start', a.startColor),
84 actionBtn('⏸ Pause', a.stopColor),
85 a.showLaps && actionBtn('⏱ Lap', a.lapColor),
86 actionBtn('↺ Reset', a.resetColor)
87 ),
88
89 a.showLaps && el('div', {
90 style: { background: a.cardBg, borderRadius:'12px', overflow:'hidden', border:'1.5px solid #e5e7eb', textAlign:'left' }
91 },
92 el('div', { style:{ display:'flex', fontWeight:'700', fontSize:'11px', textTransform:'uppercase', letterSpacing:'0.06em', color:a.labelColor, background:'#f9fafb', padding:'8px 14px', gap:'10px' } },
93 el('span', { style:{ width:'32px' } }, '#'),
94 el('span', { style:{ flex:'1' } }, 'Split'),
95 el('span', { style:{ flex:'1', textAlign:'right' } }, 'Total')
96 ),
97 SAMPLE_LAPS.map(function (lap) {
98 return el('div', { key: lap.num, style:{ display:'flex', padding:'8px 14px', gap:'10px', fontSize:'13px', color:a.labelColor, borderTop:'1px solid #f3f4f6', fontFamily:"'Courier New', monospace" } },
99 el('span', { style:{ width:'32px', fontWeight:'700', color:a.accentColor } }, lap.num),
100 el('span', { style:{ flex:'1' } }, lap.split),
101 el('span', { style:{ flex:'1', textAlign:'right', color:a.accentColor } }, lap.total)
102 );
103 })
104 )
105 );
106 }
107
108 registerBlockType('blockenberg/stopwatch', {
109 edit: function (props) {
110 var a = props.attributes;
111 var set = props.setAttributes;
112
113 var colorSettings = [
114 { value:a.accentColor, onChange:function(v){set({accentColor: v||'#6366f1'});}, label:'Accent / lap number' },
115 { value:a.startColor, onChange:function(v){set({startColor: v||'#22c55e'});}, label:'Start button' },
116 { value:a.stopColor, onChange:function(v){set({stopColor: v||'#ef4444'});}, label:'Pause/Stop button' },
117 { value:a.resetColor, onChange:function(v){set({resetColor: v||'#6b7280'});}, label:'Reset button' },
118 { value:a.lapColor, onChange:function(v){set({lapColor: v||'#f59e0b'});}, label:'Lap button' },
119 { value:a.clockBg, onChange:function(v){set({clockBg: v||'#1e1b4b'});}, label:'Clock background' },
120 { value:a.clockColor, onChange:function(v){set({clockColor: v||'#e0e7ff'});}, label:'Clock digits color' },
121 { value:a.sectionBg, onChange:function(v){set({sectionBg: v||'#f5f3ff'});}, label:'Section background' },
122 { value:a.cardBg, onChange:function(v){set({cardBg: v||'#ffffff'});}, label:'Lap table background'},
123 { value:a.titleColor, onChange:function(v){set({titleColor: v||'#111827'});}, label:'Title color' },
124 { value:a.subtitleColor, onChange:function(v){set({subtitleColor: v||'#6b7280'});}, label:'Subtitle color' },
125 { value:a.labelColor, onChange:function(v){set({labelColor: v||'#374151'});}, label:'Label color' }
126 ];
127
128 return el(Fragment, null,
129 el(InspectorControls, null,
130 el(PanelBody, { title:'Stopwatch Settings', initialOpen:true },
131 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show title', checked:a.showTitle, onChange:function(v){set({showTitle:v});} }),
132 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show subtitle', checked:a.showSubtitle, onChange:function(v){set({showSubtitle:v});} }),
133 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show lap recorder', checked:a.showLaps, onChange:function(v){set({showLaps:v});} }),
134 el(ToggleControl, { __nextHasNoMarginBottom:true, label:'Show milliseconds', checked:a.showMilliseconds, onChange:function(v){set({showMilliseconds:v});} }),
135 a.showLaps && el(RangeControl, { label:'Max laps to show', value:a.maxLaps, min:5, max:50, onChange:function(v){set({maxLaps:v});} })
136 ),
137 el(PanelBody, { title:'Sizing', initialOpen:false },
138 el(RangeControl, { label:'Max width (px)', value:a.contentMaxWidth, min:320, max:900, step:20, onChange:function(v){set({contentMaxWidth:v});} })
139 ),
140
141 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
142 getTypoControl()({ label: __('Title', 'blockenberg'), value: a.titleTypo, onChange: function (v) { set({ titleTypo: v }); } }),
143 getTypoControl()({ label: __('Subtitle', 'blockenberg'), value: a.subtitleTypo, onChange: function (v) { set({ subtitleTypo: v }); } }),
144 el(RangeControl, { label:'Clock font size', value:a.clockFontSize, min:32, max:120, onChange:function(v){set({clockFontSize:v});} })
145 ),
146 el(PanelColorSettings, { title:'Colors', initialOpen:false, disableCustomGradients:true, colorSettings:colorSettings })
147 ),
148 el('div', useBlockProps((function () {
149 var _tvf = getTypoCssVars();
150 var s = {};
151 Object.assign(s, _tvf(a.titleTypo, '--bksw-tt-'));
152 Object.assign(s, _tvf(a.subtitleTypo, '--bksw-st-'));
153 return { className: 'bkbg-sw-editor-wrap', style: s };
154 })()),
155 el(EditorPreview, { attributes:a, setAttributes:set })
156 )
157 );
158 },
159
160 save: function (props) {
161 var a = props.attributes;
162 return el('div', useBlockProps.save(),
163 el('div', {
164 className: 'bkbg-sw-app',
165 'data-opts': JSON.stringify({
166 title: a.title,
167 subtitle: a.subtitle,
168 showTitle: a.showTitle,
169 showSubtitle: a.showSubtitle,
170 showLaps: a.showLaps,
171 showMilliseconds: a.showMilliseconds,
172 maxLaps: a.maxLaps,
173 accentColor: a.accentColor,
174 startColor: a.startColor,
175 stopColor: a.stopColor,
176 resetColor: a.resetColor,
177 lapColor: a.lapColor,
178 clockBg: a.clockBg,
179 clockColor: a.clockColor,
180 sectionBg: a.sectionBg,
181 cardBg: a.cardBg,
182 titleColor: a.titleColor,
183 subtitleColor: a.subtitleColor,
184 labelColor: a.labelColor,
185 titleFontSize: a.titleFontSize,
186 clockFontSize: a.clockFontSize,
187 contentMaxWidth: a.contentMaxWidth,
188 titleTypo: a.titleTypo,
189 subtitleTypo: a.subtitleTypo
190 })
191 })
192 );
193 }
194 });
195 }() );
196