@elementor/editor-editing-panel 1.45.0 → 1.47.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 (86) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/dist/index.d.mts +22 -4
  3. package/dist/index.d.ts +22 -4
  4. package/dist/index.js +1187 -1051
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1027 -893
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +18 -17
  9. package/src/components/css-classes/css-class-menu.tsx +6 -8
  10. package/src/components/css-classes/css-class-selector.tsx +17 -11
  11. package/src/components/popover-scrollable-content.tsx +12 -0
  12. package/src/components/section-content.tsx +6 -16
  13. package/src/components/section.tsx +8 -4
  14. package/src/components/settings-tab.tsx +30 -4
  15. package/src/components/style-indicator.tsx +19 -15
  16. package/src/components/style-sections/background-section/background-section.tsx +4 -1
  17. package/src/components/style-sections/border-section/border-color-field.tsx +10 -16
  18. package/src/components/style-sections/border-section/border-field.tsx +4 -6
  19. package/src/components/style-sections/border-section/border-radius-field.tsx +4 -2
  20. package/src/components/style-sections/border-section/border-style-field.tsx +11 -16
  21. package/src/components/style-sections/border-section/border-width-field.tsx +4 -2
  22. package/src/components/style-sections/effects-section/effects-section.tsx +22 -2
  23. package/src/components/style-sections/layout-section/align-content-field.tsx +11 -12
  24. package/src/components/style-sections/layout-section/align-items-field.tsx +8 -11
  25. package/src/components/style-sections/layout-section/align-self-child-field.tsx +11 -16
  26. package/src/components/style-sections/layout-section/display-field.tsx +6 -6
  27. package/src/components/style-sections/layout-section/flex-direction-field.tsx +11 -14
  28. package/src/components/style-sections/layout-section/flex-order-field.tsx +32 -37
  29. package/src/components/style-sections/layout-section/flex-size-field.tsx +35 -58
  30. package/src/components/style-sections/layout-section/gap-control-field.tsx +5 -6
  31. package/src/components/style-sections/layout-section/justify-content-field.tsx +11 -12
  32. package/src/components/style-sections/layout-section/layout-section.tsx +2 -2
  33. package/src/components/style-sections/layout-section/opacity-control-field.tsx +21 -0
  34. package/src/components/style-sections/layout-section/utils/rotated-icon.tsx +1 -1
  35. package/src/components/style-sections/layout-section/wrap-field.tsx +10 -14
  36. package/src/components/style-sections/position-section/dimensions-field.tsx +4 -4
  37. package/src/components/style-sections/position-section/offset-field.tsx +12 -14
  38. package/src/components/style-sections/position-section/position-field.tsx +7 -11
  39. package/src/components/style-sections/position-section/position-section.tsx +6 -6
  40. package/src/components/style-sections/position-section/z-index-field.tsx +7 -11
  41. package/src/components/style-sections/size-section/object-fit-field.tsx +7 -11
  42. package/src/components/style-sections/size-section/object-position-field.tsx +4 -23
  43. package/src/components/style-sections/size-section/overflow-field.tsx +7 -11
  44. package/src/components/style-sections/size-section/size-section.tsx +10 -8
  45. package/src/components/style-sections/spacing-section/spacing-section.tsx +7 -4
  46. package/src/components/style-sections/typography-section/column-count-field.tsx +7 -11
  47. package/src/components/style-sections/typography-section/column-gap-field.tsx +9 -13
  48. package/src/components/style-sections/typography-section/font-family-field.tsx +9 -11
  49. package/src/components/style-sections/typography-section/font-size-field.tsx +9 -13
  50. package/src/components/style-sections/typography-section/font-style-field.tsx +13 -13
  51. package/src/components/style-sections/typography-section/font-weight-field.tsx +7 -11
  52. package/src/components/style-sections/typography-section/letter-spacing-field.tsx +9 -13
  53. package/src/components/style-sections/typography-section/line-height-field.tsx +9 -13
  54. package/src/components/style-sections/typography-section/text-alignment-field.tsx +11 -14
  55. package/src/components/style-sections/typography-section/text-color-field.tsx +7 -11
  56. package/src/components/style-sections/typography-section/text-decoration-field.tsx +7 -11
  57. package/src/components/style-sections/typography-section/text-direction-field.tsx +7 -11
  58. package/src/components/style-sections/typography-section/text-stroke-field.tsx +8 -8
  59. package/src/components/style-sections/typography-section/transform-field.tsx +7 -11
  60. package/src/components/style-sections/typography-section/typography-section.tsx +4 -2
  61. package/src/components/style-sections/typography-section/word-spacing-field.tsx +9 -13
  62. package/src/components/styles-field-layout.tsx +50 -0
  63. package/src/contexts/section-context.tsx +14 -0
  64. package/src/controls-registry/control-type-container.tsx +6 -2
  65. package/src/controls-registry/controls-registry.tsx +30 -10
  66. package/src/controls-registry/settings-field.tsx +65 -6
  67. package/src/controls-registry/styles-field.tsx +11 -5
  68. package/src/dynamics/components/dynamic-selection-control.tsx +20 -22
  69. package/src/dynamics/components/dynamic-selection.tsx +64 -79
  70. package/src/dynamics/hooks/use-prop-dynamic-action.tsx +1 -1
  71. package/src/hooks/use-default-panel-settings.ts +4 -0
  72. package/src/hooks/use-styles-field.ts +9 -3
  73. package/src/hooks/use-styles-fields.ts +4 -4
  74. package/src/index.ts +5 -0
  75. package/src/popover-action.tsx +11 -6
  76. package/src/provider-colors-registry.ts +20 -0
  77. package/src/styles-inheritance/components/infotip/label-chip.tsx +4 -5
  78. package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +36 -41
  79. package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +10 -24
  80. package/src/styles-inheritance/components/styles-inheritance-section-indicators.tsx +29 -44
  81. package/src/styles-inheritance/hooks/use-normalized-inheritance-chain-items.tsx +1 -17
  82. package/src/styles-inheritance/types.ts +0 -2
  83. package/src/styles-inheritance/utils.ts +17 -1
  84. package/src/sync/experiments-flags.ts +1 -0
  85. package/src/utils/get-styles-provider-color.ts +28 -0
  86. package/src/components/popover-content.tsx +0 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-editing-panel",
3
- "version": "1.45.0",
3
+ "version": "1.47.0",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,31 +39,32 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "0.19.4",
43
- "@elementor/editor-canvas": "0.23.0",
44
- "@elementor/editor-controls": "1.0.0",
42
+ "@elementor/editor": "0.20.1",
43
+ "@elementor/editor-canvas": "0.25.0",
44
+ "@elementor/editor-controls": "1.2.0",
45
45
  "@elementor/editor-current-user": "0.5.0",
46
- "@elementor/editor-documents": "0.13.6",
47
- "@elementor/editor-elements": "0.8.5",
48
- "@elementor/editor-panels": "0.15.4",
49
- "@elementor/editor-props": "0.13.0",
50
- "@elementor/editor-responsive": "0.13.5",
51
- "@elementor/editor-styles": "0.6.9",
52
- "@elementor/editor-styles-repository": "0.10.2",
53
- "@elementor/editor-ui": "0.11.0",
54
- "@elementor/editor-v1-adapters": "0.12.0",
46
+ "@elementor/editor-documents": "0.13.8",
47
+ "@elementor/editor-elements": "0.8.7",
48
+ "@elementor/editor-panels": "0.16.1",
49
+ "@elementor/editor-props": "0.15.0",
50
+ "@elementor/editor-responsive": "0.13.6",
51
+ "@elementor/editor-styles": "0.6.11",
52
+ "@elementor/editor-styles-repository": "0.10.4",
53
+ "@elementor/editor-ui": "0.13.0",
54
+ "@elementor/editor-v1-adapters": "0.12.1",
55
55
  "@elementor/icons": "1.44.0",
56
56
  "@elementor/locations": "0.8.0",
57
57
  "@elementor/menus": "0.1.5",
58
58
  "@elementor/schema": "0.1.2",
59
59
  "@elementor/session": "0.1.0",
60
- "@elementor/ui": "1.34.5",
61
- "@elementor/utils": "0.4.0",
62
- "@elementor/wp-media": "0.6.0",
60
+ "@elementor/ui": "1.35.5",
61
+ "@elementor/utils": "0.5.0",
62
+ "@elementor/wp-media": "0.6.1",
63
63
  "@wordpress/i18n": "^5.13.0"
64
64
  },
65
65
  "peerDependencies": {
66
- "react": "^18.3.1"
66
+ "react": "^18.3.1",
67
+ "react-dom": "^18.3.1"
67
68
  },
68
69
  "devDependencies": {
69
70
  "tsup": "^8.3.5"
@@ -1,16 +1,13 @@
1
1
  import * as React from 'react';
2
2
  import { type StyleDefinitionState } from '@elementor/editor-styles';
3
- import {
4
- isElementsStylesProvider,
5
- stylesRepository,
6
- useUserStylesCapability,
7
- } from '@elementor/editor-styles-repository';
3
+ import { stylesRepository, useUserStylesCapability } from '@elementor/editor-styles-repository';
8
4
  import { MenuItemInfotip, MenuListItem } from '@elementor/editor-ui';
9
5
  import { bindMenu, Divider, Menu, MenuSubheader, type PopupState, Stack } from '@elementor/ui';
10
6
  import { __ } from '@wordpress/i18n';
11
7
 
12
8
  import { useStyle } from '../../contexts/style-context';
13
9
  import { type StyleDefinitionStateWithNormal } from '../../styles-inheritance/types';
10
+ import { getStylesProviderThemeColor } from '../../utils/get-styles-provider-color';
14
11
  import { StyleIndicator } from '../style-indicator';
15
12
  import { useCssClass } from './css-class-context';
16
13
  import { useUnapplyClass } from './use-apply-and-unapply-class';
@@ -135,8 +132,6 @@ function StateMenuItem( { state, closeMenu, ...props }: StateMenuItemProps ) {
135
132
 
136
133
  const isUpdateAllowed = ! state || userCan( provider ?? '' ).updateProps;
137
134
 
138
- const indicatorVariant = ! provider || isElementsStylesProvider( provider ) ? 'local' : 'global';
139
-
140
135
  const isStyled = modifiedStates[ state ?? 'normal' ] ?? false;
141
136
  const disabled = ! isUpdateAllowed && ! isStyled;
142
137
  const isActive = styleId === activeId;
@@ -164,7 +159,10 @@ function StateMenuItem( { state, closeMenu, ...props }: StateMenuItemProps ) {
164
159
  >
165
160
  <Stack gap={ 0.75 } direction="row" alignItems="center">
166
161
  { isStyled && (
167
- <StyleIndicator aria-label={ __( 'Has style', 'elementor' ) } variant={ indicatorVariant } />
162
+ <StyleIndicator
163
+ aria-label={ __( 'Has style', 'elementor' ) }
164
+ getColor={ getStylesProviderThemeColor( provider ?? '' ) }
165
+ />
168
166
  ) }
169
167
  { state ?? 'normal' }
170
168
  </Stack>
@@ -14,12 +14,22 @@ import {
14
14
  import { InfoAlert, WarningInfotip } from '@elementor/editor-ui';
15
15
  import { ColorSwatchIcon, MapPinIcon } from '@elementor/icons';
16
16
  import { createLocation } from '@elementor/locations';
17
- import { type AutocompleteChangeReason, Box, Chip, FormLabel, Link, Stack, Typography } from '@elementor/ui';
17
+ import {
18
+ type AutocompleteChangeReason,
19
+ Box,
20
+ Chip,
21
+ type ChipOwnProps,
22
+ FormLabel,
23
+ Link,
24
+ Stack,
25
+ Typography,
26
+ } from '@elementor/ui';
18
27
  import { __ } from '@wordpress/i18n';
19
28
 
20
29
  import { useClassesProp } from '../../contexts/classes-prop-context';
21
30
  import { useElement } from '../../contexts/element-context';
22
31
  import { useStyle } from '../../contexts/style-context';
32
+ import { getStylesProviderColorName } from '../../utils/get-styles-provider-color';
23
33
  import {
24
34
  CreatableAutocomplete,
25
35
  type CreatableAutocompleteProps,
@@ -34,7 +44,7 @@ const ID = 'elementor-css-class-selector';
34
44
  const TAGS_LIMIT = 50;
35
45
 
36
46
  type StyleDefOption = Option & {
37
- color: 'accent' | 'global';
47
+ color: ChipOwnProps[ 'color' ];
38
48
  icon: ReactElement | null;
39
49
  provider: string | null;
40
50
  };
@@ -141,13 +151,9 @@ export function CssClassSelector() {
141
151
  />
142
152
  </WarningInfotip>
143
153
  { ! canEdit && (
144
- <InfoAlert
145
- content={ __(
146
- 'With your current role, you can use existing classes but can’t modify them.',
147
- 'elementor'
148
- ) }
149
- sx={ { mt: 1 } }
150
- />
154
+ <InfoAlert sx={ { mt: 1 } }>
155
+ { __( 'With your current role, you can use existing classes but can’t modify them.', 'elementor' ) }
156
+ </InfoAlert>
151
157
  ) }
152
158
  </Stack>
153
159
  );
@@ -205,7 +211,7 @@ function useOptions() {
205
211
  const isElements = isElementsStylesProvider( provider.getKey() );
206
212
  const styleDefs = provider.actions.all( { elementId: element.id } );
207
213
 
208
- // Add empty local option for elements, as fallback.
214
+ // Add an empty local option for elements, as fallback.
209
215
  if ( isElements && styleDefs.length === 0 ) {
210
216
  return [ EMPTY_OPTION ];
211
217
  }
@@ -215,7 +221,7 @@ function useOptions() {
215
221
  label: styleDef.label,
216
222
  value: styleDef.id,
217
223
  fixed: isElements,
218
- color: isElements ? 'accent' : 'global',
224
+ color: getStylesProviderColorName( provider.getKey() ),
219
225
  icon: isElements ? <MapPinIcon /> : null,
220
226
  provider: provider.getKey(),
221
227
  };
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ import { PopoverScrollableContent as BasePopoverScrollableContent } from '@elementor/editor-ui';
3
+
4
+ import { useSectionWidth } from '../contexts/section-context';
5
+
6
+ type Props = React.ComponentProps< typeof BasePopoverScrollableContent >;
7
+
8
+ export const PopoverScrollableContent = ( props: Props ) => {
9
+ const sectionWidth = useSectionWidth();
10
+
11
+ return <BasePopoverScrollableContent { ...props } width={ sectionWidth } />;
12
+ };
@@ -1,11 +1,7 @@
1
- import { createContext, type FC, type PropsWithChildren, useContext, useRef } from 'react';
1
+ import { type FC, type PropsWithChildren } from 'react';
2
2
  import * as React from 'react';
3
3
  import { Stack } from '@elementor/ui';
4
4
 
5
- const SectionContentRefContext = createContext< React.RefObject< HTMLElement > | null >( null );
6
-
7
- export const useSectionContentRef = () => useContext( SectionContentRefContext );
8
-
9
5
  type SectionContentProps = PropsWithChildren< {
10
6
  gap?: number;
11
7
  sx?: {
@@ -13,14 +9,8 @@ type SectionContentProps = PropsWithChildren< {
13
9
  };
14
10
  } >;
15
11
 
16
- export const SectionContent: FC< SectionContentProps > = ( { gap = 2, sx, children } ) => {
17
- const ref = useRef< HTMLElement >( null );
18
-
19
- return (
20
- <SectionContentRefContext.Provider value={ ref }>
21
- <Stack gap={ gap } sx={ { ...sx } } ref={ ref }>
22
- { children }
23
- </Stack>
24
- </SectionContentRefContext.Provider>
25
- );
26
- };
12
+ export const SectionContent: FC< SectionContentProps > = ( { gap = 2, sx, children } ) => (
13
+ <Stack gap={ gap } sx={ { ...sx } }>
14
+ { children }
15
+ </Stack>
16
+ );
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
- import { type PropsWithChildren, type ReactNode, useId } from 'react';
2
+ import { type PropsWithChildren, type ReactNode, useId, useRef } from 'react';
3
3
  import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
4
  import { Collapse, Divider, ListItemButton, ListItemText, Stack } from '@elementor/ui';
5
5
 
6
+ import { SectionRefContext } from '../contexts/section-context';
6
7
  import { useStateByElement } from '../hooks/use-state-by-element';
7
8
  import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
8
9
  import { CollapseIcon } from './collapse-icon';
@@ -16,6 +17,7 @@ type Props = PropsWithChildren< {
16
17
 
17
18
  export function Section( { title, children, defaultExpanded = false, titleEnd }: Props ) {
18
19
  const [ isOpen, setIsOpen ] = useStateByElement( title, !! defaultExpanded );
20
+ const ref = useRef< HTMLElement >( null );
19
21
 
20
22
  const handleClick = () => {
21
23
  setIsOpen( ! isOpen );
@@ -46,9 +48,11 @@ export function Section( { title, children, defaultExpanded = false, titleEnd }:
46
48
  <CollapseIcon open={ isOpen } color="secondary" fontSize="tiny" />
47
49
  </ListItemButton>
48
50
  <Collapse id={ contentId } aria-labelledby={ labelId } in={ isOpen } timeout="auto" unmountOnExit>
49
- <Stack gap={ 2.5 } p={ 2 }>
50
- { children }
51
- </Stack>
51
+ <SectionRefContext.Provider value={ ref }>
52
+ <Stack ref={ ref } gap={ 2.5 } p={ 2 }>
53
+ { children }
54
+ </Stack>
55
+ </SectionRefContext.Provider>
52
56
  </Collapse>
53
57
  <Divider />
54
58
  </>
@@ -8,7 +8,12 @@ import { Divider } from '@elementor/ui';
8
8
  import { useElement } from '../contexts/element-context';
9
9
  import { Control as BaseControl } from '../controls-registry/control';
10
10
  import { ControlTypeContainer } from '../controls-registry/control-type-container';
11
- import { type ControlType, getControl, getDefaultLayout } from '../controls-registry/controls-registry';
11
+ import {
12
+ type ControlType,
13
+ getControl,
14
+ getDefaultLayout,
15
+ getPropTypeUtil,
16
+ } from '../controls-registry/controls-registry';
12
17
  import { SettingsField } from '../controls-registry/settings-field';
13
18
  import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
14
19
  import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
@@ -64,14 +69,35 @@ const Control = ( { control }: { control: Control[ 'value' ] } ) => {
64
69
  }
65
70
 
66
71
  const layout = control.meta?.layout || getDefaultLayout( control.type as ControlType );
72
+ const controlProps = populateChildControlProps( control.props );
73
+ if ( layout === 'custom' ) {
74
+ controlProps.label = control.label;
75
+ }
67
76
 
68
77
  return (
69
- <SettingsField bind={ control.bind }>
78
+ <SettingsField bind={ control.bind } propDisplayName={ control.label || control.bind }>
70
79
  { control.meta?.topDivider && <Divider /> }
71
80
  <ControlTypeContainer layout={ layout }>
72
- { control.label ? <ControlFormLabel>{ control.label }</ControlFormLabel> : null }
73
- <BaseControl type={ control.type as ControlType } props={ control.props } />
81
+ { control.label && layout !== 'custom' ? <ControlFormLabel>{ control.label }</ControlFormLabel> : null }
82
+ <BaseControl type={ control.type as ControlType } props={ controlProps } />
74
83
  </ControlTypeContainer>
75
84
  </SettingsField>
76
85
  );
77
86
  };
87
+
88
+ function populateChildControlProps( props: Record< string, unknown > ) {
89
+ if ( props.childControlType ) {
90
+ const childComponent = getControl( props.childControlType as ControlType );
91
+ const childPropType = getPropTypeUtil( props.childControlType as ControlType );
92
+ props = {
93
+ ...props,
94
+ childControlConfig: {
95
+ component: childComponent,
96
+ props: props.childControlProps || {},
97
+ propTypeUtil: childPropType,
98
+ },
99
+ };
100
+ }
101
+
102
+ return props;
103
+ }
@@ -1,23 +1,27 @@
1
- import { styled } from '@elementor/ui';
2
-
3
- type StyleIndicatorVariant = 'overridden' | 'local' | 'global';
1
+ import { styled, type Theme } from '@elementor/ui';
4
2
 
5
3
  export const StyleIndicator = styled( 'div', {
6
- shouldForwardProp: ( prop ) => prop !== 'variant',
7
- } )< { variant?: StyleIndicatorVariant } >`
4
+ shouldForwardProp: ( prop: string ) => ! [ 'isOverridden', 'getColor' ].includes( prop ),
5
+ } )<
6
+ | {
7
+ isOverridden?: boolean;
8
+ getColor?: never;
9
+ }
10
+ | {
11
+ isOverridden?: boolean;
12
+ getColor?: ( ( theme: Theme ) => string ) | null;
13
+ }
14
+ >`
8
15
  width: 5px;
9
16
  height: 5px;
10
17
  border-radius: 50%;
11
- background-color: ${ ( { theme, variant } ) => {
12
- switch ( variant ) {
13
- case 'overridden':
14
- return theme.palette.warning.light;
15
- case 'global':
16
- return theme.palette.global.dark;
17
- case 'local':
18
- return theme.palette.accent.main;
19
- default:
20
- return theme.palette.text.disabled;
18
+ background-color: ${ ( { theme, isOverridden, getColor } ) => {
19
+ if ( isOverridden ) {
20
+ return theme.palette.warning.light;
21
21
  }
22
+
23
+ const providerColor = getColor?.( theme );
24
+
25
+ return providerColor ?? theme.palette.text.disabled;
22
26
  } };
23
27
  `;
@@ -1,13 +1,16 @@
1
1
  import * as React from 'react';
2
2
  import { BackgroundControl } from '@elementor/editor-controls';
3
+ import { __ } from '@wordpress/i18n';
3
4
 
4
5
  import { StylesField } from '../../../controls-registry/styles-field';
5
6
  import { SectionContent } from '../../section-content';
6
7
 
8
+ const BACKGROUND_LABEL = __( 'Background', 'elementor' );
9
+
7
10
  export const BackgroundSection = () => {
8
11
  return (
9
12
  <SectionContent>
10
- <StylesField bind="background">
13
+ <StylesField bind="background" propDisplayName={ BACKGROUND_LABEL }>
11
14
  <BackgroundControl />
12
15
  </StylesField>
13
16
  </SectionContent>
@@ -1,22 +1,16 @@
1
1
  import * as React from 'react';
2
2
  import { ColorControl } from '@elementor/editor-controls';
3
- import { Grid } from '@elementor/ui';
4
3
  import { __ } from '@wordpress/i18n';
5
4
 
6
5
  import { StylesField } from '../../../controls-registry/styles-field';
7
- import { ControlLabel } from '../../control-label';
6
+ import { StylesFieldLayout } from '../../styles-field-layout';
8
7
 
9
- export const BorderColorField = () => {
10
- return (
11
- <StylesField bind={ 'border-color' }>
12
- <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
13
- <Grid item xs={ 6 }>
14
- <ControlLabel>{ __( 'Border color', 'elementor' ) }</ControlLabel>
15
- </Grid>
16
- <Grid item xs={ 6 }>
17
- <ColorControl />
18
- </Grid>
19
- </Grid>
20
- </StylesField>
21
- );
22
- };
8
+ const BORDER_COLOR_LABEL = __( 'Border color', 'elementor' );
9
+
10
+ export const BorderColorField = () => (
11
+ <StylesField bind="border-color" propDisplayName={ BORDER_COLOR_LABEL }>
12
+ <StylesFieldLayout label={ BORDER_COLOR_LABEL }>
13
+ <ColorControl />
14
+ </StylesFieldLayout>
15
+ </StylesField>
16
+ );
@@ -2,7 +2,6 @@ import * as React from 'react';
2
2
  import { ControlFormLabel } from '@elementor/editor-controls';
3
3
  import { __ } from '@wordpress/i18n';
4
4
 
5
- import { useStyle } from '../../../contexts/style-context';
6
5
  import { useStylesFields } from '../../../hooks/use-styles-fields';
7
6
  import { AddOrRemoveContent } from '../../add-or-remove-content';
8
7
  import { BorderColorField } from './border-color-field';
@@ -16,22 +15,21 @@ const initialBorder = {
16
15
  };
17
16
 
18
17
  export const BorderField = () => {
19
- const { canEdit } = useStyle();
20
- const [ border, setBorder ] = useStylesFields( Object.keys( initialBorder ) );
18
+ const { values, setValues, canEdit } = useStylesFields( Object.keys( initialBorder ) );
21
19
 
22
20
  const addBorder = () => {
23
- setBorder( initialBorder );
21
+ setValues( initialBorder );
24
22
  };
25
23
 
26
24
  const removeBorder = () => {
27
- setBorder( {
25
+ setValues( {
28
26
  'border-width': null,
29
27
  'border-color': null,
30
28
  'border-style': null,
31
29
  } );
32
30
  };
33
31
 
34
- const hasBorder = Object.values( border ?? {} ).some( Boolean );
32
+ const hasBorder = Object.values( values ?? {} ).some( Boolean );
35
33
 
36
34
  return (
37
35
  <AddOrRemoveContent
@@ -15,6 +15,8 @@ import { StylesField } from '../../../controls-registry/styles-field';
15
15
  import { useDirection } from '../../../hooks/use-direction';
16
16
  import { UiProviders } from '../../../styles-inheritance/components/ui-providers';
17
17
 
18
+ const BORDER_RADIUS_LABEL = __( 'Border radius', 'elementor' );
19
+
18
20
  const StartStartIcon = withDirection( RadiusTopLeftIcon );
19
21
  const StartEndIcon = withDirection( RadiusTopRightIcon );
20
22
  const EndStartIcon = withDirection( RadiusBottomLeftIcon );
@@ -57,10 +59,10 @@ export const BorderRadiusField = () => {
57
59
 
58
60
  return (
59
61
  <UiProviders>
60
- <StylesField bind={ 'border-radius' }>
62
+ <StylesField bind={ 'border-radius' } propDisplayName={ BORDER_RADIUS_LABEL }>
61
63
  <EqualUnequalSizesControl
62
64
  items={ getCorners( isSiteRtl ) }
63
- label={ __( 'Border radius', 'elementor' ) }
65
+ label={ BORDER_RADIUS_LABEL }
64
66
  icon={ <BorderCornersIcon fontSize={ 'tiny' } /> }
65
67
  tooltipLabel={ __( 'Adjust corners', 'elementor' ) }
66
68
  multiSizePropTypeUtil={ borderRadiusPropTypeUtil }
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
2
  import { SelectControl } from '@elementor/editor-controls';
3
- import { Grid } from '@elementor/ui';
4
3
  import { __ } from '@wordpress/i18n';
5
4
 
6
5
  import { StylesField } from '../../../controls-registry/styles-field';
7
- import { ControlLabel } from '../../control-label';
6
+ import { StylesFieldLayout } from '../../styles-field-layout';
7
+
8
+ const BORDER_TYPE_LABEL = __( 'Border type', 'elementor' );
8
9
 
9
10
  const borderStyles = [
10
11
  { value: 'none', label: __( 'None', 'elementor' ) },
@@ -17,17 +18,11 @@ const borderStyles = [
17
18
  { value: 'inset', label: __( 'Inset', 'elementor' ) },
18
19
  { value: 'outset', label: __( 'Outset', 'elementor' ) },
19
20
  ];
20
- export const BorderStyleField = () => {
21
- return (
22
- <StylesField bind={ 'border-style' }>
23
- <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
24
- <Grid item xs={ 6 }>
25
- <ControlLabel>{ __( 'Border type', 'elementor' ) }</ControlLabel>
26
- </Grid>
27
- <Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
28
- <SelectControl options={ borderStyles } />
29
- </Grid>
30
- </Grid>
31
- </StylesField>
32
- );
33
- };
21
+
22
+ export const BorderStyleField = () => (
23
+ <StylesField bind="border-style" propDisplayName={ BORDER_TYPE_LABEL }>
24
+ <StylesFieldLayout label={ BORDER_TYPE_LABEL }>
25
+ <SelectControl options={ borderStyles } />
26
+ </StylesFieldLayout>
27
+ </StylesField>
28
+ );
@@ -8,6 +8,8 @@ import { __ } from '@wordpress/i18n';
8
8
  import { StylesField } from '../../../controls-registry/styles-field';
9
9
  import { useDirection } from '../../../hooks/use-direction';
10
10
 
11
+ const BORDER_WIDTH_LABEL = __( 'Border width', 'elementor' );
12
+
11
13
  const InlineStartIcon = withDirection( SideRightIcon );
12
14
  const InlineEndIcon = withDirection( SideLeftIcon );
13
15
 
@@ -38,10 +40,10 @@ export const BorderWidthField = () => {
38
40
  const { isSiteRtl } = useDirection();
39
41
 
40
42
  return (
41
- <StylesField bind={ 'border-width' }>
43
+ <StylesField bind={ 'border-width' } propDisplayName={ BORDER_WIDTH_LABEL }>
42
44
  <EqualUnequalSizesControl
43
45
  items={ getEdges( isSiteRtl ) }
44
- label={ __( 'Border width', 'elementor' ) }
46
+ label={ BORDER_WIDTH_LABEL }
45
47
  icon={ <SideAllIcon fontSize={ 'tiny' } /> }
46
48
  tooltipLabel={ __( 'Adjust borders', 'elementor' ) }
47
49
  multiSizePropTypeUtil={ borderWidthPropTypeUtil }
@@ -1,15 +1,35 @@
1
1
  import * as React from 'react';
2
- import { BoxShadowRepeaterControl } from '@elementor/editor-controls';
2
+ import { BoxShadowRepeaterControl, FilterRepeaterControl } from '@elementor/editor-controls';
3
+ import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
+ import { __ } from '@wordpress/i18n';
3
5
 
4
6
  import { StylesField } from '../../../controls-registry/styles-field';
7
+ import { EXPERIMENTAL_FEATURES } from '../../../sync/experiments-flags';
8
+ import { PanelDivider } from '../../panel-divider';
5
9
  import { SectionContent } from '../../section-content';
10
+ import { OpacityControlField } from '../layout-section/opacity-control-field';
11
+
12
+ const BOX_SHADOW_LABEL = __( 'Box shadow', 'elementor' );
13
+ const FILTER_LABEL = __( 'Filter', 'elementor' );
6
14
 
7
15
  export const EffectsSection = () => {
16
+ const isVersion331Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_31 );
17
+
8
18
  return (
9
19
  <SectionContent>
10
- <StylesField bind="box-shadow">
20
+ <OpacityControlField />
21
+ <PanelDivider />
22
+ <StylesField bind="box-shadow" propDisplayName={ BOX_SHADOW_LABEL }>
11
23
  <BoxShadowRepeaterControl />
12
24
  </StylesField>
25
+ { isVersion331Active && (
26
+ <>
27
+ <PanelDivider />
28
+ <StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
29
+ <FilterRepeaterControl />
30
+ </StylesField>
31
+ </>
32
+ ) }
13
33
  </SectionContent>
14
34
  );
15
35
  };
@@ -8,16 +8,18 @@ import {
8
8
  JustifySpaceBetweenVerticalIcon as BetweenIcon,
9
9
  JustifyTopIcon,
10
10
  } from '@elementor/icons';
11
- import { Stack, withDirection } from '@elementor/ui';
11
+ import { withDirection } from '@elementor/ui';
12
12
  import { __ } from '@wordpress/i18n';
13
13
 
14
14
  import { StylesField } from '../../../controls-registry/styles-field';
15
15
  import { UiProviders } from '../../../styles-inheritance/components/ui-providers';
16
- import { ControlLabel } from '../../control-label';
16
+ import { StylesFieldLayout } from '../../styles-field-layout';
17
17
  import { RotatedIcon } from './utils/rotated-icon';
18
18
 
19
19
  type AlignContent = 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
20
20
 
21
+ const ALIGN_CONTENT_LABEL = __( 'Align content', 'elementor' );
22
+
21
23
  const StartIcon = withDirection( JustifyTopIcon );
22
24
  const EndIcon = withDirection( JustifyBottomIcon );
23
25
 
@@ -66,15 +68,12 @@ const options: ToggleButtonGroupItem< AlignContent >[] = [
66
68
  },
67
69
  ];
68
70
 
69
- export const AlignContentField = () => {
70
- return (
71
+ export const AlignContentField = () => (
72
+ <StylesField bind="align-content" propDisplayName={ ALIGN_CONTENT_LABEL }>
71
73
  <UiProviders>
72
- <StylesField bind="align-content">
73
- <Stack gap={ 1 }>
74
- <ControlLabel>{ __( 'Align content', 'elementor' ) }</ControlLabel>
75
- <ToggleControl options={ options } fullWidth={ true } />
76
- </Stack>
77
- </StylesField>
74
+ <StylesFieldLayout label={ ALIGN_CONTENT_LABEL } direction="column">
75
+ <ToggleControl options={ options } fullWidth={ true } />
76
+ </StylesFieldLayout>
78
77
  </UiProviders>
79
- );
80
- };
78
+ </StylesField>
79
+ );
@@ -6,16 +6,18 @@ import {
6
6
  LayoutAlignRightIcon,
7
7
  LayoutDistributeVerticalIcon as JustifyIcon,
8
8
  } from '@elementor/icons';
9
- import { Grid, withDirection } from '@elementor/ui';
9
+ import { withDirection } from '@elementor/ui';
10
10
  import { __ } from '@wordpress/i18n';
11
11
 
12
12
  import { StylesField } from '../../../controls-registry/styles-field';
13
13
  import { UiProviders } from '../../../styles-inheritance/components/ui-providers';
14
- import { ControlLabel } from '../../control-label';
14
+ import { StylesFieldLayout } from '../../styles-field-layout';
15
15
  import { RotatedIcon } from './utils/rotated-icon';
16
16
 
17
17
  type AlignItems = 'start' | 'center' | 'end' | 'stretch';
18
18
 
19
+ const ALIGN_ITEMS_LABEL = __( 'Align items', 'elementor' );
20
+
19
21
  const StartIcon = withDirection( LayoutAlignLeftIcon );
20
22
  const EndIcon = withDirection( LayoutAlignRightIcon );
21
23
 
@@ -54,15 +56,10 @@ const options: ToggleButtonGroupItem< AlignItems >[] = [
54
56
  export const AlignItemsField = () => {
55
57
  return (
56
58
  <UiProviders>
57
- <StylesField bind="align-items">
58
- <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
59
- <Grid item xs={ 6 }>
60
- <ControlLabel>{ __( 'Align items', 'elementor' ) }</ControlLabel>
61
- </Grid>
62
- <Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
63
- <ToggleControl options={ options } />
64
- </Grid>
65
- </Grid>
59
+ <StylesField bind="align-items" propDisplayName={ ALIGN_ITEMS_LABEL }>
60
+ <StylesFieldLayout label={ ALIGN_ITEMS_LABEL }>
61
+ <ToggleControl options={ options } />
62
+ </StylesFieldLayout>
66
63
  </StylesField>
67
64
  </UiProviders>
68
65
  );