@elementor/editor-components 3.33.0-235 → 3.33.0-237
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 +378 -97
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +362 -77
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/components-tab/components-item.tsx +11 -2
- package/src/components/create-component-form/utils/replace-element-with-component.ts +3 -1
- package/src/components/edit-component/component-modal.tsx +134 -0
- package/src/components/edit-component/edit-component.tsx +119 -0
- package/src/create-component-type.ts +8 -2
- package/src/hooks/use-canvas-document.ts +6 -0
- package/src/hooks/use-element-rect.ts +81 -0
- package/src/init.ts +9 -2
- package/src/store/load-components-styles.ts +3 -3
- package/src/store/store.ts +9 -0
- package/src/types.ts +0 -11
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type CSSProperties, useEffect } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
import { useCanvasDocument } from '../../hooks/use-canvas-document';
|
|
7
|
+
import { useElementRect } from '../../hooks/use-element-rect';
|
|
8
|
+
|
|
9
|
+
type ModalProps = {
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
};
|
|
13
|
+
export function ComponentModal( { element, onClose }: ModalProps ) {
|
|
14
|
+
const canvasDocument = useCanvasDocument();
|
|
15
|
+
|
|
16
|
+
useEffect( () => {
|
|
17
|
+
const handleEsc = ( event: KeyboardEvent ) => {
|
|
18
|
+
if ( event.key === 'Escape' ) {
|
|
19
|
+
onClose();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
canvasDocument?.body.addEventListener( 'keydown', handleEsc );
|
|
24
|
+
|
|
25
|
+
return () => {
|
|
26
|
+
canvasDocument?.body.removeEventListener( 'keydown', handleEsc );
|
|
27
|
+
};
|
|
28
|
+
}, [ canvasDocument, onClose ] );
|
|
29
|
+
|
|
30
|
+
if ( ! canvasDocument?.body ) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return createPortal(
|
|
35
|
+
<>
|
|
36
|
+
<BlockEditPage />
|
|
37
|
+
<Backdrop canvas={ canvasDocument } element={ element } onClose={ onClose } />
|
|
38
|
+
</>,
|
|
39
|
+
canvasDocument.body
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function Backdrop( { canvas, element, onClose }: { canvas: HTMLDocument; element: HTMLElement; onClose: () => void } ) {
|
|
44
|
+
const rect = useElementRect( element );
|
|
45
|
+
const backdropStyle: CSSProperties = {
|
|
46
|
+
position: 'fixed',
|
|
47
|
+
top: 0,
|
|
48
|
+
left: 0,
|
|
49
|
+
width: '100vw',
|
|
50
|
+
height: '100vh',
|
|
51
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
52
|
+
zIndex: 999,
|
|
53
|
+
pointerEvents: 'painted',
|
|
54
|
+
cursor: 'pointer',
|
|
55
|
+
clipPath: getRoundedRectPath( rect, canvas.defaultView as Window, 5 ),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const handleKeyDown = ( event: React.KeyboardEvent ) => {
|
|
59
|
+
if ( event.key === 'Enter' || event.key === ' ' ) {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
onClose();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
style={ backdropStyle }
|
|
68
|
+
onClick={ onClose }
|
|
69
|
+
onKeyDown={ handleKeyDown }
|
|
70
|
+
role="button"
|
|
71
|
+
tabIndex={ 0 }
|
|
72
|
+
aria-label={ __( 'Exit component editing mode', 'elementor' ) }
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getRoundedRectPath( rect: DOMRect, viewport: Window, borderRadius: number ) {
|
|
78
|
+
const padding = borderRadius / 2;
|
|
79
|
+
const { x: originalX, y: originalY, width: originalWidth, height: originalHeight } = rect;
|
|
80
|
+
const x = originalX - padding;
|
|
81
|
+
const y = originalY - padding;
|
|
82
|
+
const width = originalWidth + 2 * padding;
|
|
83
|
+
const height = originalHeight + 2 * padding;
|
|
84
|
+
const radius = Math.min( borderRadius, width / 2, height / 2 );
|
|
85
|
+
|
|
86
|
+
const { innerWidth: vw, innerHeight: vh } = viewport;
|
|
87
|
+
|
|
88
|
+
const path = `path(evenodd, 'M 0 0
|
|
89
|
+
L ${ vw } 0
|
|
90
|
+
L ${ vw } ${ vh }
|
|
91
|
+
L 0 ${ vh }
|
|
92
|
+
Z
|
|
93
|
+
M ${ x + radius } ${ y }
|
|
94
|
+
L ${ x + width - radius } ${ y }
|
|
95
|
+
A ${ radius } ${ radius } 0 0 1 ${ x + width } ${ y + radius }
|
|
96
|
+
L ${ x + width } ${ y + height - radius }
|
|
97
|
+
A ${ radius } ${ radius } 0 0 1 ${ x + width - radius } ${ y + height }
|
|
98
|
+
L ${ x + radius } ${ y + height }
|
|
99
|
+
A ${ radius } ${ radius } 0 0 1 ${ x } ${ y + height - radius }
|
|
100
|
+
L ${ x } ${ y + radius }
|
|
101
|
+
A ${ radius } ${ radius } 0 0 1 ${ x + radius } ${ y }
|
|
102
|
+
Z'
|
|
103
|
+
)`;
|
|
104
|
+
|
|
105
|
+
return path.replace( /\s{2,}/g, ' ' );
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* when switching to another document id, we get a document handler when hovering
|
|
110
|
+
* this functionality originates in Pro, and is intended for editing templates, e.g. header/footer
|
|
111
|
+
* in components we don't want that, so the easy way out is to prevent it of being displayed via a CSS rule
|
|
112
|
+
*/
|
|
113
|
+
function BlockEditPage() {
|
|
114
|
+
const blockV3DocumentHandlesStyles = `
|
|
115
|
+
.elementor-editor-active {
|
|
116
|
+
& .elementor-section-wrap.ui-sortable {
|
|
117
|
+
display: contents;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
& *[data-editable-elementor-document]:not(.elementor-edit-mode):hover {
|
|
121
|
+
& .elementor-document-handle:not(.elementor-document-save-back-handle) {
|
|
122
|
+
display: none;
|
|
123
|
+
|
|
124
|
+
&::before,
|
|
125
|
+
& .elementor-document-handle__inner {
|
|
126
|
+
display: none;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
return <style data-e-style-id="e-block-v3-document-handles-styles">{ blockV3DocumentHandlesStyles }</style>;
|
|
134
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type Dispatch, type SetStateAction, useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { getV1DocumentsManager, type V1Document } from '@elementor/editor-documents';
|
|
4
|
+
import { type V1Element } from '@elementor/editor-elements';
|
|
5
|
+
import {
|
|
6
|
+
__privateListenTo as listenTo,
|
|
7
|
+
__privateRunCommand as runCommand,
|
|
8
|
+
commandEndEvent,
|
|
9
|
+
} from '@elementor/editor-v1-adapters';
|
|
10
|
+
import { __useSelector as useSelector } from '@elementor/store';
|
|
11
|
+
|
|
12
|
+
import { apiClient } from '../../api';
|
|
13
|
+
import { selectComponentsObject } from '../../store/store';
|
|
14
|
+
import { ComponentModal } from './component-modal';
|
|
15
|
+
|
|
16
|
+
type ComponentsPathItem = {
|
|
17
|
+
instanceId: string | undefined;
|
|
18
|
+
component: V1Document;
|
|
19
|
+
};
|
|
20
|
+
export function EditComponent() {
|
|
21
|
+
const [ componentsPath, setComponentsPath ] = useState< ComponentsPathItem[] >( [] );
|
|
22
|
+
|
|
23
|
+
useHandleDocumentSwitches( componentsPath, setComponentsPath );
|
|
24
|
+
const onBack = useNavigateBack( componentsPath );
|
|
25
|
+
|
|
26
|
+
const currentItem = componentsPath.at( -1 );
|
|
27
|
+
const { component: currentComponent } = currentItem ?? {};
|
|
28
|
+
|
|
29
|
+
const widget = currentComponent?.container as V1Element;
|
|
30
|
+
const container = ( widget?.view?.el?.children?.[ 0 ] ?? null ) as HTMLElement | null;
|
|
31
|
+
const elementDom = container?.children[ 0 ] as HTMLElement | null;
|
|
32
|
+
|
|
33
|
+
if ( ! elementDom ) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return <ComponentModal element={ elementDom } onClose={ onBack } />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function useHandleDocumentSwitches(
|
|
41
|
+
path: ComponentsPathItem[],
|
|
42
|
+
setPath: Dispatch< SetStateAction< ComponentsPathItem[] > >
|
|
43
|
+
) {
|
|
44
|
+
const components = useSelector( selectComponentsObject );
|
|
45
|
+
const documentsManager = getV1DocumentsManager();
|
|
46
|
+
|
|
47
|
+
useEffect(
|
|
48
|
+
() =>
|
|
49
|
+
listenTo( commandEndEvent( 'editor/documents/attach-preview' ), () => {
|
|
50
|
+
const { component: currentComponent } = path.at( -1 ) ?? {};
|
|
51
|
+
const { id: currentComponentId } = currentComponent ?? {};
|
|
52
|
+
const nextDocument = documentsManager.getCurrent();
|
|
53
|
+
|
|
54
|
+
if ( nextDocument.id === currentComponentId ) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if ( currentComponentId ) {
|
|
59
|
+
apiClient.unlockComponent( currentComponentId );
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const isComponent = !! components?.[ nextDocument.id ];
|
|
63
|
+
|
|
64
|
+
if ( ! isComponent ) {
|
|
65
|
+
setPath( [] );
|
|
66
|
+
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setPath( getUpdatedComponentPath( path, nextDocument ) );
|
|
71
|
+
} ),
|
|
72
|
+
[ path, setPath, components, documentsManager ]
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getUpdatedComponentPath( path: ComponentsPathItem[], nextDocument: V1Document ): ComponentsPathItem[] {
|
|
77
|
+
const componentIndex = path.findIndex( ( { component } ) => component.id === nextDocument.id );
|
|
78
|
+
|
|
79
|
+
if ( componentIndex >= 0 ) {
|
|
80
|
+
// When exiting the editing of a nested component - we in fact go back a step
|
|
81
|
+
// so we need to make sure the path is cleaned up of any newer items
|
|
82
|
+
// By doing it with the slice and not a simple pop() - we could jump to any component in the path and make sure it becomes the current one
|
|
83
|
+
return path.slice( 0, componentIndex + 1 );
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return [
|
|
87
|
+
...path,
|
|
88
|
+
{
|
|
89
|
+
instanceId: nextDocument?.container.view?.el?.dataset.id,
|
|
90
|
+
component: nextDocument,
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function useNavigateBack( path: ComponentsPathItem[] ) {
|
|
96
|
+
const documentsManager = getV1DocumentsManager();
|
|
97
|
+
|
|
98
|
+
return useCallback( () => {
|
|
99
|
+
const { component: prevComponent, instanceId: prevComponentInstanceId } = path.at( -2 ) ?? {};
|
|
100
|
+
const { id: prevComponentId } = prevComponent ?? {};
|
|
101
|
+
const switchToDocument = ( id: number, selector?: string ) => {
|
|
102
|
+
runCommand( 'editor/documents/switch', {
|
|
103
|
+
id,
|
|
104
|
+
selector,
|
|
105
|
+
mode: 'autosave',
|
|
106
|
+
setAsInitial: false,
|
|
107
|
+
shouldScroll: false,
|
|
108
|
+
} );
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if ( prevComponentId && prevComponentInstanceId ) {
|
|
112
|
+
switchToDocument( prevComponentId, `[data-id="${ prevComponentInstanceId }"]` );
|
|
113
|
+
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
switchToDocument( documentsManager.getInitialId() );
|
|
118
|
+
}, [ path, documentsManager ] );
|
|
119
|
+
}
|
|
@@ -106,15 +106,21 @@ function createComponentView(
|
|
|
106
106
|
id: this.getComponentId()?.value as number,
|
|
107
107
|
mode: 'autosave',
|
|
108
108
|
selector: `[data-id="${ this.model.get( 'id' ) }"]`,
|
|
109
|
+
shouldScroll: false,
|
|
109
110
|
} );
|
|
110
|
-
apiClient.lockComponent( this.getComponentId()?.value as number );
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
handleDblClick( e: MouseEvent ) {
|
|
115
|
+
e.stopPropagation();
|
|
116
|
+
|
|
117
|
+
this.switchDocument();
|
|
118
|
+
}
|
|
119
|
+
|
|
114
120
|
events() {
|
|
115
121
|
return {
|
|
116
122
|
...super.events(),
|
|
117
|
-
dblclick: this.
|
|
123
|
+
dblclick: this.handleDblClick,
|
|
118
124
|
};
|
|
119
125
|
}
|
|
120
126
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCanvasIframeDocument } from '@elementor/editor-canvas';
|
|
2
|
+
import { __privateUseListenTo as useListenTo, commandEndEvent } from '@elementor/editor-v1-adapters';
|
|
3
|
+
|
|
4
|
+
export function useCanvasDocument() {
|
|
5
|
+
return useListenTo( commandEndEvent( 'editor/documents/attach-preview' ), () => getCanvasIframeDocument() );
|
|
6
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { throttle } from '@elementor/utils';
|
|
3
|
+
|
|
4
|
+
export function useElementRect( element: HTMLElement | null ) {
|
|
5
|
+
const [ rect, setRect ] = useState< DOMRect >( new DOMRect( 0, 0, 0, 0 ) );
|
|
6
|
+
|
|
7
|
+
const onChange = throttle(
|
|
8
|
+
() => {
|
|
9
|
+
setRect( element?.getBoundingClientRect() ?? new DOMRect( 0, 0, 0, 0 ) );
|
|
10
|
+
},
|
|
11
|
+
20,
|
|
12
|
+
true
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
useScrollListener( { element, onChange } );
|
|
16
|
+
useResizeListener( { element, onChange } );
|
|
17
|
+
useMutationsListener( { element, onChange } );
|
|
18
|
+
|
|
19
|
+
useEffect(
|
|
20
|
+
() => () => {
|
|
21
|
+
onChange.cancel();
|
|
22
|
+
},
|
|
23
|
+
[ onChange ]
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return rect;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type ListenerProps = {
|
|
30
|
+
element: HTMLElement | null;
|
|
31
|
+
onChange: () => void;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function useScrollListener( { element, onChange }: ListenerProps ) {
|
|
35
|
+
useEffect( () => {
|
|
36
|
+
if ( ! element ) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const win = element.ownerDocument?.defaultView;
|
|
41
|
+
win?.addEventListener( 'scroll', onChange, { passive: true } );
|
|
42
|
+
|
|
43
|
+
return () => {
|
|
44
|
+
win?.removeEventListener( 'scroll', onChange );
|
|
45
|
+
};
|
|
46
|
+
}, [ element, onChange ] );
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function useResizeListener( { element, onChange }: ListenerProps ) {
|
|
50
|
+
useEffect( () => {
|
|
51
|
+
if ( ! element ) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const resizeObserver = new ResizeObserver( onChange );
|
|
56
|
+
resizeObserver.observe( element );
|
|
57
|
+
|
|
58
|
+
const win = element.ownerDocument?.defaultView;
|
|
59
|
+
win?.addEventListener( 'resize', onChange, { passive: true } );
|
|
60
|
+
|
|
61
|
+
return () => {
|
|
62
|
+
resizeObserver.disconnect();
|
|
63
|
+
win?.removeEventListener( 'resize', onChange );
|
|
64
|
+
};
|
|
65
|
+
}, [ element, onChange ] );
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function useMutationsListener( { element, onChange }: ListenerProps ) {
|
|
69
|
+
useEffect( () => {
|
|
70
|
+
if ( ! element ) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const mutationObserver = new MutationObserver( onChange );
|
|
75
|
+
mutationObserver.observe( element, { childList: true, subtree: true } );
|
|
76
|
+
|
|
77
|
+
return () => {
|
|
78
|
+
mutationObserver.disconnect();
|
|
79
|
+
};
|
|
80
|
+
}, [ element, onChange ] );
|
|
81
|
+
}
|
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 { type V1ElementData } from '@elementor/editor-elements';
|
|
8
9
|
import { injectTab } from '@elementor/editor-elements-panel';
|
|
9
10
|
import { stylesRepository } from '@elementor/editor-styles-repository';
|
|
10
11
|
import { __privateListenTo as listenTo, commandStartEvent, registerDataHook } from '@elementor/editor-v1-adapters';
|
|
@@ -14,6 +15,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
14
15
|
import { componentIdTransformer } from './component-id-transformer';
|
|
15
16
|
import { Components } from './components/components-tab/components';
|
|
16
17
|
import { CreateComponentForm } from './components/create-component-form/create-component-form';
|
|
18
|
+
import { EditComponent } from './components/edit-component/edit-component';
|
|
17
19
|
import { openEditModeDialog } from './components/in-edit-mode';
|
|
18
20
|
import { createComponentType, TYPE } from './create-component-type';
|
|
19
21
|
import { PopulateStore } from './populate-store';
|
|
@@ -21,7 +23,7 @@ import { componentsStylesProvider } from './store/components-styles-provider';
|
|
|
21
23
|
import { loadComponentsStyles } from './store/load-components-styles';
|
|
22
24
|
import { removeComponentStyles } from './store/remove-component-styles';
|
|
23
25
|
import { slice } from './store/store';
|
|
24
|
-
import { type
|
|
26
|
+
import { type ExtendedWindow } from './types';
|
|
25
27
|
import { beforeSave } from './utils/before-save';
|
|
26
28
|
|
|
27
29
|
const COMPONENT_DOCUMENT_TYPE = 'elementor_component';
|
|
@@ -58,6 +60,11 @@ export function init() {
|
|
|
58
60
|
component: PopulateStore,
|
|
59
61
|
} );
|
|
60
62
|
|
|
63
|
+
injectIntoTop( {
|
|
64
|
+
id: 'edit-component',
|
|
65
|
+
component: EditComponent,
|
|
66
|
+
} );
|
|
67
|
+
|
|
61
68
|
listenTo( commandStartEvent( 'editor/documents/attach-preview' ), () => {
|
|
62
69
|
const { id, config } = getV1CurrentDocument();
|
|
63
70
|
|
|
@@ -65,7 +72,7 @@ export function init() {
|
|
|
65
72
|
removeComponentStyles( id );
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
loadComponentsStyles( ( config?.elements as
|
|
75
|
+
loadComponentsStyles( ( config?.elements as V1ElementData[] ) ?? [] );
|
|
69
76
|
} );
|
|
70
77
|
|
|
71
78
|
settingsTransformersRegistry.register( 'component-id', componentIdTransformer );
|
|
@@ -3,11 +3,11 @@ import { type StyleDefinition } from '@elementor/editor-styles';
|
|
|
3
3
|
import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
|
|
4
4
|
|
|
5
5
|
import { apiClient } from '../api';
|
|
6
|
-
import { type ComponentId
|
|
6
|
+
import { type ComponentId } from '../types';
|
|
7
7
|
import { getComponentIds } from '../utils/get-component-ids';
|
|
8
8
|
import { selectStyles, slice } from './store';
|
|
9
9
|
|
|
10
|
-
export async function loadComponentsStyles( elements:
|
|
10
|
+
export async function loadComponentsStyles( elements: V1ElementData[] ) {
|
|
11
11
|
const componentIds = Array.from( new Set( getComponentIds( elements ) ) );
|
|
12
12
|
|
|
13
13
|
if ( ! componentIds.length ) {
|
|
@@ -30,7 +30,7 @@ async function addComponentStyles( ids: ComponentId[] ) {
|
|
|
30
30
|
addStyles( newComponents );
|
|
31
31
|
|
|
32
32
|
Object.values( newComponents ).forEach( ( [ , data ] ) => {
|
|
33
|
-
loadComponentsStyles( data.elements as
|
|
33
|
+
loadComponentsStyles( data.elements ?? ( [] as V1ElementData[] ) );
|
|
34
34
|
} );
|
|
35
35
|
}
|
|
36
36
|
|
package/src/store/store.ts
CHANGED
|
@@ -94,6 +94,15 @@ export const selectUnpublishedComponents = createSelector(
|
|
|
94
94
|
selectUnpublishedData,
|
|
95
95
|
( unpublishedData: UnpublishedComponent[] ) => unpublishedData
|
|
96
96
|
);
|
|
97
|
+
export const selectComponentsObject = createSelector(
|
|
98
|
+
selectData,
|
|
99
|
+
selectUnpublishedData,
|
|
100
|
+
( data: Component[], unpublishedData: UnpublishedComponent[] ) =>
|
|
101
|
+
data.concat( unpublishedData ).reduce< Record< ComponentId, Component > >( ( acc, component ) => {
|
|
102
|
+
acc[ component.id ] = component;
|
|
103
|
+
return acc;
|
|
104
|
+
}, {} )
|
|
105
|
+
);
|
|
97
106
|
export const selectLoadIsPending = createSelector( selectLoadStatus, ( status ) => status === 'pending' );
|
|
98
107
|
export const selectLoadIsError = createSelector( selectLoadStatus, ( status ) => status === 'error' );
|
|
99
108
|
export const selectStyles = ( state: ComponentsSlice ) => state[ SLICE_NAME ].styles ?? {};
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type V1ElementModelProps, type V1ElementSettingsProps } from '@elementor/editor-elements';
|
|
2
1
|
import type { StyleDefinition } from '@elementor/editor-styles';
|
|
3
2
|
|
|
4
3
|
export type ComponentFormValues = {
|
|
@@ -16,16 +15,6 @@ export type Component = {
|
|
|
16
15
|
|
|
17
16
|
export type DocumentStatus = 'publish' | 'draft' | 'autosave';
|
|
18
17
|
|
|
19
|
-
export type Element = V1ElementModelProps & {
|
|
20
|
-
elements?: Element[];
|
|
21
|
-
settings?: V1ElementSettingsProps & {
|
|
22
|
-
component?: {
|
|
23
|
-
$$type: 'component-id';
|
|
24
|
-
value: number;
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
|
|
29
18
|
export type ExtendedWindow = Window & {
|
|
30
19
|
elementorCommon: Record< string, unknown >;
|
|
31
20
|
};
|