1 |
|
2 |
|
3 |
|
4 | import { omit } from 'lodash';
|
5 | import classnames from 'classnames';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | import { createBlock } from '@wordpress/blocks';
|
11 | import {
|
12 | InnerBlocks,
|
13 | RichText,
|
14 | getColorClassName,
|
15 | } from '@wordpress/block-editor';
|
16 | import { __ } from '@wordpress/i18n';
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | import icon from './icon';
|
22 | import {
|
23 | default as CoverEdit,
|
24 | IMAGE_BACKGROUND_TYPE,
|
25 | VIDEO_BACKGROUND_TYPE,
|
26 | backgroundImageStyles,
|
27 | dimRatioToClass,
|
28 | } from './edit';
|
29 |
|
30 | const blockAttributes = {
|
31 | url: {
|
32 | type: 'string',
|
33 | },
|
34 | id: {
|
35 | type: 'number',
|
36 | },
|
37 | hasParallax: {
|
38 | type: 'boolean',
|
39 | default: false,
|
40 | },
|
41 | dimRatio: {
|
42 | type: 'number',
|
43 | default: 50,
|
44 | },
|
45 | overlayColor: {
|
46 | type: 'string',
|
47 | },
|
48 | customOverlayColor: {
|
49 | type: 'string',
|
50 | },
|
51 | backgroundType: {
|
52 | type: 'string',
|
53 | default: 'image',
|
54 | },
|
55 | focalPoint: {
|
56 | type: 'object',
|
57 | },
|
58 | };
|
59 |
|
60 | export const name = 'core/cover';
|
61 |
|
62 | export const settings = {
|
63 | title: __( 'Cover' ),
|
64 |
|
65 | description: __( 'Add an image or video with a text overlay — great for headers.' ),
|
66 |
|
67 | icon,
|
68 |
|
69 | category: 'common',
|
70 |
|
71 | attributes: blockAttributes,
|
72 |
|
73 | supports: {
|
74 | align: true,
|
75 | },
|
76 |
|
77 | transforms: {
|
78 | from: [
|
79 | {
|
80 | type: 'block',
|
81 | blocks: [ 'core/image' ],
|
82 | transform: ( { caption, url, align, id } ) => (
|
83 | createBlock( 'core/cover', {
|
84 | title: caption,
|
85 | url,
|
86 | align,
|
87 | id,
|
88 | } )
|
89 | ),
|
90 | },
|
91 | {
|
92 | type: 'block',
|
93 | blocks: [ 'core/video' ],
|
94 | transform: ( { caption, src, align, id } ) => (
|
95 | createBlock( 'core/cover', {
|
96 | title: caption,
|
97 | url: src,
|
98 | align,
|
99 | id,
|
100 | backgroundType: VIDEO_BACKGROUND_TYPE,
|
101 | } )
|
102 | ),
|
103 | },
|
104 | ],
|
105 | to: [
|
106 | {
|
107 | type: 'block',
|
108 | blocks: [ 'core/image' ],
|
109 | isMatch: ( { backgroundType, url } ) => {
|
110 | return ! url || backgroundType === IMAGE_BACKGROUND_TYPE;
|
111 | },
|
112 | transform: ( { title, url, align, id } ) => (
|
113 | createBlock( 'core/image', {
|
114 | caption: title,
|
115 | url,
|
116 | align,
|
117 | id,
|
118 | } )
|
119 | ),
|
120 | },
|
121 | {
|
122 | type: 'block',
|
123 | blocks: [ 'core/video' ],
|
124 | isMatch: ( { backgroundType, url } ) => {
|
125 | return ! url || backgroundType === VIDEO_BACKGROUND_TYPE;
|
126 | },
|
127 | transform: ( { title, url, align, id } ) => (
|
128 | createBlock( 'core/video', {
|
129 | caption: title,
|
130 | src: url,
|
131 | id,
|
132 | align,
|
133 | } )
|
134 | ),
|
135 | },
|
136 | ],
|
137 | },
|
138 |
|
139 | save( { attributes } ) {
|
140 | const {
|
141 | backgroundType,
|
142 | customOverlayColor,
|
143 | dimRatio,
|
144 | focalPoint,
|
145 | hasParallax,
|
146 | overlayColor,
|
147 | url,
|
148 | } = attributes;
|
149 | const overlayColorClass = getColorClassName( 'background-color', overlayColor );
|
150 | const style = backgroundType === IMAGE_BACKGROUND_TYPE ?
|
151 | backgroundImageStyles( url ) :
|
152 | {};
|
153 | if ( ! overlayColorClass ) {
|
154 | style.backgroundColor = customOverlayColor;
|
155 | }
|
156 | if ( focalPoint && ! hasParallax ) {
|
157 | style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`;
|
158 | }
|
159 |
|
160 | const classes = classnames(
|
161 | dimRatioToClass( dimRatio ),
|
162 | overlayColorClass,
|
163 | {
|
164 | 'has-background-dim': dimRatio !== 0,
|
165 | 'has-parallax': hasParallax,
|
166 | },
|
167 | );
|
168 |
|
169 | return (
|
170 | <div className={ classes } style={ style }>
|
171 | { VIDEO_BACKGROUND_TYPE === backgroundType && url && ( <video
|
172 | className="wp-block-cover__video-background"
|
173 | autoPlay
|
174 | muted
|
175 | loop
|
176 | src={ url }
|
177 | /> ) }
|
178 | <div className="wp-block-cover__inner-container">
|
179 | <InnerBlocks.Content />
|
180 | </div>
|
181 | </div>
|
182 | );
|
183 | },
|
184 |
|
185 | edit: CoverEdit,
|
186 | deprecated: [ {
|
187 | attributes: {
|
188 | ...blockAttributes,
|
189 | title: {
|
190 | type: 'string',
|
191 | source: 'html',
|
192 | selector: 'p',
|
193 | },
|
194 | contentAlign: {
|
195 | type: 'string',
|
196 | default: 'center',
|
197 | },
|
198 | },
|
199 |
|
200 | supports: {
|
201 | align: true,
|
202 | },
|
203 |
|
204 | save( { attributes } ) {
|
205 | const {
|
206 | backgroundType,
|
207 | contentAlign,
|
208 | customOverlayColor,
|
209 | dimRatio,
|
210 | focalPoint,
|
211 | hasParallax,
|
212 | overlayColor,
|
213 | title,
|
214 | url,
|
215 | } = attributes;
|
216 | const overlayColorClass = getColorClassName( 'background-color', overlayColor );
|
217 | const style = backgroundType === IMAGE_BACKGROUND_TYPE ?
|
218 | backgroundImageStyles( url ) :
|
219 | {};
|
220 | if ( ! overlayColorClass ) {
|
221 | style.backgroundColor = customOverlayColor;
|
222 | }
|
223 | if ( focalPoint && ! hasParallax ) {
|
224 | style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`;
|
225 | }
|
226 |
|
227 | const classes = classnames(
|
228 | dimRatioToClass( dimRatio ),
|
229 | overlayColorClass,
|
230 | {
|
231 | 'has-background-dim': dimRatio !== 0,
|
232 | 'has-parallax': hasParallax,
|
233 | [ `has-${ contentAlign }-content` ]: contentAlign !== 'center',
|
234 | },
|
235 | );
|
236 |
|
237 | return (
|
238 | <div className={ classes } style={ style }>
|
239 | { VIDEO_BACKGROUND_TYPE === backgroundType && url && ( <video
|
240 | className="wp-block-cover__video-background"
|
241 | autoPlay
|
242 | muted
|
243 | loop
|
244 | src={ url }
|
245 | /> ) }
|
246 | { ! RichText.isEmpty( title ) && (
|
247 | <RichText.Content tagName="p" className="wp-block-cover-text" value={ title } />
|
248 | ) }
|
249 | </div>
|
250 | );
|
251 | },
|
252 |
|
253 | migrate( attributes ) {
|
254 | return [
|
255 | omit( attributes, [ 'title', 'contentAlign' ] ),
|
256 | [
|
257 | createBlock(
|
258 | 'core/paragraph',
|
259 | {
|
260 | content: attributes.title,
|
261 | align: attributes.contentAlign,
|
262 | fontSize: 'large',
|
263 | placeholder: __( 'Write title…' ),
|
264 | }
|
265 | ),
|
266 | ],
|
267 | ];
|
268 | },
|
269 | }, {
|
270 | attributes: {
|
271 | ...blockAttributes,
|
272 | title: {
|
273 | type: 'string',
|
274 | source: 'html',
|
275 | selector: 'p',
|
276 | },
|
277 | contentAlign: {
|
278 | type: 'string',
|
279 | default: 'center',
|
280 | },
|
281 | align: {
|
282 | type: 'string',
|
283 | },
|
284 | },
|
285 |
|
286 | supports: {
|
287 | className: false,
|
288 | },
|
289 |
|
290 | save( { attributes } ) {
|
291 | const { url, title, hasParallax, dimRatio, align, contentAlign, overlayColor, customOverlayColor } = attributes;
|
292 | const overlayColorClass = getColorClassName( 'background-color', overlayColor );
|
293 | const style = backgroundImageStyles( url );
|
294 | if ( ! overlayColorClass ) {
|
295 | style.backgroundColor = customOverlayColor;
|
296 | }
|
297 |
|
298 | const classes = classnames(
|
299 | 'wp-block-cover-image',
|
300 | dimRatioToClass( dimRatio ),
|
301 | overlayColorClass,
|
302 | {
|
303 | 'has-background-dim': dimRatio !== 0,
|
304 | 'has-parallax': hasParallax,
|
305 | [ `has-${ contentAlign }-content` ]: contentAlign !== 'center',
|
306 | },
|
307 | align ? `align${ align }` : null,
|
308 | );
|
309 |
|
310 | return (
|
311 | <div className={ classes } style={ style }>
|
312 | { ! RichText.isEmpty( title ) && (
|
313 | <RichText.Content tagName="p" className="wp-block-cover-image-text" value={ title } />
|
314 | ) }
|
315 | </div>
|
316 | );
|
317 | },
|
318 | }, {
|
319 | attributes: {
|
320 | ...blockAttributes,
|
321 | align: {
|
322 | type: 'string',
|
323 | },
|
324 | title: {
|
325 | type: 'string',
|
326 | source: 'html',
|
327 | selector: 'h2',
|
328 | },
|
329 | contentAlign: {
|
330 | type: 'string',
|
331 | default: 'center',
|
332 | },
|
333 | },
|
334 |
|
335 | save( { attributes } ) {
|
336 | const { url, title, hasParallax, dimRatio, align } = attributes;
|
337 | const style = backgroundImageStyles( url );
|
338 | const classes = classnames(
|
339 | dimRatioToClass( dimRatio ),
|
340 | {
|
341 | 'has-background-dim': dimRatio !== 0,
|
342 | 'has-parallax': hasParallax,
|
343 | },
|
344 | align ? `align${ align }` : null,
|
345 | );
|
346 |
|
347 | return (
|
348 | <section className={ classes } style={ style }>
|
349 | <RichText.Content tagName="h2" value={ title } />
|
350 | </section>
|
351 | );
|
352 | },
|
353 | } ],
|
354 | };
|