@elementor/editor-editing-panel 4.2.0-885 → 4.2.0-886
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 +1011 -963
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +832 -784
- package/dist/index.mjs.map +1 -1
- package/package.json +24 -24
- package/src/components/css-classes/css-class-menu.tsx +2 -2
- package/src/components/css-classes/css-class-selector.tsx +21 -4
- package/src/components/css-classes/duplicate-class-menu-item.tsx +2 -2
- package/src/components/css-classes/missing-classes-alert.tsx +25 -0
- package/src/components/css-classes/use-apply-and-unapply-class.ts +24 -21
- package/src/components/css-classes/use-missing-classes.ts +17 -0
- package/src/hooks/use-active-style-def-id.ts +11 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-editing-panel",
|
|
3
|
-
"version": "4.2.0-
|
|
3
|
+
"version": "4.2.0-886",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,31 +39,31 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "4.2.0-
|
|
43
|
-
"@elementor/editor-canvas": "4.2.0-
|
|
44
|
-
"@elementor/editor-controls": "4.2.0-
|
|
45
|
-
"@elementor/editor-documents": "4.2.0-
|
|
46
|
-
"@elementor/editor-elements": "4.2.0-
|
|
47
|
-
"@elementor/editor-interactions": "4.2.0-
|
|
48
|
-
"@elementor/editor-notifications": "4.2.0-
|
|
49
|
-
"@elementor/editor-panels": "4.2.0-
|
|
50
|
-
"@elementor/editor-props": "4.2.0-
|
|
51
|
-
"@elementor/editor-responsive": "4.2.0-
|
|
52
|
-
"@elementor/editor-styles": "4.2.0-
|
|
53
|
-
"@elementor/editor-styles-repository": "4.2.0-
|
|
54
|
-
"@elementor/editor-ui": "4.2.0-
|
|
55
|
-
"@elementor/editor-v1-adapters": "4.2.0-
|
|
56
|
-
"@elementor/http-client": "4.2.0-
|
|
42
|
+
"@elementor/editor": "4.2.0-886",
|
|
43
|
+
"@elementor/editor-canvas": "4.2.0-886",
|
|
44
|
+
"@elementor/editor-controls": "4.2.0-886",
|
|
45
|
+
"@elementor/editor-documents": "4.2.0-886",
|
|
46
|
+
"@elementor/editor-elements": "4.2.0-886",
|
|
47
|
+
"@elementor/editor-interactions": "4.2.0-886",
|
|
48
|
+
"@elementor/editor-notifications": "4.2.0-886",
|
|
49
|
+
"@elementor/editor-panels": "4.2.0-886",
|
|
50
|
+
"@elementor/editor-props": "4.2.0-886",
|
|
51
|
+
"@elementor/editor-responsive": "4.2.0-886",
|
|
52
|
+
"@elementor/editor-styles": "4.2.0-886",
|
|
53
|
+
"@elementor/editor-styles-repository": "4.2.0-886",
|
|
54
|
+
"@elementor/editor-ui": "4.2.0-886",
|
|
55
|
+
"@elementor/editor-v1-adapters": "4.2.0-886",
|
|
56
|
+
"@elementor/http-client": "4.2.0-886",
|
|
57
57
|
"@elementor/icons": "~1.75.1",
|
|
58
|
-
"@elementor/editor-variables": "4.2.0-
|
|
59
|
-
"@elementor/locations": "4.2.0-
|
|
60
|
-
"@elementor/menus": "4.2.0-
|
|
61
|
-
"@elementor/query": "4.2.0-
|
|
62
|
-
"@elementor/schema": "4.2.0-
|
|
63
|
-
"@elementor/session": "4.2.0-
|
|
58
|
+
"@elementor/editor-variables": "4.2.0-886",
|
|
59
|
+
"@elementor/locations": "4.2.0-886",
|
|
60
|
+
"@elementor/menus": "4.2.0-886",
|
|
61
|
+
"@elementor/query": "4.2.0-886",
|
|
62
|
+
"@elementor/schema": "4.2.0-886",
|
|
63
|
+
"@elementor/session": "4.2.0-886",
|
|
64
64
|
"@elementor/ui": "1.37.5",
|
|
65
|
-
"@elementor/utils": "4.2.0-
|
|
66
|
-
"@elementor/wp-media": "4.2.0-
|
|
65
|
+
"@elementor/utils": "4.2.0-886",
|
|
66
|
+
"@elementor/wp-media": "4.2.0-886",
|
|
67
67
|
"@wordpress/i18n": "^5.13.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
@@ -18,7 +18,7 @@ import { StyleIndicator } from '../style-indicator';
|
|
|
18
18
|
import { useCssClass } from './css-class-context';
|
|
19
19
|
import { DuplicateClassMenuItem } from './duplicate-class-menu-item';
|
|
20
20
|
import { LocalClassSubMenu } from './local-class-sub-menu';
|
|
21
|
-
import {
|
|
21
|
+
import { useUndoableUnapplyClass } from './use-apply-and-unapply-class';
|
|
22
22
|
|
|
23
23
|
type State = {
|
|
24
24
|
key: StyleDefinitionStateWithNormal;
|
|
@@ -264,7 +264,7 @@ function StateMenuItem( { state, label, closeMenu, ...props }: StateMenuItemProp
|
|
|
264
264
|
|
|
265
265
|
function UnapplyClassMenuItem( { closeMenu, ...props }: { closeMenu: () => void } ) {
|
|
266
266
|
const { id: classId, label: classLabel, provider } = useCssClass();
|
|
267
|
-
const unapplyClass =
|
|
267
|
+
const unapplyClass = useUndoableUnapplyClass();
|
|
268
268
|
|
|
269
269
|
return classId ? (
|
|
270
270
|
<MenuListItem
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type ReactElement, useRef, useState } from 'react';
|
|
2
|
+
import { type ReactElement, useCallback, useRef, useState } from 'react';
|
|
3
3
|
import { type ClassesPropValue } from '@elementor/editor-props';
|
|
4
4
|
import {
|
|
5
5
|
isElementsStylesProvider,
|
|
@@ -39,7 +39,14 @@ import {
|
|
|
39
39
|
type ValidationResult,
|
|
40
40
|
} from '../creatable-autocomplete';
|
|
41
41
|
import { CssClassItem } from './css-class-item';
|
|
42
|
-
import {
|
|
42
|
+
import { MissingClassesAlert } from './missing-classes-alert';
|
|
43
|
+
import {
|
|
44
|
+
useCreateAndApplyClass,
|
|
45
|
+
useUnapplyClasses,
|
|
46
|
+
useUndoableApplyClass,
|
|
47
|
+
useUndoableUnapplyClass,
|
|
48
|
+
} from './use-apply-and-unapply-class';
|
|
49
|
+
import { useMissingClassesIds } from './use-missing-classes';
|
|
43
50
|
|
|
44
51
|
const ID = 'elementor-css-class-selector';
|
|
45
52
|
const TAGS_LIMIT = 50;
|
|
@@ -94,6 +101,15 @@ export function CssClassSelector() {
|
|
|
94
101
|
|
|
95
102
|
const canEdit = active.provider ? userCan( active.provider ).updateProps : true;
|
|
96
103
|
|
|
104
|
+
const missingClassesIds = useMissingClassesIds();
|
|
105
|
+
const hasMissingClasses = missingClassesIds.length > 0;
|
|
106
|
+
|
|
107
|
+
const unapplyClasses = useUnapplyClasses();
|
|
108
|
+
|
|
109
|
+
const clearMissingClasses = useCallback( () => {
|
|
110
|
+
unapplyClasses( missingClassesIds );
|
|
111
|
+
}, [ missingClassesIds, unapplyClasses ] );
|
|
112
|
+
|
|
97
113
|
return (
|
|
98
114
|
<Stack p={ 2 }>
|
|
99
115
|
<Stack direction="row" gap={ 1 } alignItems="center" justifyContent="space-between">
|
|
@@ -172,6 +188,7 @@ export function CssClassSelector() {
|
|
|
172
188
|
}
|
|
173
189
|
/>
|
|
174
190
|
</WarningInfotip>
|
|
191
|
+
{ hasMissingClasses && <MissingClassesAlert onDismiss={ clearMissingClasses } /> }
|
|
175
192
|
{ ! canEdit && (
|
|
176
193
|
<InfoAlert sx={ { mt: 1 } }>
|
|
177
194
|
{ __( 'With your current role, you can use existing classes but can’t modify them.', 'elementor' ) }
|
|
@@ -365,8 +382,8 @@ function useAppliedOptions( options: StyleDefOption[] ) {
|
|
|
365
382
|
}
|
|
366
383
|
|
|
367
384
|
function useHandleSelect() {
|
|
368
|
-
const apply =
|
|
369
|
-
const unapply =
|
|
385
|
+
const apply = useUndoableApplyClass();
|
|
386
|
+
const unapply = useUndoableUnapplyClass();
|
|
370
387
|
|
|
371
388
|
return ( _selectedOptions: StyleDefOption[], reason: AutocompleteChangeReason, option: StyleDefOption ) => {
|
|
372
389
|
if ( ! option.value ) {
|
|
@@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
7
7
|
import { trackStyles } from '../../utils/tracking/subscribe';
|
|
8
8
|
import { PENDING_CLASS_RENAME_SESSION_KEY } from './consts';
|
|
9
9
|
import { useCssClass } from './css-class-context';
|
|
10
|
-
import {
|
|
10
|
+
import { useUndoableApplyClass } from './use-apply-and-unapply-class';
|
|
11
11
|
|
|
12
12
|
const DUPLICATE_LABEL_PREFIX = 'copy-of';
|
|
13
13
|
|
|
@@ -24,7 +24,7 @@ export function getUniqueDuplicateLabel( originalLabel: string, existingLabels:
|
|
|
24
24
|
export function DuplicateClassMenuItem( { closeMenu }: { closeMenu: () => void } ) {
|
|
25
25
|
const { id: classId, provider } = useCssClass();
|
|
26
26
|
const { userCan } = useUserStylesCapability();
|
|
27
|
-
const applyClass =
|
|
27
|
+
const applyClass = useUndoableApplyClass();
|
|
28
28
|
const [ , setPendingEditId ] = useSessionStorage( PENDING_CLASS_RENAME_SESSION_KEY, 'app' );
|
|
29
29
|
|
|
30
30
|
if ( ! provider || ! classId ) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { AlertTriangleFilledIcon } from '@elementor/icons';
|
|
3
|
+
import { Alert, AlertTitle, Typography } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
type MissingClassesAlertProps = {
|
|
7
|
+
onDismiss: () => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function MissingClassesAlert( { onDismiss }: MissingClassesAlertProps ) {
|
|
11
|
+
return (
|
|
12
|
+
<Alert
|
|
13
|
+
severity="warning"
|
|
14
|
+
onClose={ onDismiss }
|
|
15
|
+
size="small"
|
|
16
|
+
icon={ <AlertTriangleFilledIcon fontSize="tiny" /> }
|
|
17
|
+
sx={ { mt: 1 } }
|
|
18
|
+
>
|
|
19
|
+
<AlertTitle>{ __( 'Some classes are missing', 'elementor' ) }</AlertTitle>
|
|
20
|
+
<Typography variant="caption" textColor="primary">
|
|
21
|
+
{ __( 'A class was removed from your site and is no longer active on this element', 'elementor' ) }
|
|
22
|
+
</Typography>
|
|
23
|
+
</Alert>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -24,12 +24,12 @@ type CreateAndApplyClassUndoData = {
|
|
|
24
24
|
createdId: StyleDefinitionID;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
export function
|
|
27
|
+
export function useUndoableApplyClass() {
|
|
28
28
|
const { id: activeId, setId: setActiveId } = useStyle();
|
|
29
29
|
const { element } = useElement();
|
|
30
30
|
|
|
31
|
-
const applyClass =
|
|
32
|
-
const
|
|
31
|
+
const applyClass = useApplyClass();
|
|
32
|
+
const unapplyClasses = useUnapplyClasses();
|
|
33
33
|
|
|
34
34
|
return useMemo( () => {
|
|
35
35
|
return undoable(
|
|
@@ -42,7 +42,7 @@ export function useApplyClass() {
|
|
|
42
42
|
return prevActiveId;
|
|
43
43
|
},
|
|
44
44
|
undo: ( { classId }: UndoableClassActionPayload, prevActiveId: string | null ) => {
|
|
45
|
-
|
|
45
|
+
unapplyClasses( [ classId ] );
|
|
46
46
|
setActiveId( prevActiveId );
|
|
47
47
|
},
|
|
48
48
|
},
|
|
@@ -54,15 +54,15 @@ export function useApplyClass() {
|
|
|
54
54
|
},
|
|
55
55
|
}
|
|
56
56
|
);
|
|
57
|
-
}, [ activeId, applyClass, element.id,
|
|
57
|
+
}, [ activeId, applyClass, element.id, unapplyClasses, setActiveId ] );
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export function
|
|
60
|
+
export function useUndoableUnapplyClass() {
|
|
61
61
|
const { id: activeId, setId: setActiveId } = useStyle();
|
|
62
62
|
const { element } = useElement();
|
|
63
63
|
|
|
64
|
-
const applyClass =
|
|
65
|
-
const
|
|
64
|
+
const applyClass = useApplyClass();
|
|
65
|
+
const unapplyClasses = useUnapplyClasses();
|
|
66
66
|
|
|
67
67
|
return useMemo( () => {
|
|
68
68
|
return undoable(
|
|
@@ -70,7 +70,7 @@ export function useUnapplyClass() {
|
|
|
70
70
|
do: ( { classId }: UndoableClassActionPayload ) => {
|
|
71
71
|
const prevActiveId = activeId;
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
unapplyClasses( [ classId ] );
|
|
74
74
|
|
|
75
75
|
return prevActiveId;
|
|
76
76
|
},
|
|
@@ -87,7 +87,7 @@ export function useUnapplyClass() {
|
|
|
87
87
|
},
|
|
88
88
|
}
|
|
89
89
|
);
|
|
90
|
-
}, [ activeId, applyClass, element.id,
|
|
90
|
+
}, [ activeId, applyClass, element.id, unapplyClasses, setActiveId ] );
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export function useCreateAndApplyClass() {
|
|
@@ -96,8 +96,8 @@ export function useCreateAndApplyClass() {
|
|
|
96
96
|
const [ provider, createAction ] = useGetStylesRepositoryCreateAction() ?? [ null, null ];
|
|
97
97
|
const deleteAction = provider?.actions.delete;
|
|
98
98
|
|
|
99
|
-
const applyClass =
|
|
100
|
-
const
|
|
99
|
+
const applyClass = useApplyClass();
|
|
100
|
+
const unapplyClasses = useUnapplyClasses();
|
|
101
101
|
|
|
102
102
|
const undoableCreateAndApply = useMemo( () => {
|
|
103
103
|
if ( ! provider || ! createAction ) {
|
|
@@ -114,7 +114,7 @@ export function useCreateAndApplyClass() {
|
|
|
114
114
|
return { prevActiveId, createdId };
|
|
115
115
|
},
|
|
116
116
|
undo: ( _: CreateAndApplyClassPayload, { prevActiveId, createdId }: CreateAndApplyClassUndoData ) => {
|
|
117
|
-
|
|
117
|
+
unapplyClasses( [ createdId ] );
|
|
118
118
|
deleteAction?.( createdId );
|
|
119
119
|
|
|
120
120
|
setActiveId( prevActiveId );
|
|
@@ -138,7 +138,7 @@ export function useCreateAndApplyClass() {
|
|
|
138
138
|
},
|
|
139
139
|
}
|
|
140
140
|
);
|
|
141
|
-
}, [ activeId, applyClass, createAction, deleteAction, provider, setActiveId,
|
|
141
|
+
}, [ activeId, applyClass, createAction, deleteAction, provider, setActiveId, unapplyClasses ] );
|
|
142
142
|
|
|
143
143
|
if ( ! provider || ! undoableCreateAndApply ) {
|
|
144
144
|
return [ null, null ];
|
|
@@ -147,7 +147,7 @@ export function useCreateAndApplyClass() {
|
|
|
147
147
|
return [ provider, undoableCreateAndApply ] as const;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
function
|
|
150
|
+
function useApplyClass() {
|
|
151
151
|
const { element } = useElement();
|
|
152
152
|
const { setId: setActiveId } = useStyle();
|
|
153
153
|
const { setClasses, getAppliedClasses } = useClasses();
|
|
@@ -170,25 +170,28 @@ function useApply() {
|
|
|
170
170
|
);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
function
|
|
173
|
+
export function useUnapplyClasses() {
|
|
174
174
|
const { element } = useElement();
|
|
175
175
|
const { id: activeId, setId: setActiveId } = useStyle();
|
|
176
176
|
const { setClasses, getAppliedClasses } = useClasses();
|
|
177
177
|
|
|
178
178
|
return useCallback(
|
|
179
|
-
(
|
|
179
|
+
( classIDsToUnapply: StyleDefinitionID[] ) => {
|
|
180
180
|
const appliedClasses = getAppliedClasses();
|
|
181
181
|
|
|
182
|
-
if ( ! appliedClasses.includes(
|
|
182
|
+
if ( ! classIDsToUnapply.every( ( classID ) => appliedClasses.includes( classID ) ) ) {
|
|
183
|
+
const missingClasses = classIDsToUnapply.filter( ( classID ) => ! appliedClasses.includes( classID ) );
|
|
183
184
|
throw new Error(
|
|
184
|
-
`
|
|
185
|
+
`Classes ${ missingClasses.join( ', ' ) } are not applied to element ${
|
|
186
|
+
element.id
|
|
187
|
+
}, cannot unapply them.`
|
|
185
188
|
);
|
|
186
189
|
}
|
|
187
190
|
|
|
188
|
-
const updatedClassesIds = appliedClasses.filter( ( id ) =>
|
|
191
|
+
const updatedClassesIds = appliedClasses.filter( ( id ) => ! classIDsToUnapply.includes( id ) );
|
|
189
192
|
setClasses( updatedClassesIds );
|
|
190
193
|
|
|
191
|
-
if ( activeId
|
|
194
|
+
if ( activeId && classIDsToUnapply.includes( activeId ) ) {
|
|
192
195
|
setActiveId( updatedClassesIds[ 0 ] ?? null );
|
|
193
196
|
}
|
|
194
197
|
},
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ClassesPropValue } from '@elementor/editor-props';
|
|
2
|
+
import { useProviders } from '@elementor/editor-styles-repository';
|
|
3
|
+
|
|
4
|
+
import { useClassesProp } from '../../contexts/classes-prop-context';
|
|
5
|
+
import { usePanelElementSetting } from '../../contexts/element-context';
|
|
6
|
+
|
|
7
|
+
export function useMissingClassesIds(): string[] {
|
|
8
|
+
const providers = useProviders();
|
|
9
|
+
const currentClassesProp = useClassesProp();
|
|
10
|
+
const appliedIds = usePanelElementSetting< ClassesPropValue >( currentClassesProp )?.value ?? [];
|
|
11
|
+
|
|
12
|
+
const allKnownIds = new Set(
|
|
13
|
+
providers.flatMap( ( provider ) => provider.actions.all().map( ( style ) => style.id ) )
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return appliedIds.filter( ( id ) => ! allKnownIds.has( id ) );
|
|
17
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getElementStyles } from '@elementor/editor-elements';
|
|
2
2
|
import { type ClassesPropValue, type PropKey } from '@elementor/editor-props';
|
|
3
3
|
import { type StyleDefinitionID } from '@elementor/editor-styles';
|
|
4
|
+
import { useProviders } from '@elementor/editor-styles-repository';
|
|
4
5
|
|
|
5
6
|
import { useElement, usePanelElementSetting } from '../contexts/element-context';
|
|
6
7
|
import { useStateByElement } from './use-state-by-element';
|
|
@@ -12,13 +13,22 @@ export function useActiveStyleDefId( classProp: PropKey ) {
|
|
|
12
13
|
);
|
|
13
14
|
|
|
14
15
|
const appliedClassesIds = usePanelElementSetting< ClassesPropValue >( classProp )?.value || [];
|
|
16
|
+
const validAppliedClassesIds = useValidClassIds( appliedClassesIds );
|
|
15
17
|
|
|
16
18
|
const fallback = useFirstAppliedClass( appliedClassesIds );
|
|
17
19
|
|
|
18
|
-
const activeAndAppliedClassId = useActiveAndAppliedClassId( activeStyledDefId,
|
|
20
|
+
const activeAndAppliedClassId = useActiveAndAppliedClassId( activeStyledDefId, validAppliedClassesIds );
|
|
19
21
|
return [ activeAndAppliedClassId || fallback?.id || null, setActiveStyledDefId ] as const;
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
function useValidClassIds( appliedClassesIds: string[] ) {
|
|
25
|
+
const providers = useProviders();
|
|
26
|
+
const allKnownIds = new Set(
|
|
27
|
+
providers.flatMap( ( provider ) => provider.actions.all().map( ( style ) => style.id ) )
|
|
28
|
+
);
|
|
29
|
+
return appliedClassesIds.filter( ( id ) => allKnownIds.has( id ) );
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
function useFirstAppliedClass( appliedClassesIds: string[] ) {
|
|
23
33
|
const { element } = useElement();
|
|
24
34
|
const stylesDefs = getElementStyles( element.id ) ?? {};
|