@elementor/editor-variables 0.15.0 → 0.18.0
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 +88 -0
- package/dist/index.js +894 -486
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +892 -511
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/components/color-variable-creation.tsx +37 -58
- package/src/components/color-variable-edit.tsx +110 -86
- package/src/components/color-variables-selection.tsx +32 -34
- package/src/components/fields/color-field.tsx +54 -0
- package/src/components/fields/font-field.tsx +85 -0
- package/src/components/fields/label-field.tsx +54 -0
- package/src/components/font-variable-creation.tsx +39 -78
- package/src/components/font-variable-edit.tsx +108 -114
- package/src/components/font-variables-selection.tsx +32 -34
- package/src/components/ui/delete-confirmation-dialog.tsx +52 -0
- package/src/components/ui/deleted-variable-alert.tsx +47 -0
- package/src/components/ui/menu-item-content.tsx +2 -5
- package/src/components/ui/tags/assigned-tag.tsx +45 -0
- package/src/components/ui/tags/deleted-tag.tsx +37 -0
- package/src/components/ui/variable/assigned-variable.tsx +70 -0
- package/src/components/ui/variable/deleted-variable.tsx +76 -0
- package/src/controls/color-variable-control.tsx +21 -48
- package/src/controls/font-variable-control.tsx +20 -43
- package/src/create-style-variables-repository.ts +44 -5
- package/src/hooks/use-prop-variables.ts +6 -0
- package/src/init-color-variables.ts +3 -48
- package/src/renderers/style-variables-renderer.tsx +10 -4
- package/src/repeater-injections.ts +35 -0
- package/src/service.ts +23 -2
- package/src/sync/enqueue-font.ts +7 -0
- package/src/sync/types.ts +5 -0
- package/src/transformers/variable-transformer.ts +21 -3
- package/src/types.ts +1 -1
- package/src/utils/validations.ts +42 -0
- package/src/components/ui/variable-tag.tsx +0 -43
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useId, useState } from 'react';
|
|
3
|
+
import { FormHelperText, FormLabel, Grid, TextField } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
import { labelHint, validateLabel, VARIABLE_LABEL_MAX_LENGTH } from '../../utils/validations';
|
|
7
|
+
|
|
8
|
+
type LabelFieldProps = {
|
|
9
|
+
value: string;
|
|
10
|
+
onChange: ( value: string ) => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const LabelField = ( { value, onChange }: LabelFieldProps ) => {
|
|
14
|
+
const [ label, setLabel ] = useState( value );
|
|
15
|
+
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
16
|
+
const [ noticeMessage, setNoticeMessage ] = useState( () => labelHint( value ) );
|
|
17
|
+
|
|
18
|
+
const handleChange = ( newValue: string ) => {
|
|
19
|
+
setLabel( newValue );
|
|
20
|
+
|
|
21
|
+
const errorMsg = validateLabel( newValue );
|
|
22
|
+
const hintMsg = labelHint( newValue );
|
|
23
|
+
|
|
24
|
+
setErrorMessage( errorMsg );
|
|
25
|
+
setNoticeMessage( errorMsg ? '' : hintMsg );
|
|
26
|
+
|
|
27
|
+
onChange( errorMsg ? '' : newValue );
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const id = useId();
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Grid container gap={ 0.75 } alignItems="center">
|
|
34
|
+
<Grid item xs={ 12 }>
|
|
35
|
+
<FormLabel htmlFor={ id } size="tiny">
|
|
36
|
+
{ __( 'Name', 'elementor' ) }
|
|
37
|
+
</FormLabel>
|
|
38
|
+
</Grid>
|
|
39
|
+
<Grid item xs={ 12 }>
|
|
40
|
+
<TextField
|
|
41
|
+
id={ id }
|
|
42
|
+
size="tiny"
|
|
43
|
+
fullWidth
|
|
44
|
+
value={ label }
|
|
45
|
+
error={ !! errorMessage }
|
|
46
|
+
onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => handleChange( e.target.value ) }
|
|
47
|
+
inputProps={ { maxLength: VARIABLE_LABEL_MAX_LENGTH } }
|
|
48
|
+
/>
|
|
49
|
+
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
50
|
+
{ noticeMessage && <FormHelperText>{ noticeMessage }</FormHelperText> }
|
|
51
|
+
</Grid>
|
|
52
|
+
</Grid>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
|
+
import { PopoverBody } from '@elementor/editor-editing-panel';
|
|
5
5
|
import { PopoverHeader } from '@elementor/editor-ui';
|
|
6
|
-
import { ArrowLeftIcon,
|
|
7
|
-
import {
|
|
8
|
-
bindPopover,
|
|
9
|
-
bindTrigger,
|
|
10
|
-
Button,
|
|
11
|
-
CardActions,
|
|
12
|
-
Divider,
|
|
13
|
-
FormLabel,
|
|
14
|
-
Grid,
|
|
15
|
-
IconButton,
|
|
16
|
-
Popover,
|
|
17
|
-
TextField,
|
|
18
|
-
UnstableTag,
|
|
19
|
-
usePopupState,
|
|
20
|
-
} from '@elementor/ui';
|
|
6
|
+
import { ArrowLeftIcon, TextIcon } from '@elementor/icons';
|
|
7
|
+
import { Button, CardActions, Divider, FormHelperText, IconButton } from '@elementor/ui';
|
|
21
8
|
import { __ } from '@wordpress/i18n';
|
|
22
9
|
|
|
23
10
|
import { createVariable } from '../hooks/use-prop-variables';
|
|
24
11
|
import { fontVariablePropTypeUtil } from '../prop-types/font-variable-prop-type';
|
|
12
|
+
import { FontField } from './fields/font-field';
|
|
13
|
+
import { LabelField } from './fields/label-field';
|
|
25
14
|
|
|
26
15
|
const SIZE = 'tiny';
|
|
27
16
|
|
|
@@ -31,18 +20,16 @@ type Props = {
|
|
|
31
20
|
};
|
|
32
21
|
|
|
33
22
|
export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
|
|
34
|
-
const fontFamilies = useFontFamilies();
|
|
35
23
|
const { setValue: setVariable } = useBoundProp( fontVariablePropTypeUtil );
|
|
36
24
|
|
|
37
25
|
const [ fontFamily, setFontFamily ] = useState( '' );
|
|
38
26
|
const [ label, setLabel ] = useState( '' );
|
|
39
|
-
|
|
40
|
-
const anchorRef = useRef< HTMLDivElement >( null );
|
|
41
|
-
const fontPopoverState = usePopupState( { variant: 'popover' } );
|
|
27
|
+
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
42
28
|
|
|
43
29
|
const resetFields = () => {
|
|
44
30
|
setFontFamily( '' );
|
|
45
31
|
setLabel( '' );
|
|
32
|
+
setErrorMessage( '' );
|
|
46
33
|
};
|
|
47
34
|
|
|
48
35
|
const closePopover = () => {
|
|
@@ -55,20 +42,24 @@ export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
|
|
|
55
42
|
value: fontFamily,
|
|
56
43
|
label,
|
|
57
44
|
type: fontVariablePropTypeUtil.key,
|
|
58
|
-
} )
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
} )
|
|
46
|
+
.then( ( key ) => {
|
|
47
|
+
setVariable( key );
|
|
48
|
+
closePopover();
|
|
49
|
+
} )
|
|
50
|
+
.catch( ( error ) => {
|
|
51
|
+
setErrorMessage( error.message );
|
|
52
|
+
} );
|
|
62
53
|
};
|
|
63
54
|
|
|
64
|
-
const
|
|
65
|
-
return
|
|
55
|
+
const hasEmptyValue = () => {
|
|
56
|
+
return '' === fontFamily.trim() || '' === label.trim();
|
|
66
57
|
};
|
|
67
58
|
|
|
68
|
-
const
|
|
59
|
+
const isSubmitDisabled = hasEmptyValue();
|
|
69
60
|
|
|
70
61
|
return (
|
|
71
|
-
<
|
|
62
|
+
<PopoverBody height="auto">
|
|
72
63
|
<PopoverHeader
|
|
73
64
|
icon={
|
|
74
65
|
<>
|
|
@@ -87,59 +78,29 @@ export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
|
|
|
87
78
|
<Divider />
|
|
88
79
|
|
|
89
80
|
<PopoverContent p={ 2 }>
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<FormLabel size="tiny">{ __( 'Value', 'elementor' ) }</FormLabel>
|
|
107
|
-
</Grid>
|
|
108
|
-
<Grid item xs={ 12 }>
|
|
109
|
-
<>
|
|
110
|
-
<UnstableTag
|
|
111
|
-
variant="outlined"
|
|
112
|
-
label={ fontFamily }
|
|
113
|
-
endIcon={ <ChevronDownIcon fontSize="tiny" /> }
|
|
114
|
-
{ ...bindTrigger( fontPopoverState ) }
|
|
115
|
-
fullWidth
|
|
116
|
-
/>
|
|
117
|
-
<Popover
|
|
118
|
-
disablePortal
|
|
119
|
-
disableScrollLock
|
|
120
|
-
anchorEl={ anchorRef.current }
|
|
121
|
-
anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
122
|
-
transformOrigin={ { vertical: 'top', horizontal: -20 } }
|
|
123
|
-
{ ...bindPopover( fontPopoverState ) }
|
|
124
|
-
>
|
|
125
|
-
<FontFamilySelector
|
|
126
|
-
fontFamilies={ fontFamilies }
|
|
127
|
-
fontFamily={ fontFamily }
|
|
128
|
-
onFontFamilyChange={ setFontFamily }
|
|
129
|
-
onClose={ fontPopoverState.close }
|
|
130
|
-
sectionWidth={ sectionWidth }
|
|
131
|
-
/>
|
|
132
|
-
</Popover>
|
|
133
|
-
</>
|
|
134
|
-
</Grid>
|
|
135
|
-
</Grid>
|
|
81
|
+
<LabelField
|
|
82
|
+
value={ label }
|
|
83
|
+
onChange={ ( value ) => {
|
|
84
|
+
setLabel( value );
|
|
85
|
+
setErrorMessage( '' );
|
|
86
|
+
} }
|
|
87
|
+
/>
|
|
88
|
+
<FontField
|
|
89
|
+
value={ fontFamily }
|
|
90
|
+
onChange={ ( value ) => {
|
|
91
|
+
setFontFamily( value );
|
|
92
|
+
setErrorMessage( '' );
|
|
93
|
+
} }
|
|
94
|
+
/>
|
|
95
|
+
|
|
96
|
+
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
136
97
|
</PopoverContent>
|
|
137
98
|
|
|
138
99
|
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
139
|
-
<Button size="small" variant="contained" disabled={
|
|
100
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleCreate }>
|
|
140
101
|
{ __( 'Create', 'elementor' ) }
|
|
141
102
|
</Button>
|
|
142
103
|
</CardActions>
|
|
143
|
-
</
|
|
104
|
+
</PopoverBody>
|
|
144
105
|
);
|
|
145
106
|
};
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { PopoverHeader
|
|
6
|
-
import { ArrowLeftIcon,
|
|
7
|
-
import {
|
|
8
|
-
bindPopover,
|
|
9
|
-
bindTrigger,
|
|
10
|
-
Button,
|
|
11
|
-
CardActions,
|
|
12
|
-
Divider,
|
|
13
|
-
FormLabel,
|
|
14
|
-
Grid,
|
|
15
|
-
IconButton,
|
|
16
|
-
Popover,
|
|
17
|
-
TextField,
|
|
18
|
-
UnstableTag,
|
|
19
|
-
usePopupState,
|
|
20
|
-
} from '@elementor/ui';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
|
+
import { PopoverBody } from '@elementor/editor-editing-panel';
|
|
5
|
+
import { PopoverHeader } from '@elementor/editor-ui';
|
|
6
|
+
import { ArrowLeftIcon, TextIcon, TrashIcon } from '@elementor/icons';
|
|
7
|
+
import { Button, CardActions, Divider, FormHelperText, IconButton } from '@elementor/ui';
|
|
21
8
|
import { __ } from '@wordpress/i18n';
|
|
22
9
|
|
|
23
10
|
import { deleteVariable, updateVariable, useVariable } from '../hooks/use-prop-variables';
|
|
11
|
+
import { fontVariablePropTypeUtil } from '../prop-types/font-variable-prop-type';
|
|
12
|
+
import { FontField } from './fields/font-field';
|
|
13
|
+
import { LabelField } from './fields/label-field';
|
|
14
|
+
import { DeleteConfirmationDialog } from './ui/delete-confirmation-dialog';
|
|
24
15
|
|
|
25
16
|
const SIZE = 'tiny';
|
|
26
17
|
|
|
@@ -32,8 +23,11 @@ type Props = {
|
|
|
32
23
|
};
|
|
33
24
|
|
|
34
25
|
export const FontVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props ) => {
|
|
35
|
-
const
|
|
26
|
+
const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp( fontVariablePropTypeUtil );
|
|
27
|
+
const [ deleteConfirmation, setDeleteConfirmation ] = useState( false );
|
|
28
|
+
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
36
29
|
|
|
30
|
+
const variable = useVariable( editId );
|
|
37
31
|
if ( ! variable ) {
|
|
38
32
|
throw new Error( `Global font variable "${ editId }" not found` );
|
|
39
33
|
}
|
|
@@ -41,123 +35,123 @@ export const FontVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props
|
|
|
41
35
|
const [ fontFamily, setFontFamily ] = useState( variable.value );
|
|
42
36
|
const [ label, setLabel ] = useState( variable.label );
|
|
43
37
|
|
|
44
|
-
const variableNameId = useId();
|
|
45
|
-
const variableValueId = useId();
|
|
46
|
-
|
|
47
|
-
const anchorRef = useRef< HTMLDivElement >( null );
|
|
48
|
-
const fontPopoverState = usePopupState( { variant: 'popover' } );
|
|
49
|
-
|
|
50
|
-
const fontFamilies = useFontFamilies();
|
|
51
|
-
|
|
52
38
|
const handleUpdate = () => {
|
|
53
39
|
updateVariable( editId, {
|
|
54
40
|
value: fontFamily,
|
|
55
41
|
label,
|
|
56
|
-
} )
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
} )
|
|
43
|
+
.then( () => {
|
|
44
|
+
maybeTriggerBoundPropChange();
|
|
45
|
+
onSubmit?.();
|
|
46
|
+
} )
|
|
47
|
+
.catch( ( error ) => {
|
|
48
|
+
setErrorMessage( error.message );
|
|
49
|
+
} );
|
|
59
50
|
};
|
|
60
51
|
|
|
61
52
|
const handleDelete = () => {
|
|
62
53
|
deleteVariable( editId ).then( () => {
|
|
54
|
+
maybeTriggerBoundPropChange();
|
|
63
55
|
onSubmit?.();
|
|
64
56
|
} );
|
|
65
57
|
};
|
|
66
58
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
const maybeTriggerBoundPropChange = () => {
|
|
60
|
+
if ( editId === assignedValue ) {
|
|
61
|
+
notifyBoundPropChange( editId );
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const handleDeleteConfirmation = () => {
|
|
66
|
+
setDeleteConfirmation( true );
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const closeDeleteDialog = () => () => {
|
|
70
|
+
setDeleteConfirmation( false );
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const hasEmptyValue = () => {
|
|
74
|
+
return ! fontFamily.trim() || ! label.trim();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const noValueChanged = () => {
|
|
78
|
+
return fontFamily === variable.value && label === variable.label;
|
|
79
|
+
};
|
|
70
80
|
|
|
71
|
-
const
|
|
81
|
+
const isSubmitDisabled = noValueChanged() || hasEmptyValue();
|
|
72
82
|
|
|
73
83
|
const actions = [];
|
|
74
84
|
|
|
75
85
|
actions.push(
|
|
76
|
-
<IconButton
|
|
86
|
+
<IconButton
|
|
87
|
+
key="delete"
|
|
88
|
+
size={ SIZE }
|
|
89
|
+
aria-label={ __( 'Delete', 'elementor' ) }
|
|
90
|
+
onClick={ handleDeleteConfirmation }
|
|
91
|
+
>
|
|
77
92
|
<TrashIcon fontSize={ SIZE } />
|
|
78
93
|
</IconButton>
|
|
79
94
|
);
|
|
80
95
|
|
|
81
96
|
return (
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{ onGoBack && (
|
|
87
|
-
<IconButton size={ SIZE } aria-label={ __( 'Go Back', 'elementor' ) } onClick={ onGoBack }>
|
|
88
|
-
<ArrowLeftIcon fontSize={ SIZE } />
|
|
89
|
-
</IconButton>
|
|
90
|
-
) }
|
|
91
|
-
<TextIcon fontSize={ SIZE } />
|
|
92
|
-
</>
|
|
93
|
-
}
|
|
94
|
-
title={ __( 'Edit variable', 'elementor' ) }
|
|
95
|
-
onClose={ onClose }
|
|
96
|
-
actions={ actions }
|
|
97
|
-
/>
|
|
98
|
-
|
|
99
|
-
<Divider />
|
|
100
|
-
|
|
101
|
-
<PopoverContent p={ 2 }>
|
|
102
|
-
<Grid container gap={ 0.75 } alignItems="center">
|
|
103
|
-
<Grid item xs={ 12 }>
|
|
104
|
-
<FormLabel htmlFor={ variableNameId } size="tiny">
|
|
105
|
-
{ __( 'Name', 'elementor' ) }
|
|
106
|
-
</FormLabel>
|
|
107
|
-
</Grid>
|
|
108
|
-
<Grid item xs={ 12 }>
|
|
109
|
-
<TextField
|
|
110
|
-
id={ variableNameId }
|
|
111
|
-
size="tiny"
|
|
112
|
-
fullWidth
|
|
113
|
-
value={ label }
|
|
114
|
-
onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
|
|
115
|
-
/>
|
|
116
|
-
</Grid>
|
|
117
|
-
</Grid>
|
|
118
|
-
|
|
119
|
-
<Grid container gap={ 0.75 } alignItems="center">
|
|
120
|
-
<Grid item xs={ 12 }>
|
|
121
|
-
<FormLabel htmlFor={ variableValueId } size="tiny">
|
|
122
|
-
{ __( 'Value', 'elementor' ) }
|
|
123
|
-
</FormLabel>
|
|
124
|
-
</Grid>
|
|
125
|
-
<Grid item xs={ 12 }>
|
|
97
|
+
<>
|
|
98
|
+
<PopoverBody height="auto">
|
|
99
|
+
<PopoverHeader
|
|
100
|
+
icon={
|
|
126
101
|
<>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
disableScrollLock
|
|
138
|
-
anchorEl={ anchorRef.current }
|
|
139
|
-
anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
140
|
-
transformOrigin={ { vertical: 'top', horizontal: -20 } }
|
|
141
|
-
{ ...bindPopover( fontPopoverState ) }
|
|
142
|
-
>
|
|
143
|
-
<FontFamilySelector
|
|
144
|
-
fontFamilies={ fontFamilies }
|
|
145
|
-
fontFamily={ fontFamily }
|
|
146
|
-
onFontFamilyChange={ setFontFamily }
|
|
147
|
-
onClose={ fontPopoverState.close }
|
|
148
|
-
sectionWidth={ sectionWidth }
|
|
149
|
-
/>
|
|
150
|
-
</Popover>
|
|
102
|
+
{ onGoBack && (
|
|
103
|
+
<IconButton
|
|
104
|
+
size={ SIZE }
|
|
105
|
+
aria-label={ __( 'Go Back', 'elementor' ) }
|
|
106
|
+
onClick={ onGoBack }
|
|
107
|
+
>
|
|
108
|
+
<ArrowLeftIcon fontSize={ SIZE } />
|
|
109
|
+
</IconButton>
|
|
110
|
+
) }
|
|
111
|
+
<TextIcon fontSize={ SIZE } />
|
|
151
112
|
</>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
113
|
+
}
|
|
114
|
+
title={ __( 'Edit variable', 'elementor' ) }
|
|
115
|
+
onClose={ onClose }
|
|
116
|
+
actions={ actions }
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
<Divider />
|
|
120
|
+
|
|
121
|
+
<PopoverContent p={ 2 }>
|
|
122
|
+
<LabelField
|
|
123
|
+
value={ label }
|
|
124
|
+
onChange={ ( value ) => {
|
|
125
|
+
setLabel( value );
|
|
126
|
+
setErrorMessage( '' );
|
|
127
|
+
} }
|
|
128
|
+
/>
|
|
129
|
+
<FontField
|
|
130
|
+
value={ fontFamily }
|
|
131
|
+
onChange={ ( value ) => {
|
|
132
|
+
setFontFamily( value );
|
|
133
|
+
setErrorMessage( '' );
|
|
134
|
+
} }
|
|
135
|
+
/>
|
|
136
|
+
|
|
137
|
+
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
138
|
+
</PopoverContent>
|
|
139
|
+
|
|
140
|
+
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
141
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleUpdate }>
|
|
142
|
+
{ __( 'Save', 'elementor' ) }
|
|
143
|
+
</Button>
|
|
144
|
+
</CardActions>
|
|
145
|
+
</PopoverBody>
|
|
146
|
+
|
|
147
|
+
{ deleteConfirmation && (
|
|
148
|
+
<DeleteConfirmationDialog
|
|
149
|
+
open
|
|
150
|
+
label={ label }
|
|
151
|
+
onConfirm={ handleDelete }
|
|
152
|
+
closeDialog={ closeDeleteDialog() }
|
|
153
|
+
/>
|
|
154
|
+
) }
|
|
155
|
+
</>
|
|
162
156
|
);
|
|
163
157
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useBoundProp } from '@elementor/editor-controls';
|
|
4
|
-
import {
|
|
4
|
+
import { PopoverBody } from '@elementor/editor-editing-panel';
|
|
5
5
|
import { PopoverHeader, PopoverMenuList, PopoverSearch, type VirtualizedItem } from '@elementor/editor-ui';
|
|
6
6
|
import { ColorFilterIcon, PlusIcon, SettingsIcon, TextIcon } from '@elementor/icons';
|
|
7
7
|
import { Divider, IconButton } from '@elementor/ui';
|
|
@@ -75,7 +75,7 @@ export const FontVariablesSelection = ( { closePopover, onAdd, onEdit, onSetting
|
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
return (
|
|
78
|
-
|
|
78
|
+
<PopoverBody>
|
|
79
79
|
<PopoverHeader
|
|
80
80
|
title={ __( 'Variables', 'elementor' ) }
|
|
81
81
|
onClose={ closePopover }
|
|
@@ -93,37 +93,35 @@ export const FontVariablesSelection = ( { closePopover, onAdd, onEdit, onSetting
|
|
|
93
93
|
|
|
94
94
|
<Divider />
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
</PopoverScrollableContent>
|
|
127
|
-
</>
|
|
96
|
+
{ hasVariables && hasSearchResults && (
|
|
97
|
+
<PopoverMenuList
|
|
98
|
+
items={ items }
|
|
99
|
+
onSelect={ handleSetVariable }
|
|
100
|
+
onClose={ () => {} }
|
|
101
|
+
selectedValue={ variable }
|
|
102
|
+
data-testid="font-variables-list"
|
|
103
|
+
menuListTemplate={ VariablesStyledMenuList }
|
|
104
|
+
menuItemContentTemplate={ ( item: VirtualizedItem< 'item', string > ) => (
|
|
105
|
+
<MenuItemContent item={ item } />
|
|
106
|
+
) }
|
|
107
|
+
/>
|
|
108
|
+
) }
|
|
109
|
+
|
|
110
|
+
{ ! hasSearchResults && hasVariables && (
|
|
111
|
+
<NoSearchResults
|
|
112
|
+
searchValue={ searchValue }
|
|
113
|
+
onClear={ handleClearSearch }
|
|
114
|
+
icon={ <TextIcon fontSize="large" /> }
|
|
115
|
+
/>
|
|
116
|
+
) }
|
|
117
|
+
|
|
118
|
+
{ ! hasVariables && (
|
|
119
|
+
<NoVariables
|
|
120
|
+
title={ __( 'Create your first font variable', 'elementor' ) }
|
|
121
|
+
icon={ <TextIcon fontSize="large" /> }
|
|
122
|
+
onAdd={ onAdd }
|
|
123
|
+
/>
|
|
124
|
+
) }
|
|
125
|
+
</PopoverBody>
|
|
128
126
|
);
|
|
129
127
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { AlertOctagonFilledIcon } from '@elementor/icons';
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Dialog,
|
|
6
|
+
DialogActions,
|
|
7
|
+
DialogContent,
|
|
8
|
+
DialogContentText,
|
|
9
|
+
DialogTitle,
|
|
10
|
+
Typography,
|
|
11
|
+
} from '@elementor/ui';
|
|
12
|
+
import { __ } from '@wordpress/i18n';
|
|
13
|
+
|
|
14
|
+
const TITLE_ID = 'delete-variable-dialog';
|
|
15
|
+
|
|
16
|
+
export const DeleteConfirmationDialog = ( {
|
|
17
|
+
open,
|
|
18
|
+
label,
|
|
19
|
+
closeDialog,
|
|
20
|
+
onConfirm,
|
|
21
|
+
}: {
|
|
22
|
+
open: boolean;
|
|
23
|
+
label: string;
|
|
24
|
+
closeDialog: () => void;
|
|
25
|
+
onConfirm: () => void;
|
|
26
|
+
} ) => {
|
|
27
|
+
return (
|
|
28
|
+
<Dialog open={ open } onClose={ closeDialog } aria-labelledby={ TITLE_ID } maxWidth="xs">
|
|
29
|
+
<DialogTitle id={ TITLE_ID } display="flex" alignItems="center" gap={ 1 } sx={ { lineHeight: 1 } }>
|
|
30
|
+
<AlertOctagonFilledIcon color="error" />
|
|
31
|
+
{ __( 'Delete this variable?', 'elementor' ) }
|
|
32
|
+
</DialogTitle>
|
|
33
|
+
<DialogContent>
|
|
34
|
+
<DialogContentText variant="body2" color="textPrimary">
|
|
35
|
+
{ __( 'All elements using', 'elementor' ) }
|
|
36
|
+
<Typography variant="subtitle2" component="span">
|
|
37
|
+
{ label }
|
|
38
|
+
</Typography>
|
|
39
|
+
{ __( 'will keep their current values, but the variable itself will be removed.', 'elementor' ) }
|
|
40
|
+
</DialogContentText>
|
|
41
|
+
</DialogContent>
|
|
42
|
+
<DialogActions>
|
|
43
|
+
<Button color="secondary" onClick={ closeDialog }>
|
|
44
|
+
{ __( 'Not now', 'elementor' ) }
|
|
45
|
+
</Button>
|
|
46
|
+
<Button variant="contained" color="error" onClick={ onConfirm }>
|
|
47
|
+
{ __( 'Delete', 'elementor' ) }
|
|
48
|
+
</Button>
|
|
49
|
+
</DialogActions>
|
|
50
|
+
</Dialog>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -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
|
+
};
|