@elementor/editor-canvas 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +29 -0
  3. package/dist/index.js +162 -127
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +158 -123
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +4 -4
  8. package/src/__tests__/init-styles-renderer.test.ts +1 -1
  9. package/src/init-styles-renderer.ts +1 -1
  10. package/src/styles-renderer/__tests__/__mocks__/styles-schema.ts +785 -0
  11. package/src/styles-renderer/__tests__/index.test.ts +644 -71
  12. package/src/styles-renderer/get-styles-schema.ts +17 -0
  13. package/src/styles-renderer/multi-props.ts +26 -0
  14. package/src/styles-renderer/render.ts +10 -12
  15. package/src/styles-renderer/resolve.ts +99 -0
  16. package/src/styles-renderer/transformers/background-color-overlay-transformer.ts +9 -0
  17. package/src/styles-renderer/transformers/background-transformer.ts +12 -0
  18. package/src/styles-renderer/transformers/create-combine-array-transformer.ts +4 -15
  19. package/src/styles-renderer/transformers/create-corner-sizes-transformer.ts +33 -0
  20. package/src/styles-renderer/transformers/create-edge-sizes-transformer.ts +31 -0
  21. package/src/styles-renderer/transformers/gap-transformer.ts +20 -0
  22. package/src/styles-renderer/transformers/index.ts +22 -15
  23. package/src/styles-renderer/transformers/linked-dimensions-transformer.ts +13 -8
  24. package/src/styles-renderer/transformers/primitive-transformer.ts +7 -0
  25. package/src/styles-renderer/transformers/shadow-transformer.ts +5 -16
  26. package/src/styles-renderer/transformers/size-transformer.ts +3 -5
  27. package/src/styles-renderer/transformers/stroke-transformer.ts +3 -5
  28. package/src/styles-renderer/types.ts +3 -6
  29. package/src/styles-renderer/__tests__/__mocks__/style-definitions.ts +0 -171
  30. package/src/styles-renderer/transform.ts +0 -34
  31. package/src/styles-renderer/transformers/__tests__/background-overlay-transformer.test.ts +0 -46
  32. package/src/styles-renderer/transformers/__tests__/create-combine-array-transformer.test.ts +0 -61
  33. package/src/styles-renderer/transformers/__tests__/linked-dimensions-transformer.test.ts +0 -34
  34. package/src/styles-renderer/transformers/__tests__/shadow-transformer.test.ts +0 -127
  35. package/src/styles-renderer/transformers/__tests__/size-transformer.test.ts +0 -37
  36. package/src/styles-renderer/transformers/__tests__/stroke-transformer.test.ts +0 -59
  37. package/src/styles-renderer/transformers/background-overlay-transformer.ts +0 -13
  38. package/src/styles-renderer/transformers/border-radius-transformer.ts +0 -20
  39. package/src/styles-renderer/transformers/border-width-transformer.ts +0 -15
  40. package/src/styles-renderer/transformers/color-transformer.ts +0 -11
  41. package/src/styles-renderer/transformers/number-transformer.ts +0 -11
  42. package/src/styles-renderer/transformers/string-transformer.ts +0 -11
@@ -1,132 +1,705 @@
1
- import { transformers } from '../index';
2
- import createStyles from '../render';
1
+ /* eslint-disable testing-library/render-result-naming-convention */
2
+ import { createMockStyleDefinition } from 'test-utils';
3
3
  import {
4
- breakpointsStyleMock,
5
- mockBreakpoints,
6
- multiVariantsStyleMock,
7
- singleVariantStyleMock,
8
- statesStyleMock,
9
- transformableStyleMock,
10
- } from './__mocks__/style-definitions';
4
+ backgroundColorOverlayPropTypeUtil,
5
+ backgroundOverlayPropTypeUtil,
6
+ backgroundPropTypeUtil,
7
+ borderRadiusPropTypeUtil,
8
+ borderWidthPropTypeUtil,
9
+ boxShadowPropTypeUtil,
10
+ colorPropTypeUtil,
11
+ gapPropTypeUtil,
12
+ linkedDimensionsPropTypeUtil,
13
+ shadowPropTypeUtil,
14
+ sizePropTypeUtil,
15
+ strokePropTypeUtil,
16
+ } from '@elementor/editor-props';
17
+ import type { BreakpointsMap } from '@elementor/editor-responsive';
18
+ import { type StyleDefinition } from '@elementor/editor-styles';
11
19
 
12
- describe( 'style renderer', () => {
13
- it( 'should return a string wrapped with style tag or without', () => {
20
+ import { getStylesSchema } from '../get-styles-schema';
21
+ import render from '../render';
22
+ import transformers from '../transformers';
23
+ import backgroundTransformer from '../transformers/background-transformer';
24
+ import { stylesSchemaMock } from './__mocks__/styles-schema';
25
+
26
+ jest.mock( '../get-styles-schema' );
27
+
28
+ describe( 'styles-renderer', () => {
29
+ beforeEach( () => {
30
+ jest.mocked( getStylesSchema ).mockReturnValue( stylesSchemaMock );
31
+ } );
32
+
33
+ /**
34
+ * Prop Types
35
+ */
36
+
37
+ it( 'should transform stroke (including also size, number, string & color)', () => {
38
+ const styleDef = createMockStyleDefinition( {
39
+ id: 'test',
40
+ props: {
41
+ 'text-stroke': strokePropTypeUtil.create( {
42
+ width: sizePropTypeUtil.create( {
43
+ size: 1,
44
+ unit: 'px',
45
+ } ),
46
+ color: colorPropTypeUtil.create( '#000000' ),
47
+ } ),
48
+ },
49
+ } );
50
+
51
+ const cssString = render( {
52
+ styles: [ styleDef ],
53
+ transformers,
54
+ breakpoints: mockBreakpoints,
55
+ } );
56
+
57
+ expect( cssString ).toBe( `<style data-style-id="test">.test{text-stroke:1px #000000;}</style>` );
58
+ } );
59
+
60
+ it( 'should transform box-shadow (including also shadow)', () => {
14
61
  // Arrange.
15
- const styleRule = `.${ singleVariantStyleMock.id }{font-size:24px;font-weight:bold}`;
62
+ const shadow = shadowPropTypeUtil.create( {
63
+ hOffset: sizePropTypeUtil.create( {
64
+ size: 1,
65
+ unit: 'px',
66
+ } ),
67
+ vOffset: sizePropTypeUtil.create( {
68
+ size: 1,
69
+ unit: 'px',
70
+ } ),
71
+ blur: sizePropTypeUtil.create( {
72
+ size: 1,
73
+ unit: 'px',
74
+ } ),
75
+ spread: sizePropTypeUtil.create( {
76
+ size: 1,
77
+ unit: 'px',
78
+ } ),
79
+ color: colorPropTypeUtil.create( '#000000' ),
80
+ } );
81
+
82
+ const shadowInset = shadowPropTypeUtil.create(
83
+ ( prev ) => ( {
84
+ ...prev,
85
+ position: 'inset',
86
+ } ),
87
+ { base: shadow }
88
+ );
89
+
90
+ const styleDef = createMockStyleDefinition( {
91
+ id: 'test',
92
+ props: {
93
+ 'box-shadow': boxShadowPropTypeUtil.create( [ shadow, shadowInset ] ),
94
+ },
95
+ } );
16
96
 
17
97
  // Act.
18
- const cssString = createStyles( {
19
- styles: [ singleVariantStyleMock ],
20
- transformers: {},
98
+ const cssString = render( {
99
+ styles: [ styleDef ],
100
+ transformers,
21
101
  breakpoints: mockBreakpoints,
22
102
  } );
23
103
 
24
104
  // Assert.
25
- expect( cssString ).toEqual( `<style data-style-id="${ singleVariantStyleMock.id }">${ styleRule }</style>` );
105
+ expect( cssString ).toBe(
106
+ `<style data-style-id="test">.test{box-shadow:1px 1px 1px 1px #000000,1px 1px 1px 1px #000000 inset;}</style>`
107
+ );
26
108
  } );
27
109
 
28
- it( 'should support breakpoints using media queries', () => {
110
+ it( 'should transform linked-dimensions (including also size, number & string)', () => {
29
111
  // Arrange.
30
- const className = `.${ breakpointsStyleMock.id }`;
31
- const defaultStyleRule = `${ className }{padding:24px}`;
32
- const smStyleRule = `@media(max-width:768px){${ className }{padding:4px}}`;
33
- const mdStyleRule = `@media(max-width:992px){${ className }{padding:16px}}`;
112
+ const styleDef = createMockStyleDefinition( {
113
+ id: 'test',
114
+ props: {
115
+ padding: linkedDimensionsPropTypeUtil.create( {
116
+ top: sizePropTypeUtil.create( {
117
+ size: 10,
118
+ unit: 'px',
119
+ } ),
120
+ right: sizePropTypeUtil.create( {
121
+ size: 20,
122
+ unit: 'px',
123
+ } ),
124
+ bottom: sizePropTypeUtil.create( {
125
+ size: 30,
126
+ unit: 'px',
127
+ } ),
128
+ left: sizePropTypeUtil.create( {
129
+ size: 40,
130
+ unit: 'px',
131
+ } ),
132
+ } ),
133
+ },
134
+ } );
135
+
136
+ // Act.
137
+ const cssString = render( {
138
+ styles: [ styleDef ],
139
+ transformers,
140
+ breakpoints: mockBreakpoints,
141
+ } );
142
+
143
+ // Assert.
144
+ expect( cssString ).toBe(
145
+ `<style data-style-id="test">.test{padding-top:10px;padding-right:20px;padding-bottom:30px;padding-left:40px;}</style>`
146
+ );
147
+ } );
34
148
 
149
+ it( 'should transform border-width (including also size, number & string)', () => {
150
+ // Arrange.
151
+ const styleDef = createMockStyleDefinition( {
152
+ id: 'test',
153
+ props: {
154
+ 'border-width': borderWidthPropTypeUtil.create( {
155
+ top: sizePropTypeUtil.create( {
156
+ size: 10,
157
+ unit: 'px',
158
+ } ),
159
+ right: sizePropTypeUtil.create( {
160
+ size: 20,
161
+ unit: 'px',
162
+ } ),
163
+ bottom: sizePropTypeUtil.create( {
164
+ size: 30,
165
+ unit: 'px',
166
+ } ),
167
+ left: sizePropTypeUtil.create( {
168
+ size: 40,
169
+ unit: 'px',
170
+ } ),
171
+ } ),
172
+ },
173
+ } );
35
174
  // Act.
36
- const cssString = createStyles( {
37
- styles: [ breakpointsStyleMock ],
38
- transformers: {},
175
+ const cssString = render( {
176
+ styles: [ styleDef ],
177
+ transformers,
39
178
  breakpoints: mockBreakpoints,
40
179
  } );
41
180
 
42
181
  // Assert.
43
- expect( cssString ).toEqual(
44
- `<style data-style-id="${ breakpointsStyleMock.id }">${ [ defaultStyleRule, smStyleRule, mdStyleRule ].join(
45
- ''
46
- ) }</style>`
182
+ expect( cssString ).toBe(
183
+ `<style data-style-id="test">.test{border-top-width:10px;border-right-width:20px;border-bottom-width:30px;border-left-width:40px;}</style>`
47
184
  );
48
185
  } );
49
186
 
50
- it( 'should support states using pseudo selectors', () => {
187
+ it( 'should transform border-radius (including also union, size, number & string)', () => {
51
188
  // Arrange.
52
- const className = `.${ statesStyleMock.id }`;
53
- const defaultStyleRule = `${ className }{font-weight:normal}`;
54
- const hoverStyleRule = `${ className }:hover{font-weight:bold}`;
55
- const focusStyleRule = `${ className }:focus{color:red}`;
189
+ const styleDef = createMockStyleDefinition( {
190
+ id: 'test',
191
+ props: {
192
+ 'border-radius': borderRadiusPropTypeUtil.create( {
193
+ 'top-left': sizePropTypeUtil.create( {
194
+ size: 10,
195
+ unit: 'px',
196
+ } ),
197
+ 'top-right': sizePropTypeUtil.create( {
198
+ size: 20,
199
+ unit: 'px',
200
+ } ),
201
+ 'bottom-right': sizePropTypeUtil.create( {
202
+ size: 30,
203
+ unit: 'px',
204
+ } ),
205
+ 'bottom-left': sizePropTypeUtil.create( {
206
+ size: 40,
207
+ unit: 'px',
208
+ } ),
209
+ } ),
210
+ },
211
+ } );
56
212
 
57
213
  // Act.
58
- const cssString = createStyles( {
59
- styles: [ statesStyleMock ],
60
- transformers: {},
214
+ const cssString = render( {
215
+ styles: [ styleDef ],
216
+ transformers,
61
217
  breakpoints: mockBreakpoints,
62
218
  } );
63
219
 
64
220
  // Assert.
65
- expect( cssString ).toEqual(
66
- `<style data-style-id="${ breakpointsStyleMock.id }">${ [
67
- defaultStyleRule,
68
- hoverStyleRule,
69
- focusStyleRule,
70
- ].join( '' ) }</style>`
221
+ expect( cssString ).toBe(
222
+ `<style data-style-id="test">.test{border-top-left-radius:10px;border-top-right-radius:20px;border-bottom-right-radius:30px;border-bottom-left-radius:40px;}</style>`
71
223
  );
72
224
  } );
73
225
 
74
- it( 'should suppress non supported transformable values', () => {
226
+ it( 'should transform gap (including also size, number & string)', () => {
227
+ // Arrange.
228
+ const styleDef = createMockStyleDefinition( {
229
+ id: 'test',
230
+ props: {
231
+ gap: gapPropTypeUtil.create( {
232
+ isLinked: true,
233
+ row: sizePropTypeUtil.create( {
234
+ size: 10,
235
+ unit: 'px',
236
+ } ),
237
+ column: sizePropTypeUtil.create( {
238
+ size: 20,
239
+ unit: 'px',
240
+ } ),
241
+ } ),
242
+ },
243
+ } );
244
+
245
+ // Act.
246
+ const cssString = render( {
247
+ styles: [ styleDef ],
248
+ transformers,
249
+ breakpoints: mockBreakpoints,
250
+ } );
251
+
252
+ // Assert.
253
+ expect( cssString ).toBe( `<style data-style-id="test">.test{column-gap:20px;row-gap:10px;}</style>` );
254
+ } );
255
+ /**
256
+ * Features
257
+ */
258
+
259
+ it( 'should render media queries', () => {
75
260
  // Arrange.
76
- const defaultStyleRule = `.${ transformableStyleMock.id }{font-size:unset}`;
261
+ const styleDef: StyleDefinition = {
262
+ id: 'test',
263
+ type: 'class',
264
+ label: 'Test',
265
+ variants: [
266
+ {
267
+ meta: {
268
+ breakpoint: null,
269
+ state: null,
270
+ },
271
+ props: {
272
+ 'font-size': sizePropTypeUtil.create( {
273
+ size: 24,
274
+ unit: 'px',
275
+ } ),
276
+ },
277
+ },
278
+
279
+ {
280
+ meta: {
281
+ breakpoint: 'tablet',
282
+ state: null,
283
+ },
284
+ props: {
285
+ 'font-size': sizePropTypeUtil.create( {
286
+ size: 18,
287
+ unit: 'px',
288
+ } ),
289
+ },
290
+ },
291
+
292
+ {
293
+ meta: {
294
+ breakpoint: 'mobile',
295
+ state: null,
296
+ },
297
+ props: {
298
+ 'font-size': sizePropTypeUtil.create( {
299
+ size: 12,
300
+ unit: 'px',
301
+ } ),
302
+ },
303
+ },
304
+ ],
305
+ };
77
306
 
78
307
  // Act.
79
- const cssString = createStyles( {
80
- styles: [ transformableStyleMock ],
81
- transformers: {},
308
+ const cssString = render( {
309
+ styles: [ styleDef ],
310
+ transformers,
82
311
  breakpoints: mockBreakpoints,
83
312
  } );
84
313
 
85
314
  // Assert.
86
- expect( console ).toHaveErrored();
87
- expect( cssString ).toEqual(
88
- `<style data-style-id="${ transformableStyleMock.id }">${ defaultStyleRule }</style>`
315
+ const defaultStyle = '.test{font-size:24px;}';
316
+ const tabletStyle = '@media(max-width:992px){.test{font-size:18px;}}';
317
+ const mobileStyle = '@media(max-width:768px){.test{font-size:12px;}}';
318
+
319
+ expect( cssString ).toBe(
320
+ `<style data-style-id="test">${ defaultStyle }${ tabletStyle }${ mobileStyle }</style>`
89
321
  );
90
322
  } );
91
323
 
92
- it( 'should support known transformable values', () => {
324
+ it( 'should render pseudo classes', () => {
93
325
  // Arrange.
94
- const defaultStyleRule = `.${ transformableStyleMock.id }{font-size:24px}`;
326
+ const styleDef: StyleDefinition = {
327
+ id: 'test',
328
+ type: 'class',
329
+ label: 'Test',
330
+ variants: [
331
+ {
332
+ meta: {
333
+ breakpoint: null,
334
+ state: null,
335
+ },
336
+ props: {
337
+ 'font-size': sizePropTypeUtil.create( {
338
+ size: 24,
339
+ unit: 'px',
340
+ } ),
341
+ },
342
+ },
343
+
344
+ {
345
+ meta: {
346
+ breakpoint: null,
347
+ state: 'hover',
348
+ },
349
+ props: {
350
+ 'font-size': sizePropTypeUtil.create( {
351
+ size: 18,
352
+ unit: 'px',
353
+ } ),
354
+ },
355
+ },
356
+
357
+ {
358
+ meta: {
359
+ breakpoint: 'mobile',
360
+ state: 'focus',
361
+ },
362
+ props: {
363
+ 'font-size': sizePropTypeUtil.create( {
364
+ size: 12,
365
+ unit: 'px',
366
+ } ),
367
+ },
368
+ },
369
+ ],
370
+ };
95
371
 
96
372
  // Act.
97
- const cssString = createStyles( {
98
- styles: [ transformableStyleMock ],
99
- transformers: { size: transformers.size },
373
+ const cssString = render( {
374
+ styles: [ styleDef ],
375
+ transformers,
100
376
  breakpoints: mockBreakpoints,
101
377
  } );
102
378
 
103
379
  // Assert.
104
- expect( cssString ).toEqual(
105
- `<style data-style-id="${ transformableStyleMock.id }">${ defaultStyleRule }</style>`
380
+ const defaultStyle = '.test{font-size:24px;}';
381
+ const hoverStyle = '.test:hover{font-size:18px;}';
382
+ const focusStyle = '@media(max-width:768px){.test:focus{font-size:12px;}}';
383
+
384
+ expect( cssString ).toBe(
385
+ `<style data-style-id="test">${ defaultStyle }${ hoverStyle }${ focusStyle }</style>`
106
386
  );
107
387
  } );
108
388
 
109
- it( 'should support multi variants of mixed variation types', () => {
389
+ it( 'should skip disabled props', () => {
390
+ // Arrange.
391
+ const styleDef = createMockStyleDefinition( {
392
+ id: 'test',
393
+ props: {
394
+ 'font-size': sizePropTypeUtil.create( {
395
+ size: 24,
396
+ unit: 'px',
397
+ } ),
398
+ padding: sizePropTypeUtil.create(
399
+ {
400
+ size: 24,
401
+ unit: 'px',
402
+ },
403
+ { disabled: true }
404
+ ),
405
+ },
406
+ } );
407
+
408
+ // Act.
409
+ const cssString = render( {
410
+ styles: [ styleDef ],
411
+ transformers,
412
+ breakpoints: mockBreakpoints,
413
+ } );
414
+
415
+ // Assert.
416
+ expect( cssString ).toBe( `<style data-style-id="test">.test{font-size:24px;}</style>` );
417
+ } );
418
+
419
+ it( 'should fallback to default value when there is no value', () => {
420
+ // Arrange.
421
+ const styleDef = createMockStyleDefinition( {
422
+ id: 'test',
423
+ props: {},
424
+ } );
425
+
426
+ jest.mocked( getStylesSchema ).mockReturnValue( {
427
+ overflow: {
428
+ kind: 'plain',
429
+ key: 'string',
430
+ default: {
431
+ $$type: 'string',
432
+ value: 'hidden',
433
+ },
434
+ settings: {},
435
+ meta: {},
436
+ },
437
+ } );
438
+
439
+ // Act.
440
+ const cssString = render( {
441
+ styles: [ styleDef ],
442
+ transformers,
443
+ breakpoints: mockBreakpoints,
444
+ } );
445
+
446
+ // Assert.
447
+ expect( cssString ).toBe( `<style data-style-id="test">.test{overflow:hidden;}</style>` );
448
+ } );
449
+
450
+ it( 'should skip props that are not in the schema', () => {
451
+ // Arrange.
452
+ const styleDef = createMockStyleDefinition( {
453
+ id: 'test',
454
+ props: {
455
+ 'font-size': sizePropTypeUtil.create( {
456
+ size: 24,
457
+ unit: 'px',
458
+ } ),
459
+ 'not-a-css-prop': sizePropTypeUtil.create( {
460
+ size: 24,
461
+ unit: 'px',
462
+ } ),
463
+ },
464
+ } );
465
+
466
+ // Act.
467
+ const cssString = render( {
468
+ styles: [ styleDef ],
469
+ transformers,
470
+ breakpoints: mockBreakpoints,
471
+ } );
472
+
473
+ // Assert.
474
+ expect( cssString ).toBe( `<style data-style-id="test">.test{font-size:24px;}</style>` );
475
+ } );
476
+
477
+ it( "should skip props that don't have a transformer", () => {
110
478
  // Arrange.
111
- const className = `.${ multiVariantsStyleMock.id }`;
112
- const defaultStyleRule = `${ className }{font-size:24px;font-weight:normal}`;
113
- const smStyleRule = `@media(max-width:768px){${ className }{font-size:20px}}`;
114
- const hoverStyleRule = `${ className }:hover{font-weight:bold}`;
479
+ const styleDef = createMockStyleDefinition( {
480
+ id: 'test',
481
+ props: {
482
+ 'font-size': sizePropTypeUtil.create( {
483
+ size: 24,
484
+ unit: 'px',
485
+ } ),
486
+ padding: {
487
+ $$type: 'invalid',
488
+ value: 'invalid',
489
+ },
490
+ },
491
+ } );
115
492
 
116
493
  // Act.
117
- const cssString = createStyles( {
118
- styles: [ multiVariantsStyleMock ],
119
- transformers: { size: transformers.size },
494
+ const cssString = render( {
495
+ styles: [ styleDef ],
496
+ transformers,
120
497
  breakpoints: mockBreakpoints,
121
498
  } );
122
499
 
123
500
  // Assert.
124
- expect( cssString ).toEqual(
125
- `<style data-style-id="${ multiVariantsStyleMock.id }">${ [
126
- defaultStyleRule,
127
- smStyleRule,
128
- hoverStyleRule,
129
- ].join( '' ) }</style>`
501
+ expect( cssString ).toBe( `<style data-style-id="test">.test{font-size:24px;}</style>` );
502
+ } );
503
+
504
+ it( 'should skip props when their transformer throws an error', () => {
505
+ // Arrange.
506
+ const styleDef = createMockStyleDefinition( {
507
+ id: 'test',
508
+ props: {
509
+ 'font-size': '24px',
510
+ padding: sizePropTypeUtil.create( {
511
+ size: 24,
512
+ unit: 'px',
513
+ } ),
514
+ },
515
+ } );
516
+
517
+ // Act.
518
+ const cssString = render( {
519
+ styles: [ styleDef ],
520
+ transformers: {
521
+ size: () => {
522
+ throw new Error( 'Test error' );
523
+ },
524
+ },
525
+ breakpoints: mockBreakpoints,
526
+ } );
527
+
528
+ // Assert.
529
+ expect( cssString ).toBe( `<style data-style-id="test">.test{font-size:24px;}</style>` );
530
+ } );
531
+
532
+ it( 'should consider 0 as valid value', () => {
533
+ // Arrange.
534
+ const styleDef = createMockStyleDefinition( {
535
+ id: 'test',
536
+ props: {
537
+ 'font-size': sizePropTypeUtil.create( {
538
+ size: 0,
539
+ unit: 'px',
540
+ } ),
541
+ },
542
+ } );
543
+
544
+ // Act.
545
+ const cssString = render( {
546
+ styles: [ styleDef ],
547
+ transformers,
548
+ breakpoints: mockBreakpoints,
549
+ } );
550
+
551
+ // Assert.
552
+ expect( cssString ).toBe( `<style data-style-id="test">.test{font-size:0px;}</style>` );
553
+ } );
554
+ } );
555
+
556
+ const backgroundExpectationWrapper = ( id: string, bgShorthand: string ) => {
557
+ return `<style data-style-id="${ id }">.${ id }{background:${ bgShorthand };}</style>`;
558
+ };
559
+
560
+ describe( 'background-transformer', () => {
561
+ beforeEach( () => {
562
+ jest.mocked( getStylesSchema ).mockReturnValue( stylesSchemaMock );
563
+ } );
564
+
565
+ it( 'should transform background color', () => {
566
+ // Arrange.
567
+ const styleDef = createMockStyleDefinition( {
568
+ id: 'bg-color',
569
+ props: {
570
+ background: backgroundPropTypeUtil.create( {
571
+ color: colorPropTypeUtil.create( '#ee00ff' ),
572
+ } ),
573
+ },
574
+ } );
575
+
576
+ // Act.
577
+ const cssString = render( {
578
+ styles: [ styleDef ],
579
+ transformers,
580
+ breakpoints: mockBreakpoints,
581
+ } );
582
+
583
+ // Assert.
584
+ expect( cssString ).toBe( backgroundExpectationWrapper( 'bg-color', '#ee00ff' ) );
585
+ } );
586
+
587
+ it( 'should transform background overlay (repeater)', () => {
588
+ // Arrange.
589
+ const styleDef = createMockStyleDefinition( {
590
+ id: 'test',
591
+ props: {
592
+ background: backgroundPropTypeUtil.create( {
593
+ 'background-overlay': backgroundOverlayPropTypeUtil.create( [
594
+ backgroundColorOverlayPropTypeUtil.create( 'blue' ),
595
+ backgroundColorOverlayPropTypeUtil.create( 'yellow' ),
596
+ ] ),
597
+ } ),
598
+ },
599
+ } );
600
+
601
+ // Act.
602
+ const cssString = render( {
603
+ styles: [ styleDef ],
604
+ transformers,
605
+ breakpoints: mockBreakpoints,
606
+ } );
607
+
608
+ // Assert.
609
+ expect( cssString ).toBe(
610
+ backgroundExpectationWrapper( 'test', 'linear-gradient(blue, blue),linear-gradient(yellow, yellow)' )
611
+ );
612
+ } );
613
+
614
+ it( 'should transform background (including also background-overlay & color)', () => {
615
+ // Arrange.
616
+ const styleDef = createMockStyleDefinition( {
617
+ id: 'test',
618
+ props: {
619
+ background: backgroundPropTypeUtil.create( {
620
+ color: colorPropTypeUtil.create( '#000' ),
621
+ 'background-overlay': backgroundOverlayPropTypeUtil.create( [
622
+ backgroundColorOverlayPropTypeUtil.create( '#FFFFFF' ),
623
+ backgroundColorOverlayPropTypeUtil.create( '#FF2222' ),
624
+ ] ),
625
+ } ),
626
+ },
627
+ } );
628
+
629
+ // Act.
630
+ const cssString = render( {
631
+ styles: [ styleDef ],
632
+ transformers,
633
+ breakpoints: mockBreakpoints,
634
+ } );
635
+
636
+ // Assert.
637
+ expect( cssString ).toBe(
638
+ backgroundExpectationWrapper(
639
+ 'test',
640
+ 'linear-gradient(#FFFFFF, #FFFFFF),linear-gradient(#FF2222, #FF2222) #000'
641
+ )
130
642
  );
131
643
  } );
132
644
  } );
645
+
646
+ describe( 'background-overlay-transformer', () => {
647
+ it( 'should return empty if background-overlay is invalid', () => {
648
+ // Arrange.
649
+ const initialData = {
650
+ 'background-overlay': null,
651
+ };
652
+
653
+ // Act.
654
+ const result = backgroundTransformer( initialData, 'background-overlay' );
655
+
656
+ // Assert.
657
+ expect( result ).toBe( '' );
658
+ } );
659
+
660
+ it( 'should transform only valid background color', () => {
661
+ // Arrange.
662
+ const backgroundColor = 'rgba(255, 0, 255, 0.9)';
663
+
664
+ const initialData = {
665
+ color: backgroundColor,
666
+ };
667
+
668
+ // Act.
669
+ const result = backgroundTransformer( initialData, 'background-overlay' );
670
+
671
+ // Assert.
672
+ expect( result ).toBe( backgroundColor );
673
+ } );
674
+
675
+ it( 'should transform only background overlay color', () => {
676
+ // Arrange.
677
+ const backgroundOverlayColor = 'rgba(0, 0, 0, 0.5)';
678
+ const expected = `linear-gradient(${ backgroundOverlayColor }, ${ backgroundOverlayColor })`;
679
+
680
+ const initialData = {
681
+ 'background-overlay': `linear-gradient(${ backgroundOverlayColor }, ${ backgroundOverlayColor })`,
682
+ };
683
+
684
+ // Act.
685
+ const result = backgroundTransformer( initialData, 'background-overlay' );
686
+
687
+ // Assert.
688
+ expect( result ).toBe( expected );
689
+ } );
690
+ } );
691
+
692
+ const mockBreakpoints = {
693
+ tablet: {
694
+ id: 'tablet',
695
+ width: 992,
696
+ label: 'Tablet Portrait',
697
+ type: 'max-width',
698
+ },
699
+ mobile: {
700
+ id: 'mobile',
701
+ width: 768,
702
+ label: 'Mobile Portrait',
703
+ type: 'max-width',
704
+ },
705
+ } as BreakpointsMap;