@elementor/editor-editing-panel 0.19.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 (139) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/dist/index.d.mts +10 -36
  3. package/dist/index.d.ts +10 -36
  4. package/dist/index.js +1256 -1445
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1311 -1482
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +15 -14
  9. package/src/components/add-or-remove-content.tsx +42 -0
  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 +36 -0
  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 +21 -21
  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 +17 -16
  24. package/src/components/style-sections/background-section/background-color-field.tsx +21 -0
  25. package/src/components/style-sections/background-section/background-section.tsx +10 -8
  26. package/src/components/style-sections/border-section/border-color-field.tsx +21 -0
  27. package/src/components/style-sections/border-section/border-field.tsx +48 -0
  28. package/src/components/style-sections/border-section/border-radius-field.tsx +49 -0
  29. package/src/components/style-sections/border-section/border-section.tsx +13 -0
  30. package/src/components/style-sections/border-section/border-style-field.tsx +32 -0
  31. package/src/components/style-sections/border-section/border-width-field.tsx +43 -0
  32. package/src/components/style-sections/effects-section/effects-section.tsx +8 -11
  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 +46 -0
  38. package/src/components/style-sections/position-section/position-field.tsx +28 -0
  39. package/src/components/style-sections/position-section/position-section.tsx +51 -8
  40. package/src/components/style-sections/position-section/z-index-field.tsx +21 -0
  41. package/src/components/style-sections/size-section/overflow-field.tsx +45 -0
  42. package/src/components/style-sections/size-section/size-section.tsx +62 -0
  43. package/src/components/style-sections/spacing-section/spacing-section.tsx +12 -14
  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 +21 -0
  46. package/src/components/style-sections/typography-section/{font-weight-control.tsx → font-weight-field.tsx} +9 -8
  47. package/src/components/style-sections/typography-section/letter-spacing-field.tsx +21 -0
  48. package/src/components/style-sections/typography-section/text-alignment-field.tsx +47 -0
  49. package/src/components/style-sections/typography-section/text-color-field.tsx +21 -0
  50. package/src/components/style-sections/typography-section/{text-direction-control.tsx → text-direction-field.tsx} +12 -12
  51. package/src/components/style-sections/typography-section/text-stroke-field.tsx +16 -0
  52. package/src/components/style-sections/typography-section/{text-style-control.tsx → text-style-field.tsx} +9 -8
  53. package/src/components/style-sections/typography-section/transform-field.tsx +40 -0
  54. package/src/components/style-sections/typography-section/typography-section.tsx +31 -30
  55. package/src/components/style-sections/typography-section/word-spacing-field.tsx +21 -0
  56. package/src/components/style-tab.tsx +82 -29
  57. package/src/contexts/classes-prop-context.tsx +24 -0
  58. package/src/{controls/providers/element-provider.tsx → contexts/element-context.tsx} +3 -7
  59. package/src/contexts/style-context.tsx +10 -23
  60. package/src/control-replacement.tsx +1 -1
  61. package/src/{controls/control-actions/control-actions-menu.ts → controls-actions.ts} +2 -1
  62. package/src/{controls/components → controls-registry}/control-type-container.tsx +3 -2
  63. package/src/{controls → controls-registry}/control.tsx +2 -1
  64. package/src/{controls → controls-registry}/controls-registry.tsx +8 -6
  65. package/src/controls-registry/settings-field.tsx +36 -0
  66. package/src/controls-registry/styles-field.tsx +20 -0
  67. package/src/dynamics/components/dynamic-selection-control.tsx +18 -17
  68. package/src/dynamics/components/dynamic-selection.tsx +10 -9
  69. package/src/dynamics/dynamic-control.tsx +7 -6
  70. package/src/dynamics/hooks/use-dynamic-tag.ts +3 -2
  71. package/src/dynamics/hooks/use-prop-dynamic-action.tsx +7 -6
  72. package/src/dynamics/hooks/use-prop-dynamic-tags.ts +3 -2
  73. package/src/dynamics/init.ts +3 -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 -3
  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 +51 -0
  83. package/src/index.ts +2 -3
  84. package/src/init.ts +5 -4
  85. package/src/panel.ts +1 -0
  86. package/src/{controls/control-actions/actions/popover-action.tsx → popover-action.tsx} +2 -2
  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} +2 -3
  90. package/src/sync/types.ts +20 -21
  91. package/src/components/accordion-section.tsx +0 -25
  92. package/src/components/control-label.tsx +0 -10
  93. package/src/components/style-sections/background-section/background-color-control.tsx +0 -20
  94. package/src/components/style-sections/effects-section/box-shadow-repeater.tsx +0 -224
  95. package/src/components/style-sections/position-section/z-index-control.tsx +0 -20
  96. package/src/components/style-sections/size-section.tsx +0 -49
  97. package/src/components/style-sections/spacing-section/linked-dimensions-control.tsx +0 -155
  98. package/src/components/style-sections/typography-section/font-size-control.tsx +0 -20
  99. package/src/components/style-sections/typography-section/letter-spacing-control.tsx +0 -20
  100. package/src/components/style-sections/typography-section/text-alignment-control.tsx +0 -47
  101. package/src/components/style-sections/typography-section/text-color-control.tsx +0 -20
  102. package/src/components/style-sections/typography-section/transform-control.tsx +0 -25
  103. package/src/components/style-sections/typography-section/word-spacing-control.tsx +0 -20
  104. package/src/controls/components/control-toggle-button-group.tsx +0 -59
  105. package/src/controls/components/repeater.tsx +0 -197
  106. package/src/controls/components/text-field-inner-selection.tsx +0 -79
  107. package/src/controls/control-actions/control-actions.tsx +0 -43
  108. package/src/controls/control-context.tsx +0 -22
  109. package/src/controls/control-replacement.ts +0 -34
  110. package/src/controls/control-types/color-control.tsx +0 -27
  111. package/src/controls/control-types/image-control.tsx +0 -66
  112. package/src/controls/control-types/image-media-control.tsx +0 -73
  113. package/src/controls/control-types/number-control.tsx +0 -29
  114. package/src/controls/control-types/select-control.tsx +0 -30
  115. package/src/controls/control-types/size-control.tsx +0 -71
  116. package/src/controls/control-types/text-area-control.tsx +0 -31
  117. package/src/controls/control-types/text-control.tsx +0 -17
  118. package/src/controls/control-types/toggle-control.tsx +0 -26
  119. package/src/controls/create-control-replacement.tsx +0 -53
  120. package/src/controls/create-control.tsx +0 -40
  121. package/src/controls/hooks/use-style-control.ts +0 -29
  122. package/src/controls/hooks/use-sync-external-state.tsx +0 -51
  123. package/src/controls/hooks/use-widget-settings.ts +0 -16
  124. package/src/controls/props/is-transformable.ts +0 -13
  125. package/src/controls/props/types.ts +0 -51
  126. package/src/controls/settings-control.tsx +0 -37
  127. package/src/controls/style-control.tsx +0 -20
  128. package/src/controls/sync/get-container.ts +0 -8
  129. package/src/controls/sync/update-settings.ts +0 -14
  130. package/src/controls/types.ts +0 -39
  131. package/src/dynamics/hooks/use-prop-value-history.ts +0 -26
  132. package/src/hooks/use-element-style-prop.ts +0 -46
  133. package/src/hooks/use-element-styles.ts +0 -13
  134. package/src/hooks/use-element-type.ts +0 -33
  135. package/src/hooks/use-selected-elements.ts +0 -9
  136. package/src/sync/get-element-styles.ts +0 -9
  137. package/src/sync/get-selected-elements.ts +0 -21
  138. package/src/sync/get-widgets-cache.ts +0 -7
  139. package/src/sync/update-style.ts +0 -25
@@ -1,37 +1,97 @@
1
1
  import * as React from 'react';
2
- import { StyleContext } from '../contexts/style-context';
3
- import { useElement } from '../controls/providers/element-provider';
4
- import { useElementStyles } from '../hooks/use-element-styles';
5
- import { Stack } from '@elementor/ui';
6
- import { SizeSection } from './style-sections/size-section';
7
- import { TypographySection } from './style-sections/typography-section/typography-section';
2
+ import { useState } from 'react';
3
+ import { useElementSetting, useElementStyles } from '@elementor/editor-elements';
4
+ import { type ClassesPropValue, type PropKey } from '@elementor/editor-props';
5
+ import { useActiveBreakpoint } from '@elementor/editor-responsive';
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';
12
+ import { StyleProvider } from '../contexts/style-context';
13
+ import { CssClassSelectorSection } from './css-class-selector-section';
14
+ import { Section } from './section';
15
+ import { SectionsList } from './sections-list';
16
+ import { BackgroundSection } from './style-sections/background-section/background-section';
17
+ import { BorderSection } from './style-sections/border-section/border-section';
18
+ import { EffectsSection } from './style-sections/effects-section/effects-section';
19
+ import { LayoutSection } from './style-sections/layout-section/layout-section';
8
20
  import { PositionSection } from './style-sections/position-section/position-section';
9
- import { StyleDefinition } from '@elementor/editor-style';
21
+ import { SizeSection } from './style-sections/size-section/size-section';
10
22
  import { SpacingSection } from './style-sections/spacing-section/spacing-section';
11
- import { EffectsSection } from './style-sections/effects-section/effects-section';
12
- import { BackgroundSection } from './style-sections/background-section/background-section';
23
+ import { TypographySection } from './style-sections/typography-section/typography-section';
13
24
 
14
25
  const CLASSES_PROP_KEY = 'classes';
15
26
 
16
27
  export const StyleTab = () => {
17
- const styleDefinition = useStyleDefinition();
18
- const classesProp = useClassesProp();
28
+ const currentClassesProp = useCurrentClassesProp();
29
+ const [ activeStyleDefId, setActiveStyleDefId ] = useActiveStyleDefId( currentClassesProp );
30
+ const breakpoint = useActiveBreakpoint();
19
31
 
20
32
  return (
21
- <StyleContext selectedStyleDef={ styleDefinition } selectedClassesProp={ classesProp }>
22
- <Stack>
23
- <SizeSection />
24
- <PositionSection />
25
- <TypographySection />
26
- <BackgroundSection />
27
- <SpacingSection />
28
- <EffectsSection />
29
- </Stack>
30
- </StyleContext>
33
+ <ClassesPropProvider prop={ currentClassesProp }>
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>
63
+ </StyleProvider>
64
+ </ClassesPropProvider>
31
65
  );
32
66
  };
33
67
 
34
- function useClassesProp(): string {
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 ) {
79
+ const { element } = useElement();
80
+
81
+ const classesIds = useElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
82
+ const stylesDefs = useElementStyles( element.id );
83
+
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 );
90
+
91
+ return generateId( `e-${ element.id }-`, Object.keys( stylesDefs ) );
92
+ }
93
+
94
+ function useCurrentClassesProp(): string {
35
95
  const { elementType } = useElement();
36
96
 
37
97
  const prop = Object.entries( elementType.propsSchema ).find(
@@ -44,10 +104,3 @@ function useClassesProp(): string {
44
104
 
45
105
  return prop[ 0 ];
46
106
  }
47
-
48
- function useStyleDefinition(): StyleDefinition | null {
49
- const { element } = useElement();
50
- const elementStyles = useElementStyles( element.id );
51
-
52
- return Object.values( elementStyles || {} )[ 0 ] ?? null;
53
- }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+ import { createContext, type PropsWithChildren, useContext } from 'react';
3
+
4
+ type ContextValue = {
5
+ prop: string;
6
+ };
7
+
8
+ const Context = createContext< ContextValue | null >( null );
9
+
10
+ type Props = PropsWithChildren< ContextValue >;
11
+
12
+ export function ClassesPropProvider( { children, prop }: Props ) {
13
+ return <Context.Provider value={ { prop } }>{ children }</Context.Provider>;
14
+ }
15
+
16
+ export function useClassesProp() {
17
+ const context = useContext( Context );
18
+
19
+ if ( ! context ) {
20
+ throw new Error( 'useClassesProp must be used within a ClassesPropProvider' );
21
+ }
22
+
23
+ return context.prop;
24
+ }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { createContext, ReactNode, useContext } from 'react';
3
- import { Element, ElementType } from '../types';
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;
@@ -9,11 +9,7 @@ type ContextValue = {
9
9
 
10
10
  const Context = createContext< ContextValue | null >( null );
11
11
 
12
- type Props = {
13
- element: Element;
14
- children?: ReactNode;
15
- elementType: ElementType;
16
- };
12
+ type Props = PropsWithChildren< ContextValue >;
17
13
 
18
14
  export function ElementProvider( { children, element, elementType }: Props ) {
19
15
  return <Context.Provider value={ { element, elementType } }>{ children }</Context.Provider>;
@@ -1,39 +1,26 @@
1
1
  import * as React from 'react';
2
- import { createContext, ReactNode, useContext } from 'react';
3
- import { useActiveBreakpoint } from '@elementor/editor-responsive';
4
- import { StyleDefinition, StyleVariant } from '@elementor/editor-style';
2
+ import { createContext, type Dispatch, type PropsWithChildren, useContext } from 'react';
3
+ import { type StyleDefinition, type StyleVariant } from '@elementor/editor-styles';
5
4
 
6
5
  type ContextValue = {
7
- selectedStyleDef: StyleDefinition | null;
8
- selectedMeta: StyleVariant[ 'meta' ];
9
- selectedClassesProp: string;
6
+ id: StyleDefinition[ 'id' ];
7
+ setId: Dispatch< StyleDefinition[ 'id' ] >;
8
+ meta: StyleVariant[ 'meta' ];
10
9
  };
11
10
 
12
11
  const Context = createContext< ContextValue | null >( null );
13
12
 
14
- type Props = {
15
- children: ReactNode;
16
- selectedStyleDef: StyleDefinition | null;
17
- selectedClassesProp: string;
18
- };
19
-
20
- export function StyleContext( { children, selectedStyleDef, selectedClassesProp }: Props ) {
21
- const breakpoint = useActiveBreakpoint();
22
- // TODO: Handle state when we support it.
23
- const selectedMeta = { breakpoint, state: null } as const;
13
+ type Props = PropsWithChildren< ContextValue >;
24
14
 
25
- return (
26
- <Context.Provider value={ { selectedStyleDef, selectedMeta, selectedClassesProp } }>
27
- { children }
28
- </Context.Provider>
29
- );
15
+ export function StyleProvider( { children, id, setId, meta }: Props ) {
16
+ return <Context.Provider value={ { id, setId, meta } }>{ children }</Context.Provider>;
30
17
  }
31
18
 
32
- export function useStyleContext() {
19
+ export function useStyle() {
33
20
  const context = useContext( Context );
34
21
 
35
22
  if ( ! context ) {
36
- throw new Error( 'UseStyleContext must be used within a StyleContextProvider' );
23
+ throw new Error( 'useStyle must be used within a StyleProvider' );
37
24
  }
38
25
 
39
26
  return context;
@@ -1,3 +1,3 @@
1
- import { createControlReplacement } from './controls/create-control-replacement';
1
+ import { createControlReplacement } from '@elementor/editor-controls';
2
2
 
3
3
  export const { replaceControl, getControlReplacement } = createControlReplacement();
@@ -1,6 +1,7 @@
1
- import PopoverAction from './actions/popover-action';
2
1
  import { createMenu } from '@elementor/menus';
3
2
 
3
+ import PopoverAction from './popover-action';
4
+
4
5
  export const controlActionsMenu = createMenu( {
5
6
  components: {
6
7
  PopoverAction,
@@ -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,9 +1,11 @@
1
- import { ImageControl } from './control-types/image-control';
2
- import { TextControl } from './control-types/text-control';
3
- import { TextAreaControl } from './control-types/text-area-control';
4
- import { SizeControl } from './control-types/size-control';
5
- import { SelectControl } from './control-types/select-control';
6
- import { ControlComponent } from './create-control';
1
+ import {
2
+ type ControlComponent,
3
+ ImageControl,
4
+ SelectControl,
5
+ SizeControl,
6
+ TextAreaControl,
7
+ TextControl,
8
+ } from '@elementor/editor-controls';
7
9
 
8
10
  export type ControlLayout = 'full' | 'two-columns';
9
11
 
@@ -0,0 +1,36 @@
1
+ import * as React from 'react';
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
+
6
+ import { useElement } from '../contexts/element-context';
7
+
8
+ type Props = {
9
+ bind: PropKey;
10
+ children: React.ReactNode;
11
+ };
12
+
13
+ const SettingsField = ( { bind, children }: Props ) => {
14
+ const { element, elementType } = useElement();
15
+
16
+ const defaultValue = elementType.propsSchema[ bind ]?.default;
17
+ const settingsValue = useElementSetting( element.id, bind );
18
+ const value = settingsValue ?? defaultValue ?? null;
19
+
20
+ const setValue = ( newValue: PropValue ) => {
21
+ updateSettings( {
22
+ id: element.id,
23
+ props: {
24
+ [ bind ]: newValue,
25
+ },
26
+ } );
27
+ };
28
+
29
+ return (
30
+ <BoundPropProvider setValue={ setValue } value={ value } bind={ bind }>
31
+ { children }
32
+ </BoundPropProvider>
33
+ );
34
+ };
35
+
36
+ export { SettingsField };
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ import { BoundPropProvider } from '@elementor/editor-controls';
3
+ import { type PropKey } from '@elementor/editor-props';
4
+
5
+ import { useStylesField } from '../hooks/use-styles-field';
6
+
7
+ export type StylesFieldProps = {
8
+ bind: PropKey;
9
+ children: React.ReactNode;
10
+ };
11
+
12
+ export const StylesField = ( { bind, children }: StylesFieldProps ) => {
13
+ const [ value, setValue ] = useStylesField( bind );
14
+
15
+ return (
16
+ <BoundPropProvider setValue={ setValue } value={ value } bind={ bind }>
17
+ { children }
18
+ </BoundPropProvider>
19
+ );
20
+ };
@@ -1,40 +1,40 @@
1
1
  import * as React from 'react';
2
2
  import { useId } from 'react';
3
- import { useControl } from '../../controls/control-context';
4
- import { DynamicPropValue, DynamicTag } from '../types';
5
- import { DynamicControl } from '../dynamic-control';
3
+ import { ControlLabel, useBoundProp } from '@elementor/editor-controls';
4
+ import type { Control, ControlsSection } from '@elementor/editor-elements';
6
5
  import { DatabaseIcon, SettingsIcon, XIcon } from '@elementor/icons';
7
- import type { Control, ControlsSection } from '../../controls/types';
8
- import { DynamicSelection } from './dynamic-selection';
9
- import { ControlType, getControlByType } from '../../controls/controls-registry';
10
- import { ControlLabel } from '../../components/control-label';
11
- import { Control as BaseControl } from '../../controls/control';
12
- import { useDynamicTag } from '../hooks/use-dynamic-tag';
13
6
  import {
14
7
  bindPopover,
15
8
  bindTrigger,
16
9
  Box,
10
+ Divider,
17
11
  IconButton,
18
12
  Paper,
19
13
  Popover,
20
14
  Stack,
15
+ Tab,
16
+ TabPanel,
17
+ Tabs,
21
18
  Typography,
22
19
  UnstableTag as Tag,
23
20
  usePopupState,
24
- Tabs,
25
- Divider,
26
21
  useTabs,
27
- Tab,
28
- TabPanel,
29
22
  } from '@elementor/ui';
30
23
  import { __ } from '@wordpress/i18n';
31
- import { usePropValueHistory } from '../hooks/use-prop-value-history';
24
+
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
+ import { useDynamicTag } from '../hooks/use-dynamic-tag';
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
- const { bind, value, setValue } = useControl< DynamicPropValue | null >();
37
- const [ propValueFromHistory ] = usePropValueHistory( bind );
36
+ const { bind, value, setValue } = useBoundProp< DynamicPropValue | null >();
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,6 +1,8 @@
1
1
  import * as React from 'react';
2
- import { useState, Fragment } from 'react';
3
- 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';
4
6
  import {
5
7
  Box,
6
8
  Divider,
@@ -14,13 +16,12 @@ import {
14
16
  Typography,
15
17
  } from '@elementor/ui';
16
18
  import { __ } from '@wordpress/i18n';
17
- import { useControl } from '../../controls/control-context';
19
+
20
+ import { usePropValueHistory } from '../../hooks/use-prop-value-history';
18
21
  import { usePropDynamicTags } from '../hooks/use-prop-dynamic-tags';
19
22
  import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
23
+ import { type DynamicPropValue } from '../types';
20
24
  import { isDynamicPropValue } from '../utils';
21
- import { usePropValueHistory } from '../hooks/use-prop-value-history';
22
- import { DynamicPropValue } from '../types';
23
- import { PropKey, PropValue } from '../../controls/props/types';
24
25
 
25
26
  type Option = {
26
27
  label: string;
@@ -38,8 +39,8 @@ export type DynamicSelectionProps = {
38
39
  export const DynamicSelection = ( { onSelect }: DynamicSelectionProps ) => {
39
40
  const [ searchValue, setSearchValue ] = useState( '' );
40
41
  const { groups: dynamicGroups } = getAtomicDynamicTags() || {};
41
- const { bind, value: currentValue, setValue } = useControl< DynamicPropValue | PropValue >();
42
- const [ , updatePropValueHistory ] = usePropValueHistory( bind );
42
+ const { bind, value: currentValue, setValue } = useBoundProp< DynamicPropValue | PropValue >();
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,15 +1,16 @@
1
1
  import * as React from 'react';
2
- import { ControlContext, useControl } from '../controls/control-context';
3
- import { PropKey, PropValue } from '../controls/props/types';
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 { type DynamicPropValue } from './types';
6
7
 
7
8
  export type DynamicControlProps = React.PropsWithChildren< {
8
9
  bind: PropKey;
9
10
  } >;
10
11
 
11
12
  export const DynamicControl = ( { bind, children }: DynamicControlProps ) => {
12
- const { value, setValue, bind: propName } = useControl< DynamicPropValue >();
13
+ const { value, setValue, bind: propName } = useBoundProp< DynamicPropValue >();
13
14
  const { name = '', settings } = value?.value ?? {};
14
15
 
15
16
  const dynamicTag = useDynamicTag( propName, name );
@@ -35,8 +36,8 @@ export const DynamicControl = ( { bind, children }: DynamicControlProps ) => {
35
36
  };
36
37
 
37
38
  return (
38
- <ControlContext.Provider value={ { setValue: setDynamicValue, value: dynamicValue, bind } }>
39
+ <BoundPropProvider setValue={ setDynamicValue } value={ dynamicValue } bind={ bind }>
39
40
  { children }
40
- </ControlContext.Provider>
41
+ </BoundPropProvider>
41
42
  );
42
43
  };
@@ -1,7 +1,8 @@
1
1
  import { useMemo } from 'react';
2
+ import { type PropKey } from '@elementor/editor-props';
3
+
4
+ import { type DynamicTag } from '../types';
2
5
  import { usePropDynamicTags } from './use-prop-dynamic-tags';
3
- import { PropKey } from '../../controls/props/types';
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,14 +1,15 @@
1
1
  import * as React from 'react';
2
- import { useElement } from '../../controls/providers/element-provider';
3
- import { supportsDynamic } from '../utils';
4
- import { DynamicSelection } from '../components/dynamic-selection';
2
+ import { useBoundProp } from '@elementor/editor-controls';
5
3
  import { DatabaseIcon } from '@elementor/icons';
6
4
  import { __ } from '@wordpress/i18n';
7
- import { useControl } from '../../controls/control-context';
8
- import { PopoverActionProps } from '../../controls/control-actions/actions/popover-action';
5
+
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
- const { bind } = useControl();
12
+ const { bind } = useBoundProp();
12
13
  const { elementType } = useElement();
13
14
 
14
15
  const propType = elementType.propsSchema[ bind ];
@@ -1,7 +1,8 @@
1
1
  import { useMemo } from 'react';
2
- import { useElement } from '../../controls/providers/element-provider';
2
+ import { type PropKey } from '@elementor/editor-props';
3
+
4
+ import { useElement } from '../../contexts/element-context';
3
5
  import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
4
- import { PropKey } from '../../controls/props/types';
5
6
  import { getDynamicPropType } from '../utils';
6
7
 
7
8
  export const usePropDynamicTags = ( propName: PropKey ) => {
@@ -1,8 +1,8 @@
1
+ import { replaceControl } from '../control-replacement';
2
+ import { controlActionsMenu } from '../controls-actions';
1
3
  import { DynamicSelectionControl } from './components/dynamic-selection-control';
2
- import { isDynamicPropValue } from './utils';
3
4
  import { usePropDynamicAction } from './hooks/use-prop-dynamic-action';
4
- import { controlActionsMenu } from '../controls/control-actions/control-actions-menu';
5
- import { replaceControl } from '../control-replacement';
5
+ import { isDynamicPropValue } from './utils';
6
6
 
7
7
  const { registerPopoverAction } = controlActionsMenu;
8
8
 
@@ -1,4 +1,4 @@
1
- import { ExtendedWindow } from '../types';
1
+ import { type ExtendedWindow } from '../types';
2
2
 
3
3
  export const getElementorConfig = () => {
4
4
  const extendedWindow = window as unknown as ExtendedWindow;
@@ -1,5 +1,5 @@
1
- import { ControlItem, PropsSchema } from '../controls/types';
2
- import { TransformablePropType, TransformablePropValue } from '../controls/props/types';
1
+ import { type ControlItem, type PropsSchema } from '@elementor/editor-elements';
2
+ import { type TransformablePropType, type TransformablePropValue } from '@elementor/editor-props';
3
3
 
4
4
  export type ExtendedWindow = Window & {
5
5
  elementor?: {
@@ -1,6 +1,6 @@
1
- import { PropType, PropValue, TransformablePropType } from '../controls/props/types';
2
- import { DynamicPropType, DynamicPropValue } from './types';
3
- import { isTransformable } from '../controls/props/is-transformable';
1
+ import { isTransformable, type PropType, type PropValue, type TransformablePropType } from '@elementor/editor-props';
2
+
3
+ import { type DynamicPropType, type DynamicPropValue } from './types';
4
4
 
5
5
  const DYNAMIC_PROP_TYPE_KEY = 'dynamic';
6
6
 
@@ -0,0 +1,23 @@
1
+ import { useEffect } from 'react';
2
+ import { getSelectedElements, isElementInContainer, type V1Element } from '@elementor/editor-elements';
3
+ import { __privateListenTo as listenTo, type CommandEvent, commandStartEvent } from '@elementor/editor-v1-adapters';
4
+
5
+ import { usePanelActions } from '../panel';
6
+ import { isAtomicWidgetSelected } from '../sync/is-atomic-widget-selected';
7
+
8
+ export const useCloseEditorPanel = () => {
9
+ const { close } = usePanelActions();
10
+
11
+ return useEffect( () => {
12
+ return listenTo( commandStartEvent( 'document/elements/delete' ), ( e ) => {
13
+ const selectedElement = getSelectedElements()[ 0 ];
14
+ const { container: deletedContainer } = ( e as CommandEvent< { container: V1Element } > )?.args;
15
+ const isSelectedElementInDeletedContainer =
16
+ deletedContainer && selectedElement && isElementInContainer( selectedElement, deletedContainer );
17
+
18
+ if ( isSelectedElementInDeletedContainer && isAtomicWidgetSelected() ) {
19
+ close();
20
+ }
21
+ } );
22
+ }, [] ); // eslint-disable-line react-hooks/exhaustive-deps
23
+ };
@@ -0,0 +1,13 @@
1
+ import { useTheme } from '@elementor/ui';
2
+
3
+ import { type ExtendedWindow } from '../sync/types';
4
+
5
+ export function useDirection() {
6
+ const theme = useTheme(),
7
+ extendedWindow: ExtendedWindow = window;
8
+
9
+ const isUiRtl = 'rtl' === theme.direction,
10
+ isSiteRtl = !! extendedWindow.elementorFrontend?.config?.is_rtl;
11
+
12
+ return { isSiteRtl, isUiRtl };
13
+ }
@@ -1,14 +1,15 @@
1
1
  import { useEffect } from 'react';
2
- import { commandStartEvent, __privateListenTo as listenTo } from '@elementor/editor-v1-adapters';
2
+ import { __privateListenTo as listenTo, commandStartEvent } from '@elementor/editor-v1-adapters';
3
+
3
4
  import { usePanelActions } from '../panel';
4
- import { shouldUseV2Panel } from '../sync/should-use-v2-panel';
5
+ import { isAtomicWidgetSelected } from '../sync/is-atomic-widget-selected';
5
6
 
6
7
  export const useOpenEditorPanel = () => {
7
8
  const { open } = usePanelActions();
8
9
 
9
10
  useEffect( () => {
10
11
  return listenTo( commandStartEvent( 'panel/editor/open' ), () => {
11
- if ( shouldUseV2Panel() ) {
12
+ if ( isAtomicWidgetSelected() ) {
12
13
  open();
13
14
  }
14
15
  } );