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

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

260 lines 14.2 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 PanelBody = wp.components.PanelBody;
11 var RangeControl = wp.components.RangeControl;
12 var TextControl = wp.components.TextControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var SelectControl = wp.components.SelectControl;
15
16 var _tc, _tvf;
17 Object.defineProperty(window, '_tc', { get: function () { return _tc || (_tc = window.bkbgTypographyControl); } });
18 Object.defineProperty(window, '_tvf', { get: function () { return _tvf || (_tvf = window.bkbgTypoCssVars); } });
19 function getTypoControl(label, key, attrs, setA) { return _tc(label, key, attrs, setA); }
20 function getTypoCssVars(attrs) {
21 var v = {};
22 _tvf(v, 'titleTypo', attrs, '--bktst-tt-');
23 _tvf(v, 'subtitleTypo', attrs, '--bktst-st-');
24 return v;
25 }
26
27 var SAMPLE_TEXT = 'The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump.';
28
29 registerBlockType('blockenberg/typing-speed-test', {
30 edit: function (props) {
31 var a = props.attributes;
32 var setAttributes = props.setAttributes;
33 var blockProps = useBlockProps((function () { var _tv = getTypoCssVars(a); var s = {}; Object.assign(s, _tv); return { className: 'bkbg-tst-editor-wrap', style: s }; })());
34
35 var containerStyle = {
36 background: a.sectionBg,
37 borderRadius: '12px',
38 padding: '28px',
39 maxWidth: a.contentMaxWidth + 'px',
40 margin: '0 auto',
41 fontFamily: 'system-ui, sans-serif'
42 };
43
44 var cardStyle = {
45 background: a.cardBg,
46 borderRadius: '10px',
47 padding: '20px',
48 marginBottom: '16px',
49 boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
50 };
51
52 var btnStyle = {
53 background: a.accentColor,
54 color: '#fff',
55 border: 'none',
56 borderRadius: '8px',
57 padding: '10px 24px',
58 cursor: 'pointer',
59 fontWeight: '600',
60 fontSize: '14px'
61 };
62
63 var statBoxStyle = {
64 textAlign: 'center',
65 flex: '1',
66 minWidth: '80px'
67 };
68
69 return el(
70 Fragment,
71 null,
72 el(
73 InspectorControls,
74 null,
75 el(
76 PanelBody,
77 { title: __('Content', 'blockenberg'), initialOpen: true },
78 el(TextControl, {
79 label: __('Title', 'blockenberg'),
80 value: a.title,
81 onChange: function (v) { setAttributes({ title: v }); }
82 }),
83 el(TextControl, {
84 label: __('Subtitle', 'blockenberg'),
85 value: a.subtitle,
86 onChange: function (v) { setAttributes({ subtitle: v }); }
87 }),
88 el(ToggleControl, {
89 label: __('Show Title', 'blockenberg'),
90 checked: a.showTitle,
91 onChange: function (v) { setAttributes({ showTitle: v }); },
92 __nextHasNoMarginBottom: true
93 }),
94 el(ToggleControl, {
95 label: __('Show Subtitle', 'blockenberg'),
96 checked: a.showSubtitle,
97 onChange: function (v) { setAttributes({ showSubtitle: v }); },
98 __nextHasNoMarginBottom: true
99 })
100 ),
101 el(
102 PanelBody,
103 { title: __('Test Settings', 'blockenberg'), initialOpen: false },
104 el(SelectControl, {
105 label: __('Test Duration', 'blockenberg'),
106 value: String(a.duration),
107 options: [
108 { value: '30', label: '30 seconds' },
109 { value: '60', label: '60 seconds' },
110 { value: '120', label: '2 minutes' },
111 { value: '180', label: '3 minutes' }
112 ],
113 onChange: function (v) { setAttributes({ duration: parseInt(v) }); }
114 }),
115 el(SelectControl, {
116 label: __('Default Difficulty', 'blockenberg'),
117 value: a.defaultDifficulty,
118 options: [
119 { value: 'easy', label: __('Easy', 'blockenberg') },
120 { value: 'medium', label: __('Medium', 'blockenberg') },
121 { value: 'hard', label: __('Hard', 'blockenberg') }
122 ],
123 onChange: function (v) { setAttributes({ defaultDifficulty: v }); }
124 }),
125 el(ToggleControl, {
126 label: __('Show Difficulty Buttons', 'blockenberg'),
127 checked: a.showDifficultyBtn,
128 onChange: function (v) { setAttributes({ showDifficultyBtn: v }); },
129 __nextHasNoMarginBottom: true
130 }),
131 el(ToggleControl, {
132 label: __('Show Live WPM', 'blockenberg'),
133 checked: a.showLiveWpm,
134 onChange: function (v) { setAttributes({ showLiveWpm: v }); },
135 __nextHasNoMarginBottom: true
136 }),
137 el(ToggleControl, {
138 label: __('Show Accuracy', 'blockenberg'),
139 checked: a.showAccuracy,
140 onChange: function (v) { setAttributes({ showAccuracy: v }); },
141 __nextHasNoMarginBottom: true
142 }),
143 el(ToggleControl, {
144 label: __('Show Error Count', 'blockenberg'),
145 checked: a.showErrors,
146 onChange: function (v) { setAttributes({ showErrors: v }); },
147 __nextHasNoMarginBottom: true
148 })
149 ),
150 el(
151 PanelBody,
152 { title: __('Typography', 'blockenberg'), initialOpen: false },
153 getTypoControl(__('Title', 'blockenberg'), 'titleTypo', a, setAttributes),
154 getTypoControl(__('Subtitle', 'blockenberg'), 'subtitleTypo', a, setAttributes)
155 ),
156 el(
157 PanelBody,
158 { title: __('Appearance', 'blockenberg'), initialOpen: false },
159 el(RangeControl, {
160 label: __('Max Width (px)', 'blockenberg'),
161 value: a.contentMaxWidth,
162 min: 320, max: 1200,
163 onChange: function (v) { setAttributes({ contentMaxWidth: v }); }
164 })
165 ),
166 el(
167 PanelColorSettings,
168 {
169 title: __('Colors', 'blockenberg'),
170 initialOpen: false,
171 colorSettings: [
172 { value: a.accentColor, onChange: function (v) { setAttributes({ accentColor: v || '#8b5cf6' }); }, label: __('Accent Color', 'blockenberg') },
173 { value: a.correctColor, onChange: function (v) { setAttributes({ correctColor: v || '#22c55e' }); }, label: __('Correct Letter Color', 'blockenberg') },
174 { value: a.errorColor, onChange: function (v) { setAttributes({ errorColor: v || '#ef4444' }); }, label: __('Error Color', 'blockenberg') },
175 { value: a.sectionBg, onChange: function (v) { setAttributes({ sectionBg: v || '#f5f3ff' }); }, label: __('Section Background', 'blockenberg') },
176 { value: a.cardBg, onChange: function (v) { setAttributes({ cardBg: v || '#ffffff' }); }, label: __('Card Background', 'blockenberg') },
177 { value: a.textAreaBg, onChange: function (v) { setAttributes({ textAreaBg: v || '#1e1b4b' }); }, label: __('Text Area Background', 'blockenberg') },
178 { value: a.textAreaColor, onChange: function (v) { setAttributes({ textAreaColor: v || '#c4b5fd' }); }, label: __('Text Area Text', 'blockenberg') },
179 { value: a.titleColor, onChange: function (v) { setAttributes({ titleColor: v || '#4c1d95' }); }, label: __('Title Color', 'blockenberg') },
180 { value: a.subtitleColor, onChange: function (v) { setAttributes({ subtitleColor: v || '#6b7280' }); }, label: __('Subtitle Color', 'blockenberg') },
181 { value: a.labelColor, onChange: function (v) { setAttributes({ labelColor: v || '#374151' }); }, label: __('Label Color', 'blockenberg') }
182 ]
183 }
184 )
185 ),
186 el(
187 'div',
188 blockProps,
189 el(
190 'div',
191 { style: containerStyle },
192 a.showTitle && el('div', { className: 'bkbg-tst-title', style: { color: a.titleColor } }, a.title),
193 a.showSubtitle && el('div', { className: 'bkbg-tst-subtitle', style: { color: a.subtitleColor } }, a.subtitle),
194
195 // Stats bar
196 el('div', { style: Object.assign({}, cardStyle, { display: 'flex', gap: '12px', justifyContent: 'space-between', flexWrap: 'wrap' }) },
197 [
198 { label: 'Time', value: a.duration + 's' },
199 a.showLiveWpm && { label: 'WPM', value: '' },
200 a.showAccuracy && { label: 'Accuracy', value: '' },
201 a.showErrors && { label: 'Errors', value: '' }
202 ].filter(Boolean).map(function (s, i) {
203 return el('div', { key: i, style: statBoxStyle },
204 el('div', { style: { fontSize: '28px', fontWeight: '700', color: a.accentColor } }, s.value),
205 el('div', { style: { fontSize: '12px', color: a.subtitleColor, marginTop: '2px' } }, s.label)
206 );
207 })
208 ),
209
210 // Difficulty buttons
211 a.showDifficultyBtn && el('div', { style: { display: 'flex', gap: '8px', marginBottom: '14px', flexWrap: 'wrap' } },
212 ['easy', 'medium', 'hard'].map(function (d) {
213 var active = d === a.defaultDifficulty;
214 return el('button', {
215 key: d,
216 style: {
217 background: active ? a.accentColor : '#e5e7eb',
218 color: active ? '#fff' : '#374151',
219 border: 'none', borderRadius: '6px', padding: '6px 16px',
220 cursor: 'pointer', fontSize: '13px', fontWeight: '600', textTransform: 'capitalize'
221 }
222 }, d.charAt(0).toUpperCase() + d.slice(1));
223 })
224 ),
225
226 // Text display area
227 el('div', { style: Object.assign({}, cardStyle, { background: a.textAreaBg, fontFamily: 'monospace', fontSize: '17px', lineHeight: '1.9', color: a.textAreaColor, letterSpacing: '0.02em', minHeight: '100px', padding: '20px' }) },
228 SAMPLE_TEXT
229 ),
230
231 // Input area
232 el('textarea', {
233 placeholder: 'Click here and start typing...',
234 disabled: true,
235 style: {
236 width: '100%', borderRadius: '8px', padding: '14px',
237 fontSize: '15px', border: '2px solid ' + a.accentColor,
238 background: a.cardBg, color: a.labelColor,
239 resize: 'none', height: '80px', fontFamily: 'monospace',
240 boxSizing: 'border-box', marginTop: '4px'
241 }
242 }),
243
244 el('div', { style: { display: 'flex', justifyContent: 'center', marginTop: '14px' } },
245 el('button', { style: btnStyle }, '▶ Start Test')
246 )
247 )
248 )
249 );
250 },
251 save: function (props) {
252 var a = props.attributes;
253 var blockProps = wp.blockEditor.useBlockProps.save((function () { var _tv = getTypoCssVars(a); var s = {}; Object.assign(s, _tv); return { style: s }; })());
254 return el('div', blockProps,
255 el('div', { className: 'bkbg-tst-app', 'data-opts': JSON.stringify(a) })
256 );
257 }
258 });
259 }() );
260