@elementor/editor-controls 0.34.2 → 0.36.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,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.34.2",
4
+ "version": "0.36.0",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -43,7 +43,7 @@
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.10.1",
46
+ "@elementor/editor-ui": "0.11.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",
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { FormLabel } from '@elementor/ui';
2
+ import { FormLabel, type FormLabelProps } from '@elementor/ui';
3
3
 
4
- export const ControlFormLabel = ( { children }: { children: React.ReactNode } ) => {
5
- return <FormLabel size="tiny">{ children }</FormLabel>;
4
+ export const ControlFormLabel = ( props: FormLabelProps ) => {
5
+ return <FormLabel size="tiny" { ...props } />;
6
6
  };
@@ -7,7 +7,7 @@ import { ControlFormLabel } from './control-form-label';
7
7
 
8
8
  export const ControlLabel = ( { children }: PropsWithChildren< object > ) => {
9
9
  return (
10
- <Stack direction="row" alignItems="center" justifyItems="start" gap={ 1 }>
10
+ <Stack direction="row" alignItems="center" justifyItems="start" gap={ 0.25 }>
11
11
  <ControlFormLabel>{ children }</ControlFormLabel>
12
12
  <ControlAdornments />
13
13
  </Stack>
@@ -0,0 +1,282 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import * as React from 'react';
3
+ import { PopoverHeader } from '@elementor/editor-ui';
4
+ import { SearchIcon, TextIcon } from '@elementor/icons';
5
+ import {
6
+ Box,
7
+ Divider,
8
+ InputAdornment,
9
+ Link,
10
+ MenuList,
11
+ MenuSubheader,
12
+ Stack,
13
+ styled,
14
+ TextField,
15
+ Typography,
16
+ } from '@elementor/ui';
17
+ import { debounce } from '@elementor/utils';
18
+ import { useVirtualizer } from '@tanstack/react-virtual';
19
+ import { __ } from '@wordpress/i18n';
20
+
21
+ import { enqueueFont } from '../controls/font-family-control/enqueue-font';
22
+ import { type FontCategory } from '../controls/font-family-control/font-family-control';
23
+ import { type FontListItem, useFilteredFontFamilies } from '../hooks/use-filtered-font-families';
24
+
25
+ const SIZE = 'tiny';
26
+
27
+ type FontFamilySelectorProps = {
28
+ fontFamilies: FontCategory[];
29
+ fontFamily: string | null;
30
+ onFontFamilyChange: ( fontFamily: string ) => void;
31
+ onClose: () => void;
32
+ };
33
+
34
+ export const FontFamilySelector = ( {
35
+ fontFamilies,
36
+ fontFamily,
37
+ onFontFamilyChange,
38
+ onClose,
39
+ }: FontFamilySelectorProps ) => {
40
+ const [ searchValue, setSearchValue ] = useState( '' );
41
+
42
+ const filteredFontFamilies = useFilteredFontFamilies( fontFamilies, searchValue );
43
+
44
+ const handleSearch = ( event: React.ChangeEvent< HTMLInputElement > ) => {
45
+ setSearchValue( event.target.value );
46
+ };
47
+
48
+ const handleClose = () => {
49
+ setSearchValue( '' );
50
+ onClose();
51
+ };
52
+
53
+ return (
54
+ <Stack>
55
+ <PopoverHeader
56
+ title={ __( 'Font Family', 'elementor' ) }
57
+ onClose={ handleClose }
58
+ icon={ <TextIcon fontSize={ SIZE } /> }
59
+ />
60
+
61
+ <Box px={ 1.5 } pb={ 1 }>
62
+ <TextField
63
+ // eslint-disable-next-line jsx-a11y/no-autofocus
64
+ autoFocus
65
+ fullWidth
66
+ size={ SIZE }
67
+ value={ searchValue }
68
+ placeholder={ __( 'Search', 'elementor' ) }
69
+ onChange={ handleSearch }
70
+ InputProps={ {
71
+ startAdornment: (
72
+ <InputAdornment position="start">
73
+ <SearchIcon fontSize={ SIZE } />
74
+ </InputAdornment>
75
+ ),
76
+ } }
77
+ />
78
+ </Box>
79
+ <Divider />
80
+ { filteredFontFamilies.length > 0 ? (
81
+ <FontList
82
+ fontListItems={ filteredFontFamilies }
83
+ setFontFamily={ onFontFamilyChange }
84
+ handleClose={ handleClose }
85
+ fontFamily={ fontFamily }
86
+ />
87
+ ) : (
88
+ <Box sx={ { overflowY: 'auto', height: 260, width: 220 } }>
89
+ <Stack alignItems="center" p={ 2.5 } gap={ 1.5 } overflow={ 'hidden' }>
90
+ <TextIcon fontSize="large" />
91
+ <Box sx={ { maxWidth: 160, overflow: 'hidden' } }>
92
+ <Typography align="center" variant="subtitle2" color="text.secondary">
93
+ { __( 'Sorry, nothing matched', 'elementor' ) }
94
+ </Typography>
95
+ <Typography
96
+ variant="subtitle2"
97
+ color="text.secondary"
98
+ sx={ {
99
+ display: 'flex',
100
+ width: '100%',
101
+ justifyContent: 'center',
102
+ } }
103
+ >
104
+ <span>&ldquo;</span>
105
+ <span style={ { maxWidth: '80%', overflow: 'hidden', textOverflow: 'ellipsis' } }>
106
+ { searchValue }
107
+ </span>
108
+ <span>&rdquo;.</span>
109
+ </Typography>
110
+ </Box>
111
+ <Typography align="center" variant="caption" color="text.secondary">
112
+ { __( 'Try something else.', 'elementor' ) }
113
+ <Link
114
+ color="secondary"
115
+ variant="caption"
116
+ component="button"
117
+ onClick={ () => setSearchValue( '' ) }
118
+ >
119
+ { __( 'Clear & try again', 'elementor' ) }
120
+ </Link>
121
+ </Typography>
122
+ </Stack>
123
+ </Box>
124
+ ) }
125
+ </Stack>
126
+ );
127
+ };
128
+
129
+ type FontListProps = {
130
+ fontListItems: FontListItem[];
131
+ setFontFamily: ( fontFamily: string ) => void;
132
+ handleClose: () => void;
133
+ fontFamily: string | null;
134
+ };
135
+
136
+ const LIST_ITEM_HEIGHT = 36;
137
+ const LIST_ITEMS_BUFFER = 6;
138
+
139
+ const FontList = ( { fontListItems, setFontFamily, handleClose, fontFamily }: FontListProps ) => {
140
+ const containerRef = useRef< HTMLDivElement >( null );
141
+ const selectedItem = fontListItems.find( ( item ) => item.value === fontFamily );
142
+
143
+ const debouncedVirtualizeChange = useDebounce( ( { getVirtualIndexes }: { getVirtualIndexes: () => number[] } ) => {
144
+ getVirtualIndexes().forEach( ( index ) => {
145
+ const item = fontListItems[ index ];
146
+ if ( item && item.type === 'font' ) {
147
+ enqueueFont( item.value );
148
+ }
149
+ } );
150
+ }, 100 );
151
+
152
+ const virtualizer = useVirtualizer( {
153
+ count: fontListItems.length,
154
+ getScrollElement: () => containerRef.current,
155
+ estimateSize: () => LIST_ITEM_HEIGHT,
156
+ overscan: LIST_ITEMS_BUFFER,
157
+ onChange: debouncedVirtualizeChange,
158
+ } );
159
+
160
+ useEffect(
161
+ () => {
162
+ virtualizer.scrollToIndex( fontListItems.findIndex( ( item ) => item.value === fontFamily ) );
163
+ },
164
+ // eslint-disable-next-line react-compiler/react-compiler
165
+ // eslint-disable-next-line react-hooks/exhaustive-deps
166
+ [ fontFamily ]
167
+ );
168
+
169
+ return (
170
+ <Box
171
+ ref={ containerRef }
172
+ sx={ {
173
+ overflowY: 'auto',
174
+ height: 260,
175
+ width: 220,
176
+ } }
177
+ >
178
+ <StyledMenuList
179
+ role="listbox"
180
+ style={ {
181
+ height: `${ virtualizer.getTotalSize() }px`,
182
+ } }
183
+ data-testid="font-list"
184
+ >
185
+ { virtualizer.getVirtualItems().map( ( virtualRow ) => {
186
+ const item = fontListItems[ virtualRow.index ];
187
+ const isLast = virtualRow.index === fontListItems.length - 1;
188
+ // Ignore the first item, which is a category, and use the second item instead.
189
+ const isFirst = virtualRow.index === 1;
190
+ const isSelected = selectedItem?.value === item.value;
191
+
192
+ // If no item is selected, the first item should be focused.
193
+ const tabIndexFallback = ! selectedItem ? 0 : -1;
194
+
195
+ if ( item.type === 'category' ) {
196
+ return (
197
+ <MenuSubheader
198
+ key={ virtualRow.key }
199
+ style={ {
200
+ transform: `translateY(${ virtualRow.start }px)`,
201
+ } }
202
+ >
203
+ { item.value }
204
+ </MenuSubheader>
205
+ );
206
+ }
207
+
208
+ return (
209
+ <li
210
+ key={ virtualRow.key }
211
+ role="option"
212
+ aria-selected={ isSelected }
213
+ onClick={ () => {
214
+ setFontFamily( item.value );
215
+ handleClose();
216
+ } }
217
+ onKeyDown={ ( event ) => {
218
+ if ( event.key === 'Enter' ) {
219
+ setFontFamily( item.value );
220
+ handleClose();
221
+ }
222
+
223
+ if ( event.key === 'ArrowDown' && isLast ) {
224
+ event.preventDefault();
225
+ event.stopPropagation();
226
+ }
227
+
228
+ if ( event.key === 'ArrowUp' && isFirst ) {
229
+ event.preventDefault();
230
+ event.stopPropagation();
231
+ }
232
+ } }
233
+ tabIndex={ isSelected ? 0 : tabIndexFallback }
234
+ style={ {
235
+ transform: `translateY(${ virtualRow.start }px)`,
236
+ fontFamily: item.value,
237
+ } }
238
+ >
239
+ { item.value }
240
+ </li>
241
+ );
242
+ } ) }
243
+ </StyledMenuList>
244
+ </Box>
245
+ );
246
+ };
247
+
248
+ const StyledMenuList = styled( MenuList )( ( { theme } ) => ( {
249
+ '& > li': {
250
+ height: LIST_ITEM_HEIGHT,
251
+ position: 'absolute',
252
+ top: 0,
253
+ left: 0,
254
+ width: '100%',
255
+ display: 'flex',
256
+ alignItems: 'center',
257
+ },
258
+ '& > [role="option"]': {
259
+ ...theme.typography.caption,
260
+ lineHeight: 'inherit',
261
+ padding: theme.spacing( 0.75, 2, 0.75, 4 ),
262
+ '&:hover, &:focus': {
263
+ backgroundColor: theme.palette.action.hover,
264
+ },
265
+ '&[aria-selected="true"]': {
266
+ backgroundColor: theme.palette.action.selected,
267
+ },
268
+ cursor: 'pointer',
269
+ textOverflow: 'ellipsis',
270
+ },
271
+ width: '100%',
272
+ position: 'relative',
273
+ } ) );
274
+
275
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
276
+ const useDebounce = < TArgs extends any[] >( fn: ( ...args: TArgs ) => void, delay: number ) => {
277
+ const [ debouncedFn ] = useState( () => debounce( fn, delay ) );
278
+
279
+ useEffect( () => () => debouncedFn.cancel(), [ debouncedFn ] );
280
+
281
+ return debouncedFn;
282
+ };
@@ -143,8 +143,6 @@ export const Repeater = < T, >( {
143
143
  } );
144
144
  };
145
145
 
146
- const ItemWrapper = disabled ? React.Fragment : SortableItem;
147
-
148
146
  return (
149
147
  <SectionContent>
150
148
  <Stack
@@ -178,7 +176,7 @@ export const Repeater = < T, >( {
178
176
  }
179
177
 
180
178
  return (
181
- <ItemWrapper id={ key } key={ `sortable-${ key }` }>
179
+ <SortableItem id={ key } key={ `sortable-${ key }` } disabled={ disabled }>
182
180
  <RepeaterItem
183
181
  disabled={ disabled }
184
182
  propDisabled={ value?.disabled }
@@ -202,7 +200,7 @@ export const Repeater = < T, >( {
202
200
  <itemSettings.Content { ...props } value={ value } bind={ String( index ) } />
203
201
  ) }
204
202
  </RepeaterItem>
205
- </ItemWrapper>
203
+ </SortableItem>
206
204
  );
207
205
  } ) }
208
206
  </SortableProvider>
@@ -23,12 +23,14 @@ export const SortableProvider = < T extends number >( props: UnstableSortablePro
23
23
  type SortableItemProps = {
24
24
  id: UnstableSortableItemProps[ 'id' ];
25
25
  children: React.ReactNode;
26
+ disabled?: boolean;
26
27
  };
27
28
 
28
- export const SortableItem = ( { id, children }: SortableItemProps ): React.ReactNode => {
29
+ export const SortableItem = ( { id, children, disabled }: SortableItemProps ): React.ReactNode => {
29
30
  return (
30
31
  <UnstableSortableItem
31
32
  id={ id }
33
+ disabled={ disabled }
32
34
  render={ ( {
33
35
  itemProps,
34
36
  triggerProps,
@@ -39,7 +41,7 @@ export const SortableItem = ( { id, children }: SortableItemProps ): React.React
39
41
  }: UnstableSortableItemRenderProps ) => {
40
42
  return (
41
43
  <StyledListItem { ...itemProps } style={ itemStyle }>
42
- <SortableTrigger { ...triggerProps } style={ triggerStyle } />
44
+ { ! disabled && <SortableTrigger { ...triggerProps } style={ triggerStyle } /> }
43
45
  { children }
44
46
  { showDropIndication && <StyledDivider style={ dropIndicationStyle } /> }
45
47
  </StyledListItem>
@@ -8,6 +8,7 @@ import { __ } from '@wordpress/i18n';
8
8
 
9
9
  import { useBoundProp } from '../bound-prop-context';
10
10
  import { ControlLabel } from '../components/control-label';
11
+ import ControlActions from '../control-actions/control-actions';
11
12
  import { createControl } from '../create-control';
12
13
 
13
14
  const RATIO_OPTIONS = [
@@ -69,61 +70,63 @@ export const AspectRatioControl = createControl( ( { label }: { label: string }
69
70
  };
70
71
 
71
72
  return (
72
- <Stack direction="column" pt={ 2 } gap={ 2 }>
73
- <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
74
- <Grid item xs={ 6 }>
75
- <ControlLabel>{ label }</ControlLabel>
76
- </Grid>
77
- <Grid item xs={ 6 }>
78
- <Select
79
- size="tiny"
80
- displayEmpty
81
- sx={ { overflow: 'hidden' } }
82
- disabled={ disabled }
83
- value={ selectedValue }
84
- onChange={ handleSelectChange }
85
- fullWidth
86
- >
87
- { [ ...RATIO_OPTIONS, { label: __( 'Custom', 'elementor' ), value: CUSTOM_RATIO } ].map(
88
- ( { label: optionLabel, ...props } ) => (
89
- <MenuListItem key={ props.value } { ...props } value={ props.value ?? '' }>
90
- { optionLabel }
91
- </MenuListItem>
92
- )
93
- ) }
94
- </Select>
95
- </Grid>
96
- </Grid>
97
- { isCustom && (
73
+ <ControlActions>
74
+ <Stack direction="column" pt={ 2 } gap={ 2 }>
98
75
  <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
99
76
  <Grid item xs={ 6 }>
100
- <TextField
101
- size="tiny"
102
- type="number"
103
- fullWidth
104
- disabled={ disabled }
105
- value={ customWidth }
106
- onChange={ handleCustomWidthChange }
107
- InputProps={ {
108
- startAdornment: <ArrowsMoveHorizontalIcon fontSize="tiny" />,
109
- } }
110
- />
77
+ <ControlLabel>{ label }</ControlLabel>
111
78
  </Grid>
112
79
  <Grid item xs={ 6 }>
113
- <TextField
80
+ <Select
114
81
  size="tiny"
115
- type="number"
116
- fullWidth
82
+ displayEmpty
83
+ sx={ { overflow: 'hidden' } }
117
84
  disabled={ disabled }
118
- value={ customHeight }
119
- onChange={ handleCustomHeightChange }
120
- InputProps={ {
121
- startAdornment: <ArrowsMoveVerticalIcon fontSize="tiny" />,
122
- } }
123
- />
85
+ value={ selectedValue }
86
+ onChange={ handleSelectChange }
87
+ fullWidth
88
+ >
89
+ { [ ...RATIO_OPTIONS, { label: __( 'Custom', 'elementor' ), value: CUSTOM_RATIO } ].map(
90
+ ( { label: optionLabel, ...props } ) => (
91
+ <MenuListItem key={ props.value } { ...props } value={ props.value ?? '' }>
92
+ { optionLabel }
93
+ </MenuListItem>
94
+ )
95
+ ) }
96
+ </Select>
124
97
  </Grid>
125
98
  </Grid>
126
- ) }
127
- </Stack>
99
+ { isCustom && (
100
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
101
+ <Grid item xs={ 6 }>
102
+ <TextField
103
+ size="tiny"
104
+ type="number"
105
+ fullWidth
106
+ disabled={ disabled }
107
+ value={ customWidth }
108
+ onChange={ handleCustomWidthChange }
109
+ InputProps={ {
110
+ startAdornment: <ArrowsMoveHorizontalIcon fontSize="tiny" />,
111
+ } }
112
+ />
113
+ </Grid>
114
+ <Grid item xs={ 6 }>
115
+ <TextField
116
+ size="tiny"
117
+ type="number"
118
+ fullWidth
119
+ disabled={ disabled }
120
+ value={ customHeight }
121
+ onChange={ handleCustomHeightChange }
122
+ InputProps={ {
123
+ startAdornment: <ArrowsMoveVerticalIcon fontSize="tiny" />,
124
+ } }
125
+ />
126
+ </Grid>
127
+ </Grid>
128
+ ) }
129
+ </Stack>
130
+ </ControlActions>
128
131
  );
129
132
  } );
@@ -60,10 +60,11 @@ export const BackgroundImageOverlayPosition = () => {
60
60
  </Grid>
61
61
  <Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end', overflow: 'hidden' } }>
62
62
  <Select
63
+ fullWidth
63
64
  size="tiny"
64
- value={ ( backgroundImageOffsetContext.value ? 'custom' : stringPropContext.value ) ?? '' }
65
65
  onChange={ handlePositionChange }
66
- fullWidth
66
+ disabled={ stringPropContext.disabled }
67
+ value={ ( backgroundImageOffsetContext.value ? 'custom' : stringPropContext.value ) ?? '' }
67
68
  >
68
69
  { backgroundPositionOptions.map( ( { label, value } ) => (
69
70
  <MenuListItem key={ value } value={ value ?? '' }>
@@ -74,10 +74,11 @@ export const BackgroundImageOverlaySize = () => {
74
74
  <ControlToggleButtonGroup
75
75
  exclusive
76
76
  items={ sizeControlOptions }
77
+ onChange={ handleSizeChange }
78
+ disabled={ stringPropContext.disabled }
77
79
  value={
78
80
  ( backgroundImageScaleContext.value ? 'custom' : stringPropContext.value ) as Sizes
79
81
  }
80
- onChange={ handleSizeChange }
81
82
  />
82
83
  </Grid>
83
84
  </PopoverGridContainer>
@@ -74,7 +74,7 @@ export const BackgroundOverlayRepeaterControl = createControl( () => {
74
74
  const { propType, value: overlayValues, setValue, disabled } = useBoundProp( backgroundOverlayPropTypeUtil );
75
75
 
76
76
  return (
77
- <PropProvider propType={ propType } value={ overlayValues } setValue={ setValue }>
77
+ <PropProvider propType={ propType } value={ overlayValues } setValue={ setValue } disabled={ disabled }>
78
78
  <Repeater
79
79
  openOnAdd
80
80
  disabled={ disabled }
@@ -16,7 +16,7 @@ export const BoxShadowRepeaterControl = createControl( () => {
16
16
  const { propType, value, setValue, disabled } = useBoundProp( boxShadowPropTypeUtil );
17
17
 
18
18
  return (
19
- <PropProvider propType={ propType } value={ value } setValue={ setValue }>
19
+ <PropProvider propType={ propType } value={ value } setValue={ setValue } disabled={ disabled }>
20
20
  <Repeater
21
21
  openOnAdd
22
22
  disabled={ disabled }
@@ -47,10 +47,10 @@ const ItemContent = ( { anchorEl, bind }: { anchorEl: HTMLElement | null; bind:
47
47
  };
48
48
 
49
49
  const Content = ( { anchorEl }: { anchorEl: HTMLElement | null } ) => {
50
- const { propType, value, setValue } = useBoundProp( shadowPropTypeUtil );
50
+ const context = useBoundProp( shadowPropTypeUtil );
51
51
 
52
52
  return (
53
- <PropProvider propType={ propType } value={ value } setValue={ setValue }>
53
+ <PropProvider { ...context }>
54
54
  <PopoverContent p={ 1.5 }>
55
55
  <PopoverGridContainer>
56
56
  <Control bind="color" label={ __( 'Color', 'elementor' ) }>
@@ -62,7 +62,7 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
62
62
  disabled: multiSizeDisabled,
63
63
  } = useBoundProp( multiSizePropTypeUtil );
64
64
 
65
- const { value: sizeValue, setValue: setSizeValue, disabled: sizeDisabled } = useBoundProp( sizePropTypeUtil );
65
+ const { value: sizeValue, setValue: setSizeValue } = useBoundProp( sizePropTypeUtil );
66
66
 
67
67
  const splitEqualValue = () => {
68
68
  if ( ! sizeValue ) {
@@ -98,13 +98,19 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
98
98
  return splitEqualValue() ?? null;
99
99
  };
100
100
 
101
+ const isShowingGeneralIndicator = ! isExperimentActive( 'e_v_3_30' ) || ! popupState.isOpen;
102
+
101
103
  const isMixed = !! multiSizeValue;
102
104
 
103
105
  return (
104
106
  <>
105
107
  <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap" ref={ controlRef }>
106
108
  <Grid item xs={ 6 }>
107
- <ControlLabel>{ label }</ControlLabel>
109
+ { ! isShowingGeneralIndicator ? (
110
+ <ControlFormLabel>{ label }</ControlFormLabel>
111
+ ) : (
112
+ <ControlLabel>{ label }</ControlLabel>
113
+ ) }
108
114
  </Grid>
109
115
  <Grid item xs={ 6 }>
110
116
  <Stack direction="row" alignItems="center" gap={ 1 }>
@@ -117,7 +123,6 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
117
123
  { ...bindToggle( popupState ) }
118
124
  selected={ popupState.isOpen }
119
125
  aria-label={ tooltipLabel }
120
- disabled={ multiSizeDisabled || sizeDisabled }
121
126
  >
122
127
  { icon }
123
128
  </ToggleButton>
@@ -141,7 +146,12 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
141
146
  paper: { sx: { mt: 0.5, width: controlRef.current?.getBoundingClientRect().width } },
142
147
  } }
143
148
  >
144
- <PropProvider propType={ multiSizePropType } value={ getMultiSizeValues() } setValue={ setNestedProp }>
149
+ <PropProvider
150
+ propType={ multiSizePropType }
151
+ value={ getMultiSizeValues() }
152
+ setValue={ setNestedProp }
153
+ disabled={ multiSizeDisabled }
154
+ >
145
155
  <PopoverContent p={ 1.5 } pt={ 2.5 } pb={ 3 }>
146
156
  <PopoverGridContainer>
147
157
  <MultiSizeValueControl item={ items[ 0 ] } />