@elementor/editor-controls 0.15.0 → 0.16.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 +12 -0
- package/dist/index.js +197 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +188 -53
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/controls/background-control/background-gradient-color-control.tsx +101 -0
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +43 -5
- package/src/controls/background-control/background-overlay/use-background-tabs-history.ts +29 -2
- package/src/controls/font-family-control/font-family-control.tsx +28 -12
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.
|
|
4
|
+
"version": "0.16.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-props": "0.
|
|
43
|
+
"@elementor/editor-props": "0.10.0",
|
|
44
44
|
"@elementor/env": "0.3.5",
|
|
45
45
|
"@elementor/http": "0.1.4",
|
|
46
|
-
"@elementor/icons": "1.
|
|
46
|
+
"@elementor/icons": "1.37.0",
|
|
47
47
|
"@elementor/query": "0.2.4",
|
|
48
48
|
"@elementor/session": "0.1.0",
|
|
49
49
|
"@elementor/ui": "1.26.0",
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
backgroundGradientOverlayPropTypeUtil,
|
|
4
|
+
type BackgroundGradientOverlayPropValue,
|
|
5
|
+
type BackgroundOverlayItemPropValue,
|
|
6
|
+
colorPropTypeUtil,
|
|
7
|
+
type ColorPropValue,
|
|
8
|
+
colorStopPropTypeUtil,
|
|
9
|
+
gradientColorStopPropTypeUtil,
|
|
10
|
+
numberPropTypeUtil,
|
|
11
|
+
type NumberPropValue,
|
|
12
|
+
stringPropTypeUtil,
|
|
13
|
+
type TransformablePropValue,
|
|
14
|
+
} from '@elementor/editor-props';
|
|
15
|
+
import { UnstableGradientBox } from '@elementor/ui';
|
|
16
|
+
|
|
17
|
+
import { useBoundProp } from '../../bound-prop-context';
|
|
18
|
+
import ControlActions from '../../control-actions/control-actions';
|
|
19
|
+
import { createControl } from '../../create-control';
|
|
20
|
+
|
|
21
|
+
export type ColorStop = TransformablePropValue<
|
|
22
|
+
'color-stop',
|
|
23
|
+
{
|
|
24
|
+
color: ColorPropValue;
|
|
25
|
+
offset: NumberPropValue;
|
|
26
|
+
}
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
export const BackgroundGradientColorControl = createControl( () => {
|
|
30
|
+
const { value, setValue } = useBoundProp( backgroundGradientOverlayPropTypeUtil );
|
|
31
|
+
|
|
32
|
+
const handleChange = ( newValue: BackgroundGradientOverlayPropValue[ 'value' ] ) => {
|
|
33
|
+
const transformedValue = createTransformableValue( newValue );
|
|
34
|
+
|
|
35
|
+
if ( transformedValue.positions ) {
|
|
36
|
+
transformedValue.positions = stringPropTypeUtil.create( newValue.positions.join( ' ' ) );
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setValue( transformedValue );
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// TODO: To support Global variables this won't be needed when we have a flexible Gradient Box
|
|
43
|
+
const createTransformableValue = ( newValue: BackgroundGradientOverlayPropValue[ 'value' ] ) => ( {
|
|
44
|
+
...newValue,
|
|
45
|
+
type: stringPropTypeUtil.create( newValue.type ),
|
|
46
|
+
angle: numberPropTypeUtil.create( newValue.angle ),
|
|
47
|
+
stops: gradientColorStopPropTypeUtil.create(
|
|
48
|
+
newValue.stops.map( ( { color, offset }: { color: string; offset: number } ) =>
|
|
49
|
+
colorStopPropTypeUtil.create( {
|
|
50
|
+
color: colorPropTypeUtil.create( color ),
|
|
51
|
+
offset: numberPropTypeUtil.create( offset ),
|
|
52
|
+
} )
|
|
53
|
+
)
|
|
54
|
+
),
|
|
55
|
+
} );
|
|
56
|
+
|
|
57
|
+
// TODO: To support Global variables this won't be needed when we have a flexible Gradient Box
|
|
58
|
+
const normalizeValue = () => {
|
|
59
|
+
if ( ! value ) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { type, angle, stops, positions } = value;
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
type: type.value,
|
|
67
|
+
angle: angle.value,
|
|
68
|
+
stops: stops.value.map( ( { value: { color, offset } }: ColorStop ) => ( {
|
|
69
|
+
color: color.value,
|
|
70
|
+
offset: offset.value,
|
|
71
|
+
} ) ),
|
|
72
|
+
positions: positions?.value.split( ' ' ),
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<ControlActions>
|
|
78
|
+
<UnstableGradientBox
|
|
79
|
+
sx={ { width: 'auto', padding: 1.5 } }
|
|
80
|
+
value={ normalizeValue() }
|
|
81
|
+
onChange={ handleChange }
|
|
82
|
+
/>
|
|
83
|
+
</ControlActions>
|
|
84
|
+
);
|
|
85
|
+
} );
|
|
86
|
+
|
|
87
|
+
export const initialBackgroundGradientOverlay: BackgroundOverlayItemPropValue =
|
|
88
|
+
backgroundGradientOverlayPropTypeUtil.create( {
|
|
89
|
+
type: stringPropTypeUtil.create( 'linear' ),
|
|
90
|
+
angle: numberPropTypeUtil.create( 180 ),
|
|
91
|
+
stops: gradientColorStopPropTypeUtil.create( [
|
|
92
|
+
colorStopPropTypeUtil.create( {
|
|
93
|
+
color: stringPropTypeUtil.create( 'var(--primary-color)' ),
|
|
94
|
+
offset: numberPropTypeUtil.create( 0 ),
|
|
95
|
+
} ),
|
|
96
|
+
colorStopPropTypeUtil.create( {
|
|
97
|
+
color: colorPropTypeUtil.create( 'rgb(255,255,255)' ),
|
|
98
|
+
offset: numberPropTypeUtil.create( 100 ),
|
|
99
|
+
} ),
|
|
100
|
+
] ),
|
|
101
|
+
} );
|
package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx
CHANGED
|
@@ -17,6 +17,11 @@ import { createControl } from '../../../create-control';
|
|
|
17
17
|
import { env } from '../../../env';
|
|
18
18
|
import { ColorControl } from '../../color-control';
|
|
19
19
|
import { ImageControl } from '../../image-control';
|
|
20
|
+
import {
|
|
21
|
+
BackgroundGradientColorControl,
|
|
22
|
+
type ColorStop,
|
|
23
|
+
initialBackgroundGradientOverlay,
|
|
24
|
+
} from '../background-gradient-color-control';
|
|
20
25
|
import { BackgroundImageOverlayAttachment } from './background-image-overlay/background-image-overlay-attachment';
|
|
21
26
|
import { BackgroundImageOverlayPosition } from './background-image-overlay/background-image-overlay-position';
|
|
22
27
|
import { BackgroundImageOverlayRepeat } from './background-image-overlay/background-image-overlay-repeat';
|
|
@@ -93,6 +98,7 @@ const Content = () => {
|
|
|
93
98
|
const { getTabsProps, getTabProps, getTabPanelProps } = useBackgroundTabsHistory( {
|
|
94
99
|
image: getInitialBackgroundOverlay().value,
|
|
95
100
|
color: initialBackgroundColorOverlay.value,
|
|
101
|
+
gradient: initialBackgroundGradientOverlay.value,
|
|
96
102
|
} );
|
|
97
103
|
|
|
98
104
|
return (
|
|
@@ -100,6 +106,7 @@ const Content = () => {
|
|
|
100
106
|
<Box sx={ { borderBottom: 1, borderColor: 'divider' } }>
|
|
101
107
|
<Tabs { ...getTabsProps() } aria-label={ __( 'Background Overlay', 'elementor' ) }>
|
|
102
108
|
<Tab label={ __( 'Image', 'elementor' ) } { ...getTabProps( 'image' ) } />
|
|
109
|
+
<Tab label={ __( 'Gradient', 'elementor' ) } { ...getTabProps( 'gradient' ) } />
|
|
103
110
|
<Tab label={ __( 'Color', 'elementor' ) } { ...getTabProps( 'color' ) } />
|
|
104
111
|
</Tabs>
|
|
105
112
|
</Box>
|
|
@@ -108,12 +115,11 @@ const Content = () => {
|
|
|
108
115
|
<ImageOverlayContent />
|
|
109
116
|
</PopoverContent>
|
|
110
117
|
</TabPanel>
|
|
118
|
+
<TabPanel sx={ { p: 1.5 } } { ...getTabPanelProps( 'gradient' ) }>
|
|
119
|
+
<BackgroundGradientColorControl />
|
|
120
|
+
</TabPanel>
|
|
111
121
|
<TabPanel { ...getTabPanelProps( 'color' ) } sx={ { p: 1.5 } }>
|
|
112
|
-
<
|
|
113
|
-
<Grid item xs={ 12 }>
|
|
114
|
-
<ColorControl propTypeUtil={ backgroundColorOverlayPropTypeUtil } />
|
|
115
|
-
</Grid>
|
|
116
|
-
</Grid>
|
|
122
|
+
<ColorControl propTypeUtil={ backgroundColorOverlayPropTypeUtil } />
|
|
117
123
|
</TabPanel>
|
|
118
124
|
</Box>
|
|
119
125
|
);
|
|
@@ -125,6 +131,8 @@ const ItemIcon = ( { value }: { value: BackgroundOverlayItemPropValue } ) => {
|
|
|
125
131
|
return <ItemIconImage value={ value as BackgroundImageOverlay } />;
|
|
126
132
|
case 'background-color-overlay':
|
|
127
133
|
return <ItemIconColor value={ value } />;
|
|
134
|
+
case 'background-gradient-overlay':
|
|
135
|
+
return <ItemIconGradient value={ value } />;
|
|
128
136
|
default:
|
|
129
137
|
return null;
|
|
130
138
|
}
|
|
@@ -140,12 +148,20 @@ const ItemIconImage = ( { value }: { value: BackgroundImageOverlay } ) => {
|
|
|
140
148
|
return <CardMedia image={ imageUrl } sx={ { height: 13, width: 13, borderRadius: '4px' } } />;
|
|
141
149
|
};
|
|
142
150
|
|
|
151
|
+
const ItemIconGradient = ( { value }: { value: BackgroundOverlayItemPropValue } ) => {
|
|
152
|
+
const gradient = getGradientValue( value );
|
|
153
|
+
|
|
154
|
+
return <UnstableColorIndicator size="inherit" component="span" value={ gradient } />;
|
|
155
|
+
};
|
|
156
|
+
|
|
143
157
|
const ItemLabel = ( { value }: { value: BackgroundOverlayItemPropValue } ) => {
|
|
144
158
|
switch ( value.$$type ) {
|
|
145
159
|
case 'background-image-overlay':
|
|
146
160
|
return <ItemLabelImage value={ value as BackgroundImageOverlay } />;
|
|
147
161
|
case 'background-color-overlay':
|
|
148
162
|
return <ItemLabelColor value={ value } />;
|
|
163
|
+
case 'background-gradient-overlay':
|
|
164
|
+
return <ItemLabelGradient value={ value } />;
|
|
149
165
|
default:
|
|
150
166
|
return null;
|
|
151
167
|
}
|
|
@@ -161,6 +177,14 @@ const ItemLabelImage = ( { value }: { value: BackgroundImageOverlay } ) => {
|
|
|
161
177
|
return <span>{ imageTitle }</span>;
|
|
162
178
|
};
|
|
163
179
|
|
|
180
|
+
const ItemLabelGradient = ( { value }: { value: BackgroundOverlayItemPropValue } ) => {
|
|
181
|
+
if ( value.value.type.value === 'linear' ) {
|
|
182
|
+
return <span>{ __( 'Linear Gradient', 'elementor' ) }</span>;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return <span>{ __( 'Radial Gradient', 'elementor' ) }</span>;
|
|
186
|
+
};
|
|
187
|
+
|
|
164
188
|
const ImageOverlayContent = () => {
|
|
165
189
|
const propContext = useBoundProp( backgroundImageOverlayPropTypeUtil );
|
|
166
190
|
|
|
@@ -210,3 +234,17 @@ const useImage = ( image: BackgroundImageOverlay ) => {
|
|
|
210
234
|
|
|
211
235
|
return { imageTitle, imageUrl };
|
|
212
236
|
};
|
|
237
|
+
|
|
238
|
+
const getGradientValue = ( value: BackgroundOverlayItemPropValue ) => {
|
|
239
|
+
const gradient = value.value;
|
|
240
|
+
|
|
241
|
+
const stops = gradient.stops.value
|
|
242
|
+
?.map( ( { value: { color, offset } }: ColorStop ) => `${ color.value } ${ offset.value ?? 0 }%` )
|
|
243
|
+
?.join( ',' );
|
|
244
|
+
|
|
245
|
+
if ( gradient.type.value === 'linear' ) {
|
|
246
|
+
return `linear-gradient(${ gradient.angle.value }deg, ${ stops })`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return `radial-gradient(circle at ${ gradient.positions.value }, ${ stops })`;
|
|
250
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
backgroundColorOverlayPropTypeUtil,
|
|
4
|
+
backgroundGradientOverlayPropTypeUtil,
|
|
4
5
|
backgroundImageOverlayPropTypeUtil,
|
|
5
6
|
type BackgroundOverlayItemPropValue,
|
|
6
7
|
} from '@elementor/editor-props';
|
|
@@ -9,25 +10,41 @@ import { useTabs } from '@elementor/ui';
|
|
|
9
10
|
import { useBoundProp } from '../../../bound-prop-context';
|
|
10
11
|
import { type BackgroundImageOverlay } from './types';
|
|
11
12
|
|
|
12
|
-
type OverlayType = 'image' | 'color';
|
|
13
|
+
type OverlayType = 'image' | 'gradient' | 'color';
|
|
13
14
|
|
|
14
15
|
type InitialBackgroundValues = {
|
|
15
16
|
color: BackgroundOverlayItemPropValue[ 'value' ];
|
|
16
17
|
image: BackgroundImageOverlay[ 'value' ];
|
|
18
|
+
gradient: BackgroundOverlayItemPropValue[ 'value' ];
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export const useBackgroundTabsHistory = ( {
|
|
20
22
|
color: initialBackgroundColorOverlay,
|
|
21
23
|
image: initialBackgroundImageOverlay,
|
|
24
|
+
gradient: initialBackgroundGradientOverlay,
|
|
22
25
|
}: InitialBackgroundValues ) => {
|
|
23
26
|
const { value: imageValue, setValue: setImageValue } = useBoundProp( backgroundImageOverlayPropTypeUtil );
|
|
24
27
|
const { value: colorValue, setValue: setColorValue } = useBoundProp( backgroundColorOverlayPropTypeUtil );
|
|
28
|
+
const { value: gradientValue, setValue: setGradientValue } = useBoundProp( backgroundGradientOverlayPropTypeUtil );
|
|
25
29
|
|
|
26
|
-
const
|
|
30
|
+
const getCurrentOverlayType = (): OverlayType => {
|
|
31
|
+
if ( colorValue ) {
|
|
32
|
+
return 'color';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if ( gradientValue ) {
|
|
36
|
+
return 'gradient';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return 'image';
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const { getTabsProps, getTabProps, getTabPanelProps } = useTabs< OverlayType >( getCurrentOverlayType() );
|
|
27
43
|
|
|
28
44
|
const valuesHistory = useRef< InitialBackgroundValues >( {
|
|
29
45
|
image: initialBackgroundImageOverlay,
|
|
30
46
|
color: initialBackgroundColorOverlay,
|
|
47
|
+
gradient: initialBackgroundGradientOverlay,
|
|
31
48
|
} );
|
|
32
49
|
|
|
33
50
|
const saveToHistory = ( key: keyof InitialBackgroundValues, value: BackgroundOverlayItemPropValue[ 'value' ] ) => {
|
|
@@ -42,6 +59,15 @@ export const useBackgroundTabsHistory = ( {
|
|
|
42
59
|
setImageValue( valuesHistory.current.image );
|
|
43
60
|
|
|
44
61
|
saveToHistory( 'color', colorValue );
|
|
62
|
+
saveToHistory( 'gradient', gradientValue );
|
|
63
|
+
|
|
64
|
+
break;
|
|
65
|
+
|
|
66
|
+
case 'gradient':
|
|
67
|
+
setGradientValue( valuesHistory.current.gradient );
|
|
68
|
+
|
|
69
|
+
saveToHistory( 'color', colorValue );
|
|
70
|
+
saveToHistory( 'image', imageValue );
|
|
45
71
|
|
|
46
72
|
break;
|
|
47
73
|
|
|
@@ -49,6 +75,7 @@ export const useBackgroundTabsHistory = ( {
|
|
|
49
75
|
setColorValue( valuesHistory.current.color );
|
|
50
76
|
|
|
51
77
|
saveToHistory( 'image', imageValue );
|
|
78
|
+
saveToHistory( 'gradient', gradientValue );
|
|
52
79
|
}
|
|
53
80
|
|
|
54
81
|
return getTabsProps().onChange( e, tabName );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { stringPropTypeUtil } from '@elementor/editor-props';
|
|
4
|
-
import { ChevronDownIcon,
|
|
4
|
+
import { ChevronDownIcon, SearchIcon, TextIcon, XIcon } from '@elementor/icons';
|
|
5
5
|
import {
|
|
6
6
|
bindPopover,
|
|
7
7
|
bindTrigger,
|
|
@@ -72,7 +72,7 @@ export const FontFamilyControl = createControl( ( { fontFamilies }: FontFamilyCo
|
|
|
72
72
|
>
|
|
73
73
|
<Stack>
|
|
74
74
|
<Stack direction="row" alignItems="center" pl={ 1.5 } pr={ 0.5 } py={ 1.5 }>
|
|
75
|
-
<
|
|
75
|
+
<TextIcon fontSize={ SIZE } sx={ { mr: 0.5 } } />
|
|
76
76
|
<Typography variant="subtitle2">{ __( 'Font Family', 'elementor' ) }</Typography>
|
|
77
77
|
<IconButton size={ SIZE } sx={ { ml: 'auto' } } onClick={ handleClose }>
|
|
78
78
|
<XIcon fontSize={ SIZE } />
|
|
@@ -105,24 +105,40 @@ export const FontFamilyControl = createControl( ( { fontFamilies }: FontFamilyCo
|
|
|
105
105
|
/>
|
|
106
106
|
) : (
|
|
107
107
|
<Box sx={ { overflowY: 'auto', height: 260, width: 220 } }>
|
|
108
|
-
<Stack alignItems="center" p={ 2.5 } gap={ 1.5 }>
|
|
109
|
-
<
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
<Stack alignItems="center" p={ 2.5 } gap={ 1.5 } overflow={ 'hidden' }>
|
|
109
|
+
<TextIcon fontSize="large" />
|
|
110
|
+
<Box sx={ { maxWidth: 160, overflow: 'hidden' } }>
|
|
111
|
+
<Typography align="center" variant="subtitle2" color="text.secondary">
|
|
112
|
+
{ __( 'Sorry, nothing matched', 'elementor' ) }
|
|
113
|
+
</Typography>
|
|
114
|
+
<Typography
|
|
115
|
+
variant="subtitle2"
|
|
116
|
+
color="text.secondary"
|
|
117
|
+
sx={ {
|
|
118
|
+
display: 'flex',
|
|
119
|
+
width: '100%',
|
|
120
|
+
justifyContent: 'center',
|
|
121
|
+
} }
|
|
122
|
+
>
|
|
123
|
+
<span>“</span>
|
|
124
|
+
<span
|
|
125
|
+
style={ { maxWidth: '80%', overflow: 'hidden', textOverflow: 'ellipsis' } }
|
|
126
|
+
>
|
|
127
|
+
{ searchValue }
|
|
128
|
+
</span>
|
|
129
|
+
<span>”.</span>
|
|
130
|
+
</Typography>
|
|
131
|
+
</Box>
|
|
115
132
|
<Typography align="center" variant="caption" color="text.secondary">
|
|
133
|
+
{ __( 'Try something else.', 'elementor' ) }
|
|
116
134
|
<Link
|
|
117
135
|
color="secondary"
|
|
118
136
|
variant="caption"
|
|
119
137
|
component="button"
|
|
120
138
|
onClick={ () => setSearchValue( '' ) }
|
|
121
139
|
>
|
|
122
|
-
{ __( 'Clear
|
|
140
|
+
{ __( 'Clear & try again', 'elementor' ) }
|
|
123
141
|
</Link>
|
|
124
|
-
|
|
125
|
-
{ __( 'and try again.', 'elementor' ) }
|
|
126
142
|
</Typography>
|
|
127
143
|
</Stack>
|
|
128
144
|
</Box>
|