@elementor/editor-editing-panel 1.24.0 → 1.28.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 (36) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/dist/index.d.mts +3 -1
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +448 -309
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +426 -287
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +11 -10
  9. package/src/components/css-classes/css-class-item.tsx +8 -10
  10. package/src/components/css-classes/css-class-menu.tsx +60 -12
  11. package/src/components/css-classes/css-class-selector.tsx +28 -27
  12. package/src/components/editing-panel-tabs.tsx +1 -8
  13. package/src/components/multi-combobox.tsx +3 -0
  14. package/src/components/style-indicator.tsx +23 -0
  15. package/src/components/style-sections/border-section/border-radius-field.tsx +4 -5
  16. package/src/components/style-sections/border-section/border-width-field.tsx +2 -3
  17. package/src/components/style-sections/layout-section/display-field.tsx +34 -28
  18. package/src/components/style-sections/layout-section/flex-size-field.tsx +28 -18
  19. package/src/components/style-sections/layout-section/layout-section.tsx +14 -2
  20. package/src/components/style-sections/typography-section/text-alignment-field.tsx +5 -6
  21. package/src/components/style-tab.tsx +2 -19
  22. package/src/contexts/style-context.tsx +2 -2
  23. package/src/controls-registry/control-type-container.tsx +2 -2
  24. package/src/controls-registry/styles-field.tsx +9 -2
  25. package/src/dynamics/dynamic-transformer.ts +61 -0
  26. package/src/dynamics/errors.ts +6 -0
  27. package/src/dynamics/init.ts +6 -0
  28. package/src/dynamics/types.ts +17 -0
  29. package/src/hooks/use-active-style-def-id.ts +36 -0
  30. package/src/hooks/use-styles-fields.ts +7 -7
  31. package/src/index.ts +1 -3
  32. package/src/init.ts +1 -1
  33. package/src/styles-inheritance/create-snapshots-manager.ts +16 -9
  34. package/src/styles-inheritance/create-styles-inheritance.ts +8 -4
  35. package/src/styles-inheritance/styles-inheritance-indicator.tsx +13 -31
  36. package/src/styles-inheritance/types.ts +7 -6
@@ -6,14 +6,14 @@ import {
6
6
  SizeControl,
7
7
  type ToggleButtonGroupItem,
8
8
  } from '@elementor/editor-controls';
9
- import type { NumberPropValue, SizePropValue } from '@elementor/editor-props';
9
+ import { numberPropTypeUtil, type NumberPropValue, type SizePropValue } from '@elementor/editor-props';
10
10
  import { ExpandIcon, PencilIcon, ShrinkIcon } from '@elementor/icons';
11
- import { DirectionProvider, Grid, ThemeProvider, Typography } from '@elementor/ui';
11
+ import { DirectionProvider, Grid, ThemeProvider } from '@elementor/ui';
12
12
  import { __ } from '@wordpress/i18n';
13
13
 
14
14
  import { StylesField } from '../../../controls-registry/styles-field';
15
15
  import { useDirection } from '../../../hooks/use-direction';
16
- import { useStylesField } from '../../../hooks/use-styles-field';
16
+ import { useStylesFields } from '../../../hooks/use-styles-fields';
17
17
  import { ControlLabel } from '../../control-label';
18
18
  import { SectionContent } from '../../section-content';
19
19
 
@@ -43,45 +43,55 @@ const items: ToggleButtonGroupItem< GroupItem >[] = [
43
43
  ];
44
44
 
45
45
  export const FlexSizeField = () => {
46
- const { isSiteRtl } = useDirection(),
47
- [ growField, setGrowField ] = useStylesField< NumberPropValue | null >( 'flex-grow' ),
48
- [ shrinkField, setShrinkField ] = useStylesField< NumberPropValue | null >( 'flex-shrink' ),
49
- [ basisField, setBasisField ] = useStylesField< SizePropValue | null >( 'flex-basis' );
46
+ const { isSiteRtl } = useDirection();
50
47
 
51
- const grow = growField?.value || null,
52
- shrink = shrinkField?.value || null,
53
- basis = basisField?.value || null;
48
+ const [ fields, setFields ] = useStylesFields< {
49
+ 'flex-grow': NumberPropValue | null;
50
+ 'flex-shrink': NumberPropValue | null;
51
+ 'flex-basis': SizePropValue | null;
52
+ } >( [ 'flex-grow', 'flex-shrink', 'flex-basis' ] );
53
+
54
+ const grow = fields?.[ 'flex-grow' ]?.value || null;
55
+ const shrink = fields?.[ 'flex-shrink' ]?.value || null;
56
+ const basis = fields?.[ 'flex-basis' ]?.value || null;
54
57
 
55
58
  const currentGroup = useMemo( () => getActiveGroup( { grow, shrink, basis } ), [ grow, shrink, basis ] ),
56
59
  [ activeGroup, setActiveGroup ] = useState( currentGroup );
57
60
 
58
61
  const onChangeGroup = ( group: GroupItem | null = null ) => {
59
62
  setActiveGroup( group );
60
- setBasisField( null );
61
63
 
62
64
  if ( ! group || group === 'custom' ) {
63
- setGrowField( null );
64
- setShrinkField( null );
65
+ setFields( {
66
+ 'flex-basis': null,
67
+ 'flex-grow': null,
68
+ 'flex-shrink': null,
69
+ } );
65
70
 
66
71
  return;
67
72
  }
68
73
 
69
74
  if ( group === 'flex-grow' ) {
70
- setGrowField( { $$type: 'number', value: DEFAULT } );
71
- setShrinkField( null );
75
+ setFields( {
76
+ 'flex-basis': null,
77
+ 'flex-grow': numberPropTypeUtil.create( DEFAULT ),
78
+ 'flex-shrink': null,
79
+ } );
72
80
 
73
81
  return;
74
82
  }
75
83
 
76
- setGrowField( null );
77
- setShrinkField( { $$type: 'number', value: DEFAULT } );
84
+ setFields( {
85
+ 'flex-basis': null,
86
+ 'flex-grow': null,
87
+ 'flex-shrink': numberPropTypeUtil.create( DEFAULT ),
88
+ } );
78
89
  };
79
90
 
80
91
  return (
81
92
  <DirectionProvider rtl={ isSiteRtl }>
82
93
  <ThemeProvider>
83
94
  <SectionContent>
84
- <Typography fontSize="large">{ activeGroup }</Typography>
85
95
  <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
86
96
  <Grid item xs={ 6 }>
87
97
  <StylesField bind={ activeGroup ?? '' }>
@@ -12,7 +12,7 @@ import { SectionContent } from '../../section-content';
12
12
  import { AlignContentField } from './align-content-field';
13
13
  import { AlignItemsField } from './align-items-field';
14
14
  import { AlignSelfChild } from './align-self-child-field';
15
- import { DisplayField } from './display-field';
15
+ import { DisplayField, useDisplayPlaceholderValue } from './display-field';
16
16
  import { FlexDirectionField } from './flex-direction-field';
17
17
  import { FlexOrderField } from './flex-order-field';
18
18
  import { FlexSizeField } from './flex-size-field';
@@ -22,6 +22,8 @@ import { WrapField } from './wrap-field';
22
22
 
23
23
  export const LayoutSection = () => {
24
24
  const [ display ] = useStylesField< StringPropValue >( 'display' );
25
+ const displayPlaceholder = useDisplayPlaceholderValue();
26
+ const isDisplayFlex = shouldDisplayFlexFields( display, displayPlaceholder as StringPropValue );
25
27
  const { element } = useElement();
26
28
  const parent = useParentElement( element.id );
27
29
  const parentStyle = useComputedStyle( parent?.id || null );
@@ -29,7 +31,7 @@ export const LayoutSection = () => {
29
31
  return (
30
32
  <SectionContent>
31
33
  <DisplayField />
32
- { ( 'flex' === display?.value || 'inline-flex' === display?.value ) && <FlexFields /> }
34
+ { isDisplayFlex && <FlexFields /> }
33
35
  { 'flex' === parentStyle?.display && <FlexChildFields /> }
34
36
  </SectionContent>
35
37
  );
@@ -60,3 +62,13 @@ const FlexChildFields = () => (
60
62
  <FlexSizeField />
61
63
  </>
62
64
  );
65
+
66
+ const shouldDisplayFlexFields = ( display: StringPropValue | null, local: StringPropValue ) => {
67
+ const value = display?.value ?? local?.value;
68
+
69
+ if ( ! value ) {
70
+ return false;
71
+ }
72
+
73
+ return 'flex' === value || 'inline-flex' === value;
74
+ };
@@ -6,18 +6,17 @@ import { __ } from '@wordpress/i18n';
6
6
 
7
7
  import { StylesField } from '../../../controls-registry/styles-field';
8
8
  import { ControlLabel } from '../../control-label';
9
- import { RotatedIcon } from '../layout-section/utils/rotated-icon';
10
9
 
11
10
  type Alignments = 'start' | 'center' | 'end' | 'justify';
12
11
 
13
- const StartIcon = withDirection( AlignLeftIcon );
14
- const EndIcon = withDirection( AlignRightIcon );
12
+ const AlignStartIcon = withDirection( AlignLeftIcon );
13
+ const AlignEndIcon = withDirection( AlignRightIcon );
15
14
 
16
15
  const options: ToggleButtonGroupItem< Alignments >[] = [
17
16
  {
18
17
  value: 'start',
19
18
  label: __( 'Start', 'elementor' ),
20
- renderContent: () => <RotatedIcon icon={ StartIcon } size="tiny" />,
19
+ renderContent: ( { size } ) => <AlignStartIcon fontSize={ size } />,
21
20
  showTooltip: true,
22
21
  },
23
22
  {
@@ -29,7 +28,7 @@ const options: ToggleButtonGroupItem< Alignments >[] = [
29
28
  {
30
29
  value: 'end',
31
30
  label: __( 'End', 'elementor' ),
32
- renderContent: () => <RotatedIcon icon={ EndIcon } size="tiny" />,
31
+ renderContent: ( { size } ) => <AlignEndIcon fontSize={ size } />,
33
32
  showTooltip: true,
34
33
  },
35
34
  {
@@ -45,7 +44,7 @@ export const TextAlignmentField = () => {
45
44
  <StylesField bind={ 'text-align' }>
46
45
  <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
47
46
  <Grid item xs={ 6 }>
48
- <ControlLabel>{ __( 'Alignment', 'elementor' ) }</ControlLabel>
47
+ <ControlLabel>{ __( 'Text align', 'elementor' ) }</ControlLabel>
49
48
  </Grid>
50
49
  <Grid item xs={ 6 } display="flex" justifyContent="end">
51
50
  <ToggleControl options={ options } />
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { useState } from 'react';
3
- import { getElementStyles, useElementSetting } from '@elementor/editor-elements';
4
- import { CLASSES_PROP_KEY, type ClassesPropValue, type PropKey } from '@elementor/editor-props';
3
+ import { CLASSES_PROP_KEY } from '@elementor/editor-props';
5
4
  import { useActiveBreakpoint } from '@elementor/editor-responsive';
6
5
  import { type StyleDefinitionID, type StyleDefinitionState } from '@elementor/editor-styles';
7
6
  import { SessionStorageProvider } from '@elementor/session';
@@ -12,6 +11,7 @@ import { ClassesPropProvider } from '../contexts/classes-prop-context';
12
11
  import { useElement } from '../contexts/element-context';
13
12
  import { StyleProvider } from '../contexts/style-context';
14
13
  import { StyleInheritanceProvider } from '../contexts/styles-inheritance-context';
14
+ import { useActiveStyleDefId } from '../hooks/use-active-style-def-id';
15
15
  import { CssClassSelector } from './css-classes/css-class-selector';
16
16
  import { Section } from './section';
17
17
  import { SectionsList } from './sections-list';
@@ -78,23 +78,6 @@ export const StyleTab = () => {
78
78
  );
79
79
  };
80
80
 
81
- function useActiveStyleDefId( currentClassesProp: PropKey ) {
82
- const [ activeStyledDefId, setActiveStyledDefId ] = useState< StyleDefinitionID | null >( null );
83
-
84
- const fallback = useFirstElementStyleDef( currentClassesProp );
85
-
86
- return [ activeStyledDefId || fallback?.id || null, setActiveStyledDefId ] as const;
87
- }
88
-
89
- function useFirstElementStyleDef( currentClassesProp: PropKey ) {
90
- const { element } = useElement();
91
-
92
- const classesIds = useElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
93
- const stylesDefs = getElementStyles( element.id ) ?? {};
94
-
95
- return Object.values( stylesDefs ).find( ( styleDef ) => classesIds.includes( styleDef.id ) );
96
- }
97
-
98
81
  function useCurrentClassesProp(): string {
99
82
  const { elementType } = useElement();
100
83
 
@@ -50,9 +50,9 @@ export function useStyle() {
50
50
  return context;
51
51
  }
52
52
 
53
- function getProviderByStyleId( styleId: StyleDefinitionID ) {
53
+ export function getProviderByStyleId( styleId: StyleDefinitionID ) {
54
54
  const styleProvider = stylesRepository.getProviders().find( ( provider ) => {
55
- return provider.actions.get().find( ( style ) => style.id === styleId );
55
+ return provider.actions.all().find( ( style ) => style.id === styleId );
56
56
  } );
57
57
 
58
58
  return styleProvider ?? null;
@@ -23,7 +23,7 @@ const StyledContainer = styled( Box, {
23
23
  const getGridLayout = ( layout: ControlLayout ) => ( {
24
24
  justifyContent: 'space-between',
25
25
  gridTemplateColumns: {
26
- full: '1fr',
27
- 'two-columns': 'repeat(2, 1fr)',
26
+ full: 'minmax(0, 1fr)',
27
+ 'two-columns': 'repeat(2, minmax(0, 1fr))',
28
28
  }[ layout ],
29
29
  } );
@@ -9,10 +9,11 @@ import { createTopLevelOjectType } from './create-top-level-object-type';
9
9
 
10
10
  export type StylesFieldProps = {
11
11
  bind: PropKey;
12
+ placeholder?: PropValue;
12
13
  children: React.ReactNode;
13
14
  };
14
15
 
15
- export const StylesField = ( { bind, children }: StylesFieldProps ) => {
16
+ export const StylesField = ( { bind, placeholder, children }: StylesFieldProps ) => {
16
17
  const [ value, setValue ] = useStylesField( bind );
17
18
 
18
19
  const stylesSchema = getStylesSchema();
@@ -20,6 +21,7 @@ export const StylesField = ( { bind, children }: StylesFieldProps ) => {
20
21
  const propType = createTopLevelOjectType( { schema: stylesSchema } );
21
22
 
22
23
  const values = { [ bind ]: value };
24
+ const placeholderValues = { [ bind ]: placeholder };
23
25
 
24
26
  const setValues = ( newValue: Record< string, PropValue > ) => {
25
27
  setValue( newValue[ bind ] );
@@ -34,7 +36,12 @@ export const StylesField = ( { bind, children }: StylesFieldProps ) => {
34
36
  },
35
37
  ] }
36
38
  >
37
- <PropProvider propType={ propType } value={ values } setValue={ setValues }>
39
+ <PropProvider
40
+ propType={ propType }
41
+ value={ values }
42
+ setValue={ setValues }
43
+ placeholder={ placeholderValues }
44
+ >
38
45
  <PropKeyProvider bind={ bind }>{ children }</PropKeyProvider>
39
46
  </PropProvider>
40
47
  </ControlAdornmentsProvider>
@@ -0,0 +1,61 @@
1
+ import { createTransformer } from '@elementor/editor-canvas';
2
+ import { isTransformable, type Props } from '@elementor/editor-props';
3
+
4
+ import { DynamicTagsManagerNotFoundError } from './errors';
5
+ import { type ExtendedWindow } from './types';
6
+
7
+ type Dynamic = {
8
+ name?: string;
9
+ settings?: Props;
10
+ };
11
+
12
+ export const dynamicTransformer = createTransformer( ( value: Dynamic ) => {
13
+ if ( ! value.name ) {
14
+ return null;
15
+ }
16
+
17
+ return getDynamicValue( value.name, simpleTransform( value.settings ?? {} ) );
18
+ } );
19
+
20
+ // Temporary naive transformation until we'll have a `backendTransformer` that
21
+ // will replace the `dynamicTransformer` client implementation.
22
+ function simpleTransform( props: Props ) {
23
+ const transformed = Object.entries( props ).map( ( [ settingKey, settingValue ] ) => {
24
+ const value = isTransformable( settingValue ) ? settingValue.value : settingValue;
25
+
26
+ return [ settingKey, value ] as const;
27
+ } );
28
+
29
+ return Object.fromEntries( transformed );
30
+ }
31
+
32
+ function getDynamicValue( name: string, settings: Record< string, unknown > ) {
33
+ const extendedWindow = window as unknown as ExtendedWindow;
34
+ const { dynamicTags } = extendedWindow.elementor ?? {};
35
+
36
+ if ( ! dynamicTags ) {
37
+ throw new DynamicTagsManagerNotFoundError();
38
+ }
39
+
40
+ const getTagValue = () => {
41
+ const tag = dynamicTags.createTag( 'v4-dynamic-tag', name, settings );
42
+
43
+ if ( ! tag ) {
44
+ return null;
45
+ }
46
+
47
+ return dynamicTags.loadTagDataFromCache( tag ) ?? null;
48
+ };
49
+
50
+ const tagValue = getTagValue();
51
+
52
+ if ( tagValue !== null ) {
53
+ return tagValue;
54
+ }
55
+
56
+ return new Promise( ( resolve ) => {
57
+ dynamicTags.refreshCacheFromServer( () => {
58
+ resolve( getTagValue() );
59
+ } );
60
+ } );
61
+ }
@@ -0,0 +1,6 @@
1
+ import { createError } from '@elementor/utils';
2
+
3
+ export const DynamicTagsManagerNotFoundError = createError( {
4
+ code: 'dynamic_tags_manager_not_found',
5
+ message: 'Dynamic tags manager not found',
6
+ } );
@@ -1,6 +1,9 @@
1
+ import { settingsTransformersRegistry, styleTransformersRegistry } from '@elementor/editor-canvas';
2
+
1
3
  import { replaceControl } from '../control-replacement';
2
4
  import { controlActionsMenu } from '../controls-actions';
3
5
  import { DynamicSelectionControl } from './components/dynamic-selection-control';
6
+ import { dynamicTransformer } from './dynamic-transformer';
4
7
  import { usePropDynamicAction } from './hooks/use-prop-dynamic-action';
5
8
  import { isDynamicPropValue } from './utils';
6
9
 
@@ -16,4 +19,7 @@ export const init = () => {
16
19
  id: 'dynamic-tags',
17
20
  useProps: usePropDynamicAction,
18
21
  } );
22
+
23
+ styleTransformersRegistry.register( 'dynamic', dynamicTransformer );
24
+ settingsTransformersRegistry.register( 'dynamic', dynamicTransformer );
19
25
  };
@@ -9,6 +9,7 @@ export type ExtendedWindow = Window & {
9
9
  groups: Record< DynamicTag[ 'group' ], { title: string } >;
10
10
  };
11
11
  };
12
+ dynamicTags?: DynamicTagsManager;
12
13
  };
13
14
  };
14
15
 
@@ -34,3 +35,19 @@ export type DynamicPropValue = TransformablePropValue<
34
35
  'dynamic',
35
36
  { name: string; settings?: Record< string, unknown > }
36
37
  >;
38
+
39
+ export type DynamicTagsManager = {
40
+ createTag: ( id: string, name: string, settings: Record< string, unknown > ) => TagInstance;
41
+ loadTagDataFromCache: ( tag: TagInstance ) => unknown;
42
+ refreshCacheFromServer: ( callback: () => void ) => void;
43
+ };
44
+
45
+ export type TagInstance = {
46
+ options: {
47
+ id: string;
48
+ name: string;
49
+ };
50
+ model: {
51
+ toJSON: () => Record< string, unknown >;
52
+ };
53
+ };
@@ -0,0 +1,36 @@
1
+ import { useState } from 'react';
2
+ import { getElementStyles, useElementSetting } from '@elementor/editor-elements';
3
+ import { type ClassesPropValue, type PropKey } from '@elementor/editor-props';
4
+ import { type StyleDefinitionID } from '@elementor/editor-styles';
5
+
6
+ import { useElement } from '../contexts/element-context';
7
+
8
+ export function useActiveStyleDefId( classProp: PropKey ) {
9
+ const [ activeStyledDefId, setActiveStyledDefId ] = useState< StyleDefinitionID | null >( null );
10
+
11
+ const appliedClassesIds = useAppliedClassesIds( classProp )?.value || [];
12
+
13
+ const fallback = useFirstAppliedClass( appliedClassesIds );
14
+
15
+ const activeAndAppliedClassId = useActiveAndAppliedClassId( activeStyledDefId, appliedClassesIds );
16
+ return [ activeAndAppliedClassId || fallback?.id || null, setActiveStyledDefId ] as const;
17
+ }
18
+
19
+ function useFirstAppliedClass( appliedClassesIds: string[] ) {
20
+ const { element } = useElement();
21
+ const stylesDefs = getElementStyles( element.id ) ?? {};
22
+
23
+ return Object.values( stylesDefs ).find( ( styleDef ) => appliedClassesIds.includes( styleDef.id ) );
24
+ }
25
+
26
+ function useAppliedClassesIds( classProp: PropKey ) {
27
+ const { element } = useElement();
28
+
29
+ return useElementSetting< ClassesPropValue >( element.id, classProp );
30
+ }
31
+
32
+ function useActiveAndAppliedClassId( id: StyleDefinitionID | null, appliedClassesIds: string[] ) {
33
+ const isClassApplied = !! id && appliedClassesIds.includes( id );
34
+
35
+ return isClassApplied ? id : null;
36
+ }
@@ -9,7 +9,7 @@ import {
9
9
  import type { Props } from '@elementor/editor-props';
10
10
  import { getVariantByMeta, type StyleDefinition, type StyleDefinitionVariant } from '@elementor/editor-styles';
11
11
  import { type StylesProvider } from '@elementor/editor-styles-repository';
12
- import { LOCAL_STYLES_RESERVED_LABEL } from '@elementor/editor-styles-repository';
12
+ import { ELEMENTS_STYLES_RESERVED_LABEL } from '@elementor/editor-styles-repository';
13
13
  import { undoable } from '@elementor/editor-v1-adapters';
14
14
  import { __ } from '@wordpress/i18n';
15
15
 
@@ -78,10 +78,10 @@ function getProps< T extends Props >( { styleId, elementId, provider, meta, prop
78
78
  return null;
79
79
  }
80
80
 
81
- const style = provider.actions.getById?.( styleId, { elementId } );
81
+ const style = provider.actions.get( styleId, { elementId } );
82
82
 
83
83
  if ( ! style ) {
84
- throw new StyleNotFoundUnderProviderError( { context: { styleId, providerKey: provider.key } } );
84
+ throw new StyleNotFoundUnderProviderError( { context: { styleId, providerKey: provider.getKey() } } );
85
85
  }
86
86
 
87
87
  const variant = getVariantByMeta( style, meta );
@@ -100,7 +100,7 @@ function useUndoableCreateElementStyle() {
100
100
  do: ( payload: UndoableCreateElementStyleArgs ) => {
101
101
  return createElementStyle( {
102
102
  ...payload,
103
- label: LOCAL_STYLES_RESERVED_LABEL,
103
+ label: ELEMENTS_STYLES_RESERVED_LABEL,
104
104
  } );
105
105
  },
106
106
 
@@ -112,7 +112,7 @@ function useUndoableCreateElementStyle() {
112
112
  return createElementStyle( {
113
113
  ...payload,
114
114
  styleId,
115
- label: LOCAL_STYLES_RESERVED_LABEL,
115
+ label: ELEMENTS_STYLES_RESERVED_LABEL,
116
116
  } );
117
117
  },
118
118
  },
@@ -139,11 +139,11 @@ function useUndoableUpdateStyle() {
139
139
  do: ( { elementId, styleId, provider, meta, props }: UndoableUpdateStyleArgs ) => {
140
140
  if ( ! provider.actions.updateProps ) {
141
141
  throw new StylesProviderCannotUpdatePropsError( {
142
- context: { providerKey: provider.key },
142
+ context: { providerKey: provider.getKey() },
143
143
  } );
144
144
  }
145
145
 
146
- const style = provider.actions.getById( styleId, { elementId } );
146
+ const style = provider.actions.get( styleId, { elementId } );
147
147
 
148
148
  const prevProps = getCurrentProps( style, meta );
149
149
 
package/src/index.ts CHANGED
@@ -4,6 +4,4 @@ export { replaceControl } from './control-replacement';
4
4
  export { injectIntoClassSelectorActions } from './components/css-classes/css-class-selector';
5
5
  export { usePanelActions, usePanelStatus } from './panel';
6
6
 
7
- import init from './init';
8
-
9
- init();
7
+ export { init } from './init';
package/src/init.ts CHANGED
@@ -8,7 +8,7 @@ import { init as initDynamics } from './dynamics/init';
8
8
  import { panel } from './panel';
9
9
  import { isAtomicWidgetSelected } from './sync/is-atomic-widget-selected';
10
10
 
11
- export default function init() {
11
+ export function init() {
12
12
  registerPanel( panel );
13
13
  blockV1Panel();
14
14
 
@@ -1,3 +1,4 @@
1
+ import { filterEmptyValues } from '@elementor/editor-props';
1
2
  import { type BreakpointId, type BreakpointNode } from '@elementor/editor-responsive';
2
3
  import { type StyleDefinitionState } from '@elementor/editor-styles';
3
4
 
@@ -10,12 +11,12 @@ import {
10
11
  type StylesInheritanceSnapshot,
11
12
  type StylesInheritanceSnapshotGetter,
12
13
  type StylesInheritanceSnapshotsSlot,
13
- type StyleVariantWithId,
14
+ type StyleVariantDetails,
14
15
  } from './types';
15
16
  import { DEFAULT_STATE, getBreakpointKey, getStateKey } from './utils';
16
17
 
17
18
  export function createSnapshotsManager(
18
- getStylesByMeta: ( meta: StyleInheritanceMetaProps ) => StyleVariantWithId[],
19
+ getStylesByMeta: ( meta: StyleInheritanceMetaProps ) => StyleVariantDetails[],
19
20
  breakpointsRoot: BreakpointNode
20
21
  ): StylesInheritanceSnapshotGetter {
21
22
  const breakpointsInheritancePaths = makeBreakpointsInheritancePaths( breakpointsRoot );
@@ -104,7 +105,7 @@ function makeBreakpointsInheritancePaths( root: BreakpointNode ): BreakpointsInh
104
105
 
105
106
  // creates a snapshot slot for a specific breakpoint and state
106
107
  function buildStateSnapshotSlot(
107
- styles: StyleVariantWithId[],
108
+ styles: StyleVariantDetails[],
108
109
  parentBreakpoint: BreakpointStatesSlotsMapping | undefined,
109
110
  currentBreakpoint: BreakpointStatesSlotsMapping,
110
111
  state: StyleDefinitionState
@@ -132,22 +133,28 @@ function buildStateSnapshotSlot(
132
133
  }
133
134
 
134
135
  // creates an initial snapshot based on the passed style variants only
135
- function buildInitialSnapshotFromStyles( styles: StyleVariantWithId[] ): StylesInheritanceSnapshotsSlot {
136
+ function buildInitialSnapshotFromStyles( styles: StyleVariantDetails[] ): StylesInheritanceSnapshotsSlot {
136
137
  const snapshot: StylesInheritanceSnapshot = {};
137
138
 
138
- styles.forEach( ( styleVariantWithId ) => {
139
+ styles.forEach( ( styleData ) => {
139
140
  const {
140
- styleVariant: { props },
141
- } = styleVariantWithId;
141
+ variant: { props },
142
+ } = styleData;
142
143
 
143
144
  Object.entries( props ).forEach( ( [ key, value ] ) => {
145
+ const filteredValue = filterEmptyValues( value );
146
+
147
+ if ( filteredValue === null ) {
148
+ return;
149
+ }
150
+
144
151
  if ( ! snapshot[ key ] ) {
145
152
  snapshot[ key ] = [];
146
153
  }
147
154
 
148
155
  const snapshotPropValue: SnapshotPropValue = {
149
- ...styleVariantWithId,
150
- value,
156
+ ...styleData,
157
+ value: filteredValue,
151
158
  };
152
159
 
153
160
  snapshot[ key ].push( snapshotPropValue );
@@ -1,6 +1,7 @@
1
1
  import { type BreakpointNode } from '@elementor/editor-responsive';
2
2
  import { type StyleDefinition } from '@elementor/editor-styles';
3
3
 
4
+ import { getProviderByStyleId } from '../contexts/style-context';
4
5
  import { createSnapshotsManager } from './create-snapshots-manager';
5
6
  import { type BreakpointsStatesStyles, type StyleInheritanceMetaProps, type StylesInheritanceSnapshot } from './types';
6
7
  import { getBreakpointKey, getStateKey } from './utils';
@@ -21,9 +22,11 @@ function buildStyleVariantsByMetaMapping( styleDefs: StyleDefinition[] ): Breakp
21
22
  const breakpointStateSlots: BreakpointsStatesStyles = {};
22
23
 
23
24
  styleDefs.forEach( ( styleDef ) => {
25
+ const provider = getProviderByStyleId( styleDef.id )?.getKey() ?? null;
26
+
24
27
  // iterate over each style definition's variants and place them in the corresponding breakpoint's base or state styles
25
- styleDef.variants.forEach( ( styleVariant ) => {
26
- const { meta } = styleVariant;
28
+ styleDef.variants.forEach( ( variant ) => {
29
+ const { meta } = variant;
27
30
  const { state, breakpoint } = meta;
28
31
 
29
32
  const breakpointKey = getBreakpointKey( breakpoint );
@@ -40,8 +43,9 @@ function buildStyleVariantsByMetaMapping( styleDefs: StyleDefinition[] ): Breakp
40
43
  }
41
44
 
42
45
  breakpointNode[ stateKey ].push( {
43
- styleId: styleDef.id,
44
- styleVariant,
46
+ style: styleDef,
47
+ variant,
48
+ provider,
45
49
  } );
46
50
  } );
47
51
  } );