PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.4.1
Block Animations, Motion & Scroll Effects – Ghost Kit v3.4.1
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.4.1, at gutenberg/blocks/grid/awb-fallback.js

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