PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.3.2
Block Animations, Motion & Scroll Effects – Ghost Kit v3.3.2
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / gutenberg / blocks / grid / awb-fallback.js

awb-fallback.js in Block Animations, Motion & Scroll Effects – Ghost Kit 3.3.2, at gutenberg/blocks/grid/awb-fallback.js

511 lines 11.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { MediaUpload } from '@wordpress/block-editor';
2 import { hasBlockSupport } from '@wordpress/blocks';
3 import {
4 Button,
5 ExternalLink,
6 PanelBody,
7 SelectControl,
8 } from '@wordpress/components';
9 import { useSelect } from '@wordpress/data';
10 import { useEffect } from '@wordpress/element';
11 import { addFilter } from '@wordpress/hooks';
12 import { __ } from '@wordpress/i18n';
13
14 import ColorIndicator from '../../components/color-indicator';
15 import ColorPicker from '../../components/color-picker';
16 import FocalPointPicker from '../../components/focal-point-picker';
17 import ToggleGroup from '../../components/toggle-group';
18 import dashCaseToTitle from '../../utils/dash-case-to-title';
19 import { maybeDecode, maybeEncode } from '../../utils/encode-decode';
20
21 /**
22 * Filters registered block settings, extending attributes to include backgrounds.
23 *
24 * @param {Object} blockSettings Original block settings
25 * @return {Object} Filtered block settings
26 */
27 export function addAttribute(blockSettings) {
28 if (
29 blockSettings.name === 'ghostkit/grid' ||
30 blockSettings.name === 'ghostkit/grid-column'
31 ) {
32 blockSettings.supports.awb = true;
33 }
34
35 let allow = false;
36
37 if (hasBlockSupport(blockSettings, 'awb', false)) {
38 allow = true;
39 }
40
41 if (allow) {
42 blockSettings.attributes.awb_type = {
43 type: 'string',
44 default: 'color',
45 };
46 blockSettings.attributes.awb_align = {
47 type: 'string',
48 };
49 blockSettings.attributes.awb_color = {
50 type: 'string',
51 default: '',
52 };
53 blockSettings.attributes.awb_image = {
54 type: 'number',
55 default: '',
56 };
57 blockSettings.attributes.awb_imageTag = {
58 type: 'string',
59 default: '',
60 };
61 blockSettings.attributes.awb_imageSizes = {
62 type: 'object',
63 default: '',
64 };
65 blockSettings.attributes.awb_imageSize = {
66 type: 'string',
67 default: 'full',
68 };
69 blockSettings.attributes.awb_imageBackgroundSize = {
70 type: 'string',
71 default: 'cover',
72 };
73 blockSettings.attributes.awb_imageBackgroundPosition = {
74 type: 'string',
75 default: '50% 50%',
76 };
77 }
78
79 return blockSettings;
80 }
81
82 /**
83 * Select image
84 *
85 * @param {Object} media - media data.
86 * @param {Function} setAttributes - function to set attributes on the block.
87 */
88 function onImageSelect(media, setAttributes) {
89 setAttributes({
90 image: '',
91 imageSizes: '',
92 });
93
94 wp.media
95 .attachment(media.id)
96 .fetch()
97 .then((data) => {
98 if (data && data.sizes) {
99 const { url } =
100 data.sizes['post-thumbnail'] ||
101 data.sizes.medium ||
102 data.sizes.medium_large ||
103 data.sizes.full;
104 if (url) {
105 setAttributes({
106 image: media.id,
107 imageSizes: data.sizes,
108 });
109 }
110 }
111 });
112 }
113
114 function BackgroundControlsInspector(props) {
115 const { attributes, setAttributes: wpSetAttributes } = props;
116
117 const {
118 awb_color: color,
119 awb_type: type,
120 awb_image: image,
121 awb_imageTag: imageTag,
122 awb_imageSizes: imageSizes,
123 awb_imageSize: imageSize,
124 awb_imageBackgroundSize: imageBackgroundSize,
125 awb_imageBackgroundPosition: imageBackgroundPosition,
126 } = attributes;
127
128 function setAttributes(attr) {
129 const newAttrs = {};
130
131 Object.keys(attr).forEach((k) => {
132 newAttrs[`awb_${k}`] = attr[k];
133 });
134
135 wpSetAttributes(newAttrs);
136 }
137
138 const { fetchedImageTag } = useSelect((select) => {
139 if (!image) {
140 return false;
141 }
142
143 const data = {
144 id: image,
145 size: imageSize,
146 attr: {
147 class: 'jarallax-img',
148 },
149 };
150
151 // background image with pattern size
152 if (imageBackgroundSize === 'pattern') {
153 data.div_tag = true;
154 }
155
156 return {
157 fetchedImageTag: select('ghostkit/base/images').getImageTagData(
158 data
159 ),
160 };
161 });
162
163 // Mounted and updated.
164 useEffect(() => {
165 // set image tag to attribute
166 if (fetchedImageTag && maybeEncode(fetchedImageTag) !== imageTag) {
167 setAttributes({ imageTag: maybeEncode(fetchedImageTag) });
168 }
169 });
170
171 return (
172 <PanelBody title={__('Background', 'ghostkit')} initialOpen={false}>
173 <ToggleGroup
174 value={
175 type === 'video' || type === 'yt_vm_video'
176 ? 'yt_vm_video'
177 : type
178 }
179 options={[
180 {
181 label: __('Color', 'ghostkit'),
182 value: 'color',
183 },
184 {
185 label: __('Image', 'ghostkit'),
186 value: 'image',
187 },
188 {
189 label: __('Video', 'ghostkit'),
190 value: 'yt_vm_video',
191 },
192 ]}
193 onChange={(value) => {
194 setAttributes({ type: value });
195 }}
196 />
197
198 {type === 'image' ? (
199 <PanelBody
200 title={__('Image', 'ghostkit')}
201 initialOpen={type === 'image'}
202 >
203 {/* Select Image */}
204 {!image || !imageTag ? (
205 <MediaUpload
206 onSelect={(media) => {
207 onImageSelect(media, setAttributes);
208 }}
209 allowedTypes={['image']}
210 value={image}
211 render={({ open }) => (
212 <Button onClick={open} isPrimary>
213 {__('Select image', 'ghostkit')}
214 </Button>
215 )}
216 />
217 ) : null}
218
219 {image && imageTag ? (
220 <>
221 <FocalPointPicker
222 value={imageBackgroundPosition}
223 image={maybeDecode(imageTag)}
224 onChange={(v) =>
225 setAttributes({
226 imageBackgroundPosition: v,
227 })
228 }
229 />
230 {imageSizes ? (
231 <SelectControl
232 label={__('Size', 'ghostkit')}
233 value={imageSize}
234 options={(() => {
235 const result = [];
236 Object.keys(imageSizes).forEach((k) => {
237 result.push({
238 value: k,
239 label: dashCaseToTitle(k),
240 });
241 });
242 return result;
243 })()}
244 onChange={(v) =>
245 setAttributes({ imageSize: v })
246 }
247 />
248 ) : null}
249 <SelectControl
250 label={__('Background size', 'ghostkit')}
251 value={imageBackgroundSize}
252 options={[
253 {
254 label: __('Cover', 'ghostkit'),
255 value: 'cover',
256 },
257 {
258 label: __('Contain', 'ghostkit'),
259 value: 'contain',
260 },
261 {
262 label: __('Pattern', 'ghostkit'),
263 value: 'pattern',
264 },
265 ]}
266 onChange={(v) =>
267 setAttributes({ imageBackgroundSize: v })
268 }
269 />
270 <Button
271 isLink
272 onClick={(e) => {
273 setAttributes({
274 image: '',
275 imageTag: '',
276 imageSizes: '',
277 });
278 e.preventDefault();
279 }}
280 >
281 {__('Remove image', 'ghostkit')}
282 </Button>
283 </>
284 ) : null}
285 </PanelBody>
286 ) : null}
287
288 {type === 'color' ? (
289 <ColorPicker
290 label={__('Background Color', 'ghostkit')}
291 value={color}
292 onChange={(val) => setAttributes({ color: val })}
293 alpha
294 />
295 ) : (
296 <PanelBody
297 title={
298 <>
299 {__('Overlay', 'ghostkit')}
300 <ColorIndicator colorValue={color} />
301 </>
302 }
303 initialOpen={type === 'color'}
304 >
305 <ColorPicker
306 label={__('Background Color', 'ghostkit')}
307 value={color}
308 onChange={(val) => setAttributes({ color: val })}
309 alpha
310 />
311 </PanelBody>
312 )}
313
314 <p>
315 {__(
316 'Install AWB plugin to set video backgrounds and images with parallax support.',
317 'ghostkit'
318 )}
319 </p>
320 <ExternalLink
321 className="components-button is-button is-secondary is-small"
322 href="https://wordpress.org/plugins/advanced-backgrounds/"
323 >
324 {__('Install', 'ghostkit')}
325 </ExternalLink>
326 </PanelBody>
327 );
328 }
329
330 /**
331 * Override background control to add AWB settings
332 *
333 * @param {Object} Control JSX control.
334 * @param {Object} props additional props.
335 *
336 * @return {Object} Control.
337 */
338 function addBackgroundControls(Control, props) {
339 if (
340 props.attribute === 'background' &&
341 hasBlockSupport(props.props.name, 'awb', false)
342 ) {
343 return <BackgroundControlsInspector {...props.props} />;
344 }
345
346 return Control;
347 }
348
349 /**
350 * Override the default edit UI to include background preview.
351 *
352 * @param {Object} background background JSX.
353 * @param {Object} props additional props.
354 *
355 * @return {Object} Control.
356 */
357 function addEditorBackground(background, props) {
358 if (hasBlockSupport(props.name, 'awb', false)) {
359 const {
360 awb_color: color,
361 awb_type: type,
362 awb_imageTag: imageTag,
363 } = props.attributes;
364
365 let addBackground = false;
366
367 if (type === 'color' && color) {
368 addBackground = true;
369 }
370
371 if (type === 'image' && (color || imageTag)) {
372 addBackground = true;
373 }
374
375 if (addBackground) {
376 return (
377 <div className="awb-gutenberg-preview-block">
378 {color ? (
379 <div
380 className="nk-awb-overlay"
381 style={{ 'background-color': color }}
382 />
383 ) : null}
384 {type === 'image' && imageTag ? (
385 <div
386 className="nk-awb-inner"
387 dangerouslySetInnerHTML={{
388 __html: maybeDecode(imageTag),
389 }}
390 />
391 ) : null}
392 </div>
393 );
394 }
395
396 return null;
397 }
398
399 return background;
400 }
401
402 /**
403 * Add background
404 *
405 * @param {Object} background Background jsx.
406 * @param {Object} props Block properties.
407 *
408 * @return {Object} Filtered props applied to save element.
409 */
410 function addSaveBackground(background, props) {
411 if (hasBlockSupport(props.name, 'awb', false)) {
412 const {
413 awb_color: color,
414 awb_type: type,
415 awb_imageBackgroundSize: imageBackgroundSize,
416 awb_imageBackgroundPosition: imageBackgroundPosition,
417 } = props.attributes;
418
419 let { awb_imageTag: imageTag } = props.attributes;
420
421 let addBackground = false;
422
423 if (type === 'color' && color) {
424 addBackground = true;
425 }
426
427 if (type === 'image' && (color || imageTag)) {
428 addBackground = true;
429 }
430
431 if (addBackground) {
432 const dataAttrs = {
433 'data-awb-type': type,
434 };
435
436 if (type === 'image') {
437 if (imageBackgroundSize) {
438 dataAttrs['data-awb-image-background-size'] =
439 imageBackgroundSize;
440 }
441 if (imageBackgroundPosition) {
442 dataAttrs['data-awb-image-background-position'] =
443 imageBackgroundPosition;
444 }
445 }
446
447 // Fix style tag background.
448 if (type === 'image' && imageTag) {
449 imageTag = maybeDecode(imageTag);
450
451 imageTag = imageTag.replace('url(&quot;', "url('");
452 imageTag = imageTag.replace('&quot;);', "');");
453 }
454
455 return (
456 <div className="nk-awb">
457 <div className="nk-awb-wrap" {...dataAttrs}>
458 {color ? (
459 <div
460 className="nk-awb-overlay"
461 style={{ 'background-color': color }}
462 />
463 ) : null}
464 {type === 'image' && imageTag ? (
465 <div
466 className="nk-awb-inner"
467 dangerouslySetInnerHTML={{ __html: imageTag }}
468 />
469 ) : null}
470 </div>
471 </div>
472 );
473 }
474
475 return null;
476 }
477
478 return background;
479 }
480
481 addFilter(
482 'blocks.registerBlockType',
483 'ghostkit/grid/awb/additional-attributes',
484 addAttribute
485 );
486 addFilter(
487 'ghostkit.editor.controls',
488 'ghostkit/grid/awb/addBackgroundControls',
489 addBackgroundControls
490 );
491 addFilter(
492 'ghostkit.editor.grid.background',
493 'ghostkit/grid/awb/addEditorBackground',
494 addEditorBackground
495 );
496 addFilter(
497 'ghostkit.editor.grid-column.background',
498 'ghostkit/grid-column/awb/addEditorBackground',
499 addEditorBackground
500 );
501 addFilter(
502 'ghostkit.blocks.grid.background',
503 'ghostkit/grid/addSaveBackground',
504 addSaveBackground
505 );
506 addFilter(
507 'ghostkit.blocks.grid-column.background',
508 'ghostkit/grid-column/addSaveBackground',
509 addSaveBackground
510 );
511