UNPKG

7.2 kBJavaScriptView Raw
1/**
2 * External dependencies
3 */
4import { omit } from 'lodash';
5import classnames from 'classnames';
6
7/**
8 * WordPress dependencies
9 */
10import { createBlock } from '@wordpress/blocks';
11import {
12 InnerBlocks,
13 RichText,
14 getColorClassName,
15} from '@wordpress/block-editor';
16import { __ } from '@wordpress/i18n';
17
18/**
19 * Internal dependencies
20 */
21import icon from './icon';
22import {
23 default as CoverEdit,
24 IMAGE_BACKGROUND_TYPE,
25 VIDEO_BACKGROUND_TYPE,
26 backgroundImageStyles,
27 dimRatioToClass,
28} from './edit';
29
30const 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
60export const name = 'core/cover';
61
62export 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};