@elementor/editor-controls 0.26.0 → 0.28.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 +26 -0
- package/dist/index.d.mts +27 -23
- package/dist/index.d.ts +27 -23
- package/dist/index.js +38 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/control-replacements.tsx +49 -0
- package/src/controls/equal-unequal-sizes-control.tsx +0 -1
- package/src/controls/image-control.tsx +19 -14
- package/src/controls/link-control.tsx +17 -6
- package/src/create-control.tsx +3 -18
- package/src/index.ts +1 -1
- package/src/create-control-replacement.tsx +0 -54
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.28.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"@elementor/editor-current-user": "0.3.0",
|
|
44
44
|
"@elementor/editor-elements": "0.8.1",
|
|
45
45
|
"@elementor/editor-props": "0.12.0",
|
|
46
|
-
"@elementor/editor-ui": "0.
|
|
46
|
+
"@elementor/editor-ui": "0.8.1",
|
|
47
47
|
"@elementor/env": "0.3.5",
|
|
48
48
|
"@elementor/http": "0.1.4",
|
|
49
|
-
"@elementor/icons": "1.
|
|
49
|
+
"@elementor/icons": "1.40.1",
|
|
50
50
|
"@elementor/query": "0.2.4",
|
|
51
51
|
"@elementor/session": "0.1.0",
|
|
52
|
-
"@elementor/ui": "1.
|
|
52
|
+
"@elementor/ui": "1.34.2",
|
|
53
53
|
"@elementor/utils": "0.4.0",
|
|
54
54
|
"@elementor/wp-media": "0.6.0",
|
|
55
55
|
"@tanstack/react-virtual": "3.13.3",
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type ComponentType, createContext, type PropsWithChildren, useContext } from 'react';
|
|
3
|
+
import { type PropValue } from '@elementor/editor-props';
|
|
4
|
+
|
|
5
|
+
import { useBoundProp } from './bound-prop-context';
|
|
6
|
+
|
|
7
|
+
type ControlReplacement = {
|
|
8
|
+
component: ComponentType;
|
|
9
|
+
condition: ( { value }: ConditionArgs ) => boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type ConditionArgs = {
|
|
13
|
+
value: PropValue;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type Props = PropsWithChildren< { replacements: ControlReplacement[] } >;
|
|
17
|
+
|
|
18
|
+
const ControlReplacementContext = createContext< ControlReplacement[] >( [] );
|
|
19
|
+
|
|
20
|
+
export const ControlReplacementsProvider = ( { replacements, children }: Props ) => {
|
|
21
|
+
return <ControlReplacementContext.Provider value={ replacements }>{ children }</ControlReplacementContext.Provider>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const useControlReplacement = ( OriginalComponent: ComponentType ) => {
|
|
25
|
+
const { value } = useBoundProp();
|
|
26
|
+
const replacements = useContext( ControlReplacementContext );
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const replacement = replacements.find( ( r ) => r.condition( { value } ) );
|
|
30
|
+
|
|
31
|
+
return replacement?.component ?? OriginalComponent;
|
|
32
|
+
} catch {
|
|
33
|
+
return OriginalComponent;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const createControlReplacementsRegistry = () => {
|
|
38
|
+
const controlReplacements: ControlReplacement[] = [];
|
|
39
|
+
|
|
40
|
+
function registerControlReplacement( replacement: ControlReplacement ) {
|
|
41
|
+
controlReplacements.push( replacement );
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getControlReplacements() {
|
|
45
|
+
return controlReplacements;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { registerControlReplacement, getControlReplacements };
|
|
49
|
+
};
|
|
@@ -135,7 +135,6 @@ export function EqualUnequalSizesControl< TMultiPropType extends string, TPropVa
|
|
|
135
135
|
} }
|
|
136
136
|
{ ...bindPopover( popupState ) }
|
|
137
137
|
slotProps={ {
|
|
138
|
-
// eslint-disable-next-line react-compiler/react-compiler
|
|
139
138
|
paper: { sx: { mt: 0.5, width: controlRef.current?.getBoundingClientRect().width } },
|
|
140
139
|
} }
|
|
141
140
|
>
|
|
@@ -14,10 +14,11 @@ import { SelectControl } from './select-control';
|
|
|
14
14
|
type ImageControlProps = {
|
|
15
15
|
sizes: { label: string; value: string }[];
|
|
16
16
|
resolutionLabel?: string;
|
|
17
|
+
showMode?: 'all' | 'media' | 'sizes';
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
export const ImageControl = createControl(
|
|
20
|
-
( { sizes, resolutionLabel = __( 'Image resolution', 'elementor' ) }: ImageControlProps ) => {
|
|
21
|
+
( { sizes, resolutionLabel = __( 'Image resolution', 'elementor' ), showMode = 'all' }: ImageControlProps ) => {
|
|
21
22
|
const propContext = useBoundProp( imagePropTypeUtil );
|
|
22
23
|
|
|
23
24
|
const { data: allowSvgUpload } = useUnfilteredFilesUpload();
|
|
@@ -26,20 +27,24 @@ export const ImageControl = createControl(
|
|
|
26
27
|
return (
|
|
27
28
|
<PropProvider { ...propContext }>
|
|
28
29
|
<Stack gap={ 1.5 }>
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
{ [ 'all', 'media' ].includes( showMode ) ? (
|
|
31
|
+
<PropKeyProvider bind={ 'src' }>
|
|
32
|
+
<ControlFormLabel> { __( 'Image', 'elementor' ) } </ControlFormLabel>
|
|
33
|
+
<ImageMediaControl mediaTypes={ mediaTypes } />
|
|
34
|
+
</PropKeyProvider>
|
|
35
|
+
) : null }
|
|
36
|
+
{ [ 'all', 'sizes' ].includes( showMode ) ? (
|
|
37
|
+
<PropKeyProvider bind={ 'size' }>
|
|
38
|
+
<Grid container gap={ 1.5 } alignItems="center" flexWrap="nowrap">
|
|
39
|
+
<Grid item xs={ 6 }>
|
|
40
|
+
<ControlFormLabel> { resolutionLabel } </ControlFormLabel>
|
|
41
|
+
</Grid>
|
|
42
|
+
<Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
|
|
43
|
+
<SelectControl options={ sizes } />
|
|
44
|
+
</Grid>
|
|
37
45
|
</Grid>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
</Grid>
|
|
41
|
-
</Grid>
|
|
42
|
-
</PropKeyProvider>
|
|
46
|
+
</PropKeyProvider>
|
|
47
|
+
) : null }
|
|
43
48
|
</Stack>
|
|
44
49
|
</PropProvider>
|
|
45
50
|
);
|
|
@@ -13,7 +13,7 @@ import { InfoTipCard } from '@elementor/editor-ui';
|
|
|
13
13
|
import { type HttpResponse, httpService } from '@elementor/http';
|
|
14
14
|
import { AlertTriangleIcon, MinusIcon, PlusIcon } from '@elementor/icons';
|
|
15
15
|
import { useSessionStorage } from '@elementor/session';
|
|
16
|
-
import { Box, Collapse,
|
|
16
|
+
import { Box, Collapse, Grid, IconButton, Infotip, Stack, Switch } from '@elementor/ui';
|
|
17
17
|
import { debounce } from '@elementor/utils';
|
|
18
18
|
import { __ } from '@wordpress/i18n';
|
|
19
19
|
|
|
@@ -81,9 +81,21 @@ export const LinkControl = createControl( ( props: Props ) => {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
const newState = ! isActive;
|
|
85
|
+
setIsActive( newState );
|
|
86
|
+
|
|
87
|
+
if ( ! newState && value !== null ) {
|
|
88
|
+
setValue( null );
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if ( newState && linkSessionValue?.value ) {
|
|
92
|
+
setValue( linkSessionValue.value );
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setLinkSessionValue( {
|
|
96
|
+
value: newState ? value : linkSessionValue?.value,
|
|
97
|
+
meta: { isEnabled: newState },
|
|
98
|
+
} );
|
|
87
99
|
};
|
|
88
100
|
|
|
89
101
|
const onOptionChange = ( newValue: number | null ) => {
|
|
@@ -105,7 +117,7 @@ export const LinkControl = createControl( ( props: Props ) => {
|
|
|
105
117
|
? {
|
|
106
118
|
...value,
|
|
107
119
|
destination: urlPropTypeUtil.create( newValue ),
|
|
108
|
-
label:
|
|
120
|
+
label: stringPropTypeUtil.create( '' ),
|
|
109
121
|
}
|
|
110
122
|
: null;
|
|
111
123
|
|
|
@@ -143,7 +155,6 @@ export const LinkControl = createControl( ( props: Props ) => {
|
|
|
143
155
|
return (
|
|
144
156
|
<PropProvider { ...propContext } value={ value } setValue={ setValue }>
|
|
145
157
|
<Stack gap={ 1.5 }>
|
|
146
|
-
<Divider />
|
|
147
158
|
<Stack
|
|
148
159
|
direction="row"
|
|
149
160
|
sx={ {
|
package/src/create-control.tsx
CHANGED
|
@@ -2,35 +2,20 @@ import * as React from 'react';
|
|
|
2
2
|
import { type ComponentProps, type ComponentType } from 'react';
|
|
3
3
|
import { ErrorBoundary } from '@elementor/ui';
|
|
4
4
|
|
|
5
|
-
import { useControlReplacement } from './
|
|
5
|
+
import { useControlReplacement } from './control-replacements';
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
8
|
type AnyComponentType = ComponentType< any >;
|
|
9
9
|
|
|
10
|
-
type Options = {
|
|
11
|
-
supportsReplacements?: boolean;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
10
|
const brandSymbol = Symbol( 'control' );
|
|
15
11
|
|
|
16
12
|
export type ControlComponent< TComponent extends AnyComponentType = AnyComponentType > = TComponent & {
|
|
17
13
|
[ brandSymbol ]: true;
|
|
18
14
|
};
|
|
19
15
|
|
|
20
|
-
export function createControl< T extends AnyComponentType >(
|
|
21
|
-
Component: T,
|
|
22
|
-
{ supportsReplacements = true }: Options = {}
|
|
23
|
-
) {
|
|
16
|
+
export function createControl< T extends AnyComponentType >( Control: T ) {
|
|
24
17
|
return ( ( props: ComponentProps< T > ) => {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
if ( ControlReplacement && supportsReplacements ) {
|
|
28
|
-
return (
|
|
29
|
-
<ErrorBoundary fallback={ null }>
|
|
30
|
-
<ControlReplacement { ...props } />
|
|
31
|
-
</ErrorBoundary>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
18
|
+
const Component = useControlReplacement( Control );
|
|
34
19
|
|
|
35
20
|
return (
|
|
36
21
|
<ErrorBoundary fallback={ null }>
|
package/src/index.ts
CHANGED
|
@@ -34,7 +34,7 @@ export type { ToggleControlProps } from './controls/toggle-control';
|
|
|
34
34
|
export type { FontCategory } from './controls/font-family-control/font-family-control';
|
|
35
35
|
|
|
36
36
|
// providers
|
|
37
|
-
export {
|
|
37
|
+
export { createControlReplacementsRegistry, ControlReplacementsProvider } from './control-replacements';
|
|
38
38
|
export { ControlActionsProvider, useControlActions } from './control-actions/control-actions-context';
|
|
39
39
|
export { useBoundProp, PropProvider, PropKeyProvider } from './bound-prop-context';
|
|
40
40
|
export { ControlAdornmentsProvider } from './control-adornments/control-adornments-context';
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { type ComponentType, createContext, useContext } from 'react';
|
|
3
|
-
import { type PropValue } from '@elementor/editor-props';
|
|
4
|
-
|
|
5
|
-
import { useBoundProp } from './bound-prop-context';
|
|
6
|
-
|
|
7
|
-
type ReplaceWhenParams = {
|
|
8
|
-
value: PropValue;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type CreateControlReplacement = {
|
|
12
|
-
component: ComponentType;
|
|
13
|
-
condition: ( { value }: ReplaceWhenParams ) => boolean;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const ControlReplacementContext = createContext< CreateControlReplacement | undefined >( undefined );
|
|
17
|
-
|
|
18
|
-
export const ControlReplacementProvider = ( {
|
|
19
|
-
component,
|
|
20
|
-
condition,
|
|
21
|
-
children,
|
|
22
|
-
}: React.PropsWithChildren< CreateControlReplacement > ) => {
|
|
23
|
-
return (
|
|
24
|
-
<ControlReplacementContext.Provider value={ { component, condition } }>
|
|
25
|
-
{ children }
|
|
26
|
-
</ControlReplacementContext.Provider>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
export const useControlReplacement = () => {
|
|
30
|
-
const { value } = useBoundProp();
|
|
31
|
-
const controlReplacement = useContext( ControlReplacementContext );
|
|
32
|
-
|
|
33
|
-
let shouldReplace = false;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
shouldReplace = !! controlReplacement?.condition( { value } ) && !! controlReplacement.component;
|
|
37
|
-
} catch {}
|
|
38
|
-
|
|
39
|
-
return shouldReplace ? controlReplacement?.component : undefined;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const createControlReplacement = () => {
|
|
43
|
-
let controlReplacement: CreateControlReplacement;
|
|
44
|
-
|
|
45
|
-
function replaceControl( { component, condition }: CreateControlReplacement ) {
|
|
46
|
-
controlReplacement = { component, condition };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function getControlReplacement() {
|
|
50
|
-
return controlReplacement;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return { replaceControl, getControlReplacement };
|
|
54
|
-
};
|