@elementor/editor-canvas 0.8.0 → 0.10.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 (57) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +29 -0
  3. package/dist/index.d.mts +13 -1
  4. package/dist/index.d.ts +13 -1
  5. package/dist/index.js +203 -220
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +192 -222
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +5 -5
  10. package/src/{renderers/__tests__ → __tests__}/__mocks__/styles-schema.ts +11 -4
  11. package/src/__tests__/init-styles-renderer.test.ts +8 -3
  12. package/src/{renderers/__tests__/create-props-resolver.transformers.test.ts → __tests__/styles-prop-resolver.test.ts} +23 -27
  13. package/src/index.ts +2 -0
  14. package/src/init-style-transformers.ts +58 -0
  15. package/src/init-styles-renderer.ts +8 -6
  16. package/src/init.tsx +2 -0
  17. package/src/renderers/__tests__/create-props-resolver.test.ts +43 -34
  18. package/src/renderers/__tests__/render-styles.test.ts +3 -15
  19. package/src/renderers/create-props-resolver.ts +32 -31
  20. package/src/renderers/render-styles.ts +4 -7
  21. package/src/style-transformers-registry.ts +3 -0
  22. package/src/transformers/create-transformer.ts +6 -0
  23. package/src/transformers/create-transformers-registry.ts +16 -0
  24. package/src/transformers/styles/background-color-overlay-transformer.ts +5 -0
  25. package/src/transformers/styles/background-image-overlay-transformer.ts +28 -0
  26. package/src/transformers/styles/background-image-position-offset-transformer.ts +10 -0
  27. package/src/transformers/styles/background-image-size-scale-transformer.ts +10 -0
  28. package/src/transformers/styles/background-transformer.ts +13 -0
  29. package/src/transformers/styles/create-combine-array-transformer.ts +5 -0
  30. package/src/transformers/styles/create-multi-props-transformer.ts +14 -0
  31. package/src/transformers/styles/image-attachment-transformer.ts +15 -0
  32. package/src/transformers/styles/image-src-transformer.ts +11 -0
  33. package/src/transformers/styles/image-transformer.ts +34 -0
  34. package/src/transformers/styles/primitive-transformer.ts +3 -0
  35. package/src/transformers/styles/shadow-transformer.ts +16 -0
  36. package/src/transformers/styles/size-transformer.ts +10 -0
  37. package/src/transformers/styles/stroke-transformer.ts +17 -0
  38. package/src/transformers/types.ts +14 -0
  39. package/src/renderers/style-transformers/background-color-overlay-transformer.ts +0 -9
  40. package/src/renderers/style-transformers/background-image-overlay-transformer.ts +0 -24
  41. package/src/renderers/style-transformers/background-image-position-offset-transformer.ts +0 -10
  42. package/src/renderers/style-transformers/background-image-size-scale-transformer.ts +0 -10
  43. package/src/renderers/style-transformers/background-transformer.ts +0 -12
  44. package/src/renderers/style-transformers/create-combine-array-transformer.ts +0 -9
  45. package/src/renderers/style-transformers/create-corner-sizes-transformer.ts +0 -31
  46. package/src/renderers/style-transformers/create-edge-sizes-transformer.ts +0 -31
  47. package/src/renderers/style-transformers/dimensions.ts +0 -20
  48. package/src/renderers/style-transformers/image-attachment.ts +0 -14
  49. package/src/renderers/style-transformers/image-src.ts +0 -8
  50. package/src/renderers/style-transformers/image.ts +0 -25
  51. package/src/renderers/style-transformers/index.ts +0 -48
  52. package/src/renderers/style-transformers/layout-direction-transformer.ts +0 -20
  53. package/src/renderers/style-transformers/primitive-transformer.ts +0 -7
  54. package/src/renderers/style-transformers/shadow-transformer.ts +0 -11
  55. package/src/renderers/style-transformers/size-transformer.ts +0 -9
  56. package/src/renderers/style-transformers/stroke-transformer.ts +0 -9
  57. package/src/renderers/types.ts +0 -12
@@ -5,16 +5,16 @@ import { createPropsResolver } from '../create-props-resolver';
5
5
  describe( 'createPropsResolver', () => {
6
6
  it( 'should resolve simple props', async () => {
7
7
  // Arrange.
8
- const resolve = createPropsResolver( { int: ( value ) => value + 1 } );
8
+ const resolve = createPropsResolver( {
9
+ transformers: { int: ( value ) => value + 1 },
10
+ schema: { int: createMockPropType( { kind: 'plain', key: 'int' } ) },
11
+ } );
9
12
 
10
13
  // Act.
11
14
  const result = await resolve( {
12
15
  props: {
13
16
  int: { $$type: 'int', value: 0 },
14
17
  },
15
- schema: {
16
- int: createMockPropType( { kind: 'plain', key: 'int' } ),
17
- },
18
18
  } );
19
19
 
20
20
  // Assert.
@@ -23,7 +23,10 @@ describe( 'createPropsResolver', () => {
23
23
 
24
24
  it( 'should skip disabled props', async () => {
25
25
  // Arrange.
26
- const resolve = createPropsResolver( { int: ( value ) => value + 1 } );
26
+ const resolve = createPropsResolver( {
27
+ transformers: { int: ( value ) => value + 1 },
28
+ schema: { int: createMockPropType( { kind: 'plain', key: 'int' } ) },
29
+ } );
27
30
 
28
31
  // Act.
29
32
  const result = await resolve( {
@@ -34,9 +37,6 @@ describe( 'createPropsResolver', () => {
34
37
  disabled: true,
35
38
  },
36
39
  },
37
- schema: {
38
- int: createMockPropType( { kind: 'plain', key: 'int' } ),
39
- },
40
40
  } );
41
41
 
42
42
  // Assert.
@@ -45,11 +45,8 @@ describe( 'createPropsResolver', () => {
45
45
 
46
46
  it( 'should fallback to default value when there is no value', async () => {
47
47
  // Arrange.
48
- const resolve = createPropsResolver( { int: ( value ) => value + 1 } );
49
-
50
- // Act.
51
- const result = await resolve( {
52
- props: {},
48
+ const resolve = createPropsResolver( {
49
+ transformers: { int: ( value ) => value + 1 },
53
50
  schema: {
54
51
  int: createMockPropType( {
55
52
  kind: 'plain',
@@ -59,13 +56,21 @@ describe( 'createPropsResolver', () => {
59
56
  },
60
57
  } );
61
58
 
59
+ // Act.
60
+ const result = await resolve( { props: {} } );
61
+
62
62
  // Assert.
63
63
  expect( result ).toEqual( { int: 4 } );
64
64
  } );
65
65
 
66
66
  it( 'should skip props that are not in the schema', async () => {
67
67
  // Arrange.
68
- const resolve = createPropsResolver( { int: ( value ) => value + 1 } );
68
+ const resolve = createPropsResolver( {
69
+ transformers: { int: ( value ) => value + 1 },
70
+ schema: {
71
+ int: createMockPropType( { kind: 'plain', key: 'int' } ),
72
+ },
73
+ } );
69
74
 
70
75
  // Act.
71
76
  const result = await resolve( {
@@ -79,9 +84,6 @@ describe( 'createPropsResolver', () => {
79
84
  value: 1,
80
85
  },
81
86
  },
82
- schema: {
83
- int: createMockPropType( { kind: 'plain', key: 'int' } ),
84
- },
85
87
  } );
86
88
 
87
89
  // Assert.
@@ -90,7 +92,13 @@ describe( 'createPropsResolver', () => {
90
92
 
91
93
  it( "should skip props that don't have a transformer", async () => {
92
94
  // Arrange.
93
- const resolve = createPropsResolver( { int: ( value ) => value + 1 } );
95
+ const resolve = createPropsResolver( {
96
+ transformers: { int: ( value ) => value + 1 },
97
+ schema: {
98
+ int: createMockPropType( { kind: 'plain', key: 'int' } ),
99
+ invalid: createMockPropType( { kind: 'plain', key: 'invalid' } ),
100
+ },
101
+ } );
94
102
 
95
103
  // Act.
96
104
  const result = await resolve( {
@@ -104,10 +112,6 @@ describe( 'createPropsResolver', () => {
104
112
  value: 1,
105
113
  },
106
114
  },
107
- schema: {
108
- int: createMockPropType( { kind: 'plain', key: 'int' } ),
109
- invalid: createMockPropType( { kind: 'plain', key: 'invalid' } ),
110
- },
111
115
  } );
112
116
 
113
117
  // Assert.
@@ -116,9 +120,15 @@ describe( 'createPropsResolver', () => {
116
120
 
117
121
  it( 'should skip props when their transformer throws an error', async () => {
118
122
  const resolve = createPropsResolver( {
119
- int: ( value ) => value + 1,
120
- throws: () => {
121
- throw new Error( 'Not Working!' );
123
+ transformers: {
124
+ int: ( value ) => value + 1,
125
+ throws: () => {
126
+ throw new Error( 'Not Working!' );
127
+ },
128
+ },
129
+ schema: {
130
+ int: createMockPropType( { kind: 'plain', key: 'int' } ),
131
+ invalid: createMockPropType( { kind: 'plain', key: 'throws' } ),
122
132
  },
123
133
  } );
124
134
 
@@ -134,10 +144,6 @@ describe( 'createPropsResolver', () => {
134
144
  value: 1,
135
145
  },
136
146
  },
137
- schema: {
138
- int: createMockPropType( { kind: 'plain', key: 'int' } ),
139
- invalid: createMockPropType( { kind: 'plain', key: 'throws' } ),
140
- },
141
147
  } );
142
148
 
143
149
  // Assert.
@@ -147,7 +153,14 @@ describe( 'createPropsResolver', () => {
147
153
  it( 'should trigger onResolve when resolving a prop', async () => {
148
154
  const onResolve = jest.fn();
149
155
 
150
- const resolve = createPropsResolver( { int: ( value ) => value + 1 }, { onPropResolve: onResolve } );
156
+ const resolve = createPropsResolver( {
157
+ transformers: { int: ( value ) => value + 1 },
158
+ schema: {
159
+ int: createMockPropType( { kind: 'plain', key: 'int' } ),
160
+ int2: createMockPropType( { kind: 'plain', key: 'int' } ),
161
+ },
162
+ onPropResolve: onResolve,
163
+ } );
151
164
 
152
165
  // Act.
153
166
  await resolve( {
@@ -161,10 +174,6 @@ describe( 'createPropsResolver', () => {
161
174
  value: 3,
162
175
  },
163
176
  },
164
- schema: {
165
- int: createMockPropType( { kind: 'plain', key: 'int' } ),
166
- int2: createMockPropType( { kind: 'plain', key: 'int' } ),
167
- },
168
177
  } );
169
178
 
170
179
  // Assert.
@@ -1,18 +1,10 @@
1
1
  /* eslint-disable testing-library/render-result-naming-convention */
2
- import { createMockPropType } from 'test-utils';
3
2
  import type { BreakpointsMap } from '@elementor/editor-responsive';
4
- import { getStylesSchema, type StyleDefinition } from '@elementor/editor-styles';
3
+ import { type StyleDefinition } from '@elementor/editor-styles';
5
4
 
6
5
  import renderStyles from '../render-styles';
7
- import { stylesSchemaMock } from './__mocks__/styles-schema';
8
-
9
- jest.mock( '@elementor/editor-styles' );
10
6
 
11
7
  describe( 'renderStyles', () => {
12
- beforeEach( () => {
13
- jest.mocked( getStylesSchema ).mockReturnValue( stylesSchemaMock );
14
- } );
15
-
16
8
  it( 'should render media queries', async () => {
17
9
  // Arrange.
18
10
  const styleDef: StyleDefinition = {
@@ -32,14 +24,12 @@ describe( 'renderStyles', () => {
32
24
  };
33
25
 
34
26
  const resolve = jest.fn( ( { props } ) => props );
35
- const schema = { 'font-size': createMockPropType( { kind: 'plain', key: 'string' } ) };
36
27
 
37
28
  // Act.
38
29
  const cssString = await renderStyles( {
39
30
  styles: [ styleDef ],
40
31
  resolve,
41
32
  breakpoints: { tablet: { width: 992, type: 'max-width' } } as BreakpointsMap,
42
- schema,
43
33
  } );
44
34
 
45
35
  // Assert.
@@ -49,8 +39,8 @@ describe( 'renderStyles', () => {
49
39
  expect( cssString ).toBe( `<style data-style-id="test">${ defaultStyle }${ tabletStyle }</style>` );
50
40
 
51
41
  expect( resolve ).toHaveBeenCalledTimes( 2 );
52
- expect( resolve ).toHaveBeenNthCalledWith( 1, { props: { 'font-size': '24px' }, schema } );
53
- expect( resolve ).toHaveBeenNthCalledWith( 2, { props: { 'font-size': '18px' }, schema } );
42
+ expect( resolve ).toHaveBeenNthCalledWith( 1, { props: { 'font-size': '24px' } } );
43
+ expect( resolve ).toHaveBeenNthCalledWith( 2, { props: { 'font-size': '18px' } } );
54
44
  } );
55
45
 
56
46
  it( 'should render pseudo classes', async () => {
@@ -82,7 +72,6 @@ describe( 'renderStyles', () => {
82
72
  styles: [ styleDef ],
83
73
  resolve,
84
74
  breakpoints: { mobile: { width: 768, type: 'max-width' } } as BreakpointsMap,
85
- schema: { 'font-size': createMockPropType( { kind: 'plain', key: 'string' } ) },
86
75
  } );
87
76
 
88
77
  // Assert.
@@ -115,7 +104,6 @@ describe( 'renderStyles', () => {
115
104
  const result = await renderStyles( {
116
105
  styles: [ styleDef ],
117
106
  resolve,
118
- schema: getStylesSchema(),
119
107
  selectorPrefix: '.elementor-prefix',
120
108
  breakpoints: {} as BreakpointsMap,
121
109
  } );
@@ -7,16 +7,18 @@ import {
7
7
  type PropValue,
8
8
  } from '@elementor/editor-props';
9
9
 
10
+ import { type TransformersMap } from '../transformers/types';
10
11
  import { getMultiPropsValue, isMultiProps } from './multi-props';
11
- import { type TransformersMap } from './types';
12
12
 
13
- type CreatePropResolverOptions = {
13
+ type CreatePropResolverArgs = {
14
+ transformers: TransformersMap;
15
+ schema: PropsSchema;
14
16
  onPropResolve?: ( args: { key: string; value: unknown } ) => void;
15
17
  };
16
18
 
17
19
  type ResolveArgs = {
18
20
  props: Props;
19
- schema: PropsSchema;
21
+ schema?: PropsSchema;
20
22
  signal?: AbortSignal;
21
23
  };
22
24
 
@@ -32,10 +34,33 @@ export type PropsResolver = ReturnType< typeof createPropsResolver >;
32
34
 
33
35
  const TRANSFORM_DEPTH_LIMIT = 3;
34
36
 
35
- export function createPropsResolver(
36
- transformers: TransformersMap,
37
- { onPropResolve }: CreatePropResolverOptions = {}
38
- ) {
37
+ export function createPropsResolver( { transformers, schema: initialSchema, onPropResolve }: CreatePropResolverArgs ) {
38
+ async function resolve( { props, schema, signal }: ResolveArgs ) {
39
+ schema = schema ?? initialSchema;
40
+
41
+ const promises = Promise.all(
42
+ Object.entries( schema ).map( async ( [ key, type ] ) => {
43
+ const value = props[ key ] ?? type.default;
44
+
45
+ const transformed = await transform( { value, key, type, signal } );
46
+
47
+ if ( transformed === null ) {
48
+ return;
49
+ }
50
+
51
+ onPropResolve?.( { key, value: transformed } );
52
+
53
+ if ( isMultiProps( transformed ) ) {
54
+ return getMultiPropsValue( transformed );
55
+ }
56
+
57
+ return { [ key ]: transformed };
58
+ } )
59
+ );
60
+
61
+ return Object.assign( {}, ...( await promises ).filter( Boolean ) );
62
+ }
63
+
39
64
  async function transform( { value, key, type, signal, depth = 0 }: TransformArgs ) {
40
65
  if ( value === null || value === undefined ) {
41
66
  return null;
@@ -95,29 +120,5 @@ export function createPropsResolver(
95
120
  }
96
121
  }
97
122
 
98
- async function resolve( { props, schema, signal }: ResolveArgs ) {
99
- const promises = Promise.all(
100
- Object.entries( schema ).map( async ( [ key, type ] ) => {
101
- const value = props[ key ] ?? type.default;
102
-
103
- const transformed = await transform( { value, key, type, signal } );
104
-
105
- if ( transformed === null ) {
106
- return;
107
- }
108
-
109
- onPropResolve?.( { key, value: transformed } );
110
-
111
- if ( isMultiProps( transformed ) ) {
112
- return getMultiPropsValue( transformed );
113
- }
114
-
115
- return { [ key ]: transformed };
116
- } )
117
- );
118
-
119
- return Object.assign( {}, ...( await promises ).filter( Boolean ) );
120
- }
121
-
122
123
  return resolve;
123
124
  }
@@ -1,4 +1,4 @@
1
- import { type Props, type PropsSchema } from '@elementor/editor-props';
1
+ import { type Props } from '@elementor/editor-props';
2
2
  import { type Breakpoint, type BreakpointsMap } from '@elementor/editor-responsive';
3
3
  import { type StyleDefinition, type StyleDefinitionState, type StyleDefinitionType } from '@elementor/editor-styles';
4
4
 
@@ -8,7 +8,6 @@ import { UnknownStyleTypeError } from './errors';
8
8
  type RenderParams = {
9
9
  resolve: PropsResolver;
10
10
  styles: StyleDefinition[];
11
- schema: PropsSchema;
12
11
  breakpoints: BreakpointsMap;
13
12
  selectorPrefix?: string;
14
13
  signal?: AbortSignal;
@@ -16,7 +15,6 @@ type RenderParams = {
16
15
 
17
16
  type PropsToCssArgs = {
18
17
  props: Props;
19
- schema: PropsSchema;
20
18
  resolve: PropsResolver;
21
19
  signal?: AbortSignal;
22
20
  };
@@ -28,14 +26,13 @@ const SELECTORS_MAP: Record< StyleDefinitionType, string > = {
28
26
  export default async function renderStyles( {
29
27
  resolve,
30
28
  styles,
31
- schema,
32
29
  breakpoints,
33
30
  selectorPrefix = '',
34
31
  signal,
35
32
  }: RenderParams ) {
36
33
  const stylesCssPromises = styles.map( async ( style ) => {
37
34
  const variantCssPromises = Object.values( style.variants ).map( async ( variant ) => {
38
- const css = await propsToCss( { props: variant.props, schema, resolve, signal } );
35
+ const css = await propsToCss( { props: variant.props, resolve, signal } );
39
36
 
40
37
  return createStyleWrapper()
41
38
  .forStyle( style )
@@ -95,8 +92,8 @@ function createStyleWrapper( value: string = '', wrapper?: ( css: string ) => st
95
92
  };
96
93
  }
97
94
 
98
- async function propsToCss( { props, resolve, signal, schema }: PropsToCssArgs ) {
99
- const transformed = await resolve( { props, schema, signal } );
95
+ async function propsToCss( { props, resolve, signal }: PropsToCssArgs ) {
96
+ const transformed = await resolve( { props, signal } );
100
97
 
101
98
  return Object.entries( transformed )
102
99
  .reduce< string[] >( ( acc, [ propName, propValue ] ) => {
@@ -0,0 +1,3 @@
1
+ import { createTransformersRegistry } from './transformers/create-transformers-registry';
2
+
3
+ export const styleTransformersRegistry = createTransformersRegistry();
@@ -0,0 +1,6 @@
1
+ import { type Transformer } from './types';
2
+
3
+ // Wrap transformer for better DX (types) + it will allow us to add more features in the future.
4
+ export function createTransformer< TValue >( cb: Transformer< TValue > ): Transformer< TValue > {
5
+ return cb;
6
+ }
@@ -0,0 +1,16 @@
1
+ import { type AnyTransformer, type TransformerName, type TransformersMap } from './types';
2
+
3
+ export function createTransformersRegistry() {
4
+ const transformers: TransformersMap = {};
5
+
6
+ return {
7
+ register( name: TransformerName, transformer: AnyTransformer ) {
8
+ transformers[ name ] = transformer;
9
+
10
+ return this;
11
+ },
12
+ all() {
13
+ return transformers;
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,5 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ export const backgroundColorOverlayTransformer = createTransformer(
4
+ ( value: string ) => `linear-gradient(${ value }, ${ value })`
5
+ );
@@ -0,0 +1,28 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ const DEFAULT_POSITION_VALUE = '0% 0%';
4
+
5
+ type BackgroundImageOverlay = {
6
+ image?: string;
7
+ size?: string;
8
+ position?: string;
9
+ repeat?: string;
10
+ attachment?: string;
11
+ };
12
+
13
+ export const backgroundImageOverlayTransformer = createTransformer( ( value: BackgroundImageOverlay ) => {
14
+ const { image, size = null, position = null, repeat = null, attachment = null } = value;
15
+
16
+ if ( ! image ) {
17
+ return null;
18
+ }
19
+
20
+ const backgroundStyles = [
21
+ image,
22
+ repeat,
23
+ attachment,
24
+ size ? `${ position || DEFAULT_POSITION_VALUE } / ${ size }` : position,
25
+ ].filter( Boolean );
26
+
27
+ return backgroundStyles.join( ' ' );
28
+ } );
@@ -0,0 +1,10 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type BackgroundImagePositionOffset = {
4
+ x?: string;
5
+ y?: string;
6
+ };
7
+
8
+ export const backgroundImagePositionOffsetTransformer = createTransformer(
9
+ ( { x = '0px', y = '0px' }: BackgroundImagePositionOffset ) => `${ x } ${ y }`
10
+ );
@@ -0,0 +1,10 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type BackgroundImageSizeScale = {
4
+ width?: string;
5
+ height?: string;
6
+ };
7
+
8
+ export const backgroundImageSizeScaleTransformer = createTransformer(
9
+ ( { width = 'auto', height = 'auto' }: BackgroundImageSizeScale ) => `${ width } ${ height }`
10
+ );
@@ -0,0 +1,13 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type Background = {
4
+ 'background-overlay'?: string;
5
+ color?: string;
6
+ };
7
+
8
+ export const backgroundTransformer = createTransformer( ( value: Background ) => {
9
+ const overlays = value[ 'background-overlay' ] ?? '';
10
+ const color = value.color ?? '';
11
+
12
+ return `${ overlays } ${ color }`.trim();
13
+ } );
@@ -0,0 +1,5 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ export const createCombineArrayTransformer = ( delimiter: string ) => {
4
+ return createTransformer( ( value: Array< string | number > ) => value.filter( Boolean ).join( delimiter ) );
5
+ };
@@ -0,0 +1,14 @@
1
+ import { createMultiPropsValue } from '../../renderers/multi-props';
2
+ import { createTransformer } from '../create-transformer';
3
+
4
+ type KeyGenerator = ( { propKey, key }: { propKey: string; key: string } ) => string;
5
+
6
+ export const createMultiPropsTransformer = ( keys: string[], keyGenerator: KeyGenerator ) => {
7
+ return createTransformer( ( value: Record< string, string >, { key: propKey } ) => {
8
+ const entries = keys
9
+ .filter( ( key ) => value[ key ] )
10
+ .map( ( key ) => [ keyGenerator( { propKey, key } ), value[ key ] ] );
11
+
12
+ return createMultiPropsValue( Object.fromEntries( entries ) );
13
+ } );
14
+ };
@@ -0,0 +1,15 @@
1
+ import { getMediaAttachment } from '@elementor/wp-media';
2
+
3
+ import { createTransformer } from '../create-transformer';
4
+
5
+ type ImageAttachmentId = number;
6
+
7
+ export const imageAttachmentTransformer = createTransformer( async ( value: ImageAttachmentId ) => {
8
+ const attachment = await getMediaAttachment( { id: value } );
9
+
10
+ if ( ! attachment ) {
11
+ return null;
12
+ }
13
+
14
+ return attachment;
15
+ } );
@@ -0,0 +1,11 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type ImageSrc = {
4
+ id?: unknown;
5
+ url?: unknown;
6
+ };
7
+
8
+ export const imageSrcTransformer = createTransformer( ( value: ImageSrc ) => ( {
9
+ attachment: value.id,
10
+ url: value.url,
11
+ } ) );
@@ -0,0 +1,34 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type Image = {
4
+ src?: {
5
+ url?: string;
6
+ attachment?: {
7
+ url?: string;
8
+ sizes?: Record< string, { url: string } >;
9
+ };
10
+ };
11
+ size?: string;
12
+ };
13
+
14
+ export const imageTransformer = createTransformer( ( value: Image ) => {
15
+ const { src, size } = value;
16
+
17
+ if ( src?.url ) {
18
+ return `url(${ src.url })`;
19
+ }
20
+
21
+ const sizeUrl = src?.attachment?.sizes?.[ size ?? '' ]?.url;
22
+
23
+ if ( sizeUrl ) {
24
+ return `url(${ sizeUrl })`;
25
+ }
26
+
27
+ const attachmentUrl = src?.attachment?.url;
28
+
29
+ if ( attachmentUrl ) {
30
+ return `url(${ attachmentUrl })`;
31
+ }
32
+
33
+ return null;
34
+ } );
@@ -0,0 +1,3 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ export const primitiveTransformer = createTransformer( ( value: unknown ) => value );
@@ -0,0 +1,16 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type Shadow = {
4
+ hOffset?: string;
5
+ vOffset?: string;
6
+ blur?: string;
7
+ spread?: string;
8
+ color?: string;
9
+ position?: string;
10
+ };
11
+
12
+ export const shadowTransformer = createTransformer( ( value: Shadow ) => {
13
+ return [ value.hOffset, value.vOffset, value.blur, value.spread, value.color, value.position ]
14
+ .filter( Boolean )
15
+ .join( ' ' );
16
+ } );
@@ -0,0 +1,10 @@
1
+ import { createTransformer } from '../create-transformer';
2
+
3
+ type Size = {
4
+ size?: number;
5
+ unit?: string;
6
+ };
7
+
8
+ export const sizeTransformer = createTransformer( ( value: Size ) => {
9
+ return `${ value.size }${ value.unit }`;
10
+ } );
@@ -0,0 +1,17 @@
1
+ import { createMultiPropsValue } from '../../renderers/multi-props';
2
+ import { createTransformer } from '../create-transformer';
3
+
4
+ type Stroke = {
5
+ width?: string;
6
+ color?: string;
7
+ };
8
+
9
+ export const strokeTransformer = createTransformer( ( value: Stroke ) => {
10
+ const parsed = {
11
+ '-webkit-text-stroke': `${ value.width } ${ value.color }`,
12
+ stroke: `${ value.color }`,
13
+ 'stroke-width': `${ value.width }`,
14
+ };
15
+
16
+ return createMultiPropsValue( parsed );
17
+ } );
@@ -0,0 +1,14 @@
1
+ export type Transformer< TValue > = (
2
+ value: TValue,
3
+ options: {
4
+ key: string;
5
+ signal?: AbortSignal;
6
+ }
7
+ ) => unknown;
8
+
9
+ export type TransformerName = string;
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ export type AnyTransformer = Transformer< any >;
13
+
14
+ export type TransformersMap = Record< string, AnyTransformer >;
@@ -1,9 +0,0 @@
1
- import { type BackgroundColorOverlayPropValue } from '@elementor/editor-props';
2
-
3
- import { type Transformer } from '../types';
4
-
5
- const backgroundColorOverlayTransformer: Transformer< BackgroundColorOverlayPropValue[ 'value' ] > = ( value ) => {
6
- return `linear-gradient(${ value }, ${ value })`;
7
- };
8
-
9
- export default backgroundColorOverlayTransformer;
@@ -1,24 +0,0 @@
1
- import { type BackgroundImageOverlayPropValue } from '@elementor/editor-props';
2
-
3
- import { type Transformer } from '../types';
4
-
5
- const DEFAULT_POSITION_VALUE = '0% 0%';
6
-
7
- const backgroundImageOverlayTransformer: Transformer< BackgroundImageOverlayPropValue[ 'value' ] > = ( value ) => {
8
- const { image: imageSrc, size = null, position = null, repeat = null, attachment = null } = value;
9
-
10
- if ( ! imageSrc ) {
11
- return null;
12
- }
13
-
14
- const backgroundStyles = [
15
- imageSrc,
16
- repeat,
17
- attachment,
18
- size ? `${ position || DEFAULT_POSITION_VALUE } / ${ size }` : position,
19
- ].filter( Boolean );
20
-
21
- return backgroundStyles.join( ' ' );
22
- };
23
-
24
- export default backgroundImageOverlayTransformer;
@@ -1,10 +0,0 @@
1
- import type { BackgroundImagePositionOffsetPropValue } from '@elementor/editor-props';
2
-
3
- import { type Transformer } from '../types';
4
-
5
- const backgroundImagePositionOffsetTransformer: Transformer< BackgroundImagePositionOffsetPropValue[ 'value' ] > = ( {
6
- x = '0px',
7
- y = '0px',
8
- } ) => `${ x } ${ y }`;
9
-
10
- export default backgroundImagePositionOffsetTransformer;