@elementor/editor-variables 3.32.0-49 → 3.32.0-50
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 +664 -457
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +603 -386
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -12
- package/src/components/variable-selection-popover.tsx +2 -2
- package/src/components/variables-manager/variable-edit-menu.tsx +72 -0
- package/src/components/variables-manager/variable-table-cell.tsx +37 -0
- package/src/components/variables-manager/variables-manager-panel.tsx +15 -12
- package/src/components/variables-manager/variables-manager-table.tsx +172 -0
- package/src/hooks/use-prop-variables.ts +14 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-variables",
|
|
3
|
-
"version": "3.32.0-
|
|
3
|
+
"version": "3.32.0-50",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,18 +39,18 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "3.32.0-
|
|
43
|
-
"@elementor/editor-canvas": "3.32.0-
|
|
44
|
-
"@elementor/editor-controls": "3.32.0-
|
|
45
|
-
"@elementor/editor-current-user": "3.32.0-
|
|
46
|
-
"@elementor/editor-editing-panel": "3.32.0-
|
|
47
|
-
"@elementor/editor-panels": "3.32.0-
|
|
48
|
-
"@elementor/editor-props": "3.32.0-
|
|
49
|
-
"@elementor/editor-ui": "3.32.0-
|
|
50
|
-
"@elementor/editor-v1-adapters": "3.32.0-
|
|
51
|
-
"@elementor/http-client": "3.32.0-
|
|
42
|
+
"@elementor/editor": "3.32.0-50",
|
|
43
|
+
"@elementor/editor-canvas": "3.32.0-50",
|
|
44
|
+
"@elementor/editor-controls": "3.32.0-50",
|
|
45
|
+
"@elementor/editor-current-user": "3.32.0-50",
|
|
46
|
+
"@elementor/editor-editing-panel": "3.32.0-50",
|
|
47
|
+
"@elementor/editor-panels": "3.32.0-50",
|
|
48
|
+
"@elementor/editor-props": "3.32.0-50",
|
|
49
|
+
"@elementor/editor-ui": "3.32.0-50",
|
|
50
|
+
"@elementor/editor-v1-adapters": "3.32.0-50",
|
|
51
|
+
"@elementor/http-client": "3.32.0-50",
|
|
52
52
|
"@elementor/icons": "1.46.0",
|
|
53
|
-
"@elementor/schema": "3.32.0-
|
|
53
|
+
"@elementor/schema": "3.32.0-50",
|
|
54
54
|
"@elementor/ui": "1.36.8",
|
|
55
55
|
"@wordpress/i18n": "^5.13.0"
|
|
56
56
|
},
|
|
@@ -28,7 +28,7 @@ export const VariableSelectionPopover = ( { closePopover, propTypeKey, selectedV
|
|
|
28
28
|
const [ currentView, setCurrentView ] = useState< View >( VIEW_LIST );
|
|
29
29
|
const [ editId, setEditId ] = useState< string >( '' );
|
|
30
30
|
const { open } = usePanelActions();
|
|
31
|
-
const onSettingsAvailable = isExperimentActive( '
|
|
31
|
+
const onSettingsAvailable = isExperimentActive( 'e_variables_manager' )
|
|
32
32
|
? () => {
|
|
33
33
|
open();
|
|
34
34
|
}
|
|
@@ -98,8 +98,8 @@ function RenderView( props: ViewProps ): React.ReactNode {
|
|
|
98
98
|
|
|
99
99
|
if ( userPermissions.canManageSettings() && props.onSettings ) {
|
|
100
100
|
handlers.onSettings = () => {
|
|
101
|
-
props.onSettings?.();
|
|
102
101
|
props.closePopover();
|
|
102
|
+
props.onSettings?.();
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
import { DotsVerticalIcon } from '@elementor/icons';
|
|
4
|
+
import { bindMenu, bindTrigger, IconButton, Menu, MenuItem, type SvgIconProps, usePopupState } from '@elementor/ui';
|
|
5
|
+
|
|
6
|
+
export type VariableManagerMenuAction = {
|
|
7
|
+
name: string;
|
|
8
|
+
icon: React.ForwardRefExoticComponent< Omit< SvgIconProps, 'ref' > & React.RefAttributes< SVGSVGElement > >;
|
|
9
|
+
color: string;
|
|
10
|
+
onClick: () => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type VariableEditMenuProps = {
|
|
14
|
+
menuActions: VariableManagerMenuAction[];
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const VariableEditMenu = ( { menuActions, disabled }: VariableEditMenuProps ) => {
|
|
19
|
+
const menuState = usePopupState( {
|
|
20
|
+
variant: 'popover',
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<IconButton { ...bindTrigger( menuState ) } disabled={ disabled } size="tiny">
|
|
26
|
+
<DotsVerticalIcon fontSize="tiny" />
|
|
27
|
+
</IconButton>
|
|
28
|
+
|
|
29
|
+
<Menu
|
|
30
|
+
disablePortal
|
|
31
|
+
MenuListProps={ {
|
|
32
|
+
dense: true,
|
|
33
|
+
} }
|
|
34
|
+
PaperProps={ {
|
|
35
|
+
elevation: 6,
|
|
36
|
+
} }
|
|
37
|
+
{ ...bindMenu( menuState ) }
|
|
38
|
+
anchorEl={ menuState.anchorEl }
|
|
39
|
+
anchorOrigin={ {
|
|
40
|
+
vertical: 'bottom',
|
|
41
|
+
horizontal: 'right',
|
|
42
|
+
} }
|
|
43
|
+
transformOrigin={ {
|
|
44
|
+
vertical: 'top',
|
|
45
|
+
horizontal: 'right',
|
|
46
|
+
} }
|
|
47
|
+
open={ menuState.isOpen }
|
|
48
|
+
onClose={ menuState.close }
|
|
49
|
+
>
|
|
50
|
+
{ menuActions.map( ( action ) => (
|
|
51
|
+
<MenuItem
|
|
52
|
+
key={ action.name }
|
|
53
|
+
onClick={ () => {
|
|
54
|
+
action.onClick?.();
|
|
55
|
+
menuState.close();
|
|
56
|
+
} }
|
|
57
|
+
sx={ {
|
|
58
|
+
color: action.color,
|
|
59
|
+
gap: 1,
|
|
60
|
+
} }
|
|
61
|
+
>
|
|
62
|
+
{ action.icon &&
|
|
63
|
+
createElement( action.icon, {
|
|
64
|
+
fontSize: 'inherit',
|
|
65
|
+
} ) }{ ' ' }
|
|
66
|
+
{ action.name }
|
|
67
|
+
</MenuItem>
|
|
68
|
+
) ) }
|
|
69
|
+
</Menu>
|
|
70
|
+
</>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type SxProps, TableCell } from '@elementor/ui';
|
|
3
|
+
|
|
4
|
+
type VariableTableCellProps = {
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
isHeader?: boolean;
|
|
7
|
+
width?: number;
|
|
8
|
+
maxWidth?: number;
|
|
9
|
+
align?: 'left' | 'right' | 'center';
|
|
10
|
+
noPadding?: boolean;
|
|
11
|
+
sx?: SxProps;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const VariableTableCell = ( {
|
|
15
|
+
children,
|
|
16
|
+
isHeader,
|
|
17
|
+
width,
|
|
18
|
+
maxWidth,
|
|
19
|
+
align,
|
|
20
|
+
noPadding,
|
|
21
|
+
sx,
|
|
22
|
+
}: VariableTableCellProps ) => {
|
|
23
|
+
const baseSx: SxProps = {
|
|
24
|
+
maxWidth: maxWidth ?? 150,
|
|
25
|
+
cursor: 'initial',
|
|
26
|
+
typography: 'caption',
|
|
27
|
+
...( isHeader && { color: 'text.primary', fontWeight: 'bold' } ),
|
|
28
|
+
...( width && { width } ),
|
|
29
|
+
...sx,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<TableCell size="small" padding={ noPadding ? 'none' : undefined } align={ align } sx={ baseSx }>
|
|
34
|
+
{ children }
|
|
35
|
+
</TableCell>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
@@ -10,10 +10,12 @@ import {
|
|
|
10
10
|
} from '@elementor/editor-panels';
|
|
11
11
|
import { ThemeProvider } from '@elementor/editor-ui';
|
|
12
12
|
import { changeEditMode } from '@elementor/editor-v1-adapters';
|
|
13
|
-
import {
|
|
13
|
+
import { ColorFilterIcon, TrashIcon, XIcon } from '@elementor/icons';
|
|
14
14
|
import { Alert, Box, Button, Divider, ErrorBoundary, IconButton, type IconButtonProps, Stack } from '@elementor/ui';
|
|
15
15
|
import { __ } from '@wordpress/i18n';
|
|
16
16
|
|
|
17
|
+
import { VariablesManagerTable } from './variables-manager-table';
|
|
18
|
+
|
|
17
19
|
const id = 'variables-manager';
|
|
18
20
|
|
|
19
21
|
export const { panel, usePanelActions } = createPanel( {
|
|
@@ -34,6 +36,15 @@ export function VariablesManagerPanel() {
|
|
|
34
36
|
|
|
35
37
|
usePreventUnload( isDirty );
|
|
36
38
|
|
|
39
|
+
const menuActions = [
|
|
40
|
+
{
|
|
41
|
+
name: __( 'Delete', 'elementor' ),
|
|
42
|
+
icon: TrashIcon,
|
|
43
|
+
color: 'error.main',
|
|
44
|
+
onClick: () => {},
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
37
48
|
return (
|
|
38
49
|
<ThemeProvider>
|
|
39
50
|
<ErrorBoundary fallback={ <ErrorBoundaryFallback /> }>
|
|
@@ -42,8 +53,8 @@ export function VariablesManagerPanel() {
|
|
|
42
53
|
<Stack p={ 1 } pl={ 2 } width="100%" direction="row" alignItems="center">
|
|
43
54
|
<Stack width="100%" direction="row" gap={ 1 }>
|
|
44
55
|
<PanelHeaderTitle sx={ { display: 'flex', alignItems: 'center', gap: 0.5 } }>
|
|
45
|
-
<
|
|
46
|
-
{ __( '
|
|
56
|
+
<ColorFilterIcon fontSize="inherit" />
|
|
57
|
+
{ __( 'Variable Manager', 'elementor' ) }
|
|
47
58
|
</PanelHeaderTitle>
|
|
48
59
|
</Stack>
|
|
49
60
|
<CloseButton
|
|
@@ -62,15 +73,7 @@ export function VariablesManagerPanel() {
|
|
|
62
73
|
} }
|
|
63
74
|
>
|
|
64
75
|
<Divider />
|
|
65
|
-
<
|
|
66
|
-
px={ 2 }
|
|
67
|
-
sx={ {
|
|
68
|
-
flexGrow: 1,
|
|
69
|
-
overflowY: 'auto',
|
|
70
|
-
} }
|
|
71
|
-
>
|
|
72
|
-
List
|
|
73
|
-
</Box>
|
|
76
|
+
<VariablesManagerTable menuActions={ menuActions } />
|
|
74
77
|
</PanelBody>
|
|
75
78
|
|
|
76
79
|
<PanelFooter>
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createElement, useState } from 'react';
|
|
3
|
+
import { EllipsisWithTooltip } from '@elementor/editor-ui';
|
|
4
|
+
import { GripVerticalIcon } from '@elementor/icons';
|
|
5
|
+
import {
|
|
6
|
+
IconButton,
|
|
7
|
+
Stack,
|
|
8
|
+
type SxProps,
|
|
9
|
+
Table,
|
|
10
|
+
TableBody,
|
|
11
|
+
TableContainer,
|
|
12
|
+
TableHead,
|
|
13
|
+
TableRow,
|
|
14
|
+
UnstableSortableItem,
|
|
15
|
+
type UnstableSortableItemRenderProps,
|
|
16
|
+
UnstableSortableProvider,
|
|
17
|
+
} from '@elementor/ui';
|
|
18
|
+
import { __ } from '@wordpress/i18n';
|
|
19
|
+
|
|
20
|
+
import { getVariables } from '../../hooks/use-prop-variables';
|
|
21
|
+
import { getVariableType } from '../../variables-registry/variable-type-registry';
|
|
22
|
+
import { VariableEditMenu, type VariableManagerMenuAction } from './variable-edit-menu';
|
|
23
|
+
import { VariableTableCell } from './variable-table-cell';
|
|
24
|
+
|
|
25
|
+
type Props = {
|
|
26
|
+
menuActions: VariableManagerMenuAction[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const VariablesManagerTable = ( { menuActions }: Props ) => {
|
|
30
|
+
const variables = getVariables( false );
|
|
31
|
+
|
|
32
|
+
const [ ids, setIds ] = useState< string[] >( Object.keys( variables ) );
|
|
33
|
+
const rows = ids.map( ( id ) => ( {
|
|
34
|
+
id,
|
|
35
|
+
name: variables[ id ].label,
|
|
36
|
+
value: variables[ id ].value,
|
|
37
|
+
type: variables[ id ].type,
|
|
38
|
+
icon: getVariableType( variables[ id ].type ).icon,
|
|
39
|
+
startIcon: getVariableType( variables[ id ].type ).startIcon,
|
|
40
|
+
} ) );
|
|
41
|
+
|
|
42
|
+
const tableSX: SxProps = {
|
|
43
|
+
minWidth: 250,
|
|
44
|
+
tableLayout: 'fixed',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<TableContainer sx={ { overflow: 'initial' } }>
|
|
49
|
+
<Table sx={ tableSX } aria-label="Variables manager list with drag and drop reordering">
|
|
50
|
+
<TableHead>
|
|
51
|
+
<TableRow>
|
|
52
|
+
<VariableTableCell isHeader noPadding width={ 10 } maxWidth={ 10 } />
|
|
53
|
+
<VariableTableCell isHeader>{ __( 'Name', 'elementor' ) }</VariableTableCell>
|
|
54
|
+
<VariableTableCell isHeader>{ __( 'Value', 'elementor' ) }</VariableTableCell>
|
|
55
|
+
<VariableTableCell isHeader noPadding width={ 16 } maxWidth={ 16 } />
|
|
56
|
+
</TableRow>
|
|
57
|
+
</TableHead>
|
|
58
|
+
<TableBody>
|
|
59
|
+
<UnstableSortableProvider
|
|
60
|
+
value={ ids }
|
|
61
|
+
onChange={ setIds }
|
|
62
|
+
variant="static"
|
|
63
|
+
restrictAxis
|
|
64
|
+
dragOverlay={ ( { children: dragOverlayChildren, ...dragOverlayProps } ) => (
|
|
65
|
+
<Table sx={ tableSX } { ...dragOverlayProps }>
|
|
66
|
+
<TableBody>{ dragOverlayChildren }</TableBody>
|
|
67
|
+
</Table>
|
|
68
|
+
) }
|
|
69
|
+
>
|
|
70
|
+
{ rows.map( ( row ) => (
|
|
71
|
+
<UnstableSortableItem
|
|
72
|
+
key={ row.id }
|
|
73
|
+
id={ row.id }
|
|
74
|
+
render={ ( {
|
|
75
|
+
itemProps,
|
|
76
|
+
showDropIndication,
|
|
77
|
+
triggerProps,
|
|
78
|
+
itemStyle,
|
|
79
|
+
triggerStyle,
|
|
80
|
+
isDragged,
|
|
81
|
+
dropPosition,
|
|
82
|
+
setTriggerRef,
|
|
83
|
+
isDragOverlay,
|
|
84
|
+
isSorting,
|
|
85
|
+
index,
|
|
86
|
+
}: UnstableSortableItemRenderProps ) => {
|
|
87
|
+
const showIndicationBefore = showDropIndication && dropPosition === 'before';
|
|
88
|
+
const showIndicationAfter = showDropIndication && dropPosition === 'after';
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<TableRow
|
|
92
|
+
{ ...itemProps }
|
|
93
|
+
selected={ isDragged }
|
|
94
|
+
sx={ {
|
|
95
|
+
...( showIndicationBefore && {
|
|
96
|
+
'& td, & th': {
|
|
97
|
+
borderTop: '2px solid',
|
|
98
|
+
borderTopColor: 'primary.main',
|
|
99
|
+
},
|
|
100
|
+
} ),
|
|
101
|
+
...( showIndicationAfter && {
|
|
102
|
+
'& td, & th': {
|
|
103
|
+
borderBottom: '2px solid',
|
|
104
|
+
borderBottomColor: 'primary.main',
|
|
105
|
+
},
|
|
106
|
+
} ),
|
|
107
|
+
'& [role="toolbar"], & [draggable]': {
|
|
108
|
+
opacity: 0,
|
|
109
|
+
},
|
|
110
|
+
'&:hover, &:focus-within': {
|
|
111
|
+
backgroundColor: 'action.hover',
|
|
112
|
+
'& [role="toolbar"], & [draggable]': {
|
|
113
|
+
opacity: 1,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
} }
|
|
117
|
+
style={ { ...itemStyle, ...triggerStyle } }
|
|
118
|
+
disableDivider={ isDragOverlay || index === rows.length - 1 }
|
|
119
|
+
>
|
|
120
|
+
<VariableTableCell noPadding width={ 10 } maxWidth={ 10 }>
|
|
121
|
+
<IconButton
|
|
122
|
+
size="small"
|
|
123
|
+
ref={ setTriggerRef }
|
|
124
|
+
{ ...triggerProps }
|
|
125
|
+
disabled={ isSorting }
|
|
126
|
+
draggable
|
|
127
|
+
>
|
|
128
|
+
<GripVerticalIcon fontSize="inherit" />
|
|
129
|
+
</IconButton>
|
|
130
|
+
</VariableTableCell>
|
|
131
|
+
<VariableTableCell>
|
|
132
|
+
<Stack direction="row" alignItems="center" gap={ 1 }>
|
|
133
|
+
{ createElement( row.icon, { fontSize: 'inherit' } ) }
|
|
134
|
+
<EllipsisWithTooltip title={ row.name }>
|
|
135
|
+
{ row.name }
|
|
136
|
+
</EllipsisWithTooltip>
|
|
137
|
+
</Stack>
|
|
138
|
+
</VariableTableCell>
|
|
139
|
+
<VariableTableCell>
|
|
140
|
+
<Stack direction="row" alignItems="center" gap={ 1 }>
|
|
141
|
+
{ row.startIcon && row.startIcon( { value: row.value } ) }
|
|
142
|
+
|
|
143
|
+
<EllipsisWithTooltip title={ row.value }>
|
|
144
|
+
{ row.value }
|
|
145
|
+
</EllipsisWithTooltip>
|
|
146
|
+
</Stack>
|
|
147
|
+
</VariableTableCell>
|
|
148
|
+
<VariableTableCell
|
|
149
|
+
align="right"
|
|
150
|
+
noPadding
|
|
151
|
+
width={ 16 }
|
|
152
|
+
maxWidth={ 16 }
|
|
153
|
+
sx={ { paddingInlineEnd: 1 } }
|
|
154
|
+
>
|
|
155
|
+
<Stack role="toolbar" direction="row" justifyContent="flex-end">
|
|
156
|
+
<VariableEditMenu
|
|
157
|
+
menuActions={ menuActions }
|
|
158
|
+
disabled={ isSorting }
|
|
159
|
+
/>
|
|
160
|
+
</Stack>
|
|
161
|
+
</VariableTableCell>
|
|
162
|
+
</TableRow>
|
|
163
|
+
);
|
|
164
|
+
} }
|
|
165
|
+
/>
|
|
166
|
+
) ) }
|
|
167
|
+
</UnstableSortableProvider>
|
|
168
|
+
</TableBody>
|
|
169
|
+
</Table>
|
|
170
|
+
</TableContainer>
|
|
171
|
+
);
|
|
172
|
+
};
|
|
@@ -6,9 +6,19 @@ import { useVariableType } from '../context/variable-type-context';
|
|
|
6
6
|
import { service } from '../service';
|
|
7
7
|
import { type NormalizedVariable, type Variable } from '../types';
|
|
8
8
|
|
|
9
|
-
export const
|
|
9
|
+
export const getVariables = ( includeDeleted = true ) => {
|
|
10
10
|
const variables = service.variables();
|
|
11
11
|
|
|
12
|
+
if ( includeDeleted ) {
|
|
13
|
+
return variables;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return Object.fromEntries( Object.entries( variables ).filter( ( [ , variable ] ) => ! variable.deleted ) );
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const useVariable = ( key: string ) => {
|
|
20
|
+
const variables = getVariables();
|
|
21
|
+
|
|
12
22
|
if ( ! variables?.[ key ] ) {
|
|
13
23
|
return null;
|
|
14
24
|
}
|
|
@@ -48,13 +58,11 @@ const usePropVariables = ( propKey: PropKey ): NormalizedVariable[] => {
|
|
|
48
58
|
return useMemo( () => normalizeVariables( propKey ), [ propKey ] );
|
|
49
59
|
};
|
|
50
60
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const normalizeVariables = ( propKey: string ): NormalizedVariable[] => {
|
|
54
|
-
const variables = service.variables();
|
|
61
|
+
const normalizeVariables = ( propKey: string ) => {
|
|
62
|
+
const variables = getVariables( false );
|
|
55
63
|
|
|
56
64
|
return Object.entries( variables )
|
|
57
|
-
.filter( ( [ , variable ] ) => variable.type === propKey
|
|
65
|
+
.filter( ( [ , variable ] ) => variable.type === propKey )
|
|
58
66
|
.map( ( [ key, { label, value } ] ) => ( {
|
|
59
67
|
key,
|
|
60
68
|
label,
|