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

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

281 lines 16.1 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 SelectControl = wp.components.SelectControl;
13 var TextControl = wp.components.TextControl;
14 var ToggleControl = wp.components.ToggleControl;
15 var Button = wp.components.Button;
16
17 var _flTC, _flTV;
18 function _tc() { return _flTC || (_flTC = window.bkbgTypographyControl); }
19 function _tv() { return _flTV || (_flTV = window.bkbgTypoCssVars); }
20
21 var DEFAULT_CARDS = [
22 { id: '1', front: 'What is the capital of France?', back: 'Paris', known: false },
23 { id: '2', front: 'What is 7 × 8?', back: '56', known: false },
24 { id: '3', front: 'Who wrote Romeo and Juliet?', back: 'William Shakespeare', known: false },
25 { id: '4', front: 'What is H₂O?', back: 'Water', known: false },
26 { id: '5', front: 'What year did WWII end?', back: '1945', known: false }
27 ];
28
29 registerBlockType('blockenberg/flashcard', {
30 edit: function (props) {
31 var a = props.attributes;
32 var setAttributes = props.setAttributes;
33 var wrapStyle = Object.assign({},
34 _tv()(a.typoTitle, '--bkbg-flash-tt-'),
35 _tv()(a.typoSubtitle, '--bkbg-flash-ts-'),
36 _tv()(a.typoCard, '--bkbg-flash-tc-')
37 );
38 var blockProps = useBlockProps({ className: 'bkbg-fc-editor-wrap', style: wrapStyle });
39
40 var cards;
41 try { cards = JSON.parse(a.cards); } catch (e) { cards = DEFAULT_CARDS; }
42
43 var containerStyle = {
44 background: a.sectionBg,
45 borderRadius: '12px',
46 padding: '28px',
47 maxWidth: a.contentMaxWidth + 'px',
48 margin: '0 auto'
49 };
50
51 var cardPreviewStyle = {
52 background: a.cardFrontBg,
53 borderRadius: '12px',
54 height: a.cardHeight + 'px',
55 display: 'flex',
56 alignItems: 'center',
57 justifyContent: 'center',
58 textAlign: 'center',
59 padding: '24px',
60 boxShadow: '0 8px 32px rgba(99,102,241,0.15)',
61 color: a.labelColor,
62 cursor: 'pointer',
63 position: 'relative'
64 };
65
66 function addCard() {
67 var newCards = cards.concat([{ id: Date.now().toString(), front: 'New question', back: 'Answer', known: false }]);
68 setAttributes({ cards: JSON.stringify(newCards) });
69 }
70
71 function removeCard(id) {
72 setAttributes({ cards: JSON.stringify(cards.filter(function (c) { return c.id !== id; })) });
73 }
74
75 function updateCard(id, field, value) {
76 var updated = cards.map(function (c) {
77 if (c.id !== id) return c;
78 var n = {}; Object.keys(c).forEach(function (k) { n[k] = c[k]; }); n[field] = value; return n;
79 });
80 setAttributes({ cards: JSON.stringify(updated) });
81 }
82
83 return el(
84 Fragment,
85 null,
86 el(
87 InspectorControls,
88 null,
89 el(
90 PanelBody,
91 { title: __('Content', 'blockenberg'), initialOpen: true },
92 el(TextControl, {
93 label: __('Title', 'blockenberg'),
94 value: a.title,
95 onChange: function (v) { setAttributes({ title: v }); }
96 }),
97 el(TextControl, {
98 label: __('Subtitle', 'blockenberg'),
99 value: a.subtitle,
100 onChange: function (v) { setAttributes({ subtitle: v }); }
101 }),
102 el(ToggleControl, {
103 label: __('Show Title', 'blockenberg'),
104 checked: a.showTitle,
105 onChange: function (v) { setAttributes({ showTitle: v }); },
106 __nextHasNoMarginBottom: true
107 }),
108 el(ToggleControl, {
109 label: __('Show Subtitle', 'blockenberg'),
110 checked: a.showSubtitle,
111 onChange: function (v) { setAttributes({ showSubtitle: v }); },
112 __nextHasNoMarginBottom: true
113 })
114 ),
115 el(
116 PanelBody,
117 { title: __('Cards', 'blockenberg'), initialOpen: true },
118 cards.map(function (card) {
119 return el(
120 'div',
121 { key: card.id, style: { background: '#f9f9f9', borderRadius: '8px', padding: '12px', marginBottom: '10px', border: '1px solid #e5e7eb' } },
122 el(TextControl, {
123 label: __('Front', 'blockenberg'),
124 value: card.front,
125 onChange: function (v) { updateCard(card.id, 'front', v); }
126 }),
127 el(TextControl, {
128 label: __('Back', 'blockenberg'),
129 value: card.back,
130 onChange: function (v) { updateCard(card.id, 'back', v); }
131 }),
132 el(
133 'button',
134 {
135 style: { background: '#fee2e2', color: '#991b1b', border: 'none', borderRadius: '4px', padding: '4px 10px', cursor: 'pointer', fontSize: '12px' },
136 onClick: function () { removeCard(card.id); }
137 },
138 __('Remove', 'blockenberg')
139 )
140 );
141 }),
142 el(
143 'button',
144 {
145 style: { background: a.accentColor, color: '#fff', border: 'none', borderRadius: '6px', padding: '8px 16px', cursor: 'pointer', width: '100%', fontWeight: '600' },
146 onClick: addCard
147 },
148 __('+ Add Card', 'blockenberg')
149 )
150 ),
151 el(
152 PanelBody,
153 { title: __('Options', 'blockenberg'), initialOpen: false },
154 el(ToggleControl, {
155 label: __('Show Progress Bar', 'blockenberg'),
156 checked: a.showProgress,
157 onChange: function (v) { setAttributes({ showProgress: v }); },
158 __nextHasNoMarginBottom: true
159 }),
160 el(ToggleControl, {
161 label: __('Show Shuffle Button', 'blockenberg'),
162 checked: a.showShuffleBtn,
163 onChange: function (v) { setAttributes({ showShuffleBtn: v }); },
164 __nextHasNoMarginBottom: true
165 }),
166 el(ToggleControl, {
167 label: __('Show "Mark Known" Button', 'blockenberg'),
168 checked: a.showKnownBtn,
169 onChange: function (v) { setAttributes({ showKnownBtn: v }); },
170 __nextHasNoMarginBottom: true
171 }),
172 el(ToggleControl, {
173 label: __('Show Keyboard Hint', 'blockenberg'),
174 checked: a.showKeyboardHint,
175 onChange: function (v) { setAttributes({ showKeyboardHint: v }); },
176 __nextHasNoMarginBottom: true
177 }),
178 el(RangeControl, {
179 label: __('Card Height (px)', 'blockenberg'),
180 value: a.cardHeight,
181 min: 120,
182 max: 500,
183 onChange: function (v) { setAttributes({ cardHeight: v }); }
184 })
185 ),
186 el(
187 PanelBody,
188 { title: __('Typography', 'blockenberg'), initialOpen: false },
189 _tc() && _tc()({ label: __('Title', 'blockenberg'), typo: a.typoTitle, onChange: function (v) { setAttributes({ typoTitle: v }); } }),
190 _tc() && _tc()({ label: __('Subtitle', 'blockenberg'), typo: a.typoSubtitle, onChange: function (v) { setAttributes({ typoSubtitle: v }); } }),
191 _tc() && _tc()({ label: __('Card Text', 'blockenberg'), typo: a.typoCard, onChange: function (v) { setAttributes({ typoCard: v }); } })
192 ),
193 el(
194 PanelBody,
195 { title: __('Appearance', 'blockenberg'), initialOpen: false },
196 el(RangeControl, {
197 label: __('Max Width (px)', 'blockenberg'),
198 value: a.contentMaxWidth,
199 min: 320,
200 max: 1200,
201 onChange: function (v) { setAttributes({ contentMaxWidth: v }); }
202 })
203 ),
204 el(
205 PanelColorSettings,
206 {
207 title: __('Colors', 'blockenberg'),
208 initialOpen: false,
209 colorSettings: [
210 { value: a.accentColor, onChange: function (v) { setAttributes({ accentColor: v || '#6366f1' }); }, label: __('Accent Color', 'blockenberg') },
211 { value: a.cardFrontBg, onChange: function (v) { setAttributes({ cardFrontBg: v || '#ffffff' }); }, label: __('Card Front Background', 'blockenberg') },
212 { value: a.cardBackBg, onChange: function (v) { setAttributes({ cardBackBg: v || '#4f46e5' }); }, label: __('Card Back Background', 'blockenberg') },
213 { value: a.cardBackColor, onChange: function (v) { setAttributes({ cardBackColor: v || '#ffffff' }); }, label: __('Card Back Text', 'blockenberg') },
214 { value: a.knownColor, onChange: function (v) { setAttributes({ knownColor: v || '#22c55e' }); }, label: __('Known Color', 'blockenberg') },
215 { value: a.sectionBg, onChange: function (v) { setAttributes({ sectionBg: v || '#f5f3ff' }); }, label: __('Section Background', 'blockenberg') },
216 { value: a.cardBg, onChange: function (v) { setAttributes({ cardBg: v || '#ffffff' }); }, label: __('Controls Background', 'blockenberg') },
217 { value: a.titleColor, onChange: function (v) { setAttributes({ titleColor: v || '#3730a3' }); }, label: __('Title Color', 'blockenberg') },
218 { value: a.subtitleColor, onChange: function (v) { setAttributes({ subtitleColor: v || '#6b7280' }); }, label: __('Subtitle Color', 'blockenberg') },
219 { value: a.labelColor, onChange: function (v) { setAttributes({ labelColor: v || '#374151' }); }, label: __('Label Color', 'blockenberg') }
220 ]
221 }
222 )
223 ),
224 el(
225 'div',
226 blockProps,
227 el(
228 'div',
229 { style: containerStyle },
230 a.showTitle && el('div', {
231 className: 'bkbg-fc-title',
232 style: { color: a.titleColor, marginBottom: '6px' }
233 }, a.title),
234 a.showSubtitle && el('div', {
235 className: 'bkbg-fc-subtitle',
236 style: { color: a.subtitleColor, marginBottom: '20px' }
237 }, a.subtitle),
238 a.showProgress && el('div', {
239 style: { marginBottom: '16px' }
240 },
241 el('div', { style: { display: 'flex', justifyContent: 'space-between', fontSize: '13px', color: a.labelColor, marginBottom: '6px' } },
242 el('span', null, __('Progress', 'blockenberg')),
243 el('span', null, '0 / ' + cards.length + ' known')
244 ),
245 el('div', { style: { height: '8px', background: '#e5e7eb', borderRadius: '4px' } },
246 el('div', { style: { height: '100%', width: '0%', background: a.accentColor, borderRadius: '4px' } })
247 )
248 ),
249 el('div', { className: 'bkbg-fc-front', style: cardPreviewStyle },
250 el('span', null, cards[0] ? cards[0].front : 'No cards yet')
251 ),
252 el('div', { style: { display: 'flex', justifyContent: 'center', gap: '12px', marginTop: '16px', flexWrap: 'wrap' } },
253 el('button', { style: { background: '#e5e7eb', color: '#374151', border: 'none', borderRadius: '8px', padding: '10px 20px', cursor: 'pointer', fontSize: '20px' } }, ''),
254 a.showKnownBtn && el('button', { style: { background: a.knownColor, color: '#fff', border: 'none', borderRadius: '8px', padding: '10px 18px', cursor: 'pointer', fontWeight: '600' } }, '✓ Know it'),
255 el('button', { style: { background: '#e5e7eb', color: '#374151', border: 'none', borderRadius: '8px', padding: '10px 20px', cursor: 'pointer', fontSize: '20px' } }, '')
256 ),
257 el('div', { style: { textAlign: 'center', marginTop: '10px', display: 'flex', gap: '10px', justifyContent: 'center', flexWrap: 'wrap' } },
258 el('span', { style: { color: a.subtitleColor, fontSize: '13px' } }, '1 / ' + cards.length),
259 a.showShuffleBtn && el('button', { style: { background: 'transparent', border: '1px solid ' + a.accentColor, color: a.accentColor, borderRadius: '6px', padding: '4px 12px', cursor: 'pointer', fontSize: '12px' } }, '⇌ Shuffle'),
260 el('button', { style: { background: 'transparent', border: '1px solid #e5e7eb', color: a.subtitleColor, borderRadius: '6px', padding: '4px 12px', cursor: 'pointer', fontSize: '12px' } }, '↺ Reset')
261 ),
262 a.showKeyboardHint && el('div', { style: { textAlign: 'center', marginTop: '12px', color: a.subtitleColor, fontSize: '12px' } },
263 '← → Arrow keys to navigate • Space to flip'
264 )
265 )
266 )
267 );
268 },
269 save: function (props) {
270 var a = props.attributes;
271 var blockProps = wp.blockEditor.useBlockProps.save();
272 return el('div', blockProps,
273 el('div', {
274 className: 'bkbg-fc-app',
275 'data-opts': JSON.stringify(a)
276 })
277 );
278 }
279 });
280 }() );
281