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

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

173 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 registerBlockType = wp.blocks.registerBlockType;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
7 var RichText = wp.blockEditor.RichText;
8 var PanelBody = wp.components.PanelBody;
9 var RangeControl = wp.components.RangeControl;
10 var ToggleControl = wp.components.ToggleControl;
11 var TextControl = wp.components.TextControl;
12 var SelectControl = wp.components.SelectControl;
13
14 var _tc, _tv;
15 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
16 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
17
18 registerBlockType('blockenberg/magnetic-button', {
19 edit: function (props) {
20 var a = props.attributes;
21 var set = props.setAttributes;
22 var blockProps = useBlockProps((function () {
23 var _tvFn = getTypoCssVars();
24 var s = { textAlign: a.align || 'center' };
25 if (_tvFn) Object.assign(s, _tvFn(a.textTypo, '--bkbg-mgb-tx-'));
26 return { style: s };
27 })());
28
29 var isOutline = a.buttonStyle === 'outline';
30 var isGhost = a.buttonStyle === 'ghost';
31
32 var btnStyle = {
33 display: 'inline-flex',
34 alignItems: 'center',
35 gap: 8,
36 padding: (a.paddingY || 18) + 'px ' + (a.paddingX || 40) + 'px',
37 borderRadius: (a.borderRadius || 999) + 'px',
38 cursor: 'pointer',
39 transition: 'background 0.2s, box-shadow 0.2s',
40 background: isOutline || isGhost ? 'transparent' : (a.btnBg || '#6366f1'),
41 color: isOutline || isGhost ? (a.btnBg || '#6366f1') : (a.btnColor || '#ffffff'),
42 border: isGhost ? 'none' : (a.borderWidth || 2) + 'px solid ' + (a.btnBorderColor || '#6366f1'),
43 boxShadow: isOutline || isGhost ? 'none' : '0 4px 20px ' + (a.shadowColor || 'rgba(99,102,241,0.4)'),
44 userSelect: 'none',
45 WebkitUserSelect: 'none',
46 flexDirection: 'column'
47 };
48
49 return el('div', blockProps,
50 el(InspectorControls, {},
51 el(PanelBody, { title: 'Button Content', initialOpen: true },
52 el(TextControl, { label: 'Sub-text (optional)', value: a.subtext || '',
53 onChange: function (v) { set({ subtext: v }); },
54 help: 'Smaller text shown below main label', __nextHasNoMarginBottom: true }),
55 el(TextControl, { label: 'Link URL', value: a.href || '',
56 onChange: function (v) { set({ href: v }); }, __nextHasNoMarginBottom: true }),
57 el(SelectControl, { label: 'Link target', value: a.target || '_self',
58 options: [{ label: 'Same tab', value: '_self' }, { label: 'New tab', value: '_blank' }],
59 onChange: function (v) { set({ target: v }); }, __nextHasNoMarginBottom: true }),
60 el(ToggleControl, { label: 'Show arrow icon', checked: a.showArrow === true,
61 onChange: function (v) { set({ showArrow: v }); }, __nextHasNoMarginBottom: true })
62 ),
63 el(PanelBody, { title: 'Magnetic Effect', initialOpen: false },
64 el(RangeControl, { label: 'Magnetic pull strength (px)', value: a.magnetStrength || 40,
65 onChange: function (v) { set({ magnetStrength: v }); }, min: 0, max: 100, __nextHasNoMarginBottom: true }),
66 el(RangeControl, { label: 'Activation radius (px)', value: a.magnetRadius || 120,
67 onChange: function (v) { set({ magnetRadius: v }); }, min: 40, max: 400, __nextHasNoMarginBottom: true }),
68 el(ToggleControl, { label: 'Click ripple effect', checked: a.ripple !== false,
69 onChange: function (v) { set({ ripple: v }); }, __nextHasNoMarginBottom: true })
70 ),
71 el(PanelBody, { title: 'Style', initialOpen: false },
72 el(SelectControl, { label: 'Button style', value: a.buttonStyle || 'filled',
73 options: [
74 { label: 'Filled', value: 'filled' },
75 { label: 'Outline', value: 'outline' },
76 { label: 'Ghost (no border)', value: 'ghost' }
77 ],
78 onChange: function (v) { set({ buttonStyle: v }); }, __nextHasNoMarginBottom: true }),
79 el(SelectControl, { label: 'Alignment', value: a.align || 'center',
80 options: [
81 { label: 'Left', value: 'left' },
82 { label: 'Center', value: 'center' },
83 { label: 'Right', value: 'right' }
84 ],
85 onChange: function (v) { set({ align: v }); }, __nextHasNoMarginBottom: true }),
86 el(RangeControl, { label: 'Padding horizontal', value: a.paddingX || 40,
87 onChange: function (v) { set({ paddingX: v }); }, min: 12, max: 100, __nextHasNoMarginBottom: true }),
88 el(RangeControl, { label: 'Padding vertical', value: a.paddingY || 18,
89 onChange: function (v) { set({ paddingY: v }); }, min: 6, max: 60, __nextHasNoMarginBottom: true }),
90 el(RangeControl, { label: 'Border radius', value: a.borderRadius || 999,
91 onChange: function (v) { set({ borderRadius: v }); }, min: 0, max: 999, __nextHasNoMarginBottom: true }),
92 el(RangeControl, { label: 'Border width (px)', value: a.borderWidth || 2,
93 onChange: function (v) { set({ borderWidth: v }); }, min: 0, max: 8, __nextHasNoMarginBottom: true })
94 ),
95
96 el( PanelBody, { title: 'Typography', initialOpen: false },
97 (function () { var C = getTypoControl(); return C ? el(C, { label: 'Button Text', value: a.textTypo, onChange: function (v) { set({ textTypo: v }); } }) : null; })()
98 ),
99 el(PanelColorSettings, {
100 title: 'Colors', initialOpen: false,
101 colorSettings: [
102 { label: 'Button background', value: a.btnBg, onChange: function (v) { set({ btnBg: v || '#6366f1' }); } },
103 { label: 'Button text', value: a.btnColor, onChange: function (v) { set({ btnColor: v || '#ffffff' }); } },
104 { label: 'Border color', value: a.btnBorderColor,onChange: function (v) { set({ btnBorderColor:v || '#6366f1' }); } },
105 { label: 'Hover background', value: a.hoverBg, onChange: function (v) { set({ hoverBg: v || '#4f46e5' }); } },
106 { label: 'Hover text', value: a.hoverColor, onChange: function (v) { set({ hoverColor: v || '#ffffff' }); } },
107 { label: 'Ripple color', value: a.rippleColor, onChange: function (v) { set({ rippleColor: v || 'rgba(255,255,255,0.35)' }); } },
108 { label: 'Shadow / glow', value: a.shadowColor, onChange: function (v) { set({ shadowColor: v || 'rgba(99,102,241,0.4)' }); } }
109 ],
110 disableCustomGradients: true
111 })
112 ),
113
114 // Editor preview
115 el('div', { style: { textAlign: a.align || 'center' } },
116 el('div', { className: 'bkbg-mgb-btn', style: btnStyle },
117 el(RichText, {
118 tagName: 'span', value: a.text,
119 onChange: function (v) { set({ text: v }); },
120 placeholder: 'Button text…',
121 className: 'bkbg-mgb-text'
122 }),
123 a.subtext && el('span', { className: 'bkbg-mgb-sub' }, a.subtext),
124 a.showArrow && el('span', { className: 'bkbg-mgb-arrow' }, '')
125 )
126 )
127 );
128 },
129
130 save: function (props) {
131 var a = props.attributes;
132 var _tvFn = getTypoCssVars();
133 var blockProps = useBlockProps.save((function () {
134 var s = { textAlign: a.align || 'center' };
135 if (_tvFn) Object.assign(s, _tvFn(a.textTypo, '--bkbg-mgb-tx-'));
136 return { style: s };
137 })());
138 var opts = {
139 magnetStrength: a.magnetStrength || 40,
140 magnetRadius: a.magnetRadius || 120,
141 ripple: a.ripple !== false,
142 btnBg: a.btnBg || '#6366f1',
143 btnColor: a.btnColor || '#ffffff',
144 hoverBg: a.hoverBg || '#4f46e5',
145 hoverColor: a.hoverColor || '#ffffff',
146 rippleColor: a.rippleColor || 'rgba(255,255,255,0.35)',
147 shadowColor: a.shadowColor || 'rgba(99,102,241,0.4)',
148 borderRadius: a.borderRadius || 999,
149 borderWidth: a.borderWidth || 2,
150 btnBorderColor: a.btnBorderColor || '#6366f1',
151 buttonStyle: a.buttonStyle || 'filled',
152 paddingX: a.paddingX || 40,
153 paddingY: a.paddingY || 18,
154 textTypo: a.textTypo
155 };
156 return el('div', blockProps,
157 el('div', { className: 'bkbg-mgb-wrap', 'data-opts': JSON.stringify(opts) },
158 el('a', {
159 className: 'bkbg-mgb-btn',
160 href: a.href || '#',
161 target: a.target || '_self',
162 rel: a.target === '_blank' ? 'noopener noreferrer' : undefined
163 },
164 el(RichText.Content, { tagName: 'span', value: a.text, className: 'bkbg-mgb-text' }),
165 a.subtext && el('span', { className: 'bkbg-mgb-sub' }, a.subtext),
166 a.showArrow && el('span', { className: 'bkbg-mgb-arrow' }, '')
167 )
168 )
169 );
170 }
171 });
172 }() );
173