@elementor/editor-editing-panel 4.1.0-749 → 4.1.0-750

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-editing-panel",
3
- "version": "4.1.0-749",
3
+ "version": "4.1.0-750",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,28 +39,28 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "4.1.0-749",
43
- "@elementor/editor-canvas": "4.1.0-749",
44
- "@elementor/editor-controls": "4.1.0-749",
45
- "@elementor/editor-documents": "4.1.0-749",
46
- "@elementor/editor-elements": "4.1.0-749",
47
- "@elementor/editor-interactions": "4.1.0-749",
48
- "@elementor/editor-panels": "4.1.0-749",
49
- "@elementor/editor-props": "4.1.0-749",
50
- "@elementor/editor-responsive": "4.1.0-749",
51
- "@elementor/editor-styles": "4.1.0-749",
52
- "@elementor/editor-styles-repository": "4.1.0-749",
53
- "@elementor/editor-ui": "4.1.0-749",
54
- "@elementor/editor-v1-adapters": "4.1.0-749",
42
+ "@elementor/editor": "4.1.0-750",
43
+ "@elementor/editor-canvas": "4.1.0-750",
44
+ "@elementor/editor-controls": "4.1.0-750",
45
+ "@elementor/editor-documents": "4.1.0-750",
46
+ "@elementor/editor-elements": "4.1.0-750",
47
+ "@elementor/editor-interactions": "4.1.0-750",
48
+ "@elementor/editor-panels": "4.1.0-750",
49
+ "@elementor/editor-props": "4.1.0-750",
50
+ "@elementor/editor-responsive": "4.1.0-750",
51
+ "@elementor/editor-styles": "4.1.0-750",
52
+ "@elementor/editor-styles-repository": "4.1.0-750",
53
+ "@elementor/editor-ui": "4.1.0-750",
54
+ "@elementor/editor-v1-adapters": "4.1.0-750",
55
55
  "@elementor/icons": "^1.68.0",
56
- "@elementor/editor-variables": "4.1.0-749",
57
- "@elementor/locations": "4.1.0-749",
58
- "@elementor/menus": "4.1.0-749",
59
- "@elementor/schema": "4.1.0-749",
60
- "@elementor/session": "4.1.0-749",
56
+ "@elementor/editor-variables": "4.1.0-750",
57
+ "@elementor/locations": "4.1.0-750",
58
+ "@elementor/menus": "4.1.0-750",
59
+ "@elementor/schema": "4.1.0-750",
60
+ "@elementor/session": "4.1.0-750",
61
61
  "@elementor/ui": "1.36.17",
62
- "@elementor/utils": "4.1.0-749",
63
- "@elementor/wp-media": "4.1.0-749",
62
+ "@elementor/utils": "4.1.0-750",
63
+ "@elementor/wp-media": "4.1.0-750",
64
64
  "@wordpress/i18n": "^5.13.0"
65
65
  },
66
66
  "peerDependencies": {
@@ -0,0 +1 @@
1
+ export const PENDING_CLASS_RENAME_SESSION_KEY = 'pending-class-rename-id';
@@ -8,6 +8,7 @@ import { useSessionStorage } from '@elementor/session';
8
8
  import { useClassesProp } from '../../contexts/classes-prop-context';
9
9
  import { useElement } from '../../contexts/element-context';
10
10
  import { useStyle } from '../../contexts/style-context';
11
+ import { PENDING_CLASS_RENAME_SESSION_KEY } from './consts';
11
12
 
12
13
  export const { Slot: CssClassConvertSlot, inject: injectIntoCssClassConvert } = createLocation< {
13
14
  styleDef: StyleDefinition | null;
@@ -30,7 +31,7 @@ export const CssClassConvert = ( props: OwnProps ) => {
30
31
  const elementId = element.id;
31
32
  const currentClassesProp = useClassesProp();
32
33
  const { setId: setActiveId } = useStyle();
33
- const [ , saveValue ] = useSessionStorage( 'last-converted-class-generated-name', 'app' );
34
+ const [ , saveValue ] = useSessionStorage( PENDING_CLASS_RENAME_SESSION_KEY, 'app' );
34
35
 
35
36
  const successCallback = ( newId: string ) => {
36
37
  if ( ! props.styleDef ) {
@@ -20,6 +20,7 @@ import {
20
20
  import { __ } from '@wordpress/i18n';
21
21
 
22
22
  import { useStyle } from '../../contexts/style-context';
23
+ import { PENDING_CLASS_RENAME_SESSION_KEY } from './consts';
23
24
  import { CssClassProvider } from './css-class-context';
24
25
  import { CssClassMenu, useElementStates } from './css-class-menu';
25
26
 
@@ -54,7 +55,7 @@ export function CssClassItem( props: CssClassItemProps ) {
54
55
  const { userCan } = useUserStylesCapability();
55
56
 
56
57
  const [ convertedFromLocalId, , clearConvertedFromLocalId ] = useSessionStorage(
57
- 'last-converted-class-generated-name',
58
+ PENDING_CLASS_RENAME_SESSION_KEY,
58
59
  'app'
59
60
  );
60
61
 
@@ -16,6 +16,7 @@ import { getTempStylesProviderThemeColor } from '../../utils/get-styles-provider
16
16
  import { trackStyles } from '../../utils/tracking/subscribe';
17
17
  import { StyleIndicator } from '../style-indicator';
18
18
  import { useCssClass } from './css-class-context';
19
+ import { DuplicateClassMenuItem } from './duplicate-class-menu-item';
19
20
  import { LocalClassSubMenu } from './local-class-sub-menu';
20
21
  import { useUnapplyClass } from './use-apply-and-unapply-class';
21
22
 
@@ -179,10 +180,12 @@ function getMenuItemsByProvider( {
179
180
  const providerActions = providerInstance?.actions;
180
181
 
181
182
  const canUpdate = providerActions?.update;
183
+ const canDuplicate = providerActions?.create && providerActions?.get;
182
184
  const canUnapply = ! fixed;
183
185
 
184
186
  const actions = [
185
187
  canUpdate && <RenameClassMenuItem key="rename-class" closeMenu={ closeMenu } />,
188
+ canDuplicate && <DuplicateClassMenuItem key="duplicate-class" closeMenu={ closeMenu } />,
186
189
  canUnapply && <UnapplyClassMenuItem key="unapply-class" closeMenu={ closeMenu } />,
187
190
  ].filter( Boolean );
188
191
 
@@ -302,7 +305,7 @@ function RenameClassMenuItem( { closeMenu }: { closeMenu: () => void } ) {
302
305
  <MenuItemInfotip
303
306
  showInfoTip={ ! isAllowed }
304
307
  content={ __(
305
- 'With your current role, you can use existing classes but cant modify them.',
308
+ "With your current role, you can use existing classes but can't modify them.",
306
309
  'elementor'
307
310
  ) }
308
311
  >
@@ -0,0 +1,68 @@
1
+ import * as React from 'react';
2
+ import { stylesRepository, useUserStylesCapability } from '@elementor/editor-styles-repository';
3
+ import { MenuListItem } from '@elementor/editor-ui';
4
+ import { useSessionStorage } from '@elementor/session';
5
+ import { __ } from '@wordpress/i18n';
6
+
7
+ import { trackStyles } from '../../utils/tracking/subscribe';
8
+ import { PENDING_CLASS_RENAME_SESSION_KEY } from './consts';
9
+ import { useCssClass } from './css-class-context';
10
+ import { useApplyClass } from './use-apply-and-unapply-class';
11
+
12
+ const DUPLICATE_LABEL_PREFIX = 'copy-of';
13
+
14
+ export function getUniqueDuplicateLabel( originalLabel: string, existingLabels: string[] ): string {
15
+ let newLabel = `${ DUPLICATE_LABEL_PREFIX }-${ originalLabel }`;
16
+ let counter = 2;
17
+ while ( existingLabels.includes( newLabel ) ) {
18
+ newLabel = `${ DUPLICATE_LABEL_PREFIX }-${ originalLabel }-${ counter }`;
19
+ counter++;
20
+ }
21
+ return newLabel;
22
+ }
23
+
24
+ export function DuplicateClassMenuItem( { closeMenu }: { closeMenu: () => void } ) {
25
+ const { id: classId, provider } = useCssClass();
26
+ const { userCan } = useUserStylesCapability();
27
+ const applyClass = useApplyClass();
28
+ const [ , setPendingEditId ] = useSessionStorage( PENDING_CLASS_RENAME_SESSION_KEY, 'app' );
29
+
30
+ if ( ! provider || ! classId ) {
31
+ return null;
32
+ }
33
+
34
+ const providerInstance = stylesRepository.getProviderByKey( provider );
35
+ const createAction = providerInstance?.actions.create;
36
+ const getAction = providerInstance?.actions.get;
37
+
38
+ if ( ! createAction || ! getAction ) {
39
+ return null;
40
+ }
41
+
42
+ if ( ! userCan( provider ).create ) {
43
+ return null;
44
+ }
45
+
46
+ const handleDuplicate = () => {
47
+ const styleDef = getAction( classId );
48
+ if ( ! styleDef ) {
49
+ closeMenu();
50
+ return;
51
+ }
52
+ const existingLabels = providerInstance.actions.all().map( ( style ) => style.label );
53
+ const newLabel = getUniqueDuplicateLabel( styleDef.label, existingLabels );
54
+ const newId = createAction( newLabel, styleDef.variants );
55
+ if ( newId ) {
56
+ applyClass( { classId: newId, classLabel: newLabel } );
57
+ setPendingEditId( newId );
58
+ trackStyles( provider, 'classCreated', {
59
+ classId: newId,
60
+ source: 'duplicated',
61
+ classTitle: newLabel,
62
+ } );
63
+ }
64
+ closeMenu();
65
+ };
66
+
67
+ return <MenuListItem onClick={ handleDuplicate }>{ __( 'Duplicate', 'elementor' ) }</MenuListItem>;
68
+ }