@elementor/editor-variables 0.7.0 → 0.9.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.
@@ -1,57 +1,51 @@
1
1
  import { useMemo } from 'react';
2
+ import { type PropKey } from '@elementor/editor-props';
2
3
 
3
- import { type Variable } from '../types';
4
+ import { styleVariablesRepository } from '../style-variables-repository';
5
+ import { type Variable, type Variables } from '../types';
4
6
 
5
- type VariableData = {
6
- value: string;
7
- label: string;
7
+ export const usePropVariables = ( propKey: PropKey ) => {
8
+ return useMemo( () => normalizeVariables( propKey ), [ propKey ] );
8
9
  };
9
- type Variables = Record< string, VariableData >;
10
10
 
11
- type VariablesGroup = Record< string, Variables >;
12
-
13
- export const usePropVariables = ( propTypeKey: string ) => {
14
- return useMemo( () => normalizeVariables( propTypeKey ), [ propTypeKey ] );
15
- };
16
-
17
- export const useVariable = ( propTypeKey: string, key: string ) => {
18
- if ( ! variables[ propTypeKey ]?.[ key ] ) {
11
+ export const useVariable = ( key: string ) => {
12
+ if ( ! variables?.[ key ] ) {
19
13
  return null;
20
14
  }
21
15
 
22
16
  return {
23
- ...variables[ propTypeKey ][ key ],
17
+ ...variables[ key ],
24
18
  key,
25
19
  };
26
20
  };
27
21
 
28
- const normalizeVariables = ( propTypeKey: string ) => {
29
- return Object.entries( variables[ propTypeKey ] || {} ).map( ( [ key, { label, value } ] ) => ( {
30
- key,
31
- label,
32
- value,
33
- } ) );
22
+ const normalizeVariables = ( propKey: string ) => {
23
+ return Object.entries( variables )
24
+ .filter( ( [ , { type } ] ) => type === propKey )
25
+ .map( ( [ key, { label, value } ] ) => ( {
26
+ key,
27
+ label,
28
+ value,
29
+ } ) );
34
30
  };
35
31
 
36
- export const createVariable = ( propTypeKey: string, variable: VariableData ) => {
37
- const id = generateId( 'e-gv', Object.keys( variables[ propTypeKey ] ).length );
32
+ export const createVariable = ( variable: Variable ) => {
33
+ const id = generateId();
38
34
 
39
- const newVariable: Variable = {
40
- value: variable.value,
41
- label: variable.label,
42
- key: propTypeKey,
43
- };
35
+ variables[ id ] = variable;
44
36
 
45
- variables[ propTypeKey ][ id ] = newVariable || {};
37
+ styleVariablesRepository.update( {
38
+ [ id ]: variable,
39
+ } );
46
40
 
47
41
  return id;
48
42
  };
49
43
 
50
44
  // @ts-expect-error the temporary solution to get the list of variables from the server
51
- const variables: VariablesGroup = window?.ElementorV4Variables || {};
45
+ const variables: Variables = window?.ElementorV4Variables || {};
52
46
 
53
- const generateId = ( prefix: string, variablesCount: number ) => {
47
+ const generateId = ( prefix = 'e-gv' ) => {
54
48
  const randomHex = Math.random().toString( 16 ).slice( 2, 9 );
55
49
 
56
- return `${ prefix }${ randomHex }${ variablesCount }`;
50
+ return `${ prefix }${ randomHex }`;
57
51
  };
package/src/init.ts CHANGED
@@ -1,8 +1,16 @@
1
+ import { injectIntoTop } from '@elementor/editor';
2
+
1
3
  import { initColorVariables } from './init-color-variables';
2
4
  import { initFontVariables } from './init-font-variables';
5
+ import { StyleVariablesRenderer } from './renderers/style-variables-renderer';
3
6
 
4
7
  export function init() {
5
8
  initColorVariables();
6
9
 
7
10
  initFontVariables();
11
+
12
+ injectIntoTop( {
13
+ id: 'canvas-style-variables-render',
14
+ component: StyleVariablesRenderer,
15
+ } );
8
16
  }
@@ -0,0 +1,56 @@
1
+ import * as React from 'react';
2
+ import { useEffect, useState } from 'react';
3
+ import { __privateUseListenTo as useListenTo, commandEndEvent } from '@elementor/editor-v1-adapters';
4
+ import { Portal } from '@elementor/ui';
5
+
6
+ import { styleVariablesRepository } from '../style-variables-repository';
7
+ import { getCanvasIframeDocument } from '../sync/get-canvas-iframe-document';
8
+ import { type StyleVariables } from '../types';
9
+
10
+ const VARIABLES_WRAPPER = 'body';
11
+
12
+ export function StyleVariablesRenderer() {
13
+ const container = usePortalContainer();
14
+ const styleVariables = useStyleVariables();
15
+
16
+ const hasVariables = Object.keys( styleVariables ).length > 0;
17
+
18
+ if ( ! container || ! hasVariables ) {
19
+ return null;
20
+ }
21
+
22
+ const cssVariables = convertToCssVariables( styleVariables );
23
+ const wrappedCss = `${ VARIABLES_WRAPPER }{${ cssVariables }}`;
24
+
25
+ return (
26
+ <Portal container={ container }>
27
+ <style data-e-style-id="e-variables" key={ wrappedCss }>
28
+ { wrappedCss }
29
+ </style>
30
+ </Portal>
31
+ );
32
+ }
33
+
34
+ function usePortalContainer() {
35
+ return useListenTo( commandEndEvent( 'editor/documents/attach-preview' ), () => getCanvasIframeDocument()?.head );
36
+ }
37
+
38
+ function useStyleVariables() {
39
+ const [ variables, setVariables ] = useState< StyleVariables >( {} );
40
+
41
+ useEffect( () => {
42
+ const unsubscribe = styleVariablesRepository.subscribe( setVariables );
43
+
44
+ return () => {
45
+ unsubscribe();
46
+ };
47
+ }, [] );
48
+
49
+ return variables;
50
+ }
51
+
52
+ function convertToCssVariables( variables: StyleVariables ): string {
53
+ return Object.entries( variables )
54
+ .map( ( [ key, value ] ) => `--${ key }:${ value };` )
55
+ .join( '' );
56
+ }
@@ -0,0 +1,3 @@
1
+ import { createStyleVariablesRepository } from './create-style-variables-repository';
2
+
3
+ export const styleVariablesRepository = createStyleVariablesRepository();
@@ -0,0 +1,7 @@
1
+ import type { CanvasExtendedWindow } from './types';
2
+
3
+ export function getCanvasIframeDocument() {
4
+ const extendedWindow = window as unknown as CanvasExtendedWindow;
5
+
6
+ return extendedWindow.elementor?.$preview?.[ 0 ]?.contentDocument;
7
+ }
@@ -0,0 +1,5 @@
1
+ export type CanvasExtendedWindow = Window & {
2
+ elementor?: {
3
+ $preview?: [ HTMLIFrameElement ];
4
+ };
5
+ };
package/src/types.ts CHANGED
@@ -1,5 +1,15 @@
1
+ export type VariableKey = string;
2
+
3
+ export type VariableValue = string;
4
+
1
5
  export type Variable = {
2
- value: string;
6
+ value: VariableValue;
3
7
  label: string;
4
- key: string;
8
+ type: string;
5
9
  };
10
+
11
+ export type Variables = {
12
+ [ key: VariableKey ]: Variable;
13
+ };
14
+
15
+ export type StyleVariables = Record< VariableKey, VariableValue >;