@elementor/editor-variables 0.14.0 → 0.15.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.
@@ -0,0 +1,43 @@
1
+ import * as React from 'react';
2
+ import { DetachIcon } from '@elementor/icons';
3
+ import { Box, IconButton, Stack, Typography, UnstableTag as Tag, type UnstableTagProps } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
6
+ export const SIZE = 'tiny';
7
+
8
+ interface VariableTagProps extends UnstableTagProps {
9
+ onUnlink?: () => void;
10
+ }
11
+
12
+ export const VariableTag = ( { startIcon, label, onUnlink, ...props }: VariableTagProps ) => {
13
+ const actions = [];
14
+
15
+ if ( onUnlink ) {
16
+ actions.push(
17
+ <IconButton key="unlink" size={ SIZE } onClick={ onUnlink } aria-label={ __( 'Unlink', 'elementor' ) }>
18
+ <DetachIcon fontSize={ SIZE } />
19
+ </IconButton>
20
+ );
21
+ }
22
+
23
+ return (
24
+ <Tag
25
+ fullWidth
26
+ showActionsOnHover
27
+ startIcon={
28
+ <Stack gap={ 0.5 } direction="row" alignItems="center">
29
+ { startIcon }
30
+ </Stack>
31
+ }
32
+ label={
33
+ <Box sx={ { display: 'inline-grid', minWidth: 0 } }>
34
+ <Typography sx={ { lineHeight: 1.34 } } variant="caption" noWrap>
35
+ { label }
36
+ </Typography>
37
+ </Box>
38
+ }
39
+ actions={ actions }
40
+ { ...props }
41
+ />
42
+ );
43
+ };
@@ -0,0 +1,7 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ export const PopoverContentRefContext = createContext< React.RefObject< HTMLDivElement > | null >( null );
4
+
5
+ export const usePopoverContentRef = () => {
6
+ return useContext( PopoverContentRefContext );
7
+ };
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { useRef, useState } from 'react';
3
+ import { Box } from '@elementor/ui';
3
4
 
4
5
  import { colorVariablePropTypeUtil } from '../prop-types/color-variable-prop-type';
5
6
  import { fontVariablePropTypeUtil } from '../prop-types/font-variable-prop-type';
@@ -10,6 +11,7 @@ import { ColorVariablesSelection } from './color-variables-selection';
10
11
  import { FontVariableCreation } from './font-variable-creation';
11
12
  import { FontVariableEdit } from './font-variable-edit';
12
13
  import { FontVariablesSelection } from './font-variables-selection';
14
+ import { PopoverContentRefContext } from './variable-selection-popover.context';
13
15
 
14
16
  const VIEW_LIST = 'list';
15
17
  const VIEW_ADD = 'add';
@@ -26,15 +28,22 @@ type Props = {
26
28
  export const VariableSelectionPopover = ( { closePopover, propTypeKey, selectedVariable }: Props ) => {
27
29
  const [ currentView, setCurrentView ] = useState< View >( VIEW_LIST );
28
30
  const editIdRef = useRef< string >( '' );
31
+ const anchorRef = useRef< HTMLDivElement >( null );
29
32
 
30
- return renderStage( {
31
- propTypeKey,
32
- currentView,
33
- selectedVariable,
34
- editIdRef,
35
- setCurrentView,
36
- closePopover,
37
- } );
33
+ return (
34
+ <PopoverContentRefContext.Provider value={ anchorRef }>
35
+ <Box ref={ anchorRef }>
36
+ { renderStage( {
37
+ propTypeKey,
38
+ currentView,
39
+ selectedVariable,
40
+ editIdRef,
41
+ setCurrentView,
42
+ closePopover,
43
+ } ) }
44
+ </Box>
45
+ </PopoverContentRefContext.Provider>
46
+ );
38
47
  };
39
48
 
40
49
  type StageProps = {
@@ -2,27 +2,15 @@ import * as React from 'react';
2
2
  import { useId, useRef } from 'react';
3
3
  import { useBoundProp } from '@elementor/editor-controls';
4
4
  import { colorPropTypeUtil } from '@elementor/editor-props';
5
- import { ColorFilterIcon, DetachIcon } from '@elementor/icons';
6
- import {
7
- bindPopover,
8
- bindTrigger,
9
- Box,
10
- IconButton,
11
- Popover,
12
- Stack,
13
- Typography,
14
- UnstableTag as Tag,
15
- usePopupState,
16
- } from '@elementor/ui';
17
- import { __ } from '@wordpress/i18n';
5
+ import { ColorFilterIcon } from '@elementor/icons';
6
+ import { bindPopover, bindTrigger, Box, Popover, usePopupState } from '@elementor/ui';
18
7
 
19
8
  import { ColorIndicator } from '../components/ui/color-indicator';
9
+ import { SIZE, VariableTag } from '../components/ui/variable-tag';
20
10
  import { VariableSelectionPopover } from '../components/variable-selection-popover';
21
11
  import { useVariable } from '../hooks/use-prop-variables';
22
12
  import { colorVariablePropTypeUtil } from '../prop-types/color-variable-prop-type';
23
13
 
24
- const SIZE = 'tiny';
25
-
26
14
  export const ColorVariableControl = () => {
27
15
  const { setValue: setColor } = useBoundProp();
28
16
  const { value: variableValue } = useBoundProp( colorVariablePropTypeUtil );
@@ -46,30 +34,15 @@ export const ColorVariableControl = () => {
46
34
 
47
35
  return (
48
36
  <Box ref={ anchorRef }>
49
- <Tag
50
- fullWidth
51
- showActionsOnHover
37
+ <VariableTag
38
+ label={ selectedVariable.label }
52
39
  startIcon={
53
- <Stack spacing={ 0.75 } direction="row" alignItems="center">
40
+ <>
41
+ <ColorFilterIcon fontSize={ SIZE } />
54
42
  <ColorIndicator size="inherit" value={ selectedVariable.value } component="span" />
55
- <ColorFilterIcon fontSize="inherit" sx={ { mr: 1 } } />
56
- </Stack>
57
- }
58
- label={
59
- <Box sx={ { display: 'inline-grid', minWidth: 0 } }>
60
- <Typography
61
- sx={ { textOverflow: 'ellipsis', overflowX: 'hidden', lineHeight: 1 } }
62
- variant="caption"
63
- >
64
- { selectedVariable.label }
65
- </Typography>
66
- </Box>
67
- }
68
- actions={
69
- <IconButton size={ SIZE } onClick={ unlinkVariable } aria-label={ __( 'Unlink', 'elementor' ) }>
70
- <DetachIcon fontSize={ SIZE } />
71
- </IconButton>
43
+ </>
72
44
  }
45
+ onUnlink={ unlinkVariable }
73
46
  { ...bindTrigger( popupState ) }
74
47
  />
75
48
  <Popover
@@ -77,6 +50,9 @@ export const ColorVariableControl = () => {
77
50
  anchorEl={ anchorRef.current }
78
51
  anchorOrigin={ { vertical: 'bottom', horizontal: 'right' } }
79
52
  transformOrigin={ { vertical: 'top', horizontal: 'right' } }
53
+ PaperProps={ {
54
+ sx: { my: 1 },
55
+ } }
80
56
  { ...bindPopover( popupState ) }
81
57
  >
82
58
  <VariableSelectionPopover
@@ -2,26 +2,14 @@ import * as React from 'react';
2
2
  import { useId, useRef } from 'react';
3
3
  import { useBoundProp } from '@elementor/editor-controls';
4
4
  import { stringPropTypeUtil } from '@elementor/editor-props';
5
- import { ColorFilterIcon, DetachIcon } from '@elementor/icons';
6
- import {
7
- bindPopover,
8
- bindTrigger,
9
- Box,
10
- IconButton,
11
- Popover,
12
- Stack,
13
- Typography,
14
- UnstableTag as Tag,
15
- usePopupState,
16
- } from '@elementor/ui';
17
- import { __ } from '@wordpress/i18n';
5
+ import { ColorFilterIcon } from '@elementor/icons';
6
+ import { bindPopover, bindTrigger, Box, Popover, usePopupState } from '@elementor/ui';
18
7
 
8
+ import { SIZE, VariableTag } from '../components/ui/variable-tag';
19
9
  import { VariableSelectionPopover } from '../components/variable-selection-popover';
20
10
  import { useVariable } from '../hooks/use-prop-variables';
21
11
  import { fontVariablePropTypeUtil } from '../prop-types/font-variable-prop-type';
22
12
 
23
- const SIZE = 'tiny';
24
-
25
13
  export const FontVariableControl = () => {
26
14
  const { setValue: setFontFamily } = useBoundProp();
27
15
  const { value: variableValue } = useBoundProp( fontVariablePropTypeUtil );
@@ -45,29 +33,10 @@ export const FontVariableControl = () => {
45
33
 
46
34
  return (
47
35
  <Box ref={ anchorRef }>
48
- <Tag
49
- fullWidth
50
- showActionsOnHover
51
- startIcon={
52
- <Stack spacing={ 0.75 } direction="row" alignItems="center">
53
- <ColorFilterIcon fontSize={ 'inherit' } sx={ { mr: 1 } } />
54
- </Stack>
55
- }
56
- label={
57
- <Box sx={ { display: 'inline-grid', minWidth: 0 } }>
58
- <Typography
59
- sx={ { textOverflow: 'ellipsis', overflowX: 'hidden', lineHeight: 1 } }
60
- variant="caption"
61
- >
62
- { selectedVariable.label }
63
- </Typography>
64
- </Box>
65
- }
66
- actions={
67
- <IconButton size={ SIZE } onClick={ unlinkVariable } aria-label={ __( 'Unlink', 'elementor' ) }>
68
- <DetachIcon fontSize={ SIZE } />
69
- </IconButton>
70
- }
36
+ <VariableTag
37
+ label={ selectedVariable.label }
38
+ startIcon={ <ColorFilterIcon fontSize={ SIZE } /> }
39
+ onUnlink={ unlinkVariable }
71
40
  { ...bindTrigger( popupState ) }
72
41
  />
73
42
  <Popover
@@ -75,6 +44,9 @@ export const FontVariableControl = () => {
75
44
  anchorEl={ anchorRef.current }
76
45
  anchorOrigin={ { vertical: 'bottom', horizontal: 'right' } }
77
46
  transformOrigin={ { vertical: 'top', horizontal: 'right' } }
47
+ PaperProps={ {
48
+ sx: { my: 1 },
49
+ } }
78
50
  { ...bindPopover( popupState ) }
79
51
  >
80
52
  <VariableSelectionPopover
@@ -2,8 +2,6 @@ import { useMemo } from 'react';
2
2
  import { type PropKey } from '@elementor/editor-props';
3
3
 
4
4
  import { service } from '../service';
5
- import { type TVariable } from '../storage';
6
- import { styleVariablesRepository } from '../style-variables-repository';
7
5
  import { type Variable } from '../types';
8
6
 
9
7
  export const useVariable = ( key: string ) => {
@@ -37,13 +35,13 @@ const usePropVariables = ( propKey: PropKey ) => {
37
35
  return useMemo( () => normalizeVariables( propKey ), [ propKey ] );
38
36
  };
39
37
 
38
+ const isNotDeleted = ( { deleted }: { deleted?: boolean } ) => ! deleted;
39
+
40
40
  const normalizeVariables = ( propKey: string ) => {
41
41
  const variables = service.variables();
42
42
 
43
- styleVariablesRepository.update( variables );
44
-
45
43
  return Object.entries( variables )
46
- .filter( ( [ , { type } ] ) => type === propKey )
44
+ .filter( ( [ , variable ] ) => variable.type === propKey && isNotDeleted( variable ) )
47
45
  .map( ( [ key, { label, value } ] ) => ( {
48
46
  key,
49
47
  label,
@@ -52,23 +50,19 @@ const normalizeVariables = ( propKey: string ) => {
52
50
  };
53
51
 
54
52
  export const createVariable = ( newVariable: Variable ): Promise< string > => {
55
- return service.create( newVariable ).then( ( { id, variable }: { id: string; variable: TVariable } ) => {
56
- styleVariablesRepository.update( {
57
- [ id ]: variable,
58
- } );
59
-
53
+ return service.create( newVariable ).then( ( { id }: { id: string } ) => {
60
54
  return id;
61
55
  } );
62
56
  };
63
57
 
64
58
  export const updateVariable = ( updateId: string, { value, label }: { value: string; label: string } ) => {
65
- return service
66
- .update( updateId, { value, label } )
67
- .then( ( { id, variable }: { id: string; variable: TVariable } ) => {
68
- styleVariablesRepository.update( {
69
- [ id ]: variable,
70
- } );
59
+ return service.update( updateId, { value, label } ).then( ( { id }: { id: string } ) => {
60
+ return id;
61
+ } );
62
+ };
71
63
 
72
- return id;
73
- } );
64
+ export const deleteVariable = ( deleteId: string ) => {
65
+ return service.delete( deleteId ).then( ( { id }: { id: string } ) => {
66
+ return id;
67
+ } );
74
68
  };