@elementor/editor-editing-panel 1.47.0 → 1.48.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-editing-panel",
3
- "version": "1.47.0",
3
+ "version": "1.48.0",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,25 +39,24 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "0.20.1",
43
- "@elementor/editor-canvas": "0.25.0",
44
- "@elementor/editor-controls": "1.2.0",
45
- "@elementor/editor-current-user": "0.5.0",
46
- "@elementor/editor-documents": "0.13.8",
47
- "@elementor/editor-elements": "0.8.7",
48
- "@elementor/editor-panels": "0.16.1",
49
- "@elementor/editor-props": "0.15.0",
42
+ "@elementor/editor": "0.21.0",
43
+ "@elementor/editor-canvas": "0.26.0",
44
+ "@elementor/editor-controls": "1.3.0",
45
+ "@elementor/editor-documents": "0.13.9",
46
+ "@elementor/editor-elements": "0.9.0",
47
+ "@elementor/editor-panels": "0.17.0",
48
+ "@elementor/editor-props": "0.16.0",
50
49
  "@elementor/editor-responsive": "0.13.6",
51
- "@elementor/editor-styles": "0.6.11",
52
- "@elementor/editor-styles-repository": "0.10.4",
53
- "@elementor/editor-ui": "0.13.0",
50
+ "@elementor/editor-styles": "0.6.12",
51
+ "@elementor/editor-styles-repository": "0.10.5",
52
+ "@elementor/editor-ui": "0.14.0",
54
53
  "@elementor/editor-v1-adapters": "0.12.1",
55
- "@elementor/icons": "1.44.0",
54
+ "@elementor/icons": "1.46.0",
56
55
  "@elementor/locations": "0.8.0",
57
56
  "@elementor/menus": "0.1.5",
58
57
  "@elementor/schema": "0.1.2",
59
58
  "@elementor/session": "0.1.0",
60
- "@elementor/ui": "1.35.5",
59
+ "@elementor/ui": "1.36.0",
61
60
  "@elementor/utils": "0.5.0",
62
61
  "@elementor/wp-media": "0.6.1",
63
62
  "@wordpress/i18n": "^5.13.0"
@@ -8,6 +8,8 @@ import { BorderColorField } from './border-color-field';
8
8
  import { BorderStyleField } from './border-style-field';
9
9
  import { BorderWidthField } from './border-width-field';
10
10
 
11
+ const BORDER_LABEL = __( 'Border', 'elementor' );
12
+
11
13
  const initialBorder = {
12
14
  'border-width': { $$type: 'size', value: { size: 1, unit: 'px' } },
13
15
  'border-color': { $$type: 'color', value: '#000000' },
@@ -17,16 +19,21 @@ const initialBorder = {
17
19
  export const BorderField = () => {
18
20
  const { values, setValues, canEdit } = useStylesFields( Object.keys( initialBorder ) );
19
21
 
22
+ const meta = { history: { propDisplayName: BORDER_LABEL } };
23
+
20
24
  const addBorder = () => {
21
- setValues( initialBorder );
25
+ setValues( initialBorder, meta );
22
26
  };
23
27
 
24
28
  const removeBorder = () => {
25
- setValues( {
26
- 'border-width': null,
27
- 'border-color': null,
28
- 'border-style': null,
29
- } );
29
+ setValues(
30
+ {
31
+ 'border-width': null,
32
+ 'border-color': null,
33
+ 'border-style': null,
34
+ },
35
+ meta
36
+ );
30
37
  };
31
38
 
32
39
  const hasBorder = Object.values( values ?? {} ).some( Boolean );
@@ -37,7 +44,7 @@ export const BorderField = () => {
37
44
  onAdd={ addBorder }
38
45
  onRemove={ removeBorder }
39
46
  disabled={ ! canEdit }
40
- renderLabel={ () => <ControlFormLabel>{ __( 'Border', 'elementor' ) }</ControlFormLabel> }
47
+ renderLabel={ () => <ControlFormLabel>{ BORDER_LABEL }</ControlFormLabel> }
41
48
  >
42
49
  <BorderWidthField />
43
50
  <BorderColorField />
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { BoxShadowRepeaterControl, FilterRepeaterControl } from '@elementor/editor-controls';
2
+ import { BoxShadowRepeaterControl, FilterRepeaterControl, TransformRepeaterControl } from '@elementor/editor-controls';
3
3
  import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
4
  import { __ } from '@wordpress/i18n';
5
5
 
@@ -11,19 +11,28 @@ import { OpacityControlField } from '../layout-section/opacity-control-field';
11
11
 
12
12
  const BOX_SHADOW_LABEL = __( 'Box shadow', 'elementor' );
13
13
  const FILTER_LABEL = __( 'Filter', 'elementor' );
14
+ const TRANSFORM_LABEL = __( 'Transform', 'elementor' );
14
15
 
15
16
  export const EffectsSection = () => {
16
17
  const isVersion331Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_31 );
17
18
 
18
19
  return (
19
20
  <SectionContent>
20
- <OpacityControlField />
21
- <PanelDivider />
21
+ { isVersion331Active && (
22
+ <>
23
+ <OpacityControlField />
24
+ <PanelDivider />
25
+ </>
26
+ ) }
22
27
  <StylesField bind="box-shadow" propDisplayName={ BOX_SHADOW_LABEL }>
23
28
  <BoxShadowRepeaterControl />
24
29
  </StylesField>
25
30
  { isVersion331Active && (
26
31
  <>
32
+ <PanelDivider />
33
+ <StylesField bind="transform" propDisplayName={ TRANSFORM_LABEL }>
34
+ <TransformRepeaterControl />
35
+ </StylesField>
27
36
  <PanelDivider />
28
37
  <StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
29
38
  <FilterRepeaterControl />
@@ -50,7 +50,13 @@ const items: ToggleButtonGroupItem< GroupControlItemOption >[] = [
50
50
  ];
51
51
 
52
52
  export const FlexOrderField = () => {
53
- const { value: order, setValue: setOrder, canEdit } = useStylesField< NumberPropValue | null >( 'order' );
53
+ const {
54
+ value: order,
55
+ setValue: setOrder,
56
+ canEdit,
57
+ } = useStylesField< NumberPropValue | null >( 'order', {
58
+ history: { propDisplayName: ORDER_LABEL },
59
+ } );
54
60
 
55
61
  const [ groupControlValue, setGroupControlValue ] = useState( getGroupControlValue( order?.value || null ) );
56
62
 
@@ -69,8 +75,8 @@ export const FlexOrderField = () => {
69
75
  return (
70
76
  <StylesField bind="order" propDisplayName={ ORDER_LABEL }>
71
77
  <UiProviders>
72
- <StylesFieldLayout label={ ORDER_LABEL }>
73
- <SectionContent>
78
+ <SectionContent>
79
+ <StylesFieldLayout label={ ORDER_LABEL }>
74
80
  <ControlToggleButtonGroup
75
81
  items={ items }
76
82
  value={ groupControlValue }
@@ -78,22 +84,22 @@ export const FlexOrderField = () => {
78
84
  exclusive={ true }
79
85
  disabled={ ! canEdit }
80
86
  />
81
- { CUSTOM === groupControlValue && (
82
- <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
83
- <Grid item xs={ 6 }>
84
- <ControlLabel>{ __( 'Custom order', 'elementor' ) }</ControlLabel>
85
- </Grid>
86
- <Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
87
- <NumberControl
88
- min={ FIRST_DEFAULT_VALUE + 1 }
89
- max={ LAST_DEFAULT_VALUE - 1 }
90
- shouldForceInt={ true }
91
- />
92
- </Grid>
87
+ </StylesFieldLayout>
88
+ { CUSTOM === groupControlValue && (
89
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
90
+ <Grid item xs={ 6 }>
91
+ <ControlLabel>{ __( 'Custom order', 'elementor' ) }</ControlLabel>
93
92
  </Grid>
94
- ) }
95
- </SectionContent>
96
- </StylesFieldLayout>
93
+ <Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
94
+ <NumberControl
95
+ min={ FIRST_DEFAULT_VALUE + 1 }
96
+ max={ LAST_DEFAULT_VALUE - 1 }
97
+ shouldForceInt={ true }
98
+ />
99
+ </Grid>
100
+ </Grid>
101
+ ) }
102
+ </SectionContent>
97
103
  </UiProviders>
98
104
  </StylesField>
99
105
  );
@@ -60,31 +60,29 @@ export const FlexSizeField = () => {
60
60
  const onChangeGroup = ( group: GroupItem | null = null ) => {
61
61
  setActiveGroup( group );
62
62
 
63
+ let props;
64
+
63
65
  if ( ! group || group === 'custom' ) {
64
- setValues( {
66
+ props = {
65
67
  'flex-basis': null,
66
68
  'flex-grow': null,
67
69
  'flex-shrink': null,
68
- } );
69
-
70
- return;
71
- }
72
-
73
- if ( group === 'flex-grow' ) {
74
- setValues( {
70
+ };
71
+ } else if ( group === 'flex-grow' ) {
72
+ props = {
75
73
  'flex-basis': null,
76
74
  'flex-grow': numberPropTypeUtil.create( DEFAULT ),
77
75
  'flex-shrink': null,
78
- } );
79
-
80
- return;
76
+ };
77
+ } else {
78
+ props = {
79
+ 'flex-basis': null,
80
+ 'flex-grow': null,
81
+ 'flex-shrink': numberPropTypeUtil.create( DEFAULT ),
82
+ };
81
83
  }
82
84
 
83
- setValues( {
84
- 'flex-basis': null,
85
- 'flex-grow': null,
86
- 'flex-shrink': numberPropTypeUtil.create( DEFAULT ),
87
- } );
85
+ setValues( props, { history: { propDisplayName: FLEX_SIZE_LABEL } } );
88
86
  };
89
87
 
90
88
  return (
@@ -20,8 +20,13 @@ import { GapControlField } from './gap-control-field';
20
20
  import { JustifyContentField } from './justify-content-field';
21
21
  import { WrapField } from './wrap-field';
22
22
 
23
+ const DISPLAY_LABEL = __( 'Display', 'elementor' );
24
+ const FLEX_WRAP_LABEL = __( 'Flex wrap', 'elementor' );
25
+
23
26
  export const LayoutSection = () => {
24
- const { value: display } = useStylesField< StringPropValue >( 'display' );
27
+ const { value: display } = useStylesField< StringPropValue >( 'display', {
28
+ history: { propDisplayName: DISPLAY_LABEL },
29
+ } );
25
30
  const displayPlaceholder = useDisplayPlaceholderValue();
26
31
  const isDisplayFlex = shouldDisplayFlexFields( display, displayPlaceholder as StringPropValue );
27
32
  const { element } = useElement();
@@ -39,7 +44,9 @@ export const LayoutSection = () => {
39
44
  };
40
45
 
41
46
  const FlexFields = () => {
42
- const { value: flexWrap } = useStylesField< StringPropValue >( 'flex-wrap' );
47
+ const { value: flexWrap } = useStylesField< StringPropValue >( 'flex-wrap', {
48
+ history: { propDisplayName: FLEX_WRAP_LABEL },
49
+ } );
43
50
 
44
51
  return (
45
52
  <>
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { useRef } from 'react';
3
3
  import { type StringPropValue } from '@elementor/editor-props';
4
4
  import { type ToggleButtonProps, useTheme } from '@elementor/ui';
5
+ import { __ } from '@wordpress/i18n';
5
6
 
6
7
  import { useStylesField } from '../../../../hooks/use-styles-field';
7
8
  import type { FlexDirection } from '../flex-direction-field';
@@ -14,6 +15,8 @@ type Props = {
14
15
  disableRotationForReversed?: boolean;
15
16
  };
16
17
 
18
+ const FLEX_DIRECTION_LABEL = __( 'Flex direction', 'elementor' );
19
+
17
20
  const CLOCKWISE_ANGLES: Record< FlexDirection, number > = {
18
21
  row: 0,
19
22
  column: 90,
@@ -48,7 +51,9 @@ const useGetTargetAngle = (
48
51
  disableRotationForReversed: boolean,
49
52
  existingRef?: React.MutableRefObject< number >
50
53
  ) => {
51
- const { value: direction } = useStylesField< StringPropValue >( 'flex-direction' );
54
+ const { value: direction } = useStylesField< StringPropValue >( 'flex-direction', {
55
+ history: { propDisplayName: FLEX_DIRECTION_LABEL },
56
+ } );
52
57
  const isRtl = 'rtl' === useTheme().direction;
53
58
  const rotationMultiplier = isRtl ? -1 : 1;
54
59
  const angleMap = isClockwise ? CLOCKWISE_ANGLES : COUNTER_CLOCKWISE_ANGLES;
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { type StringPropValue } from '@elementor/editor-props';
3
3
  import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
4
  import { useSessionStorage } from '@elementor/session';
5
+ import { __ } from '@wordpress/i18n';
5
6
 
6
7
  import { useStyle } from '../../../contexts/style-context';
7
8
  import { useStylesField } from '../../../hooks/use-styles-field';
@@ -28,8 +29,13 @@ type DimensionsValues = {
28
29
  'inset-inline-end': DimensionValue;
29
30
  };
30
31
 
32
+ const POSITION_LABEL = __( 'Position', 'elementor' );
33
+ const DIMENSIONS_LABEL = __( 'Dimensions', 'elementor' );
34
+
31
35
  export const PositionSection = () => {
32
- const { value: positionValue } = useStylesField< StringPropValue >( 'position' );
36
+ const { value: positionValue } = useStylesField< StringPropValue >( 'position', {
37
+ history: { propDisplayName: POSITION_LABEL },
38
+ } );
33
39
  const { values: dimensions, setValues: setDimensions } = useStylesFields< DimensionsValues >( [
34
40
  'inset-block-start',
35
41
  'inset-block-end',
@@ -41,19 +47,24 @@ export const PositionSection = () => {
41
47
  const isCssIdFeatureActive = isExperimentActive( 'e_v_3_30' );
42
48
 
43
49
  const onPositionChange = ( newPosition: string | null, previousPosition: string | null | undefined ) => {
50
+ const meta = { history: { propDisplayName: DIMENSIONS_LABEL } };
51
+
44
52
  if ( newPosition === 'static' ) {
45
53
  if ( dimensions ) {
46
54
  updateDimensionsHistory( dimensions );
47
- setDimensions( {
48
- 'inset-block-start': undefined,
49
- 'inset-block-end': undefined,
50
- 'inset-inline-start': undefined,
51
- 'inset-inline-end': undefined,
52
- } );
55
+ setDimensions(
56
+ {
57
+ 'inset-block-start': undefined,
58
+ 'inset-block-end': undefined,
59
+ 'inset-inline-start': undefined,
60
+ 'inset-inline-end': undefined,
61
+ },
62
+ meta
63
+ );
53
64
  }
54
65
  } else if ( previousPosition === 'static' ) {
55
66
  if ( dimensionsValuesFromHistory ) {
56
- setDimensions( dimensionsValuesFromHistory );
67
+ setDimensions( dimensionsValuesFromHistory, meta );
57
68
  clearDimensionsHistory();
58
69
  }
59
70
  }
@@ -52,9 +52,12 @@ const CssSizeProps = [
52
52
  ];
53
53
 
54
54
  const ASPECT_RATIO_LABEL = __( 'Aspect Ratio', 'elementor' );
55
+ const OBJECT_FIT_LABEL = __( 'Object fit', 'elementor' );
55
56
 
56
57
  export const SizeSection = () => {
57
- const { value: fitValue } = useStylesField< StringPropValue >( 'object-fit' );
58
+ const { value: fitValue } = useStylesField< StringPropValue >( 'object-fit', {
59
+ history: { propDisplayName: OBJECT_FIT_LABEL },
60
+ } );
58
61
 
59
62
  const isNotFill = fitValue && fitValue?.value !== 'fill';
60
63
 
@@ -27,7 +27,9 @@ const initTextStroke = {
27
27
  const TEXT_STROKE_LABEL = __( 'Text stroke', 'elementor' );
28
28
 
29
29
  export const TextStrokeField = () => {
30
- const { value, setValue, canEdit } = useStylesField( 'stroke' );
30
+ const { value, setValue, canEdit } = useStylesField( 'stroke', {
31
+ history: { propDisplayName: TEXT_STROKE_LABEL },
32
+ } );
31
33
 
32
34
  const addTextStroke = () => {
33
35
  setValue( initTextStroke );
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import type { NumberPropValue } from '@elementor/editor-props';
3
3
  import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
+ import { __ } from '@wordpress/i18n';
4
5
 
5
6
  import { useStylesField } from '../../../hooks/use-styles-field';
6
7
  import { PanelDivider } from '../../panel-divider';
@@ -22,8 +23,12 @@ import { TextStrokeField } from './text-stroke-field';
22
23
  import { TransformField } from './transform-field';
23
24
  import { WordSpacingField } from './word-spacing-field';
24
25
 
26
+ const COLUMN_COUNT_LABEL = __( 'Column count', 'elementor' );
27
+
25
28
  export const TypographySection = () => {
26
- const { value: columnCount } = useStylesField< NumberPropValue >( 'column-count' );
29
+ const { value: columnCount } = useStylesField< NumberPropValue >( 'column-count', {
30
+ history: { propDisplayName: COLUMN_COUNT_LABEL },
31
+ } );
27
32
  const hasMultiColumns = !! ( columnCount?.value && columnCount?.value > 1 );
28
33
 
29
34
  const isVersion330Active = isExperimentActive( 'e_v_3_30' );
@@ -29,7 +29,7 @@ const TABS_HEADER_HEIGHT = '37px';
29
29
 
30
30
  export const stickyHeaderStyles = {
31
31
  position: 'sticky',
32
- zIndex: 1,
32
+ zIndex: 1100,
33
33
  opacity: 1,
34
34
  backgroundColor: 'background.default',
35
35
  transition: 'top 300ms ease',
@@ -7,9 +7,9 @@ import {
7
7
  getElementLabel,
8
8
  getElementSetting,
9
9
  updateElementSettings,
10
- useElementSetting,
10
+ useElementSettings,
11
11
  } from '@elementor/editor-elements';
12
- import { type PropKey, type PropValue } from '@elementor/editor-props';
12
+ import { type PropKey, type PropType, type PropValue, shouldApplyEffect } from '@elementor/editor-props';
13
13
  import { isExperimentActive, undoable } from '@elementor/editor-v1-adapters';
14
14
  import { __ } from '@wordpress/i18n';
15
15
 
@@ -26,9 +26,9 @@ type Props = {
26
26
  export const SettingsField = ( { bind, children, propDisplayName }: Props ) => {
27
27
  const { element, elementType } = useElement();
28
28
 
29
- const settingsValue = useElementSetting< PropValue >( element.id, bind );
29
+ const elementSettingValues = useElementSettings< PropValue >( element.id, Object.keys( elementType.propsSchema ) );
30
30
 
31
- const value = { [ bind ]: settingsValue };
31
+ const value = { [ bind ]: elementSettingValues?.[ bind ] };
32
32
 
33
33
  const propType = createTopLevelOjectType( { schema: elementType.propsSchema } );
34
34
 
@@ -48,13 +48,29 @@ export const SettingsField = ( { bind, children, propDisplayName }: Props ) => {
48
48
  }
49
49
  };
50
50
 
51
+ const isDisabled = ( prop: PropType ) => getDisableState( prop, elementSettingValues );
52
+
51
53
  return (
52
- <PropProvider propType={ propType } value={ value } setValue={ setValue }>
54
+ <PropProvider propType={ propType } value={ value } setValue={ setValue } isDisabled={ isDisabled }>
53
55
  <PropKeyProvider bind={ bind }>{ children }</PropKeyProvider>
54
56
  </PropProvider>
55
57
  );
56
58
  };
57
59
 
60
+ function getDisableState( propType: PropType, elementValues: PropValue ): boolean | undefined {
61
+ const disablingDependencies = propType.dependencies?.filter( ( { effect } ) => effect === 'disable' ) || [];
62
+
63
+ if ( ! disablingDependencies.length ) {
64
+ return false;
65
+ }
66
+
67
+ if ( disablingDependencies.length > 1 ) {
68
+ throw new Error( 'Multiple disabling dependencies are not supported.' );
69
+ }
70
+
71
+ return shouldApplyEffect( disablingDependencies[ 0 ], elementValues );
72
+ }
73
+
58
74
  type UndoableUpdateElementSettingsArgs = {
59
75
  newValue: Record< string, PropValue >;
60
76
  };
@@ -16,8 +16,10 @@ export type StylesFieldProps = {
16
16
  propDisplayName: string;
17
17
  };
18
18
 
19
- export const StylesField = ( { bind, placeholder, children }: StylesFieldProps ) => {
20
- const { value, setValue, canEdit } = useStylesField( bind );
19
+ export const StylesField = ( { bind, placeholder, propDisplayName, children }: StylesFieldProps ) => {
20
+ const { value, setValue, canEdit } = useStylesField( bind, {
21
+ history: { propDisplayName },
22
+ } );
21
23
 
22
24
  const isVersion331Active = isExperimentActive( 'e_v_3_31' );
23
25
  const stylesInheritanceChain = useStylesInheritanceChain( [ bind ] );
@@ -49,7 +51,7 @@ export const StylesField = ( { bind, placeholder, children }: StylesFieldProps )
49
51
  value={ values }
50
52
  setValue={ setValues }
51
53
  placeholder={ placeholderValues }
52
- disabled={ ! canEdit }
54
+ isDisabled={ () => ! canEdit }
53
55
  >
54
56
  <PropKeyProvider bind={ bind }>{ children }</PropKeyProvider>
55
57
  </PropProvider>
@@ -3,7 +3,8 @@ import type { PropKey, PropValue } from '@elementor/editor-props';
3
3
  import { useStylesFields } from './use-styles-fields';
4
4
 
5
5
  export function useStylesField< T extends PropValue >(
6
- propName: PropKey
6
+ propName: PropKey,
7
+ meta: { history: { propDisplayName: string } }
7
8
  ): {
8
9
  value: T;
9
10
  setValue: ( newValue: T ) => void;
@@ -14,9 +15,7 @@ export function useStylesField< T extends PropValue >(
14
15
  const value = values?.[ propName ] ?? null;
15
16
 
16
17
  const setValue = ( newValue: T ) => {
17
- setValues( {
18
- [ propName ]: newValue,
19
- } );
18
+ setValues( { [ propName ]: newValue }, meta );
20
19
  };
21
20
 
22
21
  return { value: value as T, setValue, canEdit };