@elementor/editor-editing-panel 1.50.0 → 3.32.0-21
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/CHANGELOG.md +0 -27
- package/dist/index.d.mts +78 -47
- package/dist/index.d.ts +78 -47
- package/dist/index.js +1723 -1384
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1510 -1143
- package/dist/index.mjs.map +1 -1
- package/package.json +22 -22
- package/src/components/css-classes/css-class-convert-local.tsx +77 -0
- package/src/components/css-classes/css-class-item.tsx +15 -1
- package/src/components/css-classes/css-class-menu.tsx +8 -1
- package/src/components/css-classes/local-class-sub-menu.tsx +23 -0
- package/src/components/css-classes/use-apply-and-unapply-class.ts +7 -50
- package/src/components/css-classes/use-can-convert-local-class-to-global.ts +22 -0
- package/src/components/custom-css.tsx +21 -0
- package/src/components/editing-panel-tabs.tsx +1 -5
- package/src/components/section.tsx +1 -5
- package/src/components/settings-tab.tsx +6 -15
- package/src/components/style-sections/effects-section/effects-section.tsx +30 -22
- package/src/components/style-sections/layout-section/display-field.tsx +11 -20
- package/src/components/style-sections/layout-section/flex-size-field.tsx +86 -52
- package/src/components/style-sections/position-section/offset-field.tsx +2 -2
- package/src/components/style-sections/position-section/position-section.tsx +2 -8
- package/src/components/style-sections/size-section/size-section.tsx +16 -31
- package/src/components/style-sections/typography-section/typography-section.tsx +2 -19
- package/src/components/style-tab-collapsible-content.tsx +1 -5
- package/src/components/style-tab-section.tsx +1 -5
- package/src/components/style-tab.tsx +15 -2
- package/src/controls-actions.ts +1 -1
- package/src/controls-registry/conditional-field.tsx +26 -0
- package/src/controls-registry/control.tsx +2 -2
- package/src/controls-registry/controls-registry.tsx +44 -3
- package/src/controls-registry/settings-field.tsx +33 -45
- package/src/controls-registry/styles-field.tsx +14 -14
- package/src/dynamics/components/dynamic-selection-control.tsx +2 -2
- package/src/errors.ts +10 -0
- package/src/hooks/use-custom-css.ts +184 -0
- package/src/hooks/use-state-by-element.ts +1 -4
- package/src/hooks/use-styles-fields.ts +129 -106
- package/src/index.ts +9 -10
- package/src/init.ts +2 -5
- package/src/popover-action.tsx +36 -15
- package/src/reset-style-props.tsx +2 -6
- package/src/styles-inheritance/components/infotip/value-component.tsx +1 -0
- package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +6 -23
- package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +17 -8
- package/src/styles-inheritance/consts.ts +0 -4
- package/src/styles-inheritance/init.ts +1 -4
- package/src/styles-inheritance/transformers/background-color-overlay-transformer.tsx +5 -1
- package/src/styles-inheritance/transformers/background-gradient-overlay-transformer.tsx +3 -3
- package/src/styles-inheritance/transformers/background-image-overlay-transformer.tsx +2 -1
- package/src/utils/prop-dependency-utils.ts +156 -0
- package/src/components/style-sections/size-section/object-position-field.tsx +0 -15
- package/src/sync/experiments-flags.ts +0 -5
- /package/src/components/style-sections/{layout-section → effects-section}/opacity-control-field.tsx +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-editing-panel",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.32.0-21",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "git+https://github.com/elementor/elementor
|
|
21
|
+
"url": "git+https://github.com/elementor/elementor.git",
|
|
22
22
|
"directory": "packages/core/editor-editing-panel"
|
|
23
23
|
},
|
|
24
24
|
"bugs": {
|
|
25
|
-
"url": "https://github.com/elementor/elementor
|
|
25
|
+
"url": "https://github.com/elementor/elementor/issues"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
@@ -39,26 +39,26 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "0
|
|
43
|
-
"@elementor/editor-canvas": "
|
|
44
|
-
"@elementor/editor-controls": "
|
|
45
|
-
"@elementor/editor-documents": "
|
|
46
|
-
"@elementor/editor-elements": "
|
|
47
|
-
"@elementor/editor-panels": "
|
|
48
|
-
"@elementor/editor-props": "
|
|
49
|
-
"@elementor/editor-responsive": "
|
|
50
|
-
"@elementor/editor-styles": "
|
|
51
|
-
"@elementor/editor-styles-repository": "
|
|
52
|
-
"@elementor/editor-ui": "
|
|
53
|
-
"@elementor/editor-v1-adapters": "
|
|
42
|
+
"@elementor/editor": "3.32.0-21",
|
|
43
|
+
"@elementor/editor-canvas": "3.32.0-21",
|
|
44
|
+
"@elementor/editor-controls": "3.32.0-21",
|
|
45
|
+
"@elementor/editor-documents": "3.32.0-21",
|
|
46
|
+
"@elementor/editor-elements": "3.32.0-21",
|
|
47
|
+
"@elementor/editor-panels": "3.32.0-21",
|
|
48
|
+
"@elementor/editor-props": "3.32.0-21",
|
|
49
|
+
"@elementor/editor-responsive": "3.32.0-21",
|
|
50
|
+
"@elementor/editor-styles": "3.32.0-21",
|
|
51
|
+
"@elementor/editor-styles-repository": "3.32.0-21",
|
|
52
|
+
"@elementor/editor-ui": "3.32.0-21",
|
|
53
|
+
"@elementor/editor-v1-adapters": "3.32.0-21",
|
|
54
54
|
"@elementor/icons": "1.46.0",
|
|
55
|
-
"@elementor/locations": "
|
|
56
|
-
"@elementor/menus": "
|
|
57
|
-
"@elementor/schema": "
|
|
58
|
-
"@elementor/session": "
|
|
59
|
-
"@elementor/ui": "1.36.
|
|
60
|
-
"@elementor/utils": "
|
|
61
|
-
"@elementor/wp-media": "
|
|
55
|
+
"@elementor/locations": "3.32.0-21",
|
|
56
|
+
"@elementor/menus": "3.32.0-21",
|
|
57
|
+
"@elementor/schema": "3.32.0-21",
|
|
58
|
+
"@elementor/session": "3.32.0-21",
|
|
59
|
+
"@elementor/ui": "1.36.2",
|
|
60
|
+
"@elementor/utils": "3.32.0-21",
|
|
61
|
+
"@elementor/wp-media": "3.32.0-21",
|
|
62
62
|
"@wordpress/i18n": "^5.13.0"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { deleteElementStyle, getElementSetting, updateElementSettings } from '@elementor/editor-elements';
|
|
3
|
+
import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
|
|
4
|
+
import { type StyleDefinition } from '@elementor/editor-styles';
|
|
5
|
+
import { createLocation } from '@elementor/locations';
|
|
6
|
+
import { useSessionStorage } from '@elementor/session';
|
|
7
|
+
|
|
8
|
+
import { useClassesProp } from '../../contexts/classes-prop-context';
|
|
9
|
+
import { useElement } from '../../contexts/element-context';
|
|
10
|
+
import { useStyle } from '../../contexts/style-context';
|
|
11
|
+
|
|
12
|
+
export const { Slot: CssClassConvertSlot, inject: injectIntoCssClassConvert } = createLocation< {
|
|
13
|
+
styleDef: StyleDefinition | null;
|
|
14
|
+
successCallback: ( newId: string ) => void;
|
|
15
|
+
canConvert: boolean;
|
|
16
|
+
} >();
|
|
17
|
+
|
|
18
|
+
type OwnProps = {
|
|
19
|
+
styleDef: StyleDefinition | null;
|
|
20
|
+
closeMenu: () => void;
|
|
21
|
+
canConvert: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Convert a local class to a global class injection point
|
|
26
|
+
* @param props
|
|
27
|
+
*/
|
|
28
|
+
export const CssClassConvert = ( props: OwnProps ) => {
|
|
29
|
+
const { element } = useElement();
|
|
30
|
+
const elementId = element.id;
|
|
31
|
+
const currentClassesProp = useClassesProp();
|
|
32
|
+
const { setId: setActiveId } = useStyle();
|
|
33
|
+
const [ , saveValue ] = useSessionStorage( `last-converted-class-generated-name` );
|
|
34
|
+
|
|
35
|
+
const successCallback = ( newId: string ) => {
|
|
36
|
+
if ( ! props.styleDef ) {
|
|
37
|
+
throw new Error( 'Style definition is required for converting local class to global class.' );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onConvert( {
|
|
41
|
+
newId,
|
|
42
|
+
elementId,
|
|
43
|
+
classesProp: currentClassesProp,
|
|
44
|
+
styleDef: props.styleDef,
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
saveValue( newId );
|
|
48
|
+
setActiveId( newId );
|
|
49
|
+
props.closeMenu();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<CssClassConvertSlot
|
|
54
|
+
canConvert={ !! props.canConvert }
|
|
55
|
+
styleDef={ props.styleDef }
|
|
56
|
+
successCallback={ successCallback }
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type OnConvertOptions = {
|
|
62
|
+
newId: string;
|
|
63
|
+
elementId: string;
|
|
64
|
+
classesProp: string;
|
|
65
|
+
styleDef: StyleDefinition;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const onConvert = ( opts: OnConvertOptions ) => {
|
|
69
|
+
const { newId, elementId, classesProp } = opts;
|
|
70
|
+
deleteElementStyle( elementId, opts.styleDef.id );
|
|
71
|
+
const currentUsedClasses = getElementSetting< ClassesPropValue >( elementId, classesProp ) || { value: [] };
|
|
72
|
+
updateElementSettings( {
|
|
73
|
+
id: elementId,
|
|
74
|
+
props: { [ classesProp ]: classesPropTypeUtil.create( [ newId, ...currentUsedClasses.value ] ) },
|
|
75
|
+
withHistory: false,
|
|
76
|
+
} );
|
|
77
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type ReactElement, useState } from 'react';
|
|
2
|
+
import { type ReactElement, useEffect, useState } from 'react';
|
|
3
3
|
import { stylesRepository, useUserStylesCapability, validateStyleLabel } from '@elementor/editor-styles-repository';
|
|
4
4
|
import { EditableField, EllipsisWithTooltip, useEditable } from '@elementor/editor-ui';
|
|
5
5
|
import { DotsVerticalIcon } from '@elementor/icons';
|
|
6
|
+
import { useSessionStorage } from '@elementor/session';
|
|
6
7
|
import {
|
|
7
8
|
type AutocompleteRenderGetTagProps,
|
|
8
9
|
bindTrigger,
|
|
@@ -49,6 +50,10 @@ export function CssClassItem( props: CssClassItemProps ) {
|
|
|
49
50
|
|
|
50
51
|
const { userCan } = useUserStylesCapability();
|
|
51
52
|
|
|
53
|
+
const [ convertedFromLocalId, , clearConvertedFromLocalId ] = useSessionStorage(
|
|
54
|
+
`last-converted-class-generated-name`
|
|
55
|
+
);
|
|
56
|
+
|
|
52
57
|
const {
|
|
53
58
|
ref,
|
|
54
59
|
isEditing,
|
|
@@ -69,6 +74,15 @@ export function CssClassItem( props: CssClassItemProps ) {
|
|
|
69
74
|
|
|
70
75
|
const isShowingState = isActive && meta.state;
|
|
71
76
|
|
|
77
|
+
useEffect( () => {
|
|
78
|
+
if ( convertedFromLocalId && id === convertedFromLocalId ) {
|
|
79
|
+
clearConvertedFromLocalId();
|
|
80
|
+
openEditMode();
|
|
81
|
+
}
|
|
82
|
+
// eslint-disable-next-line react-compiler/react-compiler
|
|
83
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
84
|
+
}, [ id ] );
|
|
85
|
+
|
|
72
86
|
return (
|
|
73
87
|
<ThemeProvider palette="default">
|
|
74
88
|
<UnstableChipGroup
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type StyleDefinitionState } from '@elementor/editor-styles';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
isElementsStylesProvider,
|
|
5
|
+
stylesRepository,
|
|
6
|
+
useUserStylesCapability,
|
|
7
|
+
} from '@elementor/editor-styles-repository';
|
|
4
8
|
import { MenuItemInfotip, MenuListItem } from '@elementor/editor-ui';
|
|
5
9
|
import { bindMenu, Divider, Menu, MenuSubheader, type PopupState, Stack } from '@elementor/ui';
|
|
6
10
|
import { __ } from '@wordpress/i18n';
|
|
@@ -10,6 +14,7 @@ import { type StyleDefinitionStateWithNormal } from '../../styles-inheritance/ty
|
|
|
10
14
|
import { getTempStylesProviderThemeColor } from '../../utils/get-styles-provider-color';
|
|
11
15
|
import { StyleIndicator } from '../style-indicator';
|
|
12
16
|
import { useCssClass } from './css-class-context';
|
|
17
|
+
import { LocalClassSubMenu } from './local-class-sub-menu';
|
|
13
18
|
import { useUnapplyClass } from './use-apply-and-unapply-class';
|
|
14
19
|
|
|
15
20
|
type State = {
|
|
@@ -32,6 +37,7 @@ type CssClassMenuProps = {
|
|
|
32
37
|
|
|
33
38
|
export function CssClassMenu( { popupState, anchorEl, fixed }: CssClassMenuProps ) {
|
|
34
39
|
const { provider } = useCssClass();
|
|
40
|
+
const isLocalStyle = provider ? isElementsStylesProvider( provider ) : true;
|
|
35
41
|
|
|
36
42
|
const handleKeyDown = ( e: React.KeyboardEvent< HTMLElement > ) => {
|
|
37
43
|
e.stopPropagation();
|
|
@@ -54,6 +60,7 @@ export function CssClassMenu( { popupState, anchorEl, fixed }: CssClassMenuProps
|
|
|
54
60
|
// Workaround for focus-visible issue.
|
|
55
61
|
disableAutoFocusItem
|
|
56
62
|
>
|
|
63
|
+
{ isLocalStyle && <LocalClassSubMenu popupState={ popupState } /> }
|
|
57
64
|
{ /* It has to be an array since MUI menu doesn't accept a Fragment as a child, and wrapping the items with an HTML element disrupts keyboard navigation */ }
|
|
58
65
|
{ getMenuItemsByProvider( { provider, closeMenu: popupState.close, fixed } ) }
|
|
59
66
|
<MenuSubheader sx={ { typography: 'caption', color: 'text.secondary', pb: 0.5, pt: 1 } }>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { MenuSubheader, type PopupState } from '@elementor/ui';
|
|
3
|
+
import { __ } from '@wordpress/i18n';
|
|
4
|
+
|
|
5
|
+
import { CssClassConvert } from './css-class-convert-local';
|
|
6
|
+
import { useCanConvertLocalClassToGlobal } from './use-can-convert-local-class-to-global';
|
|
7
|
+
|
|
8
|
+
type OwnProps = {
|
|
9
|
+
popupState: PopupState;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const LocalClassSubMenu = ( props: OwnProps ) => {
|
|
13
|
+
const { canConvert, styleDef } = useCanConvertLocalClassToGlobal();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<MenuSubheader sx={ { typography: 'caption', color: 'text.secondary', pb: 0.5, pt: 1 } }>
|
|
18
|
+
{ __( 'Local Class', 'elementor' ) }
|
|
19
|
+
</MenuSubheader>
|
|
20
|
+
<CssClassConvert canConvert={ canConvert } styleDef={ styleDef } closeMenu={ props.popupState.close } />
|
|
21
|
+
</>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
@@ -4,13 +4,12 @@ import { getElementLabel, getElementSetting, updateElementSettings } from '@elem
|
|
|
4
4
|
import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
|
|
5
5
|
import { type StyleDefinitionID } from '@elementor/editor-styles';
|
|
6
6
|
import { useGetStylesRepositoryCreateAction } from '@elementor/editor-styles-repository';
|
|
7
|
-
import {
|
|
7
|
+
import { undoable } from '@elementor/editor-v1-adapters';
|
|
8
8
|
import { __ } from '@wordpress/i18n';
|
|
9
9
|
|
|
10
10
|
import { useClassesProp } from '../../contexts/classes-prop-context';
|
|
11
11
|
import { useElement } from '../../contexts/element-context';
|
|
12
12
|
import { useStyle } from '../../contexts/style-context';
|
|
13
|
-
import { EXPERIMENTAL_FEATURES } from '../../sync/experiments-flags';
|
|
14
13
|
|
|
15
14
|
type UndoableClassActionPayload = {
|
|
16
15
|
classId: StyleDefinitionID;
|
|
@@ -30,12 +29,10 @@ export function useApplyClass() {
|
|
|
30
29
|
const { id: activeId, setId: setActiveId } = useStyle();
|
|
31
30
|
const { element } = useElement();
|
|
32
31
|
|
|
33
|
-
const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
|
|
34
|
-
|
|
35
32
|
const applyClass = useApply();
|
|
36
33
|
const unapplyClass = useUnapply();
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
return useMemo( () => {
|
|
39
36
|
return undoable(
|
|
40
37
|
{
|
|
41
38
|
do: ( { classId }: UndoableClassActionPayload ) => {
|
|
@@ -59,27 +56,16 @@ export function useApplyClass() {
|
|
|
59
56
|
}
|
|
60
57
|
);
|
|
61
58
|
}, [ activeId, applyClass, element.id, unapplyClass, setActiveId ] );
|
|
62
|
-
|
|
63
|
-
const applyWithoutHistory = useCallback(
|
|
64
|
-
( { classId }: UndoableClassActionPayload ) => {
|
|
65
|
-
applyClass( classId );
|
|
66
|
-
},
|
|
67
|
-
[ applyClass ]
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
return isVersion330Active ? undoableApply : applyWithoutHistory;
|
|
71
59
|
}
|
|
72
60
|
|
|
73
61
|
export function useUnapplyClass() {
|
|
74
62
|
const { id: activeId, setId: setActiveId } = useStyle();
|
|
75
63
|
const { element } = useElement();
|
|
76
64
|
|
|
77
|
-
const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
|
|
78
|
-
|
|
79
65
|
const applyClass = useApply();
|
|
80
66
|
const unapplyClass = useUnapply();
|
|
81
67
|
|
|
82
|
-
|
|
68
|
+
return useMemo( () => {
|
|
83
69
|
return undoable(
|
|
84
70
|
{
|
|
85
71
|
do: ( { classId }: UndoableClassActionPayload ) => {
|
|
@@ -103,22 +89,11 @@ export function useUnapplyClass() {
|
|
|
103
89
|
}
|
|
104
90
|
);
|
|
105
91
|
}, [ activeId, applyClass, element.id, unapplyClass, setActiveId ] );
|
|
106
|
-
|
|
107
|
-
const unapplyWithoutHistory = useCallback(
|
|
108
|
-
( { classId }: UndoableClassActionPayload ) => {
|
|
109
|
-
unapplyClass( classId );
|
|
110
|
-
},
|
|
111
|
-
[ unapplyClass ]
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
return isVersion330Active ? undoableUnapply : unapplyWithoutHistory;
|
|
115
92
|
}
|
|
116
93
|
|
|
117
94
|
export function useCreateAndApplyClass() {
|
|
118
95
|
const { id: activeId, setId: setActiveId } = useStyle();
|
|
119
96
|
|
|
120
|
-
const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
|
|
121
|
-
|
|
122
97
|
const [ provider, createAction ] = useGetStylesRepositoryCreateAction() ?? [ null, null ];
|
|
123
98
|
const deleteAction = provider?.actions.delete;
|
|
124
99
|
|
|
@@ -157,25 +132,11 @@ export function useCreateAndApplyClass() {
|
|
|
157
132
|
);
|
|
158
133
|
}, [ activeId, applyClass, createAction, deleteAction, provider, setActiveId, unapplyClass ] );
|
|
159
134
|
|
|
160
|
-
const createAndApplyWithoutHistory = useCallback(
|
|
161
|
-
( { classLabel }: CreateAndApplyClassPayload ) => {
|
|
162
|
-
if ( ! createAction ) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const createdId = createAction( classLabel );
|
|
167
|
-
applyClass( createdId );
|
|
168
|
-
},
|
|
169
|
-
[ applyClass, createAction ]
|
|
170
|
-
);
|
|
171
|
-
|
|
172
135
|
if ( ! provider || ! undoableCreateAndApply ) {
|
|
173
136
|
return [ null, null ];
|
|
174
137
|
}
|
|
175
138
|
|
|
176
|
-
return
|
|
177
|
-
? ( [ provider, undoableCreateAndApply ] as const )
|
|
178
|
-
: ( [ provider, createAndApplyWithoutHistory ] as const );
|
|
139
|
+
return [ provider, undoableCreateAndApply ] as const;
|
|
179
140
|
}
|
|
180
141
|
|
|
181
142
|
function useApply() {
|
|
@@ -231,24 +192,20 @@ function useClasses() {
|
|
|
231
192
|
const { element } = useElement();
|
|
232
193
|
const currentClassesProp = useClassesProp();
|
|
233
194
|
|
|
234
|
-
const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
|
|
235
|
-
|
|
236
195
|
return useMemo( () => {
|
|
237
196
|
const setClasses = ( ids: StyleDefinitionID[] ) => {
|
|
238
197
|
updateElementSettings( {
|
|
239
198
|
id: element.id,
|
|
240
199
|
props: { [ currentClassesProp ]: classesPropTypeUtil.create( ids ) },
|
|
241
|
-
withHistory:
|
|
200
|
+
withHistory: false,
|
|
242
201
|
} );
|
|
243
202
|
|
|
244
|
-
|
|
245
|
-
setDocumentModifiedStatus( true );
|
|
246
|
-
}
|
|
203
|
+
setDocumentModifiedStatus( true );
|
|
247
204
|
};
|
|
248
205
|
|
|
249
206
|
const getAppliedClasses = () =>
|
|
250
207
|
getElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
|
|
251
208
|
|
|
252
209
|
return { setClasses, getAppliedClasses };
|
|
253
|
-
}, [ currentClassesProp, element.id
|
|
210
|
+
}, [ currentClassesProp, element.id ] );
|
|
254
211
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isElementsStylesProvider } from '@elementor/editor-styles-repository';
|
|
2
|
+
|
|
3
|
+
import { useElement } from '../../contexts/element-context';
|
|
4
|
+
import { useStyle } from '../../contexts/style-context';
|
|
5
|
+
|
|
6
|
+
export const useCanConvertLocalClassToGlobal = () => {
|
|
7
|
+
const { element } = useElement();
|
|
8
|
+
const { provider, id, meta } = useStyle();
|
|
9
|
+
const styleDef = provider?.actions.get( id, { elementId: element.id, ...meta } );
|
|
10
|
+
|
|
11
|
+
const isLocalStylesProvider = provider && isElementsStylesProvider( provider?.getKey() );
|
|
12
|
+
const variants = styleDef?.variants || [];
|
|
13
|
+
|
|
14
|
+
const canConvert = !! ( isLocalStylesProvider && variants.length );
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
canConvert,
|
|
18
|
+
isLocalStylesProvider,
|
|
19
|
+
id,
|
|
20
|
+
styleDef: styleDef || null,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TextField } from '@elementor/ui';
|
|
3
|
+
|
|
4
|
+
import { useCustomCss } from '../hooks/use-custom-css';
|
|
5
|
+
import { SectionContent } from './section-content';
|
|
6
|
+
|
|
7
|
+
export const CustomCss = () => {
|
|
8
|
+
const { customCss, setCustomCss } = useCustomCss();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<SectionContent>
|
|
12
|
+
<TextField
|
|
13
|
+
value={ customCss?.raw || '' }
|
|
14
|
+
onChange={ ( ev: React.ChangeEvent< HTMLInputElement > ) =>
|
|
15
|
+
setCustomCss( ev.target.value, { history: { propDisplayName: 'Custom CSS' } } )
|
|
16
|
+
}
|
|
17
|
+
multiline
|
|
18
|
+
/>
|
|
19
|
+
</SectionContent>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
3
|
import { Divider, Stack, Tab, TabPanel, Tabs, useTabs } from '@elementor/ui';
|
|
5
4
|
import { __ } from '@wordpress/i18n';
|
|
6
5
|
|
|
@@ -8,7 +7,6 @@ import { useElement } from '../contexts/element-context';
|
|
|
8
7
|
import { ScrollProvider } from '../contexts/scroll-context';
|
|
9
8
|
import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
|
|
10
9
|
import { useStateByElement } from '../hooks/use-state-by-element';
|
|
11
|
-
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
12
10
|
import { SettingsTab } from './settings-tab';
|
|
13
11
|
import { stickyHeaderStyles, StyleTab } from './style-tab';
|
|
14
12
|
|
|
@@ -27,9 +25,7 @@ export const EditingPanelTabs = () => {
|
|
|
27
25
|
|
|
28
26
|
const PanelTabContent = () => {
|
|
29
27
|
const editorDefaults = useDefaultPanelSettings();
|
|
30
|
-
const defaultComponentTab =
|
|
31
|
-
? ( editorDefaults.defaultTab as TabValue )
|
|
32
|
-
: 'settings';
|
|
28
|
+
const defaultComponentTab = editorDefaults.defaultTab as TabValue;
|
|
33
29
|
|
|
34
30
|
const [ currentTab, setCurrentTab ] = useStateByElement< TabValue >( 'tab', defaultComponentTab );
|
|
35
31
|
const { getTabProps, getTabPanelProps, getTabsProps } = useTabs< TabValue >( currentTab );
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type PropsWithChildren, type ReactNode, useId, useRef } from 'react';
|
|
3
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
3
|
import { Collapse, Divider, ListItemButton, ListItemText, Stack } from '@elementor/ui';
|
|
5
4
|
|
|
6
5
|
import { SectionRefContext } from '../contexts/section-context';
|
|
7
6
|
import { useStateByElement } from '../hooks/use-state-by-element';
|
|
8
|
-
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
9
7
|
import { CollapseIcon } from './collapse-icon';
|
|
10
8
|
import { type CollapsibleValue, getCollapsibleValue } from './collapsible-content';
|
|
11
9
|
|
|
@@ -27,8 +25,6 @@ export function Section( { title, children, defaultExpanded = false, titleEnd }:
|
|
|
27
25
|
const labelId = `label-${ id }`;
|
|
28
26
|
const contentId = `content-${ id }`;
|
|
29
27
|
|
|
30
|
-
const isUsingTitleEnd = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
|
|
31
|
-
|
|
32
28
|
return (
|
|
33
29
|
<>
|
|
34
30
|
<ListItemButton
|
|
@@ -43,7 +39,7 @@ export function Section( { title, children, defaultExpanded = false, titleEnd }:
|
|
|
43
39
|
secondaryTypographyProps={ { color: 'text.primary', variant: 'caption', fontWeight: 'bold' } }
|
|
44
40
|
sx={ { flexGrow: 0, flexShrink: 1, marginInlineEnd: 1 } }
|
|
45
41
|
/>
|
|
46
|
-
{
|
|
42
|
+
{ getCollapsibleValue( titleEnd, isOpen ) }
|
|
47
43
|
</Stack>
|
|
48
44
|
<CollapseIcon open={ isOpen } color="secondary" fontSize="tiny" />
|
|
49
45
|
</ListItemButton>
|
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ControlFormLabel } from '@elementor/editor-controls';
|
|
3
3
|
import { type Control } from '@elementor/editor-elements';
|
|
4
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
5
4
|
import { SessionStorageProvider } from '@elementor/session';
|
|
6
5
|
import { Divider } from '@elementor/ui';
|
|
7
6
|
|
|
8
7
|
import { useElement } from '../contexts/element-context';
|
|
9
8
|
import { Control as BaseControl } from '../controls-registry/control';
|
|
10
9
|
import { ControlTypeContainer } from '../controls-registry/control-type-container';
|
|
11
|
-
import {
|
|
12
|
-
type ControlType,
|
|
13
|
-
getControl,
|
|
14
|
-
getDefaultLayout,
|
|
15
|
-
getPropTypeUtil,
|
|
16
|
-
} from '../controls-registry/controls-registry';
|
|
10
|
+
import { controlsRegistry, type ControlType } from '../controls-registry/controls-registry';
|
|
17
11
|
import { SettingsField } from '../controls-registry/settings-field';
|
|
18
12
|
import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
|
|
19
|
-
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
20
13
|
import { Section } from './section';
|
|
21
14
|
import { SectionsList } from './sections-list';
|
|
22
15
|
|
|
@@ -25,9 +18,7 @@ export const SettingsTab = () => {
|
|
|
25
18
|
const settingsDefault = useDefaultPanelSettings();
|
|
26
19
|
|
|
27
20
|
const isDefaultExpanded = ( sectionId: string ) =>
|
|
28
|
-
|
|
29
|
-
? settingsDefault.defaultSectionsExpanded.settings?.includes( sectionId )
|
|
30
|
-
: true;
|
|
21
|
+
settingsDefault.defaultSectionsExpanded.settings?.includes( sectionId );
|
|
31
22
|
|
|
32
23
|
return (
|
|
33
24
|
<SessionStorageProvider prefix={ element.id }>
|
|
@@ -64,11 +55,11 @@ export const SettingsTab = () => {
|
|
|
64
55
|
};
|
|
65
56
|
|
|
66
57
|
const Control = ( { control }: { control: Control[ 'value' ] } ) => {
|
|
67
|
-
if ( !
|
|
58
|
+
if ( ! controlsRegistry.get( control.type as ControlType ) ) {
|
|
68
59
|
return null;
|
|
69
60
|
}
|
|
70
61
|
|
|
71
|
-
const layout = control.meta?.layout ||
|
|
62
|
+
const layout = control.meta?.layout || controlsRegistry.getLayout( control.type as ControlType );
|
|
72
63
|
const controlProps = populateChildControlProps( control.props );
|
|
73
64
|
if ( layout === 'custom' ) {
|
|
74
65
|
controlProps.label = control.label;
|
|
@@ -87,8 +78,8 @@ const Control = ( { control }: { control: Control[ 'value' ] } ) => {
|
|
|
87
78
|
|
|
88
79
|
function populateChildControlProps( props: Record< string, unknown > ) {
|
|
89
80
|
if ( props.childControlType ) {
|
|
90
|
-
const childComponent =
|
|
91
|
-
const childPropType = getPropTypeUtil( props.childControlType as ControlType );
|
|
81
|
+
const childComponent = controlsRegistry.get( props.childControlType as ControlType );
|
|
82
|
+
const childPropType = controlsRegistry.getPropTypeUtil( props.childControlType as ControlType );
|
|
92
83
|
props = {
|
|
93
84
|
...props,
|
|
94
85
|
childControlConfig: {
|
|
@@ -1,49 +1,57 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
BoxShadowRepeaterControl,
|
|
4
|
+
FilterRepeaterControl,
|
|
5
|
+
TransformRepeaterControl,
|
|
6
|
+
TransitionRepeaterControl,
|
|
7
|
+
UnstableTransformRepeaterControl,
|
|
8
|
+
} from '@elementor/editor-controls';
|
|
9
|
+
import { EXPERIMENTAL_FEATURES, isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
10
|
import { __ } from '@wordpress/i18n';
|
|
5
11
|
|
|
6
12
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
|
-
import { EXPERIMENTAL_FEATURES } from '../../../sync/experiments-flags';
|
|
8
13
|
import { PanelDivider } from '../../panel-divider';
|
|
9
14
|
import { SectionContent } from '../../section-content';
|
|
10
|
-
import { OpacityControlField } from '
|
|
15
|
+
import { OpacityControlField } from './opacity-control-field';
|
|
11
16
|
|
|
12
17
|
const BOX_SHADOW_LABEL = __( 'Box shadow', 'elementor' );
|
|
13
18
|
const FILTER_LABEL = __( 'Filters', 'elementor' );
|
|
14
19
|
const TRANSFORM_LABEL = __( 'Transform', 'elementor' );
|
|
15
20
|
const BACKDROP_FILTER_LABEL = __( 'Backdrop filters', 'elementor' );
|
|
21
|
+
const TRANSITIONS_LABEL = __( 'Transitions', 'elementor' );
|
|
16
22
|
|
|
17
23
|
export const EffectsSection = () => {
|
|
18
|
-
const
|
|
24
|
+
const shouldShowTransition = isExperimentActive( EXPERIMENTAL_FEATURES.TRANSITIONS );
|
|
25
|
+
|
|
26
|
+
const isUnstableRepeaterActive = isExperimentActive( EXPERIMENTAL_FEATURES.UNSTABLE_REPEATER );
|
|
19
27
|
|
|
20
28
|
return (
|
|
21
29
|
<SectionContent>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<OpacityControlField />
|
|
25
|
-
<PanelDivider />
|
|
26
|
-
</>
|
|
27
|
-
) }
|
|
30
|
+
<OpacityControlField />
|
|
31
|
+
<PanelDivider />
|
|
28
32
|
<StylesField bind="box-shadow" propDisplayName={ BOX_SHADOW_LABEL }>
|
|
29
33
|
<BoxShadowRepeaterControl />
|
|
30
34
|
</StylesField>
|
|
31
|
-
|
|
35
|
+
<PanelDivider />
|
|
36
|
+
<StylesField bind="transform" propDisplayName={ TRANSFORM_LABEL }>
|
|
37
|
+
{ isUnstableRepeaterActive ? <UnstableTransformRepeaterControl /> : <TransformRepeaterControl /> }
|
|
38
|
+
</StylesField>
|
|
39
|
+
{ shouldShowTransition && (
|
|
32
40
|
<>
|
|
33
41
|
<PanelDivider />
|
|
34
|
-
<StylesField bind="
|
|
35
|
-
<
|
|
36
|
-
</StylesField>
|
|
37
|
-
<PanelDivider />
|
|
38
|
-
<StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
|
|
39
|
-
<FilterRepeaterControl />
|
|
40
|
-
</StylesField>
|
|
41
|
-
<PanelDivider />
|
|
42
|
-
<StylesField bind="backdrop-filter" propDisplayName={ BACKDROP_FILTER_LABEL }>
|
|
43
|
-
<FilterRepeaterControl filterPropName="backdrop-filter" />
|
|
42
|
+
<StylesField bind="transition" propDisplayName={ TRANSITIONS_LABEL }>
|
|
43
|
+
<TransitionRepeaterControl />
|
|
44
44
|
</StylesField>
|
|
45
45
|
</>
|
|
46
46
|
) }
|
|
47
|
+
<PanelDivider />
|
|
48
|
+
<StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
|
|
49
|
+
<FilterRepeaterControl />
|
|
50
|
+
</StylesField>
|
|
51
|
+
<PanelDivider />
|
|
52
|
+
<StylesField bind="backdrop-filter" propDisplayName={ BACKDROP_FILTER_LABEL }>
|
|
53
|
+
<FilterRepeaterControl filterPropName="backdrop-filter" />
|
|
54
|
+
</StylesField>
|
|
47
55
|
</SectionContent>
|
|
48
56
|
);
|
|
49
57
|
};
|