@elementor/editor-editing-panel 1.23.0 → 1.27.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 (60) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/dist/index.js +603 -455
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +568 -425
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +10 -9
  7. package/src/components/add-or-remove-content.tsx +1 -1
  8. package/src/components/{control-label-with-adornments.tsx → control-label.tsx} +3 -3
  9. package/src/components/css-classes/css-class-item.tsx +18 -7
  10. package/src/components/css-classes/css-class-menu.tsx +55 -9
  11. package/src/components/css-classes/css-class-selector.tsx +9 -8
  12. package/src/components/editing-panel-tabs.tsx +1 -1
  13. package/src/components/editing-panel.tsx +18 -15
  14. package/src/components/multi-combobox.tsx +12 -1
  15. package/src/components/settings-tab.tsx +2 -2
  16. package/src/components/style-indicator.tsx +23 -0
  17. package/src/components/style-sections/border-section/border-color-field.tsx +2 -1
  18. package/src/components/style-sections/border-section/border-radius-field.tsx +4 -5
  19. package/src/components/style-sections/border-section/border-style-field.tsx +2 -1
  20. package/src/components/style-sections/border-section/border-width-field.tsx +2 -3
  21. package/src/components/style-sections/layout-section/align-content-field.tsx +2 -1
  22. package/src/components/style-sections/layout-section/align-items-field.tsx +2 -1
  23. package/src/components/style-sections/layout-section/align-self-child-field.tsx +2 -1
  24. package/src/components/style-sections/layout-section/display-field.tsx +2 -1
  25. package/src/components/style-sections/layout-section/flex-direction-field.tsx +2 -1
  26. package/src/components/style-sections/layout-section/flex-order-field.tsx +20 -24
  27. package/src/components/style-sections/layout-section/flex-size-field.tsx +31 -19
  28. package/src/components/style-sections/layout-section/justify-content-field.tsx +5 -4
  29. package/src/components/style-sections/layout-section/layout-section.tsx +2 -2
  30. package/src/components/style-sections/layout-section/wrap-field.tsx +2 -1
  31. package/src/components/style-sections/position-section/dimensions-field.tsx +2 -1
  32. package/src/components/style-sections/position-section/position-field.tsx +2 -1
  33. package/src/components/style-sections/position-section/z-index-field.tsx +2 -1
  34. package/src/components/style-sections/size-section/overflow-field.tsx +2 -1
  35. package/src/components/style-sections/size-section/size-section.tsx +2 -1
  36. package/src/components/style-sections/typography-section/font-family-field.tsx +2 -1
  37. package/src/components/style-sections/typography-section/font-size-field.tsx +2 -1
  38. package/src/components/style-sections/typography-section/font-style-field.tsx +2 -2
  39. package/src/components/style-sections/typography-section/font-weight-field.tsx +2 -1
  40. package/src/components/style-sections/typography-section/letter-spacing-field.tsx +2 -1
  41. package/src/components/style-sections/typography-section/line-height-field.tsx +2 -1
  42. package/src/components/style-sections/typography-section/text-alignment-field.tsx +7 -7
  43. package/src/components/style-sections/typography-section/text-color-field.tsx +2 -1
  44. package/src/components/style-sections/typography-section/text-decoration-field.tsx +2 -1
  45. package/src/components/style-sections/typography-section/text-direction-field.tsx +2 -1
  46. package/src/components/style-sections/typography-section/text-stroke-field.tsx +9 -9
  47. package/src/components/style-sections/typography-section/transform-field.tsx +2 -1
  48. package/src/components/style-sections/typography-section/word-spacing-field.tsx +2 -1
  49. package/src/contexts/style-context.tsx +1 -1
  50. package/src/controls-registry/control-type-container.tsx +2 -2
  51. package/src/dynamics/components/dynamic-selection-control.tsx +2 -2
  52. package/src/dynamics/components/dynamic-selection.tsx +4 -4
  53. package/src/dynamics/dynamic-transformer.ts +61 -0
  54. package/src/dynamics/errors.ts +6 -0
  55. package/src/dynamics/init.ts +6 -0
  56. package/src/dynamics/types.ts +17 -0
  57. package/src/styles-inheritance/create-snapshots-manager.ts +8 -8
  58. package/src/styles-inheritance/create-styles-inheritance.ts +8 -4
  59. package/src/styles-inheritance/styles-inheritance-indicator.tsx +17 -34
  60. package/src/styles-inheritance/types.ts +7 -6
@@ -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
+ };
@@ -10,12 +10,12 @@ import {
10
10
  type StylesInheritanceSnapshot,
11
11
  type StylesInheritanceSnapshotGetter,
12
12
  type StylesInheritanceSnapshotsSlot,
13
- type StyleVariantWithId,
13
+ type StyleVariantDetails,
14
14
  } from './types';
15
15
  import { DEFAULT_STATE, getBreakpointKey, getStateKey } from './utils';
16
16
 
17
17
  export function createSnapshotsManager(
18
- getStylesByMeta: ( meta: StyleInheritanceMetaProps ) => StyleVariantWithId[],
18
+ getStylesByMeta: ( meta: StyleInheritanceMetaProps ) => StyleVariantDetails[],
19
19
  breakpointsRoot: BreakpointNode
20
20
  ): StylesInheritanceSnapshotGetter {
21
21
  const breakpointsInheritancePaths = makeBreakpointsInheritancePaths( breakpointsRoot );
@@ -104,7 +104,7 @@ function makeBreakpointsInheritancePaths( root: BreakpointNode ): BreakpointsInh
104
104
 
105
105
  // creates a snapshot slot for a specific breakpoint and state
106
106
  function buildStateSnapshotSlot(
107
- styles: StyleVariantWithId[],
107
+ styles: StyleVariantDetails[],
108
108
  parentBreakpoint: BreakpointStatesSlotsMapping | undefined,
109
109
  currentBreakpoint: BreakpointStatesSlotsMapping,
110
110
  state: StyleDefinitionState
@@ -132,13 +132,13 @@ function buildStateSnapshotSlot(
132
132
  }
133
133
 
134
134
  // creates an initial snapshot based on the passed style variants only
135
- function buildInitialSnapshotFromStyles( styles: StyleVariantWithId[] ): StylesInheritanceSnapshotsSlot {
135
+ function buildInitialSnapshotFromStyles( styles: StyleVariantDetails[] ): StylesInheritanceSnapshotsSlot {
136
136
  const snapshot: StylesInheritanceSnapshot = {};
137
137
 
138
- styles.forEach( ( styleVariantWithId ) => {
138
+ styles.forEach( ( styleData ) => {
139
139
  const {
140
- styleVariant: { props },
141
- } = styleVariantWithId;
140
+ variant: { props },
141
+ } = styleData;
142
142
 
143
143
  Object.entries( props ).forEach( ( [ key, value ] ) => {
144
144
  if ( ! snapshot[ key ] ) {
@@ -146,7 +146,7 @@ function buildInitialSnapshotFromStyles( styles: StyleVariantWithId[] ): StylesI
146
146
  }
147
147
 
148
148
  const snapshotPropValue: SnapshotPropValue = {
149
- ...styleVariantWithId,
149
+ ...styleData,
150
150
  value,
151
151
  };
152
152
 
@@ -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 )?.key ?? 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
  } );
@@ -1,70 +1,53 @@
1
1
  import * as React from 'react';
2
2
  import { useBoundProp } from '@elementor/editor-controls';
3
- import { ELEMENTS_STYLES_PROVIDER_KEY } from '@elementor/editor-styles-repository';
4
- import { styled } from '@elementor/ui';
3
+ import { ELEMENTS_BASE_STYLES_PROVIDER_KEY, ELEMENTS_STYLES_PROVIDER_KEY } from '@elementor/editor-styles-repository';
5
4
  import { __ } from '@wordpress/i18n';
6
5
 
6
+ import { StyleIndicator } from '../components/style-indicator';
7
7
  import { useStyle } from '../contexts/style-context';
8
8
  import { useStylesInheritanceField } from '../contexts/styles-inheritance-context';
9
- import { useStylesField } from '../hooks/use-styles-field';
10
-
11
- const Circle = styled( 'div', {
12
- shouldForwardProp: ( prop ) => prop !== 'variant',
13
- } )< { variant?: 'overridden' | 'local-affects' | 'global-affects' } >`
14
- width: 5px;
15
- height: 5px;
16
- border-radius: 50%;
17
- background-color: ${ ( { theme, variant } ) => {
18
- switch ( variant ) {
19
- case 'overridden':
20
- return theme.palette.warning.main;
21
- case 'global-affects':
22
- return theme.palette.global.main;
23
- case 'local-affects':
24
- return theme.palette.primary.main;
25
- default:
26
- return theme.palette.text.secondary;
27
- }
28
- } };
29
- `;
30
9
 
31
10
  export const StylesInheritanceIndicator = () => {
32
- const { bind } = useBoundProp();
11
+ const { value, path } = useBoundProp();
33
12
  const { id: currentStyleId, provider: currentStyleProvider, meta: currentStyleMeta } = useStyle();
34
- const [ value ] = useStylesField( bind );
13
+
14
+ // in the styles inheritance snapshot the keys are only those of the top level style schema attributes
15
+ const [ bind ] = path;
35
16
  const inheritanceChain = useStylesInheritanceField( bind );
36
17
 
37
18
  if ( ! inheritanceChain.length ) {
38
19
  return null;
39
20
  }
40
21
 
41
- const [ { styleId, styleVariant } ] = inheritanceChain;
22
+ const [ { style, variant, provider } ] = inheritanceChain;
23
+
24
+ if ( provider === ELEMENTS_BASE_STYLES_PROVIDER_KEY ) {
25
+ return null;
26
+ }
42
27
 
43
- const { breakpoint, state } = styleVariant.meta;
28
+ const { breakpoint, state } = variant.meta;
44
29
 
45
30
  if (
46
- styleId === currentStyleId &&
31
+ style.id === currentStyleId &&
47
32
  breakpoint === currentStyleMeta.breakpoint &&
48
33
  state === currentStyleMeta.state
49
34
  ) {
50
35
  return (
51
- <Circle
36
+ <StyleIndicator
52
37
  aria-label={ __( 'This is the final value', 'elementor' ) }
53
- variant={
54
- currentStyleProvider?.key === ELEMENTS_STYLES_PROVIDER_KEY ? 'local-affects' : 'global-affects'
55
- }
38
+ variant={ currentStyleProvider?.key === ELEMENTS_STYLES_PROVIDER_KEY ? 'local' : 'global' }
56
39
  />
57
40
  );
58
41
  }
59
42
 
60
43
  if ( value !== null && value !== undefined ) {
61
44
  return (
62
- <Circle
45
+ <StyleIndicator
63
46
  aria-label={ __( 'This value is overridden by another style', 'elementor' ) }
64
47
  variant="overridden"
65
48
  />
66
49
  );
67
50
  }
68
51
 
69
- return <Circle aria-label={ __( 'This has value from another style', 'elementor' ) } />;
52
+ return <StyleIndicator aria-label={ __( 'This has value from another style', 'elementor' ) } />;
70
53
  };
@@ -1,17 +1,18 @@
1
1
  import { type PropValue } from '@elementor/editor-props';
2
2
  import { type BreakpointId } from '@elementor/editor-responsive';
3
- import { type StyleDefinitionState, type StyleDefinitionVariant } from '@elementor/editor-styles';
3
+ import { type StyleDefinition, type StyleDefinitionState, type StyleDefinitionVariant } from '@elementor/editor-styles';
4
4
 
5
5
  export type StyleDefinitionStateWithNormal = NonNullable< StyleDefinitionState > | 'normal';
6
6
 
7
7
  type StatesMapping< T > = Partial< Record< StyleDefinitionStateWithNormal, T > >;
8
8
 
9
- export type StyleVariantWithId = {
10
- styleId: string;
11
- styleVariant: StyleDefinitionVariant;
9
+ export type StyleVariantDetails = {
10
+ style: StyleDefinition;
11
+ provider: string | null;
12
+ variant: StyleDefinitionVariant;
12
13
  };
13
14
 
14
- export type SnapshotPropValue = StyleVariantWithId & {
15
+ export type SnapshotPropValue = StyleVariantDetails & {
15
16
  value: PropValue;
16
17
  };
17
18
 
@@ -26,7 +27,7 @@ export type BreakpointStatesSlotsMapping = StatesMapping< StylesInheritanceSnaps
26
27
 
27
28
  export type BreakpointsStatesSnapshotsMapping = Partial< Record< BreakpointId, BreakpointStatesSlotsMapping > >;
28
29
 
29
- type BreakpointStatesStyles = StatesMapping< StyleVariantWithId[] >;
30
+ type BreakpointStatesStyles = StatesMapping< StyleVariantDetails[] >;
30
31
 
31
32
  export type BreakpointsStatesStyles = Partial< Record< BreakpointId, Partial< BreakpointStatesStyles > > >;
32
33