@elementor/editor-variables 0.18.0 → 3.32.0-21
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 +0 -28
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +1282 -1026
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1262 -990
- 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/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/missing-tag.tsx +25 -0
- package/src/components/ui/variable/assigned-variable.tsx +11 -14
- package/src/components/ui/variable/deleted-variable.tsx +102 -50
- package/src/components/ui/variable/missing-variable.tsx +44 -0
- package/src/components/{color-variable-creation.tsx → variable-creation.tsx} +51 -22
- 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/{font-variables-selection.tsx → variables-selection.tsx} +38 -17
- 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/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 +2 -2
- package/src/index.ts +1 -0
- package/src/init.ts +33 -4
- package/src/register-variable-types.tsx +29 -0
- package/src/repeater-injections.ts +5 -1
- package/src/service.ts +2 -19
- package/src/transformers/inheritance-transformer.tsx +30 -0
- package/src/transformers/utils/resolve-css-variable.ts +24 -0
- package/src/transformers/variable-transformer.ts +3 -16
- 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-edit.tsx +0 -157
- package/src/components/color-variables-selection.tsx +0 -128
- package/src/components/font-variable-creation.tsx +0 -106
- package/src/components/font-variable-edit.tsx +0 -157
- package/src/components/variable-selection-popover.context.ts +0 -7
- package/src/controls/color-variable-control.tsx +0 -39
- package/src/controls/font-variable-control.tsx +0 -37
- 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
|
@@ -1,76 +1,128 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useId, useRef, useState } from 'react';
|
|
3
3
|
import { useBoundProp } from '@elementor/editor-controls';
|
|
4
|
-
import { type
|
|
5
|
-
import {
|
|
6
|
-
import { Backdrop, Infotip } from '@elementor/ui';
|
|
4
|
+
import { type PropTypeKey } from '@elementor/editor-props';
|
|
5
|
+
import { Backdrop, bindPopover, Box, Infotip, Popover, usePopupState } from '@elementor/ui';
|
|
7
6
|
|
|
7
|
+
import { VariableTypeProvider } from '../../../context/variable-type-context';
|
|
8
|
+
import { usePermissions } from '../../../hooks/use-permissions';
|
|
8
9
|
import { restoreVariable } from '../../../hooks/use-prop-variables';
|
|
9
10
|
import { type Variable } from '../../../types';
|
|
11
|
+
import { getVariableType } from '../../../variables-registry/variable-type-registry';
|
|
12
|
+
import { VariableRestore } from '../../variable-restore';
|
|
10
13
|
import { DeletedVariableAlert } from '../deleted-variable-alert';
|
|
11
14
|
import { DeletedTag } from '../tags/deleted-tag';
|
|
12
15
|
|
|
13
|
-
const isV331Active = isExperimentActive( 'e_v_3_31' );
|
|
14
|
-
|
|
15
16
|
type Props = {
|
|
16
17
|
variable: Variable;
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
propTypeKey: PropTypeKey;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type Handlers = {
|
|
22
|
+
onUnlink?: () => void;
|
|
23
|
+
onRestore?: () => void;
|
|
19
24
|
};
|
|
20
25
|
|
|
21
|
-
export const DeletedVariable = ( { variable,
|
|
26
|
+
export const DeletedVariable = ( { variable, propTypeKey }: Props ) => {
|
|
27
|
+
const { fallbackPropTypeUtil, propTypeUtil } = getVariableType( propTypeKey );
|
|
28
|
+
|
|
22
29
|
const { setValue } = useBoundProp();
|
|
23
|
-
const [ showInfotip, setShowInfotip ] = useState< boolean >( false );
|
|
24
30
|
|
|
25
|
-
const
|
|
31
|
+
const userPermissions = usePermissions();
|
|
26
32
|
|
|
33
|
+
const [ showInfotip, setShowInfotip ] = useState< boolean >( false );
|
|
34
|
+
const toggleInfotip = () => setShowInfotip( ( prev ) => ! prev );
|
|
27
35
|
const closeInfotip = () => setShowInfotip( false );
|
|
28
36
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
const deletedChipAnchorRef = useRef< HTMLDivElement >( null );
|
|
38
|
+
|
|
39
|
+
const popupId = useId();
|
|
40
|
+
const popupState = usePopupState( {
|
|
41
|
+
variant: 'popover',
|
|
42
|
+
popupId: `elementor-variables-restore-${ popupId }`,
|
|
43
|
+
} );
|
|
44
|
+
|
|
45
|
+
const handlers: Handlers = {};
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
47
|
+
if ( userPermissions.canUnlink() ) {
|
|
48
|
+
handlers.onUnlink = () => {
|
|
49
|
+
setValue( fallbackPropTypeUtil.create( variable.value ) );
|
|
50
|
+
};
|
|
51
|
+
}
|
|
37
52
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
if ( userPermissions.canRestore() ) {
|
|
54
|
+
handlers.onRestore = () => {
|
|
55
|
+
if ( ! variable.key ) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
restoreVariable( variable.key )
|
|
60
|
+
.then( ( key ) => {
|
|
61
|
+
setValue( propTypeUtil.create( key ) );
|
|
62
|
+
closeInfotip();
|
|
63
|
+
} )
|
|
64
|
+
.catch( () => {
|
|
65
|
+
closeInfotip();
|
|
66
|
+
popupState.setAnchorEl( deletedChipAnchorRef.current );
|
|
67
|
+
popupState.open();
|
|
68
|
+
} );
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const handleRestoreWithOverrides = () => {
|
|
73
|
+
popupState.close();
|
|
42
74
|
};
|
|
43
75
|
|
|
44
76
|
return (
|
|
45
77
|
<>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
<Box ref={ deletedChipAnchorRef }>
|
|
79
|
+
{ showInfotip && <Backdrop open onClick={ closeInfotip } invisible /> }
|
|
80
|
+
<Infotip
|
|
81
|
+
color="warning"
|
|
82
|
+
placement="right-start"
|
|
83
|
+
open={ showInfotip }
|
|
84
|
+
disableHoverListener
|
|
85
|
+
onClose={ closeInfotip }
|
|
86
|
+
content={
|
|
87
|
+
<DeletedVariableAlert
|
|
88
|
+
onClose={ closeInfotip }
|
|
89
|
+
onUnlink={ handlers.onUnlink }
|
|
90
|
+
onRestore={ handlers.onRestore }
|
|
91
|
+
label={ variable.label }
|
|
92
|
+
/>
|
|
93
|
+
}
|
|
94
|
+
slotProps={ {
|
|
95
|
+
popper: {
|
|
96
|
+
modifiers: [
|
|
97
|
+
{
|
|
98
|
+
name: 'offset',
|
|
99
|
+
options: { offset: [ 0, 24 ] },
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
} }
|
|
104
|
+
>
|
|
105
|
+
<DeletedTag label={ variable.label } onClick={ toggleInfotip } />
|
|
106
|
+
</Infotip>
|
|
107
|
+
|
|
108
|
+
<Popover
|
|
109
|
+
disableScrollLock
|
|
110
|
+
anchorOrigin={ { vertical: 'bottom', horizontal: 'right' } }
|
|
111
|
+
transformOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
112
|
+
PaperProps={ {
|
|
113
|
+
sx: { my: 1 },
|
|
114
|
+
} }
|
|
115
|
+
{ ...bindPopover( popupState ) }
|
|
116
|
+
>
|
|
117
|
+
<VariableTypeProvider propTypeKey={ propTypeKey }>
|
|
118
|
+
<VariableRestore
|
|
119
|
+
variableId={ variable.key ?? '' }
|
|
120
|
+
onClose={ popupState.close }
|
|
121
|
+
onSubmit={ handleRestoreWithOverrides }
|
|
122
|
+
/>
|
|
123
|
+
</VariableTypeProvider>
|
|
124
|
+
</Popover>
|
|
125
|
+
</Box>
|
|
74
126
|
</>
|
|
75
127
|
);
|
|
76
128
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useBoundProp } from '@elementor/editor-controls';
|
|
4
|
+
import { Backdrop, Infotip } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
import { MissingVariableAlert } from '../missing-variable-alert';
|
|
8
|
+
import { MissingTag } from '../tags/missing-tag';
|
|
9
|
+
|
|
10
|
+
export const MissingVariable = () => {
|
|
11
|
+
const { setValue } = useBoundProp();
|
|
12
|
+
|
|
13
|
+
const [ infotipVisible, setInfotipVisible ] = useState< boolean >( false );
|
|
14
|
+
const toggleInfotip = () => setInfotipVisible( ( prev ) => ! prev );
|
|
15
|
+
const closeInfotip = () => setInfotipVisible( false );
|
|
16
|
+
|
|
17
|
+
const clearValue = () => setValue( null );
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
{ infotipVisible && <Backdrop open onClick={ closeInfotip } invisible /> }
|
|
22
|
+
<Infotip
|
|
23
|
+
color="warning"
|
|
24
|
+
placement="right-start"
|
|
25
|
+
open={ infotipVisible }
|
|
26
|
+
disableHoverListener
|
|
27
|
+
onClose={ closeInfotip }
|
|
28
|
+
content={ <MissingVariableAlert onClose={ closeInfotip } onClear={ clearValue } /> }
|
|
29
|
+
slotProps={ {
|
|
30
|
+
popper: {
|
|
31
|
+
modifiers: [
|
|
32
|
+
{
|
|
33
|
+
name: 'offset',
|
|
34
|
+
options: { offset: [ 0, 24 ] },
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
} }
|
|
39
|
+
>
|
|
40
|
+
<MissingTag label={ __( 'Missing variable', 'elementor' ) } onClick={ toggleInfotip } />
|
|
41
|
+
</Infotip>
|
|
42
|
+
</>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
@@ -3,14 +3,16 @@ import { useState } from 'react';
|
|
|
3
3
|
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
4
|
import { PopoverBody } from '@elementor/editor-editing-panel';
|
|
5
5
|
import { PopoverHeader } from '@elementor/editor-ui';
|
|
6
|
-
import { ArrowLeftIcon
|
|
6
|
+
import { ArrowLeftIcon } from '@elementor/icons';
|
|
7
7
|
import { Button, CardActions, Divider, FormHelperText, IconButton } from '@elementor/ui';
|
|
8
8
|
import { __ } from '@wordpress/i18n';
|
|
9
9
|
|
|
10
|
+
import { useVariableType } from '../context/variable-type-context';
|
|
11
|
+
import { useInitialValue } from '../hooks/use-initial-value';
|
|
10
12
|
import { createVariable } from '../hooks/use-prop-variables';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { LabelField } from './fields/label-field';
|
|
13
|
+
import { trackVariableEvent } from '../utils/tracking';
|
|
14
|
+
import { ERROR_MESSAGES, mapServerError } from '../utils/validations';
|
|
15
|
+
import { LabelField, useLabelError } from './fields/label-field';
|
|
14
16
|
|
|
15
17
|
const SIZE = 'tiny';
|
|
16
18
|
|
|
@@ -19,15 +21,21 @@ type Props = {
|
|
|
19
21
|
onClose: () => void;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
export const
|
|
23
|
-
const {
|
|
24
|
+
export const VariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
25
|
+
const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
|
|
24
26
|
|
|
25
|
-
const
|
|
27
|
+
const { setValue: setVariable, path } = useBoundProp( propTypeUtil );
|
|
28
|
+
|
|
29
|
+
const initialValue = useInitialValue();
|
|
30
|
+
|
|
31
|
+
const [ value, setValue ] = useState( initialValue );
|
|
26
32
|
const [ label, setLabel ] = useState( '' );
|
|
27
33
|
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
28
34
|
|
|
35
|
+
const { labelFieldError, setLabelFieldError } = useLabelError();
|
|
36
|
+
|
|
29
37
|
const resetFields = () => {
|
|
30
|
-
|
|
38
|
+
setValue( '' );
|
|
31
39
|
setLabel( '' );
|
|
32
40
|
setErrorMessage( '' );
|
|
33
41
|
};
|
|
@@ -37,26 +45,46 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
37
45
|
onClose();
|
|
38
46
|
};
|
|
39
47
|
|
|
40
|
-
const
|
|
48
|
+
const handleCreateAndTrack = () => {
|
|
41
49
|
createVariable( {
|
|
42
|
-
value
|
|
50
|
+
value,
|
|
43
51
|
label,
|
|
44
|
-
type:
|
|
52
|
+
type: propTypeUtil.key,
|
|
45
53
|
} )
|
|
46
54
|
.then( ( key ) => {
|
|
47
55
|
setVariable( key );
|
|
48
56
|
closePopover();
|
|
49
57
|
} )
|
|
50
58
|
.catch( ( error ) => {
|
|
51
|
-
|
|
59
|
+
const mappedError = mapServerError( error );
|
|
60
|
+
if ( mappedError && 'label' === mappedError.field ) {
|
|
61
|
+
setLabel( '' );
|
|
62
|
+
setLabelFieldError( {
|
|
63
|
+
value: label,
|
|
64
|
+
message: mappedError.message,
|
|
65
|
+
} );
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setErrorMessage( ERROR_MESSAGES.UNEXPECTED_ERROR );
|
|
52
70
|
} );
|
|
71
|
+
|
|
72
|
+
trackVariableEvent( {
|
|
73
|
+
varType: variableType,
|
|
74
|
+
controlPath: path.join( '.' ),
|
|
75
|
+
action: 'save',
|
|
76
|
+
} );
|
|
53
77
|
};
|
|
54
78
|
|
|
55
79
|
const hasEmptyValue = () => {
|
|
56
|
-
return '' ===
|
|
80
|
+
return '' === value.trim() || '' === label.trim();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const hasErrors = () => {
|
|
84
|
+
return !! errorMessage;
|
|
57
85
|
};
|
|
58
86
|
|
|
59
|
-
const isSubmitDisabled = hasEmptyValue();
|
|
87
|
+
const isSubmitDisabled = hasEmptyValue() || hasErrors();
|
|
60
88
|
|
|
61
89
|
return (
|
|
62
90
|
<PopoverBody height="auto">
|
|
@@ -68,7 +96,7 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
68
96
|
<ArrowLeftIcon fontSize={ SIZE } />
|
|
69
97
|
</IconButton>
|
|
70
98
|
) }
|
|
71
|
-
<
|
|
99
|
+
<VariableIcon fontSize={ SIZE } />
|
|
72
100
|
</>
|
|
73
101
|
}
|
|
74
102
|
title={ __( 'Create variable', 'elementor' ) }
|
|
@@ -80,15 +108,16 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
80
108
|
<PopoverContent p={ 2 }>
|
|
81
109
|
<LabelField
|
|
82
110
|
value={ label }
|
|
83
|
-
|
|
84
|
-
|
|
111
|
+
error={ labelFieldError }
|
|
112
|
+
onChange={ ( newValue ) => {
|
|
113
|
+
setLabel( newValue );
|
|
85
114
|
setErrorMessage( '' );
|
|
86
115
|
} }
|
|
87
116
|
/>
|
|
88
|
-
<
|
|
89
|
-
value={
|
|
90
|
-
onChange={ (
|
|
91
|
-
|
|
117
|
+
<ValueField
|
|
118
|
+
value={ value }
|
|
119
|
+
onChange={ ( newValue ) => {
|
|
120
|
+
setValue( newValue );
|
|
92
121
|
setErrorMessage( '' );
|
|
93
122
|
} }
|
|
94
123
|
/>
|
|
@@ -97,7 +126,7 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
97
126
|
</PopoverContent>
|
|
98
127
|
|
|
99
128
|
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
100
|
-
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={
|
|
129
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleCreateAndTrack }>
|
|
101
130
|
{ __( 'Create', 'elementor' ) }
|
|
102
131
|
</Button>
|
|
103
132
|
</CardActions>
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
|
+
import { useSuppressedMessage } from '@elementor/editor-current-user';
|
|
5
|
+
import { PopoverBody } from '@elementor/editor-editing-panel';
|
|
6
|
+
import { PopoverHeader } from '@elementor/editor-ui';
|
|
7
|
+
import { ArrowLeftIcon, TrashIcon } from '@elementor/icons';
|
|
8
|
+
import { Button, CardActions, Divider, FormHelperText, IconButton } from '@elementor/ui';
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
|
|
11
|
+
import { useVariableType } from '../context/variable-type-context';
|
|
12
|
+
import { usePermissions } from '../hooks/use-permissions';
|
|
13
|
+
import { deleteVariable, updateVariable, useVariable } from '../hooks/use-prop-variables';
|
|
14
|
+
import { styleVariablesRepository } from '../style-variables-repository';
|
|
15
|
+
import { ERROR_MESSAGES, mapServerError } from '../utils/validations';
|
|
16
|
+
import { LabelField, useLabelError } from './fields/label-field';
|
|
17
|
+
import { DeleteConfirmationDialog } from './ui/delete-confirmation-dialog';
|
|
18
|
+
import { EDIT_CONFIRMATION_DIALOG_ID, EditConfirmationDialog } from './ui/edit-confirmation-dialog';
|
|
19
|
+
|
|
20
|
+
const SIZE = 'tiny';
|
|
21
|
+
|
|
22
|
+
type Props = {
|
|
23
|
+
editId: string;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
onGoBack?: () => void;
|
|
26
|
+
onSubmit?: () => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const VariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props ) => {
|
|
30
|
+
const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
|
|
31
|
+
|
|
32
|
+
const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp( propTypeUtil );
|
|
33
|
+
const [ isMessageSuppressed, suppressMessage ] = useSuppressedMessage( EDIT_CONFIRMATION_DIALOG_ID );
|
|
34
|
+
const [ deleteConfirmation, setDeleteConfirmation ] = useState( false );
|
|
35
|
+
const [ editConfirmation, setEditConfirmation ] = useState( false );
|
|
36
|
+
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
37
|
+
|
|
38
|
+
const { labelFieldError, setLabelFieldError } = useLabelError();
|
|
39
|
+
const variable = useVariable( editId );
|
|
40
|
+
|
|
41
|
+
if ( ! variable ) {
|
|
42
|
+
throw new Error( `Global ${ variableType } variable not found` );
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const userPermissions = usePermissions();
|
|
46
|
+
|
|
47
|
+
const [ value, setValue ] = useState( variable.value );
|
|
48
|
+
const [ label, setLabel ] = useState( variable.label );
|
|
49
|
+
|
|
50
|
+
useEffect( () => {
|
|
51
|
+
styleVariablesRepository.update( {
|
|
52
|
+
[ editId ]: {
|
|
53
|
+
...variable,
|
|
54
|
+
value,
|
|
55
|
+
},
|
|
56
|
+
} );
|
|
57
|
+
|
|
58
|
+
return () => {
|
|
59
|
+
styleVariablesRepository.update( {
|
|
60
|
+
[ editId ]: { ...variable },
|
|
61
|
+
} );
|
|
62
|
+
};
|
|
63
|
+
}, [ editId, value, variable ] );
|
|
64
|
+
|
|
65
|
+
const handleUpdate = () => {
|
|
66
|
+
if ( isMessageSuppressed ) {
|
|
67
|
+
handleSaveVariable();
|
|
68
|
+
} else {
|
|
69
|
+
setEditConfirmation( true );
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const handleSaveVariable = () => {
|
|
74
|
+
updateVariable( editId, {
|
|
75
|
+
value,
|
|
76
|
+
label,
|
|
77
|
+
} )
|
|
78
|
+
.then( () => {
|
|
79
|
+
maybeTriggerBoundPropChange();
|
|
80
|
+
onSubmit?.();
|
|
81
|
+
} )
|
|
82
|
+
.catch( ( error ) => {
|
|
83
|
+
const mappedError = mapServerError( error );
|
|
84
|
+
if ( mappedError && 'label' === mappedError.field ) {
|
|
85
|
+
setLabel( '' );
|
|
86
|
+
setLabelFieldError( {
|
|
87
|
+
value: label,
|
|
88
|
+
message: mappedError.message,
|
|
89
|
+
} );
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
setErrorMessage( ERROR_MESSAGES.UNEXPECTED_ERROR );
|
|
94
|
+
} );
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleDelete = () => {
|
|
98
|
+
deleteVariable( editId ).then( () => {
|
|
99
|
+
maybeTriggerBoundPropChange();
|
|
100
|
+
onSubmit?.();
|
|
101
|
+
} );
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const maybeTriggerBoundPropChange = () => {
|
|
105
|
+
if ( editId === assignedValue ) {
|
|
106
|
+
notifyBoundPropChange( editId );
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const handleDeleteConfirmation = () => {
|
|
111
|
+
setDeleteConfirmation( true );
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const closeDeleteDialog = () => () => {
|
|
115
|
+
setDeleteConfirmation( false );
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const closeEditDialog = () => () => {
|
|
119
|
+
setEditConfirmation( false );
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const actions = [];
|
|
123
|
+
|
|
124
|
+
if ( userPermissions.canDelete() ) {
|
|
125
|
+
actions.push(
|
|
126
|
+
<IconButton
|
|
127
|
+
key="delete"
|
|
128
|
+
size={ SIZE }
|
|
129
|
+
aria-label={ __( 'Delete', 'elementor' ) }
|
|
130
|
+
onClick={ handleDeleteConfirmation }
|
|
131
|
+
>
|
|
132
|
+
<TrashIcon fontSize={ SIZE } />
|
|
133
|
+
</IconButton>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const hasEmptyValues = () => {
|
|
138
|
+
return ! value.trim() || ! label.trim();
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const noValueChanged = () => {
|
|
142
|
+
return value === variable.value && label === variable.label;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const hasErrors = () => {
|
|
146
|
+
return !! errorMessage;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const isSubmitDisabled = noValueChanged() || hasEmptyValues() || hasErrors();
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<>
|
|
153
|
+
<PopoverBody height="auto">
|
|
154
|
+
<PopoverHeader
|
|
155
|
+
title={ __( 'Edit variable', 'elementor' ) }
|
|
156
|
+
onClose={ onClose }
|
|
157
|
+
icon={
|
|
158
|
+
<>
|
|
159
|
+
{ onGoBack && (
|
|
160
|
+
<IconButton
|
|
161
|
+
size={ SIZE }
|
|
162
|
+
aria-label={ __( 'Go Back', 'elementor' ) }
|
|
163
|
+
onClick={ onGoBack }
|
|
164
|
+
>
|
|
165
|
+
<ArrowLeftIcon fontSize={ SIZE } />
|
|
166
|
+
</IconButton>
|
|
167
|
+
) }
|
|
168
|
+
<VariableIcon fontSize={ SIZE } />
|
|
169
|
+
</>
|
|
170
|
+
}
|
|
171
|
+
actions={ actions }
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
<Divider />
|
|
175
|
+
|
|
176
|
+
<PopoverContent p={ 2 }>
|
|
177
|
+
<LabelField
|
|
178
|
+
value={ label }
|
|
179
|
+
error={ labelFieldError }
|
|
180
|
+
onChange={ ( newValue ) => {
|
|
181
|
+
setLabel( newValue );
|
|
182
|
+
setErrorMessage( '' );
|
|
183
|
+
} }
|
|
184
|
+
/>
|
|
185
|
+
<ValueField
|
|
186
|
+
value={ value }
|
|
187
|
+
onChange={ ( newValue ) => {
|
|
188
|
+
setValue( newValue );
|
|
189
|
+
setErrorMessage( '' );
|
|
190
|
+
} }
|
|
191
|
+
/>
|
|
192
|
+
|
|
193
|
+
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
194
|
+
</PopoverContent>
|
|
195
|
+
|
|
196
|
+
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
197
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleUpdate }>
|
|
198
|
+
{ __( 'Save', 'elementor' ) }
|
|
199
|
+
</Button>
|
|
200
|
+
</CardActions>
|
|
201
|
+
</PopoverBody>
|
|
202
|
+
|
|
203
|
+
{ deleteConfirmation && (
|
|
204
|
+
<DeleteConfirmationDialog
|
|
205
|
+
open
|
|
206
|
+
label={ label }
|
|
207
|
+
onConfirm={ handleDelete }
|
|
208
|
+
closeDialog={ closeDeleteDialog() }
|
|
209
|
+
/>
|
|
210
|
+
) }
|
|
211
|
+
|
|
212
|
+
{ editConfirmation && ! isMessageSuppressed && (
|
|
213
|
+
<EditConfirmationDialog
|
|
214
|
+
closeDialog={ closeEditDialog() }
|
|
215
|
+
onConfirm={ handleSaveVariable }
|
|
216
|
+
onSuppressMessage={ suppressMessage }
|
|
217
|
+
/>
|
|
218
|
+
) }
|
|
219
|
+
</>
|
|
220
|
+
);
|
|
221
|
+
};
|