@elementor/editor-editing-panel 1.2.0 → 1.4.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 (34) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/index.js +852 -615
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +790 -544
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +13 -11
  7. package/src/components/conditional-tooltip-wrapper.tsx +52 -0
  8. package/src/components/css-class-selector.tsx +59 -19
  9. package/src/components/multi-combobox/types.ts +1 -0
  10. package/src/components/style-sections/border-section/border-radius-field.tsx +4 -4
  11. package/src/components/style-sections/border-section/border-width-field.tsx +4 -4
  12. package/src/components/style-sections/layout-section/align-items-field.tsx +40 -60
  13. package/src/components/style-sections/layout-section/align-self-child-field.tsx +72 -0
  14. package/src/components/style-sections/layout-section/flex-direction-field.tsx +2 -2
  15. package/src/components/style-sections/layout-section/flex-order-field.tsx +14 -8
  16. package/src/components/style-sections/layout-section/flex-size-field.tsx +164 -0
  17. package/src/components/style-sections/layout-section/gap-control-field.tsx +18 -0
  18. package/src/components/style-sections/layout-section/justify-content-field.tsx +51 -78
  19. package/src/components/style-sections/layout-section/layout-section.tsx +9 -2
  20. package/src/components/style-sections/layout-section/utils/rotated-icon.tsx +52 -0
  21. package/src/components/style-sections/layout-section/wrap-field.tsx +1 -1
  22. package/src/components/style-sections/position-section/position-section.tsx +3 -3
  23. package/src/components/style-sections/typography-section/line-height-field.tsx +21 -0
  24. package/src/components/style-sections/typography-section/text-style-field.tsx +31 -8
  25. package/src/components/style-sections/typography-section/typography-section.tsx +3 -1
  26. package/src/components/style-tab.tsx +2 -11
  27. package/src/contexts/style-context.tsx +2 -2
  28. package/src/controls-registry/controls-registry.tsx +4 -0
  29. package/src/dynamics/components/dynamic-selection-control.tsx +8 -5
  30. package/src/dynamics/components/dynamic-selection.tsx +10 -8
  31. package/src/dynamics/dynamic-control.tsx +9 -11
  32. package/src/dynamics/utils.ts +20 -3
  33. package/src/hooks/use-style-prop-history.ts +1 -1
  34. package/src/hooks/use-styles-field.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-editing-panel",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,18 +39,20 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "^0.17.1",
43
- "@elementor/editor-controls": "^0.1.1",
44
- "@elementor/editor-elements": "^0.3.1",
45
- "@elementor/menus": "^0.1.1",
46
- "@elementor/editor-props": "^0.3.0",
47
- "@elementor/editor-panels": "^0.10.1",
48
- "@elementor/editor-responsive": "^0.12.3",
49
- "@elementor/editor-styles": "^0.3.0",
50
- "@elementor/editor-v1-adapters": "^0.8.4",
42
+ "@elementor/editor": "0.17.2",
43
+ "@elementor/editor-controls": "0.3.0",
44
+ "@elementor/editor-elements": "0.3.3",
45
+ "@elementor/menus": "0.1.2",
46
+ "@elementor/editor-props": "0.5.0",
47
+ "@elementor/editor-panels": "0.10.2",
48
+ "@elementor/editor-responsive": "0.12.4",
49
+ "@elementor/editor-styles": "0.3.2",
50
+ "@elementor/editor-styles-repository": "0.2.0",
51
+ "@elementor/editor-v1-adapters": "0.8.5",
51
52
  "@elementor/icons": "^1.20.0",
53
+ "@elementor/schema": "0.1.2",
52
54
  "@elementor/ui": "^1.22.0",
53
- "@elementor/utils": "^0.3.0",
55
+ "@elementor/utils": "0.3.0",
54
56
  "@wordpress/i18n": "^5.13.0"
55
57
  },
56
58
  "peerDependencies": {
@@ -0,0 +1,52 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import * as React from 'react';
3
+ import { Box, Tooltip } from '@elementor/ui';
4
+
5
+ type ConditionalTooltipWrapperProps = {
6
+ maxWidth: React.CSSProperties[ 'maxWidth' ];
7
+ title: string;
8
+ };
9
+
10
+ export const ConditionalTooltipWrapper = ( { maxWidth, title }: ConditionalTooltipWrapperProps ) => {
11
+ const elRef = useRef< HTMLElement >( null );
12
+ const [ isOverflown, setIsOverflown ] = useState( false );
13
+
14
+ useEffect( () => {
15
+ const onResize = () => {
16
+ const element = elRef.current;
17
+
18
+ if ( element ) {
19
+ setIsOverflown( element.scrollWidth > element.clientWidth );
20
+ }
21
+ };
22
+
23
+ onResize();
24
+
25
+ window.addEventListener( 'resize', onResize );
26
+
27
+ return () => {
28
+ window.removeEventListener( 'resize', onResize );
29
+ };
30
+ }, [] );
31
+
32
+ if ( isOverflown ) {
33
+ return (
34
+ <Tooltip title={ title } placement="top">
35
+ <Content maxWidth={ maxWidth } ref={ elRef } title={ title } />
36
+ </Tooltip>
37
+ );
38
+ }
39
+
40
+ return <Content maxWidth={ maxWidth } ref={ elRef } title={ title } />;
41
+ };
42
+
43
+ const Content = React.forwardRef( ( { maxWidth, title, ...rest }: ConditionalTooltipWrapperProps, ref ) => (
44
+ <Box
45
+ ref={ ref }
46
+ position="relative"
47
+ sx={ { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth } }
48
+ { ...rest }
49
+ >
50
+ { title }
51
+ </Box>
52
+ ) );
@@ -1,32 +1,44 @@
1
1
  import * as React from 'react';
2
- import { updateSettings, useElementSetting, useElementStyles } from '@elementor/editor-elements';
2
+ import { updateSettings, useElementSetting } from '@elementor/editor-elements';
3
3
  import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
4
4
  import { type StyleDefinitionID } from '@elementor/editor-styles';
5
+ import { ELEMENTS_STYLES_PROVIDER_KEY, useAllStylesByProvider } from '@elementor/editor-styles-repository';
5
6
  import { Chip, Stack, Typography } from '@elementor/ui';
6
7
  import { __ } from '@wordpress/i18n';
7
8
 
8
9
  import { useClassesProp } from '../contexts/classes-prop-context';
9
10
  import { useElement } from '../contexts/element-context';
10
11
  import { useStyle } from '../contexts/style-context';
12
+ import { ConditionalTooltipWrapper } from './conditional-tooltip-wrapper';
11
13
  import { MultiCombobox, type Option } from './multi-combobox';
12
14
 
13
15
  const ID = 'elementor-css-class-selector';
14
16
  const TAGS_LIMIT = 8;
15
17
 
18
+ const EMPTY_OPTION = {
19
+ label: __( 'local', 'elementor' ),
20
+ value: '',
21
+ fixed: true,
22
+ color: 'primary',
23
+ provider: ELEMENTS_STYLES_PROVIDER_KEY,
24
+ } satisfies Option;
25
+
26
+ /**
27
+ * Applied - Classes applied to an element.
28
+ * Active - Class that is currently on edit mode.
29
+ */
30
+
16
31
  export function CssClassSelector() {
17
32
  const options = useOptions();
33
+ const [ appliedIds, setAppliedIds ] = useAppliedClassesIds();
18
34
 
19
35
  const { id: activeId, setId: setActiveId } = useStyle();
20
- const [ appliedIds ] = useAppliedClassesIds();
21
36
 
22
- const handleApply = useHandleApply();
37
+ const handleApply = useHandleApply( appliedIds, setAppliedIds );
23
38
  const handleActivate = ( { value }: Option ) => setActiveId( value );
24
39
 
25
- const active = options.find( ( option ) => option.value === activeId ) || null;
26
-
27
- const applied = appliedIds
28
- .map( ( id ) => options.find( ( option ) => option.value === id ) )
29
- .filter( ( option ) => !! option );
40
+ const applied = useAppliedOptions( options, appliedIds );
41
+ const active = applied.find( ( option ) => option.value === activeId ) ?? EMPTY_OPTION;
30
42
 
31
43
  return (
32
44
  <Stack gap={ 1 } p={ 2 }>
@@ -51,11 +63,12 @@ export function CssClassSelector() {
51
63
  { ...chipProps }
52
64
  key={ chipProps.key }
53
65
  size="small"
54
- label={ value.label }
66
+ label={ <ConditionalTooltipWrapper maxWidth="10ch" title={ value.label } /> }
55
67
  variant={ isActive ? 'filled' : 'standard' }
56
68
  color={ isActive && value.color ? value.color : 'default' }
57
69
  onClick={ () => handleActivate( value ) }
58
70
  onDelete={ null }
71
+ aria-pressed={ isActive }
59
72
  />
60
73
  );
61
74
  } )
@@ -68,14 +81,40 @@ export function CssClassSelector() {
68
81
  function useOptions() {
69
82
  const { element } = useElement();
70
83
 
71
- const styleDefs = useElementStyles( element.id );
84
+ return useAllStylesByProvider( { elementId: element.id } ).flatMap< Option >( ( [ providerKey, styleDefs ] ) => {
85
+ const isElements = providerKey === ELEMENTS_STYLES_PROVIDER_KEY;
86
+
87
+ // Add empty local option for elements, as fallback.
88
+ if ( isElements && styleDefs.length === 0 ) {
89
+ return [ EMPTY_OPTION ];
90
+ }
91
+
92
+ return styleDefs.map( ( styleDef ) => {
93
+ return {
94
+ label: styleDef.label,
95
+ value: styleDef.id,
96
+ fixed: isElements,
97
+ color: isElements ? 'primary' : 'global',
98
+ provider: providerKey,
99
+ };
100
+ } );
101
+ } );
102
+ }
103
+
104
+ function useAppliedOptions( options: Option[], appliedIds: StyleDefinitionID[] ) {
105
+ const applied = appliedIds
106
+ .map( ( id ) => options.find( ( option ) => option.value === id ) )
107
+ .filter( ( option ) => !! option );
108
+
109
+ const hasElementsProviderStyleApplied = applied.some(
110
+ ( option ) => option.provider === ELEMENTS_STYLES_PROVIDER_KEY
111
+ );
72
112
 
73
- return Object.values( styleDefs ).map< Option >( ( styleDef ) => ( {
74
- label: styleDef.label,
75
- value: styleDef.id,
76
- fixed: true,
77
- color: 'primary',
78
- } ) );
113
+ if ( ! hasElementsProviderStyleApplied ) {
114
+ applied.unshift( EMPTY_OPTION );
115
+ }
116
+
117
+ return applied;
79
118
  }
80
119
 
81
120
  function useAppliedClassesIds() {
@@ -96,12 +135,13 @@ function useAppliedClassesIds() {
96
135
  return [ value, setValue ] as const;
97
136
  }
98
137
 
99
- function useHandleApply() {
138
+ function useHandleApply( appliedIds: StyleDefinitionID[], setAppliedIds: ( ids: StyleDefinitionID[] ) => void ) {
100
139
  const { id: activeId, setId: setActiveId } = useStyle();
101
- const [ appliedIds, setAppliedIds ] = useAppliedClassesIds();
102
140
 
103
141
  return ( selectedOptions: Option[] ) => {
104
- const selectedValues = selectedOptions.map( ( { value } ) => value );
142
+ const selectedValues = selectedOptions
143
+ .map( ( { value } ) => value )
144
+ .filter( ( value ) => value !== EMPTY_OPTION.value );
105
145
 
106
146
  const isSameClassesAlreadyApplied =
107
147
  selectedValues.length === appliedIds.length &&
@@ -4,6 +4,7 @@ export type Option = {
4
4
  fixed?: boolean;
5
5
  // TODO: Should be remove from here or use some kind of `meta`
6
6
  color?: 'primary' | 'global';
7
+ provider?: string;
7
8
  };
8
9
 
9
10
  export type Action = {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type EqualUnequalItems, EqualUnequalSizesControl } from '@elementor/editor-controls';
3
- import type { BorderRadiusPropValue } from '@elementor/editor-props';
3
+ import { borderRadiusPropTypeUtil } from '@elementor/editor-props';
4
4
  import {
5
5
  BorderCornersIcon,
6
6
  RadiusBottomLeftIcon,
@@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n';
12
12
 
13
13
  import { StylesField } from '../../../controls-registry/styles-field';
14
14
 
15
- const corners: EqualUnequalItems< BorderRadiusPropValue[ '$$type' ], BorderRadiusPropValue > = [
15
+ const corners: EqualUnequalItems = [
16
16
  {
17
17
  label: __( 'Top Left', 'elementor' ),
18
18
  icon: <RadiusTopLeftIcon fontSize={ 'tiny' } />,
@@ -39,10 +39,10 @@ export const BorderRadiusField = () => {
39
39
  return (
40
40
  <StylesField bind={ 'border-radius' }>
41
41
  <EqualUnequalSizesControl
42
+ items={ corners }
42
43
  label={ __( 'Border Radius', 'elementor' ) }
43
44
  icon={ <BorderCornersIcon fontSize={ 'tiny' } /> }
44
- items={ corners }
45
- multiSizeType={ 'border-radius' }
45
+ multiSizePropTypeUtil={ borderRadiusPropTypeUtil }
46
46
  />
47
47
  </StylesField>
48
48
  );
@@ -1,12 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { type EqualUnequalItems, EqualUnequalSizesControl } from '@elementor/editor-controls';
3
- import { type BorderWidthPropValue } from '@elementor/editor-props';
3
+ import { borderWidthPropTypeUtil } from '@elementor/editor-props';
4
4
  import { SideAllIcon, SideBottomIcon, SideLeftIcon, SideRightIcon, SideTopIcon } from '@elementor/icons';
5
5
  import { __ } from '@wordpress/i18n';
6
6
 
7
7
  import { StylesField } from '../../../controls-registry/styles-field';
8
8
 
9
- const edges: EqualUnequalItems< BorderWidthPropValue[ '$$type' ], BorderWidthPropValue > = [
9
+ const edges: EqualUnequalItems = [
10
10
  {
11
11
  label: __( 'Top', 'elementor' ),
12
12
  icon: <SideTopIcon fontSize={ 'tiny' } />,
@@ -33,10 +33,10 @@ export const BorderWidthField = () => {
33
33
  return (
34
34
  <StylesField bind={ 'border-width' }>
35
35
  <EqualUnequalSizesControl
36
+ items={ edges }
36
37
  label={ __( 'Border Width', 'elementor' ) }
37
38
  icon={ <SideAllIcon fontSize={ 'tiny' } /> }
38
- items={ edges }
39
- multiSizeType={ 'border-width' }
39
+ multiSizePropTypeUtil={ borderWidthPropTypeUtil }
40
40
  />
41
41
  </StylesField>
42
42
  );
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import type { JSX } from 'react';
3
2
  import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
4
3
  import {
5
4
  LayoutAlignCenterIcon as CenterIcon,
@@ -7,19 +6,52 @@ import {
7
6
  LayoutAlignRightIcon,
8
7
  LayoutDistributeVerticalIcon as JustifyIcon,
9
8
  } from '@elementor/icons';
10
- import { DirectionProvider, Grid, ThemeProvider, type ToggleButtonProps, useTheme, withDirection } from '@elementor/ui';
9
+ import { DirectionProvider, Grid, ThemeProvider, withDirection } from '@elementor/ui';
11
10
  import { __ } from '@wordpress/i18n';
12
11
 
13
12
  import { StylesField } from '../../../controls-registry/styles-field';
14
13
  import { useDirection } from '../../../hooks/use-direction';
15
- import { useStylesField } from '../../../hooks/use-styles-field';
16
- import { type FlexDirection } from './flex-direction-field';
14
+ import { RotatedIcon } from './utils/rotated-icon';
17
15
 
18
- type AlignItems = 'start' | 'center' | 'end' | 'justify';
16
+ type AlignItems = 'start' | 'center' | 'end' | 'stretch';
17
+
18
+ const StartIcon = withDirection( LayoutAlignLeftIcon );
19
+ const EndIcon = withDirection( LayoutAlignRightIcon );
20
+
21
+ const iconProps = {
22
+ isClockwise: false,
23
+ offset: 90,
24
+ };
25
+
26
+ const options: ToggleButtonGroupItem< AlignItems >[] = [
27
+ {
28
+ value: 'start',
29
+ label: __( 'Start', 'elementor' ),
30
+ renderContent: ( { size } ) => <RotatedIcon icon={ StartIcon } size={ size } { ...iconProps } />,
31
+ showTooltip: true,
32
+ },
33
+ {
34
+ value: 'center',
35
+ label: __( 'Center', 'elementor' ),
36
+ renderContent: ( { size } ) => <RotatedIcon icon={ CenterIcon } size={ size } { ...iconProps } />,
37
+ showTooltip: true,
38
+ },
39
+ {
40
+ value: 'end',
41
+ label: __( 'End', 'elementor' ),
42
+ renderContent: ( { size } ) => <RotatedIcon icon={ EndIcon } size={ size } { ...iconProps } />,
43
+ showTooltip: true,
44
+ },
45
+ {
46
+ value: 'stretch',
47
+ label: __( 'Stretch', 'elementor' ),
48
+ renderContent: ( { size } ) => <RotatedIcon icon={ JustifyIcon } size={ size } { ...iconProps } />,
49
+ showTooltip: true,
50
+ },
51
+ ];
19
52
 
20
53
  export const AlignItemsField = () => {
21
- const options = useOptions(),
22
- { isSiteRtl } = useDirection();
54
+ const { isSiteRtl } = useDirection();
23
55
 
24
56
  return (
25
57
  <DirectionProvider rtl={ isSiteRtl }>
@@ -27,7 +59,7 @@ export const AlignItemsField = () => {
27
59
  <StylesField bind="align-items">
28
60
  <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
29
61
  <Grid item xs={ 6 }>
30
- <ControlLabel>{ __( 'Align Items', 'elementor' ) }</ControlLabel>
62
+ <ControlLabel>{ __( 'Align items', 'elementor' ) }</ControlLabel>
31
63
  </Grid>
32
64
  <Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
33
65
  <ToggleControl options={ options } />
@@ -38,55 +70,3 @@ export const AlignItemsField = () => {
38
70
  </DirectionProvider>
39
71
  );
40
72
  };
41
-
42
- const useOptions = (): ToggleButtonGroupItem< AlignItems >[] => {
43
- const StartIcon = withDirection( LayoutAlignLeftIcon ),
44
- EndIcon = withDirection( LayoutAlignRightIcon );
45
-
46
- return [
47
- {
48
- value: 'start',
49
- label: __( 'Start', 'elementor' ),
50
- renderContent: ( { size } ) => <RotatedIcon icon={ StartIcon } size={ size } />,
51
- showTooltip: true,
52
- },
53
- {
54
- value: 'center',
55
- label: __( 'Center', 'elementor' ),
56
- renderContent: ( { size } ) => <RotatedIcon icon={ CenterIcon } size={ size } />,
57
- showTooltip: true,
58
- },
59
- {
60
- value: 'end',
61
- label: __( 'End', 'elementor' ),
62
- renderContent: ( { size } ) => <RotatedIcon icon={ EndIcon } size={ size } />,
63
- showTooltip: true,
64
- },
65
- {
66
- value: 'justify',
67
- label: __( 'Justify', 'elementor' ),
68
- renderContent: ( { size } ) => <RotatedIcon icon={ JustifyIcon } size={ size } />,
69
- showTooltip: true,
70
- },
71
- ];
72
- };
73
-
74
- const RotatedIcon = ( { icon: Icon, size }: { icon: JSX.ElementType; size: ToggleButtonProps[ 'size' ] } ) => {
75
- const [ direction ] = useStylesField< FlexDirection >( 'flex-direction' ),
76
- isRtl = 'rtl' === useTheme().direction,
77
- rotationMultiplier = isRtl ? -1 : 1;
78
-
79
- const rotationAngelMap: Record< FlexDirection, number > = {
80
- row: 90,
81
- column: 0,
82
- 'row-reverse': -90,
83
- 'column-reverse': -180,
84
- };
85
-
86
- return (
87
- <Icon
88
- fontSize={ size }
89
- sx={ { transition: '.3s', rotate: `${ rotationAngelMap[ direction || 'row' ] * rotationMultiplier }deg` } }
90
- />
91
- );
92
- };
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
3
+ import {
4
+ LayoutAlignCenterIcon as CenterIcon,
5
+ LayoutAlignLeftIcon,
6
+ LayoutAlignRightIcon,
7
+ LayoutDistributeVerticalIcon as JustifyIcon,
8
+ } from '@elementor/icons';
9
+ import { DirectionProvider, Grid, ThemeProvider, withDirection } from '@elementor/ui';
10
+ import { __ } from '@wordpress/i18n';
11
+
12
+ import { StylesField } from '../../../controls-registry/styles-field';
13
+ import { useDirection } from '../../../hooks/use-direction';
14
+ import { RotatedIcon } from './utils/rotated-icon';
15
+
16
+ type AlignItems = 'start' | 'center' | 'end' | 'stretch';
17
+
18
+ const StartIcon = withDirection( LayoutAlignLeftIcon );
19
+ const EndIcon = withDirection( LayoutAlignRightIcon );
20
+
21
+ const iconProps = {
22
+ isClockwise: false,
23
+ offset: 90,
24
+ };
25
+
26
+ const options: ToggleButtonGroupItem< AlignItems >[] = [
27
+ {
28
+ value: 'start',
29
+ label: __( 'Start', 'elementor' ),
30
+ renderContent: ( { size } ) => <RotatedIcon icon={ StartIcon } size={ size } { ...iconProps } />,
31
+ showTooltip: true,
32
+ },
33
+ {
34
+ value: 'center',
35
+ label: __( 'Center', 'elementor' ),
36
+ renderContent: ( { size } ) => <RotatedIcon icon={ CenterIcon } size={ size } { ...iconProps } />,
37
+ showTooltip: true,
38
+ },
39
+ {
40
+ value: 'end',
41
+ label: __( 'End', 'elementor' ),
42
+ renderContent: ( { size } ) => <RotatedIcon icon={ EndIcon } size={ size } { ...iconProps } />,
43
+ showTooltip: true,
44
+ },
45
+ {
46
+ value: 'stretch',
47
+ label: __( 'Stretch', 'elementor' ),
48
+ renderContent: ( { size } ) => <RotatedIcon icon={ JustifyIcon } size={ size } { ...iconProps } />,
49
+ showTooltip: true,
50
+ },
51
+ ];
52
+
53
+ export const AlignSelfChild = () => {
54
+ const { isSiteRtl } = useDirection();
55
+
56
+ return (
57
+ <DirectionProvider rtl={ isSiteRtl }>
58
+ <ThemeProvider>
59
+ <StylesField bind={ 'align-self' }>
60
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
61
+ <Grid item xs={ 6 }>
62
+ <ControlLabel>{ __( 'Align self', 'elementor' ) }</ControlLabel>
63
+ </Grid>
64
+ <Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'flex-end' } }>
65
+ <ToggleControl options={ options } />
66
+ </Grid>
67
+ </Grid>
68
+ </StylesField>
69
+ </ThemeProvider>
70
+ </DirectionProvider>
71
+ );
72
+ };
@@ -27,7 +27,7 @@ const options: ToggleButtonGroupItem< FlexDirection >[] = [
27
27
  },
28
28
  {
29
29
  value: 'row-reverse',
30
- label: __( 'Row reverse', 'elementor' ),
30
+ label: __( 'Reversed row', 'elementor' ),
31
31
  renderContent: ( { size } ) => {
32
32
  const EndIcon = withDirection( ArrowLeftIcon );
33
33
  return <EndIcon fontSize={ size } />;
@@ -36,7 +36,7 @@ const options: ToggleButtonGroupItem< FlexDirection >[] = [
36
36
  },
37
37
  {
38
38
  value: 'column-reverse',
39
- label: __( 'Column reverse', 'elementor' ),
39
+ label: __( 'Reversed column', 'elementor' ),
40
40
  renderContent: ( { size } ) => <ArrowUpSmallIcon fontSize={ size } />,
41
41
  showTooltip: true,
42
42
  },
@@ -6,6 +6,7 @@ import {
6
6
  NumberControl,
7
7
  type ToggleButtonGroupItem,
8
8
  } from '@elementor/editor-controls';
9
+ import { type NumberPropValue } from '@elementor/editor-props';
9
10
  import { ArrowDownSmallIcon, ArrowUpSmallIcon, PencilIcon } from '@elementor/icons';
10
11
  import { DirectionProvider, Grid, Stack, ThemeProvider } from '@elementor/ui';
11
12
  import { __ } from '@wordpress/i18n';
@@ -22,6 +23,11 @@ export const FIRST_DEFAULT_VALUE = -99999,
22
23
  LAST = 'last',
23
24
  CUSTOM = 'custom';
24
25
 
26
+ const orderValueMap = {
27
+ [ FIRST ]: FIRST_DEFAULT_VALUE,
28
+ [ LAST ]: LAST_DEFAULT_VALUE,
29
+ };
30
+
25
31
  const items: ToggleButtonGroupItem< GroupControlItemOption >[] = [
26
32
  {
27
33
  value: FIRST,
@@ -45,20 +51,20 @@ const items: ToggleButtonGroupItem< GroupControlItemOption >[] = [
45
51
 
46
52
  export const FlexOrderField = () => {
47
53
  const { isSiteRtl } = useDirection(),
48
- [ order, setOrder ] = useStylesField< number | null >( 'order' );
54
+ [ order, setOrder ] = useStylesField< NumberPropValue | null >( 'order' );
49
55
 
50
- const [ groupControlValue, setGroupControlValue ] = useState( getGroupControlValue( order ) );
56
+ const [ groupControlValue, setGroupControlValue ] = useState( getGroupControlValue( order?.value || null ) );
51
57
 
52
58
  const handleToggleButtonChange = ( group: GroupControlItemOption | null ) => {
53
59
  setGroupControlValue( group );
54
60
 
55
- const orderValueMap = {
56
- [ FIRST ]: FIRST_DEFAULT_VALUE,
57
- [ LAST ]: LAST_DEFAULT_VALUE,
58
- [ CUSTOM ]: null,
59
- };
61
+ if ( ! group || group === CUSTOM ) {
62
+ setOrder( null );
63
+
64
+ return;
65
+ }
60
66
 
61
- setOrder( group ? orderValueMap[ group ] : null );
67
+ setOrder( { $$type: 'number', value: orderValueMap[ group ] } );
62
68
  };
63
69
 
64
70
  return (