@elementor/editor-editing-panel 1.0.0 → 1.1.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 (117) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/index.d.mts +10 -19
  3. package/dist/index.d.ts +10 -19
  4. package/dist/index.js +1283 -1751
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1305 -1762
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +12 -12
  9. package/src/components/add-or-remove-content.tsx +3 -3
  10. package/src/components/collapse-icon.tsx +12 -0
  11. package/src/components/collapsible-content.tsx +5 -14
  12. package/src/components/collapsible-field.tsx +5 -3
  13. package/src/components/css-class-selector-section.tsx +76 -0
  14. package/src/components/editing-panel-hooks.tsx +2 -0
  15. package/src/components/editing-panel-tabs.tsx +23 -13
  16. package/src/components/editing-panel.tsx +9 -6
  17. package/src/components/multi-combobox/index.ts +3 -0
  18. package/src/components/multi-combobox/multi-combobox.tsx +120 -0
  19. package/src/components/multi-combobox/types.ts +26 -0
  20. package/src/components/multi-combobox/use-combobox-actions.ts +62 -0
  21. package/src/components/section.tsx +37 -0
  22. package/src/components/sections-list.tsx +6 -0
  23. package/src/components/settings-tab.tsx +11 -11
  24. package/src/components/style-sections/background-section/background-color-field.tsx +4 -4
  25. package/src/components/style-sections/background-section/background-section.tsx +9 -7
  26. package/src/components/style-sections/border-section/border-color-field.tsx +4 -4
  27. package/src/components/style-sections/border-section/border-field.tsx +4 -3
  28. package/src/components/style-sections/border-section/border-radius-field.tsx +4 -3
  29. package/src/components/style-sections/border-section/border-section.tsx +7 -10
  30. package/src/components/style-sections/border-section/border-style-field.tsx +4 -4
  31. package/src/components/style-sections/border-section/border-width-field.tsx +4 -3
  32. package/src/components/style-sections/effects-section/effects-section.tsx +7 -10
  33. package/src/components/style-sections/layout-section/display-field.tsx +32 -0
  34. package/src/components/style-sections/layout-section/justify-content-field.tsx +82 -0
  35. package/src/components/style-sections/layout-section/layout-section.tsx +17 -0
  36. package/src/components/style-sections/layout-section/utils/rotate-flex-icon.ts +12 -0
  37. package/src/components/style-sections/position-section/dimensions-field.tsx +6 -6
  38. package/src/components/style-sections/position-section/position-field.tsx +4 -4
  39. package/src/components/style-sections/position-section/position-section.tsx +45 -15
  40. package/src/components/style-sections/position-section/z-index-field.tsx +4 -4
  41. package/src/components/style-sections/size-section/overflow-field.tsx +8 -8
  42. package/src/components/style-sections/size-section/size-section.tsx +33 -26
  43. package/src/components/style-sections/spacing-section/spacing-section.tsx +11 -13
  44. package/src/components/style-sections/typography-section/font-family-field.tsx +40 -0
  45. package/src/components/style-sections/typography-section/font-size-field.tsx +4 -4
  46. package/src/components/style-sections/typography-section/font-weight-field.tsx +4 -4
  47. package/src/components/style-sections/typography-section/letter-spacing-field.tsx +4 -4
  48. package/src/components/style-sections/typography-section/text-alignment-field.tsx +9 -9
  49. package/src/components/style-sections/typography-section/text-color-field.tsx +4 -4
  50. package/src/components/style-sections/typography-section/text-direction-field.tsx +7 -7
  51. package/src/components/style-sections/typography-section/text-stroke-field.tsx +3 -3
  52. package/src/components/style-sections/typography-section/text-style-field.tsx +5 -4
  53. package/src/components/style-sections/typography-section/transform-field.tsx +23 -9
  54. package/src/components/style-sections/typography-section/typography-section.tsx +26 -27
  55. package/src/components/style-sections/typography-section/word-spacing-field.tsx +4 -4
  56. package/src/components/style-tab.tsx +67 -31
  57. package/src/contexts/classes-prop-context.tsx +1 -1
  58. package/src/contexts/element-context.tsx +2 -2
  59. package/src/contexts/style-context.tsx +6 -5
  60. package/src/control-replacement.tsx +1 -1
  61. package/src/controls-actions.ts +3 -2
  62. package/src/controls-registry/control-type-container.tsx +3 -2
  63. package/src/controls-registry/control.tsx +2 -1
  64. package/src/controls-registry/controls-registry.tsx +8 -1
  65. package/src/controls-registry/settings-field.tsx +5 -4
  66. package/src/controls-registry/styles-field.tsx +3 -2
  67. package/src/dynamics/components/dynamic-selection-control.tsx +15 -14
  68. package/src/dynamics/components/dynamic-selection.tsx +9 -8
  69. package/src/dynamics/dynamic-control.tsx +4 -4
  70. package/src/dynamics/hooks/use-dynamic-tag.ts +3 -2
  71. package/src/dynamics/hooks/use-prop-dynamic-action.tsx +6 -5
  72. package/src/dynamics/hooks/use-prop-dynamic-tags.ts +3 -2
  73. package/src/dynamics/init.ts +5 -3
  74. package/src/dynamics/sync/get-elementor-config.ts +1 -1
  75. package/src/dynamics/types.ts +2 -2
  76. package/src/dynamics/utils.ts +3 -2
  77. package/src/hooks/use-close-editor-panel.ts +23 -0
  78. package/src/hooks/use-direction.ts +13 -0
  79. package/src/hooks/use-open-editor-panel.ts +4 -3
  80. package/src/hooks/use-prop-value-history.ts +45 -0
  81. package/src/hooks/use-style-prop-history.ts +75 -0
  82. package/src/hooks/use-styles-field.ts +25 -4
  83. package/src/index.ts +1 -1
  84. package/src/init.ts +5 -4
  85. package/src/panel.ts +1 -0
  86. package/src/popover-action.tsx +1 -1
  87. package/src/sync/enqueue-font.ts +7 -0
  88. package/src/sync/get-elementor-config.ts +7 -0
  89. package/src/sync/{should-use-v2-panel.ts → is-atomic-widget-selected.ts} +1 -1
  90. package/src/sync/types.ts +20 -21
  91. package/src/components/accordion-section.tsx +0 -26
  92. package/src/components/control-label.tsx +0 -10
  93. package/src/controls/bound-prop-context.tsx +0 -30
  94. package/src/controls/components/control-toggle-button-group.tsx +0 -68
  95. package/src/controls/components/repeater.tsx +0 -197
  96. package/src/controls/components/text-field-inner-selection.tsx +0 -75
  97. package/src/controls/control-actions/control-actions-context.tsx +0 -27
  98. package/src/controls/control-actions/control-actions-menu.ts +0 -7
  99. package/src/controls/control-actions/control-actions.tsx +0 -31
  100. package/src/controls/controls/box-shadow-repeater-control.tsx +0 -210
  101. package/src/controls/controls/color-control.tsx +0 -25
  102. package/src/controls/controls/equal-unequal-sizes-control.tsx +0 -196
  103. package/src/controls/controls/image-control.tsx +0 -58
  104. package/src/controls/controls/image-media-control.tsx +0 -64
  105. package/src/controls/controls/linked-dimensions-control.tsx +0 -139
  106. package/src/controls/controls/number-control.tsx +0 -29
  107. package/src/controls/controls/select-control.tsx +0 -30
  108. package/src/controls/controls/size-control.tsx +0 -71
  109. package/src/controls/controls/stroke-control.tsx +0 -105
  110. package/src/controls/controls/text-area-control.tsx +0 -31
  111. package/src/controls/controls/text-control.tsx +0 -17
  112. package/src/controls/controls/toggle-control.tsx +0 -26
  113. package/src/controls/create-control-replacement.tsx +0 -53
  114. package/src/controls/create-control.tsx +0 -40
  115. package/src/controls/hooks/use-sync-external-state.tsx +0 -51
  116. package/src/controls/index.ts +0 -24
  117. package/src/dynamics/hooks/use-prop-value-history.ts +0 -26
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { ControlLabel, FontFamilyControl } from '@elementor/editor-controls';
3
+ import { Grid } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
6
+ import { StylesField } from '../../../controls-registry/styles-field';
7
+ import { getElementorConfig } from '../../../sync/get-elementor-config';
8
+
9
+ export const FontFamilyField = () => {
10
+ const fontFamilies = getFontFamilies();
11
+
12
+ if ( ! fontFamilies ) {
13
+ return null;
14
+ }
15
+
16
+ return (
17
+ <StylesField bind="font-family">
18
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
19
+ <Grid item xs={ 6 }>
20
+ <ControlLabel>{ __( 'Font Family', 'elementor' ) }</ControlLabel>
21
+ </Grid>
22
+ <Grid item xs={ 6 }>
23
+ <FontFamilyControl fontFamilies={ fontFamilies } />
24
+ </Grid>
25
+ </Grid>
26
+ </StylesField>
27
+ );
28
+ };
29
+
30
+ const getFontFamilies = () => {
31
+ const { controls } = getElementorConfig();
32
+
33
+ const options = controls?.font?.options;
34
+
35
+ if ( ! options ) {
36
+ return null;
37
+ }
38
+
39
+ return options;
40
+ };
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { ControlLabel, SizeControl } from '@elementor/editor-controls';
3
3
  import { Grid } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
4
6
  import { StylesField } from '../../../controls-registry/styles-field';
5
- import { SizeControl } from '../../../controls';
6
- import { ControlLabel } from '../../control-label';
7
7
 
8
8
  export const FontSizeField = () => {
9
9
  return (
10
10
  <StylesField bind="font-size">
11
- <Grid container spacing={ 1 } alignItems="center">
11
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
12
12
  <Grid item xs={ 6 }>
13
13
  <ControlLabel>{ __( 'Font Size', 'elementor' ) }</ControlLabel>
14
14
  </Grid>
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { ControlLabel, SelectControl } from '@elementor/editor-controls';
3
3
  import { Grid } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
4
6
  import { StylesField } from '../../../controls-registry/styles-field';
5
- import { SelectControl } from '../../../controls';
6
- import { ControlLabel } from '../../control-label';
7
7
 
8
8
  const fontWeightOptions = [
9
9
  { label: __( 'Light - 400', 'elementor' ), value: '400' },
@@ -16,7 +16,7 @@ const fontWeightOptions = [
16
16
  export const FontWeightField = () => {
17
17
  return (
18
18
  <StylesField bind="font-weight">
19
- <Grid container spacing={ 1 } alignItems="center">
19
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
20
20
  <Grid item xs={ 6 }>
21
21
  <ControlLabel>{ __( 'Font Weight', 'elementor' ) }</ControlLabel>
22
22
  </Grid>
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { ControlLabel, SizeControl } from '@elementor/editor-controls';
3
3
  import { Grid } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
4
6
  import { StylesField } from '../../../controls-registry/styles-field';
5
- import { SizeControl } from '../../../controls';
6
- import { ControlLabel } from '../../control-label';
7
7
 
8
8
  export const LetterSpacingField = () => {
9
9
  return (
10
10
  <StylesField bind="letter-spacing">
11
- <Grid container spacing={ 1 } alignItems="center">
11
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
12
12
  <Grid item xs={ 6 }>
13
13
  <ControlLabel>{ __( 'Letter Spacing', 'elementor' ) }</ControlLabel>
14
14
  </Grid>
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
3
+ import { AlignCenterIcon, AlignJustifiedIcon, AlignLeftIcon, AlignRightIcon } from '@elementor/icons';
3
4
  import { Grid } from '@elementor/ui';
4
- import { AlignLeftIcon, AlignCenterIcon, AlignRightIcon, AlignJustifiedIcon } from '@elementor/icons';
5
+ import { __ } from '@wordpress/i18n';
6
+
5
7
  import { StylesField } from '../../../controls-registry/styles-field';
6
- import { ToggleControl, ToggleButtonGroupItem } from '../../../controls';
7
- import { ControlLabel } from '../../control-label';
8
8
 
9
9
  type Alignments = 'left' | 'center' | 'right' | 'justify';
10
10
 
@@ -12,29 +12,29 @@ const options: ToggleButtonGroupItem< Alignments >[] = [
12
12
  {
13
13
  value: 'left',
14
14
  label: __( 'Left', 'elementor' ),
15
- icon: AlignLeftIcon,
15
+ renderContent: ( { size } ) => <AlignLeftIcon fontSize={ size } />,
16
16
  },
17
17
  {
18
18
  value: 'center',
19
19
  label: __( 'Center', 'elementor' ),
20
- icon: AlignCenterIcon,
20
+ renderContent: ( { size } ) => <AlignCenterIcon fontSize={ size } />,
21
21
  },
22
22
  {
23
23
  value: 'right',
24
24
  label: __( 'Right', 'elementor' ),
25
- icon: AlignRightIcon,
25
+ renderContent: ( { size } ) => <AlignRightIcon fontSize={ size } />,
26
26
  },
27
27
  {
28
28
  value: 'justify',
29
29
  label: __( 'Justify', 'elementor' ),
30
- icon: AlignJustifiedIcon,
30
+ renderContent: ( { size } ) => <AlignJustifiedIcon fontSize={ size } />,
31
31
  },
32
32
  ];
33
33
 
34
34
  export const TextAlignmentField = () => {
35
35
  return (
36
36
  <StylesField bind={ 'text-align' }>
37
- <Grid container spacing={ 1 } alignItems="center">
37
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
38
38
  <Grid item xs={ 6 }>
39
39
  <ControlLabel>{ __( 'Alignment', 'elementor' ) }</ControlLabel>
40
40
  </Grid>
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { ColorControl, ControlLabel } from '@elementor/editor-controls';
3
3
  import { Grid } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
4
6
  import { StylesField } from '../../../controls-registry/styles-field';
5
- import { ColorControl } from '../../../controls';
6
- import { ControlLabel } from '../../control-label';
7
7
 
8
8
  export const TextColorField = () => {
9
9
  return (
10
10
  <StylesField bind="color">
11
- <Grid container spacing={ 1 } alignItems="center">
11
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
12
12
  <Grid item xs={ 6 }>
13
13
  <ControlLabel>{ __( 'Text Color', 'elementor' ) }</ControlLabel>
14
14
  </Grid>
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
3
- import { Grid } from '@elementor/ui';
2
+ import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
4
3
  import { TextDirectionLtrIcon, TextDirectionRtlIcon } from '@elementor/icons';
4
+ import { Grid } from '@elementor/ui';
5
+ import { __ } from '@wordpress/i18n';
6
+
5
7
  import { StylesField } from '../../../controls-registry/styles-field';
6
- import { ToggleControl, ToggleButtonGroupItem } from '../../../controls';
7
- import { ControlLabel } from '../../control-label';
8
8
 
9
9
  type Direction = 'ltr' | 'rtl';
10
10
 
@@ -12,19 +12,19 @@ const options: ToggleButtonGroupItem< Direction >[] = [
12
12
  {
13
13
  value: 'ltr',
14
14
  label: __( 'Left to Right', 'elementor' ),
15
- icon: TextDirectionLtrIcon,
15
+ renderContent: ( { size } ) => <TextDirectionLtrIcon fontSize={ size } />,
16
16
  },
17
17
  {
18
18
  value: 'rtl',
19
19
  label: __( 'Right to Left', 'elementor' ),
20
- icon: TextDirectionRtlIcon,
20
+ renderContent: ( { size } ) => <TextDirectionRtlIcon fontSize={ size } />,
21
21
  },
22
22
  ];
23
23
 
24
24
  export const TextDirectionField = () => {
25
25
  return (
26
26
  <StylesField bind={ 'direction' }>
27
- <Grid container spacing={ 1 } alignItems="center">
27
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
28
28
  <Grid item xs={ 6 }>
29
29
  <ControlLabel>{ __( 'Direction', 'elementor' ) }</ControlLabel>
30
30
  </Grid>
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
+ import { ControlLabel, StrokeControl } from '@elementor/editor-controls';
2
3
  import { __ } from '@wordpress/i18n';
3
- import { CollapsibleField } from '../../collapsible-field';
4
- import { ControlLabel } from '../../control-label';
4
+
5
5
  import { StylesField } from '../../../controls-registry/styles-field';
6
- import { StrokeControl } from '../../../controls';
6
+ import { CollapsibleField } from '../../collapsible-field';
7
7
 
8
8
  export const TextStrokeField = () => {
9
9
  return (
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
3
- import { Grid, ToggleButton as ToggleButtonBase, ToggleButtonGroup, ToggleButtonProps } from '@elementor/ui';
2
+ import { ControlLabel } from '@elementor/editor-controls';
4
3
  import { ItalicIcon, StrikethroughIcon, UnderlineIcon } from '@elementor/icons';
5
- import { ControlLabel } from '../../control-label';
4
+ import { Grid, ToggleButton as ToggleButtonBase, ToggleButtonGroup, type ToggleButtonProps } from '@elementor/ui';
5
+ import { __ } from '@wordpress/i18n';
6
+
6
7
  import { useStylesField } from '../../../hooks/use-styles-field';
7
8
 
8
9
  const buttonSize = 'tiny';
@@ -14,7 +15,7 @@ export const TextStyleField = () => {
14
15
  const formats = [ fontStyle, ...( textDecoration || '' ).split( ' ' ) ];
15
16
 
16
17
  return (
17
- <Grid container spacing={ 1 } alignItems="center">
18
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
18
19
  <Grid item xs={ 6 }>
19
20
  <ControlLabel>{ __( 'Style', 'elementor' ) }</ControlLabel>
20
21
  </Grid>
@@ -1,20 +1,34 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
3
- import { Grid } from '@elementor/ui';
2
+ import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
4
3
  import { LetterCaseIcon, LetterCaseLowerIcon, LetterCaseUpperIcon } from '@elementor/icons';
4
+ import { Grid } from '@elementor/ui';
5
+ import { __ } from '@wordpress/i18n';
6
+
5
7
  import { StylesField } from '../../../controls-registry/styles-field';
6
- import { ToggleControl } from '../../../controls';
7
- import { ControlLabel } from '../../control-label';
8
8
 
9
- const options = [
10
- { value: 'capitalize', label: __( 'Capitalize', 'elementor' ), icon: LetterCaseIcon },
11
- { value: 'uppercase', label: __( 'Uppercase', 'elementor' ), icon: LetterCaseUpperIcon },
12
- { value: 'lowercase', label: __( 'Lowercase', 'elementor' ), icon: LetterCaseLowerIcon },
9
+ type Transforms = 'capitalize' | 'uppercase' | 'lowercase';
10
+
11
+ const options: ToggleButtonGroupItem< Transforms >[] = [
12
+ {
13
+ value: 'capitalize',
14
+ label: __( 'Capitalize', 'elementor' ),
15
+ renderContent: ( { size } ) => <LetterCaseIcon fontSize={ size } />,
16
+ },
17
+ {
18
+ value: 'uppercase',
19
+ label: __( 'Uppercase', 'elementor' ),
20
+ renderContent: ( { size } ) => <LetterCaseUpperIcon fontSize={ size } />,
21
+ },
22
+ {
23
+ value: 'lowercase',
24
+ label: __( 'Lowercase', 'elementor' ),
25
+ renderContent: ( { size } ) => <LetterCaseLowerIcon fontSize={ size } />,
26
+ },
13
27
  ];
14
28
 
15
29
  export const TransformField = () => (
16
30
  <StylesField bind={ 'text-transform' }>
17
- <Grid container spacing={ 1 } alignItems="center">
31
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
18
32
  <Grid item xs={ 6 }>
19
33
  <ControlLabel>{ __( 'Transform', 'elementor' ) }</ControlLabel>
20
34
  </Grid>
@@ -1,40 +1,39 @@
1
1
  import * as React from 'react';
2
- import { AccordionSection } from '../../accordion-section';
3
2
  import { Divider, Stack } from '@elementor/ui';
4
- import { TextStyleField } from './text-style-field';
5
- import { __ } from '@wordpress/i18n';
3
+
4
+ import { CollapsibleContent } from '../../collapsible-content';
5
+ import { FontFamilyField } from './font-family-field';
6
6
  import { FontSizeField } from './font-size-field';
7
7
  import { FontWeightField } from './font-weight-field';
8
- import { TextColorField } from './text-color-field';
9
8
  import { LetterSpacingField } from './letter-spacing-field';
10
- import { WordSpacingField } from './word-spacing-field';
11
- import { CollapsibleContent } from '../../collapsible-content';
12
- import { TransformField } from './transform-field';
13
9
  import { TextAlignmentField } from './text-alignment-field';
10
+ import { TextColorField } from './text-color-field';
14
11
  import { TextDirectionField } from './text-direction-field';
15
12
  import { TextStrokeField } from './text-stroke-field';
13
+ import { TextStyleField } from './text-style-field';
14
+ import { TransformField } from './transform-field';
15
+ import { WordSpacingField } from './word-spacing-field';
16
16
 
17
17
  export const TypographySection = () => {
18
18
  return (
19
- <AccordionSection title={ __( 'Typography', 'elementor' ) }>
20
- <Stack gap={ 1.5 }>
21
- <FontWeightField />
22
- <FontSizeField />
23
- <Divider />
24
- <TextColorField />
25
- <CollapsibleContent>
26
- <Stack gap={ 1.5 } sx={ { pt: 1.5 } }>
27
- <LetterSpacingField />
28
- <WordSpacingField />
29
- <Divider />
30
- <TextAlignmentField />
31
- <TextStyleField />
32
- <TransformField />
33
- <TextDirectionField />
34
- <TextStrokeField />
35
- </Stack>
36
- </CollapsibleContent>
37
- </Stack>
38
- </AccordionSection>
19
+ <Stack gap={ 1.5 }>
20
+ <FontFamilyField />
21
+ <FontWeightField />
22
+ <FontSizeField />
23
+ <Divider />
24
+ <TextColorField />
25
+ <CollapsibleContent>
26
+ <Stack gap={ 1.5 } sx={ { pt: 1.5 } }>
27
+ <LetterSpacingField />
28
+ <WordSpacingField />
29
+ <Divider />
30
+ <TextAlignmentField />
31
+ <TextStyleField />
32
+ <TransformField />
33
+ <TextDirectionField />
34
+ <TextStrokeField />
35
+ </Stack>
36
+ </CollapsibleContent>
37
+ </Stack>
39
38
  );
40
39
  };
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { ControlLabel, SizeControl } from '@elementor/editor-controls';
3
3
  import { Grid } from '@elementor/ui';
4
+ import { __ } from '@wordpress/i18n';
5
+
4
6
  import { StylesField } from '../../../controls-registry/styles-field';
5
- import { SizeControl } from '../../../controls';
6
- import { ControlLabel } from '../../control-label';
7
7
 
8
8
  export const WordSpacingField = () => {
9
9
  return (
10
10
  <StylesField bind="word-spacing">
11
- <Grid container spacing={ 1 } alignItems="center">
11
+ <Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
12
12
  <Grid item xs={ 6 }>
13
13
  <ControlLabel>{ __( 'Word Spacing', 'elementor' ) }</ControlLabel>
14
14
  </Grid>
@@ -1,58 +1,94 @@
1
1
  import * as React from 'react';
2
2
  import { useState } from 'react';
3
- import { Stack } from '@elementor/ui';
4
- import { generateId, StyleDefinition } from '@elementor/editor-styles';
3
+ import { useElementSetting, useElementStyles } from '@elementor/editor-elements';
4
+ import { type ClassesPropValue, type PropKey } from '@elementor/editor-props';
5
5
  import { useActiveBreakpoint } from '@elementor/editor-responsive';
6
- import { getElementStyles, getElementSetting } from '@elementor/editor-elements';
6
+ import { generateId, type StyleDefinition } from '@elementor/editor-styles';
7
+ import { Divider } from '@elementor/ui';
8
+ import { __ } from '@wordpress/i18n';
9
+
10
+ import { ClassesPropProvider } from '../contexts/classes-prop-context';
11
+ import { useElement } from '../contexts/element-context';
7
12
  import { StyleProvider } from '../contexts/style-context';
8
- import { SizeSection } from './style-sections/size-section/size-section';
9
- import { TypographySection } from './style-sections/typography-section/typography-section';
10
- import { PositionSection } from './style-sections/position-section/position-section';
11
- import { SpacingSection } from './style-sections/spacing-section/spacing-section';
12
- import { EffectsSection } from './style-sections/effects-section/effects-section';
13
+ import { CssClassSelectorSection } from './css-class-selector-section';
14
+ import { Section } from './section';
15
+ import { SectionsList } from './sections-list';
13
16
  import { BackgroundSection } from './style-sections/background-section/background-section';
14
17
  import { BorderSection } from './style-sections/border-section/border-section';
15
- import { useElement } from '../contexts/element-context';
16
- import { ClassesPropValue, PropKey } from '@elementor/editor-props';
17
- import { ClassesPropProvider } from '../contexts/classes-prop-context';
18
+ import { EffectsSection } from './style-sections/effects-section/effects-section';
19
+ import { LayoutSection } from './style-sections/layout-section/layout-section';
20
+ import { PositionSection } from './style-sections/position-section/position-section';
21
+ import { SizeSection } from './style-sections/size-section/size-section';
22
+ import { SpacingSection } from './style-sections/spacing-section/spacing-section';
23
+ import { TypographySection } from './style-sections/typography-section/typography-section';
18
24
 
19
25
  const CLASSES_PROP_KEY = 'classes';
20
26
 
21
27
  export const StyleTab = () => {
22
28
  const currentClassesProp = useCurrentClassesProp();
23
- const [ selectedStyleDefId ] = useSelectedStyleDefId( currentClassesProp );
29
+ const [ activeStyleDefId, setActiveStyleDefId ] = useActiveStyleDefId( currentClassesProp );
24
30
  const breakpoint = useActiveBreakpoint();
25
31
 
26
32
  return (
27
33
  <ClassesPropProvider prop={ currentClassesProp }>
28
- <StyleProvider meta={ { breakpoint, state: null } } id={ selectedStyleDefId }>
29
- <Stack>
30
- <SpacingSection />
31
- <SizeSection />
32
- <PositionSection />
33
- <TypographySection />
34
- <BackgroundSection />
35
- <BorderSection />
36
- <EffectsSection />
37
- </Stack>
34
+ <StyleProvider meta={ { breakpoint, state: null } } id={ activeStyleDefId } setId={ setActiveStyleDefId }>
35
+ <CssClassSelectorSection />
36
+ <Divider />
37
+ <SectionsList>
38
+ <Section title={ __( 'Layout', 'elementor' ) }>
39
+ <LayoutSection />
40
+ </Section>
41
+ <Section title={ __( 'Spacing', 'elementor' ) }>
42
+ <SpacingSection />
43
+ </Section>
44
+ <Section title={ __( 'Size', 'elementor' ) }>
45
+ <SizeSection />
46
+ </Section>
47
+ <Section title={ __( 'Position', 'elementor' ) }>
48
+ <PositionSection />
49
+ </Section>
50
+ <Section title={ __( 'Typography', 'elementor' ) }>
51
+ <TypographySection />
52
+ </Section>
53
+ <Section title={ __( 'Background', 'elementor' ) }>
54
+ <BackgroundSection />
55
+ </Section>
56
+ <Section title={ __( 'Border', 'elementor' ) }>
57
+ <BorderSection />
58
+ </Section>
59
+ <Section title={ __( 'Effects', 'elementor' ) }>
60
+ <EffectsSection />
61
+ </Section>
62
+ </SectionsList>
38
63
  </StyleProvider>
39
64
  </ClassesPropProvider>
40
65
  );
41
66
  };
42
67
 
43
- function useSelectedStyleDefId( currentClassesProp: PropKey ) {
68
+ function useActiveStyleDefId( currentClassesProp: PropKey ) {
69
+ const [ activeStyledDefId, setActiveStyledDefId ] = useState< StyleDefinition[ 'id' ] | null >( null );
70
+
71
+ const fallback = useFirstElementStyleDef( currentClassesProp );
72
+
73
+ const newId = useGeneratedId();
74
+
75
+ return [ activeStyledDefId || fallback?.id || newId, setActiveStyledDefId ] as const;
76
+ }
77
+
78
+ function useFirstElementStyleDef( currentClassesProp: PropKey ) {
44
79
  const { element } = useElement();
45
80
 
46
- const [ selectedStyleDefId, setSelectedStyleDefId ] = useState< StyleDefinition[ 'id' ] >( () => {
47
- const styleIds = getElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value ?? [];
48
- const stylesDefs = getElementStyles( element.id ) ?? {};
81
+ const classesIds = useElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
82
+ const stylesDefs = useElementStyles( element.id );
49
83
 
50
- return (
51
- styleIds.find( ( id ) => id in stylesDefs ) ?? generateId( `e-${ element.id }-`, Object.keys( stylesDefs ) )
52
- );
53
- } );
84
+ return Object.values( stylesDefs ).find( ( styleDef ) => classesIds.includes( styleDef.id ) );
85
+ }
86
+
87
+ function useGeneratedId() {
88
+ const { element } = useElement();
89
+ const stylesDefs = useElementStyles( element.id );
54
90
 
55
- return [ selectedStyleDefId, setSelectedStyleDefId ] as const;
91
+ return generateId( `e-${ element.id }-`, Object.keys( stylesDefs ) );
56
92
  }
57
93
 
58
94
  function useCurrentClassesProp(): string {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { createContext, PropsWithChildren, useContext } from 'react';
2
+ import { createContext, type PropsWithChildren, useContext } from 'react';
3
3
 
4
4
  type ContextValue = {
5
5
  prop: string;
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { createContext, PropsWithChildren, useContext } from 'react';
3
- import { ElementType, Element } from '@elementor/editor-elements';
2
+ import { createContext, type PropsWithChildren, useContext } from 'react';
3
+ import { type Element, type ElementType } from '@elementor/editor-elements';
4
4
 
5
5
  type ContextValue = {
6
6
  element: Element;
@@ -1,9 +1,10 @@
1
1
  import * as React from 'react';
2
- import { createContext, PropsWithChildren, useContext } from 'react';
3
- import { StyleDefinition, StyleVariant } from '@elementor/editor-styles';
2
+ import { createContext, type Dispatch, type PropsWithChildren, useContext } from 'react';
3
+ import { type StyleDefinition, type StyleVariant } from '@elementor/editor-styles';
4
4
 
5
5
  type ContextValue = {
6
6
  id: StyleDefinition[ 'id' ];
7
+ setId: Dispatch< StyleDefinition[ 'id' ] >;
7
8
  meta: StyleVariant[ 'meta' ];
8
9
  };
9
10
 
@@ -11,15 +12,15 @@ const Context = createContext< ContextValue | null >( null );
11
12
 
12
13
  type Props = PropsWithChildren< ContextValue >;
13
14
 
14
- export function StyleProvider( { children, id, meta }: Props ) {
15
- return <Context.Provider value={ { id, meta } }>{ children }</Context.Provider>;
15
+ export function StyleProvider( { children, id, setId, meta }: Props ) {
16
+ return <Context.Provider value={ { id, setId, meta } }>{ children }</Context.Provider>;
16
17
  }
17
18
 
18
19
  export function useStyle() {
19
20
  const context = useContext( Context );
20
21
 
21
22
  if ( ! context ) {
22
- throw new Error( 'UseStyleContext must be used within a StyleContextProvider' );
23
+ throw new Error( 'useStyle must be used within a StyleProvider' );
23
24
  }
24
25
 
25
26
  return context;
@@ -1,3 +1,3 @@
1
- import { createControlReplacement } from './controls';
1
+ import { createControlReplacement } from '@elementor/editor-controls';
2
2
 
3
3
  export const { replaceControl, getControlReplacement } = createControlReplacement();
@@ -1,7 +1,8 @@
1
- import { createControlActionsMenu } from './controls';
1
+ import { createMenu } from '@elementor/menus';
2
+
2
3
  import PopoverAction from './popover-action';
3
4
 
4
- export const { useMenuItems, registerPopoverAction } = createControlActionsMenu( {
5
+ export const controlActionsMenu = createMenu( {
5
6
  components: {
6
7
  PopoverAction,
7
8
  },
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
- import { styled, Box, BoxProps } from '@elementor/ui';
3
- import { ControlLayout, ControlType, getLayoutByType } from './controls-registry';
2
+ import { Box, type BoxProps, styled } from '@elementor/ui';
3
+
4
+ import { type ControlLayout, type ControlType, getLayoutByType } from './controls-registry';
4
5
 
5
6
  export const ControlTypeContainer = ( {
6
7
  controlType,
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import type { ComponentProps } from 'react';
3
3
  import { createError } from '@elementor/utils';
4
- import { ControlType, ControlTypes, getControlByType } from './controls-registry';
4
+
5
+ import { type ControlType, type ControlTypes, getControlByType } from './controls-registry';
5
6
 
6
7
  export type ControlTypeErrorContext = {
7
8
  type: string;
@@ -1,4 +1,11 @@
1
- import { ControlComponent, ImageControl, SelectControl, SizeControl, TextAreaControl, TextControl } from '../controls';
1
+ import {
2
+ type ControlComponent,
3
+ ImageControl,
4
+ SelectControl,
5
+ SizeControl,
6
+ TextAreaControl,
7
+ TextControl,
8
+ } from '@elementor/editor-controls';
2
9
 
3
10
  export type ControlLayout = 'full' | 'two-columns';
4
11
 
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
- import { PropKey, PropValue } from '@elementor/editor-props';
3
- import { useElementSetting, updateSettings } from '@elementor/editor-elements';
2
+ import { BoundPropProvider } from '@elementor/editor-controls';
3
+ import { updateSettings, useElementSetting } from '@elementor/editor-elements';
4
+ import { type PropKey, type PropValue } from '@elementor/editor-props';
5
+
4
6
  import { useElement } from '../contexts/element-context';
5
- import { BoundPropProvider } from '../controls';
6
7
 
7
8
  type Props = {
8
9
  bind: PropKey;
@@ -13,7 +14,7 @@ const SettingsField = ( { bind, children }: Props ) => {
13
14
  const { element, elementType } = useElement();
14
15
 
15
16
  const defaultValue = elementType.propsSchema[ bind ]?.default;
16
- const settingsValue = useElementSetting( { id: element.id, bind } );
17
+ const settingsValue = useElementSetting( element.id, bind );
17
18
  const value = settingsValue ?? defaultValue ?? null;
18
19
 
19
20
  const setValue = ( newValue: PropValue ) => {