PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / memory-game / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/memory-game/index.js

212 lines 12.5 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 ToggleControl = wp.components.ToggleControl;
14 var SelectControl = wp.components.SelectControl;
15 var TextControl = wp.components.TextControl;
16
17 var _tc, _tv;
18 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
19 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
20
21 var THEMES = {
22 animals: ['🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🐨','🐯','🦁','🐸'],
23 food: ['🍕','🍔','🍟','🌮','🌯','🍜','🍣','🍩','🍪','🎂','🍦','🍫'],
24 nature: ['🌸','🌺','🌻','🌹','🌷','🍀','🍁','🍂','🌿','🎋','🌵','🌴'],
25 space: ['🚀','🌍','🌙','','☀️','🪐','🌟','💫','🌌','🔭','👨‍🚀','🛸'],
26 sports: ['','🏀','🏈','','🎾','🏐','🏉','🎱','🏓','🏸','🥊','🎯'],
27 symbols: ['❤️','','🔥','💎','🎵','🌈','💡','🔑','🎭','🎨','🎪','🎲']
28 };
29
30 var GRID_SIZES = { easy: 4, medium: 4, hard: 6 };
31 var PAIR_COUNTS = { easy: 6, medium: 8, hard: 12 };
32
33 function EditorPreview(props) {
34 var a = props.attributes;
35 var pairs = PAIR_COUNTS[a.defaultDifficulty] || 8;
36 var gridCols = GRID_SIZES[a.defaultDifficulty] || 4;
37 var icons = (THEMES[a.defaultTheme] || THEMES.animals).slice(0, pairs);
38 var cards = icons.concat(icons).sort(function () { return Math.random() - 0.5; });
39
40 var cellSize = Math.min(70, Math.floor(((a.contentMaxWidth || 620) - 48) / gridCols - 8));
41
42 return el('div', {
43 style: {
44 background: a.sectionBg, borderRadius: '16px', padding: '28px 20px',
45 maxWidth: a.contentMaxWidth + 'px', margin: '0 auto', fontFamily: 'inherit', boxSizing: 'border-box'
46 }
47 },
48 a.showTitle && el(RichText, {
49 tagName: 'h3', className: 'bkbg-mem-title', value: a.title,
50 onChange: function (v) { props.setAttributes({ title: v }); },
51 style: { color: a.titleColor, textAlign: 'center' },
52 placeholder: 'Title…'
53 }),
54 a.showSubtitle && el(RichText, {
55 tagName: 'p', className: 'bkbg-mem-subtitle', value: a.subtitle,
56 onChange: function (v) { props.setAttributes({ subtitle: v }); },
57 style: { color: a.subtitleColor, textAlign: 'center' },
58 placeholder: 'Subtitle…'
59 }),
60
61 /* Stats bar */
62 el('div', { style: { display: 'flex', justifyContent: 'center', gap: '20px', marginBottom: '16px', flexWrap: 'wrap' } },
63 a.showTimer && el('div', { style: { background: a.cardBg, borderRadius: '8px', padding: '8px 16px', textAlign: 'center', boxShadow: '0 1px 4px rgba(0,0,0,0.08)' } },
64 el('div', { style: { fontSize: '20px', fontWeight: '800', color: a.accentColor } }, '0:00'),
65 el('div', { style: { fontSize: '11px', color: a.subtitleColor } }, 'Time')
66 ),
67 a.showMoves && el('div', { style: { background: a.cardBg, borderRadius: '8px', padding: '8px 16px', textAlign: 'center', boxShadow: '0 1px 4px rgba(0,0,0,0.08)' } },
68 el('div', { style: { fontSize: '20px', fontWeight: '800', color: a.accentColor } }, '0'),
69 el('div', { style: { fontSize: '11px', color: a.subtitleColor } }, 'Moves')
70 ),
71 a.showBestScore && el('div', { style: { background: a.cardBg, borderRadius: '8px', padding: '8px 16px', textAlign: 'center', boxShadow: '0 1px 4px rgba(0,0,0,0.08)' } },
72 el('div', { style: { fontSize: '20px', fontWeight: '800', color: a.accentColor } }, ''),
73 el('div', { style: { fontSize: '11px', color: a.subtitleColor } }, 'Best')
74 )
75 ),
76
77 /* Card grid */
78 el('div', {
79 style: {
80 display: 'grid',
81 gridTemplateColumns: 'repeat(' + gridCols + ', 1fr)',
82 gap: '8px',
83 marginBottom: '16px'
84 }
85 },
86 cards.map(function (icon, i) {
87 var isFlipped = i < 3;
88 return el('div', {
89 key: i,
90 style: {
91 height: cellSize + 'px', borderRadius: '10px', display: 'flex',
92 alignItems: 'center', justifyContent: 'center', fontSize: cellSize * 0.45 + 'px',
93 background: isFlipped ? a.cardFront : a.cardBack,
94 cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
95 border: isFlipped ? '2px solid ' + a.accentColor + '44' : 'none',
96 transition: 'transform 0.3s'
97 }
98 }, isFlipped ? icon : '?')
99 })
100 ),
101
102 /* Start button */
103 el('div', { style: { textAlign: 'center' } },
104 el('button', {
105 style: {
106 background: a.accentColor, color: '#fff', border: 'none',
107 borderRadius: '10px', padding: '12px 32px', fontSize: '16px',
108 fontWeight: '700', cursor: 'pointer'
109 }
110 }, '▶ Start Game')
111 )
112 );
113 }
114
115 registerBlockType('blockenberg/memory-game', {
116 edit: function (props) {
117 var a = props.attributes;
118 var set = props.setAttributes;
119 var blockProps = (function(p){
120 var v = getTypoCssVars() || function () { return {}; };
121 p.style = Object.assign(p.style||{},
122 v(a.titleTypo,'--bkbg-mem-tt-'),
123 v(a.subtitleTypo,'--bkbg-mem-st-')
124 ); return p;
125 })(useBlockProps({ className: 'bkbg-mem-root' }));
126
127 return el(Fragment, null,
128 el(InspectorControls, null,
129 el(PanelBody, { title: 'Content', initialOpen: true },
130 el(ToggleControl, { label: 'Show Title', checked: a.showTitle, onChange: function (v) { set({ showTitle: v }); }, __nextHasNoMarginBottom: true }),
131 el(ToggleControl, { label: 'Show Subtitle', checked: a.showSubtitle, onChange: function (v) { set({ showSubtitle: v }); }, __nextHasNoMarginBottom: true })
132 ),
133 el(PanelBody, { title: 'Game Settings', initialOpen: false },
134 el(SelectControl, {
135 label: 'Default Difficulty',
136 value: a.defaultDifficulty,
137 options: [
138 { label: 'Easy (6 pairs, 4×3)', value: 'easy' },
139 { label: 'Medium (8 pairs, 4×4)', value: 'medium' },
140 { label: 'Hard (12 pairs, 6×4)', value: 'hard' }
141 ],
142 onChange: function (v) { set({ defaultDifficulty: v }); },
143 __nextHasNoMarginBottom: true
144 }),
145 el('div', { style: { marginBottom: '16px' } }),
146 el(SelectControl, {
147 label: 'Card Theme',
148 value: a.defaultTheme,
149 options: [
150 { label: 'Animals 🐶', value: 'animals' },
151 { label: 'Food 🍕', value: 'food' },
152 { label: 'Nature 🌸', value: 'nature' },
153 { label: 'Space 🚀', value: 'space' },
154 { label: 'Sports ⚽', value: 'sports' },
155 { label: 'Symbols ❤️', value: 'symbols' }
156 ],
157 onChange: function (v) { set({ defaultTheme: v }); },
158 __nextHasNoMarginBottom: true
159 }),
160 el('div', { style: { marginBottom: '16px' } }),
161 el(RangeControl, {
162 label: 'Flip Delay (ms)',
163 value: a.flipDelay, min: 400, max: 2000, step: 100,
164 onChange: function (v) { set({ flipDelay: v }); },
165 __nextHasNoMarginBottom: true
166 }),
167 el('div', { style: { marginBottom: '16px' } }),
168 el(ToggleControl, { label: 'Show Timer', checked: a.showTimer, onChange: function (v) { set({ showTimer: v }); }, __nextHasNoMarginBottom: true }),
169 el(ToggleControl, { label: 'Show Move Counter', checked: a.showMoves, onChange: function (v) { set({ showMoves: v }); }, __nextHasNoMarginBottom: true }),
170 el(ToggleControl, { label: 'Show Best Score', checked: a.showBestScore, onChange: function (v) { set({ showBestScore: v }); }, __nextHasNoMarginBottom: true }),
171 el('div', { style: { marginBottom: '16px' } }),
172 el(RangeControl, {
173 label: 'Max Width (px)', value: a.contentMaxWidth, min: 320, max: 900, step: 10,
174 onChange: function (v) { set({ contentMaxWidth: v }); }, __nextHasNoMarginBottom: true
175 })
176 ),
177 el(PanelBody, { title: 'Typography', initialOpen: false },
178 getTypoControl() && el(getTypoControl(), { label: 'Title', value: a.titleTypo || {}, onChange: function(v){ set({ titleTypo: v }); } }),
179 getTypoControl() && el(getTypoControl(), { label: 'Subtitle', value: a.subtitleTypo || {}, onChange: function(v){ set({ subtitleTypo: v }); } })
180 ),
181 el(PanelColorSettings, {
182 title: 'Colors', initialOpen: false,
183 colorSettings: [
184 { label: 'Accent Color', value: a.accentColor, onChange: function (v) { set({ accentColor: v || '#8b5cf6' }); } },
185 { label: 'Card Back', value: a.cardBack, onChange: function (v) { set({ cardBack: v || '#8b5cf6' }); } },
186 { label: 'Card Front', value: a.cardFront, onChange: function (v) { set({ cardFront: v || '#ffffff' }); } },
187 { label: 'Matched Card', value: a.cardMatched, onChange: function (v) { set({ cardMatched: v || '#22c55e' }); } },
188 { label: 'Section Background', value: a.sectionBg, onChange: function (v) { set({ sectionBg: v || '#f5f3ff' }); } },
189 { label: 'Card Background', value: a.cardBg, onChange: function (v) { set({ cardBg: v || '#ffffff' }); } },
190 { label: 'Title Color', value: a.titleColor, onChange: function (v) { set({ titleColor: v || '#4c1d95' }); } },
191 { label: 'Subtitle Color', value: a.subtitleColor, onChange: function (v) { set({ subtitleColor: v || '#6b7280' }); } }
192 ]
193 })
194 ),
195 el('div', blockProps, el(EditorPreview, { attributes: a, setAttributes: set }))
196 );
197 },
198 save: function (props) {
199 var a = props.attributes;
200 var ubp = wp.blockEditor.useBlockProps;
201 var v = (typeof window.bkbgTypoCssVars === 'function') ? window.bkbgTypoCssVars : function () { return {}; };
202 var s = Object.assign({},
203 v(a.titleTypo,'--bkbg-mem-tt-'),
204 v(a.subtitleTypo,'--bkbg-mem-st-')
205 );
206 return el('div', (function(p){p.style=Object.assign(p.style||{},s);return p;})(ubp.save()),
207 el('div', { className: 'bkbg-mem-app', 'data-opts': JSON.stringify(a) })
208 );
209 }
210 });
211 }() );
212