@elementor/editor-variables 0.16.0 → 3.32.0-20
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 +22 -0
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +1397 -885
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1399 -871
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -14
- package/src/api.ts +18 -2
- package/src/components/fields/color-field.tsx +3 -3
- package/src/components/fields/font-field.tsx +21 -10
- package/src/components/fields/label-field.tsx +31 -5
- package/src/components/ui/delete-confirmation-dialog.tsx +4 -7
- package/src/components/ui/deleted-variable-alert.tsx +47 -0
- package/src/components/ui/edit-confirmation-dialog.tsx +75 -0
- package/src/components/ui/missing-variable-alert.tsx +39 -0
- package/src/components/ui/no-variables.tsx +59 -26
- package/src/components/ui/tags/assigned-tag.tsx +21 -19
- package/src/components/ui/tags/deleted-tag.tsx +29 -18
- package/src/components/ui/tags/missing-tag.tsx +25 -0
- package/src/components/ui/variable/assigned-variable.tsx +11 -14
- package/src/components/ui/variable/deleted-variable.tsx +115 -7
- package/src/components/ui/variable/missing-variable.tsx +44 -0
- package/src/components/variable-creation.tsx +135 -0
- package/src/components/variable-edit.tsx +221 -0
- package/src/components/variable-restore.tsx +117 -0
- package/src/components/variable-selection-popover.tsx +91 -92
- package/src/components/variables-manager/variables-manager-panel.tsx +115 -0
- package/src/components/variables-selection.tsx +148 -0
- package/src/context/variable-selection-popover.context.tsx +19 -0
- package/src/context/variable-type-context.tsx +23 -0
- package/src/controls/variable-control.tsx +26 -0
- package/src/create-style-variables-repository.ts +44 -5
- package/src/hooks/use-initial-value.ts +22 -0
- package/src/hooks/use-permissions.ts +15 -0
- package/src/hooks/use-prop-variable-action.tsx +53 -0
- package/src/hooks/use-prop-variables.ts +6 -0
- package/src/index.ts +1 -0
- package/src/init.ts +33 -4
- package/src/register-variable-types.tsx +29 -0
- package/src/renderers/style-variables-renderer.tsx +10 -4
- package/src/repeater-injections.ts +5 -1
- package/src/service.ts +8 -4
- package/src/sync/enqueue-font.ts +7 -0
- package/src/sync/types.ts +5 -0
- package/src/transformers/inheritance-transformer.tsx +30 -0
- package/src/transformers/utils/resolve-css-variable.ts +24 -0
- package/src/transformers/variable-transformer.ts +8 -3
- package/src/types.ts +1 -1
- package/src/utils/tracking.ts +39 -0
- package/src/utils/validations.ts +40 -6
- package/src/variables-registry/create-variable-type-registry.ts +77 -0
- package/src/variables-registry/variable-type-registry.ts +3 -0
- package/src/components/color-variable-creation.tsx +0 -86
- package/src/components/color-variable-edit.tsx +0 -138
- package/src/components/color-variables-selection.tsx +0 -130
- package/src/components/font-variable-creation.tsx +0 -86
- package/src/components/font-variable-edit.tsx +0 -138
- package/src/components/font-variables-selection.tsx +0 -129
- package/src/components/variable-selection-popover.context.ts +0 -7
- package/src/controls/color-variable-control.tsx +0 -33
- package/src/controls/font-variable-control.tsx +0 -31
- package/src/hooks/use-prop-color-variable-action.tsx +0 -25
- package/src/hooks/use-prop-font-variable-action.tsx +0 -25
- package/src/init-color-variables.ts +0 -27
- package/src/init-font-variables.ts +0 -24
- package/src/utils.ts +0 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-variables",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.32.0-20",
|
|
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-variables"
|
|
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,18 +39,20 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "
|
|
43
|
-
"@elementor/editor-
|
|
44
|
-
"@elementor/editor-
|
|
45
|
-
"@elementor/editor-
|
|
46
|
-
"@elementor/
|
|
47
|
-
"@elementor/editor-
|
|
42
|
+
"@elementor/editor": "3.32.0-20",
|
|
43
|
+
"@elementor/editor-canvas": "3.32.0-20",
|
|
44
|
+
"@elementor/editor-controls": "3.32.0-20",
|
|
45
|
+
"@elementor/editor-current-user": "3.32.0-20",
|
|
46
|
+
"@elementor/editor-editing-panel": "3.32.0-20",
|
|
47
|
+
"@elementor/editor-panels": "3.32.0-20",
|
|
48
|
+
"@elementor/editor-props": "3.32.0-20",
|
|
49
|
+
"@elementor/editor-ui": "3.32.0-20",
|
|
50
|
+
"@elementor/editor-v1-adapters": "3.32.0-20",
|
|
51
|
+
"@elementor/http-client": "3.32.0-20",
|
|
48
52
|
"@elementor/icons": "1.46.0",
|
|
49
|
-
"@
|
|
50
|
-
"@elementor/ui": "1.36.
|
|
51
|
-
"@
|
|
52
|
-
"@elementor/http-client": "0.3.0",
|
|
53
|
-
"@elementor/editor-ui": "0.14.0"
|
|
53
|
+
"@elementor/schema": "3.32.0-20",
|
|
54
|
+
"@elementor/ui": "1.36.2",
|
|
55
|
+
"@wordpress/i18n": "^5.13.0"
|
|
54
56
|
},
|
|
55
57
|
"peerDependencies": {
|
|
56
58
|
"react": "^18.3.1",
|
package/src/api.ts
CHANGED
|
@@ -2,6 +2,12 @@ import { httpService } from '@elementor/http-client';
|
|
|
2
2
|
|
|
3
3
|
const BASE_PATH = 'elementor/v1/variables';
|
|
4
4
|
|
|
5
|
+
type RestoreVariablePayload = {
|
|
6
|
+
id: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
value?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
5
11
|
export const apiClient = {
|
|
6
12
|
list: () => {
|
|
7
13
|
return httpService().get( BASE_PATH + '/list' );
|
|
@@ -27,7 +33,17 @@ export const apiClient = {
|
|
|
27
33
|
return httpService().post( BASE_PATH + '/delete', { id } );
|
|
28
34
|
},
|
|
29
35
|
|
|
30
|
-
restore: ( id: string ) => {
|
|
31
|
-
|
|
36
|
+
restore: ( id: string, label?: string, value?: string ) => {
|
|
37
|
+
const payload: RestoreVariablePayload = { id };
|
|
38
|
+
|
|
39
|
+
if ( label ) {
|
|
40
|
+
payload.label = label;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if ( value ) {
|
|
44
|
+
payload.value = value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return httpService().post( BASE_PATH + '/restore', payload );
|
|
32
48
|
},
|
|
33
49
|
};
|
|
@@ -3,8 +3,8 @@ import { useRef, useState } from 'react';
|
|
|
3
3
|
import { FormHelperText, FormLabel, Grid, UnstableColorField } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
|
+
import { usePopoverContentRef } from '../../context/variable-selection-popover.context';
|
|
6
7
|
import { validateValue } from '../../utils/validations';
|
|
7
|
-
import { usePopoverContentRef } from '../variable-selection-popover.context';
|
|
8
8
|
|
|
9
9
|
type ColorFieldProps = {
|
|
10
10
|
value: string;
|
|
@@ -16,7 +16,7 @@ export const ColorField = ( { value, onChange }: ColorFieldProps ) => {
|
|
|
16
16
|
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
17
17
|
|
|
18
18
|
const defaultRef = useRef< HTMLDivElement >( null );
|
|
19
|
-
const anchorRef = usePopoverContentRef() ?? defaultRef;
|
|
19
|
+
const anchorRef = usePopoverContentRef() ?? defaultRef.current;
|
|
20
20
|
|
|
21
21
|
const handleChange = ( newValue: string ) => {
|
|
22
22
|
setColor( newValue );
|
|
@@ -41,7 +41,7 @@ export const ColorField = ( { value, onChange }: ColorFieldProps ) => {
|
|
|
41
41
|
error={ errorMessage ?? undefined }
|
|
42
42
|
slotProps={ {
|
|
43
43
|
colorPicker: {
|
|
44
|
-
anchorEl: anchorRef
|
|
44
|
+
anchorEl: anchorRef,
|
|
45
45
|
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
46
46
|
transformOrigin: { vertical: 'top', horizontal: -10 },
|
|
47
47
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { enqueueFont, ItemSelector } from '@elementor/editor-controls';
|
|
4
4
|
import { useFontFamilies, useSectionWidth } from '@elementor/editor-editing-panel';
|
|
5
|
-
import { ChevronDownIcon } from '@elementor/icons';
|
|
5
|
+
import { ChevronDownIcon, TextIcon } from '@elementor/icons';
|
|
6
6
|
import {
|
|
7
7
|
bindPopover,
|
|
8
8
|
bindTrigger,
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
} from '@elementor/ui';
|
|
16
16
|
import { __ } from '@wordpress/i18n';
|
|
17
17
|
|
|
18
|
+
import { usePopoverContentRef } from '../../context/variable-selection-popover.context';
|
|
18
19
|
import { validateValue } from '../../utils/validations';
|
|
19
|
-
import { usePopoverContentRef } from '../variable-selection-popover.context';
|
|
20
20
|
|
|
21
21
|
type FontFieldProps = {
|
|
22
22
|
value: string;
|
|
@@ -28,13 +28,20 @@ export const FontField = ( { value, onChange }: FontFieldProps ) => {
|
|
|
28
28
|
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
29
29
|
|
|
30
30
|
const defaultRef = useRef< HTMLDivElement >( null );
|
|
31
|
-
const anchorRef = usePopoverContentRef() ?? defaultRef;
|
|
31
|
+
const anchorRef = usePopoverContentRef() ?? defaultRef.current;
|
|
32
32
|
|
|
33
33
|
const fontPopoverState = usePopupState( { variant: 'popover' } );
|
|
34
34
|
|
|
35
35
|
const fontFamilies = useFontFamilies();
|
|
36
36
|
const sectionWidth = useSectionWidth();
|
|
37
37
|
|
|
38
|
+
const mapFontSubs = React.useMemo( () => {
|
|
39
|
+
return fontFamilies.map( ( { label, fonts } ) => ( {
|
|
40
|
+
label,
|
|
41
|
+
items: fonts,
|
|
42
|
+
} ) );
|
|
43
|
+
}, [ fontFamilies ] );
|
|
44
|
+
|
|
38
45
|
const handleChange = ( newValue: string ) => {
|
|
39
46
|
setFontFamily( newValue );
|
|
40
47
|
|
|
@@ -65,17 +72,21 @@ export const FontField = ( { value, onChange }: FontFieldProps ) => {
|
|
|
65
72
|
<Popover
|
|
66
73
|
disablePortal
|
|
67
74
|
disableScrollLock
|
|
68
|
-
anchorEl={ anchorRef
|
|
75
|
+
anchorEl={ anchorRef }
|
|
69
76
|
anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
70
|
-
transformOrigin={ { vertical: 'top', horizontal: -
|
|
77
|
+
transformOrigin={ { vertical: 'top', horizontal: -28 } }
|
|
71
78
|
{ ...bindPopover( fontPopoverState ) }
|
|
72
79
|
>
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
<ItemSelector
|
|
81
|
+
itemsList={ mapFontSubs }
|
|
82
|
+
selectedItem={ fontFamily }
|
|
83
|
+
onItemChange={ handleFontFamilyChange }
|
|
77
84
|
onClose={ fontPopoverState.close }
|
|
78
85
|
sectionWidth={ sectionWidth }
|
|
86
|
+
title={ __( 'Font Family', 'elementor' ) }
|
|
87
|
+
itemStyle={ ( item ) => ( { fontFamily: item.value } ) }
|
|
88
|
+
onDebounce={ enqueueFont }
|
|
89
|
+
icon={ TextIcon as React.ElementType< { fontSize: string } > }
|
|
79
90
|
/>
|
|
80
91
|
</Popover>
|
|
81
92
|
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
@@ -5,12 +5,31 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
|
|
6
6
|
import { labelHint, validateLabel, VARIABLE_LABEL_MAX_LENGTH } from '../../utils/validations';
|
|
7
7
|
|
|
8
|
+
function isLabelEqual( a: string, b: string ) {
|
|
9
|
+
return a.trim().toLowerCase() === b.trim().toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type LabelErrorProps = {
|
|
13
|
+
value: string;
|
|
14
|
+
message: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const useLabelError = ( initialError?: LabelErrorProps ) => {
|
|
18
|
+
const [ error, setError ] = useState< LabelErrorProps >( initialError ?? { value: '', message: '' } );
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
labelFieldError: error,
|
|
22
|
+
setLabelFieldError: setError,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
8
26
|
type LabelFieldProps = {
|
|
9
27
|
value: string;
|
|
28
|
+
error?: LabelErrorProps;
|
|
10
29
|
onChange: ( value: string ) => void;
|
|
11
30
|
};
|
|
12
31
|
|
|
13
|
-
export const LabelField = ( { value, onChange }: LabelFieldProps ) => {
|
|
32
|
+
export const LabelField = ( { value, error, onChange }: LabelFieldProps ) => {
|
|
14
33
|
const [ label, setLabel ] = useState( value );
|
|
15
34
|
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
16
35
|
const [ noticeMessage, setNoticeMessage ] = useState( () => labelHint( value ) );
|
|
@@ -24,11 +43,18 @@ export const LabelField = ( { value, onChange }: LabelFieldProps ) => {
|
|
|
24
43
|
setErrorMessage( errorMsg );
|
|
25
44
|
setNoticeMessage( errorMsg ? '' : hintMsg );
|
|
26
45
|
|
|
27
|
-
onChange( errorMsg ? '' : newValue );
|
|
46
|
+
onChange( isLabelEqual( newValue, error?.value ?? '' ) || errorMsg ? '' : newValue );
|
|
28
47
|
};
|
|
29
48
|
|
|
30
49
|
const id = useId();
|
|
31
50
|
|
|
51
|
+
let errorMsg = errorMessage;
|
|
52
|
+
if ( isLabelEqual( label, error?.value ?? '' ) && error?.message ) {
|
|
53
|
+
errorMsg = error.message;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const noticeMsg = errorMsg ? '' : noticeMessage;
|
|
57
|
+
|
|
32
58
|
return (
|
|
33
59
|
<Grid container gap={ 0.75 } alignItems="center">
|
|
34
60
|
<Grid item xs={ 12 }>
|
|
@@ -42,12 +68,12 @@ export const LabelField = ( { value, onChange }: LabelFieldProps ) => {
|
|
|
42
68
|
size="tiny"
|
|
43
69
|
fullWidth
|
|
44
70
|
value={ label }
|
|
45
|
-
error={ !!
|
|
71
|
+
error={ !! errorMsg }
|
|
46
72
|
onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => handleChange( e.target.value ) }
|
|
47
73
|
inputProps={ { maxLength: VARIABLE_LABEL_MAX_LENGTH } }
|
|
48
74
|
/>
|
|
49
|
-
{
|
|
50
|
-
{
|
|
75
|
+
{ errorMsg && <FormHelperText error>{ errorMsg }</FormHelperText> }
|
|
76
|
+
{ noticeMsg && <FormHelperText>{ noticeMsg }</FormHelperText> }
|
|
51
77
|
</Grid>
|
|
52
78
|
</Grid>
|
|
53
79
|
);
|
|
@@ -28,23 +28,20 @@ export const DeleteConfirmationDialog = ( {
|
|
|
28
28
|
<Dialog open={ open } onClose={ closeDialog } aria-labelledby={ TITLE_ID } maxWidth="xs">
|
|
29
29
|
<DialogTitle id={ TITLE_ID } display="flex" alignItems="center" gap={ 1 } sx={ { lineHeight: 1 } }>
|
|
30
30
|
<AlertOctagonFilledIcon color="error" />
|
|
31
|
-
{ __( 'Delete
|
|
31
|
+
{ __( 'Delete this variable?', 'elementor' ) }
|
|
32
32
|
</DialogTitle>
|
|
33
33
|
<DialogContent>
|
|
34
34
|
<DialogContentText variant="body2" color="textPrimary">
|
|
35
|
-
{ __( '
|
|
35
|
+
{ __( 'All elements using', 'elementor' ) }
|
|
36
36
|
<Typography variant="subtitle2" component="span">
|
|
37
37
|
{ label }
|
|
38
38
|
</Typography>
|
|
39
|
-
{ __(
|
|
40
|
-
'Variable. Note that its value is still being used anywhere on your site where it was connected to the variable.',
|
|
41
|
-
'elementor'
|
|
42
|
-
) }
|
|
39
|
+
{ __( 'will keep their current values, but the variable itself will be removed.', 'elementor' ) }
|
|
43
40
|
</DialogContentText>
|
|
44
41
|
</DialogContent>
|
|
45
42
|
<DialogActions>
|
|
46
43
|
<Button color="secondary" onClick={ closeDialog }>
|
|
47
|
-
{ __( '
|
|
44
|
+
{ __( 'Not now', 'elementor' ) }
|
|
48
45
|
</Button>
|
|
49
46
|
<Button variant="contained" color="error" onClick={ onConfirm }>
|
|
50
47
|
{ __( 'Delete', 'elementor' ) }
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useSectionWidth } from '@elementor/editor-editing-panel';
|
|
3
|
+
import { Alert, AlertAction, AlertTitle, ClickAwayListener } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
type DeletedVariableAlertProps = {
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
onUnlink?: () => void;
|
|
9
|
+
onRestore?: () => void;
|
|
10
|
+
label: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const DeletedVariableAlert = ( { onClose, onUnlink, onRestore, label }: DeletedVariableAlertProps ) => {
|
|
14
|
+
const sectionWidth = useSectionWidth();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<ClickAwayListener onClickAway={ onClose }>
|
|
18
|
+
<Alert
|
|
19
|
+
variant="standard"
|
|
20
|
+
severity="warning"
|
|
21
|
+
onClose={ onClose }
|
|
22
|
+
action={
|
|
23
|
+
<>
|
|
24
|
+
{ onUnlink && (
|
|
25
|
+
<AlertAction variant="contained" onClick={ onUnlink }>
|
|
26
|
+
{ __( 'Unlink', 'elementor' ) }
|
|
27
|
+
</AlertAction>
|
|
28
|
+
) }
|
|
29
|
+
{ onRestore && (
|
|
30
|
+
<AlertAction variant="outlined" onClick={ onRestore }>
|
|
31
|
+
{ __( 'Restore', 'elementor' ) }
|
|
32
|
+
</AlertAction>
|
|
33
|
+
) }
|
|
34
|
+
</>
|
|
35
|
+
}
|
|
36
|
+
sx={ { width: sectionWidth } }
|
|
37
|
+
>
|
|
38
|
+
<AlertTitle>{ __( 'Deleted variable', 'elementor' ) }</AlertTitle>
|
|
39
|
+
{ __( 'The variable', 'elementor' ) } '{ label }'{ ' ' }
|
|
40
|
+
{ __(
|
|
41
|
+
'has been deleted, but it is still referenced in this location. You may restore the variable or unlink it to assign a different value.',
|
|
42
|
+
'elementor'
|
|
43
|
+
) }
|
|
44
|
+
</Alert>
|
|
45
|
+
</ClickAwayListener>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { AlertTriangleFilledIcon } from '@elementor/icons';
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Checkbox,
|
|
7
|
+
Dialog,
|
|
8
|
+
DialogActions,
|
|
9
|
+
DialogContent,
|
|
10
|
+
DialogContentText,
|
|
11
|
+
DialogTitle,
|
|
12
|
+
FormControlLabel,
|
|
13
|
+
Typography,
|
|
14
|
+
} from '@elementor/ui';
|
|
15
|
+
import { __ } from '@wordpress/i18n';
|
|
16
|
+
|
|
17
|
+
export const EDIT_CONFIRMATION_DIALOG_ID = 'edit-confirmation-dialog';
|
|
18
|
+
|
|
19
|
+
export const EditConfirmationDialog = ( {
|
|
20
|
+
closeDialog,
|
|
21
|
+
onConfirm,
|
|
22
|
+
onSuppressMessage,
|
|
23
|
+
}: {
|
|
24
|
+
closeDialog: () => void;
|
|
25
|
+
onConfirm?: () => void;
|
|
26
|
+
onSuppressMessage?: () => void;
|
|
27
|
+
} ) => {
|
|
28
|
+
const [ dontShowAgain, setDontShowAgain ] = useState( false );
|
|
29
|
+
|
|
30
|
+
const handleSave = () => {
|
|
31
|
+
if ( dontShowAgain ) {
|
|
32
|
+
onSuppressMessage?.();
|
|
33
|
+
}
|
|
34
|
+
onConfirm?.();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<Dialog open onClose={ closeDialog } maxWidth="xs">
|
|
39
|
+
<DialogTitle display="flex" alignItems="center" gap={ 1 }>
|
|
40
|
+
<AlertTriangleFilledIcon color="secondary" />
|
|
41
|
+
{ __( 'Changes to variables go live right away.', 'elementor' ) }
|
|
42
|
+
</DialogTitle>
|
|
43
|
+
<DialogContent>
|
|
44
|
+
<DialogContentText variant="body2" color="textPrimary">
|
|
45
|
+
{ __(
|
|
46
|
+
"Don't worry - all other changes you make will wait until you publish your site.",
|
|
47
|
+
'elementor'
|
|
48
|
+
) }
|
|
49
|
+
</DialogContentText>
|
|
50
|
+
</DialogContent>
|
|
51
|
+
<DialogActions sx={ { justifyContent: 'space-between', alignItems: 'center' } }>
|
|
52
|
+
<FormControlLabel
|
|
53
|
+
control={
|
|
54
|
+
<Checkbox
|
|
55
|
+
checked={ dontShowAgain }
|
|
56
|
+
onChange={ ( event: React.ChangeEvent< HTMLInputElement > ) =>
|
|
57
|
+
setDontShowAgain( event.target.checked )
|
|
58
|
+
}
|
|
59
|
+
size="small"
|
|
60
|
+
/>
|
|
61
|
+
}
|
|
62
|
+
label={ <Typography variant="body2">{ __( "Don't show me again", 'elementor' ) }</Typography> }
|
|
63
|
+
/>
|
|
64
|
+
<div>
|
|
65
|
+
<Button color="secondary" onClick={ closeDialog }>
|
|
66
|
+
{ __( 'Keep editing', 'elementor' ) }
|
|
67
|
+
</Button>
|
|
68
|
+
<Button variant="contained" color="secondary" onClick={ handleSave } sx={ { ml: 1 } }>
|
|
69
|
+
{ __( 'Save', 'elementor' ) }
|
|
70
|
+
</Button>
|
|
71
|
+
</div>
|
|
72
|
+
</DialogActions>
|
|
73
|
+
</Dialog>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useSectionWidth } from '@elementor/editor-editing-panel';
|
|
3
|
+
import { Alert, AlertAction, AlertTitle, ClickAwayListener } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
type MissingVariableAlertProps = {
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
onClear?: () => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const MissingVariableAlert = ( { onClose, onClear }: MissingVariableAlertProps ) => {
|
|
12
|
+
const sectionWidth = useSectionWidth();
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<ClickAwayListener onClickAway={ onClose }>
|
|
16
|
+
<Alert
|
|
17
|
+
variant="standard"
|
|
18
|
+
severity="warning"
|
|
19
|
+
onClose={ onClose }
|
|
20
|
+
action={
|
|
21
|
+
<>
|
|
22
|
+
{ onClear && (
|
|
23
|
+
<AlertAction variant="contained" onClick={ onClear }>
|
|
24
|
+
{ __( 'Clear', 'elementor' ) }
|
|
25
|
+
</AlertAction>
|
|
26
|
+
) }
|
|
27
|
+
</>
|
|
28
|
+
}
|
|
29
|
+
sx={ { width: sectionWidth } }
|
|
30
|
+
>
|
|
31
|
+
<AlertTitle>{ __( 'This variable is missing', 'elementor' ) }</AlertTitle>
|
|
32
|
+
{ __(
|
|
33
|
+
'It may have been deleted. Try clearing this field and select a different value or variable.',
|
|
34
|
+
'elementor'
|
|
35
|
+
) }
|
|
36
|
+
</Alert>
|
|
37
|
+
</ClickAwayListener>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -2,35 +2,68 @@ import * as React from 'react';
|
|
|
2
2
|
import { Button, Stack, Typography } from '@elementor/ui';
|
|
3
3
|
import { __ } from '@wordpress/i18n';
|
|
4
4
|
|
|
5
|
+
import { usePermissions } from '../../hooks/use-permissions';
|
|
6
|
+
|
|
5
7
|
type Props = {
|
|
6
8
|
icon?: React.ReactNode;
|
|
7
9
|
title?: string;
|
|
8
10
|
onAdd?: () => void;
|
|
9
11
|
};
|
|
10
12
|
|
|
11
|
-
export const NoVariables = ( { icon, title, onAdd }: Props ) =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
13
|
+
export const NoVariables = ( { icon, title, onAdd }: Props ) => {
|
|
14
|
+
const canAdd = usePermissions().canAdd();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Stack
|
|
18
|
+
gap={ 1 }
|
|
19
|
+
alignItems="center"
|
|
20
|
+
justifyContent="center"
|
|
21
|
+
height="100%"
|
|
22
|
+
color="text.secondary"
|
|
23
|
+
sx={ { p: 2.5, pb: 5.5 } }
|
|
24
|
+
>
|
|
25
|
+
{ icon }
|
|
26
|
+
|
|
27
|
+
{ canAdd ? (
|
|
28
|
+
<>
|
|
29
|
+
<NoVariablesContent
|
|
30
|
+
title={ title || __( 'Create your first variable', 'elementor' ) }
|
|
31
|
+
message={ __(
|
|
32
|
+
'Variables are saved attributes that you can apply anywhere on your site.',
|
|
33
|
+
'elementor'
|
|
34
|
+
) }
|
|
35
|
+
/>
|
|
36
|
+
{ onAdd && (
|
|
37
|
+
<Button variant="outlined" color="secondary" size="small" onClick={ onAdd }>
|
|
38
|
+
{ __( 'Create a variable', 'elementor' ) }
|
|
39
|
+
</Button>
|
|
40
|
+
) }
|
|
41
|
+
</>
|
|
42
|
+
) : (
|
|
43
|
+
<NoVariablesContent
|
|
44
|
+
title={ __( 'There are no variables', 'elementor' ) }
|
|
45
|
+
message={ __( 'With your current role, you can only connect and detach variables.', 'elementor' ) }
|
|
46
|
+
/>
|
|
47
|
+
) }
|
|
48
|
+
</Stack>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type NoVariablesContentProps = {
|
|
53
|
+
title: string;
|
|
54
|
+
message: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
function NoVariablesContent( { title, message }: NoVariablesContentProps ) {
|
|
58
|
+
return (
|
|
59
|
+
<>
|
|
60
|
+
<Typography align="center" variant="subtitle2">
|
|
61
|
+
{ title }
|
|
62
|
+
</Typography>
|
|
63
|
+
|
|
64
|
+
<Typography align="center" variant="caption" maxWidth="180px">
|
|
65
|
+
{ message }
|
|
66
|
+
</Typography>
|
|
67
|
+
</>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { DetachIcon } from '@elementor/icons';
|
|
3
|
-
import { Box, IconButton, Stack, Typography, UnstableTag as Tag, type UnstableTagProps } from '@elementor/ui';
|
|
3
|
+
import { Box, IconButton, Stack, Tooltip, Typography, UnstableTag as Tag, type UnstableTagProps } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
6
|
export const SIZE = 'tiny';
|
|
@@ -21,23 +21,25 @@ export const AssignedTag = ( { startIcon, label, onUnlink, ...props }: VariableT
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
24
|
+
<Tooltip title={ label } placement="top">
|
|
25
|
+
<Tag
|
|
26
|
+
fullWidth
|
|
27
|
+
showActionsOnHover
|
|
28
|
+
startIcon={
|
|
29
|
+
<Stack gap={ 0.5 } direction="row" alignItems="center">
|
|
30
|
+
{ startIcon }
|
|
31
|
+
</Stack>
|
|
32
|
+
}
|
|
33
|
+
label={
|
|
34
|
+
<Box sx={ { display: 'inline-grid', minWidth: 0 } }>
|
|
35
|
+
<Typography sx={ { lineHeight: 1.34 } } variant="caption" noWrap>
|
|
36
|
+
{ label }
|
|
37
|
+
</Typography>
|
|
38
|
+
</Box>
|
|
39
|
+
}
|
|
40
|
+
actions={ actions }
|
|
41
|
+
{ ...props }
|
|
42
|
+
/>
|
|
43
|
+
</Tooltip>
|
|
42
44
|
);
|
|
43
45
|
};
|
|
@@ -1,26 +1,37 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { Box,
|
|
2
|
+
import { AlertTriangleFilledIcon } from '@elementor/icons';
|
|
3
|
+
import { Box, Chip, type ChipProps, type Theme, Tooltip, Typography } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
|
-
export const DeletedTag = ( { label }
|
|
6
|
+
export const DeletedTag = React.forwardRef< HTMLDivElement, ChipProps >( ( { label, onClick, ...props }, ref ) => {
|
|
7
7
|
return (
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
<Chip
|
|
9
|
+
ref={ ref }
|
|
10
|
+
size="tiny"
|
|
11
|
+
color="warning"
|
|
12
|
+
shape="rounded"
|
|
13
|
+
variant="standard"
|
|
14
|
+
onClick={ onClick }
|
|
15
|
+
icon={ <AlertTriangleFilledIcon /> }
|
|
11
16
|
label={
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
</Typography>
|
|
17
|
+
<Tooltip title={ label } placement="top">
|
|
18
|
+
<Box sx={ { display: 'flex', gap: 0.5, alignItems: 'center' } }>
|
|
19
|
+
<Typography variant="caption" noWrap>
|
|
20
|
+
{ label }
|
|
21
|
+
</Typography>
|
|
22
|
+
<Typography variant="caption" noWrap sx={ { textOverflow: 'initial', overflow: 'visible' } }>
|
|
23
|
+
({ __( 'deleted', 'elementor' ) })
|
|
24
|
+
</Typography>
|
|
25
|
+
</Box>
|
|
26
|
+
</Tooltip>
|
|
23
27
|
}
|
|
28
|
+
sx={ {
|
|
29
|
+
height: ( theme: Theme ) => theme.spacing( 3.5 ),
|
|
30
|
+
borderRadius: ( theme: Theme ) => theme.spacing( 1 ),
|
|
31
|
+
justifyContent: 'flex-start',
|
|
32
|
+
width: '100%',
|
|
33
|
+
} }
|
|
34
|
+
{ ...props }
|
|
24
35
|
/>
|
|
25
36
|
);
|
|
26
|
-
};
|
|
37
|
+
} );
|