@elementor/editor-variables 0.14.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/dist/index.js +743 -500
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +720 -528
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +10 -10
  7. package/src/components/color-variable-creation.tsx +18 -57
  8. package/src/components/color-variable-edit.tsx +100 -79
  9. package/src/components/color-variables-selection.tsx +33 -20
  10. package/src/components/fields/color-field.tsx +54 -0
  11. package/src/components/fields/font-field.tsx +85 -0
  12. package/src/components/fields/label-field.tsx +54 -0
  13. package/src/components/font-variable-creation.tsx +19 -76
  14. package/src/components/font-variable-edit.tsx +98 -106
  15. package/src/components/font-variables-selection.tsx +33 -20
  16. package/src/components/ui/color-indicator.tsx +1 -0
  17. package/src/components/ui/delete-confirmation-dialog.tsx +55 -0
  18. package/src/components/ui/menu-item-content.tsx +29 -23
  19. package/src/components/ui/no-search-results.tsx +6 -8
  20. package/src/components/ui/no-variables.tsx +3 -2
  21. package/src/components/ui/tags/assigned-tag.tsx +43 -0
  22. package/src/components/ui/tags/deleted-tag.tsx +26 -0
  23. package/src/components/ui/variable/assigned-variable.tsx +70 -0
  24. package/src/components/ui/variable/deleted-variable.tsx +20 -0
  25. package/src/components/variable-selection-popover.context.ts +7 -0
  26. package/src/components/variable-selection-popover.tsx +17 -8
  27. package/src/controls/color-variable-control.tsx +15 -72
  28. package/src/controls/font-variable-control.tsx +14 -71
  29. package/src/hooks/use-prop-variables.ts +12 -18
  30. package/src/init-color-variables.ts +3 -48
  31. package/src/repeater-injections.ts +35 -0
  32. package/src/utils/validations.ts +42 -0
@@ -1,23 +1,16 @@
1
1
  import * as React from 'react';
2
- import { useRef, useState } from 'react';
3
- import { useBoundProp } from '@elementor/editor-controls';
2
+ import { useState } from 'react';
3
+ import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
4
+ import { PopoverScrollableContent } from '@elementor/editor-editing-panel';
4
5
  import { PopoverHeader } from '@elementor/editor-ui';
5
6
  import { ArrowLeftIcon, BrushIcon } from '@elementor/icons';
6
- import {
7
- Button,
8
- CardActions,
9
- Divider,
10
- FormLabel,
11
- Grid,
12
- IconButton,
13
- Stack,
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';
12
+ import { ColorField } from './fields/color-field';
13
+ import { LabelField } from './fields/label-field';
21
14
 
22
15
  const SIZE = 'tiny';
23
16
 
@@ -32,8 +25,6 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
32
25
  const [ color, setColor ] = useState( '' );
33
26
  const [ label, setLabel ] = useState( '' );
34
27
 
35
- const anchorRef = useRef< HTMLDivElement >( null );
36
-
37
28
  const resetFields = () => {
38
29
  setColor( '' );
39
30
  setLabel( '' );
@@ -55,12 +46,14 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
55
46
  } );
56
47
  };
57
48
 
58
- const isFormInvalid = () => {
59
- return ! color?.trim() || ! label?.trim();
49
+ const hasEmptyValue = () => {
50
+ return '' === color.trim() || '' === label.trim();
60
51
  };
61
52
 
53
+ const isSubmitDisabled = hasEmptyValue();
54
+
62
55
  return (
63
- <>
56
+ <PopoverScrollableContent height="auto">
64
57
  <PopoverHeader
65
58
  icon={
66
59
  <>
@@ -78,48 +71,16 @@ export const ColorVariableCreation = ( { onGoBack, onClose }: Props ) => {
78
71
 
79
72
  <Divider />
80
73
 
81
- <Stack p={ 1.5 } gap={ 1.5 }>
82
- <Grid container gap={ 0.75 } alignItems="center">
83
- <Grid item xs={ 12 }>
84
- <FormLabel size="small">{ __( 'Name', 'elementor' ) }</FormLabel>
85
- </Grid>
86
- <Grid item xs={ 12 }>
87
- <TextField
88
- size="tiny"
89
- fullWidth
90
- value={ label }
91
- onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
92
- />
93
- </Grid>
94
- </Grid>
95
-
96
- <Grid container gap={ 0.75 } alignItems="center">
97
- <Grid item xs={ 12 }>
98
- <FormLabel size="small">{ __( 'Value', 'elementor' ) }</FormLabel>
99
- </Grid>
100
- <Grid item xs={ 12 }>
101
- <UnstableColorField
102
- size="tiny"
103
- fullWidth
104
- value={ color }
105
- onChange={ setColor }
106
- slotProps={ {
107
- colorPicker: {
108
- anchorEl: anchorRef.current,
109
- anchorOrigin: { vertical: 'top', horizontal: 'right' },
110
- transformOrigin: { vertical: 'top', horizontal: -10 },
111
- },
112
- } }
113
- />
114
- </Grid>
115
- </Grid>
116
- </Stack>
74
+ <PopoverContent p={ 2 }>
75
+ <LabelField value={ label } onChange={ setLabel } />
76
+ <ColorField value={ color } onChange={ setColor } />
77
+ </PopoverContent>
117
78
 
118
- <CardActions>
119
- <Button size="small" variant="contained" disabled={ isFormInvalid() } onClick={ handleCreate }>
79
+ <CardActions sx={ { pt: 0.5, pb: 1 } }>
80
+ <Button size="small" variant="contained" disabled={ isSubmitDisabled } onClick={ handleCreate }>
120
81
  { __( 'Create', 'elementor' ) }
121
82
  </Button>
122
83
  </CardActions>
123
- </>
84
+ </PopoverScrollableContent>
124
85
  );
125
86
  };
@@ -1,21 +1,17 @@
1
1
  import * as React from 'react';
2
- import { useRef, useState } from 'react';
2
+ import { useState } from 'react';
3
+ import { PopoverContent, useBoundProp } from '@elementor/editor-controls';
4
+ import { PopoverScrollableContent } from '@elementor/editor-editing-panel';
3
5
  import { PopoverHeader } from '@elementor/editor-ui';
4
- import { ArrowLeftIcon, BrushIcon } from '@elementor/icons';
5
- import {
6
- Button,
7
- CardActions,
8
- Divider,
9
- FormLabel,
10
- Grid,
11
- IconButton,
12
- Stack,
13
- TextField,
14
- UnstableColorField,
15
- } from '@elementor/ui';
6
+ import { ArrowLeftIcon, BrushIcon, TrashIcon } from '@elementor/icons';
7
+ import { Button, CardActions, Divider, IconButton } from '@elementor/ui';
16
8
  import { __ } from '@wordpress/i18n';
17
9
 
18
- import { updateVariable, useVariable } from '../hooks/use-prop-variables';
10
+ import { deleteVariable, updateVariable, useVariable } from '../hooks/use-prop-variables';
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';
19
15
 
20
16
  const SIZE = 'tiny';
21
17
 
@@ -27,14 +23,14 @@ type Props = {
27
23
  };
28
24
 
29
25
  export const ColorVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props ) => {
30
- const variable = useVariable( editId );
26
+ const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp( colorVariablePropTypeUtil );
27
+ const [ deleteConfirmation, setDeleteConfirmation ] = useState( false );
31
28
 
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 anchorRef = useRef< HTMLDivElement >( null );
37
-
38
34
  const [ color, setColor ] = useState( variable.value );
39
35
  const [ label, setLabel ] = useState( variable.label );
40
36
 
@@ -43,75 +39,100 @@ export const ColorVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Prop
43
39
  value: color,
44
40
  label,
45
41
  } ).then( () => {
42
+ maybeTriggerBoundPropChange();
43
+ onSubmit?.();
44
+ } );
45
+ };
46
+
47
+ const handleDelete = () => {
48
+ deleteVariable( editId ).then( () => {
49
+ maybeTriggerBoundPropChange();
46
50
  onSubmit?.();
47
51
  } );
48
52
  };
49
53
 
50
- const noValueChanged = () => color === variable.value && label === variable.label;
51
- const hasEmptyValue = () => '' === color.trim() || '' === label.trim();
52
- const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
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
+ };
67
+
68
+ const actions = [];
69
+
70
+ actions.push(
71
+ <IconButton
72
+ key="delete"
73
+ size={ SIZE }
74
+ aria-label={ __( 'Delete', 'elementor' ) }
75
+ onClick={ handleDeleteConfirmation }
76
+ >
77
+ <TrashIcon fontSize={ SIZE } />
78
+ </IconButton>
79
+ );
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();
53
90
 
54
91
  return (
55
92
  <>
56
- <PopoverHeader
57
- title={ __( 'Edit variable', 'elementor' ) }
58
- onClose={ onClose }
59
- icon={
60
- <>
61
- { onGoBack && (
62
- <IconButton size={ SIZE } aria-label={ __( 'Go Back', 'elementor' ) } onClick={ onGoBack }>
63
- <ArrowLeftIcon fontSize={ SIZE } />
64
- </IconButton>
65
- ) }
66
- <BrushIcon fontSize={ SIZE } />
67
- </>
68
- }
69
- />
70
-
71
- <Divider />
72
-
73
- <Stack p={ 1.5 } gap={ 1.5 }>
74
- <Grid container gap={ 0.75 } alignItems="center">
75
- <Grid item xs={ 12 }>
76
- <FormLabel size="small">{ __( 'Name', 'elementor' ) }</FormLabel>
77
- </Grid>
78
- <Grid item xs={ 12 }>
79
- <TextField
80
- size="tiny"
81
- fullWidth
82
- value={ label }
83
- onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
84
- />
85
- </Grid>
86
- </Grid>
87
-
88
- <Grid container gap={ 0.75 } alignItems="center">
89
- <Grid item xs={ 12 }>
90
- <FormLabel size="small">{ __( 'Value', 'elementor' ) }</FormLabel>
91
- </Grid>
92
- <Grid item xs={ 12 }>
93
- <UnstableColorField
94
- size="tiny"
95
- fullWidth
96
- value={ color }
97
- onChange={ setColor }
98
- slotProps={ {
99
- colorPicker: {
100
- anchorEl: anchorRef.current,
101
- anchorOrigin: { vertical: 'top', horizontal: 'right' },
102
- transformOrigin: { vertical: 'top', horizontal: -10 },
103
- },
104
- } }
105
- />
106
- </Grid>
107
- </Grid>
108
- </Stack>
109
-
110
- <CardActions>
111
- <Button size="small" variant="contained" disabled={ isSaveDisabled() } onClick={ handleUpdate }>
112
- { __( 'Save', 'elementor' ) }
113
- </Button>
114
- </CardActions>
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
+ ) }
115
136
  </>
116
137
  );
117
138
  };
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { useState } from 'react';
3
3
  import { useBoundProp } from '@elementor/editor-controls';
4
+ import { PopoverScrollableContent } from '@elementor/editor-editing-panel';
4
5
  import { PopoverHeader, PopoverMenuList, PopoverSearch, type VirtualizedItem } from '@elementor/editor-ui';
5
- import { ColorFilterIcon, PlusIcon, SettingsIcon } from '@elementor/icons';
6
+ import { BrushIcon, ColorFilterIcon, PlusIcon, SettingsIcon } from '@elementor/icons';
6
7
  import { Divider, IconButton } from '@elementor/ui';
7
8
  import { __ } from '@wordpress/i18n';
8
9
 
@@ -93,25 +94,37 @@ export const ColorVariablesSelection = ( { closePopover, onAdd, onEdit, onSettin
93
94
 
94
95
  <Divider />
95
96
 
96
- { hasVariables && hasSearchResults && (
97
- <PopoverMenuList< 'item', string >
98
- items={ items }
99
- onSelect={ handleSetColorVariable }
100
- onClose={ () => {} }
101
- selectedValue={ variable }
102
- data-testid="color-variables-list"
103
- menuListTemplate={ VariablesStyledMenuList }
104
- menuItemContentTemplate={ ( item: VirtualizedItem< 'item', string > ) => (
105
- <MenuItemContent item={ item } />
106
- ) }
107
- />
108
- ) }
109
-
110
- { ! hasSearchResults && hasVariables && (
111
- <NoSearchResults searchValue={ searchValue } onClear={ handleClearSearch } />
112
- ) }
113
-
114
- { ! hasVariables && <NoVariables icon={ <ColorFilterIcon fontSize="large" /> } onAdd={ onAdd } /> }
97
+ <PopoverScrollableContent>
98
+ { hasVariables && hasSearchResults && (
99
+ <PopoverMenuList
100
+ items={ items }
101
+ onSelect={ handleSetColorVariable }
102
+ onClose={ () => {} }
103
+ selectedValue={ variable }
104
+ data-testid="color-variables-list"
105
+ menuListTemplate={ VariablesStyledMenuList }
106
+ menuItemContentTemplate={ ( item: VirtualizedItem< 'item', string > ) => (
107
+ <MenuItemContent item={ item } />
108
+ ) }
109
+ />
110
+ ) }
111
+
112
+ { ! hasSearchResults && hasVariables && (
113
+ <NoSearchResults
114
+ searchValue={ searchValue }
115
+ onClear={ handleClearSearch }
116
+ icon={ <BrushIcon fontSize="large" /> }
117
+ />
118
+ ) }
119
+
120
+ { ! hasVariables && (
121
+ <NoVariables
122
+ title={ __( 'Create your first color variable', 'elementor' ) }
123
+ icon={ <BrushIcon fontSize="large" /> }
124
+ onAdd={ onAdd }
125
+ />
126
+ ) }
127
+ </PopoverScrollableContent>
115
128
  </>
116
129
  );
117
130
  };
@@ -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
+ };