@elementor/editor-controls 3.35.0-487 → 3.35.0-489
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.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +205 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +215 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/item-selector.tsx +63 -52
- package/src/controls/transition-control/data.ts +129 -7
- package/src/controls/transition-control/transition-repeater-control.tsx +21 -9
- package/src/controls/transition-control/transition-selector.tsx +59 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-controls",
|
|
3
3
|
"description": "This package contains the controls model and utils for the Elementor editor",
|
|
4
|
-
"version": "3.35.0-
|
|
4
|
+
"version": "3.35.0-489",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,22 +40,22 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "3.35.0-
|
|
44
|
-
"@elementor/editor-elements": "3.35.0-
|
|
45
|
-
"@elementor/editor-props": "3.35.0-
|
|
46
|
-
"@elementor/editor-responsive": "3.35.0-
|
|
47
|
-
"@elementor/editor-ui": "3.35.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "3.35.0-
|
|
49
|
-
"@elementor/env": "3.35.0-
|
|
50
|
-
"@elementor/http-client": "3.35.0-
|
|
43
|
+
"@elementor/editor-current-user": "3.35.0-489",
|
|
44
|
+
"@elementor/editor-elements": "3.35.0-489",
|
|
45
|
+
"@elementor/editor-props": "3.35.0-489",
|
|
46
|
+
"@elementor/editor-responsive": "3.35.0-489",
|
|
47
|
+
"@elementor/editor-ui": "3.35.0-489",
|
|
48
|
+
"@elementor/editor-v1-adapters": "3.35.0-489",
|
|
49
|
+
"@elementor/env": "3.35.0-489",
|
|
50
|
+
"@elementor/http-client": "3.35.0-489",
|
|
51
51
|
"@elementor/icons": "^1.63.0",
|
|
52
|
-
"@elementor/locations": "3.35.0-
|
|
53
|
-
"@elementor/mixpanel": "3.35.0-
|
|
54
|
-
"@elementor/query": "3.35.0-
|
|
55
|
-
"@elementor/session": "3.35.0-
|
|
52
|
+
"@elementor/locations": "3.35.0-489",
|
|
53
|
+
"@elementor/mixpanel": "3.35.0-489",
|
|
54
|
+
"@elementor/query": "3.35.0-489",
|
|
55
|
+
"@elementor/session": "3.35.0-489",
|
|
56
56
|
"@elementor/ui": "1.36.17",
|
|
57
|
-
"@elementor/utils": "3.35.0-
|
|
58
|
-
"@elementor/wp-media": "3.35.0-
|
|
57
|
+
"@elementor/utils": "3.35.0-489",
|
|
58
|
+
"@elementor/wp-media": "3.35.0-489",
|
|
59
59
|
"@wordpress/i18n": "^5.13.0",
|
|
60
60
|
"@monaco-editor/react": "^4.7.0",
|
|
61
61
|
"dayjs": "^1.11.18",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { type ReactNode, useCallback, useEffect, useState } from 'react';
|
|
3
3
|
import { PopoverBody, PopoverHeader, PopoverMenuList, SearchField } from '@elementor/editor-ui';
|
|
4
4
|
import { Box, Divider, Link, Stack, Typography } from '@elementor/ui';
|
|
5
5
|
import { debounce } from '@elementor/utils';
|
|
@@ -24,6 +24,8 @@ type ItemSelectorProps = {
|
|
|
24
24
|
icon: React.ElementType< { fontSize: string } >;
|
|
25
25
|
disabledItems?: string[];
|
|
26
26
|
id?: string;
|
|
27
|
+
footer?: ReactNode;
|
|
28
|
+
categoryItemContentTemplate?: ( item: SelectableItem ) => ReactNode;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
export const ItemSelector = ( {
|
|
@@ -38,6 +40,8 @@ export const ItemSelector = ( {
|
|
|
38
40
|
icon,
|
|
39
41
|
disabledItems,
|
|
40
42
|
id = 'item-selector',
|
|
43
|
+
footer,
|
|
44
|
+
categoryItemContentTemplate,
|
|
41
45
|
}: ItemSelectorProps ) => {
|
|
42
46
|
const [ searchValue, setSearchValue ] = useState( '' );
|
|
43
47
|
|
|
@@ -66,62 +70,66 @@ export const ItemSelector = ( {
|
|
|
66
70
|
|
|
67
71
|
<Divider />
|
|
68
72
|
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
73
|
+
<Box sx={ { flex: 1, overflow: 'auto', minHeight: 0 } }>
|
|
74
|
+
{ filteredItemsList.length > 0 ? (
|
|
75
|
+
<ItemList
|
|
76
|
+
itemListItems={ filteredItemsList }
|
|
77
|
+
setSelectedItem={ onItemChange }
|
|
78
|
+
handleClose={ handleClose }
|
|
79
|
+
selectedItem={ selectedItem }
|
|
80
|
+
itemStyle={ itemStyle }
|
|
81
|
+
onDebounce={ onDebounce }
|
|
82
|
+
categoryItemContentTemplate={ categoryItemContentTemplate }
|
|
83
|
+
/>
|
|
84
|
+
) : (
|
|
85
|
+
<Stack
|
|
86
|
+
alignItems="center"
|
|
87
|
+
justifyContent="center"
|
|
88
|
+
height="100%"
|
|
89
|
+
p={ 2.5 }
|
|
90
|
+
gap={ 1.5 }
|
|
91
|
+
overflow="hidden"
|
|
92
|
+
>
|
|
93
|
+
<IconComponent fontSize="large" />
|
|
94
|
+
<Box sx={ { maxWidth: 160, overflow: 'hidden' } }>
|
|
95
|
+
<Typography align="center" variant="subtitle2" color="text.secondary">
|
|
96
|
+
{ __( 'Sorry, nothing matched', 'elementor' ) }
|
|
97
|
+
</Typography>
|
|
98
|
+
<Typography
|
|
99
|
+
variant="subtitle2"
|
|
100
|
+
color="text.secondary"
|
|
101
|
+
sx={ { display: 'flex', width: '100%', justifyContent: 'center' } }
|
|
102
|
+
>
|
|
103
|
+
<span>“</span>
|
|
104
|
+
<Box
|
|
105
|
+
component="span"
|
|
106
|
+
sx={ { maxWidth: '80%', overflow: 'hidden', textOverflow: 'ellipsis' } }
|
|
107
|
+
>
|
|
108
|
+
{ searchValue }
|
|
109
|
+
</Box>
|
|
110
|
+
<span>”.</span>
|
|
111
|
+
</Typography>
|
|
112
|
+
</Box>
|
|
92
113
|
<Typography
|
|
93
|
-
|
|
114
|
+
align="center"
|
|
115
|
+
variant="caption"
|
|
94
116
|
color="text.secondary"
|
|
95
|
-
sx={ { display: 'flex',
|
|
117
|
+
sx={ { display: 'flex', flexDirection: 'column' } }
|
|
96
118
|
>
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
119
|
+
{ __( 'Try something else.', 'elementor' ) }
|
|
120
|
+
<Link
|
|
121
|
+
color="secondary"
|
|
122
|
+
variant="caption"
|
|
123
|
+
component="button"
|
|
124
|
+
onClick={ () => setSearchValue( '' ) }
|
|
101
125
|
>
|
|
102
|
-
{
|
|
103
|
-
</
|
|
104
|
-
<span>”.</span>
|
|
126
|
+
{ __( 'Clear & try again', 'elementor' ) }
|
|
127
|
+
</Link>
|
|
105
128
|
</Typography>
|
|
106
|
-
</
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
color="text.secondary"
|
|
111
|
-
sx={ { display: 'flex', flexDirection: 'column' } }
|
|
112
|
-
>
|
|
113
|
-
{ __( 'Try something else.', 'elementor' ) }
|
|
114
|
-
<Link
|
|
115
|
-
color="secondary"
|
|
116
|
-
variant="caption"
|
|
117
|
-
component="button"
|
|
118
|
-
onClick={ () => setSearchValue( '' ) }
|
|
119
|
-
>
|
|
120
|
-
{ __( 'Clear & try again', 'elementor' ) }
|
|
121
|
-
</Link>
|
|
122
|
-
</Typography>
|
|
123
|
-
</Stack>
|
|
124
|
-
) }
|
|
129
|
+
</Stack>
|
|
130
|
+
) }
|
|
131
|
+
</Box>
|
|
132
|
+
{ footer }
|
|
125
133
|
</PopoverBody>
|
|
126
134
|
);
|
|
127
135
|
};
|
|
@@ -134,6 +142,7 @@ type ItemListProps = {
|
|
|
134
142
|
itemStyle?: ( item: SelectableItem ) => React.CSSProperties;
|
|
135
143
|
onDebounce?: ( name: string ) => void;
|
|
136
144
|
disabledItems?: string[];
|
|
145
|
+
categoryItemContentTemplate?: ( item: SelectableItem ) => ReactNode;
|
|
137
146
|
};
|
|
138
147
|
|
|
139
148
|
const ItemList = ( {
|
|
@@ -143,6 +152,7 @@ const ItemList = ( {
|
|
|
143
152
|
selectedItem,
|
|
144
153
|
itemStyle = () => ( {} ),
|
|
145
154
|
onDebounce = () => {},
|
|
155
|
+
categoryItemContentTemplate,
|
|
146
156
|
}: ItemListProps ) => {
|
|
147
157
|
const selectedItemFound = itemListItems.find( ( item ) => item.value === selectedItem );
|
|
148
158
|
|
|
@@ -165,6 +175,7 @@ const ItemList = ( {
|
|
|
165
175
|
onClose={ handleClose }
|
|
166
176
|
itemStyle={ memoizedItemStyle }
|
|
167
177
|
data-testid="item-list"
|
|
178
|
+
categoryItemContentTemplate={ categoryItemContentTemplate }
|
|
168
179
|
/>
|
|
169
180
|
);
|
|
170
181
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type KeyValuePropValue, type SizePropValue } from '@elementor/editor-props';
|
|
2
|
+
import { isVersionGreaterOrEqual } from '@elementor/utils';
|
|
2
3
|
import { __ } from '@wordpress/i18n';
|
|
3
4
|
|
|
4
5
|
export type TransitionProperty = {
|
|
@@ -38,13 +39,134 @@ export const initialTransitionValue: TransitionValue = {
|
|
|
38
39
|
size: { $$type: 'size', value: { size: 200, unit: 'ms' } },
|
|
39
40
|
};
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
const MIN_PRO_VERSION = '3.35';
|
|
43
|
+
|
|
44
|
+
// TODO: Remove this after version 4.01 is released
|
|
45
|
+
const shouldExtendTransitionProperties = (): boolean => {
|
|
46
|
+
const hasProInstalled = !! window.elementorPro;
|
|
47
|
+
|
|
48
|
+
if ( ! hasProInstalled ) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const proVersion = window.elementorPro?.config?.version;
|
|
53
|
+
|
|
54
|
+
if ( ! proVersion ) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return isVersionGreaterOrEqual( proVersion, MIN_PRO_VERSION );
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const createTransitionPropertiesList = (): TransitionCategory[] => {
|
|
62
|
+
const baseProperties: TransitionCategory[] = [
|
|
63
|
+
{
|
|
64
|
+
label: __( 'Default', 'elementor' ),
|
|
65
|
+
type: 'category',
|
|
66
|
+
properties: [ { label: __( 'All properties', 'elementor' ), value: 'all' } ],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: __( 'Margin', 'elementor' ),
|
|
70
|
+
type: 'category',
|
|
71
|
+
properties: [
|
|
72
|
+
{ label: __( 'Margin (all)', 'elementor' ), value: 'margin', isDisabled: true },
|
|
73
|
+
{ label: __( 'Margin bottom', 'elementor' ), value: 'margin-block-end', isDisabled: true },
|
|
74
|
+
{ label: __( 'Margin left', 'elementor' ), value: 'margin-inline-start', isDisabled: true },
|
|
75
|
+
{ label: __( 'Margin right', 'elementor' ), value: 'margin-inline-end', isDisabled: true },
|
|
76
|
+
{ label: __( 'Margin top', 'elementor' ), value: 'margin-block-start', isDisabled: true },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
label: __( 'Padding', 'elementor' ),
|
|
81
|
+
type: 'category',
|
|
82
|
+
properties: [
|
|
83
|
+
{ label: __( 'Padding (all)', 'elementor' ), value: 'padding', isDisabled: true },
|
|
84
|
+
{ label: __( 'Padding bottom', 'elementor' ), value: 'padding-block-end', isDisabled: true },
|
|
85
|
+
{ label: __( 'Padding left', 'elementor' ), value: 'padding-inline-start', isDisabled: true },
|
|
86
|
+
{ label: __( 'Padding right', 'elementor' ), value: 'padding-inline-end', isDisabled: true },
|
|
87
|
+
{ label: __( 'Padding top', 'elementor' ), value: 'padding-block-start', isDisabled: true },
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
label: __( 'Flex', 'elementor' ),
|
|
92
|
+
type: 'category',
|
|
93
|
+
properties: [
|
|
94
|
+
{ label: __( 'Flex (all)', 'elementor' ), value: 'flex', isDisabled: true },
|
|
95
|
+
{ label: __( 'Flex grow', 'elementor' ), value: 'flex-grow', isDisabled: true },
|
|
96
|
+
{ label: __( 'Flex shrink', 'elementor' ), value: 'flex-shrink', isDisabled: true },
|
|
97
|
+
{ label: __( 'Flex basis', 'elementor' ), value: 'flex-basis', isDisabled: true },
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
label: __( 'Size', 'elementor' ),
|
|
102
|
+
type: 'category',
|
|
103
|
+
properties: [
|
|
104
|
+
{ label: __( 'Width', 'elementor' ), value: 'width', isDisabled: true },
|
|
105
|
+
{ label: __( 'Height', 'elementor' ), value: 'height', isDisabled: true },
|
|
106
|
+
{ label: __( 'Max height', 'elementor' ), value: 'max-height', isDisabled: true },
|
|
107
|
+
{ label: __( 'Max width', 'elementor' ), value: 'max-width', isDisabled: true },
|
|
108
|
+
{ label: __( 'Min height', 'elementor' ), value: 'min-height', isDisabled: true },
|
|
109
|
+
{ label: __( 'Min width', 'elementor' ), value: 'min-width', isDisabled: true },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
label: __( 'Position', 'elementor' ),
|
|
114
|
+
type: 'category',
|
|
115
|
+
properties: [
|
|
116
|
+
{ label: __( 'Top', 'elementor' ), value: 'inset-block-start', isDisabled: true },
|
|
117
|
+
{ label: __( 'Left', 'elementor' ), value: 'inset-inline-start', isDisabled: true },
|
|
118
|
+
{ label: __( 'Right', 'elementor' ), value: 'inset-inline-end', isDisabled: true },
|
|
119
|
+
{ label: __( 'Bottom', 'elementor' ), value: 'inset-block-end', isDisabled: true },
|
|
120
|
+
{ label: __( 'Z-index', 'elementor' ), value: 'z-index', isDisabled: true },
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
label: __( 'Typography', 'elementor' ),
|
|
125
|
+
type: 'category',
|
|
126
|
+
properties: [
|
|
127
|
+
{ label: __( 'Font color', 'elementor' ), value: 'color', isDisabled: true },
|
|
128
|
+
{ label: __( 'Font size', 'elementor' ), value: 'font-size', isDisabled: true },
|
|
129
|
+
{ label: __( 'Line height', 'elementor' ), value: 'line-height', isDisabled: true },
|
|
130
|
+
{ label: __( 'Letter spacing', 'elementor' ), value: 'letter-spacing', isDisabled: true },
|
|
131
|
+
{ label: __( 'Word spacing', 'elementor' ), value: 'word-spacing', isDisabled: true },
|
|
132
|
+
{ label: __( 'Font variations', 'elementor' ), value: 'font-variation-settings', isDisabled: true },
|
|
133
|
+
{ label: __( 'Text stroke color', 'elementor' ), value: '-webkit-text-stroke-color', isDisabled: true },
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
label: __( 'Background', 'elementor' ),
|
|
138
|
+
type: 'category',
|
|
139
|
+
properties: [
|
|
140
|
+
{ label: __( 'Background color', 'elementor' ), value: 'background-color', isDisabled: true },
|
|
141
|
+
{ label: __( 'Background position', 'elementor' ), value: 'background-position', isDisabled: true },
|
|
142
|
+
{ label: __( 'Box shadow', 'elementor' ), value: 'box-shadow', isDisabled: true },
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
label: __( 'Border', 'elementor' ),
|
|
147
|
+
type: 'category',
|
|
148
|
+
properties: [
|
|
149
|
+
{ label: __( 'Border (all)', 'elementor' ), value: 'border', isDisabled: true },
|
|
150
|
+
{ label: __( 'Border radius', 'elementor' ), value: 'border-radius', isDisabled: true },
|
|
151
|
+
{ label: __( 'Border color', 'elementor' ), value: 'border-color', isDisabled: true },
|
|
152
|
+
{ label: __( 'Border width', 'elementor' ), value: 'border-width', isDisabled: true },
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
label: __( 'Effects', 'elementor' ),
|
|
157
|
+
type: 'category',
|
|
158
|
+
properties: [
|
|
159
|
+
{ label: __( 'Opacity', 'elementor' ), value: 'opacity', isDisabled: true },
|
|
160
|
+
{ label: __( 'Transform (all)', 'elementor' ), value: 'transform', isDisabled: true },
|
|
161
|
+
{ label: __( 'Filter (all)', 'elementor' ), value: 'filter', isDisabled: true },
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
return shouldExtendTransitionProperties() ? baseProperties : [ baseProperties[ 0 ] ];
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const transitionProperties: TransitionCategory[] = createTransitionPropertiesList();
|
|
48
170
|
|
|
49
171
|
export const transitionsItemsList = transitionProperties.map( ( category ) => ( {
|
|
50
172
|
label: category.label,
|
|
@@ -59,7 +59,7 @@ const areAllPropertiesUsed = ( value: SelectionSizePropValue[] = [] ) => {
|
|
|
59
59
|
|
|
60
60
|
// this config needs to be loaded at runtime/render since it's the transitionProperties object will be mutated by the pro plugin.
|
|
61
61
|
// See: https://elementor.atlassian.net/browse/ED-20285
|
|
62
|
-
const getSelectionSizeProps = ( recentlyUsedList: string[], disabledItems?: string[] ) => {
|
|
62
|
+
const getSelectionSizeProps = ( recentlyUsedList: string[], disabledItems?: string[], showPromotion?: boolean ) => {
|
|
63
63
|
return {
|
|
64
64
|
selectionLabel: __( 'Type', 'elementor' ),
|
|
65
65
|
sizeLabel: __( 'Duration', 'elementor' ),
|
|
@@ -68,6 +68,7 @@ const getSelectionSizeProps = ( recentlyUsedList: string[], disabledItems?: stri
|
|
|
68
68
|
props: {
|
|
69
69
|
recentlyUsedList,
|
|
70
70
|
disabledItems,
|
|
71
|
+
showPromotion,
|
|
71
72
|
},
|
|
72
73
|
},
|
|
73
74
|
sizeConfigMap: {
|
|
@@ -90,11 +91,11 @@ const isItemDisabled = ( item: TransitionItem[ 'value' ] ) => {
|
|
|
90
91
|
return ! property ? false : !! property.isDisabled;
|
|
91
92
|
};
|
|
92
93
|
|
|
93
|
-
const getChildControlConfig = ( recentlyUsedList: string[], disabledItems?: string[] ) => {
|
|
94
|
+
const getChildControlConfig = ( recentlyUsedList: string[], disabledItems?: string[], showPromotion?: boolean ) => {
|
|
94
95
|
return {
|
|
95
96
|
propTypeUtil: selectionSizePropTypeUtil,
|
|
96
97
|
component: SelectionSizeControl as unknown as React.ComponentType< Record< string, unknown > >,
|
|
97
|
-
props: getSelectionSizeProps( recentlyUsedList, disabledItems ),
|
|
98
|
+
props: getSelectionSizeProps( recentlyUsedList, disabledItems, showPromotion ),
|
|
98
99
|
isItemDisabled: isItemDisabled as ( item: Item< RepeatablePropValue > ) => boolean,
|
|
99
100
|
};
|
|
100
101
|
};
|
|
@@ -106,19 +107,23 @@ const isPropertyUsed = ( value: SelectionSizePropValue[], property: TransitionPr
|
|
|
106
107
|
};
|
|
107
108
|
|
|
108
109
|
const getDisabledItemLabels = ( values: SelectionSizePropValue[] = [] ) => {
|
|
109
|
-
const
|
|
110
|
+
const selectedLabels: string[] = ( values || [] ).map(
|
|
110
111
|
( item ) => ( item.value?.selection as KeyValuePropValue )?.value?.key?.value
|
|
111
112
|
);
|
|
112
113
|
|
|
114
|
+
const proDisabledLabels: string[] = [];
|
|
113
115
|
transitionProperties.forEach( ( category ) => {
|
|
114
116
|
const disabledProperties = category.properties
|
|
115
|
-
.filter( ( property ) => property.isDisabled && !
|
|
117
|
+
.filter( ( property ) => property.isDisabled && ! selectedLabels.includes( property.label ) )
|
|
116
118
|
.map( ( property ) => property.label );
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
proDisabledLabels.push( ...disabledProperties );
|
|
119
121
|
} );
|
|
120
122
|
|
|
121
|
-
return
|
|
123
|
+
return {
|
|
124
|
+
allDisabled: [ ...selectedLabels, ...proDisabledLabels ],
|
|
125
|
+
proDisabled: proDisabledLabels,
|
|
126
|
+
};
|
|
122
127
|
};
|
|
123
128
|
|
|
124
129
|
const getInitialValue = ( values: SelectionSizePropValue[] = [] ): TransitionValue => {
|
|
@@ -178,7 +183,10 @@ export const TransitionRepeaterControl = createControl(
|
|
|
178
183
|
const [ recentlyUsedList, setRecentlyUsedList ] = useState< string[] >( [] );
|
|
179
184
|
|
|
180
185
|
const { value, setValue } = useBoundProp( childArrayPropTypeUtil );
|
|
181
|
-
const disabledItems
|
|
186
|
+
const { allDisabled: disabledItems, proDisabled: proDisabledItems } = useMemo(
|
|
187
|
+
() => getDisabledItemLabels( value ),
|
|
188
|
+
[ value ]
|
|
189
|
+
);
|
|
182
190
|
|
|
183
191
|
const allowedTransitionSet = useMemo( () => {
|
|
184
192
|
const set = new Set< string >();
|
|
@@ -220,7 +228,11 @@ export const TransitionRepeaterControl = createControl(
|
|
|
220
228
|
showDuplicate={ false }
|
|
221
229
|
showToggle={ true }
|
|
222
230
|
initialValues={ getInitialValue( value ) }
|
|
223
|
-
childControlConfig={ getChildControlConfig(
|
|
231
|
+
childControlConfig={ getChildControlConfig(
|
|
232
|
+
recentlyUsedList,
|
|
233
|
+
disabledItems,
|
|
234
|
+
proDisabledItems.length > 0
|
|
235
|
+
) }
|
|
224
236
|
propKey="transition"
|
|
225
237
|
addItemTooltipProps={ {
|
|
226
238
|
disabled: isAddItemDisabled,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useRef } from 'react';
|
|
2
|
+
import { useMemo, useRef } from 'react';
|
|
3
3
|
import { keyValuePropTypeUtil, type KeyValuePropValue, type StringPropValue } from '@elementor/editor-props';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { PromotionChip } from '@elementor/editor-ui';
|
|
5
|
+
import { ChevronDownIcon, CrownFilledIcon, VariationsIcon } from '@elementor/icons';
|
|
6
|
+
import { Alert, bindPopover, bindTrigger, Box, Popover, UnstableTag, usePopupState } from '@elementor/ui';
|
|
6
7
|
import { __ } from '@wordpress/i18n';
|
|
7
8
|
|
|
8
9
|
import { useBoundProp } from '../../bound-prop-context';
|
|
@@ -46,12 +47,16 @@ const includeCurrentValueInOptions = ( value: KeyValuePropValue[ 'value' ], disa
|
|
|
46
47
|
} );
|
|
47
48
|
};
|
|
48
49
|
|
|
50
|
+
const PRO_UPGRADE_URL = 'https://go.elementor.com/go-pro-transitions-modal/';
|
|
51
|
+
|
|
49
52
|
export const TransitionSelector = ( {
|
|
50
53
|
recentlyUsedList = [],
|
|
51
54
|
disabledItems = [],
|
|
55
|
+
showPromotion = false,
|
|
52
56
|
}: {
|
|
53
57
|
recentlyUsedList: string[];
|
|
54
58
|
disabledItems?: string[];
|
|
59
|
+
showPromotion?: boolean;
|
|
55
60
|
} ) => {
|
|
56
61
|
const { value, setValue } = useBoundProp( keyValuePropTypeUtil );
|
|
57
62
|
const {
|
|
@@ -60,6 +65,14 @@ export const TransitionSelector = ( {
|
|
|
60
65
|
const defaultRef = useRef< HTMLDivElement >( null );
|
|
61
66
|
const popoverState = usePopupState( { variant: 'popover' } );
|
|
62
67
|
|
|
68
|
+
const disabledCategories = useMemo( () => {
|
|
69
|
+
return new Set(
|
|
70
|
+
transitionProperties
|
|
71
|
+
.filter( ( cat ) => cat.properties.some( ( prop ) => prop.isDisabled ) )
|
|
72
|
+
.map( ( cat ) => cat.label )
|
|
73
|
+
);
|
|
74
|
+
}, [] );
|
|
75
|
+
|
|
63
76
|
const getItemList = () => {
|
|
64
77
|
const recentItems = recentlyUsedList
|
|
65
78
|
.map( ( item ) => getTransitionPropertyByValue( { value: item, $$type: 'string' } )?.label )
|
|
@@ -136,6 +149,49 @@ export const TransitionSelector = ( {
|
|
|
136
149
|
title={ __( 'Transition Property', 'elementor' ) }
|
|
137
150
|
icon={ VariationsIcon as React.ElementType< { fontSize: string } > }
|
|
138
151
|
disabledItems={ includeCurrentValueInOptions( value, disabledItems ) }
|
|
152
|
+
categoryItemContentTemplate={ ( item ) => (
|
|
153
|
+
<Box
|
|
154
|
+
sx={ {
|
|
155
|
+
display: 'flex',
|
|
156
|
+
alignItems: 'center',
|
|
157
|
+
justifyContent: 'space-between',
|
|
158
|
+
width: '100%',
|
|
159
|
+
} }
|
|
160
|
+
>
|
|
161
|
+
<span>{ item.value }</span>
|
|
162
|
+
{ showPromotion && disabledCategories.has( item.value ) && <PromotionChip /> }
|
|
163
|
+
</Box>
|
|
164
|
+
) }
|
|
165
|
+
footer={
|
|
166
|
+
showPromotion ? (
|
|
167
|
+
<Alert
|
|
168
|
+
variant="standard"
|
|
169
|
+
color="promotion"
|
|
170
|
+
icon={ false }
|
|
171
|
+
role="dialog"
|
|
172
|
+
aria-label="promotion-alert"
|
|
173
|
+
size="small"
|
|
174
|
+
sx={ { m: 1.5, mt: 0 } }
|
|
175
|
+
>
|
|
176
|
+
{ __( 'Upgrade to customize transition properties and control effects.', 'elementor' ) }
|
|
177
|
+
<Box
|
|
178
|
+
component="a"
|
|
179
|
+
href={ PRO_UPGRADE_URL }
|
|
180
|
+
target="_blank"
|
|
181
|
+
rel="noopener noreferrer"
|
|
182
|
+
sx={ {
|
|
183
|
+
display: 'flex',
|
|
184
|
+
alignItems: 'center',
|
|
185
|
+
gap: 0.5,
|
|
186
|
+
color: 'promotion.main',
|
|
187
|
+
} }
|
|
188
|
+
>
|
|
189
|
+
<CrownFilledIcon fontSize="tiny" />
|
|
190
|
+
{ __( 'Upgrade now', 'elementor' ) }
|
|
191
|
+
</Box>
|
|
192
|
+
</Alert>
|
|
193
|
+
) : null
|
|
194
|
+
}
|
|
139
195
|
/>
|
|
140
196
|
</Popover>
|
|
141
197
|
</Box>
|