@elementor/editor-variables 0.15.0 → 0.16.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 +38 -0
- package/dist/index.js +647 -495
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +637 -512
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/components/color-variable-creation.tsx +11 -52
- package/src/components/color-variable-edit.tsx +88 -83
- 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 +13 -72
- package/src/components/font-variable-edit.tsx +86 -111
- package/src/components/ui/delete-confirmation-dialog.tsx +55 -0
- package/src/components/ui/menu-item-content.tsx +2 -5
- package/src/components/ui/{variable-tag.tsx → tags/assigned-tag.tsx} +1 -1
- package/src/components/ui/tags/deleted-tag.tsx +26 -0
- package/src/components/ui/variable/assigned-variable.tsx +70 -0
- package/src/components/ui/variable/deleted-variable.tsx +20 -0
- package/src/controls/color-variable-control.tsx +15 -48
- package/src/controls/font-variable-control.tsx +14 -43
- package/src/init-color-variables.ts +3 -48
- package/src/repeater-injections.ts +35 -0
- package/src/utils/validations.ts +42 -0
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
4
|
import { PopoverScrollableContent } from '@elementor/editor-editing-panel';
|
|
5
5
|
import { PopoverHeader } from '@elementor/editor-ui';
|
|
6
6
|
import { ArrowLeftIcon, BrushIcon } from '@elementor/icons';
|
|
7
|
-
import {
|
|
8
|
-
Button,
|
|
9
|
-
CardActions,
|
|
10
|
-
Divider,
|
|
11
|
-
FormLabel,
|
|
12
|
-
Grid,
|
|
13
|
-
IconButton,
|
|
14
|
-
TextField,
|
|
15
|
-
UnstableColorField,
|
|
16
|
-
} from '@elementor/ui';
|
|
7
|
+
import { Button, CardActions, Divider, IconButton } from '@elementor/ui';
|
|
17
8
|
import { __ } from '@wordpress/i18n';
|
|
18
9
|
|
|
19
10
|
import { createVariable } from '../hooks/use-prop-variables';
|
|
20
11
|
import { colorVariablePropTypeUtil } from '../prop-types/color-variable-prop-type';
|
|
21
|
-
import {
|
|
12
|
+
import { ColorField } from './fields/color-field';
|
|
13
|
+
import { LabelField } from './fields/label-field';
|
|
22
14
|
|
|
23
15
|
const SIZE = 'tiny';
|
|
24
16
|
|
|
@@ -33,9 +25,6 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
33
25
|
const [ color, setColor ] = useState( '' );
|
|
34
26
|
const [ label, setLabel ] = useState( '' );
|
|
35
27
|
|
|
36
|
-
const defaultRef = useRef< HTMLDivElement >( null );
|
|
37
|
-
const anchorRef = usePopoverContentRef() ?? defaultRef;
|
|
38
|
-
|
|
39
28
|
const resetFields = () => {
|
|
40
29
|
setColor( '' );
|
|
41
30
|
setLabel( '' );
|
|
@@ -57,10 +46,12 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
57
46
|
} );
|
|
58
47
|
};
|
|
59
48
|
|
|
60
|
-
const
|
|
61
|
-
return
|
|
49
|
+
const hasEmptyValue = () => {
|
|
50
|
+
return '' === color.trim() || '' === label.trim();
|
|
62
51
|
};
|
|
63
52
|
|
|
53
|
+
const isSubmitDisabled = hasEmptyValue();
|
|
54
|
+
|
|
64
55
|
return (
|
|
65
56
|
<PopoverScrollableContent height="auto">
|
|
66
57
|
<PopoverHeader
|
|
@@ -81,44 +72,12 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
|
|
|
81
72
|
<Divider />
|
|
82
73
|
|
|
83
74
|
<PopoverContent p={ 2 }>
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
<FormLabel size="tiny">{ __( 'Name', 'elementor' ) }</FormLabel>
|
|
87
|
-
</Grid>
|
|
88
|
-
<Grid item xs={ 12 }>
|
|
89
|
-
<TextField
|
|
90
|
-
size="tiny"
|
|
91
|
-
fullWidth
|
|
92
|
-
value={ label }
|
|
93
|
-
onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
|
|
94
|
-
/>
|
|
95
|
-
</Grid>
|
|
96
|
-
</Grid>
|
|
97
|
-
|
|
98
|
-
<Grid container gap={ 0.75 } alignItems="center">
|
|
99
|
-
<Grid item xs={ 12 }>
|
|
100
|
-
<FormLabel size="tiny">{ __( 'Value', 'elementor' ) }</FormLabel>
|
|
101
|
-
</Grid>
|
|
102
|
-
<Grid item xs={ 12 }>
|
|
103
|
-
<UnstableColorField
|
|
104
|
-
size="tiny"
|
|
105
|
-
fullWidth
|
|
106
|
-
value={ color }
|
|
107
|
-
onChange={ setColor }
|
|
108
|
-
slotProps={ {
|
|
109
|
-
colorPicker: {
|
|
110
|
-
anchorEl: anchorRef.current,
|
|
111
|
-
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
112
|
-
transformOrigin: { vertical: 'top', horizontal: -10 },
|
|
113
|
-
},
|
|
114
|
-
} }
|
|
115
|
-
/>
|
|
116
|
-
</Grid>
|
|
117
|
-
</Grid>
|
|
75
|
+
<LabelField value={ label } onChange={ setLabel } />
|
|
76
|
+
<ColorField value={ color } onChange={ setColor } />
|
|
118
77
|
</PopoverContent>
|
|
119
78
|
|
|
120
79
|
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
121
|
-
<Button size="small" variant="contained" disabled={
|
|
80
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleCreate }>
|
|
122
81
|
{ __( 'Create', 'elementor' ) }
|
|
123
82
|
</Button>
|
|
124
83
|
</CardActions>
|
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { PopoverContent } from '@elementor/editor-controls';
|
|
4
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
|
+
import { PopoverScrollableContent } from '@elementor/editor-editing-panel';
|
|
5
|
+
import { PopoverHeader } from '@elementor/editor-ui';
|
|
5
6
|
import { ArrowLeftIcon, BrushIcon, TrashIcon } from '@elementor/icons';
|
|
6
|
-
import {
|
|
7
|
-
Button,
|
|
8
|
-
CardActions,
|
|
9
|
-
Divider,
|
|
10
|
-
FormLabel,
|
|
11
|
-
Grid,
|
|
12
|
-
IconButton,
|
|
13
|
-
TextField,
|
|
14
|
-
UnstableColorField,
|
|
15
|
-
} from '@elementor/ui';
|
|
7
|
+
import { Button, CardActions, Divider, IconButton } from '@elementor/ui';
|
|
16
8
|
import { __ } from '@wordpress/i18n';
|
|
17
9
|
|
|
18
10
|
import { deleteVariable, updateVariable, useVariable } from '../hooks/use-prop-variables';
|
|
19
|
-
import {
|
|
11
|
+
import { colorVariablePropTypeUtil } from '../prop-types/color-variable-prop-type';
|
|
12
|
+
import { ColorField } from './fields/color-field';
|
|
13
|
+
import { LabelField } from './fields/label-field';
|
|
14
|
+
import { DeleteConfirmationDialog } from './ui/delete-confirmation-dialog';
|
|
20
15
|
|
|
21
16
|
const SIZE = 'tiny';
|
|
22
17
|
|
|
@@ -28,14 +23,14 @@ type Props = {
|
|
|
28
23
|
};
|
|
29
24
|
|
|
30
25
|
export const ColorVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props ) => {
|
|
26
|
+
const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp( colorVariablePropTypeUtil );
|
|
27
|
+
const [ deleteConfirmation, setDeleteConfirmation ] = useState( false );
|
|
28
|
+
|
|
31
29
|
const variable = useVariable( editId );
|
|
32
30
|
if ( ! variable ) {
|
|
33
31
|
throw new Error( `Global color variable not found` );
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
const defaultRef = useRef< HTMLDivElement >( null );
|
|
37
|
-
const anchorRef = usePopoverContentRef() ?? defaultRef;
|
|
38
|
-
|
|
39
34
|
const [ color, setColor ] = useState( variable.value );
|
|
40
35
|
const [ label, setLabel ] = useState( variable.label );
|
|
41
36
|
|
|
@@ -44,90 +39,100 @@ export const ColorVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Prop
|
|
|
44
39
|
value: color,
|
|
45
40
|
label,
|
|
46
41
|
} ).then( () => {
|
|
42
|
+
maybeTriggerBoundPropChange();
|
|
47
43
|
onSubmit?.();
|
|
48
44
|
} );
|
|
49
45
|
};
|
|
50
46
|
|
|
51
47
|
const handleDelete = () => {
|
|
52
48
|
deleteVariable( editId ).then( () => {
|
|
49
|
+
maybeTriggerBoundPropChange();
|
|
53
50
|
onSubmit?.();
|
|
54
51
|
} );
|
|
55
52
|
};
|
|
56
53
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const maybeTriggerBoundPropChange = () => {
|
|
55
|
+
if ( editId === assignedValue ) {
|
|
56
|
+
notifyBoundPropChange( editId );
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleDeleteConfirmation = () => {
|
|
61
|
+
setDeleteConfirmation( true );
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const closeDeleteDialog = () => () => {
|
|
65
|
+
setDeleteConfirmation( false );
|
|
66
|
+
};
|
|
60
67
|
|
|
61
68
|
const actions = [];
|
|
62
69
|
|
|
63
70
|
actions.push(
|
|
64
|
-
<IconButton
|
|
71
|
+
<IconButton
|
|
72
|
+
key="delete"
|
|
73
|
+
size={ SIZE }
|
|
74
|
+
aria-label={ __( 'Delete', 'elementor' ) }
|
|
75
|
+
onClick={ handleDeleteConfirmation }
|
|
76
|
+
>
|
|
65
77
|
<TrashIcon fontSize={ SIZE } />
|
|
66
78
|
</IconButton>
|
|
67
79
|
);
|
|
68
80
|
|
|
81
|
+
const hasEmptyValues = () => {
|
|
82
|
+
return ! color.trim() || ! label.trim();
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const noValueChanged = () => {
|
|
86
|
+
return color === variable.value && label === variable.label;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isSubmitDisabled = noValueChanged() || hasEmptyValues();
|
|
90
|
+
|
|
69
91
|
return (
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
colorPicker: {
|
|
116
|
-
anchorEl: anchorRef.current,
|
|
117
|
-
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
118
|
-
transformOrigin: { vertical: 'top', horizontal: -10 },
|
|
119
|
-
},
|
|
120
|
-
} }
|
|
121
|
-
/>
|
|
122
|
-
</Grid>
|
|
123
|
-
</Grid>
|
|
124
|
-
</PopoverContent>
|
|
125
|
-
|
|
126
|
-
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
127
|
-
<Button size="small" variant="contained" disabled={ isSaveDisabled() } onClick={ handleUpdate }>
|
|
128
|
-
{ __( 'Save', 'elementor' ) }
|
|
129
|
-
</Button>
|
|
130
|
-
</CardActions>
|
|
131
|
-
</PopoverScrollableContent>
|
|
92
|
+
<>
|
|
93
|
+
<PopoverScrollableContent height="auto">
|
|
94
|
+
<PopoverHeader
|
|
95
|
+
title={ __( 'Edit variable', 'elementor' ) }
|
|
96
|
+
onClose={ onClose }
|
|
97
|
+
icon={
|
|
98
|
+
<>
|
|
99
|
+
{ onGoBack && (
|
|
100
|
+
<IconButton
|
|
101
|
+
size={ SIZE }
|
|
102
|
+
aria-label={ __( 'Go Back', 'elementor' ) }
|
|
103
|
+
onClick={ onGoBack }
|
|
104
|
+
>
|
|
105
|
+
<ArrowLeftIcon fontSize={ SIZE } />
|
|
106
|
+
</IconButton>
|
|
107
|
+
) }
|
|
108
|
+
<BrushIcon fontSize={ SIZE } />
|
|
109
|
+
</>
|
|
110
|
+
}
|
|
111
|
+
actions={ actions }
|
|
112
|
+
/>
|
|
113
|
+
|
|
114
|
+
<Divider />
|
|
115
|
+
|
|
116
|
+
<PopoverContent p={ 2 }>
|
|
117
|
+
<LabelField value={ label } onChange={ setLabel } />
|
|
118
|
+
<ColorField value={ color } onChange={ setColor } />
|
|
119
|
+
</PopoverContent>
|
|
120
|
+
|
|
121
|
+
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
122
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleUpdate }>
|
|
123
|
+
{ __( 'Save', 'elementor' ) }
|
|
124
|
+
</Button>
|
|
125
|
+
</CardActions>
|
|
126
|
+
</PopoverScrollableContent>
|
|
127
|
+
|
|
128
|
+
{ deleteConfirmation && (
|
|
129
|
+
<DeleteConfirmationDialog
|
|
130
|
+
open
|
|
131
|
+
label={ label }
|
|
132
|
+
onConfirm={ handleDelete }
|
|
133
|
+
closeDialog={ closeDeleteDialog() }
|
|
134
|
+
/>
|
|
135
|
+
) }
|
|
136
|
+
</>
|
|
132
137
|
);
|
|
133
138
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import { FormHelperText, FormLabel, Grid, UnstableColorField } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
import { validateValue } from '../../utils/validations';
|
|
7
|
+
import { usePopoverContentRef } from '../variable-selection-popover.context';
|
|
8
|
+
|
|
9
|
+
type ColorFieldProps = {
|
|
10
|
+
value: string;
|
|
11
|
+
onChange: ( value: string ) => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const ColorField = ( { value, onChange }: ColorFieldProps ) => {
|
|
15
|
+
const [ color, setColor ] = useState( value );
|
|
16
|
+
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
17
|
+
|
|
18
|
+
const defaultRef = useRef< HTMLDivElement >( null );
|
|
19
|
+
const anchorRef = usePopoverContentRef() ?? defaultRef;
|
|
20
|
+
|
|
21
|
+
const handleChange = ( newValue: string ) => {
|
|
22
|
+
setColor( newValue );
|
|
23
|
+
|
|
24
|
+
const errorMsg = validateValue( newValue );
|
|
25
|
+
setErrorMessage( errorMsg );
|
|
26
|
+
|
|
27
|
+
onChange( errorMsg ? '' : newValue );
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Grid container gap={ 0.75 } alignItems="center">
|
|
32
|
+
<Grid item xs={ 12 }>
|
|
33
|
+
<FormLabel size="tiny">{ __( 'Value', 'elementor' ) }</FormLabel>
|
|
34
|
+
</Grid>
|
|
35
|
+
<Grid item xs={ 12 }>
|
|
36
|
+
<UnstableColorField
|
|
37
|
+
size="tiny"
|
|
38
|
+
fullWidth
|
|
39
|
+
value={ color }
|
|
40
|
+
onChange={ handleChange }
|
|
41
|
+
error={ errorMessage ?? undefined }
|
|
42
|
+
slotProps={ {
|
|
43
|
+
colorPicker: {
|
|
44
|
+
anchorEl: anchorRef.current,
|
|
45
|
+
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
46
|
+
transformOrigin: { vertical: 'top', horizontal: -10 },
|
|
47
|
+
},
|
|
48
|
+
} }
|
|
49
|
+
/>
|
|
50
|
+
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
51
|
+
</Grid>
|
|
52
|
+
</Grid>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import { FontFamilySelector } from '@elementor/editor-controls';
|
|
4
|
+
import { useFontFamilies, useSectionWidth } from '@elementor/editor-editing-panel';
|
|
5
|
+
import { ChevronDownIcon } from '@elementor/icons';
|
|
6
|
+
import {
|
|
7
|
+
bindPopover,
|
|
8
|
+
bindTrigger,
|
|
9
|
+
FormHelperText,
|
|
10
|
+
FormLabel,
|
|
11
|
+
Grid,
|
|
12
|
+
Popover,
|
|
13
|
+
UnstableTag,
|
|
14
|
+
usePopupState,
|
|
15
|
+
} from '@elementor/ui';
|
|
16
|
+
import { __ } from '@wordpress/i18n';
|
|
17
|
+
|
|
18
|
+
import { validateValue } from '../../utils/validations';
|
|
19
|
+
import { usePopoverContentRef } from '../variable-selection-popover.context';
|
|
20
|
+
|
|
21
|
+
type FontFieldProps = {
|
|
22
|
+
value: string;
|
|
23
|
+
onChange: ( value: string ) => void;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const FontField = ( { value, onChange }: FontFieldProps ) => {
|
|
27
|
+
const [ fontFamily, setFontFamily ] = useState( value );
|
|
28
|
+
const [ errorMessage, setErrorMessage ] = useState( '' );
|
|
29
|
+
|
|
30
|
+
const defaultRef = useRef< HTMLDivElement >( null );
|
|
31
|
+
const anchorRef = usePopoverContentRef() ?? defaultRef;
|
|
32
|
+
|
|
33
|
+
const fontPopoverState = usePopupState( { variant: 'popover' } );
|
|
34
|
+
|
|
35
|
+
const fontFamilies = useFontFamilies();
|
|
36
|
+
const sectionWidth = useSectionWidth();
|
|
37
|
+
|
|
38
|
+
const handleChange = ( newValue: string ) => {
|
|
39
|
+
setFontFamily( newValue );
|
|
40
|
+
|
|
41
|
+
const errorMsg = validateValue( newValue );
|
|
42
|
+
setErrorMessage( errorMsg );
|
|
43
|
+
|
|
44
|
+
onChange( errorMsg ? '' : newValue );
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleFontFamilyChange = ( newFontFamily: string ) => {
|
|
48
|
+
handleChange( newFontFamily );
|
|
49
|
+
fontPopoverState.close();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<Grid container gap={ 0.75 } alignItems="center">
|
|
54
|
+
<Grid item xs={ 12 }>
|
|
55
|
+
<FormLabel size="tiny">{ __( 'Value', 'elementor' ) }</FormLabel>
|
|
56
|
+
</Grid>
|
|
57
|
+
<Grid item xs={ 12 }>
|
|
58
|
+
<UnstableTag
|
|
59
|
+
variant="outlined"
|
|
60
|
+
label={ fontFamily }
|
|
61
|
+
endIcon={ <ChevronDownIcon fontSize="tiny" /> }
|
|
62
|
+
{ ...bindTrigger( fontPopoverState ) }
|
|
63
|
+
fullWidth
|
|
64
|
+
/>
|
|
65
|
+
<Popover
|
|
66
|
+
disablePortal
|
|
67
|
+
disableScrollLock
|
|
68
|
+
anchorEl={ anchorRef.current }
|
|
69
|
+
anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
70
|
+
transformOrigin={ { vertical: 'top', horizontal: -20 } }
|
|
71
|
+
{ ...bindPopover( fontPopoverState ) }
|
|
72
|
+
>
|
|
73
|
+
<FontFamilySelector
|
|
74
|
+
fontFamilies={ fontFamilies }
|
|
75
|
+
fontFamily={ fontFamily }
|
|
76
|
+
onFontFamilyChange={ handleFontFamilyChange }
|
|
77
|
+
onClose={ fontPopoverState.close }
|
|
78
|
+
sectionWidth={ sectionWidth }
|
|
79
|
+
/>
|
|
80
|
+
</Popover>
|
|
81
|
+
{ errorMessage && <FormHelperText error>{ errorMessage }</FormHelperText> }
|
|
82
|
+
</Grid>
|
|
83
|
+
</Grid>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -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 { PopoverScrollableContent
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
|
|
4
|
+
import { PopoverScrollableContent } 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, 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,15 +20,11 @@ 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
27
|
|
|
40
|
-
const anchorRef = useRef< HTMLDivElement >( null );
|
|
41
|
-
const fontPopoverState = usePopupState( { variant: 'popover' } );
|
|
42
|
-
|
|
43
28
|
const resetFields = () => {
|
|
44
29
|
setFontFamily( '' );
|
|
45
30
|
setLabel( '' );
|
|
@@ -61,11 +46,11 @@ export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
|
|
|
61
46
|
} );
|
|
62
47
|
};
|
|
63
48
|
|
|
64
|
-
const
|
|
65
|
-
return
|
|
49
|
+
const hasEmptyValue = () => {
|
|
50
|
+
return '' === fontFamily.trim() || '' === label.trim();
|
|
66
51
|
};
|
|
67
52
|
|
|
68
|
-
const
|
|
53
|
+
const isSubmitDisabled = hasEmptyValue();
|
|
69
54
|
|
|
70
55
|
return (
|
|
71
56
|
<PopoverScrollableContent height="auto">
|
|
@@ -87,56 +72,12 @@ export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
|
|
|
87
72
|
<Divider />
|
|
88
73
|
|
|
89
74
|
<PopoverContent p={ 2 }>
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
<FormLabel size="tiny">{ __( 'Name', 'elementor' ) }</FormLabel>
|
|
93
|
-
</Grid>
|
|
94
|
-
<Grid item xs={ 12 }>
|
|
95
|
-
<TextField
|
|
96
|
-
size="tiny"
|
|
97
|
-
fullWidth
|
|
98
|
-
value={ label }
|
|
99
|
-
onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
|
|
100
|
-
/>
|
|
101
|
-
</Grid>
|
|
102
|
-
</Grid>
|
|
103
|
-
|
|
104
|
-
<Grid container gap={ 0.75 } alignItems="center">
|
|
105
|
-
<Grid item xs={ 12 }>
|
|
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>
|
|
75
|
+
<LabelField value={ label } onChange={ setLabel } />
|
|
76
|
+
<FontField value={ fontFamily } onChange={ setFontFamily } />
|
|
136
77
|
</PopoverContent>
|
|
137
78
|
|
|
138
79
|
<CardActions sx={ { pt: 0.5, pb: 1 } }>
|
|
139
|
-
<Button size="small" variant="contained" disabled={
|
|
80
|
+
<Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleCreate }>
|
|
140
81
|
{ __( 'Create', 'elementor' ) }
|
|
141
82
|
</Button>
|
|
142
83
|
</CardActions>
|