@elementor/editor-controls 3.32.0-84 → 3.32.0-87
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/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1359 -1514
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1157 -1316
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -14
- package/src/components/unstable-repeater/context/repeater-context.tsx +1 -1
- package/src/components/unstable-repeater/items/edit-item-popover.tsx +2 -4
- package/src/components/unstable-repeater/items/item.tsx +10 -1
- package/src/controls/box-shadow-repeater-control.tsx +30 -26
- package/src/controls/filter-control/configs.ts +49 -0
- package/src/controls/filter-control/context/filter-config-context.tsx +49 -0
- package/src/controls/filter-control/{drop-shadow-item-content.tsx → drop-shadow/drop-shadow-item-content.tsx} +11 -14
- package/src/controls/filter-control/filter-content.tsx +78 -0
- package/src/controls/filter-control/filter-icon.tsx +21 -0
- package/src/controls/filter-control/filter-label.tsx +13 -0
- package/src/controls/filter-control/filter-repeater-control.tsx +93 -0
- package/src/controls/filter-control/single-size/single-size-item-content.tsx +48 -0
- package/src/controls/filter-control/single-size/single-size-item-label.tsx +30 -0
- package/src/controls/filter-control/utils.ts +130 -0
- package/src/controls/size-control.tsx +1 -1
- package/src/index.ts +1 -1
- package/src/controls/filter-repeater-control.tsx +0 -322
- /package/src/controls/filter-control/{drop-shadow-item-label.tsx → drop-shadow/drop-shadow-item-label.tsx} +0 -0
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": "3.32.0-
|
|
4
|
+
"version": "3.32.0-87",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,21 +40,21 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "3.32.0-
|
|
44
|
-
"@elementor/editor-elements": "3.32.0-
|
|
45
|
-
"@elementor/editor-props": "3.32.0-
|
|
46
|
-
"@elementor/editor-responsive": "3.32.0-
|
|
47
|
-
"@elementor/editor-ui": "3.32.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "3.32.0-
|
|
49
|
-
"@elementor/env": "3.32.0-
|
|
50
|
-
"@elementor/http-client": "3.32.0-
|
|
43
|
+
"@elementor/editor-current-user": "3.32.0-87",
|
|
44
|
+
"@elementor/editor-elements": "3.32.0-87",
|
|
45
|
+
"@elementor/editor-props": "3.32.0-87",
|
|
46
|
+
"@elementor/editor-responsive": "3.32.0-87",
|
|
47
|
+
"@elementor/editor-ui": "3.32.0-87",
|
|
48
|
+
"@elementor/editor-v1-adapters": "3.32.0-87",
|
|
49
|
+
"@elementor/env": "3.32.0-87",
|
|
50
|
+
"@elementor/http-client": "3.32.0-87",
|
|
51
51
|
"@elementor/icons": "^1.51.1",
|
|
52
|
-
"@elementor/locations": "3.32.0-
|
|
53
|
-
"@elementor/query": "3.32.0-
|
|
54
|
-
"@elementor/session": "3.32.0-
|
|
52
|
+
"@elementor/locations": "3.32.0-87",
|
|
53
|
+
"@elementor/query": "3.32.0-87",
|
|
54
|
+
"@elementor/session": "3.32.0-87",
|
|
55
55
|
"@elementor/ui": "1.36.8",
|
|
56
|
-
"@elementor/utils": "3.32.0-
|
|
57
|
-
"@elementor/wp-media": "3.32.0-
|
|
56
|
+
"@elementor/utils": "3.32.0-87",
|
|
57
|
+
"@elementor/wp-media": "3.32.0-87",
|
|
58
58
|
"@wordpress/i18n": "^5.13.0",
|
|
59
59
|
"@monaco-editor/react": "^4.7.0"
|
|
60
60
|
},
|
|
@@ -83,7 +83,7 @@ export const RepeaterContextProvider = < T extends RepeatablePropValue = Repeata
|
|
|
83
83
|
const popoverState = usePopupState( { variant: 'popover' } );
|
|
84
84
|
|
|
85
85
|
const addItem = ( ev: React.MouseEvent, config?: AddItem< T > ) => {
|
|
86
|
-
const item = config?.item ?? initial;
|
|
86
|
+
const item = config?.item ?? { ...initial };
|
|
87
87
|
const newIndex = config?.index ?? items.length;
|
|
88
88
|
const newItems = [ ...items ];
|
|
89
89
|
|
|
@@ -6,7 +6,6 @@ import { EMPTY_OPEN_ITEM, useRepeaterContext } from '../context/repeater-context
|
|
|
6
6
|
|
|
7
7
|
export const EditItemPopover = ( { children }: { children: React.ReactNode } ) => {
|
|
8
8
|
const { popoverState, openItemIndex, isOpen, rowRef, setOpenItemIndex, setRowRef, items } = useRepeaterContext();
|
|
9
|
-
const popoverProps = bindPopover( popoverState );
|
|
10
9
|
|
|
11
10
|
if ( ! isOpen || ! rowRef ) {
|
|
12
11
|
return null;
|
|
@@ -15,8 +14,8 @@ export const EditItemPopover = ( { children }: { children: React.ReactNode } ) =
|
|
|
15
14
|
const bind = items[ openItemIndex ].item.$$type;
|
|
16
15
|
|
|
17
16
|
const onClose = () => {
|
|
18
|
-
popoverProps.onClose?.();
|
|
19
17
|
setRowRef( null );
|
|
18
|
+
popoverState.setAnchorEl( null );
|
|
20
19
|
setOpenItemIndex( EMPTY_OPEN_ITEM );
|
|
21
20
|
};
|
|
22
21
|
|
|
@@ -29,8 +28,7 @@ export const EditItemPopover = ( { children }: { children: React.ReactNode } ) =
|
|
|
29
28
|
},
|
|
30
29
|
} }
|
|
31
30
|
anchorOrigin={ { vertical: 'bottom', horizontal: 'left' } }
|
|
32
|
-
{ ...
|
|
33
|
-
anchorEl={ rowRef }
|
|
31
|
+
{ ...bindPopover( popoverState ) }
|
|
34
32
|
onClose={ onClose }
|
|
35
33
|
>
|
|
36
34
|
<PropKeyProvider bind={ String( openItemIndex ) }>
|
|
@@ -26,6 +26,15 @@ export const Item = < T extends RepeatablePropValue >( {
|
|
|
26
26
|
setOpenItemIndex( index );
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
const setRef = ( ref: HTMLDivElement | null ) => {
|
|
30
|
+
if ( ! ref || openItemIndex !== index || ref === popoverState.anchorEl ) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setRowRef( ref );
|
|
35
|
+
popoverState.setAnchorEl( ref );
|
|
36
|
+
};
|
|
37
|
+
|
|
29
38
|
return (
|
|
30
39
|
<>
|
|
31
40
|
<UnstableTag
|
|
@@ -38,7 +47,7 @@ export const Item = < T extends RepeatablePropValue >( {
|
|
|
38
47
|
}
|
|
39
48
|
showActionsOnHover
|
|
40
49
|
fullWidth
|
|
41
|
-
ref={
|
|
50
|
+
ref={ setRef }
|
|
42
51
|
variant="outlined"
|
|
43
52
|
aria-label={ __( 'Open item', 'elementor' ) }
|
|
44
53
|
sx={ { minHeight: ( theme ) => theme.spacing( 4 ) } }
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type RefObject, useRef } from 'react';
|
|
3
|
-
import { boxShadowPropTypeUtil,
|
|
4
|
-
import { FormLabel, Grid, type SxProps, type Theme, UnstableColorIndicator } from '@elementor/ui';
|
|
3
|
+
import { boxShadowPropTypeUtil, shadowPropTypeUtil, type ShadowPropValue } from '@elementor/editor-props';
|
|
4
|
+
import { FormLabel, Grid, styled, type SxProps, type Theme, UnstableColorIndicator } from '@elementor/ui';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
6
|
|
|
7
7
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
8
8
|
import { PopoverContent } from '../components/popover-content';
|
|
9
9
|
import { PopoverGridContainer } from '../components/popover-grid-container';
|
|
10
|
-
import {
|
|
10
|
+
import { Header, Item, ItemsContainer, TooltipAddItemAction, UnstableRepeater } from '../components/unstable-repeater';
|
|
11
|
+
import { DisableItemAction } from '../components/unstable-repeater/actions/disable-item-action';
|
|
12
|
+
import { DuplicateItemAction } from '../components/unstable-repeater/actions/duplicate-item-action';
|
|
13
|
+
import { RemoveItemAction } from '../components/unstable-repeater/actions/remove-item-action';
|
|
14
|
+
import { useRepeaterContext } from '../components/unstable-repeater/context/repeater-context';
|
|
15
|
+
import { EditItemPopover } from '../components/unstable-repeater/items/edit-item-popover';
|
|
11
16
|
import { createControl } from '../create-control';
|
|
12
17
|
import { ColorControl } from './color-control';
|
|
13
18
|
import { SelectControl } from './select-control';
|
|
@@ -18,38 +23,37 @@ export const BoxShadowRepeaterControl = createControl( () => {
|
|
|
18
23
|
|
|
19
24
|
return (
|
|
20
25
|
<PropProvider propType={ propType } value={ value } setValue={ setValue } isDisabled={ () => disabled }>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
<UnstableRepeater initial={ initialShadow } propTypeUtil={ boxShadowPropTypeUtil }>
|
|
27
|
+
<Header label={ __( 'Box shadow', 'elementor' ) }>
|
|
28
|
+
<TooltipAddItemAction newItemIndex={ 0 } disabled={ disabled } />
|
|
29
|
+
</Header>
|
|
30
|
+
<ItemsContainer itemTemplate={ <Item Icon={ ItemIcon } Label={ ItemLabel } /> }>
|
|
31
|
+
<DuplicateItemAction />
|
|
32
|
+
<DisableItemAction />
|
|
33
|
+
<RemoveItemAction />
|
|
34
|
+
</ItemsContainer>
|
|
35
|
+
<EditItemPopover>
|
|
36
|
+
<Content />
|
|
37
|
+
</EditItemPopover>
|
|
38
|
+
</UnstableRepeater>
|
|
34
39
|
</PropProvider>
|
|
35
40
|
);
|
|
36
41
|
} );
|
|
37
42
|
|
|
43
|
+
const StyledUnstableColorIndicator = styled( UnstableColorIndicator )( ( { theme } ) => ( {
|
|
44
|
+
height: '1rem',
|
|
45
|
+
width: '1rem',
|
|
46
|
+
borderRadius: `${ theme.shape.borderRadius / 2 }px`,
|
|
47
|
+
} ) );
|
|
48
|
+
|
|
38
49
|
const ItemIcon = ( { value }: { value: ShadowPropValue } ) => (
|
|
39
|
-
<
|
|
50
|
+
<StyledUnstableColorIndicator size="inherit" component="span" value={ value.value.color?.value } />
|
|
40
51
|
);
|
|
41
52
|
|
|
42
|
-
const
|
|
43
|
-
return (
|
|
44
|
-
<PropKeyProvider bind={ bind }>
|
|
45
|
-
<Content anchorEl={ anchorEl } />
|
|
46
|
-
</PropKeyProvider>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const Content = ( { anchorEl }: { anchorEl: HTMLElement | null } ) => {
|
|
53
|
+
const Content = () => {
|
|
51
54
|
const context = useBoundProp( shadowPropTypeUtil );
|
|
52
55
|
const rowRef: RefObject< HTMLDivElement >[] = [ useRef( null ), useRef( null ) ];
|
|
56
|
+
const { rowRef: anchorEl } = useRepeaterContext();
|
|
53
57
|
|
|
54
58
|
return (
|
|
55
59
|
<PropProvider { ...context }>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
|
|
3
|
+
export type FilterFunction =
|
|
4
|
+
| 'blur'
|
|
5
|
+
| 'brightness'
|
|
6
|
+
| 'contrast'
|
|
7
|
+
| 'hue-rotate'
|
|
8
|
+
| 'saturate'
|
|
9
|
+
| 'grayscale'
|
|
10
|
+
| 'invert'
|
|
11
|
+
| 'sepia'
|
|
12
|
+
| 'drop-shadow';
|
|
13
|
+
|
|
14
|
+
export type FilterFunctionGroup = 'blur' | 'color-tone' | 'hue-rotate' | 'intensity' | 'drop-shadow';
|
|
15
|
+
|
|
16
|
+
export type FilterGroup = {
|
|
17
|
+
[ filter in FilterFunction ]?: {
|
|
18
|
+
name: string;
|
|
19
|
+
valueName?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const FILTERS_BY_GROUP: Record< FilterFunctionGroup, FilterGroup > = {
|
|
24
|
+
blur: {
|
|
25
|
+
blur: {
|
|
26
|
+
name: __( 'Blur', 'elementor' ),
|
|
27
|
+
valueName: __( 'Radius', 'elementor' ),
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
intensity: {
|
|
31
|
+
brightness: { name: __( 'Brightness', 'elementor' ) },
|
|
32
|
+
contrast: { name: __( 'Contrast', 'elementor' ) },
|
|
33
|
+
saturate: { name: __( 'Saturate', 'elementor' ) },
|
|
34
|
+
},
|
|
35
|
+
'hue-rotate': {
|
|
36
|
+
'hue-rotate': {
|
|
37
|
+
name: __( 'Hue Rotate', 'elementor' ),
|
|
38
|
+
valueName: __( 'Angle', 'elementor' ),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
'color-tone': {
|
|
42
|
+
grayscale: { name: __( 'Grayscale', 'elementor' ) },
|
|
43
|
+
invert: { name: __( 'Invert', 'elementor' ) },
|
|
44
|
+
sepia: { name: __( 'Sepia', 'elementor' ) },
|
|
45
|
+
},
|
|
46
|
+
'drop-shadow': {
|
|
47
|
+
'drop-shadow': { name: __( 'Drop shadow', 'elementor' ), valueName: __( 'Drop-shadow', 'elementor' ) },
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
3
|
+
import { cssFilterFunctionPropUtil, type PropType } from '@elementor/editor-props';
|
|
4
|
+
|
|
5
|
+
import { useBoundProp } from '../../../bound-prop-context';
|
|
6
|
+
import { type FilterFunction } from '../configs';
|
|
7
|
+
import { buildFilterConfig, type FilterConfigEntry } from '../utils';
|
|
8
|
+
|
|
9
|
+
type FilterConfigMap = Record< FilterFunction, FilterConfigEntry >;
|
|
10
|
+
|
|
11
|
+
type FilterConfigContextValue = {
|
|
12
|
+
config: FilterConfigMap;
|
|
13
|
+
filterOptions: Array< { value: string; label: string } >;
|
|
14
|
+
getFilterFunctionConfig: ( filterFunction: FilterFunction ) => FilterConfigEntry;
|
|
15
|
+
getInitialValue: () => unknown;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const FilterConfigContext = createContext< FilterConfigContextValue | null >( null );
|
|
19
|
+
|
|
20
|
+
export function FilterConfigProvider( { children }: React.PropsWithChildren ) {
|
|
21
|
+
const propContext = useBoundProp( cssFilterFunctionPropUtil ) as { propType: { item_prop_type: PropType } };
|
|
22
|
+
|
|
23
|
+
const contextValue = useMemo( () => {
|
|
24
|
+
const config = buildFilterConfig( propContext.propType.item_prop_type );
|
|
25
|
+
const filterOptions = Object.entries( config ).map( ( [ key, conf ] ) => ( {
|
|
26
|
+
value: key,
|
|
27
|
+
label: conf.name,
|
|
28
|
+
} ) );
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
config,
|
|
32
|
+
filterOptions,
|
|
33
|
+
getFilterFunctionConfig: ( filterFunction: FilterFunction ) => config[ filterFunction ],
|
|
34
|
+
getInitialValue: () => config.blur.defaultValue,
|
|
35
|
+
};
|
|
36
|
+
}, [ propContext.propType ] );
|
|
37
|
+
|
|
38
|
+
return <FilterConfigContext.Provider value={ contextValue }>{ children }</FilterConfigContext.Provider>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function useFilterConfig(): FilterConfigContextValue {
|
|
42
|
+
const context = useContext( FilterConfigContext );
|
|
43
|
+
|
|
44
|
+
if ( ! context ) {
|
|
45
|
+
throw new Error( 'useFilterConfig must be used within FilterConfigProvider' );
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return context;
|
|
49
|
+
}
|
|
@@ -4,12 +4,11 @@ import { dropShadowFilterPropTypeUtil } from '@elementor/editor-props';
|
|
|
4
4
|
import { Grid } from '@elementor/ui';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
6
|
|
|
7
|
-
import { PropKeyProvider, PropProvider, useBoundProp } from '
|
|
8
|
-
import { ControlFormLabel } from '
|
|
9
|
-
import { PopoverGridContainer } from '
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { SizeControl } from '../size-control';
|
|
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 { ColorControl } from '../../color-control';
|
|
11
|
+
import { SizeControl } from '../../size-control';
|
|
13
12
|
|
|
14
13
|
const items = [
|
|
15
14
|
{
|
|
@@ -34,13 +33,7 @@ const items = [
|
|
|
34
33
|
},
|
|
35
34
|
];
|
|
36
35
|
|
|
37
|
-
export const DropShadowItemContent = ( {
|
|
38
|
-
units,
|
|
39
|
-
anchorEl,
|
|
40
|
-
}: {
|
|
41
|
-
units: LengthUnit[];
|
|
42
|
-
anchorEl?: HTMLElement | null;
|
|
43
|
-
} ) => {
|
|
36
|
+
export const DropShadowItemContent = ( { anchorEl }: { anchorEl?: HTMLElement | null } ) => {
|
|
44
37
|
const context = useBoundProp( dropShadowFilterPropTypeUtil );
|
|
45
38
|
const rowRefs = [ useRef< HTMLDivElement >( null ), useRef< HTMLDivElement >( null ) ];
|
|
46
39
|
|
|
@@ -56,7 +49,11 @@ export const DropShadowItemContent = ( {
|
|
|
56
49
|
{ item.bind === 'color' ? (
|
|
57
50
|
<ColorControl anchorEl={ anchorEl } />
|
|
58
51
|
) : (
|
|
59
|
-
<SizeControl
|
|
52
|
+
<SizeControl
|
|
53
|
+
anchorRef={ rowRefs[ item.rowIndex ] }
|
|
54
|
+
enablePropTypeUnits
|
|
55
|
+
defaultUnit="px"
|
|
56
|
+
/>
|
|
60
57
|
) }
|
|
61
58
|
</Grid>
|
|
62
59
|
</PropKeyProvider>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
type CreateOptions,
|
|
4
|
+
cssFilterFunctionPropUtil,
|
|
5
|
+
type FilterItemPropValue,
|
|
6
|
+
type PropKey,
|
|
7
|
+
} from '@elementor/editor-props';
|
|
8
|
+
import { Grid } from '@elementor/ui';
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
|
|
11
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../../bound-prop-context';
|
|
12
|
+
import { ControlFormLabel } from '../../components/control-form-label';
|
|
13
|
+
import { PopoverContent } from '../../components/popover-content';
|
|
14
|
+
import { PopoverGridContainer } from '../../components/popover-grid-container';
|
|
15
|
+
import { useRepeaterContext } from '../../components/unstable-repeater/context/repeater-context';
|
|
16
|
+
import { SelectControl } from '../select-control';
|
|
17
|
+
import { type FilterFunction } from './configs';
|
|
18
|
+
import { useFilterConfig } from './context/filter-config-context';
|
|
19
|
+
import { DropShadowItemContent } from './drop-shadow/drop-shadow-item-content';
|
|
20
|
+
import { SingleSizeItemContent } from './single-size/single-size-item-content';
|
|
21
|
+
|
|
22
|
+
type Value = FilterItemPropValue[ 'value' ];
|
|
23
|
+
|
|
24
|
+
export const FilterContent = () => {
|
|
25
|
+
const propContext = useBoundProp( cssFilterFunctionPropUtil );
|
|
26
|
+
const { filterOptions, getFilterFunctionConfig } = useFilterConfig();
|
|
27
|
+
|
|
28
|
+
const handleValueChange = ( value: Value, _?: CreateOptions, meta?: { bind?: PropKey } ) => {
|
|
29
|
+
let newValue = structuredClone( value );
|
|
30
|
+
const funcConfig = getFilterFunctionConfig( newValue?.func.value as FilterFunction );
|
|
31
|
+
|
|
32
|
+
if ( meta?.bind === 'func' ) {
|
|
33
|
+
newValue = funcConfig.defaultValue.value as FilterItemPropValue[ 'value' ];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if ( ! newValue.args ) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
propContext.setValue( newValue );
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<PropProvider { ...propContext } setValue={ handleValueChange }>
|
|
45
|
+
<PropKeyProvider bind="css-filter-func">
|
|
46
|
+
<PopoverContent p={ 1.5 }>
|
|
47
|
+
<PopoverGridContainer>
|
|
48
|
+
<Grid item xs={ 6 }>
|
|
49
|
+
<ControlFormLabel>{ __( 'Filter', 'elementor' ) }</ControlFormLabel>
|
|
50
|
+
</Grid>
|
|
51
|
+
<Grid item xs={ 6 }>
|
|
52
|
+
<PropKeyProvider bind="func">
|
|
53
|
+
<SelectControl options={ filterOptions } />
|
|
54
|
+
</PropKeyProvider>
|
|
55
|
+
</Grid>
|
|
56
|
+
</PopoverGridContainer>
|
|
57
|
+
<PropKeyProvider bind="args">
|
|
58
|
+
<FilterValueContent />
|
|
59
|
+
</PropKeyProvider>
|
|
60
|
+
</PopoverContent>
|
|
61
|
+
</PropKeyProvider>
|
|
62
|
+
</PropProvider>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const FilterValueContent = () => {
|
|
67
|
+
const { openItemIndex, items } = useRepeaterContext();
|
|
68
|
+
const currentItem = items[ openItemIndex ];
|
|
69
|
+
|
|
70
|
+
const filterFunc = ( currentItem.item.value as FilterItemPropValue[ 'value' ] ).func.value;
|
|
71
|
+
const isDropShadow = filterFunc === 'drop-shadow';
|
|
72
|
+
|
|
73
|
+
if ( isDropShadow ) {
|
|
74
|
+
return <DropShadowItemContent />;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return <SingleSizeItemContent filterFunc={ filterFunc as FilterFunction } />;
|
|
78
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type DropShadowFilterPropValue, type FilterItemPropValue } from '@elementor/editor-props';
|
|
3
|
+
import { styled, UnstableColorIndicator } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
export const FilterIcon = ( { value }: { value: FilterItemPropValue } ) => {
|
|
6
|
+
if ( value.value.func.value !== 'drop-shadow' ) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<StyledUnstableColorIndicator
|
|
12
|
+
size="inherit"
|
|
13
|
+
component="span"
|
|
14
|
+
value={ ( value.value.args as DropShadowFilterPropValue ).value?.color.value }
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const StyledUnstableColorIndicator = styled( UnstableColorIndicator )( ( { theme } ) => ( {
|
|
20
|
+
borderRadius: `${ theme.shape.borderRadius / 2 }px`,
|
|
21
|
+
} ) );
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { FilterItemPropValue } from '@elementor/editor-props';
|
|
3
|
+
|
|
4
|
+
import { DropShadowItemLabel } from './drop-shadow/drop-shadow-item-label';
|
|
5
|
+
import { SingleSizeItemLabel } from './single-size/single-size-item-label';
|
|
6
|
+
|
|
7
|
+
export const FilterLabel = ( { value }: { value: FilterItemPropValue } ) => {
|
|
8
|
+
if ( value.value.func.value === 'drop-shadow' ) {
|
|
9
|
+
return <DropShadowItemLabel value={ value } />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return <SingleSizeItemLabel value={ value } />;
|
|
13
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
backdropFilterPropTypeUtil,
|
|
4
|
+
type FilterItemPropValue,
|
|
5
|
+
filterPropTypeUtil,
|
|
6
|
+
type PropTypeUtil,
|
|
7
|
+
} from '@elementor/editor-props';
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
|
|
10
|
+
import { PropProvider, useBoundProp } from '../../bound-prop-context';
|
|
11
|
+
import {
|
|
12
|
+
Header,
|
|
13
|
+
Item,
|
|
14
|
+
ItemsContainer,
|
|
15
|
+
TooltipAddItemAction,
|
|
16
|
+
UnstableRepeater,
|
|
17
|
+
} from '../../components/unstable-repeater';
|
|
18
|
+
import { DisableItemAction } from '../../components/unstable-repeater/actions/disable-item-action';
|
|
19
|
+
import { DuplicateItemAction } from '../../components/unstable-repeater/actions/duplicate-item-action';
|
|
20
|
+
import { RemoveItemAction } from '../../components/unstable-repeater/actions/remove-item-action';
|
|
21
|
+
import { EditItemPopover } from '../../components/unstable-repeater/items/edit-item-popover';
|
|
22
|
+
import type { RepeatablePropValue } from '../../components/unstable-repeater/types';
|
|
23
|
+
import { createControl } from '../../create-control';
|
|
24
|
+
import { FilterConfigProvider, useFilterConfig } from './context/filter-config-context';
|
|
25
|
+
import { FilterContent } from './filter-content';
|
|
26
|
+
import { FilterIcon } from './filter-icon';
|
|
27
|
+
import { FilterLabel } from './filter-label';
|
|
28
|
+
|
|
29
|
+
type FilterPropName = {
|
|
30
|
+
filterPropName?: 'filter' | 'backdrop-filter';
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type Config = {
|
|
34
|
+
propTypeUtil: PropTypeUtil< string, FilterItemPropValue[] >;
|
|
35
|
+
label: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const FILTER_CONFIG: Record< string, Config > = {
|
|
39
|
+
filter: {
|
|
40
|
+
propTypeUtil: filterPropTypeUtil,
|
|
41
|
+
label: __( 'Filters', 'elementor' ),
|
|
42
|
+
},
|
|
43
|
+
'backdrop-filter': {
|
|
44
|
+
propTypeUtil: backdropFilterPropTypeUtil,
|
|
45
|
+
label: __( 'Backdrop Filters', 'elementor' ),
|
|
46
|
+
},
|
|
47
|
+
} as const;
|
|
48
|
+
|
|
49
|
+
export const FilterRepeaterControl = createControl( ( { filterPropName = 'filter' }: FilterPropName ) => {
|
|
50
|
+
const { propTypeUtil, label } = ensureFilterConfig( filterPropName );
|
|
51
|
+
const { propType, value: filterValues, setValue } = useBoundProp( propTypeUtil );
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<FilterConfigProvider>
|
|
55
|
+
<PropProvider propType={ propType } value={ filterValues } setValue={ setValue }>
|
|
56
|
+
<Repeater
|
|
57
|
+
propTypeUtil={ propTypeUtil as PropTypeUtil< string, RepeatablePropValue[] > }
|
|
58
|
+
label={ label }
|
|
59
|
+
/>
|
|
60
|
+
</PropProvider>
|
|
61
|
+
</FilterConfigProvider>
|
|
62
|
+
);
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
type RepeaterProps = { propTypeUtil: PropTypeUtil< string, RepeatablePropValue[] >; label: string };
|
|
66
|
+
|
|
67
|
+
const Repeater = ( { propTypeUtil, label }: RepeaterProps ) => {
|
|
68
|
+
const { getInitialValue } = useFilterConfig();
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<UnstableRepeater initial={ getInitialValue() as RepeatablePropValue } propTypeUtil={ propTypeUtil }>
|
|
72
|
+
<Header label={ label }>
|
|
73
|
+
<TooltipAddItemAction newItemIndex={ 0 } />
|
|
74
|
+
</Header>
|
|
75
|
+
<ItemsContainer itemTemplate={ <Item Label={ FilterLabel } Icon={ FilterIcon } /> }>
|
|
76
|
+
<DuplicateItemAction />
|
|
77
|
+
<DisableItemAction />
|
|
78
|
+
<RemoveItemAction />
|
|
79
|
+
</ItemsContainer>
|
|
80
|
+
<EditItemPopover>
|
|
81
|
+
<FilterContent />
|
|
82
|
+
</EditItemPopover>
|
|
83
|
+
</UnstableRepeater>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function ensureFilterConfig( name: string ): Config {
|
|
88
|
+
if ( name && name in FILTER_CONFIG ) {
|
|
89
|
+
return FILTER_CONFIG[ name ];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return FILTER_CONFIG.filter;
|
|
93
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
blurFilterPropTypeUtil,
|
|
5
|
+
colorToneFilterPropTypeUtil,
|
|
6
|
+
type createPropUtils,
|
|
7
|
+
hueRotateFilterPropTypeUtil,
|
|
8
|
+
intensityFilterPropTypeUtil,
|
|
9
|
+
} from '@elementor/editor-props';
|
|
10
|
+
import { Grid } from '@elementor/ui';
|
|
11
|
+
|
|
12
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../../../bound-prop-context';
|
|
13
|
+
import { ControlFormLabel } from '../../../components/control-form-label';
|
|
14
|
+
import { PopoverGridContainer } from '../../../components/popover-grid-container';
|
|
15
|
+
import { SizeControl } from '../../size-control';
|
|
16
|
+
import { type FilterFunction } from '../configs';
|
|
17
|
+
import { useFilterConfig } from '../context/filter-config-context';
|
|
18
|
+
|
|
19
|
+
export const propTypeMap: Record< string, ReturnType< typeof createPropUtils > > = {
|
|
20
|
+
blur: blurFilterPropTypeUtil,
|
|
21
|
+
intensity: intensityFilterPropTypeUtil,
|
|
22
|
+
'hue-rotate': hueRotateFilterPropTypeUtil,
|
|
23
|
+
'color-tone': colorToneFilterPropTypeUtil,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const SingleSizeItemContent = ( { filterFunc }: { filterFunc: FilterFunction } ) => {
|
|
27
|
+
const rowRef = useRef< HTMLDivElement >( null );
|
|
28
|
+
const { getFilterFunctionConfig } = useFilterConfig();
|
|
29
|
+
const { valueName, filterFunctionGroup } = getFilterFunctionConfig( filterFunc );
|
|
30
|
+
const context = useBoundProp( propTypeMap[ filterFunctionGroup as string ] );
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<PropProvider { ...context }>
|
|
34
|
+
<PropKeyProvider bind={ filterFunctionGroup }>
|
|
35
|
+
<PropKeyProvider bind={ 'size' }>
|
|
36
|
+
<PopoverGridContainer ref={ rowRef }>
|
|
37
|
+
<Grid item xs={ 6 }>
|
|
38
|
+
<ControlFormLabel>{ valueName }</ControlFormLabel>
|
|
39
|
+
</Grid>
|
|
40
|
+
<Grid item xs={ 6 }>
|
|
41
|
+
<SizeControl anchorRef={ rowRef } enablePropTypeUnits />
|
|
42
|
+
</Grid>
|
|
43
|
+
</PopoverGridContainer>
|
|
44
|
+
</PropKeyProvider>
|
|
45
|
+
</PropKeyProvider>
|
|
46
|
+
</PropProvider>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { FilterItemPropValue, SizePropValue } from '@elementor/editor-props';
|
|
3
|
+
import { Box } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
import { lengthUnits } from '../../../utils/size-control';
|
|
6
|
+
import { type FilterFunction } from '../configs';
|
|
7
|
+
import { useFilterConfig } from '../context/filter-config-context';
|
|
8
|
+
|
|
9
|
+
export const SingleSizeItemLabel = ( { value }: { value: FilterItemPropValue } ) => {
|
|
10
|
+
const { func, args } = value.value;
|
|
11
|
+
const { getFilterFunctionConfig } = useFilterConfig();
|
|
12
|
+
const { defaultValue } = getFilterFunctionConfig( ( func.value ?? '' ) as FilterFunction );
|
|
13
|
+
const defaultUnit =
|
|
14
|
+
( defaultValue.value.args.value as { size: SizePropValue } )?.size?.value?.unit ?? lengthUnits[ 0 ];
|
|
15
|
+
|
|
16
|
+
const { unit, size } = ( args.value as { size: SizePropValue } ).size?.value ?? { unit: defaultUnit, size: 0 };
|
|
17
|
+
|
|
18
|
+
const label = (
|
|
19
|
+
<Box component="span" style={ { textTransform: 'capitalize' } }>
|
|
20
|
+
{ func.value ?? '' }:
|
|
21
|
+
</Box>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Box component="span">
|
|
26
|
+
{ label }
|
|
27
|
+
{ unit !== 'custom' ? ` ${ size ?? 0 }${ unit ?? defaultUnit }` : size }
|
|
28
|
+
</Box>
|
|
29
|
+
);
|
|
30
|
+
};
|