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

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

281 lines 15.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 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 Button = wp.components.Button;
17 var Fragment = wp.element.Fragment;
18
19 var _TC, _tv;
20 function getTC() { return _TC || (_TC = window.bkbgTypographyControl); }
21 function getTV() { return _tv || (_tv = window.bkbgTypoCssVars); }
22
23 registerBlockType('blockenberg/scrollytelling', {
24 edit: function (props) {
25 var attr = props.attributes;
26 var set = props.setAttributes;
27 var chapters = attr.chapters || [];
28
29 function updateChapter(idx, field, val) {
30 var updated = chapters.map(function (ch, i) {
31 if (i !== idx) return ch;
32 var patch = {}; patch[field] = val;
33 return Object.assign({}, ch, patch);
34 });
35 set({ chapters: updated });
36 }
37
38 function addChapter() {
39 set({
40 chapters: chapters.concat([{
41 title: 'New Chapter', eyebrow: '', text: 'Your story continues here.',
42 imageUrl: '', imageId: 0, imageAlt: '', overlayColor: '#000000', overlayOpacity: 40
43 }])
44 });
45 }
46
47 function removeChapter(idx) {
48 set({ chapters: chapters.filter(function (_, i) { return i !== idx; }) });
49 }
50
51 function moveChapter(idx, dir) {
52 var arr = chapters.slice();
53 var target = idx + dir;
54 if (target < 0 || target >= arr.length) return;
55 var tmp = arr[idx]; arr[idx] = arr[target]; arr[target] = tmp;
56 set({ chapters: arr });
57 }
58
59 /* Inspector */
60 var inspector = el(InspectorControls, {},
61 /* Layout */
62 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: true },
63 el(SelectControl, {
64 label: __('Sticky Height', 'blockenberg'),
65 value: attr.stickyHeight,
66 options: [
67 { label: '50vh', value: '50vh' },
68 { label: '70vh', value: '70vh' },
69 { label: '100vh (Fullscreen)', value: '100vh' }
70 ],
71 onChange: function (v) { set({ stickyHeight: v }); },
72 __nextHasNoMarginBottom: true
73 }),
74 el(SelectControl, {
75 label: __('Text Panel Position', 'blockenberg'),
76 value: attr.textPosition,
77 options: [
78 { label: 'Left', value: 'left' },
79 { label: 'Right', value: 'right' },
80 { label: 'Center', value: 'center' }
81 ],
82 onChange: function (v) { set({ textPosition: v }); },
83 __nextHasNoMarginBottom: true
84 }),
85 el(SelectControl, {
86 label: __('Transition Style', 'blockenberg'),
87 value: attr.transitionStyle,
88 options: [
89 { label: 'Fade', value: 'fade' },
90 { label: 'Slide', value: 'slide' }
91 ],
92 onChange: function (v) { set({ transitionStyle: v }); },
93 __nextHasNoMarginBottom: true
94 }),
95 el(RangeControl, {
96 label: __('Panel Width (px)', 'blockenberg'),
97 value: attr.panelWidth, min: 280, max: 700, step: 10,
98 onChange: function (v) { set({ panelWidth: v }); },
99 __nextHasNoMarginBottom: true
100 }),
101 el(ToggleControl, {
102 label: __('Show Chapter Progress', 'blockenberg'),
103 checked: attr.showProgress,
104 onChange: function (v) { set({ showProgress: v }); },
105 __nextHasNoMarginBottom: true
106 }),
107 el(RangeControl, {
108 label: __('Padding Top (px)', 'blockenberg'),
109 value: attr.paddingTop, min: 0, max: 200,
110 onChange: function (v) { set({ paddingTop: v }); },
111 __nextHasNoMarginBottom: true
112 }),
113 el(RangeControl, {
114 label: __('Padding Bottom (px)', 'blockenberg'),
115 value: attr.paddingBottom, min: 0, max: 200,
116 onChange: function (v) { set({ paddingBottom: v }); },
117 __nextHasNoMarginBottom: true
118 })
119 ),
120 /* Default Background */
121 el(PanelBody, { title: __('Default Background', 'blockenberg'), initialOpen: false },
122 el(MediaUploadCheck, {},
123 el(MediaUpload, {
124 onSelect: function (m) { set({ defaultBgUrl: m.url, defaultBgId: m.id }); },
125 allowedTypes: ['image'],
126 value: attr.defaultBgId,
127 render: function (ref) {
128 return el(Fragment, {},
129 attr.defaultBgUrl && el('img', {
130 src: attr.defaultBgUrl,
131 style: { width: '100%', height: '80px', objectFit: 'cover', borderRadius: '6px', marginBottom: '6px' }
132 }),
133 el(Button, {
134 onClick: ref.open,
135 variant: attr.defaultBgUrl ? 'secondary' : 'primary',
136 isSmall: true
137 }, attr.defaultBgUrl ? __('Replace Background', 'blockenberg') : __('Choose Background', 'blockenberg')),
138 attr.defaultBgUrl && el(Button, {
139 onClick: function () { set({ defaultBgUrl: '', defaultBgId: 0 }); },
140 variant: 'link', isDestructive: true, isSmall: true,
141 style: { marginLeft: '8px' }
142 }, __('Remove', 'blockenberg'))
143 );
144 }
145 })
146 )
147 ),
148 /* Colors */
149 el(PanelColorSettings, {
150 title: __('Colors', 'blockenberg'),
151 initialOpen: false,
152 colorSettings: [
153 { value: attr.eyebrowColor, onChange: function (v) { set({ eyebrowColor: v || '#a5b4fc' }); }, label: __('Eyebrow', 'blockenberg') },
154 { value: attr.titleColor, onChange: function (v) { set({ titleColor: v || '#ffffff' }); }, label: __('Title', 'blockenberg') },
155 { value: attr.textColor, onChange: function (v) { set({ textColor: v || '#e5e7eb' }); }, label: __('Body Text', 'blockenberg') },
156 { value: attr.textBg, onChange: function (v) { set({ textBg: v || '' }); }, label: __('Panel Background', 'blockenberg') },
157 { value: attr.progressColor, onChange: function (v) { set({ progressColor: v || '#6366f1' }); }, label: __('Progress Indicator', 'blockenberg') },
158 { value: attr.accentColor, onChange: function (v) { set({ accentColor: v || '#6366f1' }); }, label: __('Accent', 'blockenberg') }
159 ]
160 }),
161 /* Typography */
162 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
163 el(getTC(), { label: __('Title', 'blockenberg'), value: attr.titleTypo, onChange: function (v) { set({ titleTypo: v }); } }),
164 el(getTC(), { label: __('Eyebrow', 'blockenberg'), value: attr.eyebrowTypo, onChange: function (v) { set({ eyebrowTypo: v }); } }),
165 el(getTC(), { label: __('Body Text', 'blockenberg'), value: attr.bodyTypo, onChange: function (v) { set({ bodyTypo: v }); } })
166 )
167 );
168
169 /* Editor Preview */
170 var preview = el('div', {
171 className: 'bkbg-sty-editor-preview',
172 style: { fontFamily: 'sans-serif', padding: '16px 0' }
173 },
174 chapters.map(function (ch, idx) {
175 return el('div', {
176 key: idx,
177 className: 'bkbg-sty-editor-chapter',
178 style: {
179 display: 'flex', gap: '12px', marginBottom: '16px',
180 background: '#1e1b4b', borderRadius: '10px', overflow: 'hidden'
181 }
182 },
183 /* bg preview */
184 el('div', {
185 style: {
186 width: '160px', flexShrink: 0,
187 background: ch.imageUrl ? ('url(' + ch.imageUrl + ') center/cover') : '#312e81',
188 minHeight: '120px', position: 'relative', display: 'flex',
189 alignItems: 'center', justifyContent: 'center'
190 }
191 },
192 !ch.imageUrl && el('span', { style: { color: '#a5b4fc', fontSize: '12px', textAlign: 'center', padding: '8px' } }, __('No image', 'blockenberg')),
193 el(MediaUploadCheck, {},
194 el(MediaUpload, {
195 onSelect: function (m) { updateChapter(idx, 'imageUrl', m.url); updateChapter(idx, 'imageId', m.id); updateChapter(idx, 'imageAlt', m.alt || ''); },
196 allowedTypes: ['image'],
197 value: ch.imageId,
198 render: function (ref) {
199 return el(Button, {
200 onClick: ref.open,
201 variant: 'primary', isSmall: true,
202 style: { position: 'absolute', bottom: '6px', left: '50%', transform: 'translateX(-50%)', whiteSpace: 'nowrap', fontSize: '11px' }
203 }, ch.imageUrl ? '' : '+');
204 }
205 })
206 )
207 ),
208 /* text fields */
209 el('div', { style: { flex: 1, padding: '12px', color: '#f3f4f6' } },
210 el(TextControl, {
211 label: __('Eyebrow', 'blockenberg'),
212 value: ch.eyebrow,
213 onChange: function (v) { updateChapter(idx, 'eyebrow', v); },
214 style: { color: '#a5b4fc' },
215 __nextHasNoMarginBottom: true
216 }),
217 el(RichText, {
218 tagName: 'h3',
219 value: ch.title,
220 onChange: function (v) { updateChapter(idx, 'title', v); },
221 placeholder: __('Chapter Title', 'blockenberg'),
222 style: { color: '#ffffff', margin: '6px 0 4px' }
223 }),
224 el(RichText, {
225 tagName: 'p',
226 value: ch.text,
227 onChange: function (v) { updateChapter(idx, 'text', v); },
228 placeholder: __('Chapter text...', 'blockenberg'),
229 style: { color: '#e5e7eb', margin: '0 0 8px' }
230 }),
231 el('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
232 el(RangeControl, {
233 label: __('Overlay %', 'blockenberg'),
234 value: ch.overlayOpacity, min: 0, max: 90,
235 onChange: function (v) { updateChapter(idx, 'overlayOpacity', v); },
236 style: { flex: 1 },
237 __nextHasNoMarginBottom: true
238 }),
239 idx > 0 && el(Button, { onClick: function () { moveChapter(idx, -1); }, variant: 'tertiary', isSmall: true }, ''),
240 idx < chapters.length - 1 && el(Button, { onClick: function () { moveChapter(idx, 1); }, variant: 'tertiary', isSmall: true }, ''),
241 el(Button, {
242 onClick: function () { removeChapter(idx); },
243 variant: 'link', isDestructive: true, isSmall: true
244 }, __('Remove', 'blockenberg'))
245 )
246 )
247 );
248 }),
249 el(Button, {
250 onClick: addChapter, variant: 'primary', isSmall: true,
251 style: { marginTop: '8px' }
252 }, __('+ Add Chapter', 'blockenberg'))
253 );
254
255 return el(Fragment, {},
256 inspector,
257 el('div', useBlockProps((function () {
258 var _tvFn = getTV();
259 var s = {};
260 Object.assign(s, _tvFn(attr.titleTypo, '--bksty-tt-'));
261 Object.assign(s, _tvFn(attr.eyebrowTypo, '--bksty-et-'));
262 Object.assign(s, _tvFn(attr.bodyTypo, '--bksty-bt-'));
263 return { style: s };
264 })()), preview)
265 );
266 },
267
268 save: function (props) {
269 var attr = props.attributes;
270 var _tvFn = getTV();
271 var s = {};
272 Object.assign(s, _tvFn(attr.titleTypo, '--bksty-tt-'));
273 Object.assign(s, _tvFn(attr.eyebrowTypo, '--bksty-et-'));
274 Object.assign(s, _tvFn(attr.bodyTypo, '--bksty-bt-'));
275 return el('div', useBlockProps.save({ style: s }),
276 el('div', { className: 'bkbg-sty-app', 'data-opts': JSON.stringify(attr) })
277 );
278 }
279 });
280 }() );
281