@elementor/editor-controls 1.2.0 → 1.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 +66 -0
- package/dist/index.d.mts +20 -8
- package/dist/index.d.ts +20 -8
- package/dist/index.js +1092 -714
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +937 -549
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/bound-prop-context/prop-context.tsx +3 -3
- package/src/bound-prop-context/prop-key-context.tsx +1 -0
- package/src/bound-prop-context/use-bound-prop.ts +5 -1
- package/src/components/font-family-selector.tsx +54 -56
- package/src/components/repeater.tsx +22 -11
- package/src/components/size-control/size-input.tsx +4 -4
- package/src/components/text-field-popover.tsx +19 -18
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +3 -15
- package/src/controls/box-shadow-repeater-control.tsx +1 -1
- package/src/controls/color-control.tsx +12 -1
- package/src/controls/equal-unequal-sizes-control.tsx +1 -1
- package/src/controls/filter-control/drop-shadow-item-content.tsx +69 -0
- package/src/controls/filter-control/drop-shadow-item-label.tsx +20 -0
- package/src/controls/filter-repeater-control.tsx +108 -21
- package/src/controls/font-family-control/font-family-control.tsx +14 -2
- package/src/controls/image-control.tsx +45 -16
- package/src/controls/key-value-control.tsx +57 -46
- package/src/controls/link-control.tsx +25 -20
- package/src/controls/linked-dimensions-control.tsx +1 -1
- package/src/controls/repeatable-control.tsx +100 -21
- package/src/controls/select-control.tsx +22 -2
- package/src/controls/size-control.tsx +25 -12
- package/src/controls/switch-control.tsx +9 -1
- package/src/controls/text-control.tsx +33 -18
- package/src/controls/transform-control/functions/axis-row.tsx +32 -0
- package/src/controls/transform-control/functions/move.tsx +44 -0
- package/src/controls/transform-control/transform-content.tsx +36 -0
- package/src/controls/transform-control/transform-icon.tsx +12 -0
- package/src/controls/transform-control/transform-label.tsx +27 -0
- package/src/controls/transform-control/transform-repeater-control.tsx +42 -0
- package/src/hooks/use-repeatable-control-context.ts +6 -1
- package/src/index.ts +1 -0
- package/src/utils/size-control.ts +4 -2
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": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,19 +40,19 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "0.
|
|
44
|
-
"@elementor/editor-elements": "0.
|
|
45
|
-
"@elementor/editor-props": "0.
|
|
43
|
+
"@elementor/editor-current-user": "0.6.1",
|
|
44
|
+
"@elementor/editor-elements": "0.9.2",
|
|
45
|
+
"@elementor/editor-props": "0.18.0",
|
|
46
46
|
"@elementor/editor-responsive": "0.13.6",
|
|
47
|
-
"@elementor/editor-ui": "0.
|
|
47
|
+
"@elementor/editor-ui": "0.14.2",
|
|
48
48
|
"@elementor/editor-v1-adapters": "0.12.1",
|
|
49
49
|
"@elementor/env": "0.3.5",
|
|
50
50
|
"@elementor/http-client": "0.3.0",
|
|
51
|
-
"@elementor/icons": "1.
|
|
51
|
+
"@elementor/icons": "1.46.0",
|
|
52
52
|
"@elementor/locations": "0.8.0",
|
|
53
53
|
"@elementor/query": "0.2.4",
|
|
54
54
|
"@elementor/session": "0.1.0",
|
|
55
|
-
"@elementor/ui": "1.
|
|
55
|
+
"@elementor/ui": "1.36.0",
|
|
56
56
|
"@elementor/utils": "0.5.0",
|
|
57
57
|
"@elementor/wp-media": "0.6.1",
|
|
58
58
|
"@wordpress/i18n": "^5.13.0"
|
|
@@ -15,7 +15,7 @@ type PropContext< T extends PropValue, P extends PropType > = {
|
|
|
15
15
|
value: T | null;
|
|
16
16
|
propType: P;
|
|
17
17
|
placeholder?: T;
|
|
18
|
-
|
|
18
|
+
isDisabled?: ( propType: PropType ) => boolean | undefined;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const PropContext = createContext< PropContext< PropValue, PropType > | null >( null );
|
|
@@ -30,7 +30,7 @@ export const PropProvider = < T extends PropValue, P extends PropType >( {
|
|
|
30
30
|
setValue,
|
|
31
31
|
propType,
|
|
32
32
|
placeholder,
|
|
33
|
-
|
|
33
|
+
isDisabled,
|
|
34
34
|
}: PropProviderProps< T, P > ) => {
|
|
35
35
|
return (
|
|
36
36
|
<PropContext.Provider
|
|
@@ -39,7 +39,7 @@ export const PropProvider = < T extends PropValue, P extends PropType >( {
|
|
|
39
39
|
propType,
|
|
40
40
|
setValue: setValue as SetValue< PropValue >,
|
|
41
41
|
placeholder,
|
|
42
|
-
|
|
42
|
+
isDisabled,
|
|
43
43
|
} }
|
|
44
44
|
>
|
|
45
45
|
{ children }
|
|
@@ -19,6 +19,7 @@ type UseBoundProp< TValue extends PropValue > = {
|
|
|
19
19
|
placeholder?: TValue;
|
|
20
20
|
path: PropKey[];
|
|
21
21
|
restoreValue: () => void;
|
|
22
|
+
isDisabled?: ( propType: PropType ) => boolean | undefined;
|
|
22
23
|
disabled?: boolean;
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -38,9 +39,11 @@ export function useBoundProp< TKey extends string, TValue extends PropValue >(
|
|
|
38
39
|
|
|
39
40
|
const { isValid, validate, restoreValue } = useValidation( propKeyContext.propType );
|
|
40
41
|
|
|
42
|
+
const disabled = propKeyContext.isDisabled?.( propKeyContext.propType );
|
|
43
|
+
|
|
41
44
|
// allow using the hook without a propTypeUtil, with no modifications or validations.
|
|
42
45
|
if ( ! propTypeUtil ) {
|
|
43
|
-
return propKeyContext
|
|
46
|
+
return { ...propKeyContext, disabled } as PropKeyContextValue< PropValue, PropType >;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
function setValue( value: TValue | null, options: CreateOptions, meta: { bind?: PropKey } ) {
|
|
@@ -67,6 +70,7 @@ export function useBoundProp< TKey extends string, TValue extends PropValue >(
|
|
|
67
70
|
value: isValid ? value : null,
|
|
68
71
|
restoreValue,
|
|
69
72
|
placeholder,
|
|
73
|
+
disabled,
|
|
70
74
|
};
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
|
-
import { PopoverHeader, PopoverMenuList,
|
|
3
|
+
import { PopoverBody, PopoverHeader, PopoverMenuList, PopoverSearch } from '@elementor/editor-ui';
|
|
4
4
|
import { TextIcon } from '@elementor/icons';
|
|
5
5
|
import { Box, Divider, Link, Stack, Typography } from '@elementor/ui';
|
|
6
6
|
import { debounce } from '@elementor/utils';
|
|
@@ -41,7 +41,7 @@ export const FontFamilySelector = ( {
|
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<
|
|
44
|
+
<PopoverBody width={ sectionWidth }>
|
|
45
45
|
<PopoverHeader
|
|
46
46
|
title={ __( 'Font Family', 'elementor' ) }
|
|
47
47
|
onClose={ handleClose }
|
|
@@ -56,64 +56,62 @@ export const FontFamilySelector = ( {
|
|
|
56
56
|
|
|
57
57
|
<Divider />
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
</Typography>
|
|
81
|
-
<Typography
|
|
82
|
-
variant="subtitle2"
|
|
83
|
-
color="text.secondary"
|
|
84
|
-
sx={ {
|
|
85
|
-
display: 'flex',
|
|
86
|
-
width: '100%',
|
|
87
|
-
justifyContent: 'center',
|
|
88
|
-
} }
|
|
89
|
-
>
|
|
90
|
-
<span>“</span>
|
|
91
|
-
<span style={ { maxWidth: '80%', overflow: 'hidden', textOverflow: 'ellipsis' } }>
|
|
92
|
-
{ searchValue }
|
|
93
|
-
</span>
|
|
94
|
-
<span>”.</span>
|
|
95
|
-
</Typography>
|
|
96
|
-
</Box>
|
|
59
|
+
{ filteredFontFamilies.length > 0 ? (
|
|
60
|
+
<FontList
|
|
61
|
+
fontListItems={ filteredFontFamilies }
|
|
62
|
+
setFontFamily={ onFontFamilyChange }
|
|
63
|
+
handleClose={ handleClose }
|
|
64
|
+
fontFamily={ fontFamily }
|
|
65
|
+
/>
|
|
66
|
+
) : (
|
|
67
|
+
<Stack
|
|
68
|
+
alignItems="center"
|
|
69
|
+
justifyContent="center"
|
|
70
|
+
height="100%"
|
|
71
|
+
p={ 2.5 }
|
|
72
|
+
gap={ 1.5 }
|
|
73
|
+
overflow={ 'hidden' }
|
|
74
|
+
>
|
|
75
|
+
<TextIcon fontSize="large" />
|
|
76
|
+
<Box sx={ { maxWidth: 160, overflow: 'hidden' } }>
|
|
77
|
+
<Typography align="center" variant="subtitle2" color="text.secondary">
|
|
78
|
+
{ __( 'Sorry, nothing matched', 'elementor' ) }
|
|
79
|
+
</Typography>
|
|
97
80
|
<Typography
|
|
98
|
-
|
|
99
|
-
variant="caption"
|
|
81
|
+
variant="subtitle2"
|
|
100
82
|
color="text.secondary"
|
|
101
|
-
sx={ {
|
|
83
|
+
sx={ {
|
|
84
|
+
display: 'flex',
|
|
85
|
+
width: '100%',
|
|
86
|
+
justifyContent: 'center',
|
|
87
|
+
} }
|
|
102
88
|
>
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
onClick={ () => setSearchValue( '' ) }
|
|
109
|
-
>
|
|
110
|
-
{ __( 'Clear & try again', 'elementor' ) }
|
|
111
|
-
</Link>
|
|
89
|
+
<span>“</span>
|
|
90
|
+
<span style={ { maxWidth: '80%', overflow: 'hidden', textOverflow: 'ellipsis' } }>
|
|
91
|
+
{ searchValue }
|
|
92
|
+
</span>
|
|
93
|
+
<span>”.</span>
|
|
112
94
|
</Typography>
|
|
113
|
-
</
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
95
|
+
</Box>
|
|
96
|
+
<Typography
|
|
97
|
+
align="center"
|
|
98
|
+
variant="caption"
|
|
99
|
+
color="text.secondary"
|
|
100
|
+
sx={ { display: 'flex', flexDirection: 'column' } }
|
|
101
|
+
>
|
|
102
|
+
{ __( 'Try something else.', 'elementor' ) }
|
|
103
|
+
<Link
|
|
104
|
+
color="secondary"
|
|
105
|
+
variant="caption"
|
|
106
|
+
component="button"
|
|
107
|
+
onClick={ () => setSearchValue( '' ) }
|
|
108
|
+
>
|
|
109
|
+
{ __( 'Clear & try again', 'elementor' ) }
|
|
110
|
+
</Link>
|
|
111
|
+
</Typography>
|
|
112
|
+
</Stack>
|
|
113
|
+
) }
|
|
114
|
+
</PopoverBody>
|
|
117
115
|
);
|
|
118
116
|
};
|
|
119
117
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
|
-
import { type PropKey } from '@elementor/editor-props';
|
|
3
|
+
import { type PropKey, type PropTypeUtil } from '@elementor/editor-props';
|
|
4
4
|
import { CopyIcon, EyeIcon, EyeOffIcon, PlusIcon, XIcon } from '@elementor/icons';
|
|
5
5
|
import {
|
|
6
6
|
bindPopover,
|
|
@@ -30,6 +30,16 @@ type AnchorEl = HTMLElement | null;
|
|
|
30
30
|
type Item< T > = {
|
|
31
31
|
disabled?: boolean;
|
|
32
32
|
} & T;
|
|
33
|
+
export type CollectionPropUtil< T > = PropTypeUtil< PropKey, T[] >;
|
|
34
|
+
|
|
35
|
+
type RepeaterItemContentProps< T > = {
|
|
36
|
+
anchorEl: AnchorEl;
|
|
37
|
+
bind: PropKey;
|
|
38
|
+
value: T;
|
|
39
|
+
collectionPropUtil?: CollectionPropUtil< T >;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type RepeaterItemContent< T > = React.ComponentType< RepeaterItemContentProps< T > >;
|
|
33
43
|
|
|
34
44
|
type RepeaterProps< T > = {
|
|
35
45
|
label: string;
|
|
@@ -42,15 +52,12 @@ type RepeaterProps< T > = {
|
|
|
42
52
|
initialValues: T;
|
|
43
53
|
Label: React.ComponentType< { value: T } >;
|
|
44
54
|
Icon: React.ComponentType< { value: T } >;
|
|
45
|
-
Content:
|
|
46
|
-
anchorEl: AnchorEl;
|
|
47
|
-
bind: PropKey;
|
|
48
|
-
value: T;
|
|
49
|
-
} >;
|
|
55
|
+
Content: RepeaterItemContent< T >;
|
|
50
56
|
};
|
|
51
57
|
showDuplicate?: boolean;
|
|
52
58
|
showToggle?: boolean;
|
|
53
59
|
isSortable?: boolean;
|
|
60
|
+
collectionPropUtil?: CollectionPropUtil< T >;
|
|
54
61
|
};
|
|
55
62
|
|
|
56
63
|
const EMPTY_OPEN_ITEM = -1;
|
|
@@ -66,6 +73,7 @@ export const Repeater = < T, >( {
|
|
|
66
73
|
showDuplicate = true,
|
|
67
74
|
showToggle = true,
|
|
68
75
|
isSortable = true,
|
|
76
|
+
collectionPropUtil,
|
|
69
77
|
}: RepeaterProps< Item< T > > ) => {
|
|
70
78
|
const [ openItem, setOpenItem ] = useState( EMPTY_OPEN_ITEM );
|
|
71
79
|
|
|
@@ -203,6 +211,7 @@ export const Repeater = < T, >( {
|
|
|
203
211
|
onOpen={ () => setOpenItem( EMPTY_OPEN_ITEM ) }
|
|
204
212
|
showDuplicate={ showDuplicate }
|
|
205
213
|
showToggle={ showToggle }
|
|
214
|
+
collectionPropUtil={ collectionPropUtil }
|
|
206
215
|
>
|
|
207
216
|
{ ( props ) => (
|
|
208
217
|
<itemSettings.Content { ...props } value={ value } bind={ String( index ) } />
|
|
@@ -217,22 +226,23 @@ export const Repeater = < T, >( {
|
|
|
217
226
|
);
|
|
218
227
|
};
|
|
219
228
|
|
|
220
|
-
type RepeaterItemProps = {
|
|
229
|
+
type RepeaterItemProps< T > = {
|
|
221
230
|
label: React.ReactNode;
|
|
222
231
|
propDisabled?: boolean;
|
|
223
232
|
startIcon: UnstableTagProps[ 'startIcon' ];
|
|
224
233
|
removeItem: () => void;
|
|
225
234
|
duplicateItem: () => void;
|
|
226
235
|
toggleDisableItem: () => void;
|
|
227
|
-
children: (
|
|
236
|
+
children: ( props: Pick< RepeaterItemContentProps< T >, 'anchorEl' | 'collectionPropUtil' > ) => React.ReactNode;
|
|
228
237
|
openOnMount: boolean;
|
|
229
238
|
onOpen: () => void;
|
|
230
239
|
showDuplicate: boolean;
|
|
231
240
|
showToggle: boolean;
|
|
232
241
|
disabled?: boolean;
|
|
242
|
+
collectionPropUtil?: CollectionPropUtil< T >;
|
|
233
243
|
};
|
|
234
244
|
|
|
235
|
-
const RepeaterItem = ( {
|
|
245
|
+
const RepeaterItem = < T, >( {
|
|
236
246
|
label,
|
|
237
247
|
propDisabled,
|
|
238
248
|
startIcon,
|
|
@@ -245,7 +255,8 @@ const RepeaterItem = ( {
|
|
|
245
255
|
showDuplicate,
|
|
246
256
|
showToggle,
|
|
247
257
|
disabled,
|
|
248
|
-
|
|
258
|
+
collectionPropUtil,
|
|
259
|
+
}: RepeaterItemProps< T > ) => {
|
|
249
260
|
const [ anchorEl, setAnchorEl ] = useState< AnchorEl >( null );
|
|
250
261
|
const { popoverState, popoverProps, ref, setRef } = usePopover( openOnMount, onOpen );
|
|
251
262
|
|
|
@@ -301,7 +312,7 @@ const RepeaterItem = ( {
|
|
|
301
312
|
{ ...popoverProps }
|
|
302
313
|
anchorEl={ ref }
|
|
303
314
|
>
|
|
304
|
-
<Box>{ children( { anchorEl } ) }</Box>
|
|
315
|
+
<Box>{ children( { anchorEl, collectionPropUtil } ) }</Box>
|
|
305
316
|
</Popover>
|
|
306
317
|
</>
|
|
307
318
|
);
|
|
@@ -4,19 +4,19 @@ import { PencilIcon } from '@elementor/icons';
|
|
|
4
4
|
import { Box, InputAdornment, type PopupState } from '@elementor/ui';
|
|
5
5
|
|
|
6
6
|
import ControlActions from '../../control-actions/control-actions';
|
|
7
|
-
import { type ExtendedOption, isUnitExtendedOption, type Unit } from '../../utils/size-control';
|
|
7
|
+
import { type DegreeUnit, type ExtendedOption, isUnitExtendedOption, type Unit } from '../../utils/size-control';
|
|
8
8
|
import { SelectionEndAdornment, TextFieldInnerSelection } from '../size-control/text-field-inner-selection';
|
|
9
9
|
|
|
10
10
|
type SizeInputProps = {
|
|
11
|
-
unit: Unit | ExtendedOption;
|
|
11
|
+
unit: Unit | DegreeUnit | ExtendedOption;
|
|
12
12
|
size: number | string;
|
|
13
13
|
placeholder?: string;
|
|
14
14
|
startIcon?: React.ReactNode;
|
|
15
|
-
units: ( Unit | ExtendedOption )[];
|
|
15
|
+
units: ( Unit | DegreeUnit | ExtendedOption )[];
|
|
16
16
|
onBlur?: ( event: React.FocusEvent< HTMLInputElement > ) => void;
|
|
17
17
|
onFocus?: ( event: React.FocusEvent< HTMLInputElement > ) => void;
|
|
18
18
|
onClick?: ( event: React.MouseEvent< HTMLInputElement > ) => void;
|
|
19
|
-
handleUnitChange: ( unit: Unit | ExtendedOption ) => void;
|
|
19
|
+
handleUnitChange: ( unit: Unit | DegreeUnit | ExtendedOption ) => void;
|
|
20
20
|
handleSizeChange: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
|
|
21
21
|
popupState: PopupState;
|
|
22
22
|
disabled?: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type RefObject } from 'react';
|
|
3
|
-
import { bindPopover,
|
|
3
|
+
import { bindPopover, Popover, type PopupState, TextField } from '@elementor/ui';
|
|
4
4
|
|
|
5
5
|
type Props = {
|
|
6
6
|
popupState: PopupState;
|
|
@@ -16,6 +16,15 @@ export const TextFieldPopover = ( props: Props ) => {
|
|
|
16
16
|
return (
|
|
17
17
|
<Popover
|
|
18
18
|
disablePortal
|
|
19
|
+
slotProps={ {
|
|
20
|
+
paper: {
|
|
21
|
+
sx: {
|
|
22
|
+
borderRadius: 2,
|
|
23
|
+
width: anchorRef.current?.offsetWidth + 'px',
|
|
24
|
+
p: 1.5,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
} }
|
|
19
28
|
{ ...bindPopover( popupState ) }
|
|
20
29
|
anchorOrigin={ { vertical: 'bottom', horizontal: 'center' } }
|
|
21
30
|
transformOrigin={ { vertical: 'top', horizontal: 'center' } }
|
|
@@ -24,24 +33,16 @@ export const TextFieldPopover = ( props: Props ) => {
|
|
|
24
33
|
popupState.close();
|
|
25
34
|
} }
|
|
26
35
|
>
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
<TextField
|
|
37
|
+
value={ value }
|
|
38
|
+
onChange={ onChange }
|
|
39
|
+
size="tiny"
|
|
40
|
+
type="text"
|
|
41
|
+
fullWidth
|
|
42
|
+
inputProps={ {
|
|
43
|
+
autoFocus: true,
|
|
32
44
|
} }
|
|
33
|
-
|
|
34
|
-
<TextField
|
|
35
|
-
value={ value }
|
|
36
|
-
onChange={ onChange }
|
|
37
|
-
size="tiny"
|
|
38
|
-
type="text"
|
|
39
|
-
fullWidth
|
|
40
|
-
inputProps={ {
|
|
41
|
-
autoFocus: true,
|
|
42
|
-
} }
|
|
43
|
-
/>
|
|
44
|
-
</Paper>
|
|
45
|
+
/>
|
|
45
46
|
</Popover>
|
|
46
47
|
);
|
|
47
48
|
};
|
package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx
CHANGED
|
@@ -7,12 +7,11 @@ import {
|
|
|
7
7
|
colorPropTypeUtil,
|
|
8
8
|
type PropKey,
|
|
9
9
|
} from '@elementor/editor-props';
|
|
10
|
-
import { Box, CardMedia,
|
|
10
|
+
import { Box, CardMedia, styled, Tab, TabPanel, Tabs, type Theme, UnstableColorIndicator } from '@elementor/ui';
|
|
11
11
|
import { useWpMediaAttachment } from '@elementor/wp-media';
|
|
12
12
|
import { __ } from '@wordpress/i18n';
|
|
13
13
|
|
|
14
14
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../../../bound-prop-context';
|
|
15
|
-
import { ControlFormLabel } from '../../../components/control-form-label';
|
|
16
15
|
import { PopoverContent } from '../../../components/popover-content';
|
|
17
16
|
import { Repeater } from '../../../components/repeater';
|
|
18
17
|
import { createControl } from '../../../create-control';
|
|
@@ -75,7 +74,7 @@ export const BackgroundOverlayRepeaterControl = createControl( () => {
|
|
|
75
74
|
const { propType, value: overlayValues, setValue, disabled } = useBoundProp( backgroundOverlayPropTypeUtil );
|
|
76
75
|
|
|
77
76
|
return (
|
|
78
|
-
<PropProvider propType={ propType } value={ overlayValues } setValue={ setValue }
|
|
77
|
+
<PropProvider propType={ propType } value={ overlayValues } setValue={ setValue } isDisabled={ () => disabled }>
|
|
79
78
|
<Repeater
|
|
80
79
|
openOnAdd
|
|
81
80
|
disabled={ disabled }
|
|
@@ -236,18 +235,7 @@ const ImageOverlayContent = () => {
|
|
|
236
235
|
return (
|
|
237
236
|
<PropProvider { ...propContext }>
|
|
238
237
|
<PropKeyProvider bind={ 'image' }>
|
|
239
|
-
<
|
|
240
|
-
<Grid item xs={ 12 }>
|
|
241
|
-
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
242
|
-
<Grid item xs={ 6 }>
|
|
243
|
-
<ControlFormLabel>{ __( 'Resolution', 'elementor' ) }</ControlFormLabel>
|
|
244
|
-
</Grid>
|
|
245
|
-
<Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
|
|
246
|
-
<ImageControl sizes={ backgroundResolutionOptions } />
|
|
247
|
-
</Grid>
|
|
248
|
-
</Grid>
|
|
249
|
-
</Grid>
|
|
250
|
-
</Grid>
|
|
238
|
+
<ImageControl sizes={ backgroundResolutionOptions } />
|
|
251
239
|
</PropKeyProvider>
|
|
252
240
|
<PropKeyProvider bind={ 'position' }>
|
|
253
241
|
<BackgroundImageOverlayPosition />
|
|
@@ -17,7 +17,7 @@ export const BoxShadowRepeaterControl = createControl( () => {
|
|
|
17
17
|
const { propType, value, setValue, disabled } = useBoundProp( boxShadowPropTypeUtil );
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
|
-
<PropProvider propType={ propType } value={ value } setValue={ setValue }
|
|
20
|
+
<PropProvider propType={ propType } value={ value } setValue={ setValue } isDisabled={ () => disabled }>
|
|
21
21
|
<Repeater
|
|
22
22
|
openOnAdd
|
|
23
23
|
disabled={ disabled }
|
|
@@ -13,7 +13,9 @@ 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, disabled } = useBoundProp( propTypeUtil );
|
|
16
|
+
const { value, setValue, placeholder: boundPropPlaceholder, disabled } = useBoundProp( propTypeUtil );
|
|
17
|
+
|
|
18
|
+
const placeholder = props.placeholder ?? boundPropPlaceholder;
|
|
17
19
|
|
|
18
20
|
const handleChange = ( selectedColor: string ) => {
|
|
19
21
|
setValue( selectedColor || null );
|
|
@@ -25,6 +27,7 @@ export const ColorControl = createControl(
|
|
|
25
27
|
size="tiny"
|
|
26
28
|
fullWidth
|
|
27
29
|
value={ value ?? '' }
|
|
30
|
+
placeholder={ placeholder ?? '' }
|
|
28
31
|
onChange={ handleChange }
|
|
29
32
|
{ ...props }
|
|
30
33
|
disabled={ disabled }
|
|
@@ -40,6 +43,14 @@ export const ColorControl = createControl(
|
|
|
40
43
|
vertical: 'top',
|
|
41
44
|
horizontal: -10,
|
|
42
45
|
},
|
|
46
|
+
slotProps: {
|
|
47
|
+
colorIndicator: {
|
|
48
|
+
value: value ?? placeholder ?? '',
|
|
49
|
+
},
|
|
50
|
+
colorBox: {
|
|
51
|
+
value: value ?? placeholder ?? '',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
43
54
|
},
|
|
44
55
|
} }
|
|
45
56
|
/>
|
|
@@ -154,7 +154,7 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
|
|
|
154
154
|
propType={ multiSizePropType }
|
|
155
155
|
value={ getMultiSizeValues() }
|
|
156
156
|
setValue={ setNestedProp }
|
|
157
|
-
|
|
157
|
+
isDisabled={ () => multiSizeDisabled }
|
|
158
158
|
>
|
|
159
159
|
<PopoverContent p={ 1.5 }>
|
|
160
160
|
<PopoverGridContainer ref={ rowRefs[ 1 ] }>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import { type DropShadowFilterPropValue, type PropTypeUtil } from '@elementor/editor-props';
|
|
4
|
+
import { Grid } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../../bound-prop-context';
|
|
8
|
+
import { ControlFormLabel } from '../../components/control-form-label';
|
|
9
|
+
import { PopoverGridContainer } from '../../components/popover-grid-container';
|
|
10
|
+
import { type Unit } from '../../utils/size-control';
|
|
11
|
+
import { ColorControl } from '../color-control';
|
|
12
|
+
import { SizeControl } from '../size-control';
|
|
13
|
+
|
|
14
|
+
const items = [
|
|
15
|
+
{
|
|
16
|
+
bind: 'xAxis',
|
|
17
|
+
label: __( 'X-axis', 'elementor' ),
|
|
18
|
+
rowIndex: 0,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
bind: 'yAxis',
|
|
22
|
+
label: __( 'Y-axis', 'elementor' ),
|
|
23
|
+
rowIndex: 0,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
bind: 'blur',
|
|
27
|
+
label: __( 'Blur', 'elementor' ),
|
|
28
|
+
rowIndex: 1,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
bind: 'color',
|
|
32
|
+
label: __( 'Color', 'elementor' ),
|
|
33
|
+
rowIndex: 1,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export const DropShadowItemContent = ( {
|
|
38
|
+
propType,
|
|
39
|
+
units,
|
|
40
|
+
anchorEl,
|
|
41
|
+
}: {
|
|
42
|
+
propType: PropTypeUtil< 'drop-shadow', DropShadowFilterPropValue[ 'value' ] >;
|
|
43
|
+
units: Unit[];
|
|
44
|
+
anchorEl?: HTMLElement | null;
|
|
45
|
+
} ) => {
|
|
46
|
+
const context = useBoundProp( propType );
|
|
47
|
+
const rowRefs = [ useRef< HTMLDivElement >( null ), useRef< HTMLDivElement >( null ) ];
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<PropProvider { ...context }>
|
|
51
|
+
{ items.map( ( item ) => (
|
|
52
|
+
<PopoverGridContainer key={ item.bind } ref={ rowRefs[ item.rowIndex ] ?? null }>
|
|
53
|
+
<PropKeyProvider bind={ item.bind }>
|
|
54
|
+
<Grid item xs={ 6 }>
|
|
55
|
+
<ControlFormLabel>{ item.label }</ControlFormLabel>
|
|
56
|
+
</Grid>
|
|
57
|
+
<Grid item xs={ 6 }>
|
|
58
|
+
{ item.bind === 'color' ? (
|
|
59
|
+
<ColorControl anchorEl={ anchorEl } />
|
|
60
|
+
) : (
|
|
61
|
+
<SizeControl anchorRef={ rowRefs[ item.rowIndex ] } units={ units } defaultUnit="px" />
|
|
62
|
+
) }
|
|
63
|
+
</Grid>
|
|
64
|
+
</PropKeyProvider>
|
|
65
|
+
</PopoverGridContainer>
|
|
66
|
+
) ) }
|
|
67
|
+
</PropProvider>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type FilterItemPropValue } from '@elementor/editor-props';
|
|
3
|
+
import { Box } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
export const DropShadowItemLabel = ( { value }: { value: FilterItemPropValue } ) => {
|
|
6
|
+
const { xAxis, yAxis, blur } = value.value;
|
|
7
|
+
|
|
8
|
+
const xValue = `${ xAxis?.value?.size ?? 0 }${ xAxis?.value?.unit ?? 'px' }`;
|
|
9
|
+
const yValue = `${ yAxis?.value?.size ?? 0 }${ yAxis?.value?.unit ?? 'px' }`;
|
|
10
|
+
const blurValue = `${ blur?.value?.size ?? 10 }${ blur?.value?.unit ?? 'px' }`;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Box component="span">
|
|
14
|
+
<Box component="span" style={ { textTransform: 'capitalize' } }>
|
|
15
|
+
Drop shadow:
|
|
16
|
+
</Box>
|
|
17
|
+
{ `${ xValue } ${ yValue } ${ blurValue }` }
|
|
18
|
+
</Box>
|
|
19
|
+
);
|
|
20
|
+
};
|