@elementor/editor-components 3.35.0-448 → 3.35.0-450
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 +68 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +22 -22
- package/src/components/components-tab/components-item.tsx +43 -28
- package/src/components/components-tab/components-list.tsx +47 -32
- package/src/components/instance-editing-panel/empty-state.tsx +21 -11
- package/src/components/instance-editing-panel/instance-editing-panel.tsx +11 -5
- package/src/create-component-type.ts +17 -10
- package/src/hooks/use-components-permissions.ts +12 -0
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.35.0-
|
|
4
|
+
"version": "3.35.0-450",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,30 +40,30 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor": "3.35.0-
|
|
44
|
-
"@elementor/editor-canvas": "3.35.0-
|
|
45
|
-
"@elementor/editor-controls": "3.35.0-
|
|
46
|
-
"@elementor/editor-documents": "3.35.0-
|
|
47
|
-
"@elementor/editor-editing-panel": "3.35.0-
|
|
48
|
-
"@elementor/editor-elements": "3.35.0-
|
|
49
|
-
"@elementor/editor-elements-panel": "3.35.0-
|
|
50
|
-
"@elementor/editor-mcp": "3.35.0-
|
|
51
|
-
"@elementor/editor-panels": "3.35.0-
|
|
52
|
-
"@elementor/editor-props": "3.35.0-
|
|
53
|
-
"@elementor/editor-styles-repository": "3.35.0-
|
|
54
|
-
"@elementor/editor-ui": "3.35.0-
|
|
55
|
-
"@elementor/editor-v1-adapters": "3.35.0-
|
|
56
|
-
"@elementor/http-client": "3.35.0-
|
|
43
|
+
"@elementor/editor": "3.35.0-450",
|
|
44
|
+
"@elementor/editor-canvas": "3.35.0-450",
|
|
45
|
+
"@elementor/editor-controls": "3.35.0-450",
|
|
46
|
+
"@elementor/editor-documents": "3.35.0-450",
|
|
47
|
+
"@elementor/editor-editing-panel": "3.35.0-450",
|
|
48
|
+
"@elementor/editor-elements": "3.35.0-450",
|
|
49
|
+
"@elementor/editor-elements-panel": "3.35.0-450",
|
|
50
|
+
"@elementor/editor-mcp": "3.35.0-450",
|
|
51
|
+
"@elementor/editor-panels": "3.35.0-450",
|
|
52
|
+
"@elementor/editor-props": "3.35.0-450",
|
|
53
|
+
"@elementor/editor-styles-repository": "3.35.0-450",
|
|
54
|
+
"@elementor/editor-ui": "3.35.0-450",
|
|
55
|
+
"@elementor/editor-v1-adapters": "3.35.0-450",
|
|
56
|
+
"@elementor/http-client": "3.35.0-450",
|
|
57
57
|
"@elementor/icons": "^1.63.0",
|
|
58
|
-
"@elementor/mixpanel": "3.35.0-
|
|
59
|
-
"@elementor/query": "3.35.0-
|
|
60
|
-
"@elementor/schema": "3.35.0-
|
|
61
|
-
"@elementor/store": "3.35.0-
|
|
58
|
+
"@elementor/mixpanel": "3.35.0-450",
|
|
59
|
+
"@elementor/query": "3.35.0-450",
|
|
60
|
+
"@elementor/schema": "3.35.0-450",
|
|
61
|
+
"@elementor/store": "3.35.0-450",
|
|
62
62
|
"@elementor/ui": "1.36.17",
|
|
63
|
-
"@elementor/utils": "3.35.0-
|
|
63
|
+
"@elementor/utils": "3.35.0-450",
|
|
64
64
|
"@wordpress/i18n": "^5.13.0",
|
|
65
|
-
"@elementor/editor-notifications": "3.35.0-
|
|
66
|
-
"@elementor/editor-current-user": "3.35.0-
|
|
65
|
+
"@elementor/editor-notifications": "3.35.0-450",
|
|
66
|
+
"@elementor/editor-current-user": "3.35.0-450"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"react": "^18.3.1",
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from '@elementor/ui';
|
|
21
21
|
import { __ } from '@wordpress/i18n';
|
|
22
22
|
|
|
23
|
+
import { useComponentsPermissions } from '../../hooks/use-components-permissions';
|
|
23
24
|
import { archiveComponent } from '../../store/actions/archive-component';
|
|
24
25
|
import { loadComponentsAssets } from '../../store/actions/load-components-assets';
|
|
25
26
|
import { type Component } from '../../types';
|
|
@@ -36,6 +37,9 @@ type ComponentItemProps = {
|
|
|
36
37
|
export const ComponentItem = ( { component, renameComponent }: ComponentItemProps ) => {
|
|
37
38
|
const itemRef = useRef< HTMLElement >( null );
|
|
38
39
|
const [ isDeleteDialogOpen, setIsDeleteDialogOpen ] = useState( false );
|
|
40
|
+
const { canRename, canDelete } = useComponentsPermissions();
|
|
41
|
+
|
|
42
|
+
const shouldShowActions = canRename || canDelete;
|
|
39
43
|
|
|
40
44
|
const {
|
|
41
45
|
ref: editableRef,
|
|
@@ -66,8 +70,8 @@ export const ComponentItem = ( { component, renameComponent }: ComponentItemProp
|
|
|
66
70
|
};
|
|
67
71
|
|
|
68
72
|
const handleDeleteClick = () => {
|
|
69
|
-
popupState.close();
|
|
70
73
|
setIsDeleteDialogOpen( true );
|
|
74
|
+
popupState.close();
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
const handleDeleteConfirm = () => {
|
|
@@ -140,37 +144,48 @@ export const ComponentItem = ( { component, renameComponent }: ComponentItemProp
|
|
|
140
144
|
</Box>
|
|
141
145
|
</Indicator>
|
|
142
146
|
</Box>
|
|
143
|
-
|
|
144
|
-
<
|
|
145
|
-
|
|
147
|
+
{ shouldShowActions && (
|
|
148
|
+
<IconButton size="tiny" { ...bindTrigger( popupState ) } aria-label="More actions">
|
|
149
|
+
<DotsVerticalIcon fontSize="tiny" />
|
|
150
|
+
</IconButton>
|
|
151
|
+
) }
|
|
146
152
|
</ListItemButton>
|
|
147
153
|
</WarningInfotip>
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
>
|
|
159
|
-
<MenuListItem
|
|
160
|
-
sx={ { minWidth: '160px' } }
|
|
161
|
-
onClick={ () => {
|
|
162
|
-
popupState.close();
|
|
163
|
-
openEditMode();
|
|
154
|
+
{ shouldShowActions && (
|
|
155
|
+
<Menu
|
|
156
|
+
{ ...bindMenu( popupState ) }
|
|
157
|
+
anchorOrigin={ {
|
|
158
|
+
vertical: 'bottom',
|
|
159
|
+
horizontal: 'right',
|
|
160
|
+
} }
|
|
161
|
+
transformOrigin={ {
|
|
162
|
+
vertical: 'top',
|
|
163
|
+
horizontal: 'right',
|
|
164
164
|
} }
|
|
165
165
|
>
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
166
|
+
{ canRename && (
|
|
167
|
+
<MenuListItem
|
|
168
|
+
sx={ { minWidth: '160px' } }
|
|
169
|
+
primaryTypographyProps={ { variant: 'caption', color: 'text.primary' } }
|
|
170
|
+
onClick={ () => {
|
|
171
|
+
popupState.close();
|
|
172
|
+
openEditMode();
|
|
173
|
+
} }
|
|
174
|
+
>
|
|
175
|
+
{ __( 'Rename', 'elementor' ) }
|
|
176
|
+
</MenuListItem>
|
|
177
|
+
) }
|
|
178
|
+
{ canDelete && (
|
|
179
|
+
<MenuListItem
|
|
180
|
+
sx={ { minWidth: '160px' } }
|
|
181
|
+
primaryTypographyProps={ { variant: 'caption', color: 'error.light' } }
|
|
182
|
+
onClick={ handleDeleteClick }
|
|
183
|
+
>
|
|
184
|
+
{ __( 'Delete', 'elementor' ) }
|
|
185
|
+
</MenuListItem>
|
|
186
|
+
) }
|
|
187
|
+
</Menu>
|
|
188
|
+
) }
|
|
174
189
|
<DeleteConfirmationDialog
|
|
175
190
|
open={ isDeleteDialogOpen }
|
|
176
191
|
onClose={ handleDeleteDialogClose }
|
|
@@ -6,6 +6,7 @@ import { Box, Button, Divider, Link, List, Stack, Typography } from '@elementor/
|
|
|
6
6
|
import { __ } from '@wordpress/i18n';
|
|
7
7
|
|
|
8
8
|
import { useComponents } from '../../hooks/use-components';
|
|
9
|
+
import { useComponentsPermissions } from '../../hooks/use-components-permissions';
|
|
9
10
|
import { renameComponent } from '../../store/actions/rename-component';
|
|
10
11
|
import { AngiePromotionModal } from './angie-promotion-modal';
|
|
11
12
|
import { ComponentItem } from './components-item';
|
|
@@ -53,6 +54,8 @@ export function ComponentsList() {
|
|
|
53
54
|
const EmptyState = () => {
|
|
54
55
|
const [ isAngieModalOpen, setIsAngieModalOpen ] = useState( false );
|
|
55
56
|
|
|
57
|
+
const { canCreate } = useComponentsPermissions();
|
|
58
|
+
|
|
56
59
|
const handleCreateWithAI = () => {
|
|
57
60
|
const sdk = getAngieSdk();
|
|
58
61
|
|
|
@@ -88,9 +91,13 @@ const EmptyState = () => {
|
|
|
88
91
|
<Typography align="center" variant="caption" color="secondary" sx={ { maxWidth: 200 } }>
|
|
89
92
|
{ __( 'Components are reusable blocks that sync across your site.', 'elementor' ) }
|
|
90
93
|
<br />
|
|
91
|
-
{
|
|
94
|
+
{ canCreate
|
|
95
|
+
? __( 'Create once, use everywhere.', 'elementor' )
|
|
96
|
+
: __(
|
|
97
|
+
'With your current role, you cannot create components. Contact an administrator to create one.',
|
|
98
|
+
'elementor'
|
|
99
|
+
) }
|
|
92
100
|
</Typography>
|
|
93
|
-
|
|
94
101
|
<Link
|
|
95
102
|
href={ LEARN_MORE_URL }
|
|
96
103
|
target="_blank"
|
|
@@ -102,36 +109,44 @@ const EmptyState = () => {
|
|
|
102
109
|
</Link>
|
|
103
110
|
</Stack>
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
color="secondary"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
112
|
+
{ canCreate && (
|
|
113
|
+
<>
|
|
114
|
+
<Divider sx={ { width: '100%' } } />
|
|
115
|
+
<Stack alignItems="center" gap={ 1 } width="100%">
|
|
116
|
+
<Typography
|
|
117
|
+
align="center"
|
|
118
|
+
variant="subtitle2"
|
|
119
|
+
color="text.secondary"
|
|
120
|
+
sx={ SUBTITLE_OVERRIDE_SX }
|
|
121
|
+
>
|
|
122
|
+
{ __( 'Create your first one:', 'elementor' ) }
|
|
123
|
+
</Typography>
|
|
124
|
+
|
|
125
|
+
<Typography align="center" variant="caption" color="secondary" sx={ { maxWidth: 228 } }>
|
|
126
|
+
{ __(
|
|
127
|
+
'Right-click any div-block or flexbox on your canvas or structure and select "Create component"',
|
|
128
|
+
'elementor'
|
|
129
|
+
) }
|
|
130
|
+
</Typography>
|
|
131
|
+
|
|
132
|
+
<Typography align="center" variant="caption" color="secondary">
|
|
133
|
+
{ __( 'Or', 'elementor' ) }
|
|
134
|
+
</Typography>
|
|
135
|
+
|
|
136
|
+
<AngiePromotionModal open={ isAngieModalOpen } onClose={ () => setIsAngieModalOpen( false ) }>
|
|
137
|
+
<Button
|
|
138
|
+
color="secondary"
|
|
139
|
+
variant="outlined"
|
|
140
|
+
size="small"
|
|
141
|
+
onClick={ handleCreateWithAI }
|
|
142
|
+
endIcon={ <AIIcon /> }
|
|
143
|
+
>
|
|
144
|
+
{ __( 'Create component with AI', 'elementor' ) }
|
|
145
|
+
</Button>
|
|
146
|
+
</AngiePromotionModal>
|
|
147
|
+
</Stack>
|
|
148
|
+
</>
|
|
149
|
+
) }
|
|
135
150
|
</Stack>
|
|
136
151
|
);
|
|
137
152
|
};
|
|
@@ -3,7 +3,21 @@ import { ComponentPropListIcon, PencilIcon } from '@elementor/icons';
|
|
|
3
3
|
import { Button, Stack, Typography } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
|
+
import { useComponentsPermissions } from '../../hooks/use-components-permissions';
|
|
7
|
+
|
|
6
8
|
export const EmptyState = ( { onEditComponent }: { onEditComponent: () => void } ) => {
|
|
9
|
+
const { canEdit } = useComponentsPermissions();
|
|
10
|
+
|
|
11
|
+
const message = canEdit
|
|
12
|
+
? __(
|
|
13
|
+
'Edit the component to add properties, manage them or update the design across all instances.',
|
|
14
|
+
'elementor'
|
|
15
|
+
)
|
|
16
|
+
: __(
|
|
17
|
+
'With your current role, you cannot edit this component. Contact an administrator to add properties.',
|
|
18
|
+
'elementor'
|
|
19
|
+
);
|
|
20
|
+
|
|
7
21
|
return (
|
|
8
22
|
<Stack
|
|
9
23
|
alignItems="center"
|
|
@@ -14,22 +28,18 @@ export const EmptyState = ( { onEditComponent }: { onEditComponent: () => void }
|
|
|
14
28
|
gap={ 1.5 }
|
|
15
29
|
>
|
|
16
30
|
<ComponentPropListIcon fontSize="large" />
|
|
17
|
-
|
|
18
31
|
<Typography align="center" variant="subtitle2">
|
|
19
32
|
{ __( 'No properties yet', 'elementor' ) }
|
|
20
33
|
</Typography>
|
|
21
|
-
|
|
22
34
|
<Typography align="center" variant="caption" maxWidth="170px">
|
|
23
|
-
{
|
|
24
|
-
'Edit the component to add properties, manage them or update the design across all instances.',
|
|
25
|
-
'elementor'
|
|
26
|
-
) }
|
|
35
|
+
{ message }
|
|
27
36
|
</Typography>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
{ canEdit && (
|
|
38
|
+
<Button variant="outlined" color="secondary" size="small" sx={ { mt: 1 } } onClick={ onEditComponent }>
|
|
39
|
+
<PencilIcon fontSize="small" />
|
|
40
|
+
{ __( 'Edit component', 'elementor' ) }
|
|
41
|
+
</Button>
|
|
42
|
+
) }
|
|
33
43
|
</Stack>
|
|
34
44
|
);
|
|
35
45
|
};
|
|
@@ -9,6 +9,7 @@ import { Divider, IconButton, Stack, Tooltip } from '@elementor/ui';
|
|
|
9
9
|
import { __ } from '@wordpress/i18n';
|
|
10
10
|
|
|
11
11
|
import { useComponentInstanceSettings } from '../../hooks/use-component-instance-settings';
|
|
12
|
+
import { useComponentsPermissions } from '../../hooks/use-components-permissions';
|
|
12
13
|
import { useComponent, useOverridableProps } from '../../store/store';
|
|
13
14
|
import { type OverridablePropsGroup } from '../../types';
|
|
14
15
|
import { switchToComponent } from '../../utils/switch-to-component';
|
|
@@ -16,7 +17,10 @@ import { EmptyState } from './empty-state';
|
|
|
16
17
|
import { OverridePropsGroup } from './override-props-group';
|
|
17
18
|
|
|
18
19
|
export function InstanceEditingPanel() {
|
|
20
|
+
const { canEdit } = useComponentsPermissions();
|
|
21
|
+
|
|
19
22
|
const settings = useComponentInstanceSettings();
|
|
23
|
+
|
|
20
24
|
const componentId = settings?.component_id?.value;
|
|
21
25
|
|
|
22
26
|
const overrides = settings?.overrides?.value;
|
|
@@ -49,11 +53,13 @@ export function InstanceEditingPanel() {
|
|
|
49
53
|
<Stack direction="row" alignItems="center" flexGrow={ 1 } gap={ 1 } maxWidth="100%">
|
|
50
54
|
<ComponentsIcon fontSize="small" sx={ { color: 'text.tertiary' } } />
|
|
51
55
|
<EllipsisWithTooltip title={ component.name } as={ PanelHeaderTitle } />
|
|
52
|
-
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
{ canEdit && (
|
|
57
|
+
<Tooltip title={ panelTitle }>
|
|
58
|
+
<IconButton size="tiny" onClick={ handleEditComponent } aria-label={ panelTitle }>
|
|
59
|
+
<PencilIcon fontSize="tiny" />
|
|
60
|
+
</IconButton>
|
|
61
|
+
</Tooltip>
|
|
62
|
+
) }
|
|
57
63
|
</Stack>
|
|
58
64
|
</PanelHeader>
|
|
59
65
|
<PanelBody>
|
|
@@ -106,9 +106,10 @@ function createComponentView(
|
|
|
106
106
|
showLockedByModal?: ( lockedBy: string ) => void;
|
|
107
107
|
}
|
|
108
108
|
): typeof ElementView {
|
|
109
|
+
const legacyWindow = window as unknown as LegacyWindow & ExtendedWindow;
|
|
110
|
+
|
|
109
111
|
return class extends createTemplatedElementView( options ) {
|
|
110
|
-
|
|
111
|
-
eventsManagerConfig = this.legacyWindow.elementorCommon.eventsManager.config;
|
|
112
|
+
eventsManagerConfig = legacyWindow.elementorCommon.eventsManager.config;
|
|
112
113
|
#componentRenderContext: ComponentRenderContext | undefined;
|
|
113
114
|
|
|
114
115
|
isComponentCurrentlyEdited() {
|
|
@@ -160,9 +161,7 @@ function createComponentView(
|
|
|
160
161
|
overrides: componentInstance.overrides ?? {},
|
|
161
162
|
};
|
|
162
163
|
|
|
163
|
-
this.collection =
|
|
164
|
-
componentInstance.elements
|
|
165
|
-
);
|
|
164
|
+
this.collection = legacyWindow.elementor.createBackboneElementsCollection( componentInstance.elements );
|
|
166
165
|
|
|
167
166
|
this.collection.models.forEach( setInactiveRecursively );
|
|
168
167
|
|
|
@@ -212,11 +211,7 @@ function createComponentView(
|
|
|
212
211
|
}
|
|
213
212
|
|
|
214
213
|
_getContextMenuConfig() {
|
|
215
|
-
const
|
|
216
|
-
const elementorWithConfig = legacyWindow.elementor as typeof legacyWindow.elementor & {
|
|
217
|
-
config?: { user?: { is_administrator?: boolean } };
|
|
218
|
-
};
|
|
219
|
-
const isAdministrator = elementorWithConfig.config?.user?.is_administrator ?? false;
|
|
214
|
+
const isAdministrator = isUserAdministrator();
|
|
220
215
|
|
|
221
216
|
const addedGroup = {
|
|
222
217
|
general: {
|
|
@@ -273,6 +268,12 @@ function createComponentView(
|
|
|
273
268
|
handleDblClick( e: MouseEvent ) {
|
|
274
269
|
e.stopPropagation();
|
|
275
270
|
|
|
271
|
+
const isAdministrator = isUserAdministrator();
|
|
272
|
+
|
|
273
|
+
if ( ! isAdministrator ) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
276
277
|
const { triggers, locations, secondaryLocations } = this.eventsManagerConfig;
|
|
277
278
|
|
|
278
279
|
this.editComponent( {
|
|
@@ -314,6 +315,12 @@ function setInactiveRecursively( model: BackboneModel< ElementModel > ) {
|
|
|
314
315
|
}
|
|
315
316
|
}
|
|
316
317
|
|
|
318
|
+
function isUserAdministrator() {
|
|
319
|
+
const legacyWindow = window as unknown as LegacyWindow;
|
|
320
|
+
|
|
321
|
+
return legacyWindow.elementor.config?.user?.is_administrator ?? false;
|
|
322
|
+
}
|
|
323
|
+
|
|
317
324
|
function createComponentModel(): BackboneModelConstructor< ComponentModel > {
|
|
318
325
|
const legacyWindow = window as unknown as LegacyWindow;
|
|
319
326
|
const WidgetType = legacyWindow.elementor.modules.elements.types.Widget;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useCurrentUserCapabilities } from '@elementor/editor-current-user';
|
|
2
|
+
|
|
3
|
+
export const useComponentsPermissions = () => {
|
|
4
|
+
const { isAdmin } = useCurrentUserCapabilities();
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
canCreate: isAdmin,
|
|
8
|
+
canEdit: isAdmin,
|
|
9
|
+
canDelete: isAdmin,
|
|
10
|
+
canRename: isAdmin,
|
|
11
|
+
};
|
|
12
|
+
};
|