@elementor/editor-controls 0.32.0 → 0.34.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 (33) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/index.d.mts +6 -2
  3. package/dist/index.d.ts +6 -2
  4. package/dist/index.js +154 -84
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +152 -82
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +3 -3
  9. package/src/bound-prop-context/prop-context.tsx +3 -0
  10. package/src/bound-prop-context/prop-key-context.tsx +1 -0
  11. package/src/bound-prop-context/use-bound-prop.ts +1 -0
  12. package/src/components/control-toggle-button-group.tsx +6 -2
  13. package/src/components/popover-content.tsx +4 -2
  14. package/src/components/repeater.tsx +19 -10
  15. package/src/components/text-field-inner-selection.tsx +6 -0
  16. package/src/control-actions/control-actions.tsx +10 -2
  17. package/src/controls/aspect-ratio-control.tsx +14 -6
  18. package/src/controls/background-control/background-control.tsx +16 -19
  19. package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +2 -1
  20. package/src/controls/box-shadow-repeater-control.tsx +2 -1
  21. package/src/controls/color-control.tsx +2 -1
  22. package/src/controls/equal-unequal-sizes-control.tsx +25 -14
  23. package/src/controls/font-family-control/font-family-control.tsx +2 -1
  24. package/src/controls/gap-control.tsx +4 -1
  25. package/src/controls/linked-dimensions-control.tsx +36 -10
  26. package/src/controls/number-control.tsx +2 -1
  27. package/src/controls/select-control.tsx +2 -1
  28. package/src/controls/size-control.tsx +35 -27
  29. package/src/controls/switch-control.tsx +2 -2
  30. package/src/controls/text-area-control.tsx +2 -1
  31. package/src/controls/text-control.tsx +2 -1
  32. package/src/controls/toggle-control.tsx +3 -1
  33. package/src/controls/url-control.tsx +2 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-controls",
3
3
  "description": "This package contains the controls model and utils for the Elementor editor",
4
- "version": "0.32.0",
4
+ "version": "0.34.0",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -43,11 +43,11 @@
43
43
  "@elementor/editor-current-user": "0.5.0",
44
44
  "@elementor/editor-elements": "0.8.4",
45
45
  "@elementor/editor-props": "0.12.1",
46
- "@elementor/editor-ui": "0.9.0",
46
+ "@elementor/editor-ui": "0.10.0",
47
47
  "@elementor/editor-v1-adapters": "0.12.0",
48
48
  "@elementor/env": "0.3.5",
49
49
  "@elementor/http-client": "0.3.0",
50
- "@elementor/icons": "1.40.1",
50
+ "@elementor/icons": "1.44.0",
51
51
  "@elementor/locations": "0.8.0",
52
52
  "@elementor/query": "0.2.4",
53
53
  "@elementor/session": "0.1.0",
@@ -15,6 +15,7 @@ type PropContext< T extends PropValue, P extends PropType > = {
15
15
  value: T | null;
16
16
  propType: P;
17
17
  placeholder?: T;
18
+ disabled?: boolean;
18
19
  };
19
20
 
20
21
  const PropContext = createContext< PropContext< PropValue, PropType > | null >( null );
@@ -29,6 +30,7 @@ export const PropProvider = < T extends PropValue, P extends PropType >( {
29
30
  setValue,
30
31
  propType,
31
32
  placeholder,
33
+ disabled,
32
34
  }: PropProviderProps< T, P > ) => {
33
35
  return (
34
36
  <PropContext.Provider
@@ -37,6 +39,7 @@ export const PropProvider = < T extends PropValue, P extends PropType >( {
37
39
  propType,
38
40
  setValue: setValue as SetValue< PropValue >,
39
41
  placeholder,
42
+ disabled,
40
43
  } }
41
44
  >
42
45
  { children }
@@ -21,6 +21,7 @@ export type PropKeyContextValue< T, P > = {
21
21
  propType: P;
22
22
  placeholder?: T;
23
23
  path: PropKey[];
24
+ disabled?: boolean;
24
25
  };
25
26
 
26
27
  const PropKeyContext = createContext< PropKeyContextValue< PropValue, PropType > | null >( null );
@@ -19,6 +19,7 @@ type UseBoundProp< TValue extends PropValue > = {
19
19
  placeholder?: TValue;
20
20
  path: PropKey[];
21
21
  restoreValue: () => void;
22
+ disabled?: boolean;
22
23
  };
23
24
 
24
25
  export function useBoundProp< T extends PropValue = PropValue >(): PropKeyContextValue< T, PropType >;
@@ -14,6 +14,7 @@ import {
14
14
  useTheme,
15
15
  } from '@elementor/ui';
16
16
 
17
+ import ControlActions from '../control-actions/control-actions';
17
18
  import { ConditionalTooltip } from './conditional-tooltip';
18
19
 
19
20
  type RenderContentProps = { size: ToggleButtonProps[ 'size' ] };
@@ -45,6 +46,7 @@ type ExclusiveValue< TValue > = TValue;
45
46
  type NonExclusiveValue< TValue > = TValue[];
46
47
 
47
48
  type Props< TValue > = {
49
+ disabled?: boolean;
48
50
  justify?: StackProps[ 'justifyContent' ];
49
51
  size?: ToggleButtonProps[ 'size' ];
50
52
  items: ToggleButtonGroupItem< TValue | null >[];
@@ -72,6 +74,7 @@ export const ControlToggleButtonGroup = < TValue, >( {
72
74
  maxItems,
73
75
  exclusive = false,
74
76
  fullWidth = false,
77
+ disabled,
75
78
  }: Props< TValue > ) => {
76
79
  const shouldSliceItems = exclusive && maxItems !== undefined && items.length > maxItems;
77
80
  const menuItems = shouldSliceItems ? items.slice( maxItems - 1 ) : [];
@@ -94,12 +97,13 @@ export const ControlToggleButtonGroup = < TValue, >( {
94
97
  }, [ menuItems?.length, fixedItems.length ] );
95
98
 
96
99
  return (
97
- <>
100
+ <ControlActions>
98
101
  <StyledToggleButtonGroup
99
102
  justify={ justify }
100
103
  value={ value }
101
104
  onChange={ handleChange }
102
105
  exclusive={ exclusive }
106
+ disabled={ disabled }
103
107
  sx={ {
104
108
  direction: isRtl ? 'rtl /* @noflip */' : 'ltr /* @noflip */',
105
109
  display: 'grid',
@@ -129,7 +133,7 @@ export const ControlToggleButtonGroup = < TValue, >( {
129
133
  />
130
134
  ) }
131
135
  </StyledToggleButtonGroup>
132
- </>
136
+ </ControlActions>
133
137
  );
134
138
  };
135
139
 
@@ -6,10 +6,12 @@ type PopoverContentProps = PropsWithChildren< {
6
6
  alignItems?: 'center';
7
7
  gap?: number;
8
8
  p?: 1.5 | 2 | 2.5;
9
+ pt?: 2.5;
10
+ pb?: 3;
9
11
  } >;
10
12
 
11
- export const PopoverContent: FC< PopoverContentProps > = ( { alignItems, gap = 1.5, p, children } ) => (
12
- <Stack alignItems={ alignItems } gap={ gap } p={ p }>
13
+ export const PopoverContent: FC< PopoverContentProps > = ( { alignItems, gap = 1.5, p, pt, pb, children } ) => (
14
+ <Stack alignItems={ alignItems } gap={ gap } p={ p } pt={ pt } pb={ pb }>
13
15
  { children }
14
16
  </Stack>
15
17
  );
@@ -37,6 +37,7 @@ type RepeaterProps< T > = {
37
37
  addToBottom?: boolean;
38
38
  openOnAdd?: boolean;
39
39
  setValues: ( newValue: T[] ) => void;
40
+ disabled?: boolean;
40
41
  itemSettings: {
41
42
  initialValues: T;
42
43
  Label: React.ComponentType< { value: T } >;
@@ -54,6 +55,7 @@ const EMPTY_OPEN_ITEM = -1;
54
55
  export const Repeater = < T, >( {
55
56
  label,
56
57
  itemSettings,
58
+ disabled = false,
57
59
  openOnAdd = false,
58
60
  addToBottom = false,
59
61
  values: repeaterValues = [],
@@ -120,10 +122,10 @@ export const Repeater = < T, >( {
120
122
  setItems(
121
123
  items.map( ( value, pos ) => {
122
124
  if ( pos === index ) {
123
- const { disabled, ...rest } = value;
125
+ const { disabled: propDisabled, ...rest } = value;
124
126
 
125
127
  // If the items should not be disabled, remove the disabled property.
126
- return { ...rest, ...( disabled ? {} : { disabled: true } ) } as Item< T >;
128
+ return { ...rest, ...( propDisabled ? {} : { disabled: true } ) } as Item< T >;
127
129
  }
128
130
 
129
131
  return value;
@@ -141,6 +143,8 @@ export const Repeater = < T, >( {
141
143
  } );
142
144
  };
143
145
 
146
+ const ItemWrapper = disabled ? React.Fragment : SortableItem;
147
+
144
148
  return (
145
149
  <SectionContent>
146
150
  <Stack
@@ -155,8 +159,9 @@ export const Repeater = < T, >( {
155
159
  </Typography>
156
160
  <ControlAdornments />
157
161
  <IconButton
158
- sx={ { ml: 'auto' } }
159
162
  size={ SIZE }
163
+ sx={ { ml: 'auto' } }
164
+ disabled={ disabled }
160
165
  onClick={ addRepeaterItem }
161
166
  aria-label={ __( 'Add item', 'elementor' ) }
162
167
  >
@@ -173,9 +178,10 @@ export const Repeater = < T, >( {
173
178
  }
174
179
 
175
180
  return (
176
- <SortableItem id={ key } key={ `sortable-${ key }` }>
181
+ <ItemWrapper id={ key } key={ `sortable-${ key }` }>
177
182
  <RepeaterItem
178
- disabled={ value?.disabled }
183
+ disabled={ disabled }
184
+ propDisabled={ value?.disabled }
179
185
  label={
180
186
  <RepeaterItemLabelSlot value={ value }>
181
187
  <itemSettings.Label value={ value } />
@@ -196,7 +202,7 @@ export const Repeater = < T, >( {
196
202
  <itemSettings.Content { ...props } value={ value } bind={ String( index ) } />
197
203
  ) }
198
204
  </RepeaterItem>
199
- </SortableItem>
205
+ </ItemWrapper>
200
206
  );
201
207
  } ) }
202
208
  </SortableProvider>
@@ -207,7 +213,7 @@ export const Repeater = < T, >( {
207
213
 
208
214
  type RepeaterItemProps = {
209
215
  label: React.ReactNode;
210
- disabled?: boolean;
216
+ propDisabled?: boolean;
211
217
  startIcon: UnstableTagProps[ 'startIcon' ];
212
218
  removeItem: () => void;
213
219
  duplicateItem: () => void;
@@ -215,11 +221,12 @@ type RepeaterItemProps = {
215
221
  children: ( { anchorEl }: { anchorEl: AnchorEl } ) => React.ReactNode;
216
222
  openOnMount: boolean;
217
223
  onOpen: () => void;
224
+ disabled?: boolean;
218
225
  };
219
226
 
220
227
  const RepeaterItem = ( {
221
228
  label,
222
- disabled,
229
+ propDisabled,
223
230
  startIcon,
224
231
  children,
225
232
  removeItem,
@@ -227,17 +234,19 @@ const RepeaterItem = ( {
227
234
  toggleDisableItem,
228
235
  openOnMount,
229
236
  onOpen,
237
+ disabled,
230
238
  }: RepeaterItemProps ) => {
231
239
  const [ anchorEl, setAnchorEl ] = useState< AnchorEl >( null );
232
240
  const { popoverState, popoverProps, ref, setRef } = usePopover( openOnMount, onOpen );
233
241
 
234
242
  const duplicateLabel = __( 'Duplicate', 'elementor' );
235
- const toggleLabel = disabled ? __( 'Show', 'elementor' ) : __( 'Hide', 'elementor' );
243
+ const toggleLabel = propDisabled ? __( 'Show', 'elementor' ) : __( 'Hide', 'elementor' );
236
244
  const removeLabel = __( 'Remove', 'elementor' );
237
245
 
238
246
  return (
239
247
  <>
240
248
  <UnstableTag
249
+ disabled={ disabled }
241
250
  label={ label }
242
251
  showActionsOnHover
243
252
  fullWidth
@@ -255,7 +264,7 @@ const RepeaterItem = ( {
255
264
  </Tooltip>
256
265
  <Tooltip title={ toggleLabel } placement="top">
257
266
  <IconButton size={ SIZE } onClick={ toggleDisableItem } aria-label={ toggleLabel }>
258
- { disabled ? <EyeOffIcon fontSize={ SIZE } /> : <EyeIcon fontSize={ SIZE } /> }
267
+ { propDisabled ? <EyeOffIcon fontSize={ SIZE } /> : <EyeIcon fontSize={ SIZE } /> }
259
268
  </IconButton>
260
269
  </Tooltip>
261
270
  <Tooltip title={ removeLabel } placement="top">
@@ -14,6 +14,7 @@ type TextFieldInnerSelectionProps = {
14
14
  onKeyUp?: ( event: React.KeyboardEvent< HTMLInputElement > ) => void;
15
15
  endAdornment: React.ReactNode;
16
16
  startAdornment?: React.ReactNode;
17
+ disabled?: boolean;
17
18
  };
18
19
 
19
20
  export const TextFieldInnerSelection = forwardRef(
@@ -28,6 +29,7 @@ export const TextFieldInnerSelection = forwardRef(
28
29
  onKeyUp,
29
30
  endAdornment,
30
31
  startAdornment,
32
+ disabled,
31
33
  }: TextFieldInnerSelectionProps,
32
34
  ref
33
35
  ) => {
@@ -38,6 +40,7 @@ export const TextFieldInnerSelection = forwardRef(
38
40
  fullWidth
39
41
  type={ type }
40
42
  value={ value }
43
+ disabled={ disabled }
41
44
  onChange={ onChange }
42
45
  onKeyDown={ onKeyDown }
43
46
  onKeyUp={ onKeyUp }
@@ -56,12 +59,14 @@ type SelectionEndAdornmentProps< T extends string > = {
56
59
  options: T[];
57
60
  onClick: ( value: T ) => void;
58
61
  value: T;
62
+ disabled?: boolean;
59
63
  };
60
64
 
61
65
  export const SelectionEndAdornment = < T extends string >( {
62
66
  options,
63
67
  onClick,
64
68
  value,
69
+ disabled,
65
70
  }: SelectionEndAdornmentProps< T > ) => {
66
71
  const popupState = usePopupState( {
67
72
  variant: 'popover',
@@ -78,6 +83,7 @@ export const SelectionEndAdornment = < T extends string >( {
78
83
  <Button
79
84
  size="small"
80
85
  color="secondary"
86
+ disabled={ disabled }
81
87
  sx={ { font: 'inherit', minWidth: 'initial', textTransform: 'uppercase' } }
82
88
  { ...bindTrigger( popupState ) }
83
89
  >
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { type PropsWithChildren, type ReactElement } from 'react';
3
3
  import { styled, UnstableFloatingActionBar } from '@elementor/ui';
4
4
 
5
+ import { useBoundProp } from '../bound-prop-context';
5
6
  import { useControlActions } from './control-actions-context';
6
7
 
7
8
  // CSS hack to hide empty floating bars.
@@ -11,14 +12,19 @@ const FloatingBarContainer = styled( 'span' )`
11
12
  .MuiFloatingActionBar-popper:has( .MuiFloatingActionBar-actions:empty ) {
12
13
  display: none;
13
14
  }
15
+
16
+ .MuiFloatingActionBar-popper {
17
+ z-index: 1000;
18
+ }
14
19
  `;
15
20
 
16
21
  type ControlActionsProps = PropsWithChildren< object >;
17
22
 
18
23
  export default function ControlActions( { children }: ControlActionsProps ) {
19
24
  const { items } = useControlActions();
25
+ const { disabled } = useBoundProp();
20
26
 
21
- if ( items.length === 0 ) {
27
+ if ( items.length === 0 || disabled ) {
22
28
  return children;
23
29
  }
24
30
 
@@ -26,7 +32,9 @@ export default function ControlActions( { children }: ControlActionsProps ) {
26
32
 
27
33
  return (
28
34
  <FloatingBarContainer>
29
- <UnstableFloatingActionBar actions={ menuItems }>{ children as ReactElement }</UnstableFloatingActionBar>
35
+ <UnstableFloatingActionBar actions={ menuItems } placement="bottom-start">
36
+ { children as ReactElement }
37
+ </UnstableFloatingActionBar>
30
38
  </FloatingBarContainer>
31
39
  );
32
40
  }
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import { useState } from 'react';
3
3
  import { stringPropTypeUtil } from '@elementor/editor-props';
4
4
  import { MenuListItem } from '@elementor/editor-ui';
5
+ import { ArrowsMoveHorizontalIcon, ArrowsMoveVerticalIcon } from '@elementor/icons';
5
6
  import { Grid, Select, type SelectChangeEvent, Stack, TextField } from '@elementor/ui';
6
7
  import { __ } from '@wordpress/i18n';
7
8
 
@@ -23,7 +24,7 @@ const RATIO_OPTIONS = [
23
24
  const CUSTOM_RATIO = 'custom';
24
25
 
25
26
  export const AspectRatioControl = createControl( ( { label }: { label: string } ) => {
26
- const { value: aspectRatioValue, setValue: setAspectRatioValue } = useBoundProp( stringPropTypeUtil );
27
+ const { value: aspectRatioValue, setValue: setAspectRatioValue, disabled } = useBoundProp( stringPropTypeUtil );
27
28
 
28
29
  const isCustomSelected =
29
30
  aspectRatioValue && ! RATIO_OPTIONS.some( ( option ) => option.value === aspectRatioValue );
@@ -68,16 +69,17 @@ export const AspectRatioControl = createControl( ( { label }: { label: string }
68
69
  };
69
70
 
70
71
  return (
71
- <Stack direction="column" gap={ 2 }>
72
+ <Stack direction="column" pt={ 2 } gap={ 2 }>
72
73
  <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
73
74
  <Grid item xs={ 6 }>
74
75
  <ControlLabel>{ label }</ControlLabel>
75
76
  </Grid>
76
77
  <Grid item xs={ 6 }>
77
78
  <Select
78
- sx={ { overflow: 'hidden' } }
79
- displayEmpty
80
79
  size="tiny"
80
+ displayEmpty
81
+ sx={ { overflow: 'hidden' } }
82
+ disabled={ disabled }
81
83
  value={ selectedValue }
82
84
  onChange={ handleSelectChange }
83
85
  fullWidth
@@ -99,9 +101,12 @@ export const AspectRatioControl = createControl( ( { label }: { label: string }
99
101
  size="tiny"
100
102
  type="number"
101
103
  fullWidth
104
+ disabled={ disabled }
102
105
  value={ customWidth }
103
106
  onChange={ handleCustomWidthChange }
104
- placeholder={ __( 'Width', 'elementor' ) }
107
+ InputProps={ {
108
+ startAdornment: <ArrowsMoveHorizontalIcon fontSize="tiny" />,
109
+ } }
105
110
  />
106
111
  </Grid>
107
112
  <Grid item xs={ 6 }>
@@ -109,9 +114,12 @@ export const AspectRatioControl = createControl( ( { label }: { label: string }
109
114
  size="tiny"
110
115
  type="number"
111
116
  fullWidth
117
+ disabled={ disabled }
112
118
  value={ customHeight }
113
119
  onChange={ handleCustomHeightChange }
114
- placeholder={ __( 'Height', 'elementor' ) }
120
+ InputProps={ {
121
+ startAdornment: <ArrowsMoveVerticalIcon fontSize="tiny" />,
122
+ } }
115
123
  />
116
124
  </Grid>
117
125
  </Grid>
@@ -7,7 +7,6 @@ import { __ } from '@wordpress/i18n';
7
7
  import { PropKeyProvider, PropProvider, useBoundProp } from '../../bound-prop-context';
8
8
  import { ControlFormLabel } from '../../components/control-form-label';
9
9
  import { ControlLabel } from '../../components/control-label';
10
- import { SectionContent } from '../../components/section-content';
11
10
  import { createControl } from '../../create-control';
12
11
  import { ColorControl } from '../color-control';
13
12
  import { BackgroundOverlayRepeaterControl } from './background-overlay/background-overlay-repeater-control';
@@ -20,25 +19,23 @@ export const BackgroundControl = createControl( () => {
20
19
 
21
20
  return (
22
21
  <PropProvider { ...propContext }>
23
- <SectionContent>
24
- <PropKeyProvider bind="background-overlay">
25
- <BackgroundOverlayRepeaterControl />
26
- </PropKeyProvider>
27
- <PropKeyProvider bind="color">
28
- <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
29
- <Grid item xs={ 6 }>
30
- { isUsingNestedProps ? (
31
- <ControlLabel>{ colorLabel }</ControlLabel>
32
- ) : (
33
- <ControlFormLabel>{ colorLabel }</ControlFormLabel>
34
- ) }
35
- </Grid>
36
- <Grid item xs={ 6 }>
37
- <ColorControl />
38
- </Grid>
22
+ <PropKeyProvider bind="background-overlay">
23
+ <BackgroundOverlayRepeaterControl />
24
+ </PropKeyProvider>
25
+ <PropKeyProvider bind="color">
26
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
27
+ <Grid item xs={ 6 }>
28
+ { isUsingNestedProps ? (
29
+ <ControlLabel>{ colorLabel }</ControlLabel>
30
+ ) : (
31
+ <ControlFormLabel>{ colorLabel }</ControlFormLabel>
32
+ ) }
39
33
  </Grid>
40
- </PropKeyProvider>
41
- </SectionContent>
34
+ <Grid item xs={ 6 }>
35
+ <ColorControl />
36
+ </Grid>
37
+ </Grid>
38
+ </PropKeyProvider>
42
39
  </PropProvider>
43
40
  );
44
41
  } );
@@ -71,12 +71,13 @@ const backgroundResolutionOptions = [
71
71
  ];
72
72
 
73
73
  export const BackgroundOverlayRepeaterControl = createControl( () => {
74
- const { propType, value: overlayValues, setValue } = useBoundProp( backgroundOverlayPropTypeUtil );
74
+ const { propType, value: overlayValues, setValue, disabled } = useBoundProp( backgroundOverlayPropTypeUtil );
75
75
 
76
76
  return (
77
77
  <PropProvider propType={ propType } value={ overlayValues } setValue={ setValue }>
78
78
  <Repeater
79
79
  openOnAdd
80
+ disabled={ disabled }
80
81
  values={ overlayValues ?? [] }
81
82
  setValues={ setValue }
82
83
  label={ __( 'Overlay', 'elementor' ) }
@@ -13,12 +13,13 @@ import { SelectControl } from './select-control';
13
13
  import { SizeControl } from './size-control';
14
14
 
15
15
  export const BoxShadowRepeaterControl = createControl( () => {
16
- const { propType, value, setValue } = useBoundProp( boxShadowPropTypeUtil );
16
+ const { propType, value, setValue, disabled } = useBoundProp( boxShadowPropTypeUtil );
17
17
 
18
18
  return (
19
19
  <PropProvider propType={ propType } value={ value } setValue={ setValue }>
20
20
  <Repeater
21
21
  openOnAdd
22
+ disabled={ disabled }
22
23
  values={ value ?? [] }
23
24
  setValues={ setValue }
24
25
  label={ __( 'Box shadow', 'elementor' ) }
@@ -13,7 +13,7 @@ type Props = Partial< Omit< UnstableColorFieldProps, 'value' | 'onChange' > > &
13
13
 
14
14
  export const ColorControl = createControl(
15
15
  ( { propTypeUtil = colorPropTypeUtil, anchorEl, slotProps = {}, ...props }: Props ) => {
16
- const { value, setValue } = useBoundProp( propTypeUtil );
16
+ const { value, setValue, disabled } = useBoundProp( propTypeUtil );
17
17
 
18
18
  const handleChange = ( selectedColor: string ) => {
19
19
  setValue( selectedColor || null );
@@ -27,6 +27,7 @@ export const ColorControl = createControl(
27
27
  value={ value ?? '' }
28
28
  onChange={ handleChange }
29
29
  { ...props }
30
+ disabled={ disabled }
30
31
  slotProps={ {
31
32
  ...slotProps,
32
33
  colorPicker: {
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { type ReactNode, useId, useRef } from 'react';
3
3
  import { type PropKey, type PropTypeUtil, sizePropTypeUtil, type SizePropValue } from '@elementor/editor-props';
4
+ import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
5
  import { bindPopover, bindToggle, Grid, Popover, Stack, ToggleButton, Tooltip, usePopupState } from '@elementor/ui';
5
6
  import { __ } from '@wordpress/i18n';
6
7
 
@@ -58,9 +59,10 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
58
59
  propType: multiSizePropType,
59
60
  value: multiSizeValue,
60
61
  setValue: setMultiSizeValue,
62
+ disabled: multiSizeDisabled,
61
63
  } = useBoundProp( multiSizePropTypeUtil );
62
64
 
63
- const { value: sizeValue, setValue: setSizeValue } = useBoundProp( sizePropTypeUtil );
65
+ const { value: sizeValue, setValue: setSizeValue, disabled: sizeDisabled } = useBoundProp( sizePropTypeUtil );
64
66
 
65
67
  const splitEqualValue = () => {
66
68
  if ( ! sizeValue ) {
@@ -115,6 +117,7 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
115
117
  { ...bindToggle( popupState ) }
116
118
  selected={ popupState.isOpen }
117
119
  aria-label={ tooltipLabel }
120
+ disabled={ multiSizeDisabled || sizeDisabled }
118
121
  >
119
122
  { icon }
120
123
  </ToggleButton>
@@ -139,7 +142,7 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
139
142
  } }
140
143
  >
141
144
  <PropProvider propType={ multiSizePropType } value={ getMultiSizeValues() } setValue={ setNestedProp }>
142
- <PopoverContent p={ 1.5 }>
145
+ <PopoverContent p={ 1.5 } pt={ 2.5 } pb={ 3 }>
143
146
  <PopoverGridContainer>
144
147
  <MultiSizeValueControl item={ items[ 0 ] } />
145
148
  <MultiSizeValueControl item={ items[ 1 ] } />
@@ -155,17 +158,25 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
155
158
  );
156
159
  }
157
160
 
158
- const MultiSizeValueControl = ( { item }: { item: Item } ) => (
159
- <PropKeyProvider bind={ item.bind }>
160
- <Grid item xs={ 6 }>
161
- <Grid container gap={ 0.75 } alignItems="center">
162
- <Grid item xs={ 12 }>
163
- <ControlFormLabel>{ item.label }</ControlFormLabel>
164
- </Grid>
165
- <Grid item xs={ 12 }>
166
- <SizeControl startIcon={ item.icon } />
161
+ const MultiSizeValueControl = ( { item }: { item: Item } ) => {
162
+ const isUsingNestedProps = isExperimentActive( 'e_v_3_30' );
163
+
164
+ return (
165
+ <PropKeyProvider bind={ item.bind }>
166
+ <Grid item xs={ 6 }>
167
+ <Grid container gap={ 0.75 } alignItems="center">
168
+ <Grid item xs={ 12 }>
169
+ { isUsingNestedProps ? (
170
+ <ControlLabel>{ item.label }</ControlLabel>
171
+ ) : (
172
+ <ControlFormLabel>{ item.label }</ControlFormLabel>
173
+ ) }
174
+ </Grid>
175
+ <Grid item xs={ 12 }>
176
+ <SizeControl startIcon={ item.icon } />
177
+ </Grid>
167
178
  </Grid>
168
179
  </Grid>
169
- </Grid>
170
- </PropKeyProvider>
171
- );
180
+ </PropKeyProvider>
181
+ );
182
+ };
@@ -43,7 +43,7 @@ type FontFamilyControlProps = {
43
43
 
44
44
  export const FontFamilyControl = createControl( ( { fontFamilies }: FontFamilyControlProps ) => {
45
45
  const [ searchValue, setSearchValue ] = useState( '' );
46
- const { value: fontFamily, setValue: setFontFamily } = useBoundProp( stringPropTypeUtil );
46
+ const { value: fontFamily, setValue: setFontFamily, disabled } = useBoundProp( stringPropTypeUtil );
47
47
 
48
48
  const popoverState = usePopupState( { variant: 'popover' } );
49
49
 
@@ -68,6 +68,7 @@ export const FontFamilyControl = createControl( ( { fontFamilies }: FontFamilyCo
68
68
  endIcon={ <ChevronDownIcon fontSize="tiny" /> }
69
69
  { ...bindTrigger( popoverState ) }
70
70
  fullWidth
71
+ disabled={ disabled }
71
72
  />
72
73
  </ControlActions>
73
74
  <Popover
@@ -15,8 +15,10 @@ export const GapControl = createControl( ( { label }: { label: string } ) => {
15
15
  value: directionValue,
16
16
  setValue: setDirectionValue,
17
17
  propType,
18
+ disabled: directionDisabled,
18
19
  } = useBoundProp( layoutDirectionPropTypeUtil );
19
- const { value: sizeValue, setValue: setSizeValue } = useBoundProp( sizePropTypeUtil );
20
+
21
+ const { value: sizeValue, setValue: setSizeValue, disabled: sizeDisabled } = useBoundProp( sizePropTypeUtil );
20
22
 
21
23
  const isLinked = ! directionValue && ! sizeValue ? true : !! sizeValue;
22
24
 
@@ -54,6 +56,7 @@ export const GapControl = createControl( ( { label }: { label: string } ) => {
54
56
  selected={ isLinked }
55
57
  sx={ { marginLeft: 'auto' } }
56
58
  onChange={ onLinkToggle }
59
+ disabled={ sizeDisabled || directionDisabled }
57
60
  >
58
61
  <LinkedIcon fontSize={ 'tiny' } />
59
62
  </ToggleButton>