@elementor/editor-variables 3.35.3 → 3.35.5
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 +776 -703
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +650 -579
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/ui/menu-item-content.tsx +12 -6
- package/src/components/ui/styled-menu-list.tsx +7 -5
- package/src/components/ui/variable-promotion-chip.tsx +63 -0
- package/src/components/variables-manager/ui/variable-edit-menu.tsx +14 -3
- package/src/components/variables-manager/ui/variable-table-row.tsx +210 -0
- package/src/components/variables-manager/variable-editable-cell.tsx +12 -4
- package/src/components/variables-manager/variables-manager-create-menu.tsx +11 -38
- package/src/components/variables-manager/variables-manager-panel.tsx +18 -15
- package/src/components/variables-manager/variables-manager-table.tsx +18 -189
- package/src/components/variables-selection.tsx +28 -12
- package/src/hooks/use-quota-permissions.ts +10 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-variables",
|
|
3
|
-
"version": "3.35.
|
|
3
|
+
"version": "3.35.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,22 +39,22 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "3.35.
|
|
43
|
-
"@elementor/editor-canvas": "3.35.
|
|
44
|
-
"@elementor/editor-controls": "3.35.
|
|
45
|
-
"@elementor/editor-current-user": "3.35.
|
|
46
|
-
"@elementor/editor-editing-panel": "3.35.
|
|
47
|
-
"@elementor/editor-mcp": "3.35.
|
|
48
|
-
"@elementor/editor-panels": "3.35.
|
|
49
|
-
"@elementor/editor-props": "3.35.
|
|
50
|
-
"@elementor/editor-ui": "3.35.
|
|
51
|
-
"@elementor/editor-v1-adapters": "3.35.
|
|
52
|
-
"@elementor/http-client": "3.35.
|
|
42
|
+
"@elementor/editor": "3.35.5",
|
|
43
|
+
"@elementor/editor-canvas": "3.35.5",
|
|
44
|
+
"@elementor/editor-controls": "3.35.5",
|
|
45
|
+
"@elementor/editor-current-user": "3.35.5",
|
|
46
|
+
"@elementor/editor-editing-panel": "3.35.5",
|
|
47
|
+
"@elementor/editor-mcp": "3.35.5",
|
|
48
|
+
"@elementor/editor-panels": "3.35.5",
|
|
49
|
+
"@elementor/editor-props": "3.35.5",
|
|
50
|
+
"@elementor/editor-ui": "3.35.5",
|
|
51
|
+
"@elementor/editor-v1-adapters": "3.35.5",
|
|
52
|
+
"@elementor/http-client": "3.35.5",
|
|
53
53
|
"@elementor/icons": "^1.63.0",
|
|
54
|
-
"@elementor/events": "3.35.
|
|
55
|
-
"@elementor/schema": "3.35.
|
|
54
|
+
"@elementor/events": "3.35.5",
|
|
55
|
+
"@elementor/schema": "3.35.5",
|
|
56
56
|
"@elementor/ui": "1.36.17",
|
|
57
|
-
"@elementor/utils": "3.35.
|
|
57
|
+
"@elementor/utils": "3.35.5",
|
|
58
58
|
"@wordpress/i18n": "^5.13.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { type MouseEvent } from 'react';
|
|
2
3
|
import { EllipsisWithTooltip, type VirtualizedItem } from '@elementor/editor-ui';
|
|
3
4
|
import { EditIcon } from '@elementor/icons';
|
|
4
5
|
import { Box, IconButton, ListItemIcon, Tooltip, Typography } from '@elementor/ui';
|
|
@@ -7,12 +8,17 @@ import { __ } from '@wordpress/i18n';
|
|
|
7
8
|
const SIZE = 'tiny';
|
|
8
9
|
const EDIT_LABEL = __( 'Edit variable', 'elementor' );
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
type MenuItemContentProps< T, V extends string > = {
|
|
12
|
+
item: VirtualizedItem< T, V >;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const MenuItemContent = < T, V extends string >( { item, disabled = false }: MenuItemContentProps< T, V > ) => {
|
|
11
17
|
const onEdit = item.onEdit as ( ( value: V ) => void ) | undefined;
|
|
12
18
|
|
|
13
19
|
return (
|
|
14
20
|
<>
|
|
15
|
-
<ListItemIcon>{ item.icon }</ListItemIcon>
|
|
21
|
+
<ListItemIcon sx={ { color: disabled ? 'text.disabled' : 'inherit' } }>{ item.icon }</ListItemIcon>
|
|
16
22
|
<Box
|
|
17
23
|
sx={ {
|
|
18
24
|
flex: 1,
|
|
@@ -26,7 +32,7 @@ export const MenuItemContent = < T, V extends string >( { item }: { item: Virtua
|
|
|
26
32
|
title={ item.label || item.value }
|
|
27
33
|
as={ Typography }
|
|
28
34
|
variant="caption"
|
|
29
|
-
color=
|
|
35
|
+
color={ disabled ? 'text.disabled' : 'text.primary' }
|
|
30
36
|
sx={ { marginTop: '1px', lineHeight: '2' } }
|
|
31
37
|
maxWidth="50%"
|
|
32
38
|
/>
|
|
@@ -35,17 +41,17 @@ export const MenuItemContent = < T, V extends string >( { item }: { item: Virtua
|
|
|
35
41
|
title={ item.secondaryText }
|
|
36
42
|
as={ Typography }
|
|
37
43
|
variant="caption"
|
|
38
|
-
color=
|
|
44
|
+
color={ disabled ? 'text.disabled' : 'text.tertiary' }
|
|
39
45
|
sx={ { marginTop: '1px', lineHeight: '1' } }
|
|
40
46
|
maxWidth="50%"
|
|
41
47
|
/>
|
|
42
48
|
) }
|
|
43
49
|
</Box>
|
|
44
|
-
{ !! onEdit && (
|
|
50
|
+
{ !! onEdit && ! disabled && (
|
|
45
51
|
<Tooltip placement="top" title={ EDIT_LABEL }>
|
|
46
52
|
<IconButton
|
|
47
53
|
sx={ { mx: 1, opacity: '0' } }
|
|
48
|
-
onClick={ ( e:
|
|
54
|
+
onClick={ ( e: MouseEvent< HTMLButtonElement > ) => {
|
|
49
55
|
e.stopPropagation();
|
|
50
56
|
onEdit( item.value );
|
|
51
57
|
} }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MenuList, styled } from '@elementor/ui';
|
|
2
2
|
|
|
3
|
-
export const VariablesStyledMenuList = styled( MenuList )( ( { theme } ) => ( {
|
|
3
|
+
export const VariablesStyledMenuList = styled( MenuList )< { disabled?: boolean } >( ( { theme, disabled } ) => ( {
|
|
4
4
|
'& > li': {
|
|
5
5
|
height: 32,
|
|
6
6
|
width: '100%',
|
|
@@ -11,13 +11,15 @@ export const VariablesStyledMenuList = styled( MenuList )( ( { theme } ) => ( {
|
|
|
11
11
|
...theme.typography.caption,
|
|
12
12
|
lineHeight: 'inherit',
|
|
13
13
|
padding: theme.spacing( 0.5, 1, 0.5, 2 ),
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
...( ! disabled && {
|
|
15
|
+
'&:hover, &:focus': {
|
|
16
|
+
backgroundColor: theme.palette.action.hover,
|
|
17
|
+
},
|
|
18
|
+
cursor: 'pointer',
|
|
19
|
+
} ),
|
|
17
20
|
'&[aria-selected="true"]': {
|
|
18
21
|
backgroundColor: theme.palette.action.selected,
|
|
19
22
|
},
|
|
20
|
-
cursor: 'pointer',
|
|
21
23
|
textOverflow: 'ellipsis',
|
|
22
24
|
position: 'absolute',
|
|
23
25
|
top: 0,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { forwardRef, type MouseEvent, useImperativeHandle, useState } from 'react';
|
|
3
|
+
import { PromotionChip, PromotionPopover, useCanvasClickHandler } from '@elementor/editor-ui';
|
|
4
|
+
import { Box } from '@elementor/ui';
|
|
5
|
+
import { capitalize } from '@elementor/utils';
|
|
6
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
7
|
+
|
|
8
|
+
type VariablePromotionChipProps = {
|
|
9
|
+
variableType: string;
|
|
10
|
+
upgradeUrl: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type VariablePromotionChipRef = {
|
|
14
|
+
toggle: () => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const VariablePromotionChip = forwardRef< VariablePromotionChipRef, VariablePromotionChipProps >(
|
|
18
|
+
( { variableType, upgradeUrl }, ref ) => {
|
|
19
|
+
const [ isOpen, setIsOpen ] = useState( false );
|
|
20
|
+
|
|
21
|
+
useCanvasClickHandler( isOpen, () => setIsOpen( false ) );
|
|
22
|
+
|
|
23
|
+
const toggle = () => setIsOpen( ( prev ) => ! prev );
|
|
24
|
+
|
|
25
|
+
useImperativeHandle( ref, () => ( { toggle } ), [] );
|
|
26
|
+
|
|
27
|
+
const title = sprintf(
|
|
28
|
+
/* translators: %s: Variable Type. */
|
|
29
|
+
__( '%s variables', 'elementor' ),
|
|
30
|
+
capitalize( variableType )
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const content = sprintf(
|
|
34
|
+
/* translators: %s: Variable Type. */
|
|
35
|
+
__( 'Upgrade to continue creating and editing %s variables.', 'elementor' ),
|
|
36
|
+
variableType
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<PromotionPopover
|
|
41
|
+
open={ isOpen }
|
|
42
|
+
title={ title }
|
|
43
|
+
content={ content }
|
|
44
|
+
ctaText={ __( 'Upgrade now', 'elementor' ) }
|
|
45
|
+
ctaUrl={ upgradeUrl }
|
|
46
|
+
onClose={ ( e: MouseEvent ) => {
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
setIsOpen( false );
|
|
49
|
+
} }
|
|
50
|
+
>
|
|
51
|
+
<Box
|
|
52
|
+
onClick={ ( e: MouseEvent ) => {
|
|
53
|
+
e.stopPropagation();
|
|
54
|
+
toggle();
|
|
55
|
+
} }
|
|
56
|
+
sx={ { cursor: 'pointer', display: 'inline-flex' } }
|
|
57
|
+
>
|
|
58
|
+
<PromotionChip />
|
|
59
|
+
</Box>
|
|
60
|
+
</PromotionPopover>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { createElement } from 'react';
|
|
2
|
+
import { createElement, type MouseEvent } from 'react';
|
|
3
3
|
import { DotsVerticalIcon } from '@elementor/icons';
|
|
4
4
|
import { bindMenu, bindTrigger, IconButton, Menu, MenuItem, type SvgIconProps, usePopupState } from '@elementor/ui';
|
|
5
5
|
|
|
@@ -21,9 +21,19 @@ export const VariableEditMenu = ( { menuActions, disabled, itemId }: VariableEdi
|
|
|
21
21
|
variant: 'popover',
|
|
22
22
|
} );
|
|
23
23
|
|
|
24
|
+
const triggerProps = bindTrigger( menuState );
|
|
25
|
+
|
|
24
26
|
return (
|
|
25
27
|
<>
|
|
26
|
-
<IconButton
|
|
28
|
+
<IconButton
|
|
29
|
+
{ ...triggerProps }
|
|
30
|
+
disabled={ disabled }
|
|
31
|
+
size="tiny"
|
|
32
|
+
onClick={ ( e: MouseEvent ) => {
|
|
33
|
+
e.stopPropagation();
|
|
34
|
+
triggerProps.onClick?.( e );
|
|
35
|
+
} }
|
|
36
|
+
>
|
|
27
37
|
<DotsVerticalIcon fontSize="tiny" />
|
|
28
38
|
</IconButton>
|
|
29
39
|
|
|
@@ -51,7 +61,8 @@ export const VariableEditMenu = ( { menuActions, disabled, itemId }: VariableEdi
|
|
|
51
61
|
{ menuActions.map( ( action ) => (
|
|
52
62
|
<MenuItem
|
|
53
63
|
key={ action.name }
|
|
54
|
-
onClick={ () => {
|
|
64
|
+
onClick={ ( e: MouseEvent ) => {
|
|
65
|
+
e.stopPropagation();
|
|
55
66
|
action.onClick?.( itemId );
|
|
56
67
|
menuState.close();
|
|
57
68
|
} }
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createElement, useRef } from 'react';
|
|
3
|
+
import { EllipsisWithTooltip } from '@elementor/editor-ui';
|
|
4
|
+
import { GripVerticalIcon } from '@elementor/icons';
|
|
5
|
+
import { IconButton, Stack, TableRow, type UnstableSortableItemRenderProps } from '@elementor/ui';
|
|
6
|
+
|
|
7
|
+
import { useQuotaPermissions } from '../../../hooks/use-quota-permissions';
|
|
8
|
+
import { type TVariablesList } from '../../../storage';
|
|
9
|
+
import { type getVariableType } from '../../../variables-registry/variable-type-registry';
|
|
10
|
+
import { LabelField } from '../../fields/label-field';
|
|
11
|
+
import { VariablePromotionChip, type VariablePromotionChipRef } from '../../ui/variable-promotion-chip';
|
|
12
|
+
import { VariableEditableCell } from '../variable-editable-cell';
|
|
13
|
+
import { VariableEditMenu, type VariableManagerMenuAction } from './variable-edit-menu';
|
|
14
|
+
import { VariableTableCell } from './variable-table-cell';
|
|
15
|
+
|
|
16
|
+
export type Row = ReturnType< typeof getVariableType > & {
|
|
17
|
+
id: string;
|
|
18
|
+
type: string;
|
|
19
|
+
name: string;
|
|
20
|
+
value: string;
|
|
21
|
+
};
|
|
22
|
+
export const VariableRow = (
|
|
23
|
+
props: UnstableSortableItemRenderProps & {
|
|
24
|
+
row: Row;
|
|
25
|
+
variables: TVariablesList;
|
|
26
|
+
handleOnChange: ( variables: TVariablesList ) => void;
|
|
27
|
+
autoEditVariableId?: string;
|
|
28
|
+
onAutoEditComplete?: () => void;
|
|
29
|
+
onFieldError?: ( hasError: boolean ) => void;
|
|
30
|
+
menuActions: ( variableId: string ) => VariableManagerMenuAction[];
|
|
31
|
+
handleRowRef: ( id: string ) => ( ref: HTMLTableRowElement | null ) => void;
|
|
32
|
+
}
|
|
33
|
+
) => {
|
|
34
|
+
const {
|
|
35
|
+
row,
|
|
36
|
+
variables,
|
|
37
|
+
handleOnChange,
|
|
38
|
+
autoEditVariableId,
|
|
39
|
+
onAutoEditComplete,
|
|
40
|
+
onFieldError,
|
|
41
|
+
menuActions,
|
|
42
|
+
handleRowRef,
|
|
43
|
+
itemProps,
|
|
44
|
+
showDropIndication,
|
|
45
|
+
triggerProps,
|
|
46
|
+
itemStyle,
|
|
47
|
+
triggerStyle,
|
|
48
|
+
isDragged,
|
|
49
|
+
dropPosition,
|
|
50
|
+
setTriggerRef,
|
|
51
|
+
isSorting,
|
|
52
|
+
} = props;
|
|
53
|
+
const promotionRef = useRef< VariablePromotionChipRef >( null );
|
|
54
|
+
const isDisabled = ! useQuotaPermissions( row.type ).canEdit();
|
|
55
|
+
|
|
56
|
+
const showIndicationBefore = showDropIndication && dropPosition === 'before';
|
|
57
|
+
const showIndicationAfter = showDropIndication && dropPosition === 'after';
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<TableRow
|
|
61
|
+
{ ...itemProps }
|
|
62
|
+
ref={ itemProps.ref }
|
|
63
|
+
selected={ isDragged }
|
|
64
|
+
sx={ {
|
|
65
|
+
...( isDisabled && {
|
|
66
|
+
'& td, & th': {
|
|
67
|
+
color: 'text.disabled',
|
|
68
|
+
},
|
|
69
|
+
} ),
|
|
70
|
+
...( showIndicationBefore && {
|
|
71
|
+
'& td, & th': {
|
|
72
|
+
borderTop: '2px solid',
|
|
73
|
+
borderTopColor: 'primary.main',
|
|
74
|
+
},
|
|
75
|
+
} ),
|
|
76
|
+
...( showIndicationAfter && {
|
|
77
|
+
'& td, & th': {
|
|
78
|
+
borderBottom: '2px solid',
|
|
79
|
+
borderBottomColor: 'primary.main',
|
|
80
|
+
},
|
|
81
|
+
} ),
|
|
82
|
+
'&:hover, &:focus-within': {
|
|
83
|
+
backgroundColor: 'action.hover',
|
|
84
|
+
'& [role="toolbar"], & [draggable]': {
|
|
85
|
+
opacity: 1,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
'& [role="toolbar"], & [draggable]': {
|
|
89
|
+
opacity: 0,
|
|
90
|
+
},
|
|
91
|
+
} }
|
|
92
|
+
style={ { ...itemStyle, ...triggerStyle } }
|
|
93
|
+
onClick={ () => {
|
|
94
|
+
if ( isDisabled ) {
|
|
95
|
+
promotionRef.current?.toggle();
|
|
96
|
+
}
|
|
97
|
+
} }
|
|
98
|
+
>
|
|
99
|
+
<VariableTableCell noPadding width={ 10 } maxWidth={ 10 }>
|
|
100
|
+
<IconButton size="small" ref={ setTriggerRef } { ...triggerProps } disabled={ isSorting } draggable>
|
|
101
|
+
<GripVerticalIcon fontSize="inherit" />
|
|
102
|
+
</IconButton>
|
|
103
|
+
</VariableTableCell>
|
|
104
|
+
<VariableTableCell>
|
|
105
|
+
<VariableEditableCell
|
|
106
|
+
initialValue={ row.name }
|
|
107
|
+
onChange={ ( value ) => {
|
|
108
|
+
if ( value !== row.name && ! isDisabled ) {
|
|
109
|
+
handleOnChange( {
|
|
110
|
+
...variables,
|
|
111
|
+
[ row.id ]: { ...variables[ row.id ], label: value },
|
|
112
|
+
} );
|
|
113
|
+
}
|
|
114
|
+
} }
|
|
115
|
+
prefixElement={ createElement( row.icon, {
|
|
116
|
+
fontSize: 'inherit',
|
|
117
|
+
color: isDisabled ? 'disabled' : 'inherit',
|
|
118
|
+
} ) }
|
|
119
|
+
editableElement={ ( { value, onChange, onValidationChange, error } ) => (
|
|
120
|
+
<LabelField
|
|
121
|
+
id={ 'variable-label-' + row.id }
|
|
122
|
+
size="tiny"
|
|
123
|
+
value={ value }
|
|
124
|
+
onChange={ onChange }
|
|
125
|
+
onErrorChange={ ( errorMsg ) => {
|
|
126
|
+
onValidationChange?.( errorMsg );
|
|
127
|
+
onFieldError?.( !! errorMsg );
|
|
128
|
+
} }
|
|
129
|
+
error={ error }
|
|
130
|
+
focusOnShow
|
|
131
|
+
selectOnShow={ autoEditVariableId === row.id }
|
|
132
|
+
showWarningInfotip={ true }
|
|
133
|
+
variables={ variables }
|
|
134
|
+
/>
|
|
135
|
+
) }
|
|
136
|
+
autoEdit={ autoEditVariableId === row.id && ! isDisabled }
|
|
137
|
+
onRowRef={ handleRowRef( row.id ) }
|
|
138
|
+
onAutoEditComplete={ autoEditVariableId === row.id ? onAutoEditComplete : undefined }
|
|
139
|
+
fieldType="label"
|
|
140
|
+
disabled={ isDisabled }
|
|
141
|
+
>
|
|
142
|
+
<EllipsisWithTooltip title={ row.name } sx={ { border: '4px solid transparent' } }>
|
|
143
|
+
{ row.name }
|
|
144
|
+
</EllipsisWithTooltip>
|
|
145
|
+
</VariableEditableCell>
|
|
146
|
+
</VariableTableCell>
|
|
147
|
+
<VariableTableCell>
|
|
148
|
+
<VariableEditableCell
|
|
149
|
+
initialValue={ row.value }
|
|
150
|
+
onChange={ ( value ) => {
|
|
151
|
+
if ( value !== row.value && ! isDisabled ) {
|
|
152
|
+
handleOnChange( {
|
|
153
|
+
...variables,
|
|
154
|
+
[ row.id ]: { ...variables[ row.id ], value },
|
|
155
|
+
} );
|
|
156
|
+
}
|
|
157
|
+
} }
|
|
158
|
+
editableElement={ ( { value, onChange, onValidationChange, error } ) =>
|
|
159
|
+
row.valueField?.( {
|
|
160
|
+
value,
|
|
161
|
+
onChange,
|
|
162
|
+
onPropTypeKeyChange: ( type ) => {
|
|
163
|
+
if ( ! isDisabled ) {
|
|
164
|
+
handleOnChange( {
|
|
165
|
+
...variables,
|
|
166
|
+
[ row.id ]: { ...variables[ row.id ], type },
|
|
167
|
+
} );
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
propTypeKey: row.type,
|
|
171
|
+
onValidationChange: ( errorMsg ) => {
|
|
172
|
+
onValidationChange?.( errorMsg );
|
|
173
|
+
onFieldError?.( !! errorMsg );
|
|
174
|
+
},
|
|
175
|
+
error,
|
|
176
|
+
} ) ?? <></>
|
|
177
|
+
}
|
|
178
|
+
onRowRef={ handleRowRef( row.id ) }
|
|
179
|
+
gap={ 0.25 }
|
|
180
|
+
fieldType="value"
|
|
181
|
+
disabled={ isDisabled }
|
|
182
|
+
>
|
|
183
|
+
{ row.startIcon && row.startIcon( { value: row.value } ) }
|
|
184
|
+
<EllipsisWithTooltip
|
|
185
|
+
title={ row.value }
|
|
186
|
+
sx={ {
|
|
187
|
+
border: '4px solid transparent',
|
|
188
|
+
lineHeight: '1',
|
|
189
|
+
pt: 0.25,
|
|
190
|
+
} }
|
|
191
|
+
>
|
|
192
|
+
{ row.value }
|
|
193
|
+
</EllipsisWithTooltip>
|
|
194
|
+
</VariableEditableCell>
|
|
195
|
+
</VariableTableCell>
|
|
196
|
+
<VariableTableCell align="right" noPadding width={ 16 } maxWidth={ 16 } sx={ { paddingInlineEnd: 1 } }>
|
|
197
|
+
<Stack role="toolbar" direction="row" justifyContent="flex-end" alignItems="center">
|
|
198
|
+
{ isDisabled && (
|
|
199
|
+
<VariablePromotionChip
|
|
200
|
+
variableType={ row.variableType }
|
|
201
|
+
upgradeUrl={ `https://go.elementor.com/renew-license-manager-${ row.variableType }-variable` }
|
|
202
|
+
ref={ promotionRef }
|
|
203
|
+
/>
|
|
204
|
+
) }
|
|
205
|
+
<VariableEditMenu menuActions={ menuActions( row.id ) } disabled={ isSorting } itemId={ row.id } />
|
|
206
|
+
</Stack>
|
|
207
|
+
</VariableTableCell>
|
|
208
|
+
</TableRow>
|
|
209
|
+
);
|
|
210
|
+
};
|
|
@@ -16,6 +16,7 @@ type VariableEditableCellProps = {
|
|
|
16
16
|
onAutoEditComplete?: () => void;
|
|
17
17
|
gap?: number;
|
|
18
18
|
fieldType?: 'label' | 'value';
|
|
19
|
+
disabled?: boolean;
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export const VariableEditableCell = React.memo(
|
|
@@ -30,6 +31,7 @@ export const VariableEditableCell = React.memo(
|
|
|
30
31
|
onAutoEditComplete,
|
|
31
32
|
gap = 1,
|
|
32
33
|
fieldType,
|
|
34
|
+
disabled = false,
|
|
33
35
|
}: VariableEditableCellProps ) => {
|
|
34
36
|
const [ value, setValue ] = useState( initialValue );
|
|
35
37
|
const [ isEditing, setIsEditing ] = useState( false );
|
|
@@ -54,17 +56,23 @@ export const VariableEditableCell = React.memo(
|
|
|
54
56
|
}, [ onRowRef ] );
|
|
55
57
|
|
|
56
58
|
useEffect( () => {
|
|
57
|
-
if ( autoEdit && ! isEditing ) {
|
|
59
|
+
if ( autoEdit && ! isEditing && ! disabled ) {
|
|
58
60
|
setIsEditing( true );
|
|
59
61
|
onAutoEditComplete?.();
|
|
60
62
|
}
|
|
61
|
-
}, [ autoEdit, isEditing, onAutoEditComplete ] );
|
|
63
|
+
}, [ autoEdit, isEditing, onAutoEditComplete, disabled ] );
|
|
62
64
|
|
|
63
65
|
const handleDoubleClick = () => {
|
|
66
|
+
if ( disabled ) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
64
69
|
setIsEditing( true );
|
|
65
70
|
};
|
|
66
71
|
|
|
67
72
|
const handleKeyDown = ( event: React.KeyboardEvent< HTMLDivElement > ) => {
|
|
73
|
+
if ( disabled ) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
68
76
|
if ( event.key === 'Enter' ) {
|
|
69
77
|
handleSave();
|
|
70
78
|
} else if ( event.key === 'Escape' ) {
|
|
@@ -137,9 +145,9 @@ export const VariableEditableCell = React.memo(
|
|
|
137
145
|
gap={ gap }
|
|
138
146
|
onDoubleClick={ handleDoubleClick }
|
|
139
147
|
onKeyDown={ handleKeyDown }
|
|
140
|
-
tabIndex={ 0 }
|
|
148
|
+
tabIndex={ disabled ? -1 : 0 }
|
|
141
149
|
role="button"
|
|
142
|
-
aria-label=
|
|
150
|
+
aria-label={ disabled ? '' : 'Double click or press Space to edit' }
|
|
143
151
|
>
|
|
144
152
|
{ prefixElement }
|
|
145
153
|
{ children }
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { createElement, useMemo, useRef
|
|
3
|
-
import { PromotionChip, PromotionPopover } from '@elementor/editor-ui';
|
|
2
|
+
import { createElement, useMemo, useRef } from 'react';
|
|
4
3
|
import { PlusIcon } from '@elementor/icons';
|
|
5
4
|
import { bindMenu, bindTrigger, IconButton, Menu, MenuItem, type PopupState, Typography } from '@elementor/ui';
|
|
6
5
|
import { capitalize } from '@elementor/utils';
|
|
7
|
-
import { __
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
8
7
|
|
|
9
8
|
import { useQuotaPermissions } from '../../hooks/use-quota-permissions';
|
|
10
9
|
import { type TVariablesList } from '../../storage';
|
|
11
10
|
import { trackVariablesManagerEvent } from '../../utils/tracking';
|
|
12
11
|
import { getVariableTypes } from '../../variables-registry/variable-type-registry';
|
|
12
|
+
import { VariablePromotionChip, type VariablePromotionChipRef } from '../ui/variable-promotion-chip';
|
|
13
13
|
|
|
14
14
|
export const SIZE = 'tiny';
|
|
15
15
|
|
|
@@ -28,12 +28,7 @@ type VariableManagerCreateMenuProps = {
|
|
|
28
28
|
menuState: PopupState;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
export const VariableManagerCreateMenu = ( {
|
|
32
|
-
variables,
|
|
33
|
-
onCreate,
|
|
34
|
-
disabled,
|
|
35
|
-
menuState,
|
|
36
|
-
}: VariableManagerCreateMenuProps ) => {
|
|
31
|
+
export const VariableManagerCreateMenu = ( { variables, onCreate, menuState }: VariableManagerCreateMenuProps ) => {
|
|
37
32
|
const buttonRef = useRef< HTMLButtonElement >( null );
|
|
38
33
|
|
|
39
34
|
const variableTypes = getVariableTypes();
|
|
@@ -57,7 +52,6 @@ export const VariableManagerCreateMenu = ( {
|
|
|
57
52
|
<IconButton
|
|
58
53
|
{ ...bindTrigger( menuState ) }
|
|
59
54
|
ref={ buttonRef }
|
|
60
|
-
disabled={ disabled }
|
|
61
55
|
size={ SIZE }
|
|
62
56
|
aria-label={ __( 'Add variable', 'elementor' ) }
|
|
63
57
|
>
|
|
@@ -109,7 +103,7 @@ const MenuOption = ( {
|
|
|
109
103
|
onCreate: VariableManagerCreateMenuProps[ 'onCreate' ];
|
|
110
104
|
onClose: () => void;
|
|
111
105
|
} ) => {
|
|
112
|
-
const
|
|
106
|
+
const promotionRef = useRef< VariablePromotionChipRef >( null );
|
|
113
107
|
const userQuotaPermissions = useQuotaPermissions( config.propTypeKey );
|
|
114
108
|
|
|
115
109
|
const displayName = capitalize( config.variableType );
|
|
@@ -117,9 +111,7 @@ const MenuOption = ( {
|
|
|
117
111
|
|
|
118
112
|
const handleClick = () => {
|
|
119
113
|
if ( isDisabled ) {
|
|
120
|
-
|
|
121
|
-
setIsPopoverOpen( true );
|
|
122
|
-
}
|
|
114
|
+
promotionRef.current?.toggle();
|
|
123
115
|
return;
|
|
124
116
|
}
|
|
125
117
|
|
|
@@ -130,18 +122,6 @@ const MenuOption = ( {
|
|
|
130
122
|
onClose();
|
|
131
123
|
};
|
|
132
124
|
|
|
133
|
-
const title = sprintf(
|
|
134
|
-
/* translators: %s: Variable Type. */
|
|
135
|
-
__( '%s variables', 'elementor' ),
|
|
136
|
-
capitalize( config.variableType )
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
const content = sprintf(
|
|
140
|
-
/* translators: %s: Variable Type. */
|
|
141
|
-
__( 'Upgrade to continue creating and editing %s variables.', 'elementor' ),
|
|
142
|
-
config.variableType
|
|
143
|
-
);
|
|
144
|
-
|
|
145
125
|
return (
|
|
146
126
|
<MenuItem onClick={ handleClick } sx={ { gap: 1.5, cursor: 'pointer' } }>
|
|
147
127
|
{ createElement( config.icon, { fontSize: SIZE, color: isDisabled ? 'disabled' : 'action' } ) }
|
|
@@ -149,18 +129,11 @@ const MenuOption = ( {
|
|
|
149
129
|
{ displayName }
|
|
150
130
|
</Typography>
|
|
151
131
|
{ isDisabled && (
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
ctaUrl={ `https://go.elementor.com/go-pro-manager-${ config.variableType }-variable/` }
|
|
158
|
-
onClose={ () => {
|
|
159
|
-
setIsPopoverOpen( false );
|
|
160
|
-
} }
|
|
161
|
-
>
|
|
162
|
-
<PromotionChip />
|
|
163
|
-
</PromotionPopover>
|
|
132
|
+
<VariablePromotionChip
|
|
133
|
+
variableType={ config.variableType }
|
|
134
|
+
upgradeUrl={ `https://go.elementor.com/go-pro-manager-${ config.variableType }-variable/` }
|
|
135
|
+
ref={ promotionRef }
|
|
136
|
+
/>
|
|
164
137
|
) }
|
|
165
138
|
</MenuItem>
|
|
166
139
|
);
|
|
@@ -139,22 +139,25 @@ export function VariablesManagerPanel() {
|
|
|
139
139
|
[ handleDeleteVariable ]
|
|
140
140
|
);
|
|
141
141
|
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
142
|
+
const buildMenuActions = useCallback(
|
|
143
|
+
() => [
|
|
144
|
+
{
|
|
145
|
+
name: __( 'Delete', 'elementor' ),
|
|
146
|
+
icon: TrashIcon,
|
|
147
|
+
color: 'error.main',
|
|
148
|
+
onClick: ( itemId: string ) => {
|
|
149
|
+
const variable = variables[ itemId ];
|
|
150
|
+
if ( variable ) {
|
|
151
|
+
setDeleteConfirmation( { id: itemId, label: variable.label } );
|
|
151
152
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
const variableTypeOptions = getVariableType( variable.type );
|
|
154
|
+
trackVariablesManagerEvent( { action: 'delete', varType: variableTypeOptions?.variableType } );
|
|
155
|
+
}
|
|
156
|
+
},
|
|
155
157
|
},
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
],
|
|
159
|
+
[ variables ]
|
|
160
|
+
);
|
|
158
161
|
|
|
159
162
|
const hasVariables = Object.keys( variables ).length > 0;
|
|
160
163
|
|
|
@@ -212,7 +215,7 @@ export function VariablesManagerPanel() {
|
|
|
212
215
|
>
|
|
213
216
|
{ hasVariables && (
|
|
214
217
|
<VariablesManagerTable
|
|
215
|
-
menuActions={
|
|
218
|
+
menuActions={ buildMenuActions }
|
|
216
219
|
variables={ variables }
|
|
217
220
|
onChange={ handleOnChange }
|
|
218
221
|
autoEditVariableId={ autoEditVariableId }
|