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 / split-flap-display / index.js

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

232 lines 14.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 __ = wp.i18n.__;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
7 var PanelBody = wp.components.PanelBody;
8 var TextControl = wp.components.TextControl;
9 var ToggleControl = wp.components.ToggleControl;
10 var SelectControl = wp.components.SelectControl;
11 var RangeControl = wp.components.RangeControl;
12 var Button = wp.components.Button;
13
14 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
15 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
16
17 var CHAR_SETS = [
18 { label: 'Alpha (A–Z + space)', value: 'alpha' },
19 { label: 'Alphanumeric (A–Z, 0–9)', value: 'alnum' },
20 { label: 'Full (A–Z, 0–9, symbols)', value: 'full' },
21 { label: 'Numeric only (0–9)', value: 'numeric' }
22 ];
23
24 var FONTS = [
25 { label: 'Monospace', value: 'mono' },
26 { label: 'Sans-serif', value: 'sans' },
27 { label: 'Slab Serif', value: 'slab' }
28 ];
29
30 var FONT_FAMILIES = {
31 mono: '"Courier New", "Lucida Console", monospace',
32 sans: '"Arial", "Helvetica Neue", sans-serif',
33 slab: '"Rockwell", "Georgia", serif'
34 };
35
36 // Build a static flap-board preview using pure HTML elements
37 function BoardPreview(props) {
38 var attr = props.attr;
39 var text = attr.messages && attr.messages.length ? attr.messages[0] : 'DEPARTURES';
40 var chars = text.split('');
41 var font = FONT_FAMILIES[attr.fontFamily || 'mono'];
42
43 var boardStyle = {
44 backgroundColor: attr.boardBg,
45 borderRadius: attr.boardRadius + 'px',
46 padding: attr.boardPadding + 'px',
47 display: 'inline-block',
48 maxWidth: '100%',
49 overflow: 'hidden'
50 };
51
52 if (attr.showLabel) {
53 boardStyle.paddingTop = (attr.boardPadding / 2) + 'px';
54 }
55
56 return el('div', { style: { textAlign: 'center' } },
57 el('div', { style: boardStyle },
58 attr.showLabel && el('div', {
59 className: 'bkbg-sfd-label',
60 style: {
61 color: attr.labelColor, marginBottom: '12px'
62 }
63 }, attr.label),
64 el('div', { style: { display: 'flex', flexWrap: 'wrap', gap: attr.charGap + 'px', justifyContent: 'center' } },
65 chars.map(function (ch, i) {
66 var isSpace = ch === ' ';
67 return el('div', {
68 key: i,
69 className: 'bkbg-sfd-char',
70 style: {
71 width: attr.charWidth + 'px',
72 height: attr.charHeight + 'px',
73 backgroundColor: isSpace ? 'transparent' : attr.charBg,
74 borderRadius: attr.borderRadius + 'px',
75 display: 'flex', alignItems: 'center', justifyContent: 'center',
76 color: attr.charColor,
77 position: 'relative', overflow: 'hidden',
78 boxShadow: attr.glowColor ? '0 0 12px ' + attr.glowColor : '0 2px 8px rgba(0,0,0,0.5)'
79 }
80 },
81 !isSpace && el('div', {
82 style: {
83 position: 'absolute', left: 0, top: '50%', width: '100%',
84 height: '1px', background: attr.dividerColor, zIndex: 2
85 }
86 }),
87 el('span', { className: 'bkbg-sfd-char-text', style: { position: 'relative', zIndex: 1 } }, isSpace ? '' : ch)
88 );
89 })
90 ),
91 attr.messages.length > 1 && el('div', {
92 style: {
93 display: 'flex', justifyContent: 'center', gap: '6px',
94 marginTop: '12px'
95 }
96 },
97 attr.messages.map(function (_, idx) {
98 return el('div', {
99 key: idx,
100 style: {
101 width: '6px', height: '6px', borderRadius: '50%',
102 background: idx === 0 ? attr.charColor : attr.labelColor,
103 opacity: idx === 0 ? 1 : 0.4
104 }
105 });
106 })
107 )
108 )
109 );
110 }
111
112 wp.blocks.registerBlockType('blockenberg/split-flap-display', {
113 title: 'Split-Flap Display',
114 icon: 'editor-table',
115 category: 'bkbg-effects',
116 edit: function (props) {
117 var attr = props.attributes;
118 var setAttr = props.setAttributes;
119 var blockProps = useBlockProps({ style: (function () {
120 var s = {
121 '--bksfd-ch-font-family': FONT_FAMILIES[attr.fontFamily || 'mono'],
122 '--bksfd-ch-font-size-d': attr.fontSize + 'px',
123 '--bksfd-ch-font-weight': String(attr.fontWeight),
124 '--bksfd-lb-font-family': FONT_FAMILIES[attr.fontFamily || 'mono'],
125 };
126 var tv = getTypoCssVars();
127 if (tv) {
128 Object.assign(s, tv(attr.charTypo, '--bksfd-ch-'));
129 Object.assign(s, tv(attr.labelTypo, '--bksfd-lb-'));
130 }
131 return s;
132 })() });
133
134 function updateMessage(idx, val) {
135 var msgs = attr.messages.slice();
136 msgs[idx] = val;
137 setAttr({ messages: msgs });
138 }
139 function addMessage() {
140 setAttr({ messages: attr.messages.concat(['']) });
141 }
142 function removeMessage(idx) {
143 var msgs = attr.messages.slice();
144 msgs.splice(idx, 1);
145 setAttr({ messages: msgs });
146 }
147
148 return el('div', blockProps,
149 el(InspectorControls, {},
150 el(PanelBody, { title: __('Messages', 'blockenberg'), initialOpen: true },
151 attr.messages.map(function (msg, idx) {
152 return el('div', { key: idx, style: { display: 'flex', gap: '6px', alignItems: 'center', marginBottom: '8px' } },
153 el(TextControl, {
154 __nextHasNoMarginBottom: true,
155 label: __('Row ', 'blockenberg') + (idx + 1),
156 value: msg,
157 onChange: function (v) { updateMessage(idx, v.toUpperCase()); }
158 }),
159 attr.messages.length > 1 && el(Button, {
160 isDestructive: true,
161 isSmall: true,
162 onClick: function () { removeMessage(idx); }
163 }, '')
164 );
165 }),
166 el(Button, {
167 __nextHasNoMarginBottom: true,
168 isSecondary: true, isSmall: true,
169 onClick: addMessage
170 }, __('+ Add Message', 'blockenberg')),
171 el('p', { style: { color: '#888', fontSize: '12px', marginTop: '8px' } },
172 __('Characters are uppercased automatically.', 'blockenberg')
173 )
174 ),
175 el(PanelBody, { title: __('Character Set & Font', 'blockenberg'), initialOpen: false },
176 el(SelectControl, { __nextHasNoMarginBottom: true, label: __('Character Set', 'blockenberg'), value: attr.charSet, options: CHAR_SETS, onChange: function (v) { setAttr({ charSet: v }); } }),
177 el(SelectControl, { __nextHasNoMarginBottom: true, label: __('Font Style', 'blockenberg'), value: attr.fontFamily, options: FONTS, onChange: function (v) { setAttr({ fontFamily: v }); } }),
178 ),
179 el(PanelBody, { title: __('Animation', 'blockenberg'), initialOpen: false },
180 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Ticker Mode (cycle messages)', 'blockenberg'), checked: attr.tickerMode, onChange: function (v) { setAttr({ tickerMode: v }); } }),
181 attr.tickerMode && el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Ticker Delay (ms)', 'blockenberg'), value: attr.tickerDelay, min: 1000, max: 10000, step: 500, onChange: function (v) { setAttr({ tickerDelay: v }); } }),
182 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Animate on Scroll Into View', 'blockenberg'), checked: attr.flipOnScroll, onChange: function (v) { setAttr({ flipOnScroll: v }); } }),
183 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Auto-Play on Load', 'blockenberg'), checked: attr.autoPlay, onChange: function (v) { setAttr({ autoPlay: v }); } }),
184 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Flip Speed (ms/step)', 'blockenberg'), value: attr.flipSpeed, min: 20, max: 200, onChange: function (v) { setAttr({ flipSpeed: v }); } }),
185 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Character Stagger (ms)', 'blockenberg'), value: attr.flipStagger, min: 0, max: 200, onChange: function (v) { setAttr({ flipStagger: v }); } })
186 ),
187 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: false },
188 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Char Width (px)', 'blockenberg'), value: attr.charWidth, min: 20, max: 120, onChange: function (v) { setAttr({ charWidth: v }); } }),
189 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Char Height (px)', 'blockenberg'), value: attr.charHeight, min: 30, max: 160, onChange: function (v) { setAttr({ charHeight: v }); } }),
190 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Char Gap (px)', 'blockenberg'), value: attr.charGap, min: 0, max: 20, onChange: function (v) { setAttr({ charGap: v }); } }),
191 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Row Gap (px)', 'blockenberg'), value: attr.rowGap, min: 0, max: 40, onChange: function (v) { setAttr({ rowGap: v }); } }),
192 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Char Border Radius', 'blockenberg'), value: attr.borderRadius, min: 0, max: 20, onChange: function (v) { setAttr({ borderRadius: v }); } }),
193 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Board Padding (px)', 'blockenberg'), value: attr.boardPadding, min: 8, max: 60, onChange: function (v) { setAttr({ boardPadding: v }); } }),
194 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Board Border Radius', 'blockenberg'), value: attr.boardRadius, min: 0, max: 40, onChange: function (v) { setAttr({ boardRadius: v }); } })
195 ),
196 el(PanelBody, { title: __('Label', 'blockenberg'), initialOpen: false },
197 el(ToggleControl, { __nextHasNoMarginBottom: true, label: __('Show Board Label', 'blockenberg'), checked: attr.showLabel, onChange: function (v) { setAttr({ showLabel: v }); } }),
198 attr.showLabel && el(TextControl, { __nextHasNoMarginBottom: true, label: __('Label Text', 'blockenberg'), value: attr.label, onChange: function (v) { setAttr({ label: v }); } })
199 ),
200
201 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
202 getTypoControl() ? el(getTypoControl(), { label: __('Character Typography', 'blockenberg'), value: attr.charTypo || {}, onChange: function (v) { setAttr({ charTypo: v }); } }) : null,
203 getTypoControl() ? el(getTypoControl(), { label: __('Label Typography', 'blockenberg'), value: attr.labelTypo || {}, onChange: function (v) { setAttr({ labelTypo: v }); } }) : null
204 ),
205 el(PanelColorSettings, {
206 title: __('Colors', 'blockenberg'),
207 initialOpen: false,
208 colorSettings: [
209 { label: __('Board Background', 'blockenberg'), value: attr.boardBg, onChange: function (v) { setAttr({ boardBg: v || '' }); } },
210 { label: __('Character Background', 'blockenberg'), value: attr.charBg, onChange: function (v) { setAttr({ charBg: v || '' }); } },
211 { label: __('Character Color', 'blockenberg'), value: attr.charColor, onChange: function (v) { setAttr({ charColor: v || '' }); } },
212 { label: __('Divider Line', 'blockenberg'), value: attr.dividerColor, onChange: function (v) { setAttr({ dividerColor: v || '' }); } },
213 { label: __('Label Color', 'blockenberg'), value: attr.labelColor, onChange: function (v) { setAttr({ labelColor: v || '' }); } },
214 { label: __('Glow Color', 'blockenberg'), value: attr.glowColor, onChange: function (v) { setAttr({ glowColor: v || '' }); } }
215 ]
216 })
217 ),
218 el(BoardPreview, { attr: attr })
219 );
220 },
221 save: function (props) {
222 var attr = props.attributes;
223 return el('div', useBlockProps.save(),
224 el('div', {
225 className: 'bkbg-sfd-app',
226 'data-opts': JSON.stringify(attr)
227 })
228 );
229 }
230 });
231 }() );
232