@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,28 +1,16 @@
1
1
  import * as React from 'react';
2
- import { useRef, useState } from 'react';
3
- import { FontFamilySelector, useBoundProp } from '@elementor/editor-controls';
4
- import { useFontFamilies } from '@elementor/editor-editing-panel';
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, ChevronDownIcon, TextIcon } from '@elementor/icons';
7
- import {
8
- bindPopover,
9
- bindTrigger,
10
- Button,
11
- CardActions,
12
- Divider,
13
- FormLabel,
14
- Grid,
15
- IconButton,
16
- Popover,
17
- Stack,
18
- TextField,
19
- UnstableTag,
20
- usePopupState,
21
- } from '@elementor/ui';
6
+ import { ArrowLeftIcon, TextIcon } from '@elementor/icons';
7
+ import { Button, CardActions, Divider, IconButton } from '@elementor/ui';
22
8
  import { __ } from '@wordpress/i18n';
23
9
 
24
10
  import { createVariable } from '../hooks/use-prop-variables';
25
11
  import { fontVariablePropTypeUtil } from '../prop-types/font-variable-prop-type';
12
+ import { FontField } from './fields/font-field';
13
+ import { LabelField } from './fields/label-field';
26
14
 
27
15
  const SIZE = 'tiny';
28
16
 
@@ -32,15 +20,11 @@ type Props = {
32
20
  };
33
21
 
34
22
  export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
35
- const fontFamilies = useFontFamilies();
36
23
  const { setValue: setVariable } = useBoundProp( fontVariablePropTypeUtil );
37
24
 
38
25
  const [ fontFamily, setFontFamily ] = useState( '' );
39
26
  const [ label, setLabel ] = useState( '' );
40
27
 
41
- const anchorRef = useRef< HTMLDivElement >( null );
42
- const fontPopoverState = usePopupState( { variant: 'popover' } );
43
-
44
28
  const resetFields = () => {
45
29
  setFontFamily( '' );
46
30
  setLabel( '' );
@@ -62,12 +46,14 @@ export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
62
46
  } );
63
47
  };
64
48
 
65
- const isFormInvalid = () => {
66
- return ! fontFamily?.trim() || ! label?.trim();
49
+ const hasEmptyValue = () => {
50
+ return '' === fontFamily.trim() || '' === label.trim();
67
51
  };
68
52
 
53
+ const isSubmitDisabled = hasEmptyValue();
54
+
69
55
  return (
70
- <>
56
+ <PopoverScrollableContent height="auto">
71
57
  <PopoverHeader
72
58
  icon={
73
59
  <>
@@ -85,59 +71,16 @@ export const FontVariableCreation = ( { onClose, onGoBack }: Props ) => {
85
71
 
86
72
  <Divider />
87
73
 
88
- <Stack p={ 1.5 } gap={ 1.5 }>
89
- <Grid container gap={ 0.75 } alignItems="center">
90
- <Grid item xs={ 12 }>
91
- <FormLabel size="small">{ __( 'Name', 'elementor' ) }</FormLabel>
92
- </Grid>
93
- <Grid item xs={ 12 }>
94
- <TextField
95
- size="tiny"
96
- fullWidth
97
- value={ label }
98
- onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
99
- />
100
- </Grid>
101
- </Grid>
102
-
103
- <Grid container gap={ 0.75 } alignItems="center">
104
- <Grid item xs={ 12 }>
105
- <FormLabel size="small">{ __( 'Value', 'elementor' ) }</FormLabel>
106
- </Grid>
107
- <Grid item xs={ 12 }>
108
- <>
109
- <UnstableTag
110
- variant="outlined"
111
- label={ fontFamily }
112
- endIcon={ <ChevronDownIcon fontSize="tiny" /> }
113
- { ...bindTrigger( fontPopoverState ) }
114
- fullWidth
115
- />
116
- <Popover
117
- disablePortal
118
- disableScrollLock
119
- anchorEl={ anchorRef.current }
120
- anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
121
- transformOrigin={ { vertical: 'top', horizontal: -20 } }
122
- { ...bindPopover( fontPopoverState ) }
123
- >
124
- <FontFamilySelector
125
- fontFamilies={ fontFamilies }
126
- fontFamily={ fontFamily }
127
- onFontFamilyChange={ setFontFamily }
128
- onClose={ fontPopoverState.close }
129
- />
130
- </Popover>
131
- </>
132
- </Grid>
133
- </Grid>
134
- </Stack>
74
+ <PopoverContent p={ 2 }>
75
+ <LabelField value={ label } onChange={ setLabel } />
76
+ <FontField value={ fontFamily } onChange={ setFontFamily } />
77
+ </PopoverContent>
135
78
 
136
- <CardActions>
137
- <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 }>
138
81
  { __( 'Create', 'elementor' ) }
139
82
  </Button>
140
83
  </CardActions>
141
- </>
84
+ </PopoverScrollableContent>
142
85
  );
143
86
  };
@@ -1,27 +1,17 @@
1
1
  import * as React from 'react';
2
- import { useId, useRef, useState } from 'react';
3
- import { FontFamilySelector } from '@elementor/editor-controls';
4
- import { useFontFamilies } from '@elementor/editor-editing-panel';
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, ChevronDownIcon, TextIcon } from '@elementor/icons';
7
- import {
8
- bindPopover,
9
- bindTrigger,
10
- Button,
11
- CardActions,
12
- Divider,
13
- FormLabel,
14
- Grid,
15
- IconButton,
16
- Popover,
17
- Stack,
18
- TextField,
19
- UnstableTag,
20
- usePopupState,
21
- } from '@elementor/ui';
6
+ import { ArrowLeftIcon, TextIcon, TrashIcon } from '@elementor/icons';
7
+ import { Button, CardActions, Divider, IconButton } from '@elementor/ui';
22
8
  import { __ } from '@wordpress/i18n';
23
9
 
24
- import { updateVariable, useVariable } from '../hooks/use-prop-variables';
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';
25
15
 
26
16
  const SIZE = 'tiny';
27
17
 
@@ -33,8 +23,10 @@ type Props = {
33
23
  };
34
24
 
35
25
  export const FontVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props ) => {
36
- const variable = useVariable( editId );
26
+ const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp( fontVariablePropTypeUtil );
27
+ const [ deleteConfirmation, setDeleteConfirmation ] = useState( false );
37
28
 
29
+ const variable = useVariable( editId );
38
30
  if ( ! variable ) {
39
31
  throw new Error( `Global font variable "${ editId }" not found` );
40
32
  }
@@ -42,105 +34,105 @@ export const FontVariableEdit = ( { onClose, onGoBack, onSubmit, editId }: Props
42
34
  const [ fontFamily, setFontFamily ] = useState( variable.value );
43
35
  const [ label, setLabel ] = useState( variable.label );
44
36
 
45
- const variableNameId = useId();
46
- const variableValueId = useId();
47
-
48
- const anchorRef = useRef< HTMLDivElement >( null );
49
- const fontPopoverState = usePopupState( { variant: 'popover' } );
50
-
51
- const fontFamilies = useFontFamilies();
52
-
53
37
  const handleUpdate = () => {
54
38
  updateVariable( editId, {
55
39
  value: fontFamily,
56
40
  label,
57
41
  } ).then( () => {
42
+ maybeTriggerBoundPropChange();
58
43
  onSubmit?.();
59
44
  } );
60
45
  };
61
46
 
62
- const noValueChanged = () => fontFamily === variable.value && label === variable.label;
63
- const hasEmptyValue = () => '' === fontFamily.trim() || '' === label.trim();
64
- const isSaveDisabled = () => noValueChanged() || hasEmptyValue();
47
+ const handleDelete = () => {
48
+ deleteVariable( editId ).then( () => {
49
+ maybeTriggerBoundPropChange();
50
+ onSubmit?.();
51
+ } );
52
+ };
53
+
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 hasEmptyValue = () => {
69
+ return ! fontFamily.trim() || ! label.trim();
70
+ };
71
+
72
+ const noValueChanged = () => {
73
+ return fontFamily === variable.value && label === variable.label;
74
+ };
75
+
76
+ const isSubmitDisabled = noValueChanged() || hasEmptyValue();
77
+
78
+ const actions = [];
79
+
80
+ actions.push(
81
+ <IconButton
82
+ key="delete"
83
+ size={ SIZE }
84
+ aria-label={ __( 'Delete', 'elementor' ) }
85
+ onClick={ handleDeleteConfirmation }
86
+ >
87
+ <TrashIcon fontSize={ SIZE } />
88
+ </IconButton>
89
+ );
65
90
 
66
91
  return (
67
92
  <>
68
- <PopoverHeader
69
- icon={
70
- <>
71
- { onGoBack && (
72
- <IconButton size={ SIZE } aria-label={ __( 'Go Back', 'elementor' ) } onClick={ onGoBack }>
73
- <ArrowLeftIcon fontSize={ SIZE } />
74
- </IconButton>
75
- ) }
76
- <TextIcon fontSize={ SIZE } />
77
- </>
78
- }
79
- title={ __( 'Edit variable', 'elementor' ) }
80
- onClose={ onClose }
81
- />
82
-
83
- <Divider />
84
-
85
- <Stack p={ 1.5 } gap={ 1.5 }>
86
- <Grid container gap={ 0.75 } alignItems="center">
87
- <Grid item xs={ 12 }>
88
- <FormLabel htmlFor={ variableNameId } size="small">
89
- { __( 'Name', 'elementor' ) }
90
- </FormLabel>
91
- </Grid>
92
- <Grid item xs={ 12 }>
93
- <TextField
94
- id={ variableNameId }
95
- size="tiny"
96
- fullWidth
97
- value={ label }
98
- onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => setLabel( e.target.value ) }
99
- />
100
- </Grid>
101
- </Grid>
102
-
103
- <Grid container gap={ 0.75 } alignItems="center">
104
- <Grid item xs={ 12 }>
105
- <FormLabel htmlFor={ variableValueId } size="small">
106
- { __( 'Value', 'elementor' ) }
107
- </FormLabel>
108
- </Grid>
109
- <Grid item xs={ 12 }>
93
+ <PopoverScrollableContent height="auto">
94
+ <PopoverHeader
95
+ icon={
110
96
  <>
111
- <UnstableTag
112
- id={ variableValueId }
113
- variant="outlined"
114
- label={ fontFamily }
115
- endIcon={ <ChevronDownIcon fontSize="tiny" /> }
116
- { ...bindTrigger( fontPopoverState ) }
117
- fullWidth
118
- />
119
- <Popover
120
- disablePortal
121
- disableScrollLock
122
- anchorEl={ anchorRef.current }
123
- anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
124
- transformOrigin={ { vertical: 'top', horizontal: -20 } }
125
- { ...bindPopover( fontPopoverState ) }
126
- >
127
- <FontFamilySelector
128
- fontFamilies={ fontFamilies }
129
- fontFamily={ fontFamily }
130
- onFontFamilyChange={ setFontFamily }
131
- onClose={ fontPopoverState.close }
132
- />
133
- </Popover>
97
+ { onGoBack && (
98
+ <IconButton
99
+ size={ SIZE }
100
+ aria-label={ __( 'Go Back', 'elementor' ) }
101
+ onClick={ onGoBack }
102
+ >
103
+ <ArrowLeftIcon fontSize={ SIZE } />
104
+ </IconButton>
105
+ ) }
106
+ <TextIcon fontSize={ SIZE } />
134
107
  </>
135
- </Grid>
136
- </Grid>
137
- </Stack>
138
-
139
- <CardActions>
140
- <Button size="small" variant="contained" disabled={ isSaveDisabled() } onClick={ handleUpdate }>
141
- { __( 'Save', 'elementor' ) }
142
- </Button>
143
- </CardActions>
108
+ }
109
+ title={ __( 'Edit variable', 'elementor' ) }
110
+ onClose={ onClose }
111
+ actions={ actions }
112
+ />
113
+
114
+ <Divider />
115
+
116
+ <PopoverContent p={ 2 }>
117
+ <LabelField value={ label } onChange={ setLabel } />
118
+ <FontField value={ fontFamily } onChange={ setFontFamily } />
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
+ ) }
144
136
  </>
145
137
  );
146
138
  };
@@ -1,6 +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 { PopoverScrollableContent } from '@elementor/editor-editing-panel';
4
5
  import { PopoverHeader, PopoverMenuList, PopoverSearch, type VirtualizedItem } from '@elementor/editor-ui';
5
6
  import { ColorFilterIcon, PlusIcon, SettingsIcon, TextIcon } from '@elementor/icons';
6
7
  import { Divider, IconButton } from '@elementor/ui';
@@ -60,7 +61,7 @@ export const FontVariablesSelection = ( { closePopover, onAdd, onEdit, onSetting
60
61
  type: 'item' as const,
61
62
  value: key,
62
63
  label,
63
- icon: <TextIcon />,
64
+ icon: <TextIcon fontSize={ SIZE } />,
64
65
  secondaryText: value,
65
66
  onEdit: () => onEdit?.( key ),
66
67
  } ) );
@@ -92,25 +93,37 @@ export const FontVariablesSelection = ( { closePopover, onAdd, onEdit, onSetting
92
93
 
93
94
  <Divider />
94
95
 
95
- { hasVariables && hasSearchResults && (
96
- <PopoverMenuList
97
- items={ items }
98
- onSelect={ handleSetVariable }
99
- onClose={ () => {} }
100
- selectedValue={ variable }
101
- data-testid="font-variables-list"
102
- menuListTemplate={ VariablesStyledMenuList }
103
- menuItemContentTemplate={ ( item: VirtualizedItem< 'item', string > ) => (
104
- <MenuItemContent item={ item } />
105
- ) }
106
- />
107
- ) }
108
-
109
- { ! hasSearchResults && hasVariables && (
110
- <NoSearchResults searchValue={ searchValue } onClear={ handleClearSearch } />
111
- ) }
112
-
113
- { ! hasVariables && <NoVariables icon={ <TextIcon fontSize="large" /> } onAdd={ onAdd } /> }
96
+ <PopoverScrollableContent>
97
+ { hasVariables && hasSearchResults && (
98
+ <PopoverMenuList
99
+ items={ items }
100
+ onSelect={ handleSetVariable }
101
+ onClose={ () => {} }
102
+ selectedValue={ variable }
103
+ data-testid="font-variables-list"
104
+ menuListTemplate={ VariablesStyledMenuList }
105
+ menuItemContentTemplate={ ( item: VirtualizedItem< 'item', string > ) => (
106
+ <MenuItemContent item={ item } />
107
+ ) }
108
+ />
109
+ ) }
110
+
111
+ { ! hasSearchResults && hasVariables && (
112
+ <NoSearchResults
113
+ searchValue={ searchValue }
114
+ onClear={ handleClearSearch }
115
+ icon={ <TextIcon fontSize="large" /> }
116
+ />
117
+ ) }
118
+
119
+ { ! hasVariables && (
120
+ <NoVariables
121
+ title={ __( 'Create your first font variable', 'elementor' ) }
122
+ icon={ <TextIcon fontSize="large" /> }
123
+ onAdd={ onAdd }
124
+ />
125
+ ) }
126
+ </PopoverScrollableContent>
114
127
  </>
115
128
  );
116
129
  };
@@ -2,4 +2,5 @@ import { styled, UnstableColorIndicator } from '@elementor/ui';
2
2
 
3
3
  export const ColorIndicator = styled( UnstableColorIndicator )( ( { theme } ) => ( {
4
4
  borderRadius: `${ theme.shape.borderRadius / 2 }px`,
5
+ marginRight: theme.spacing( 0.25 ),
5
6
  } ) );
@@ -0,0 +1,55 @@
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 Variable', 'elementor' ) }
32
+ </DialogTitle>
33
+ <DialogContent>
34
+ <DialogContentText variant="body2" color="textPrimary">
35
+ { __( 'You are about to delete', 'elementor' ) }
36
+ <Typography variant="subtitle2" component="span">
37
+ &nbsp;{ label }&nbsp;
38
+ </Typography>
39
+ { __(
40
+ 'Variable. Note that its value is still being used anywhere on your site where it was connected to the variable.',
41
+ 'elementor'
42
+ ) }
43
+ </DialogContentText>
44
+ </DialogContent>
45
+ <DialogActions>
46
+ <Button color="secondary" onClick={ closeDialog }>
47
+ { __( 'Cancel', 'elementor' ) }
48
+ </Button>
49
+ <Button variant="contained" color="error" onClick={ onConfirm }>
50
+ { __( 'Delete', 'elementor' ) }
51
+ </Button>
52
+ </DialogActions>
53
+ </Dialog>
54
+ );
55
+ };
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
- import type { VirtualizedItem } from '@elementor/editor-ui';
2
+ import { EllipsisWithTooltip, type VirtualizedItem } from '@elementor/editor-ui';
3
3
  import { EditIcon } from '@elementor/icons';
4
- import { IconButton, ListItemIcon, ListItemText } from '@elementor/ui';
4
+ import { Box, IconButton, ListItemIcon, Typography } from '@elementor/ui';
5
5
  import { __ } from '@wordpress/i18n';
6
6
 
7
7
  const SIZE = 'tiny';
@@ -12,28 +12,34 @@ export const MenuItemContent = < T, V extends string >( { item }: { item: Virtua
12
12
  return (
13
13
  <>
14
14
  <ListItemIcon>{ item.icon }</ListItemIcon>
15
- <ListItemText
16
- primary={ item.label || item.value }
17
- secondary={ item.secondaryText }
18
- primaryTypographyProps={ {
19
- variant: 'body2',
20
- color: 'text.secondary',
21
- style: {
22
- lineHeight: 2,
23
- display: 'inline-block',
24
- overflow: 'hidden',
25
- textOverflow: 'ellipsis',
26
- whiteSpace: 'nowrap',
27
- maxWidth: '81px',
28
- },
15
+ <Box
16
+ sx={ {
17
+ flex: 1,
18
+ minWidth: 0,
19
+ display: 'flex',
20
+ alignItems: 'center',
21
+ gap: 1,
29
22
  } }
30
- secondaryTypographyProps={ {
31
- variant: 'caption',
32
- color: 'text.tertiary',
33
- style: { marginTop: '1px', lineHeight: '1' },
34
- } }
35
- sx={ { display: 'flex', alignItems: 'center', gap: 1 } }
36
- />
23
+ >
24
+ <EllipsisWithTooltip
25
+ title={ item.label || item.value }
26
+ as={ Typography }
27
+ variant="caption"
28
+ color="text.primary"
29
+ sx={ { marginTop: '1px', lineHeight: '2' } }
30
+ maxWidth="50%"
31
+ />
32
+ { item.secondaryText && (
33
+ <EllipsisWithTooltip
34
+ title={ item.secondaryText }
35
+ as={ Typography }
36
+ variant="caption"
37
+ color="text.tertiary"
38
+ sx={ { marginTop: '1px', lineHeight: '1' } }
39
+ maxWidth="50%"
40
+ />
41
+ ) }
42
+ </Box>
37
43
  { !! onEdit && (
38
44
  <IconButton
39
45
  sx={ { mx: 1, opacity: '0' } }
@@ -1,34 +1,32 @@
1
1
  import * as React from 'react';
2
- import { ColorFilterIcon } from '@elementor/icons';
3
2
  import { Link, Stack, Typography } from '@elementor/ui';
4
3
  import { __ } from '@wordpress/i18n';
5
4
 
6
5
  type Props = {
7
6
  searchValue: string;
8
7
  onClear?: () => void;
8
+ icon?: React.ReactNode;
9
9
  };
10
10
 
11
- export const NoSearchResults = ( { searchValue, onClear }: Props ) => {
11
+ export const NoSearchResults = ( { searchValue, onClear, icon }: Props ) => {
12
12
  return (
13
13
  <Stack
14
14
  gap={ 1 }
15
15
  alignItems="center"
16
16
  justifyContent="center"
17
17
  height="100%"
18
+ p={ 2.5 }
18
19
  color="text.secondary"
19
- sx={ { p: 2.5, pb: 5.5 } }
20
+ sx={ { pb: 3.5 } }
20
21
  >
21
- <ColorFilterIcon fontSize="large" />
22
-
22
+ { icon }
23
23
  <Typography align="center" variant="subtitle2">
24
24
  { __( 'Sorry, nothing matched', 'elementor' ) }
25
25
  <br />
26
26
  &ldquo;{ searchValue }&rdquo;.
27
27
  </Typography>
28
-
29
- <Typography align="center" variant="caption">
28
+ <Typography align="center" variant="caption" sx={ { display: 'flex', flexDirection: 'column' } }>
30
29
  { __( 'Try something else.', 'elementor' ) }
31
- <br />
32
30
  <Link color="text.secondary" variant="caption" component="button" onClick={ onClear }>
33
31
  { __( 'Clear & try again', 'elementor' ) }
34
32
  </Link>
@@ -4,10 +4,11 @@ import { __ } from '@wordpress/i18n';
4
4
 
5
5
  type Props = {
6
6
  icon?: React.ReactNode;
7
+ title?: string;
7
8
  onAdd?: () => void;
8
9
  };
9
10
 
10
- export const NoVariables = ( { icon, onAdd }: Props ) => (
11
+ export const NoVariables = ( { icon, title, onAdd }: Props ) => (
11
12
  <Stack
12
13
  gap={ 1 }
13
14
  alignItems="center"
@@ -19,7 +20,7 @@ export const NoVariables = ( { icon, onAdd }: Props ) => (
19
20
  { icon }
20
21
 
21
22
  <Typography align="center" variant="subtitle2">
22
- { __( 'Create your first variable', 'elementor' ) }
23
+ { title }
23
24
  </Typography>
24
25
 
25
26
  <Typography align="center" variant="caption" maxWidth="180px">