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

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

216 lines 15.3 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 registerBlockType = wp.blocks.registerBlockType;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var MediaUpload = wp.blockEditor.MediaUpload;
7 var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
11 var PanelBody = wp.components.PanelBody;
12 var ToggleControl = wp.components.ToggleControl;
13 var RangeControl = wp.components.RangeControl;
14 var SelectControl = wp.components.SelectControl;
15 var TextControl = wp.components.TextControl;
16 var TextareaControl = wp.components.TextareaControl;
17 var Button = wp.components.Button;
18
19 var _TypographyControl, _typoCssVars;
20 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
21 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
22
23 registerBlockType('blockenberg/app-screenshot', {
24 edit: function (props) {
25 var attr = props.attributes;
26 var setAttr = props.setAttributes;
27
28 function updateCallout(idx, key, val) {
29 var callouts = (attr.callouts || []).map(function (c, i) {
30 return i === idx ? Object.assign({}, c, {[key]: val}) : c;
31 });
32 setAttr({ callouts: callouts });
33 }
34
35 var inspector = el(InspectorControls, null,
36 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: true },
37 el(SelectControl, {
38 __nextHasNoMarginBottom: true,
39 label: __('Layout', 'blockenberg'),
40 value: attr.layout,
41 options: [
42 { label: 'Centered', value: 'centered' },
43 { label: 'Split (text + screenshot)', value: 'split' }
44 ],
45 onChange: function (v) { setAttr({ layout: v }); }
46 }),
47 el(SelectControl, {
48 __nextHasNoMarginBottom: true,
49 label: __('Device Frame', 'blockenberg'),
50 value: attr.deviceFrame,
51 options: [
52 { label: 'Browser', value: 'browser' },
53 { label: 'MacBook', value: 'macbook' },
54 { label: 'No Frame', value: 'none' }
55 ],
56 onChange: function (v) { setAttr({ deviceFrame: v }); }
57 }),
58 el(RangeControl, {
59 __nextHasNoMarginBottom: true,
60 label: __('Max Width (px)', 'blockenberg'),
61 value: attr.maxWidth, min: 600, max: 1600,
62 onChange: function (v) { setAttr({ maxWidth: v }); }
63 }),
64 el(RangeControl, {
65 __nextHasNoMarginBottom: true,
66 label: __('Padding Top (px)', 'blockenberg'),
67 value: attr.paddingTop, min: 0, max: 200,
68 onChange: function (v) { setAttr({ paddingTop: v }); }
69 }),
70 el(RangeControl, {
71 __nextHasNoMarginBottom: true,
72 label: __('Padding Bottom (px)', 'blockenberg'),
73 value: attr.paddingBottom, min: 0, max: 200,
74 onChange: function (v) { setAttr({ paddingBottom: v }); }
75 })
76 ),
77 el(PanelBody, { title: __('Screenshot Image', 'blockenberg'), initialOpen: false },
78 el(MediaUploadCheck, null,
79 el(MediaUpload, {
80 onSelect: function (media) { setAttr({ screenshotUrl: media.url, screenshotId: media.id }); },
81 allowedTypes: ['image'],
82 value: attr.screenshotId,
83 render: function (ref) {
84 return el('div', null,
85 attr.screenshotUrl && el('img', { src: attr.screenshotUrl, style: { width: '100%', marginBottom: '8px', borderRadius: '4px' } }),
86 el(Button, { onClick: ref.open, variant: attr.screenshotUrl ? 'secondary' : 'primary' },
87 attr.screenshotUrl ? __('Replace Screenshot', 'blockenberg') : __('Upload Screenshot', 'blockenberg')
88 ),
89 attr.screenshotUrl && el(Button, { isDestructive: true, variant: 'secondary', style: { marginLeft: '8px' }, onClick: function () { setAttr({ screenshotUrl: '', screenshotId: 0 }); } }, __('Remove', 'blockenberg'))
90 );
91 }
92 })
93 )
94 ),
95 el(PanelBody, { title: __('Callout Points', 'blockenberg'), initialOpen: false },
96 el(ToggleControl, {
97 __nextHasNoMarginBottom: true,
98 label: __('Show Callouts', 'blockenberg'),
99 checked: attr.showCallouts,
100 onChange: function (v) { setAttr({ showCallouts: v }); }
101 }),
102 (attr.callouts || []).map(function (c, idx) {
103 return el(PanelBody, { key: idx, title: (c.label || 'Callout ' + (idx + 1)), initialOpen: false },
104 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Label', 'blockenberg'), value: c.label, onChange: function (v) { updateCallout(idx, 'label', v); } }),
105 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Description', 'blockenberg'), value: c.description, onChange: function (v) { updateCallout(idx, 'description', v); } }),
106 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Position X (%)', 'blockenberg'), value: c.x, min: 0, max: 100, onChange: function (v) { updateCallout(idx, 'x', v); } }),
107 el(RangeControl, { __nextHasNoMarginBottom: true, label: __('Position Y (%)', 'blockenberg'), value: c.y, min: 0, max: 100, onChange: function (v) { updateCallout(idx, 'y', v); } }),
108 el(Button, { isDestructive: true, variant: 'secondary', onClick: function () { setAttr({ callouts: (attr.callouts || []).filter(function (_, i) { return i !== idx; }) }); } }, __('Remove', 'blockenberg'))
109 );
110 }),
111 el(Button, { isPrimary: true, variant: 'primary', onClick: function () { setAttr({ callouts: (attr.callouts || []).concat([{ label: 'Feature', description: 'Description', x: 50, y: 50 }]) }); } }, __('+ Add Callout', 'blockenberg'))
112 ),
113 el(PanelBody, { title: __('CTA', 'blockenberg'), initialOpen: false },
114 el(ToggleControl, {
115 __nextHasNoMarginBottom: true,
116 label: __('Show CTA', 'blockenberg'),
117 checked: attr.showCta,
118 onChange: function (v) { setAttr({ showCta: v }); }
119 }),
120 attr.showCta && el(TextControl, { __nextHasNoMarginBottom: true, label: __('CTA Label', 'blockenberg'), value: attr.ctaLabel, onChange: function (v) { setAttr({ ctaLabel: v }); } }),
121 attr.showCta && el(TextControl, { __nextHasNoMarginBottom: true, label: __('CTA URL', 'blockenberg'), value: attr.ctaUrl, onChange: function (v) { setAttr({ ctaUrl: v }); } })
122 ),
123 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
124 el(getTypographyControl(), { label: __('Eyebrow Typography', 'blockenberg'), value: attr.eyebrowTypo || {}, onChange: function (v) { setAttr({ eyebrowTypo: v }); } }),
125 el(getTypographyControl(), { label: __('Heading Typography', 'blockenberg'), value: attr.headingTypo || {}, onChange: function (v) { setAttr({ headingTypo: v }); } }),
126 el(getTypographyControl(), { label: __('Subtext Typography', 'blockenberg'), value: attr.subtextTypo || {}, onChange: function (v) { setAttr({ subtextTypo: v }); } })
127 ),
128 el(PanelColorSettings, {
129 title: __('Colors', 'blockenberg'),
130 initialOpen: false,
131 colorSettings: [
132 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#ffffff' }); } },
133 { label: __('Heading', 'blockenberg'), value: attr.headingColor, onChange: function (v) { setAttr({ headingColor: v || '#111827' }); } },
134 { label: __('Subtext', 'blockenberg'), value: attr.subColor, onChange: function (v) { setAttr({ subColor: v || '#6b7280' }); } },
135 { label: __('Eyebrow', 'blockenberg'), value: attr.eyebrowColor, onChange: function (v) { setAttr({ eyebrowColor: v || '#6366f1' }); } },
136 { label: __('Device Frame', 'blockenberg'), value: attr.frameColor, onChange: function (v) { setAttr({ frameColor: v || '#1e293b' }); } },
137 { label: __('Callout BG', 'blockenberg'), value: attr.calloutBg, onChange: function (v) { setAttr({ calloutBg: v || '#6366f1' }); } },
138 { label: __('Callout Text', 'blockenberg'), value: attr.calloutColor, onChange: function (v) { setAttr({ calloutColor: v || '#ffffff' }); } },
139 { label: __('CTA BG', 'blockenberg'), value: attr.ctaBg, onChange: function (v) { setAttr({ ctaBg: v || '#6366f1' }); } },
140 { label: __('CTA Text', 'blockenberg'), value: attr.ctaColor, onChange: function (v) { setAttr({ ctaColor: v || '#ffffff' }); } }
141 ]
142 })
143 );
144
145 var blockProps = useBlockProps({ className: 'bkbg-aps-editor' });
146
147 return el('div', blockProps,
148 inspector,
149 el('div', (function () {
150 var _tv = getTypoCssVars();
151 var s = { background: attr.bgColor, padding: '40px', borderRadius: '8px', fontFamily: 'sans-serif' };
152 Object.assign(s, _tv(attr.eyebrowTypo || {}, '--bkbg-aps-eyebrow-'));
153 Object.assign(s, _tv(attr.headingTypo || {}, '--bkbg-aps-heading-'));
154 Object.assign(s, _tv(attr.subtextTypo || {}, '--bkbg-aps-sub-'));
155 if (attr.eyebrowFontSize && attr.eyebrowFontSize !== 13) s['--bkbg-aps-eyebrow-sz'] = attr.eyebrowFontSize + 'px';
156 if (attr.headingFontSize && attr.headingFontSize !== 36) s['--bkbg-aps-heading-sz'] = attr.headingFontSize + 'px';
157 if (attr.subtextFontSize && attr.subtextFontSize !== 18) s['--bkbg-aps-sub-sz'] = attr.subtextFontSize + 'px';
158 return { style: s };
159 })(),
160 /* Header text */
161 el('div', { style: { textAlign: 'center', marginBottom: '40px', maxWidth: '700px', margin: '0 auto 40px' } },
162 el(RichText, {
163 tagName: 'p', value: attr.eyebrow,
164 onChange: function (v) { setAttr({ eyebrow: v }); },
165 placeholder: __('Eyebrow…', 'blockenberg'),
166 className: 'bkbg-aps-eyebrow',
167 style: { color: attr.eyebrowColor, margin: '0 0 8px' }
168 }),
169 el(RichText, {
170 tagName: 'h2', value: attr.heading,
171 onChange: function (v) { setAttr({ heading: v }); },
172 placeholder: __('Heading…', 'blockenberg'),
173 className: 'bkbg-aps-heading',
174 style: { color: attr.headingColor, margin: '0 0 14px' }
175 }),
176 el(RichText, {
177 tagName: 'p', value: attr.subtext,
178 onChange: function (v) { setAttr({ subtext: v }); },
179 placeholder: __('Subtext…', 'blockenberg'),
180 className: 'bkbg-aps-sub',
181 style: { color: attr.subColor, margin: '0 auto 24px' }
182 }),
183 attr.showCta && el('a', { href: attr.ctaUrl, style: { display: 'inline-block', background: attr.ctaBg, color: attr.ctaColor, padding: '12px 28px', borderRadius: '8px', fontWeight: 700, textDecoration: 'none' } }, attr.ctaLabel)
184 ),
185 /* Screenshot frame */
186 el('div', { style: { position: 'relative', borderRadius: '12px', overflow: 'hidden', background: attr.screenshotUrl ? 'transparent' : '#f1f5f9', border: attr.deviceFrame !== 'none' ? '4px solid ' + attr.frameColor : 'none', minHeight: '300px', textAlign: 'center', marginTop: '40px' } },
187 attr.deviceFrame === 'browser' && el('div', { style: { background: attr.frameColor, padding: '12px 16px 0', display: 'flex', alignItems: 'center', gap: '6px' } },
188 el('span', { style: { width: '10px', height: '10px', borderRadius: '50%', background: '#ef4444', display: 'inline-block' } }),
189 el('span', { style: { width: '10px', height: '10px', borderRadius: '50%', background: '#fbbf24', display: 'inline-block' } }),
190 el('span', { style: { width: '10px', height: '10px', borderRadius: '50%', background: '#22c55e', display: 'inline-block' } })
191 ),
192 attr.screenshotUrl
193 ? el('img', { src: attr.screenshotUrl, style: { width: '100%', display: 'block' }, alt: '' })
194 : el('div', { style: { padding: '80px 20px', color: '#94a3b8', fontSize: '14px' } }, '🖼 Upload a screenshot in the sidebar'),
195 /* Callout pins */
196 attr.showCallouts && (attr.callouts || []).map(function (c, i) {
197 return el('div', { key: i, style: { position: 'absolute', left: c.x + '%', top: c.y + '%', transform: 'translate(-50%,-50%)' } },
198 el('div', { style: { background: attr.calloutBg, color: attr.calloutColor, borderRadius: '8px', padding: '6px 12px', fontSize: '12px', fontWeight: 700, whiteSpace: 'nowrap', boxShadow: '0 4px 12px rgba(0,0,0,0.2)' } }, c.label),
199 el('div', { style: { width: '12px', height: '12px', borderRadius: '50%', background: attr.calloutBg, margin: '4px auto 0', boxShadow: '0 0 0 3px rgba(99,102,241,0.3)' } })
200 );
201 })
202 )
203 )
204 );
205 },
206
207 save: function (props) {
208 var attr = props.attributes;
209 var useBlockProps = wp.blockEditor.useBlockProps;
210 return el('div', useBlockProps.save(),
211 el('div', { className: 'bkbg-aps-app', 'data-opts': JSON.stringify(attr) })
212 );
213 }
214 });
215 }() );
216