@elementor/editor-controls 0.10.0 → 0.12.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 +22 -0
- package/dist/index.d.mts +3 -25
- package/dist/index.d.ts +3 -25
- package/dist/index.js +427 -403
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +400 -369
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/components/autocomplete.tsx +181 -0
- package/src/components/popover-content.tsx +15 -0
- package/src/components/popover-grid-container.tsx +20 -0
- package/src/components/repeater.tsx +6 -4
- package/src/components/section-content.tsx +16 -0
- package/src/controls/background-control/background-control.tsx +4 -3
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-attachment.tsx +4 -3
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-position.tsx +15 -14
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-repeat.tsx +3 -2
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-size.tsx +5 -4
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +4 -3
- package/src/controls/box-shadow-repeater-control.tsx +12 -10
- package/src/controls/equal-unequal-sizes-control.tsx +9 -7
- package/src/controls/font-family-control.tsx +4 -2
- package/src/controls/gap-control.tsx +1 -1
- package/src/controls/image-control.tsx +2 -2
- package/src/controls/image-media-control.tsx +2 -2
- package/src/controls/link-control.tsx +65 -49
- package/src/controls/linked-dimensions-control.tsx +1 -1
- package/src/controls/select-control.tsx +8 -1
- package/src/controls/size-control.tsx +3 -1
- package/src/controls/stroke-control.tsx +6 -5
- package/src/index.ts +0 -1
- package/src/controls/autocomplete-control.tsx +0 -195
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.12.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-props": "0.9.
|
|
43
|
+
"@elementor/editor-props": "0.9.2",
|
|
44
44
|
"@elementor/env": "0.3.5",
|
|
45
45
|
"@elementor/http": "0.1.3",
|
|
46
46
|
"@elementor/icons": "1.31.0",
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { XIcon } from '@elementor/icons';
|
|
4
|
+
import {
|
|
5
|
+
Autocomplete as AutocompleteBase,
|
|
6
|
+
type AutocompleteRenderInputParams,
|
|
7
|
+
Box,
|
|
8
|
+
IconButton,
|
|
9
|
+
InputAdornment,
|
|
10
|
+
TextField,
|
|
11
|
+
} from '@elementor/ui';
|
|
12
|
+
|
|
13
|
+
export type FlatOption = {
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
groupLabel?: never;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type CategorizedOption = {
|
|
20
|
+
id: string;
|
|
21
|
+
label: string;
|
|
22
|
+
groupLabel: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type Props = {
|
|
26
|
+
options: FlatOption[] | CategorizedOption[];
|
|
27
|
+
value?: number | string | null;
|
|
28
|
+
onOptionChange: ( newValue: number | null ) => void;
|
|
29
|
+
onTextChange?: ( newValue: string | null ) => void;
|
|
30
|
+
allowCustomValues?: boolean;
|
|
31
|
+
placeholder?: string;
|
|
32
|
+
minInputLength?: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const Autocomplete = forwardRef( ( props: Props, ref ) => {
|
|
36
|
+
const {
|
|
37
|
+
options,
|
|
38
|
+
onOptionChange,
|
|
39
|
+
onTextChange,
|
|
40
|
+
allowCustomValues = false,
|
|
41
|
+
placeholder = '',
|
|
42
|
+
minInputLength = 2,
|
|
43
|
+
value = '',
|
|
44
|
+
...restProps
|
|
45
|
+
} = props;
|
|
46
|
+
|
|
47
|
+
const optionKeys = _factoryFilter( value, options, minInputLength ).map( ( { id } ) => id );
|
|
48
|
+
const allowClear = !! value;
|
|
49
|
+
|
|
50
|
+
// Prevents MUI warning when freeSolo/allowCustomValues is false
|
|
51
|
+
const muiWarningPreventer = allowCustomValues || !! value?.toString()?.length;
|
|
52
|
+
|
|
53
|
+
const isOptionEqualToValue = muiWarningPreventer ? undefined : () => true;
|
|
54
|
+
|
|
55
|
+
const isValueFromOptions = typeof value === 'number' && !! findMatchingOption( options, value );
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<AutocompleteBase
|
|
59
|
+
{ ...restProps }
|
|
60
|
+
ref={ ref }
|
|
61
|
+
forcePopupIcon={ false }
|
|
62
|
+
disableClearable={ true } // Disabled component's auto clear icon to use our custom one instead
|
|
63
|
+
freeSolo={ allowCustomValues }
|
|
64
|
+
value={ value?.toString() || '' }
|
|
65
|
+
size={ 'tiny' }
|
|
66
|
+
onChange={ ( _, newValue ) => onOptionChange( Number( newValue ) ) }
|
|
67
|
+
readOnly={ isValueFromOptions }
|
|
68
|
+
options={ optionKeys }
|
|
69
|
+
getOptionKey={ ( optionId ) => findMatchingOption( options, optionId )?.id || optionId }
|
|
70
|
+
getOptionLabel={ ( optionId ) => findMatchingOption( options, optionId )?.label || optionId.toString() }
|
|
71
|
+
groupBy={
|
|
72
|
+
isCategorizedOptionPool( options )
|
|
73
|
+
? ( optionId: string ) => findMatchingOption( options, optionId )?.groupLabel || optionId
|
|
74
|
+
: undefined
|
|
75
|
+
}
|
|
76
|
+
isOptionEqualToValue={ isOptionEqualToValue }
|
|
77
|
+
filterOptions={ () => optionKeys }
|
|
78
|
+
renderOption={ ( optionProps, optionId ) => (
|
|
79
|
+
<Box component="li" { ...optionProps } key={ optionProps.id }>
|
|
80
|
+
{ findMatchingOption( options, optionId )?.label ?? optionId }
|
|
81
|
+
</Box>
|
|
82
|
+
) }
|
|
83
|
+
renderInput={ ( params ) => (
|
|
84
|
+
<TextInput
|
|
85
|
+
params={ params }
|
|
86
|
+
handleChange={ ( newValue ) => onTextChange?.( newValue ) }
|
|
87
|
+
allowClear={ allowClear }
|
|
88
|
+
placeholder={ placeholder }
|
|
89
|
+
hasSelectedValue={ isValueFromOptions }
|
|
90
|
+
/>
|
|
91
|
+
) }
|
|
92
|
+
/>
|
|
93
|
+
);
|
|
94
|
+
} );
|
|
95
|
+
|
|
96
|
+
const TextInput = ( {
|
|
97
|
+
params,
|
|
98
|
+
allowClear,
|
|
99
|
+
placeholder,
|
|
100
|
+
handleChange,
|
|
101
|
+
hasSelectedValue,
|
|
102
|
+
}: {
|
|
103
|
+
params: AutocompleteRenderInputParams;
|
|
104
|
+
allowClear: boolean;
|
|
105
|
+
handleChange: ( newValue: string | null ) => void;
|
|
106
|
+
placeholder: string;
|
|
107
|
+
hasSelectedValue: boolean;
|
|
108
|
+
} ) => {
|
|
109
|
+
const onChange = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
110
|
+
handleChange( event.target.value );
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<TextField
|
|
115
|
+
{ ...params }
|
|
116
|
+
placeholder={ placeholder }
|
|
117
|
+
onChange={ onChange }
|
|
118
|
+
sx={ {
|
|
119
|
+
'& .MuiInputBase-input': {
|
|
120
|
+
cursor: hasSelectedValue ? 'default' : undefined,
|
|
121
|
+
},
|
|
122
|
+
} }
|
|
123
|
+
InputProps={ {
|
|
124
|
+
...params.InputProps,
|
|
125
|
+
endAdornment: <ClearButton params={ params } allowClear={ allowClear } handleChange={ handleChange } />,
|
|
126
|
+
} }
|
|
127
|
+
/>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const ClearButton = ( {
|
|
132
|
+
allowClear,
|
|
133
|
+
handleChange,
|
|
134
|
+
params,
|
|
135
|
+
}: {
|
|
136
|
+
params: AutocompleteRenderInputParams;
|
|
137
|
+
allowClear: boolean;
|
|
138
|
+
handleChange: ( newValue: string | null ) => void;
|
|
139
|
+
} ) => (
|
|
140
|
+
<InputAdornment position="end">
|
|
141
|
+
{ allowClear && (
|
|
142
|
+
<IconButton size={ params.size } onClick={ () => handleChange( null ) } sx={ { cursor: 'pointer' } }>
|
|
143
|
+
<XIcon fontSize={ params.size } />
|
|
144
|
+
</IconButton>
|
|
145
|
+
) }
|
|
146
|
+
</InputAdornment>
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
export function findMatchingOption(
|
|
150
|
+
options: FlatOption[] | CategorizedOption[],
|
|
151
|
+
optionId: string | number | null = null
|
|
152
|
+
) {
|
|
153
|
+
const formattedOption = ( optionId || '' ).toString();
|
|
154
|
+
|
|
155
|
+
return options.find( ( { id } ) => formattedOption === id.toString() );
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function isCategorizedOptionPool( options: FlatOption[] | CategorizedOption[] ): options is CategorizedOption[] {
|
|
159
|
+
return options.every( ( option ) => 'groupLabel' in option );
|
|
160
|
+
}
|
|
161
|
+
function _factoryFilter< T extends FlatOption[] | CategorizedOption[] >(
|
|
162
|
+
newValue: string | number | null,
|
|
163
|
+
options: T,
|
|
164
|
+
minInputLength: number
|
|
165
|
+
): T {
|
|
166
|
+
if ( null === newValue ) {
|
|
167
|
+
return options;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const formattedValue = String( newValue || '' )?.toLowerCase();
|
|
171
|
+
|
|
172
|
+
if ( formattedValue.length < minInputLength ) {
|
|
173
|
+
return new Array( 0 ) as T;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return options.filter(
|
|
177
|
+
( option ) =>
|
|
178
|
+
String( option.id ).toLowerCase().includes( formattedValue ) ||
|
|
179
|
+
option.label.toLowerCase().includes( formattedValue )
|
|
180
|
+
) as T;
|
|
181
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FC, type PropsWithChildren } from 'react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Stack } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
type PopoverContentProps = PropsWithChildren< {
|
|
6
|
+
alignItems?: 'center';
|
|
7
|
+
gap?: number;
|
|
8
|
+
p?: 1.5 | 2 | 2.5;
|
|
9
|
+
} >;
|
|
10
|
+
|
|
11
|
+
export const PopoverContent: FC< PopoverContentProps > = ( { alignItems, gap = 1.5, p, children } ) => (
|
|
12
|
+
<Stack alignItems={ alignItems } gap={ gap } p={ p }>
|
|
13
|
+
{ children }
|
|
14
|
+
</Stack>
|
|
15
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type FC, type PropsWithChildren } from 'react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Grid } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
type PopoverGridContainerProps = PropsWithChildren< {
|
|
6
|
+
gap?: number;
|
|
7
|
+
alignItems?: React.ComponentProps< typeof Grid >[ 'alignItems' ];
|
|
8
|
+
flexWrap?: React.ComponentProps< typeof Grid >[ 'flexWrap' ];
|
|
9
|
+
} >;
|
|
10
|
+
|
|
11
|
+
export const PopoverGridContainer: FC< PopoverGridContainerProps > = ( {
|
|
12
|
+
gap = 1.5,
|
|
13
|
+
alignItems = 'center',
|
|
14
|
+
flexWrap = 'nowrap',
|
|
15
|
+
children,
|
|
16
|
+
} ) => (
|
|
17
|
+
<Grid container gap={ gap } alignItems={ alignItems } flexWrap={ flexWrap }>
|
|
18
|
+
{ children }
|
|
19
|
+
</Grid>
|
|
20
|
+
);
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
} from '@elementor/ui';
|
|
17
17
|
import { __ } from '@wordpress/i18n';
|
|
18
18
|
|
|
19
|
+
import { SectionContent } from './section-content';
|
|
20
|
+
|
|
19
21
|
const SIZE = 'tiny';
|
|
20
22
|
|
|
21
23
|
type AnchorEl = HTMLElement | null;
|
|
@@ -86,8 +88,8 @@ export const Repeater = < T, >( {
|
|
|
86
88
|
};
|
|
87
89
|
|
|
88
90
|
return (
|
|
89
|
-
<
|
|
90
|
-
<Stack direction="row" justifyContent="space-between" alignItems="center"
|
|
91
|
+
<SectionContent>
|
|
92
|
+
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
|
91
93
|
<Typography component="label" variant="caption" color="text.secondary">
|
|
92
94
|
{ label }
|
|
93
95
|
</Typography>
|
|
@@ -95,7 +97,7 @@ export const Repeater = < T, >( {
|
|
|
95
97
|
<PlusIcon fontSize={ SIZE } />
|
|
96
98
|
</IconButton>
|
|
97
99
|
</Stack>
|
|
98
|
-
<Stack gap={ 1 }>
|
|
100
|
+
<Stack gap={ 1 } sx={ { '&:empty': { display: 'none' } } }>
|
|
99
101
|
{ repeaterValues.map( ( value, index ) => (
|
|
100
102
|
<RepeaterItem
|
|
101
103
|
key={ index }
|
|
@@ -111,7 +113,7 @@ export const Repeater = < T, >( {
|
|
|
111
113
|
</RepeaterItem>
|
|
112
114
|
) ) }
|
|
113
115
|
</Stack>
|
|
114
|
-
</
|
|
116
|
+
</SectionContent>
|
|
115
117
|
);
|
|
116
118
|
};
|
|
117
119
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type FC, type PropsWithChildren } from 'react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Stack } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
type SectionContentProps = PropsWithChildren< {
|
|
6
|
+
gap?: number;
|
|
7
|
+
sx?: {
|
|
8
|
+
pt?: number;
|
|
9
|
+
};
|
|
10
|
+
} >;
|
|
11
|
+
|
|
12
|
+
export const SectionContent: FC< SectionContentProps > = ( { gap = 2, sx, children } ) => (
|
|
13
|
+
<Stack gap={ gap } sx={ { ...sx } }>
|
|
14
|
+
{ children }
|
|
15
|
+
</Stack>
|
|
16
|
+
);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { backgroundPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
-
import { Grid
|
|
3
|
+
import { Grid } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
6
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../../bound-prop-context';
|
|
7
7
|
import { ControlLabel } from '../../components/control-label';
|
|
8
|
+
import { SectionContent } from '../../components/section-content';
|
|
8
9
|
import { createControl } from '../../create-control';
|
|
9
10
|
import { ColorControl } from '../color-control';
|
|
10
11
|
import { BackgroundOverlayRepeaterControl } from './background-overlay/background-overlay-repeater-control';
|
|
@@ -14,7 +15,7 @@ export const BackgroundControl = createControl( () => {
|
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
17
|
<PropProvider { ...propContext }>
|
|
17
|
-
<
|
|
18
|
+
<SectionContent>
|
|
18
19
|
<PropKeyProvider bind="background-overlay">
|
|
19
20
|
<BackgroundOverlayRepeaterControl />
|
|
20
21
|
</PropKeyProvider>
|
|
@@ -28,7 +29,7 @@ export const BackgroundControl = createControl( () => {
|
|
|
28
29
|
</Grid>
|
|
29
30
|
</Grid>
|
|
30
31
|
</PropKeyProvider>
|
|
31
|
-
</
|
|
32
|
+
</SectionContent>
|
|
32
33
|
</PropProvider>
|
|
33
34
|
);
|
|
34
35
|
} );
|
|
@@ -5,6 +5,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
|
|
6
6
|
import { ControlLabel } from '../../../../components/control-label';
|
|
7
7
|
import { type ToggleButtonGroupItem } from '../../../../components/control-toggle-button-group';
|
|
8
|
+
import { PopoverGridContainer } from '../../../../components/popover-grid-container';
|
|
8
9
|
import { ToggleControl } from '../../../toggle-control';
|
|
9
10
|
|
|
10
11
|
type Attachment = 'fixed' | 'scroll';
|
|
@@ -26,13 +27,13 @@ const attachmentControlOptions: ToggleButtonGroupItem< Attachment >[] = [
|
|
|
26
27
|
|
|
27
28
|
export const BackgroundImageOverlayAttachment = () => {
|
|
28
29
|
return (
|
|
29
|
-
<
|
|
30
|
+
<PopoverGridContainer>
|
|
30
31
|
<Grid item xs={ 6 }>
|
|
31
32
|
<ControlLabel>{ __( 'Attachment', 'elementor' ) }</ControlLabel>
|
|
32
33
|
</Grid>
|
|
33
|
-
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end' } }>
|
|
34
|
+
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end', overflow: 'hidden' } }>
|
|
34
35
|
<ToggleControl options={ attachmentControlOptions } />
|
|
35
36
|
</Grid>
|
|
36
|
-
</
|
|
37
|
+
</PopoverGridContainer>
|
|
37
38
|
);
|
|
38
39
|
};
|
|
@@ -6,6 +6,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
6
6
|
|
|
7
7
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../../../../bound-prop-context';
|
|
8
8
|
import { ControlLabel } from '../../../../components/control-label';
|
|
9
|
+
import { PopoverGridContainer } from '../../../../components/popover-grid-container';
|
|
9
10
|
import { SizeControl } from '../../../size-control';
|
|
10
11
|
|
|
11
12
|
type Positions =
|
|
@@ -21,15 +22,15 @@ type Positions =
|
|
|
21
22
|
| 'custom';
|
|
22
23
|
|
|
23
24
|
const backgroundPositionOptions = [
|
|
24
|
-
{ label: __( 'Center
|
|
25
|
-
{ label: __( 'Center
|
|
26
|
-
{ label: __( 'Center
|
|
27
|
-
{ label: __( 'Top
|
|
28
|
-
{ label: __( 'Top
|
|
29
|
-
{ label: __( 'Top
|
|
30
|
-
{ label: __( 'Bottom
|
|
31
|
-
{ label: __( 'Bottom
|
|
32
|
-
{ label: __( 'Bottom
|
|
25
|
+
{ label: __( 'Center center', 'elementor' ), value: 'center center' },
|
|
26
|
+
{ label: __( 'Center left', 'elementor' ), value: 'center left' },
|
|
27
|
+
{ label: __( 'Center right', 'elementor' ), value: 'center right' },
|
|
28
|
+
{ label: __( 'Top center', 'elementor' ), value: 'top center' },
|
|
29
|
+
{ label: __( 'Top left', 'elementor' ), value: 'top left' },
|
|
30
|
+
{ label: __( 'Top right', 'elementor' ), value: 'top right' },
|
|
31
|
+
{ label: __( 'Bottom center', 'elementor' ), value: 'bottom center' },
|
|
32
|
+
{ label: __( 'Bottom left', 'elementor' ), value: 'bottom left' },
|
|
33
|
+
{ label: __( 'Bottom right', 'elementor' ), value: 'bottom right' },
|
|
33
34
|
{ label: __( 'Custom', 'elementor' ), value: 'custom' },
|
|
34
35
|
];
|
|
35
36
|
|
|
@@ -50,13 +51,13 @@ export const BackgroundImageOverlayPosition = () => {
|
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
return (
|
|
53
|
-
<Grid container spacing={
|
|
54
|
+
<Grid container spacing={ 1.5 }>
|
|
54
55
|
<Grid item xs={ 12 }>
|
|
55
|
-
<
|
|
56
|
+
<PopoverGridContainer>
|
|
56
57
|
<Grid item xs={ 6 }>
|
|
57
58
|
<ControlLabel>{ __( 'Position', 'elementor' ) }</ControlLabel>
|
|
58
59
|
</Grid>
|
|
59
|
-
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end' } }>
|
|
60
|
+
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end', overflow: 'hidden' } }>
|
|
60
61
|
<Select
|
|
61
62
|
size="tiny"
|
|
62
63
|
value={ ( backgroundImageOffsetContext.value ? 'custom' : stringPropContext.value ) ?? '' }
|
|
@@ -70,12 +71,12 @@ export const BackgroundImageOverlayPosition = () => {
|
|
|
70
71
|
) ) }
|
|
71
72
|
</Select>
|
|
72
73
|
</Grid>
|
|
73
|
-
</
|
|
74
|
+
</PopoverGridContainer>
|
|
74
75
|
</Grid>
|
|
75
76
|
{ isCustom ? (
|
|
76
77
|
<PropProvider { ...backgroundImageOffsetContext }>
|
|
77
78
|
<Grid item xs={ 12 }>
|
|
78
|
-
<Grid container spacing={
|
|
79
|
+
<Grid container spacing={ 1.5 }>
|
|
79
80
|
<Grid item xs={ 6 }>
|
|
80
81
|
<PropKeyProvider bind={ 'x' }>
|
|
81
82
|
<SizeControl startIcon={ <LetterXIcon fontSize={ 'tiny' } /> } />
|
|
@@ -5,6 +5,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
|
|
6
6
|
import { ControlLabel } from '../../../../components/control-label';
|
|
7
7
|
import { type ToggleButtonGroupItem } from '../../../../components/control-toggle-button-group';
|
|
8
|
+
import { PopoverGridContainer } from '../../../../components/popover-grid-container';
|
|
8
9
|
import { ToggleControl } from '../../../toggle-control';
|
|
9
10
|
|
|
10
11
|
type Repeaters = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';
|
|
@@ -38,13 +39,13 @@ const repeatControlOptions: ToggleButtonGroupItem< Repeaters >[] = [
|
|
|
38
39
|
|
|
39
40
|
export const BackgroundImageOverlayRepeat = () => {
|
|
40
41
|
return (
|
|
41
|
-
<
|
|
42
|
+
<PopoverGridContainer>
|
|
42
43
|
<Grid item xs={ 6 }>
|
|
43
44
|
<ControlLabel>{ __( 'Repeat', 'elementor' ) }</ControlLabel>
|
|
44
45
|
</Grid>
|
|
45
46
|
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end' } }>
|
|
46
47
|
<ToggleControl options={ repeatControlOptions } />
|
|
47
48
|
</Grid>
|
|
48
|
-
</
|
|
49
|
+
</PopoverGridContainer>
|
|
49
50
|
);
|
|
50
51
|
};
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
ControlToggleButtonGroup,
|
|
18
18
|
type ToggleButtonGroupItem,
|
|
19
19
|
} from '../../../../components/control-toggle-button-group';
|
|
20
|
+
import { PopoverGridContainer } from '../../../../components/popover-grid-container';
|
|
20
21
|
import { SizeControl } from '../../../size-control';
|
|
21
22
|
|
|
22
23
|
type Sizes = 'auto' | 'cover' | 'contain' | 'custom';
|
|
@@ -65,7 +66,7 @@ export const BackgroundImageOverlaySize = () => {
|
|
|
65
66
|
return (
|
|
66
67
|
<Grid container spacing={ 1.5 }>
|
|
67
68
|
<Grid item xs={ 12 }>
|
|
68
|
-
<
|
|
69
|
+
<PopoverGridContainer>
|
|
69
70
|
<Grid item xs={ 6 }>
|
|
70
71
|
<ControlLabel>{ __( 'Size', 'elementor' ) }</ControlLabel>
|
|
71
72
|
</Grid>
|
|
@@ -79,12 +80,12 @@ export const BackgroundImageOverlaySize = () => {
|
|
|
79
80
|
onChange={ handleSizeChange }
|
|
80
81
|
/>
|
|
81
82
|
</Grid>
|
|
82
|
-
</
|
|
83
|
+
</PopoverGridContainer>
|
|
83
84
|
</Grid>
|
|
84
85
|
{ isCustom ? (
|
|
85
86
|
<PropProvider { ...backgroundImageScaleContext }>
|
|
86
87
|
<Grid item xs={ 12 }>
|
|
87
|
-
<
|
|
88
|
+
<PopoverGridContainer>
|
|
88
89
|
<Grid item xs={ 6 }>
|
|
89
90
|
<PropKeyProvider bind={ 'width' }>
|
|
90
91
|
<SizeControl startIcon={ <ArrowsMoveHorizontalIcon fontSize={ 'tiny' } /> } />
|
|
@@ -95,7 +96,7 @@ export const BackgroundImageOverlaySize = () => {
|
|
|
95
96
|
<SizeControl startIcon={ <ArrowsMoveVerticalIcon fontSize={ 'tiny' } /> } />
|
|
96
97
|
</PropKeyProvider>
|
|
97
98
|
</Grid>
|
|
98
|
-
</
|
|
99
|
+
</PopoverGridContainer>
|
|
99
100
|
</Grid>
|
|
100
101
|
</PropProvider>
|
|
101
102
|
) : null }
|
package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx
CHANGED
|
@@ -6,11 +6,12 @@ import {
|
|
|
6
6
|
backgroundOverlayPropTypeUtil,
|
|
7
7
|
type PropKey,
|
|
8
8
|
} from '@elementor/editor-props';
|
|
9
|
-
import { Box, CardMedia, Grid,
|
|
9
|
+
import { Box, CardMedia, Grid, Tab, TabPanel, Tabs, UnstableColorIndicator } from '@elementor/ui';
|
|
10
10
|
import { useWpMediaAttachment } from '@elementor/wp-media';
|
|
11
11
|
import { __ } from '@wordpress/i18n';
|
|
12
12
|
|
|
13
13
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../../../bound-prop-context';
|
|
14
|
+
import { PopoverContent } from '../../../components/popover-content';
|
|
14
15
|
import { Repeater } from '../../../components/repeater';
|
|
15
16
|
import { createControl } from '../../../create-control';
|
|
16
17
|
import { env } from '../../../env';
|
|
@@ -103,9 +104,9 @@ const Content = () => {
|
|
|
103
104
|
</Tabs>
|
|
104
105
|
</Box>
|
|
105
106
|
<TabPanel sx={ { p: 1.5 } } { ...getTabPanelProps( 'image' ) }>
|
|
106
|
-
<
|
|
107
|
+
<PopoverContent>
|
|
107
108
|
<ImageOverlayContent />
|
|
108
|
-
</
|
|
109
|
+
</PopoverContent>
|
|
109
110
|
</TabPanel>
|
|
110
111
|
<TabPanel { ...getTabPanelProps( 'color' ) } sx={ { p: 1.5 } }>
|
|
111
112
|
<Grid container spacing={ 1 } alignItems="center">
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { boxShadowPropTypeUtil, type PropKey, shadowPropTypeUtil, type ShadowPropValue } from '@elementor/editor-props';
|
|
3
|
-
import { Grid,
|
|
3
|
+
import { Grid, Typography, UnstableColorIndicator } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
6
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
7
|
+
import { PopoverContent } from '../components/popover-content';
|
|
8
|
+
import { PopoverGridContainer } from '../components/popover-grid-container';
|
|
7
9
|
import { Repeater } from '../components/repeater';
|
|
8
10
|
import { createControl } from '../create-control';
|
|
9
11
|
import { ColorControl } from './color-control';
|
|
@@ -47,8 +49,8 @@ const Content = ( { anchorEl }: { anchorEl: HTMLElement | null } ) => {
|
|
|
47
49
|
|
|
48
50
|
return (
|
|
49
51
|
<PropProvider propType={ propType } value={ value } setValue={ setValue }>
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
+
<PopoverContent p={ 1.5 }>
|
|
53
|
+
<PopoverGridContainer>
|
|
52
54
|
<Control bind="color" label={ __( 'Color', 'elementor' ) }>
|
|
53
55
|
<ColorControl
|
|
54
56
|
slotProps={ {
|
|
@@ -74,31 +76,31 @@ const Content = ( { anchorEl }: { anchorEl: HTMLElement | null } ) => {
|
|
|
74
76
|
] }
|
|
75
77
|
/>
|
|
76
78
|
</Control>
|
|
77
|
-
</
|
|
78
|
-
<
|
|
79
|
+
</PopoverGridContainer>
|
|
80
|
+
<PopoverGridContainer>
|
|
79
81
|
<Control bind="hOffset" label={ __( 'Horizontal', 'elementor' ) }>
|
|
80
82
|
<SizeControl />
|
|
81
83
|
</Control>
|
|
82
84
|
<Control bind="vOffset" label={ __( 'Vertical', 'elementor' ) }>
|
|
83
85
|
<SizeControl />
|
|
84
86
|
</Control>
|
|
85
|
-
</
|
|
86
|
-
<
|
|
87
|
+
</PopoverGridContainer>
|
|
88
|
+
<PopoverGridContainer>
|
|
87
89
|
<Control bind="blur" label={ __( 'Blur', 'elementor' ) }>
|
|
88
90
|
<SizeControl />
|
|
89
91
|
</Control>
|
|
90
92
|
<Control bind="spread" label={ __( 'Spread', 'elementor' ) }>
|
|
91
93
|
<SizeControl />
|
|
92
94
|
</Control>
|
|
93
|
-
</
|
|
94
|
-
</
|
|
95
|
+
</PopoverGridContainer>
|
|
96
|
+
</PopoverContent>
|
|
95
97
|
</PropProvider>
|
|
96
98
|
);
|
|
97
99
|
};
|
|
98
100
|
|
|
99
101
|
const Control = ( { label, bind, children }: { bind: string; label: string; children: React.ReactNode } ) => (
|
|
100
102
|
<PropKeyProvider bind={ bind }>
|
|
101
|
-
<Grid item xs={ 6 }>
|
|
103
|
+
<Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
|
|
102
104
|
<Grid container gap={ 1 } alignItems="center">
|
|
103
105
|
<Grid item xs={ 12 }>
|
|
104
106
|
<Typography component="label" variant="caption" color="text.secondary">
|
|
@@ -6,6 +6,8 @@ import { __ } from '@wordpress/i18n';
|
|
|
6
6
|
|
|
7
7
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
8
8
|
import { ControlLabel } from '../components/control-label';
|
|
9
|
+
import { PopoverContent } from '../components/popover-content';
|
|
10
|
+
import { PopoverGridContainer } from '../components/popover-grid-container';
|
|
9
11
|
import { SizeControl } from './size-control';
|
|
10
12
|
|
|
11
13
|
type MultiSizePropValue = Record< PropKey, SizePropValue >;
|
|
@@ -127,20 +129,20 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
|
|
|
127
129
|
} }
|
|
128
130
|
{ ...bindPopover( popupState ) }
|
|
129
131
|
slotProps={ {
|
|
130
|
-
paper: { sx: { mt: 0.5,
|
|
132
|
+
paper: { sx: { mt: 0.5, width: controlRef.current?.getBoundingClientRect().width } },
|
|
131
133
|
} }
|
|
132
134
|
>
|
|
133
135
|
<PropProvider propType={ multiSizePropType } value={ getMultiSizeValues() } setValue={ setNestedProp }>
|
|
134
|
-
<
|
|
135
|
-
<
|
|
136
|
+
<PopoverContent p={ 1.5 }>
|
|
137
|
+
<PopoverGridContainer>
|
|
136
138
|
<MultiSizeValueControl item={ items[ 0 ] } />
|
|
137
139
|
<MultiSizeValueControl item={ items[ 1 ] } />
|
|
138
|
-
</
|
|
139
|
-
<
|
|
140
|
+
</PopoverGridContainer>
|
|
141
|
+
<PopoverGridContainer>
|
|
140
142
|
<MultiSizeValueControl item={ items[ 3 ] } />
|
|
141
143
|
<MultiSizeValueControl item={ items[ 2 ] } />
|
|
142
|
-
</
|
|
143
|
-
</
|
|
144
|
+
</PopoverGridContainer>
|
|
145
|
+
</PopoverContent>
|
|
144
146
|
</PropProvider>
|
|
145
147
|
</Popover>
|
|
146
148
|
</>
|
|
@@ -99,7 +99,9 @@ export const FontFamilyControl = createControl( ( { fontFamilies } ) => {
|
|
|
99
99
|
<MenuList role="listbox" tabIndex={ 0 }>
|
|
100
100
|
{ filteredFontFamilies.map( ( [ category, items ], index ) => (
|
|
101
101
|
<Fragment key={ index }>
|
|
102
|
-
<ListSubheader
|
|
102
|
+
<ListSubheader
|
|
103
|
+
sx={ { px: 1.5, typography: 'caption', color: 'text.tertiary' } }
|
|
104
|
+
>
|
|
103
105
|
{ category }
|
|
104
106
|
</ListSubheader>
|
|
105
107
|
{ items.map( ( item ) => {
|
|
@@ -115,7 +117,7 @@ export const FontFamilyControl = createControl( ( { fontFamilies } ) => {
|
|
|
115
117
|
setFontFamily( item );
|
|
116
118
|
handleClose();
|
|
117
119
|
} }
|
|
118
|
-
sx={ { typography: 'caption' } }
|
|
120
|
+
sx={ { px: 1.5, typography: 'caption' } }
|
|
119
121
|
style={ { fontFamily: item } }
|
|
120
122
|
>
|
|
121
123
|
{ item }
|
|
@@ -40,7 +40,7 @@ export const GapControl = createControl( ( { label }: { label: string } ) => {
|
|
|
40
40
|
<Stack direction="row" gap={ 2 } flexWrap="nowrap">
|
|
41
41
|
<ControlLabel>{ label }</ControlLabel>
|
|
42
42
|
<ToggleButton
|
|
43
|
-
aria-label={ __( 'Link
|
|
43
|
+
aria-label={ __( 'Link inputs', 'elementor' ) }
|
|
44
44
|
size={ 'tiny' }
|
|
45
45
|
value={ 'check' }
|
|
46
46
|
selected={ isLinked }
|
|
@@ -26,11 +26,11 @@ export const ImageControl = createControl(
|
|
|
26
26
|
<ImageMediaControl />
|
|
27
27
|
</PropKeyProvider>
|
|
28
28
|
<PropKeyProvider bind={ 'size' }>
|
|
29
|
-
<Grid container gap={
|
|
29
|
+
<Grid container gap={ 1.5 } alignItems="center" flexWrap="nowrap">
|
|
30
30
|
<Grid item xs={ 6 }>
|
|
31
31
|
<ControlLabel> { resolutionLabel } </ControlLabel>
|
|
32
32
|
</Grid>
|
|
33
|
-
<Grid item xs={ 6 }>
|
|
33
|
+
<Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
|
|
34
34
|
<SelectControl options={ sizes } />
|
|
35
35
|
</Grid>
|
|
36
36
|
</Grid>
|