@elementor/editor-components 3.33.0-299 → 3.33.0-300
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.js +196 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +183 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -16
- package/src/components/overridable-props/indicator.tsx +81 -0
- package/src/components/overridable-props/overridable-prop-indicator.tsx +95 -0
- package/src/init.ts +9 -0
- package/src/prop-types/component-overridable-prop-type.ts +15 -0
- package/src/store/store.ts +6 -0
- package/src/types.ts +27 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-components",
|
|
3
3
|
"description": "Elementor editor components",
|
|
4
|
-
"version": "3.33.0-
|
|
4
|
+
"version": "3.33.0-300",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,23 +40,25 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor": "3.33.0-
|
|
44
|
-
"@elementor/editor-canvas": "3.33.0-
|
|
45
|
-
"@elementor/editor-
|
|
46
|
-
"@elementor/editor-
|
|
47
|
-
"@elementor/editor-
|
|
48
|
-
"@elementor/editor-
|
|
49
|
-
"@elementor/editor-
|
|
50
|
-
"@elementor/editor-
|
|
51
|
-
"@elementor/editor-
|
|
52
|
-
"@elementor/
|
|
43
|
+
"@elementor/editor": "3.33.0-300",
|
|
44
|
+
"@elementor/editor-canvas": "3.33.0-300",
|
|
45
|
+
"@elementor/editor-controls": "3.33.0-300",
|
|
46
|
+
"@elementor/editor-documents": "3.33.0-300",
|
|
47
|
+
"@elementor/editor-editing-panel": "3.33.0-300",
|
|
48
|
+
"@elementor/editor-elements": "3.33.0-300",
|
|
49
|
+
"@elementor/editor-elements-panel": "3.33.0-300",
|
|
50
|
+
"@elementor/editor-props": "3.33.0-300",
|
|
51
|
+
"@elementor/editor-styles-repository": "3.33.0-300",
|
|
52
|
+
"@elementor/editor-ui": "3.33.0-300",
|
|
53
|
+
"@elementor/editor-v1-adapters": "3.33.0-300",
|
|
54
|
+
"@elementor/http-client": "3.33.0-300",
|
|
53
55
|
"@elementor/icons": "^1.61.0",
|
|
54
|
-
"@elementor/mixpanel": "3.33.0-
|
|
55
|
-
"@elementor/query": "3.33.0-
|
|
56
|
-
"@elementor/schema": "3.33.0-
|
|
57
|
-
"@elementor/store": "3.33.0-
|
|
56
|
+
"@elementor/mixpanel": "3.33.0-300",
|
|
57
|
+
"@elementor/query": "3.33.0-300",
|
|
58
|
+
"@elementor/schema": "3.33.0-300",
|
|
59
|
+
"@elementor/store": "3.33.0-300",
|
|
58
60
|
"@elementor/ui": "1.36.17",
|
|
59
|
-
"@elementor/utils": "3.33.0-
|
|
61
|
+
"@elementor/utils": "3.33.0-300",
|
|
60
62
|
"@wordpress/i18n": "^5.13.0"
|
|
61
63
|
},
|
|
62
64
|
"peerDependencies": {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { CheckIcon, PlusIcon } from '@elementor/icons';
|
|
4
|
+
import { type bindTrigger, Box, styled } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
const SIZE = 'tiny';
|
|
8
|
+
|
|
9
|
+
const IconContainer = styled( Box )`
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
opacity: 0;
|
|
12
|
+
transition: opacity 0.2s ease-in-out;
|
|
13
|
+
|
|
14
|
+
& > svg {
|
|
15
|
+
position: absolute;
|
|
16
|
+
top: 50%;
|
|
17
|
+
left: 50%;
|
|
18
|
+
transform: translate( -50%, -50% );
|
|
19
|
+
width: 10px;
|
|
20
|
+
height: 10px;
|
|
21
|
+
fill: ${ ( { theme } ) => theme.palette.primary.contrastText };
|
|
22
|
+
stroke: ${ ( { theme } ) => theme.palette.primary.contrastText };
|
|
23
|
+
stroke-width: 2px;
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const Content = styled( Box )`
|
|
28
|
+
position: relative;
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
width: 16px;
|
|
34
|
+
height: 16px;
|
|
35
|
+
margin-inline: ${ ( { theme } ) => theme.spacing( 0.5 ) };
|
|
36
|
+
|
|
37
|
+
&:before {
|
|
38
|
+
content: '';
|
|
39
|
+
display: block;
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 50%;
|
|
42
|
+
left: 50%;
|
|
43
|
+
transform: translate( -50%, -50% ) rotate( 45deg );
|
|
44
|
+
width: 5px;
|
|
45
|
+
height: 5px;
|
|
46
|
+
border-radius: 1px;
|
|
47
|
+
background-color: ${ ( { theme } ) => theme.palette.primary.main };
|
|
48
|
+
transition: all 0.1s ease-in-out;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&:hover,
|
|
52
|
+
&.enlarged {
|
|
53
|
+
&:before {
|
|
54
|
+
width: 12px;
|
|
55
|
+
height: 12px;
|
|
56
|
+
border-radius: 2px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.icon {
|
|
60
|
+
opacity: 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
type Props = {
|
|
66
|
+
isOverridable: boolean;
|
|
67
|
+
triggerProps: ReturnType< typeof bindTrigger >;
|
|
68
|
+
isOpen: boolean;
|
|
69
|
+
};
|
|
70
|
+
export const Indicator = forwardRef< HTMLDivElement, Props >( ( { triggerProps, isOpen, isOverridable }, ref ) => (
|
|
71
|
+
<Content ref={ ref } { ...triggerProps } className={ isOpen || isOverridable ? 'enlarged' : '' }>
|
|
72
|
+
<IconContainer
|
|
73
|
+
className="icon"
|
|
74
|
+
aria-label={
|
|
75
|
+
isOverridable ? __( 'Overridable property', 'elementor' ) : __( 'Make prop overridable', 'elementor' )
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
{ isOverridable ? <CheckIcon fontSize={ SIZE } /> : <PlusIcon fontSize={ SIZE } /> }
|
|
79
|
+
</IconContainer>
|
|
80
|
+
</Content>
|
|
81
|
+
) );
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useBoundProp } from '@elementor/editor-controls';
|
|
3
|
+
import { getV1CurrentDocument } from '@elementor/editor-documents';
|
|
4
|
+
import { useElement } from '@elementor/editor-editing-panel';
|
|
5
|
+
import { __getState as getState } from '@elementor/store';
|
|
6
|
+
import { bindPopover, bindTrigger, Popover, Tooltip, usePopupState } from '@elementor/ui';
|
|
7
|
+
import { __ } from '@wordpress/i18n';
|
|
8
|
+
|
|
9
|
+
import { componentOverridablePropTypeUtil } from '../../prop-types/component-overridable-prop-type';
|
|
10
|
+
import { selectOverridableProps } from '../../store/store';
|
|
11
|
+
import { type OverridableProps } from '../../types';
|
|
12
|
+
import { COMPONENT_DOCUMENT_TYPE } from '../consts';
|
|
13
|
+
import { Indicator } from './indicator';
|
|
14
|
+
|
|
15
|
+
const FORBIDDEN_KEYS = [ '_cssid', 'attributes' ];
|
|
16
|
+
|
|
17
|
+
export function OverridablePropIndicator() {
|
|
18
|
+
const { bind, value } = useBoundProp();
|
|
19
|
+
const currentDocument = getV1CurrentDocument();
|
|
20
|
+
|
|
21
|
+
if ( currentDocument.config.type !== COMPONENT_DOCUMENT_TYPE || ! currentDocument.id ) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if ( ! isPropAllowed( bind ) ) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const overridableProps = selectOverridableProps( getState(), currentDocument.id );
|
|
30
|
+
const isOverridable = componentOverridablePropTypeUtil.isValid( value );
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Content
|
|
34
|
+
componentId={ currentDocument.id }
|
|
35
|
+
isOverridable={ isOverridable }
|
|
36
|
+
overridableProps={ overridableProps }
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type Props = {
|
|
42
|
+
componentId: number;
|
|
43
|
+
isOverridable: boolean;
|
|
44
|
+
overridableProps?: OverridableProps;
|
|
45
|
+
};
|
|
46
|
+
export function Content( { isOverridable, overridableProps }: Props ) {
|
|
47
|
+
const {
|
|
48
|
+
element: { id: elementId },
|
|
49
|
+
} = useElement();
|
|
50
|
+
const { bind } = useBoundProp();
|
|
51
|
+
|
|
52
|
+
const popupState = usePopupState( {
|
|
53
|
+
variant: 'popover',
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
const triggerProps = bindTrigger( popupState );
|
|
57
|
+
const popoverProps = bindPopover( popupState );
|
|
58
|
+
|
|
59
|
+
const overridableConfig = Object.values( overridableProps?.props ?? {} ).find(
|
|
60
|
+
( prop ) => prop.elementId === elementId && prop.propKey === bind
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<>
|
|
65
|
+
<Tooltip placement="top" title={ __( 'Override Property', 'elementor' ) }>
|
|
66
|
+
<Indicator
|
|
67
|
+
triggerProps={ triggerProps }
|
|
68
|
+
isOpen={ !! popoverProps.open }
|
|
69
|
+
isOverridable={ isOverridable }
|
|
70
|
+
/>
|
|
71
|
+
</Tooltip>
|
|
72
|
+
<Popover
|
|
73
|
+
disableScrollLock
|
|
74
|
+
anchorOrigin={ {
|
|
75
|
+
vertical: 'bottom',
|
|
76
|
+
horizontal: 'right',
|
|
77
|
+
} }
|
|
78
|
+
transformOrigin={ {
|
|
79
|
+
vertical: 'top',
|
|
80
|
+
horizontal: 'right',
|
|
81
|
+
} }
|
|
82
|
+
PaperProps={ {
|
|
83
|
+
sx: { my: 2.5 },
|
|
84
|
+
} }
|
|
85
|
+
{ ...popoverProps }
|
|
86
|
+
>
|
|
87
|
+
{ JSON.stringify( overridableConfig ) /** TODO: replace with actual form */ }
|
|
88
|
+
</Popover>
|
|
89
|
+
</>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function isPropAllowed( bind: string ) {
|
|
94
|
+
return ! FORBIDDEN_KEYS.includes( bind );
|
|
95
|
+
}
|
package/src/init.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
settingsTransformersRegistry,
|
|
6
6
|
} from '@elementor/editor-canvas';
|
|
7
7
|
import { getV1CurrentDocument } from '@elementor/editor-documents';
|
|
8
|
+
import { FIELD_TYPE, registerFieldIndicator } from '@elementor/editor-editing-panel';
|
|
8
9
|
import { type V1ElementData } from '@elementor/editor-elements';
|
|
9
10
|
import { injectTab } from '@elementor/editor-elements-panel';
|
|
10
11
|
import { stylesRepository } from '@elementor/editor-styles-repository';
|
|
@@ -18,6 +19,7 @@ import { Components } from './components/components-tab/components';
|
|
|
18
19
|
import { CreateComponentForm } from './components/create-component-form/create-component-form';
|
|
19
20
|
import { EditComponent } from './components/edit-component/edit-component';
|
|
20
21
|
import { openEditModeDialog } from './components/in-edit-mode';
|
|
22
|
+
import { OverridablePropIndicator } from './components/overridable-props/overridable-prop-indicator';
|
|
21
23
|
import { createComponentType, TYPE } from './create-component-type';
|
|
22
24
|
import { PopulateStore } from './populate-store';
|
|
23
25
|
import { componentsStylesProvider } from './store/components-styles-provider';
|
|
@@ -82,6 +84,13 @@ export function init() {
|
|
|
82
84
|
loadComponentsStyles( ( config?.elements as V1ElementData[] ) ?? [] );
|
|
83
85
|
} );
|
|
84
86
|
|
|
87
|
+
registerFieldIndicator( {
|
|
88
|
+
fieldType: FIELD_TYPE.SETTINGS,
|
|
89
|
+
id: 'component-overridable-prop',
|
|
90
|
+
priority: 1,
|
|
91
|
+
indicator: OverridablePropIndicator,
|
|
92
|
+
} );
|
|
93
|
+
|
|
85
94
|
settingsTransformersRegistry.register( 'component-instance', componentInstanceTransformer );
|
|
86
95
|
settingsTransformersRegistry.register( 'overridable', componentOverridableTransformer );
|
|
87
96
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createPropUtils } from '@elementor/editor-props';
|
|
2
|
+
import { z } from '@elementor/schema';
|
|
3
|
+
|
|
4
|
+
export const componentOverridablePropTypeUtil = createPropUtils(
|
|
5
|
+
'overridable',
|
|
6
|
+
z.object( {
|
|
7
|
+
override_key: z.string(),
|
|
8
|
+
default_value: z
|
|
9
|
+
.object( {
|
|
10
|
+
$$type: z.string(),
|
|
11
|
+
value: z.unknown(),
|
|
12
|
+
} )
|
|
13
|
+
.nullable(),
|
|
14
|
+
} )
|
|
15
|
+
);
|
package/src/store/store.ts
CHANGED
|
@@ -88,6 +88,8 @@ const selectLoadStatus = ( state: ComponentsSlice ) => state[ SLICE_NAME ].loadS
|
|
|
88
88
|
const selectStylesDefinitions = ( state: ComponentsSlice ) => state[ SLICE_NAME ].styles ?? {};
|
|
89
89
|
const selectUnpublishedData = ( state: ComponentsSlice ) => state[ SLICE_NAME ].unpublishedData;
|
|
90
90
|
const getCreatedThisSession = ( state: ComponentsSlice ) => state[ SLICE_NAME ].createdThisSession;
|
|
91
|
+
const selectComponent = ( state: ComponentsSlice, componentId: ComponentId ) =>
|
|
92
|
+
state[ SLICE_NAME ].data.find( ( component ) => component.id === componentId );
|
|
91
93
|
|
|
92
94
|
export const selectComponents = createSelector(
|
|
93
95
|
selectData,
|
|
@@ -109,3 +111,7 @@ export const selectCreatedThisSession = createSelector(
|
|
|
109
111
|
getCreatedThisSession,
|
|
110
112
|
( createdThisSession ) => createdThisSession
|
|
111
113
|
);
|
|
114
|
+
export const selectOverridableProps = createSelector(
|
|
115
|
+
selectComponent,
|
|
116
|
+
( component: PublishedComponent | undefined ) => component?.overridableProps
|
|
117
|
+
);
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type V1ElementData } from '@elementor/editor-elements';
|
|
2
|
-
import { type TransformablePropValue } from '@elementor/editor-props';
|
|
2
|
+
import { type PropValue, type TransformablePropValue } from '@elementor/editor-props';
|
|
3
3
|
import type { StyleDefinition } from '@elementor/editor-styles';
|
|
4
4
|
|
|
5
5
|
export type ComponentFormValues = {
|
|
@@ -20,9 +20,35 @@ export type UnpublishedComponent = BaseComponent & {
|
|
|
20
20
|
elements: V1ElementData[];
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
export type OverridableProp = {
|
|
24
|
+
overrideKey: string;
|
|
25
|
+
label: string;
|
|
26
|
+
elementId: string;
|
|
27
|
+
propKey: string;
|
|
28
|
+
elType: string;
|
|
29
|
+
widgetType: string;
|
|
30
|
+
defaultValue: PropValue;
|
|
31
|
+
groupId: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type OverridablePropGroup = {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
props: string[];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type OverridableProps = {
|
|
41
|
+
props: Record< string, OverridableProp >;
|
|
42
|
+
groups: {
|
|
43
|
+
items: Record< string, OverridablePropGroup >;
|
|
44
|
+
order: string[];
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
23
48
|
type BaseComponent = {
|
|
24
49
|
uid: string;
|
|
25
50
|
name: string;
|
|
51
|
+
overridableProps?: OverridableProps;
|
|
26
52
|
};
|
|
27
53
|
|
|
28
54
|
export type DocumentStatus = 'publish' | 'draft';
|