@elementor/editor-controls 0.1.1 → 0.2.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 +16 -0
- package/dist/index.d.mts +38 -30
- package/dist/index.d.ts +38 -30
- package/dist/index.js +242 -175
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +246 -175
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/bound-prop-context.tsx +47 -10
- package/src/components/control-toggle-button-group.tsx +2 -2
- package/src/controls/background-overlay-repeater-control.tsx +3 -7
- package/src/controls/box-shadow-repeater-control.tsx +9 -9
- package/src/controls/color-control.tsx +4 -13
- package/src/controls/equal-unequal-sizes-control.tsx +100 -100
- package/src/controls/font-family-control.tsx +2 -1
- package/src/controls/image-control.tsx +7 -18
- package/src/controls/image-media-control.tsx +7 -10
- package/src/controls/link-control.tsx +90 -0
- package/src/controls/linked-dimensions-control.tsx +5 -11
- package/src/controls/number-control.tsx +5 -4
- package/src/controls/select-control.tsx +7 -7
- package/src/controls/size-control.tsx +10 -19
- package/src/controls/stroke-control.tsx +8 -15
- package/src/controls/text-area-control.tsx +2 -1
- package/src/controls/text-control.tsx +2 -1
- package/src/controls/toggle-control.tsx +5 -5
- package/src/controls/url-control.tsx +29 -0
- package/src/hooks/use-sync-external-state.tsx +8 -8
- package/src/index.ts +2 -0
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type
|
|
2
|
+
import { stringPropTypeUtil, type StringPropValue } from '@elementor/editor-props';
|
|
3
3
|
import { MenuItem, Select, type SelectChangeEvent } 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
|
-
type Props
|
|
10
|
-
options: Array< { label: string; value:
|
|
9
|
+
type Props = {
|
|
10
|
+
options: Array< { label: string; value: StringPropValue[ 'value' ]; disabled?: boolean } >;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export const SelectControl = createControl(
|
|
14
|
-
const { value, setValue } = useBoundProp
|
|
13
|
+
export const SelectControl = createControl( ( { options }: Props ) => {
|
|
14
|
+
const { value, setValue } = useBoundProp( stringPropTypeUtil );
|
|
15
15
|
|
|
16
|
-
const handleChange = ( event: SelectChangeEvent<
|
|
17
|
-
setValue( event.target.value
|
|
16
|
+
const handleChange = ( event: SelectChangeEvent< StringPropValue[ 'value' ] > ) => {
|
|
17
|
+
setValue( event.target.value );
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
return (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { sizePropTypeUtil } from '@elementor/editor-props';
|
|
3
3
|
import { InputAdornment } from '@elementor/ui';
|
|
4
4
|
|
|
5
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
@@ -22,25 +22,19 @@ export type SizeControlProps = {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
export const SizeControl = createControl( ( { units = defaultUnits, placeholder, startIcon }: SizeControlProps ) => {
|
|
25
|
-
const { value, setValue } = useBoundProp
|
|
25
|
+
const { value, setValue } = useBoundProp( sizePropTypeUtil );
|
|
26
26
|
|
|
27
|
-
const [ state, setState ] = useSyncExternalState
|
|
27
|
+
const [ state, setState ] = useSyncExternalState( {
|
|
28
28
|
external: value,
|
|
29
29
|
setExternal: setValue,
|
|
30
|
-
persistWhen: ( controlValue ) => !! controlValue?.
|
|
31
|
-
fallback: ( controlValue ) => ( {
|
|
32
|
-
$$type: 'size',
|
|
33
|
-
value: { unit: controlValue?.value?.unit || defaultUnit, size: defaultSize },
|
|
34
|
-
} ),
|
|
30
|
+
persistWhen: ( controlValue ) => !! controlValue?.size || controlValue?.size === 0,
|
|
31
|
+
fallback: ( controlValue ) => ( { unit: controlValue?.unit || defaultUnit, size: defaultSize } ),
|
|
35
32
|
} );
|
|
36
33
|
|
|
37
34
|
const handleUnitChange = ( unit: Unit ) => {
|
|
38
35
|
setState( ( prev ) => ( {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
...prev.value,
|
|
42
|
-
unit,
|
|
43
|
-
},
|
|
36
|
+
size: prev?.size ?? defaultSize,
|
|
37
|
+
unit,
|
|
44
38
|
} ) );
|
|
45
39
|
};
|
|
46
40
|
|
|
@@ -49,10 +43,7 @@ export const SizeControl = createControl( ( { units = defaultUnits, placeholder,
|
|
|
49
43
|
|
|
50
44
|
setState( ( prev ) => ( {
|
|
51
45
|
...prev,
|
|
52
|
-
|
|
53
|
-
...prev.value,
|
|
54
|
-
size: size || size === '0' ? parseFloat( size ) : defaultSize,
|
|
55
|
-
},
|
|
46
|
+
size: size || size === '0' ? parseFloat( size ) : defaultSize,
|
|
56
47
|
} ) );
|
|
57
48
|
};
|
|
58
49
|
|
|
@@ -63,13 +54,13 @@ export const SizeControl = createControl( ( { units = defaultUnits, placeholder,
|
|
|
63
54
|
<SelectionEndAdornment
|
|
64
55
|
options={ units }
|
|
65
56
|
onClick={ handleUnitChange }
|
|
66
|
-
value={ state
|
|
57
|
+
value={ state?.unit ?? defaultUnit }
|
|
67
58
|
/>
|
|
68
59
|
}
|
|
69
60
|
placeholder={ placeholder }
|
|
70
61
|
startAdornment={ startIcon ?? <InputAdornment position="start">{ startIcon }</InputAdornment> }
|
|
71
62
|
type="number"
|
|
72
|
-
value={ Number.isNaN( state
|
|
63
|
+
value={ Number.isNaN( state?.size ) ? '' : state?.size }
|
|
73
64
|
onChange={ handleSizeChange }
|
|
74
65
|
/>
|
|
75
66
|
</ControlActions>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type ColorPropValue, type PropValue, type SizePropValue,
|
|
2
|
+
import { type ColorPropValue, type PropValue, type SizePropValue, strokePropTypeUtil } from '@elementor/editor-props';
|
|
3
3
|
import { Grid, Stack } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
@@ -18,34 +18,27 @@ export type StrokeProps< T > = {
|
|
|
18
18
|
label: string;
|
|
19
19
|
children: React.ReactNode;
|
|
20
20
|
};
|
|
21
|
-
|
|
22
21
|
const units: Unit[] = [ 'px', 'em', 'rem' ];
|
|
23
22
|
|
|
24
23
|
export const StrokeControl = createControl( () => {
|
|
25
|
-
const { value, setValue } = useBoundProp
|
|
24
|
+
const { value, setValue } = useBoundProp( strokePropTypeUtil );
|
|
26
25
|
|
|
27
26
|
const setStrokeWidth = ( newValue: SizePropValue ) => {
|
|
28
27
|
const updatedValue = {
|
|
29
|
-
...value
|
|
28
|
+
...value,
|
|
30
29
|
width: newValue,
|
|
31
30
|
};
|
|
32
31
|
|
|
33
|
-
setValue(
|
|
34
|
-
$$type: 'stroke',
|
|
35
|
-
value: updatedValue,
|
|
36
|
-
} );
|
|
32
|
+
setValue( updatedValue );
|
|
37
33
|
};
|
|
38
34
|
|
|
39
35
|
const setStrokeColor = ( newValue: ColorPropValue ) => {
|
|
40
36
|
const updatedValue = {
|
|
41
|
-
...value
|
|
37
|
+
...value,
|
|
42
38
|
color: newValue,
|
|
43
39
|
};
|
|
44
40
|
|
|
45
|
-
setValue(
|
|
46
|
-
$$type: 'stroke',
|
|
47
|
-
value: updatedValue,
|
|
48
|
-
} );
|
|
41
|
+
setValue( updatedValue );
|
|
49
42
|
};
|
|
50
43
|
|
|
51
44
|
return (
|
|
@@ -53,7 +46,7 @@ export const StrokeControl = createControl( () => {
|
|
|
53
46
|
<Control
|
|
54
47
|
bind="width"
|
|
55
48
|
label={ __( 'Stroke Width', 'elementor' ) }
|
|
56
|
-
value={ value?.
|
|
49
|
+
value={ value?.width }
|
|
57
50
|
setValue={ setStrokeWidth }
|
|
58
51
|
>
|
|
59
52
|
<SizeControl units={ units } />
|
|
@@ -62,7 +55,7 @@ export const StrokeControl = createControl( () => {
|
|
|
62
55
|
<Control
|
|
63
56
|
bind="color"
|
|
64
57
|
label={ __( 'Stroke Color', 'elementor' ) }
|
|
65
|
-
value={ value?.
|
|
58
|
+
value={ value?.color }
|
|
66
59
|
setValue={ setStrokeColor }
|
|
67
60
|
>
|
|
68
61
|
<ColorControl />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { stringPropTypeUtil } from '@elementor/editor-props';
|
|
2
3
|
import { TextField } from '@elementor/ui';
|
|
3
4
|
|
|
4
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
@@ -10,7 +11,7 @@ type Props = {
|
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
export const TextAreaControl = createControl( ( { placeholder }: Props ) => {
|
|
13
|
-
const { value, setValue } = useBoundProp
|
|
14
|
+
const { value, setValue } = useBoundProp( stringPropTypeUtil );
|
|
14
15
|
|
|
15
16
|
const handleChange = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
16
17
|
setValue( event.target.value );
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { stringPropTypeUtil } from '@elementor/editor-props';
|
|
2
3
|
import { TextField } from '@elementor/ui';
|
|
3
4
|
|
|
4
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
@@ -6,7 +7,7 @@ import ControlActions from '../control-actions/control-actions';
|
|
|
6
7
|
import { createControl } from '../create-control';
|
|
7
8
|
|
|
8
9
|
export const TextControl = createControl( ( { placeholder }: { placeholder?: string } ) => {
|
|
9
|
-
const { value, setValue } = useBoundProp
|
|
10
|
+
const { value, setValue } = useBoundProp( stringPropTypeUtil );
|
|
10
11
|
|
|
11
12
|
const handleChange = ( event: React.ChangeEvent< HTMLInputElement > ) => setValue( event.target.value );
|
|
12
13
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type PropValue } from '@elementor/editor-props';
|
|
2
|
+
import { type PropValue, stringPropTypeUtil, type StringPropValue } from '@elementor/editor-props';
|
|
3
3
|
import { type ToggleButtonProps } from '@elementor/ui';
|
|
4
4
|
|
|
5
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
@@ -13,17 +13,17 @@ type ToggleControlProps< T extends PropValue > = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export const ToggleControl = createControl(
|
|
16
|
-
|
|
17
|
-
const { value, setValue } = useBoundProp
|
|
16
|
+
( { options, fullWidth = false, size = 'tiny' }: ToggleControlProps< StringPropValue[ 'value' ] > ) => {
|
|
17
|
+
const { value, setValue } = useBoundProp( stringPropTypeUtil );
|
|
18
18
|
|
|
19
|
-
const handleToggle = ( option:
|
|
19
|
+
const handleToggle = ( option: StringPropValue[ 'value' ] | null ) => {
|
|
20
20
|
setValue( option );
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
24
|
<ControlToggleButtonGroup
|
|
25
25
|
items={ options }
|
|
26
|
-
value={ value
|
|
26
|
+
value={ value ?? null }
|
|
27
27
|
onChange={ handleToggle }
|
|
28
28
|
exclusive={ true }
|
|
29
29
|
fullWidth={ fullWidth }
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type UrlPropValue } from '@elementor/editor-props';
|
|
3
|
+
import { TextField } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
import { useBoundProp } from '../bound-prop-context';
|
|
6
|
+
import ControlActions from '../control-actions/control-actions';
|
|
7
|
+
import { createControl } from '../create-control';
|
|
8
|
+
|
|
9
|
+
export const UrlControl = createControl( ( { placeholder }: { placeholder?: string } ) => {
|
|
10
|
+
const { value, setValue } = useBoundProp< UrlPropValue >();
|
|
11
|
+
|
|
12
|
+
const handleChange = ( event: React.ChangeEvent< HTMLInputElement > ) =>
|
|
13
|
+
setValue( {
|
|
14
|
+
$$type: 'url',
|
|
15
|
+
value: event.target.value,
|
|
16
|
+
} );
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<ControlActions>
|
|
20
|
+
<TextField
|
|
21
|
+
size="tiny"
|
|
22
|
+
fullWidth
|
|
23
|
+
value={ value?.value }
|
|
24
|
+
onChange={ handleChange }
|
|
25
|
+
placeholder={ placeholder }
|
|
26
|
+
/>
|
|
27
|
+
</ControlActions>
|
|
28
|
+
);
|
|
29
|
+
} );
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
type UseInternalStateOptions< TValue > = {
|
|
4
|
-
external: TValue |
|
|
5
|
-
setExternal: ( value: TValue |
|
|
6
|
-
persistWhen: ( value: TValue |
|
|
7
|
-
fallback: ( value: TValue |
|
|
4
|
+
external: TValue | null;
|
|
5
|
+
setExternal: ( value: TValue | null ) => void;
|
|
6
|
+
persistWhen: ( value: TValue | null ) => boolean;
|
|
7
|
+
fallback: ( value: TValue | null ) => TValue;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export const useSyncExternalState = < TValue, >( {
|
|
@@ -13,15 +13,15 @@ export const useSyncExternalState = < TValue, >( {
|
|
|
13
13
|
persistWhen,
|
|
14
14
|
fallback,
|
|
15
15
|
}: UseInternalStateOptions< TValue > ) => {
|
|
16
|
-
function toExternal( internalValue: TValue |
|
|
16
|
+
function toExternal( internalValue: TValue | null ) {
|
|
17
17
|
if ( persistWhen( internalValue ) ) {
|
|
18
18
|
return internalValue;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
return
|
|
21
|
+
return null;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
function toInternal( externalValue: TValue |
|
|
24
|
+
function toInternal( externalValue: TValue | null, internalValue: TValue | null ) {
|
|
25
25
|
if ( ! externalValue ) {
|
|
26
26
|
return fallback( internalValue );
|
|
27
27
|
}
|
|
@@ -29,7 +29,7 @@ export const useSyncExternalState = < TValue, >( {
|
|
|
29
29
|
return externalValue;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const [ internal, setInternal ] = useState< TValue >( toInternal( external,
|
|
32
|
+
const [ internal, setInternal ] = useState< TValue >( toInternal( external, null ) );
|
|
33
33
|
|
|
34
34
|
useEffect( () => {
|
|
35
35
|
setInternal( ( prevInternal ) => toInternal( external, prevInternal ) );
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,8 @@ export { NumberControl } from './controls/number-control';
|
|
|
13
13
|
export { EqualUnequalSizesControl } from './controls/equal-unequal-sizes-control';
|
|
14
14
|
export { LinkedDimensionsControl } from './controls/linked-dimensions-control';
|
|
15
15
|
export { FontFamilyControl } from './controls/font-family-control';
|
|
16
|
+
export { UrlControl } from './controls/url-control';
|
|
17
|
+
export { LinkControl } from './controls/link-control';
|
|
16
18
|
|
|
17
19
|
// components
|
|
18
20
|
export { ControlLabel } from './components/control-label';
|