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

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

231 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 Fragment = wp.element.Fragment;
4 var useState = wp.element.useState;
5 var __ = wp.i18n.__;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var PanelBody = wp.components.PanelBody;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var SelectControl = wp.components.SelectControl;
14 var TextControl = wp.components.TextControl;
15 var ColorPicker = wp.components.ColorPicker;
16 var Popover = wp.components.Popover;
17
18 var _tc, _tv;
19 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
20 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
21
22 function renderColorControl(key, label, value, onChange, openKey, setOpenKey) {
23 var isOpen = openKey === key;
24 return el('div', { key: key, style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '4px 0', gap: '8px' } },
25 el('span', { style: { fontSize: '12px', color: '#1e1e1e', flex: 1 } }, label),
26 el('div', { style: { position: 'relative', flexShrink: 0 } },
27 el('button', { type: 'button', title: value || 'default', onClick: function () { setOpenKey(isOpen ? null : key); }, style: { width: '28px', height: '28px', borderRadius: '4px', border: isOpen ? '2px solid #007cba' : '2px solid #ddd', cursor: 'pointer', padding: 0, background: value || '#cccccc' } }),
28 isOpen && el(Popover, { position: 'bottom left', onClose: function () { setOpenKey(null); } },
29 el('div', { style: { padding: '8px' } }, el(ColorPicker, { color: value, enableAlpha: true, onChange: onChange }))
30 )
31 )
32 );
33 }
34
35 function buildCSS(a) {
36 var s = {
37 '--bkbg-nl-bg' : a.bgColor,
38 '--bkbg-nl-text' : a.textColor,
39 '--bkbg-nl-heading-color': a.headingColor,
40 '--bkbg-nl-sub-color' : a.subtitleColor,
41 '--bkbg-nl-field-bg' : a.fieldBg,
42 '--bkbg-nl-field-border' : a.fieldBorderColor,
43 '--bkbg-nl-btn-bg' : a.btnBg,
44 '--bkbg-nl-btn-color' : a.btnColor,
45 '--bkbg-nl-radius' : a.borderRadius + 'px',
46 '--bkbg-nl-btn-radius' : a.btnRadius + 'px',
47 '--bkbg-nl-pad' : a.padding + 'px',
48 '--bkbg-nl-heading-sz' : a.headingSize + 'px',
49 '--bkbg-nl-sub-sz' : a.subtitleSize + 'px',
50 '--bkbg-nl-heading-fw' : a.headingFontWeight || 700,
51 '--bkbg-nl-heading-lh' : a.headingLineHeight || 1.2,
52 '--bkbg-nl-sub-fw' : a.subtitleFontWeight || 400,
53 '--bkbg-nl-sub-lh' : a.subtitleLineHeight || 1.5,
54 maxWidth: a.maxWidth + 'px',
55 width: '100%'
56 };
57 var _tvf = getTypoCssVars();
58 if (_tvf) {
59 Object.assign(s, _tvf(a.headingTypo, '--bkbg-nl-ht-'));
60 Object.assign(s, _tvf(a.subtitleTypo, '--bkbg-nl-st-'));
61 }
62 return s;
63 }
64
65 registerBlockType('blockenberg/newsletter', {
66 title: __('Newsletter Signup', 'blockenberg'),
67 icon: 'email',
68 category: 'bkbg-marketing',
69 description: __('Email opt-in form connected to the built-in subscriber endpoint.', 'blockenberg'),
70
71 edit: function (props) {
72 var a = props.attributes;
73 var setAttributes = props.setAttributes;
74
75 var openColorState = useState(null);
76 var openColorKey = openColorState[0];
77 var setOpenColorKey = openColorState[1];
78
79 function cc(key, label, attrKey) {
80 return renderColorControl(key, label, a[attrKey], function (val) {
81 var upd = {}; upd[attrKey] = val; setAttributes(upd);
82 }, openColorKey, setOpenColorKey);
83 }
84
85 function sa(obj) { setAttributes(obj); }
86
87 var blockProps = useBlockProps({
88 className: 'bkbg-nl-wrapper bkbg-nl-layout-' + a.layout + ' bkbg-nl-style-' + a['style'],
89 style: buildCSS(a)
90 });
91
92 var inspector = el(InspectorControls, {},
93 el(PanelBody, { title: __('Content', 'blockenberg'), initialOpen: true },
94 el(ToggleControl, { label: __('Show Icon', 'blockenberg'), checked: a.showIcon, onChange: function (v) { sa({ showIcon: v }); } }),
95 el(ToggleControl, { label: __('Show Name Field', 'blockenberg'), checked: a.showName, onChange: function (v) { sa({ showName: v }); } }),
96 a.showName && el(TextControl, { label: __('Name Placeholder', 'blockenberg'), value: a.placeholderName, onChange: function (v) { sa({ placeholderName: v }); } }),
97 el(TextControl, { label: __('Email Placeholder', 'blockenberg'), value: a.placeholderEmail, onChange: function (v) { sa({ placeholderEmail: v }); } }),
98 el(TextControl, { label: __('Button Label', 'blockenberg'), value: a.submitLabel, onChange: function (v) { sa({ submitLabel: v }); } }),
99 el(TextControl, { label: __('Success Message', 'blockenberg'), value: a.successMessage, onChange: function (v) { sa({ successMessage: v }); } }),
100 el(TextControl, { label: __('Error Message', 'blockenberg'), value: a.errorMessage, onChange: function (v) { sa({ errorMessage: v }); } })
101 ),
102
103 el(PanelBody, { title: __('Layout & Style', 'blockenberg'), initialOpen: false },
104 el(SelectControl, {
105 label: __('Form Layout', 'blockenberg'), value: a.layout,
106 options: [{ label: __('Vertical (stacked)', 'blockenberg'), value: 'vertical' }, { label: __('Horizontal (inline)', 'blockenberg'), value: 'horizontal' }],
107 onChange: function (v) { sa({ layout: v }); }
108 }),
109 el(SelectControl, {
110 label: __('Card Style', 'blockenberg'), value: a['style'],
111 options: [
112 { label: __('Card (with background)', 'blockenberg'), value: 'card' },
113 { label: __('Box (white card)', 'blockenberg'), value: 'box' },
114 { label: __('Minimal (no background)', 'blockenberg'), value: 'minimal' },
115 { label: __('Inline (banner)', 'blockenberg'), value: 'inline' }
116 ],
117 onChange: function (v) { sa({ style: v }); }
118 }),
119 el(RangeControl, { label: __('Max Width (px)', 'blockenberg'), value: a.maxWidth, min: 200, max: 1200, onChange: function (v) { sa({ maxWidth: v }); } }),
120 el(RangeControl, { label: __('Padding (px)', 'blockenberg'), value: a.padding, min: 0, max: 80, onChange: function (v) { sa({ padding: v }); } }),
121 el(RangeControl, { label: __('Border Radius (px)', 'blockenberg'), value: a.borderRadius, min: 0, max: 40, onChange: function (v) { sa({ borderRadius: v }); } }),
122 el(RangeControl, { label: __('Button Radius (px)', 'blockenberg'), value: a.btnRadius, min: 0, max: 40, onChange: function (v) { sa({ btnRadius: v }); } }),
123 ),
124
125
126 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
127 getTypoControl() && el(getTypoControl(), { label: __('Heading Typography', 'blockenberg'), value: a.headingTypo, onChange: function (v) { sa({ headingTypo: v }); } }),
128 getTypoControl() && el(getTypoControl(), { label: __('Subtitle Typography', 'blockenberg'), value: a.subtitleTypo, onChange: function (v) { sa({ subtitleTypo: v }); } })
129 ),
130 el(PanelBody, { title: __('Colors', 'blockenberg'), initialOpen: false },
131 cc('bgColor', __('Background', 'blockenberg'), 'bgColor'),
132 cc('headingColor', __('Heading Color', 'blockenberg'), 'headingColor'),
133 cc('subtitleColor', __('Subtitle Color', 'blockenberg'), 'subtitleColor'),
134 cc('fieldBg', __('Field Background', 'blockenberg'), 'fieldBg'),
135 cc('fieldBorderColor', __('Field Border', 'blockenberg'), 'fieldBorderColor'),
136 cc('btnBg', __('Button Background', 'blockenberg'),'btnBg'),
137 cc('btnColor', __('Button Text', 'blockenberg'), 'btnColor')
138 )
139 );
140
141 return el(Fragment, {},
142 inspector,
143 el('div', blockProps,
144 el('div', { className: 'bkbg-nl-inner' },
145 el('div', { className: 'bkbg-nl-copy' },
146 a.showIcon && el('div', { className: 'bkbg-nl-icon' }, '✉️'),
147 el(RichText, {
148 tagName: 'h2', className: 'bkbg-nl-heading',
149 value: a.heading, placeholder: 'Heading…',
150 onChange: function (v) { sa({ heading: v }); },
151 allowedFormats: ['core/bold', 'core/italic']
152 }),
153 el(RichText, {
154 tagName: 'p', className: 'bkbg-nl-subtitle',
155 value: a.subheading, placeholder: 'Subtitle…',
156 onChange: function (v) { sa({ subheading: v }); },
157 allowedFormats: ['core/bold', 'core/italic']
158 })
159 ),
160 el('form', { className: 'bkbg-nl-form', onSubmit: function (e) { e.preventDefault(); } },
161 a.showName && el('input', { className: 'bkbg-nl-field', type: 'text', placeholder: a.placeholderName, readOnly: true }),
162 el('input', { className: 'bkbg-nl-field', type: 'email', placeholder: a.placeholderEmail, readOnly: true }),
163 el('button', { className: 'bkbg-nl-btn', type: 'button' }, a.submitLabel)
164 )
165 )
166 )
167 );
168 },
169
170 deprecated: [
171 {
172 attributes: wp.blocks.getBlockType('blockenberg/newsletter') ? wp.blocks.getBlockType('blockenberg/newsletter').attributes : {},
173 save: function (props) {
174 var a = props.attributes;
175 var saveProps = wp.blockEditor.useBlockProps.save({
176 className: 'bkbg-nl-wrapper bkbg-nl-layout-' + a.layout + ' bkbg-nl-style-' + a['style'],
177 style: buildCSS(a),
178 'data-success': a.successMessage,
179 'data-error' : a.errorMessage
180 });
181 return el('div', saveProps,
182 el('div', { className: 'bkbg-nl-inner' },
183 el('div', { className: 'bkbg-nl-copy' },
184 a.showIcon && el('div', { className: 'bkbg-nl-icon', 'aria-hidden': 'true' }, '✉️'),
185 el(RichText.Content, { tagName: 'h2', className: 'bkbg-nl-heading', value: a.heading }),
186 el(RichText.Content, { tagName: 'p', className: 'bkbg-nl-subtitle', value: a.subheading })
187 ),
188 el('form', { className: 'bkbg-nl-form', noValidate: true },
189 a.showName && el('input', { className: 'bkbg-nl-field', type: 'text', name: 'name', placeholder: a.placeholderName, autoComplete: 'name' }),
190 el('input', { className: 'bkbg-nl-field', type: 'email', name: 'email', placeholder: a.placeholderEmail, required: true, autoComplete: 'email' }),
191 el('input', { type: 'text', name: 'website', style: { display: 'none' }, tabIndex: '-1', autoComplete: 'off' }),
192 el('div', { className: 'bkbg-nl-status', role: 'status', 'aria-live': 'polite' }),
193 el('button', { className: 'bkbg-nl-btn', type: 'submit' }, a.submitLabel)
194 )
195 )
196 );
197 }
198 }
199 ],
200
201 save: function (props) {
202 var a = props.attributes;
203
204 var saveProps = wp.blockEditor.useBlockProps.save({
205 className: 'bkbg-nl-wrapper bkbg-nl-layout-' + a.layout + ' bkbg-nl-style-' + a['style'],
206 style: buildCSS(a),
207 'data-success': a.successMessage,
208 'data-error' : a.errorMessage
209 });
210
211 return el('div', saveProps,
212 el('div', { className: 'bkbg-nl-inner' },
213 el('div', { className: 'bkbg-nl-copy' },
214 a.showIcon && el('div', { className: 'bkbg-nl-icon', 'aria-hidden': 'true' }, '✉️'),
215 el(RichText.Content, { tagName: 'h2', className: 'bkbg-nl-heading', value: a.heading }),
216 el(RichText.Content, { tagName: 'p', className: 'bkbg-nl-subtitle', value: a.subheading })
217 ),
218 el('form', { className: 'bkbg-nl-form', noValidate: true },
219 a.showName && el('input', { className: 'bkbg-nl-field', type: 'text', name: 'name', placeholder: a.placeholderName, autoComplete: 'name' }),
220 el('input', { className: 'bkbg-nl-field', type: 'email', name: 'email', placeholder: a.placeholderEmail, required: true, autoComplete: 'email' }),
221 // Honeypot
222 el('input', { type: 'text', name: 'website', style: { display: 'none' }, tabIndex: '-1', autoComplete: 'off' }),
223 el('div', { className: 'bkbg-nl-status', role: 'status', 'aria-live': 'polite' }),
224 el('button', { className: 'bkbg-nl-btn', type: 'submit' }, a.submitLabel)
225 )
226 )
227 );
228 }
229 });
230 }() );
231