@elementor/editor-controls 0.4.0 → 0.5.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/CHANGELOG.md +20 -0
- package/dist/index.d.mts +35 -18
- package/dist/index.d.ts +35 -18
- package/dist/index.js +363 -575
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +347 -565
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
- package/src/bound-prop-context/errors.ts +16 -0
- package/src/bound-prop-context/index.ts +3 -0
- package/src/bound-prop-context/prop-context.tsx +48 -0
- package/src/bound-prop-context/prop-key-context.tsx +103 -0
- package/src/bound-prop-context/use-bound-prop.ts +69 -0
- package/src/components/repeater.tsx +3 -13
- package/src/controls/background-control/background-control.tsx +19 -42
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +32 -48
- package/src/controls/box-shadow-repeater-control.tsx +75 -139
- package/src/controls/color-control.tsx +16 -20
- package/src/controls/equal-unequal-sizes-control.tsx +65 -139
- package/src/controls/gap-control.tsx +20 -25
- package/src/controls/image-control.tsx +19 -34
- package/src/controls/image-media-control.tsx +1 -1
- package/src/controls/link-control.tsx +57 -58
- package/src/controls/linked-dimensions-control.tsx +25 -54
- package/src/controls/number-control.tsx +1 -1
- package/src/controls/stroke-control.tsx +18 -48
- package/src/controls/url-control.tsx +4 -14
- package/src/index.ts +3 -2
- package/src/bound-prop-context.tsx +0 -67
|
@@ -1,41 +1,32 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
boxShadowPropTypeUtil,
|
|
4
|
-
type BoxShadowPropValue,
|
|
5
|
-
type PropValue,
|
|
6
|
-
type ShadowPropValue,
|
|
7
|
-
} from '@elementor/editor-props';
|
|
2
|
+
import { boxShadowPropTypeUtil, type PropKey, shadowPropTypeUtil, type ShadowPropValue } from '@elementor/editor-props';
|
|
8
3
|
import { Grid, Stack, Typography, UnstableColorIndicator } from '@elementor/ui';
|
|
9
4
|
import { __ } from '@wordpress/i18n';
|
|
10
5
|
|
|
11
|
-
import {
|
|
6
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
12
7
|
import { Repeater } from '../components/repeater';
|
|
13
8
|
import { createControl } from '../create-control';
|
|
14
9
|
import { ColorControl } from './color-control';
|
|
15
10
|
import { SelectControl } from './select-control';
|
|
16
11
|
import { SizeControl } from './size-control';
|
|
17
12
|
|
|
18
|
-
type SetContextValue = ( v: PropValue ) => void;
|
|
19
|
-
|
|
20
13
|
export const BoxShadowRepeaterControl = createControl( () => {
|
|
21
|
-
const { value
|
|
22
|
-
|
|
23
|
-
const setBoxShadow = ( newValue: BoxShadowPropValue[ 'value' ] ) => {
|
|
24
|
-
setValue( newValue );
|
|
25
|
-
};
|
|
14
|
+
const { propType, value, setValue } = useBoundProp( boxShadowPropTypeUtil );
|
|
26
15
|
|
|
27
16
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
17
|
+
<PropProvider propType={ propType } value={ value } setValue={ setValue }>
|
|
18
|
+
<Repeater
|
|
19
|
+
values={ value ?? [] }
|
|
20
|
+
setValues={ setValue }
|
|
21
|
+
label={ __( 'Box shadow', 'elementor' ) }
|
|
22
|
+
itemSettings={ {
|
|
23
|
+
Icon: ItemIcon,
|
|
24
|
+
Label: ItemLabel,
|
|
25
|
+
Content: ItemContent,
|
|
26
|
+
initialValues: initialShadow,
|
|
27
|
+
} }
|
|
28
|
+
/>
|
|
29
|
+
</PropProvider>
|
|
39
30
|
);
|
|
40
31
|
} );
|
|
41
32
|
|
|
@@ -43,125 +34,70 @@ const ItemIcon = ( { value }: { value: ShadowPropValue } ) => (
|
|
|
43
34
|
<UnstableColorIndicator size="inherit" component="span" value={ value.value.color.value } />
|
|
44
35
|
);
|
|
45
36
|
|
|
46
|
-
const ItemContent = ( {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
} ) => {
|
|
55
|
-
const
|
|
56
|
-
setValue( {
|
|
57
|
-
$$type: 'shadow',
|
|
58
|
-
value: newValue,
|
|
59
|
-
} );
|
|
60
|
-
};
|
|
37
|
+
const ItemContent = ( { anchorEl, bind }: { anchorEl: HTMLElement | null; bind: PropKey } ) => {
|
|
38
|
+
return (
|
|
39
|
+
<PropKeyProvider bind={ bind }>
|
|
40
|
+
<Content anchorEl={ anchorEl } />
|
|
41
|
+
</PropKeyProvider>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const Content = ( { anchorEl }: { anchorEl: HTMLElement | null } ) => {
|
|
46
|
+
const { propType, value, setValue } = useBoundProp( shadowPropTypeUtil );
|
|
61
47
|
|
|
62
48
|
return (
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
<
|
|
66
|
-
bind="color"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
horizontal: 'right',
|
|
80
|
-
},
|
|
81
|
-
transformOrigin: {
|
|
82
|
-
vertical: 'top',
|
|
83
|
-
horizontal: -10,
|
|
49
|
+
<PropProvider propType={ propType } value={ value } setValue={ setValue }>
|
|
50
|
+
<Stack gap={ 1.5 }>
|
|
51
|
+
<Grid container gap={ 2 } flexWrap="nowrap">
|
|
52
|
+
<Control bind="color" label={ __( 'Color', 'elementor' ) }>
|
|
53
|
+
<ColorControl
|
|
54
|
+
slotProps={ {
|
|
55
|
+
colorPicker: {
|
|
56
|
+
anchorEl,
|
|
57
|
+
anchorOrigin: {
|
|
58
|
+
vertical: 'top',
|
|
59
|
+
horizontal: 'right',
|
|
60
|
+
},
|
|
61
|
+
transformOrigin: {
|
|
62
|
+
vertical: 'top',
|
|
63
|
+
horizontal: -10,
|
|
64
|
+
},
|
|
84
65
|
},
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
</Control>
|
|
116
|
-
<Control
|
|
117
|
-
bind="vOffset"
|
|
118
|
-
label={ __( 'Vertical', 'elementor' ) }
|
|
119
|
-
value={ value.value.vOffset }
|
|
120
|
-
setValue={ ( v: ShadowPropValue[ 'value' ][ 'vOffset' ] ) =>
|
|
121
|
-
setShadow( { ...value.value, vOffset: v } )
|
|
122
|
-
}
|
|
123
|
-
>
|
|
124
|
-
<SizeControl />
|
|
125
|
-
</Control>
|
|
126
|
-
</Grid>
|
|
127
|
-
<Grid container gap={ 2 } flexWrap="nowrap">
|
|
128
|
-
<Control
|
|
129
|
-
bind="blur"
|
|
130
|
-
value={ value.value.blur }
|
|
131
|
-
label={ __( 'Blur', 'elementor' ) }
|
|
132
|
-
setValue={ ( v: ShadowPropValue[ 'value' ][ 'blur' ] ) => setShadow( { ...value.value, blur: v } ) }
|
|
133
|
-
>
|
|
134
|
-
<SizeControl />
|
|
135
|
-
</Control>
|
|
136
|
-
<Control
|
|
137
|
-
bind="spread"
|
|
138
|
-
label={ __( 'Spread', 'elementor' ) }
|
|
139
|
-
value={ value.value.spread }
|
|
140
|
-
setValue={ ( v: ShadowPropValue[ 'value' ][ 'spread' ] ) =>
|
|
141
|
-
setShadow( { ...value.value, spread: v } )
|
|
142
|
-
}
|
|
143
|
-
>
|
|
144
|
-
<SizeControl />
|
|
145
|
-
</Control>
|
|
146
|
-
</Grid>
|
|
147
|
-
</Stack>
|
|
66
|
+
} }
|
|
67
|
+
/>
|
|
68
|
+
</Control>
|
|
69
|
+
<Control bind="position" label={ __( 'Position', 'elementor' ) }>
|
|
70
|
+
<SelectControl
|
|
71
|
+
options={ [
|
|
72
|
+
{ label: __( 'Inset', 'elementor' ), value: 'inset' },
|
|
73
|
+
{ label: __( 'Outset', 'elementor' ), value: '' },
|
|
74
|
+
] }
|
|
75
|
+
/>
|
|
76
|
+
</Control>
|
|
77
|
+
</Grid>
|
|
78
|
+
<Grid container gap={ 2 } flexWrap="nowrap">
|
|
79
|
+
<Control bind="hOffset" label={ __( 'Horizontal', 'elementor' ) }>
|
|
80
|
+
<SizeControl />
|
|
81
|
+
</Control>
|
|
82
|
+
<Control bind="vOffset" label={ __( 'Vertical', 'elementor' ) }>
|
|
83
|
+
<SizeControl />
|
|
84
|
+
</Control>
|
|
85
|
+
</Grid>
|
|
86
|
+
<Grid container gap={ 2 } flexWrap="nowrap">
|
|
87
|
+
<Control bind="blur" label={ __( 'Blur', 'elementor' ) }>
|
|
88
|
+
<SizeControl />
|
|
89
|
+
</Control>
|
|
90
|
+
<Control bind="spread" label={ __( 'Spread', 'elementor' ) }>
|
|
91
|
+
<SizeControl />
|
|
92
|
+
</Control>
|
|
93
|
+
</Grid>
|
|
94
|
+
</Stack>
|
|
95
|
+
</PropProvider>
|
|
148
96
|
);
|
|
149
97
|
};
|
|
150
98
|
|
|
151
|
-
const Control =
|
|
152
|
-
|
|
153
|
-
setValue,
|
|
154
|
-
label,
|
|
155
|
-
bind,
|
|
156
|
-
children,
|
|
157
|
-
}: {
|
|
158
|
-
value: T;
|
|
159
|
-
bind: string;
|
|
160
|
-
label: string;
|
|
161
|
-
children: React.ReactNode;
|
|
162
|
-
setValue: ( v: T ) => void;
|
|
163
|
-
} ) => (
|
|
164
|
-
<BoundPropProvider value={ value } setValue={ setValue as SetContextValue } bind={ bind }>
|
|
99
|
+
const Control = ( { label, bind, children }: { bind: string; label: string; children: React.ReactNode } ) => (
|
|
100
|
+
<PropKeyProvider bind={ bind }>
|
|
165
101
|
<Grid item xs={ 6 }>
|
|
166
102
|
<Grid container gap={ 1 } alignItems="center">
|
|
167
103
|
<Grid item xs={ 12 }>
|
|
@@ -174,7 +110,7 @@ const Control = < T extends PropValue >( {
|
|
|
174
110
|
</Grid>
|
|
175
111
|
</Grid>
|
|
176
112
|
</Grid>
|
|
177
|
-
</
|
|
113
|
+
</PropKeyProvider>
|
|
178
114
|
);
|
|
179
115
|
|
|
180
116
|
const ItemLabel = ( { value }: { value: ShadowPropValue } ) => {
|
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { colorPropTypeUtil } from '@elementor/editor-props';
|
|
2
|
+
import { colorPropTypeUtil, type PropTypeUtil } from '@elementor/editor-props';
|
|
3
3
|
import { UnstableColorField, type UnstableColorFieldProps } from '@elementor/ui';
|
|
4
4
|
|
|
5
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
6
6
|
import ControlActions from '../control-actions/control-actions';
|
|
7
7
|
import { createControl } from '../create-control';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
type Props = Partial< Omit< UnstableColorFieldProps, 'value' | 'onChange' > > & {
|
|
10
|
+
propTypeUtil?: PropTypeUtil< string, string >;
|
|
11
|
+
};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
13
|
+
export const ColorControl = createControl( ( { propTypeUtil = colorPropTypeUtil, ...props }: Props ) => {
|
|
14
|
+
const { value, setValue } = useBoundProp( propTypeUtil );
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
);
|
|
16
|
+
const handleChange = ( selectedColor: string ) => {
|
|
17
|
+
setValue( selectedColor );
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ControlActions>
|
|
22
|
+
<UnstableColorField size="tiny" { ...props } value={ value ?? '' } onChange={ handleChange } fullWidth />
|
|
23
|
+
</ControlActions>
|
|
24
|
+
);
|
|
25
|
+
} );
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type ReactNode, useId, useRef } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
type PropKey,
|
|
5
|
-
type PropTypeUtil,
|
|
6
|
-
type PropValue,
|
|
7
|
-
sizePropTypeUtil,
|
|
8
|
-
type SizePropValue,
|
|
9
|
-
} from '@elementor/editor-props';
|
|
3
|
+
import { type PropKey, type PropTypeUtil, sizePropTypeUtil, type SizePropValue } from '@elementor/editor-props';
|
|
10
4
|
import { bindPopover, bindToggle, Grid, Popover, Stack, ToggleButton, usePopupState } from '@elementor/ui';
|
|
11
5
|
import { __ } from '@wordpress/i18n';
|
|
12
6
|
|
|
13
|
-
import {
|
|
7
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
14
8
|
import { ControlLabel } from '../components/control-label';
|
|
15
9
|
import { SizeControl } from './size-control';
|
|
16
10
|
|
|
17
|
-
type SetContextValue = ( v: PropValue ) => void;
|
|
18
|
-
|
|
19
11
|
type MultiSizePropValue = Record< PropKey, SizePropValue >;
|
|
20
12
|
|
|
21
13
|
type Item = {
|
|
@@ -33,7 +25,9 @@ type Props< TMultiPropType extends string, TPropValue extends MultiSizePropValue
|
|
|
33
25
|
multiSizePropTypeUtil: PropTypeUtil< TMultiPropType, TPropValue >;
|
|
34
26
|
};
|
|
35
27
|
|
|
36
|
-
const isEqualSizes = (
|
|
28
|
+
const isEqualSizes = ( propValue: MultiSizePropValue, items: EqualUnequalItems ) => {
|
|
29
|
+
const values = Object.values( propValue );
|
|
30
|
+
|
|
37
31
|
if ( values.length !== items.length ) {
|
|
38
32
|
return false;
|
|
39
33
|
}
|
|
@@ -41,7 +35,7 @@ const isEqualSizes = ( values: SizePropValue[], items: EqualUnequalItems ) => {
|
|
|
41
35
|
const [ firstValue, ...restValues ] = values;
|
|
42
36
|
|
|
43
37
|
return restValues.every(
|
|
44
|
-
( value ) => value
|
|
38
|
+
( value ) => value?.value?.size === firstValue?.value?.size && value?.value?.unit === firstValue?.value?.unit
|
|
45
39
|
);
|
|
46
40
|
};
|
|
47
41
|
|
|
@@ -55,32 +49,48 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
|
|
|
55
49
|
const controlRef = useRef< HTMLElement >( null );
|
|
56
50
|
const popupState = usePopupState( { variant: 'popover', popupId } );
|
|
57
51
|
|
|
52
|
+
const {
|
|
53
|
+
propType: multiSizePropType,
|
|
54
|
+
value: multiSizeValue,
|
|
55
|
+
setValue: setMultiSizeValue,
|
|
56
|
+
} = useBoundProp( multiSizePropTypeUtil );
|
|
57
|
+
|
|
58
58
|
const { value: sizeValue, setValue: setSizeValue } = useBoundProp( sizePropTypeUtil );
|
|
59
|
-
const { value: multiSizeValue, setValue: setMultiSizeValue } = useBoundProp( multiSizePropTypeUtil );
|
|
60
59
|
|
|
61
60
|
const splitEqualValue = () => {
|
|
62
61
|
if ( ! sizeValue ) {
|
|
63
|
-
return
|
|
62
|
+
return null;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
return items.reduce
|
|
65
|
+
return items.reduce< TPropValue >(
|
|
66
|
+
( acc, { bind } ) => ( { ...acc, [ bind ]: sizePropTypeUtil.create( sizeValue ) } ),
|
|
67
|
+
{} as TPropValue
|
|
68
|
+
);
|
|
67
69
|
};
|
|
68
70
|
|
|
69
|
-
const setNestedProp = (
|
|
71
|
+
const setNestedProp = ( newValue: TPropValue ) => {
|
|
70
72
|
const newMappedValues = {
|
|
71
73
|
...( multiSizeValue ?? splitEqualValue() ),
|
|
72
|
-
|
|
74
|
+
...newValue,
|
|
73
75
|
};
|
|
74
76
|
|
|
75
|
-
const isEqual = isEqualSizes(
|
|
77
|
+
const isEqual = isEqualSizes( newMappedValues, items );
|
|
76
78
|
|
|
77
79
|
if ( isEqual ) {
|
|
78
|
-
return setSizeValue(
|
|
80
|
+
return setSizeValue( Object.values( newMappedValues )[ 0 ].value );
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
setMultiSizeValue( newMappedValues );
|
|
82
84
|
};
|
|
83
85
|
|
|
86
|
+
const getMultiSizeValues = () => {
|
|
87
|
+
if ( multiSizeValue ) {
|
|
88
|
+
return multiSizeValue;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return splitEqualValue() ?? null;
|
|
92
|
+
};
|
|
93
|
+
|
|
84
94
|
return (
|
|
85
95
|
<>
|
|
86
96
|
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap" ref={ controlRef }>
|
|
@@ -88,23 +98,18 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
|
|
|
88
98
|
<ControlLabel>{ label }</ControlLabel>
|
|
89
99
|
</Grid>
|
|
90
100
|
<Grid item xs={ 6 }>
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
>
|
|
104
|
-
{ icon }
|
|
105
|
-
</ToggleButton>
|
|
106
|
-
}
|
|
107
|
-
/>
|
|
101
|
+
<Stack direction="row" alignItems="center" gap={ 1 }>
|
|
102
|
+
<SizeControl placeholder={ __( 'MIXED', 'elementor' ) } />
|
|
103
|
+
<ToggleButton
|
|
104
|
+
size={ 'tiny' }
|
|
105
|
+
value={ 'check' }
|
|
106
|
+
sx={ { marginLeft: 'auto' } }
|
|
107
|
+
{ ...bindToggle( popupState ) }
|
|
108
|
+
selected={ popupState.isOpen }
|
|
109
|
+
>
|
|
110
|
+
{ icon }
|
|
111
|
+
</ToggleButton>
|
|
112
|
+
</Stack>
|
|
108
113
|
</Grid>
|
|
109
114
|
</Grid>
|
|
110
115
|
<Popover
|
|
@@ -123,113 +128,34 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
|
|
|
123
128
|
paper: { sx: { mt: 0.5, p: 2, pt: 1, width: controlRef.current?.getBoundingClientRect().width } },
|
|
124
129
|
} }
|
|
125
130
|
>
|
|
126
|
-
<
|
|
127
|
-
<
|
|
128
|
-
<
|
|
129
|
-
item={ items[ 0 ] }
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
splitEqualValue={ splitEqualValue }
|
|
139
|
-
/>
|
|
140
|
-
</Grid>
|
|
141
|
-
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
142
|
-
<MultiSizeValueControl
|
|
143
|
-
item={ items[ 3 ] }
|
|
144
|
-
value={ multiSizeValue }
|
|
145
|
-
setNestedProp={ setNestedProp }
|
|
146
|
-
splitEqualValue={ splitEqualValue }
|
|
147
|
-
/>
|
|
148
|
-
<MultiSizeValueControl
|
|
149
|
-
item={ items[ 2 ] }
|
|
150
|
-
value={ multiSizeValue }
|
|
151
|
-
setNestedProp={ setNestedProp }
|
|
152
|
-
splitEqualValue={ splitEqualValue }
|
|
153
|
-
/>
|
|
154
|
-
</Grid>
|
|
155
|
-
</Stack>
|
|
131
|
+
<PropProvider propType={ multiSizePropType } value={ getMultiSizeValues() } setValue={ setNestedProp }>
|
|
132
|
+
<Stack gap={ 1.5 }>
|
|
133
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
134
|
+
<MultiSizeValueControl item={ items[ 0 ] } />
|
|
135
|
+
<MultiSizeValueControl item={ items[ 1 ] } />
|
|
136
|
+
</Grid>
|
|
137
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
138
|
+
<MultiSizeValueControl item={ items[ 3 ] } />
|
|
139
|
+
<MultiSizeValueControl item={ items[ 2 ] } />
|
|
140
|
+
</Grid>
|
|
141
|
+
</Stack>
|
|
142
|
+
</PropProvider>
|
|
156
143
|
</Popover>
|
|
157
144
|
</>
|
|
158
145
|
);
|
|
159
146
|
}
|
|
160
147
|
|
|
161
|
-
const MultiSizeValueControl =
|
|
162
|
-
item
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
splitEqualValue: () => TPropValue;
|
|
171
|
-
} ) => {
|
|
172
|
-
const handleChange = ( val: SizePropValue ) => setNestedProp( item, val );
|
|
173
|
-
|
|
174
|
-
const getMultiSizeValues = () => {
|
|
175
|
-
if ( value ) {
|
|
176
|
-
return value?.[ item.bind ] ?? null;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return splitEqualValue()?.[ item.bind ] ?? null;
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
return (
|
|
183
|
-
<BoundPropProvider bind={ '' } setValue={ handleChange as SetContextValue } value={ getMultiSizeValues() }>
|
|
184
|
-
<Grid item xs={ 6 }>
|
|
185
|
-
<Grid container gap={ 1 } alignItems="center">
|
|
186
|
-
<Grid item xs={ 12 }>
|
|
187
|
-
<ControlLabel>{ item.label }</ControlLabel>
|
|
188
|
-
</Grid>
|
|
189
|
-
<Grid item xs={ 12 }>
|
|
190
|
-
<SizeControl startIcon={ item.icon } />
|
|
191
|
-
</Grid>
|
|
148
|
+
const MultiSizeValueControl = ( { item }: { item: Item } ) => (
|
|
149
|
+
<PropKeyProvider bind={ item.bind }>
|
|
150
|
+
<Grid item xs={ 6 }>
|
|
151
|
+
<Grid container gap={ 1 } alignItems="center">
|
|
152
|
+
<Grid item xs={ 12 }>
|
|
153
|
+
<ControlLabel>{ item.label }</ControlLabel>
|
|
154
|
+
</Grid>
|
|
155
|
+
<Grid item xs={ 12 }>
|
|
156
|
+
<SizeControl startIcon={ item.icon } />
|
|
192
157
|
</Grid>
|
|
193
158
|
</Grid>
|
|
194
|
-
</
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const EqualSizeControl = ( {
|
|
199
|
-
value,
|
|
200
|
-
items,
|
|
201
|
-
setValue,
|
|
202
|
-
iconButton,
|
|
203
|
-
multiSizeValue,
|
|
204
|
-
}: {
|
|
205
|
-
value: SizePropValue[ 'value' ] | null;
|
|
206
|
-
items: EqualUnequalItems;
|
|
207
|
-
setValue: ( newValue: SizePropValue[ 'value' ] ) => void;
|
|
208
|
-
iconButton: ReactNode;
|
|
209
|
-
multiSizeValue: PropValue;
|
|
210
|
-
} ) => {
|
|
211
|
-
const handleChange = ( newValue: SizePropValue ) => {
|
|
212
|
-
setValue( newValue.value );
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const getDisplayValue = () => {
|
|
216
|
-
if ( value ) {
|
|
217
|
-
return sizePropTypeUtil.create( value );
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const multiValues = Object.values( multiSizeValue ?? {} ) as SizePropValue[];
|
|
221
|
-
|
|
222
|
-
if ( isEqualSizes( multiValues, items ) ) {
|
|
223
|
-
return sizePropTypeUtil.create( multiValues[ 0 ].value );
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
return (
|
|
228
|
-
<BoundPropProvider bind={ '' } setValue={ handleChange as SetContextValue } value={ getDisplayValue() ?? null }>
|
|
229
|
-
<Stack direction="row" alignItems="center" gap={ 1 }>
|
|
230
|
-
<SizeControl placeholder={ __( 'MIXED', 'elementor' ) } />
|
|
231
|
-
{ iconButton }
|
|
232
|
-
</Stack>
|
|
233
|
-
</BoundPropProvider>
|
|
234
|
-
);
|
|
235
|
-
};
|
|
159
|
+
</Grid>
|
|
160
|
+
</PropKeyProvider>
|
|
161
|
+
);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { gapPropTypeUtil, type
|
|
2
|
+
import { gapPropTypeUtil, type GapPropValue } from '@elementor/editor-props';
|
|
3
3
|
import { DetachIcon, LinkIcon } from '@elementor/icons';
|
|
4
4
|
import { Grid, Stack, ToggleButton } from '@elementor/ui';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { PropKeyProvider, PropProvider, type SetValue, useBoundProp } from '../bound-prop-context';
|
|
8
8
|
import { ControlLabel } from '../components/control-label';
|
|
9
9
|
import { createControl } from '../create-control';
|
|
10
10
|
import { SizeControl } from './size-control';
|
|
@@ -12,18 +12,21 @@ import { SizeControl } from './size-control';
|
|
|
12
12
|
export type Gap = 'row' | 'column';
|
|
13
13
|
|
|
14
14
|
export const GapControl = createControl( ( { label }: { label: string } ) => {
|
|
15
|
-
const { value, setValue } = useBoundProp( gapPropTypeUtil );
|
|
15
|
+
const { propType, value, setValue } = useBoundProp( gapPropTypeUtil );
|
|
16
16
|
const { column, row, isLinked = true } = value || {};
|
|
17
17
|
|
|
18
|
-
const setLinkedValue = (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
row: isLinked ? newValue : row,
|
|
23
|
-
[ gap ]: newValue,
|
|
24
|
-
};
|
|
18
|
+
const setLinkedValue: SetValue< GapPropValue[ 'value' ] > = ( newValue, _, meta ) => {
|
|
19
|
+
if ( ! isLinked ) {
|
|
20
|
+
return setValue( newValue );
|
|
21
|
+
}
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
const newDimension = newValue[ meta?.bind as Gap ];
|
|
24
|
+
|
|
25
|
+
setValue( {
|
|
26
|
+
isLinked,
|
|
27
|
+
column: newDimension,
|
|
28
|
+
row: newDimension,
|
|
29
|
+
} );
|
|
27
30
|
};
|
|
28
31
|
|
|
29
32
|
const toggleLinked = () => {
|
|
@@ -39,7 +42,7 @@ export const GapControl = createControl( ( { label }: { label: string } ) => {
|
|
|
39
42
|
const LinkedIcon = isLinked ? LinkIcon : DetachIcon;
|
|
40
43
|
|
|
41
44
|
return (
|
|
42
|
-
|
|
45
|
+
<PropProvider propType={ propType } value={ value } setValue={ setLinkedValue }>
|
|
43
46
|
<Stack direction="row" gap={ 2 } flexWrap="nowrap">
|
|
44
47
|
<ControlLabel>{ label }</ControlLabel>
|
|
45
48
|
<ToggleButton
|
|
@@ -59,13 +62,9 @@ export const GapControl = createControl( ( { label }: { label: string } ) => {
|
|
|
59
62
|
<ControlLabel>{ __( 'Column', 'elementor' ) }</ControlLabel>
|
|
60
63
|
</Grid>
|
|
61
64
|
<Grid item xs={ 12 }>
|
|
62
|
-
<
|
|
63
|
-
setValue={ ( newValue ) => setLinkedValue( 'column', newValue ) }
|
|
64
|
-
value={ column }
|
|
65
|
-
bind="column"
|
|
66
|
-
>
|
|
65
|
+
<PropKeyProvider bind="column">
|
|
67
66
|
<SizeControl />
|
|
68
|
-
</
|
|
67
|
+
</PropKeyProvider>
|
|
69
68
|
</Grid>
|
|
70
69
|
</Grid>
|
|
71
70
|
<Grid container gap={ 1 } alignItems="center">
|
|
@@ -73,16 +72,12 @@ export const GapControl = createControl( ( { label }: { label: string } ) => {
|
|
|
73
72
|
<ControlLabel>{ __( 'Row', 'elementor' ) }</ControlLabel>
|
|
74
73
|
</Grid>
|
|
75
74
|
<Grid item xs={ 12 }>
|
|
76
|
-
<
|
|
77
|
-
setValue={ ( newValue ) => setLinkedValue( 'row', newValue ) }
|
|
78
|
-
value={ row }
|
|
79
|
-
bind="row"
|
|
80
|
-
>
|
|
75
|
+
<PropKeyProvider bind="row">
|
|
81
76
|
<SizeControl />
|
|
82
|
-
</
|
|
77
|
+
</PropKeyProvider>
|
|
83
78
|
</Grid>
|
|
84
79
|
</Grid>
|
|
85
80
|
</Stack>
|
|
86
|
-
|
|
81
|
+
</PropProvider>
|
|
87
82
|
);
|
|
88
83
|
} );
|