@elementor/editor-editing-panel 1.0.0 → 1.2.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 (120) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/index.d.mts +10 -19
  3. package/dist/index.d.ts +10 -19
  4. package/dist/index.js +1539 -1754
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1534 -1723
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +13 -13
  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.tsx +131 -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 +122 -0
  19. package/src/components/multi-combobox/types.ts +28 -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/align-items-field.tsx +92 -0
  34. package/src/components/style-sections/layout-section/display-field.tsx +32 -0
  35. package/src/components/style-sections/layout-section/flex-direction-field.tsx +64 -0
  36. package/src/components/style-sections/layout-section/flex-order-field.tsx +114 -0
  37. package/src/components/style-sections/layout-section/justify-content-field.tsx +109 -0
  38. package/src/components/style-sections/layout-section/layout-section.tsx +36 -0
  39. package/src/components/style-sections/layout-section/wrap-field.tsx +52 -0
  40. package/src/components/style-sections/position-section/dimensions-field.tsx +6 -6
  41. package/src/components/style-sections/position-section/position-field.tsx +4 -4
  42. package/src/components/style-sections/position-section/position-section.tsx +45 -15
  43. package/src/components/style-sections/position-section/z-index-field.tsx +4 -4
  44. package/src/components/style-sections/size-section/overflow-field.tsx +8 -8
  45. package/src/components/style-sections/size-section/size-section.tsx +33 -26
  46. package/src/components/style-sections/spacing-section/spacing-section.tsx +11 -13
  47. package/src/components/style-sections/typography-section/font-family-field.tsx +40 -0
  48. package/src/components/style-sections/typography-section/font-size-field.tsx +4 -4
  49. package/src/components/style-sections/typography-section/font-weight-field.tsx +4 -4
  50. package/src/components/style-sections/typography-section/letter-spacing-field.tsx +4 -4
  51. package/src/components/style-sections/typography-section/text-alignment-field.tsx +9 -9
  52. package/src/components/style-sections/typography-section/text-color-field.tsx +4 -4
  53. package/src/components/style-sections/typography-section/text-direction-field.tsx +7 -7
  54. package/src/components/style-sections/typography-section/text-stroke-field.tsx +42 -7
  55. package/src/components/style-sections/typography-section/text-style-field.tsx +5 -4
  56. package/src/components/style-sections/typography-section/transform-field.tsx +23 -9
  57. package/src/components/style-sections/typography-section/typography-section.tsx +26 -27
  58. package/src/components/style-sections/typography-section/word-spacing-field.tsx +4 -4
  59. package/src/components/style-tab.tsx +67 -31
  60. package/src/contexts/classes-prop-context.tsx +1 -1
  61. package/src/contexts/element-context.tsx +2 -2
  62. package/src/contexts/style-context.tsx +6 -5
  63. package/src/control-replacement.tsx +1 -1
  64. package/src/controls-actions.ts +3 -2
  65. package/src/controls-registry/control-type-container.tsx +3 -2
  66. package/src/controls-registry/control.tsx +2 -1
  67. package/src/controls-registry/controls-registry.tsx +8 -1
  68. package/src/controls-registry/settings-field.tsx +5 -4
  69. package/src/controls-registry/styles-field.tsx +3 -2
  70. package/src/dynamics/components/dynamic-selection-control.tsx +15 -14
  71. package/src/dynamics/components/dynamic-selection.tsx +9 -8
  72. package/src/dynamics/dynamic-control.tsx +4 -4
  73. package/src/dynamics/hooks/use-dynamic-tag.ts +3 -2
  74. package/src/dynamics/hooks/use-prop-dynamic-action.tsx +6 -5
  75. package/src/dynamics/hooks/use-prop-dynamic-tags.ts +3 -2
  76. package/src/dynamics/init.ts +5 -3
  77. package/src/dynamics/sync/get-elementor-config.ts +1 -1
  78. package/src/dynamics/types.ts +2 -2
  79. package/src/dynamics/utils.ts +3 -2
  80. package/src/hooks/use-close-editor-panel.ts +23 -0
  81. package/src/hooks/use-direction.ts +13 -0
  82. package/src/hooks/use-open-editor-panel.ts +4 -3
  83. package/src/hooks/use-prop-value-history.ts +45 -0
  84. package/src/hooks/use-style-prop-history.ts +75 -0
  85. package/src/hooks/use-styles-field.ts +25 -4
  86. package/src/index.ts +1 -1
  87. package/src/init.ts +5 -4
  88. package/src/panel.ts +1 -0
  89. package/src/popover-action.tsx +1 -1
  90. package/src/sync/enqueue-font.ts +7 -0
  91. package/src/sync/get-elementor-config.ts +7 -0
  92. package/src/sync/{should-use-v2-panel.ts → is-atomic-widget-selected.ts} +1 -1
  93. package/src/sync/types.ts +20 -21
  94. package/src/components/accordion-section.tsx +0 -26
  95. package/src/components/control-label.tsx +0 -10
  96. package/src/controls/bound-prop-context.tsx +0 -30
  97. package/src/controls/components/control-toggle-button-group.tsx +0 -68
  98. package/src/controls/components/repeater.tsx +0 -197
  99. package/src/controls/components/text-field-inner-selection.tsx +0 -75
  100. package/src/controls/control-actions/control-actions-context.tsx +0 -27
  101. package/src/controls/control-actions/control-actions-menu.ts +0 -7
  102. package/src/controls/control-actions/control-actions.tsx +0 -31
  103. package/src/controls/controls/box-shadow-repeater-control.tsx +0 -210
  104. package/src/controls/controls/color-control.tsx +0 -25
  105. package/src/controls/controls/equal-unequal-sizes-control.tsx +0 -196
  106. package/src/controls/controls/image-control.tsx +0 -58
  107. package/src/controls/controls/image-media-control.tsx +0 -64
  108. package/src/controls/controls/linked-dimensions-control.tsx +0 -139
  109. package/src/controls/controls/number-control.tsx +0 -29
  110. package/src/controls/controls/select-control.tsx +0 -30
  111. package/src/controls/controls/size-control.tsx +0 -71
  112. package/src/controls/controls/stroke-control.tsx +0 -105
  113. package/src/controls/controls/text-area-control.tsx +0 -31
  114. package/src/controls/controls/text-control.tsx +0 -17
  115. package/src/controls/controls/toggle-control.tsx +0 -26
  116. package/src/controls/create-control-replacement.tsx +0 -53
  117. package/src/controls/create-control.tsx +0 -40
  118. package/src/controls/hooks/use-sync-external-state.tsx +0 -51
  119. package/src/controls/index.ts +0 -24
  120. package/src/dynamics/hooks/use-prop-value-history.ts +0 -26
@@ -1,16 +1,51 @@
1
1
  import * as React from 'react';
2
+ import { 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 { useStylesField } from '../../../hooks/use-styles-field';
7
+ import { AddOrRemoveContent } from '../../add-or-remove-content';
8
+
9
+ const initTextStroke = {
10
+ $$type: 'stroke',
11
+ value: {
12
+ color: {
13
+ $$type: 'color',
14
+ value: '#000000',
15
+ },
16
+ width: {
17
+ $$type: 'size',
18
+ value: {
19
+ unit: 'px',
20
+ size: 1,
21
+ },
22
+ },
23
+ },
24
+ };
7
25
 
8
26
  export const TextStrokeField = () => {
27
+ const [ textStroke, setTextStroke ] = useStylesField( '-webkit-text-stroke' );
28
+
29
+ const addTextStroke = () => {
30
+ setTextStroke( initTextStroke );
31
+ };
32
+
33
+ const removeTextStroke = () => {
34
+ setTextStroke( null );
35
+ };
36
+
37
+ const hasTextStroke = Boolean( textStroke );
38
+
9
39
  return (
10
- <StylesField bind="-webkit-text-stroke">
11
- <CollapsibleField label={ <ControlLabel>{ __( 'Text Stroke', 'elementor' ) }</ControlLabel> }>
40
+ <AddOrRemoveContent
41
+ label={ __( 'Text Stroke', 'elementor' ) }
42
+ isAdded={ hasTextStroke }
43
+ onAdd={ addTextStroke }
44
+ onRemove={ removeTextStroke }
45
+ >
46
+ <StylesField bind={ '-webkit-text-stroke' }>
12
47
  <StrokeControl />
13
- </CollapsibleField>
14
- </StylesField>
48
+ </StylesField>
49
+ </AddOrRemoveContent>
15
50
  );
16
51
  };
@@ -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 { CssClassSelector } from './css-class-selector';
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
+ <CssClassSelector />
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 ) => {
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
- import { PropKey } from '@elementor/editor-props';
2
+ import { BoundPropProvider } from '@elementor/editor-controls';
3
+ import { type PropKey } from '@elementor/editor-props';
4
+
3
5
  import { useStylesField } from '../hooks/use-styles-field';
4
- import { BoundPropProvider } from '../controls';
5
6
 
6
7
  export type StylesFieldProps = {
7
8
  bind: PropKey;
@@ -1,40 +1,40 @@
1
1
  import * as React from 'react';
2
2
  import { useId } from 'react';
3
- import { __ } from '@wordpress/i18n';
3
+ import { ControlLabel, useBoundProp } from '@elementor/editor-controls';
4
4
  import type { Control, ControlsSection } from '@elementor/editor-elements';
5
5
  import { DatabaseIcon, SettingsIcon, XIcon } from '@elementor/icons';
6
6
  import {
7
7
  bindPopover,
8
8
  bindTrigger,
9
9
  Box,
10
+ Divider,
10
11
  IconButton,
11
12
  Paper,
12
13
  Popover,
13
14
  Stack,
15
+ Tab,
16
+ TabPanel,
17
+ Tabs,
14
18
  Typography,
15
19
  UnstableTag as Tag,
16
20
  usePopupState,
17
- Tabs,
18
- Divider,
19
21
  useTabs,
20
- Tab,
21
- TabPanel,
22
22
  } from '@elementor/ui';
23
- import { useBoundProp } from '../../controls';
24
- import { DynamicPropValue, DynamicTag } from '../types';
25
- import { DynamicControl } from '../dynamic-control';
26
- import { DynamicSelection } from './dynamic-selection';
27
- import { ControlLabel } from '../../components/control-label';
23
+ import { __ } from '@wordpress/i18n';
24
+
28
25
  import { Control as BaseControl } from '../../controls-registry/control';
26
+ import { type ControlType, getControlByType } from '../../controls-registry/controls-registry';
27
+ import { usePropValueHistory } from '../../hooks/use-prop-value-history';
28
+ import { DynamicControl } from '../dynamic-control';
29
29
  import { useDynamicTag } from '../hooks/use-dynamic-tag';
30
- import { usePropValueHistory } from '../hooks/use-prop-value-history';
31
- import { ControlType, getControlByType } from '../../controls-registry/controls-registry';
30
+ import { type DynamicPropValue, type DynamicTag } from '../types';
31
+ import { DynamicSelection } from './dynamic-selection';
32
32
 
33
33
  const SIZE = 'tiny';
34
34
 
35
35
  export const DynamicSelectionControl = () => {
36
36
  const { bind, value, setValue } = useBoundProp< DynamicPropValue | null >();
37
- const [ propValueFromHistory ] = usePropValueHistory( bind );
37
+ const { getPropValue: getPropValueFromHistory } = usePropValueHistory();
38
38
  const { name: tagName = '' } = value?.value || {};
39
39
 
40
40
  const selectionPopoverId = useId();
@@ -43,7 +43,8 @@ export const DynamicSelectionControl = () => {
43
43
  const dynamicTag = useDynamicTag( bind, tagName );
44
44
 
45
45
  const removeDynamicTag = () => {
46
- setValue( propValueFromHistory ?? null );
46
+ const propValue = getPropValueFromHistory< DynamicPropValue >( bind );
47
+ setValue( propValue ?? null );
47
48
  };
48
49
 
49
50
  if ( ! dynamicTag ) {
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
- import { useState, Fragment } from 'react';
3
- import { PropKey, PropValue } from '@elementor/editor-props';
4
- import { SearchIcon, PhotoIcon } from '@elementor/icons';
2
+ import { Fragment, useState } from 'react';
3
+ import { useBoundProp } from '@elementor/editor-controls';
4
+ import { type PropKey, type PropValue } from '@elementor/editor-props';
5
+ import { PhotoIcon, SearchIcon } from '@elementor/icons';
5
6
  import {
6
7
  Box,
7
8
  Divider,
@@ -15,12 +16,12 @@ import {
15
16
  Typography,
16
17
  } from '@elementor/ui';
17
18
  import { __ } from '@wordpress/i18n';
18
- import { useBoundProp } from '../../controls';
19
+
20
+ import { usePropValueHistory } from '../../hooks/use-prop-value-history';
19
21
  import { usePropDynamicTags } from '../hooks/use-prop-dynamic-tags';
20
22
  import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
23
+ import { type DynamicPropValue } from '../types';
21
24
  import { isDynamicPropValue } from '../utils';
22
- import { usePropValueHistory } from '../hooks/use-prop-value-history';
23
- import { DynamicPropValue } from '../types';
24
25
 
25
26
  type Option = {
26
27
  label: string;
@@ -39,7 +40,7 @@ export const DynamicSelection = ( { onSelect }: DynamicSelectionProps ) => {
39
40
  const [ searchValue, setSearchValue ] = useState( '' );
40
41
  const { groups: dynamicGroups } = getAtomicDynamicTags() || {};
41
42
  const { bind, value: currentValue, setValue } = useBoundProp< DynamicPropValue | PropValue >();
42
- const [ , updatePropValueHistory ] = usePropValueHistory( bind );
43
+ const { setPropValue: updatePropValueHistory } = usePropValueHistory();
43
44
 
44
45
  const isCurrentValueDynamic = isDynamicPropValue( currentValue );
45
46
 
@@ -51,7 +52,7 @@ export const DynamicSelection = ( { onSelect }: DynamicSelectionProps ) => {
51
52
 
52
53
  const handleSetDynamicTag = ( value: string ) => {
53
54
  if ( ! isCurrentValueDynamic ) {
54
- updatePropValueHistory( currentValue );
55
+ updatePropValueHistory( bind, currentValue );
55
56
  }
56
57
 
57
58
  setValue( { $$type: 'dynamic', value: { name: value, settings: {} } } );
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import { useBoundProp } from '../controls';
3
- import { PropKey, PropValue } from '@elementor/editor-props';
2
+ import { BoundPropProvider, useBoundProp } from '@elementor/editor-controls';
3
+ import { type PropKey, type PropValue } from '@elementor/editor-props';
4
+
4
5
  import { useDynamicTag } from './hooks/use-dynamic-tag';
5
- import { DynamicPropValue } from './types';
6
- import { BoundPropProvider } from '../controls/bound-prop-context';
6
+ import { type DynamicPropValue } from './types';
7
7
 
8
8
  export type DynamicControlProps = React.PropsWithChildren< {
9
9
  bind: PropKey;
@@ -1,7 +1,8 @@
1
1
  import { useMemo } from 'react';
2
- import { PropKey } from '@elementor/editor-props';
2
+ import { type PropKey } from '@elementor/editor-props';
3
+
4
+ import { type DynamicTag } from '../types';
3
5
  import { usePropDynamicTags } from './use-prop-dynamic-tags';
4
- import { DynamicTag } from '../types';
5
6
 
6
7
  export const useDynamicTag = ( propName: PropKey, tagName: string ): DynamicTag | null => {
7
8
  const dynamicTags = usePropDynamicTags( propName );
@@ -1,11 +1,12 @@
1
1
  import * as React from 'react';
2
- import { __ } from '@wordpress/i18n';
2
+ import { useBoundProp } from '@elementor/editor-controls';
3
3
  import { DatabaseIcon } from '@elementor/icons';
4
- import { supportsDynamic } from '../utils';
5
- import { DynamicSelection } from '../components/dynamic-selection';
6
- import { useBoundProp } from '../../controls';
7
- import { PopoverActionProps } from '../../popover-action';
4
+ import { __ } from '@wordpress/i18n';
5
+
8
6
  import { useElement } from '../../contexts/element-context';
7
+ import { type PopoverActionProps } from '../../popover-action';
8
+ import { DynamicSelection } from '../components/dynamic-selection';
9
+ import { supportsDynamic } from '../utils';
9
10
 
10
11
  export const usePropDynamicAction = (): PopoverActionProps => {
11
12
  const { bind } = useBoundProp();