@elementor/editor-editing-panel 1.50.0 → 3.32.0-21

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 (55) hide show
  1. package/CHANGELOG.md +0 -27
  2. package/dist/index.d.mts +78 -47
  3. package/dist/index.d.ts +78 -47
  4. package/dist/index.js +1723 -1384
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1510 -1143
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +22 -22
  9. package/src/components/css-classes/css-class-convert-local.tsx +77 -0
  10. package/src/components/css-classes/css-class-item.tsx +15 -1
  11. package/src/components/css-classes/css-class-menu.tsx +8 -1
  12. package/src/components/css-classes/local-class-sub-menu.tsx +23 -0
  13. package/src/components/css-classes/use-apply-and-unapply-class.ts +7 -50
  14. package/src/components/css-classes/use-can-convert-local-class-to-global.ts +22 -0
  15. package/src/components/custom-css.tsx +21 -0
  16. package/src/components/editing-panel-tabs.tsx +1 -5
  17. package/src/components/section.tsx +1 -5
  18. package/src/components/settings-tab.tsx +6 -15
  19. package/src/components/style-sections/effects-section/effects-section.tsx +30 -22
  20. package/src/components/style-sections/layout-section/display-field.tsx +11 -20
  21. package/src/components/style-sections/layout-section/flex-size-field.tsx +86 -52
  22. package/src/components/style-sections/position-section/offset-field.tsx +2 -2
  23. package/src/components/style-sections/position-section/position-section.tsx +2 -8
  24. package/src/components/style-sections/size-section/size-section.tsx +16 -31
  25. package/src/components/style-sections/typography-section/typography-section.tsx +2 -19
  26. package/src/components/style-tab-collapsible-content.tsx +1 -5
  27. package/src/components/style-tab-section.tsx +1 -5
  28. package/src/components/style-tab.tsx +15 -2
  29. package/src/controls-actions.ts +1 -1
  30. package/src/controls-registry/conditional-field.tsx +26 -0
  31. package/src/controls-registry/control.tsx +2 -2
  32. package/src/controls-registry/controls-registry.tsx +44 -3
  33. package/src/controls-registry/settings-field.tsx +33 -45
  34. package/src/controls-registry/styles-field.tsx +14 -14
  35. package/src/dynamics/components/dynamic-selection-control.tsx +2 -2
  36. package/src/errors.ts +10 -0
  37. package/src/hooks/use-custom-css.ts +184 -0
  38. package/src/hooks/use-state-by-element.ts +1 -4
  39. package/src/hooks/use-styles-fields.ts +129 -106
  40. package/src/index.ts +9 -10
  41. package/src/init.ts +2 -5
  42. package/src/popover-action.tsx +36 -15
  43. package/src/reset-style-props.tsx +2 -6
  44. package/src/styles-inheritance/components/infotip/value-component.tsx +1 -0
  45. package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +6 -23
  46. package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +17 -8
  47. package/src/styles-inheritance/consts.ts +0 -4
  48. package/src/styles-inheritance/init.ts +1 -4
  49. package/src/styles-inheritance/transformers/background-color-overlay-transformer.tsx +5 -1
  50. package/src/styles-inheritance/transformers/background-gradient-overlay-transformer.tsx +3 -3
  51. package/src/styles-inheritance/transformers/background-image-overlay-transformer.tsx +2 -1
  52. package/src/utils/prop-dependency-utils.ts +156 -0
  53. package/src/components/style-sections/size-section/object-position-field.tsx +0 -15
  54. package/src/sync/experiments-flags.ts +0 -5
  55. /package/src/components/style-sections/{layout-section → effects-section}/opacity-control-field.tsx +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-editing-panel",
3
- "version": "1.50.0",
3
+ "version": "3.32.0-21",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -18,11 +18,11 @@
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git+https://github.com/elementor/elementor-packages.git",
21
+ "url": "git+https://github.com/elementor/elementor.git",
22
22
  "directory": "packages/core/editor-editing-panel"
23
23
  },
24
24
  "bugs": {
25
- "url": "https://github.com/elementor/elementor-packages/issues"
25
+ "url": "https://github.com/elementor/elementor/issues"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "public"
@@ -39,26 +39,26 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "0.21.1",
43
- "@elementor/editor-canvas": "0.28.0",
44
- "@elementor/editor-controls": "1.5.0",
45
- "@elementor/editor-documents": "0.13.10",
46
- "@elementor/editor-elements": "0.9.2",
47
- "@elementor/editor-panels": "0.17.1",
48
- "@elementor/editor-props": "0.18.0",
49
- "@elementor/editor-responsive": "0.13.6",
50
- "@elementor/editor-styles": "0.6.14",
51
- "@elementor/editor-styles-repository": "0.10.7",
52
- "@elementor/editor-ui": "0.14.2",
53
- "@elementor/editor-v1-adapters": "0.12.1",
42
+ "@elementor/editor": "3.32.0-21",
43
+ "@elementor/editor-canvas": "3.32.0-21",
44
+ "@elementor/editor-controls": "3.32.0-21",
45
+ "@elementor/editor-documents": "3.32.0-21",
46
+ "@elementor/editor-elements": "3.32.0-21",
47
+ "@elementor/editor-panels": "3.32.0-21",
48
+ "@elementor/editor-props": "3.32.0-21",
49
+ "@elementor/editor-responsive": "3.32.0-21",
50
+ "@elementor/editor-styles": "3.32.0-21",
51
+ "@elementor/editor-styles-repository": "3.32.0-21",
52
+ "@elementor/editor-ui": "3.32.0-21",
53
+ "@elementor/editor-v1-adapters": "3.32.0-21",
54
54
  "@elementor/icons": "1.46.0",
55
- "@elementor/locations": "0.8.0",
56
- "@elementor/menus": "0.1.5",
57
- "@elementor/schema": "0.1.2",
58
- "@elementor/session": "0.1.0",
59
- "@elementor/ui": "1.36.0",
60
- "@elementor/utils": "0.5.0",
61
- "@elementor/wp-media": "0.6.1",
55
+ "@elementor/locations": "3.32.0-21",
56
+ "@elementor/menus": "3.32.0-21",
57
+ "@elementor/schema": "3.32.0-21",
58
+ "@elementor/session": "3.32.0-21",
59
+ "@elementor/ui": "1.36.2",
60
+ "@elementor/utils": "3.32.0-21",
61
+ "@elementor/wp-media": "3.32.0-21",
62
62
  "@wordpress/i18n": "^5.13.0"
63
63
  },
64
64
  "peerDependencies": {
@@ -0,0 +1,77 @@
1
+ import * as React from 'react';
2
+ import { deleteElementStyle, getElementSetting, updateElementSettings } from '@elementor/editor-elements';
3
+ import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
4
+ import { type StyleDefinition } from '@elementor/editor-styles';
5
+ import { createLocation } from '@elementor/locations';
6
+ import { useSessionStorage } from '@elementor/session';
7
+
8
+ import { useClassesProp } from '../../contexts/classes-prop-context';
9
+ import { useElement } from '../../contexts/element-context';
10
+ import { useStyle } from '../../contexts/style-context';
11
+
12
+ export const { Slot: CssClassConvertSlot, inject: injectIntoCssClassConvert } = createLocation< {
13
+ styleDef: StyleDefinition | null;
14
+ successCallback: ( newId: string ) => void;
15
+ canConvert: boolean;
16
+ } >();
17
+
18
+ type OwnProps = {
19
+ styleDef: StyleDefinition | null;
20
+ closeMenu: () => void;
21
+ canConvert: boolean;
22
+ };
23
+
24
+ /**
25
+ * Convert a local class to a global class injection point
26
+ * @param props
27
+ */
28
+ export const CssClassConvert = ( props: OwnProps ) => {
29
+ const { element } = useElement();
30
+ const elementId = element.id;
31
+ const currentClassesProp = useClassesProp();
32
+ const { setId: setActiveId } = useStyle();
33
+ const [ , saveValue ] = useSessionStorage( `last-converted-class-generated-name` );
34
+
35
+ const successCallback = ( newId: string ) => {
36
+ if ( ! props.styleDef ) {
37
+ throw new Error( 'Style definition is required for converting local class to global class.' );
38
+ }
39
+
40
+ onConvert( {
41
+ newId,
42
+ elementId,
43
+ classesProp: currentClassesProp,
44
+ styleDef: props.styleDef,
45
+ } );
46
+
47
+ saveValue( newId );
48
+ setActiveId( newId );
49
+ props.closeMenu();
50
+ };
51
+
52
+ return (
53
+ <CssClassConvertSlot
54
+ canConvert={ !! props.canConvert }
55
+ styleDef={ props.styleDef }
56
+ successCallback={ successCallback }
57
+ />
58
+ );
59
+ };
60
+
61
+ type OnConvertOptions = {
62
+ newId: string;
63
+ elementId: string;
64
+ classesProp: string;
65
+ styleDef: StyleDefinition;
66
+ };
67
+
68
+ const onConvert = ( opts: OnConvertOptions ) => {
69
+ const { newId, elementId, classesProp } = opts;
70
+ deleteElementStyle( elementId, opts.styleDef.id );
71
+ const currentUsedClasses = getElementSetting< ClassesPropValue >( elementId, classesProp ) || { value: [] };
72
+ updateElementSettings( {
73
+ id: elementId,
74
+ props: { [ classesProp ]: classesPropTypeUtil.create( [ newId, ...currentUsedClasses.value ] ) },
75
+ withHistory: false,
76
+ } );
77
+ };
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
- import { type ReactElement, useState } from 'react';
2
+ import { type ReactElement, useEffect, useState } from 'react';
3
3
  import { stylesRepository, useUserStylesCapability, validateStyleLabel } from '@elementor/editor-styles-repository';
4
4
  import { EditableField, EllipsisWithTooltip, useEditable } from '@elementor/editor-ui';
5
5
  import { DotsVerticalIcon } from '@elementor/icons';
6
+ import { useSessionStorage } from '@elementor/session';
6
7
  import {
7
8
  type AutocompleteRenderGetTagProps,
8
9
  bindTrigger,
@@ -49,6 +50,10 @@ export function CssClassItem( props: CssClassItemProps ) {
49
50
 
50
51
  const { userCan } = useUserStylesCapability();
51
52
 
53
+ const [ convertedFromLocalId, , clearConvertedFromLocalId ] = useSessionStorage(
54
+ `last-converted-class-generated-name`
55
+ );
56
+
52
57
  const {
53
58
  ref,
54
59
  isEditing,
@@ -69,6 +74,15 @@ export function CssClassItem( props: CssClassItemProps ) {
69
74
 
70
75
  const isShowingState = isActive && meta.state;
71
76
 
77
+ useEffect( () => {
78
+ if ( convertedFromLocalId && id === convertedFromLocalId ) {
79
+ clearConvertedFromLocalId();
80
+ openEditMode();
81
+ }
82
+ // eslint-disable-next-line react-compiler/react-compiler
83
+ // eslint-disable-next-line react-hooks/exhaustive-deps
84
+ }, [ id ] );
85
+
72
86
  return (
73
87
  <ThemeProvider palette="default">
74
88
  <UnstableChipGroup
@@ -1,6 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { type StyleDefinitionState } from '@elementor/editor-styles';
3
- import { stylesRepository, useUserStylesCapability } from '@elementor/editor-styles-repository';
3
+ import {
4
+ isElementsStylesProvider,
5
+ stylesRepository,
6
+ useUserStylesCapability,
7
+ } from '@elementor/editor-styles-repository';
4
8
  import { MenuItemInfotip, MenuListItem } from '@elementor/editor-ui';
5
9
  import { bindMenu, Divider, Menu, MenuSubheader, type PopupState, Stack } from '@elementor/ui';
6
10
  import { __ } from '@wordpress/i18n';
@@ -10,6 +14,7 @@ import { type StyleDefinitionStateWithNormal } from '../../styles-inheritance/ty
10
14
  import { getTempStylesProviderThemeColor } from '../../utils/get-styles-provider-color';
11
15
  import { StyleIndicator } from '../style-indicator';
12
16
  import { useCssClass } from './css-class-context';
17
+ import { LocalClassSubMenu } from './local-class-sub-menu';
13
18
  import { useUnapplyClass } from './use-apply-and-unapply-class';
14
19
 
15
20
  type State = {
@@ -32,6 +37,7 @@ type CssClassMenuProps = {
32
37
 
33
38
  export function CssClassMenu( { popupState, anchorEl, fixed }: CssClassMenuProps ) {
34
39
  const { provider } = useCssClass();
40
+ const isLocalStyle = provider ? isElementsStylesProvider( provider ) : true;
35
41
 
36
42
  const handleKeyDown = ( e: React.KeyboardEvent< HTMLElement > ) => {
37
43
  e.stopPropagation();
@@ -54,6 +60,7 @@ export function CssClassMenu( { popupState, anchorEl, fixed }: CssClassMenuProps
54
60
  // Workaround for focus-visible issue.
55
61
  disableAutoFocusItem
56
62
  >
63
+ { isLocalStyle && <LocalClassSubMenu popupState={ popupState } /> }
57
64
  { /* It has to be an array since MUI menu doesn't accept a Fragment as a child, and wrapping the items with an HTML element disrupts keyboard navigation */ }
58
65
  { getMenuItemsByProvider( { provider, closeMenu: popupState.close, fixed } ) }
59
66
  <MenuSubheader sx={ { typography: 'caption', color: 'text.secondary', pb: 0.5, pt: 1 } }>
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { MenuSubheader, type PopupState } from '@elementor/ui';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ import { CssClassConvert } from './css-class-convert-local';
6
+ import { useCanConvertLocalClassToGlobal } from './use-can-convert-local-class-to-global';
7
+
8
+ type OwnProps = {
9
+ popupState: PopupState;
10
+ };
11
+
12
+ export const LocalClassSubMenu = ( props: OwnProps ) => {
13
+ const { canConvert, styleDef } = useCanConvertLocalClassToGlobal();
14
+
15
+ return (
16
+ <>
17
+ <MenuSubheader sx={ { typography: 'caption', color: 'text.secondary', pb: 0.5, pt: 1 } }>
18
+ { __( 'Local Class', 'elementor' ) }
19
+ </MenuSubheader>
20
+ <CssClassConvert canConvert={ canConvert } styleDef={ styleDef } closeMenu={ props.popupState.close } />
21
+ </>
22
+ );
23
+ };
@@ -4,13 +4,12 @@ import { getElementLabel, getElementSetting, updateElementSettings } from '@elem
4
4
  import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
5
5
  import { type StyleDefinitionID } from '@elementor/editor-styles';
6
6
  import { useGetStylesRepositoryCreateAction } from '@elementor/editor-styles-repository';
7
- import { isExperimentActive, undoable } from '@elementor/editor-v1-adapters';
7
+ import { undoable } from '@elementor/editor-v1-adapters';
8
8
  import { __ } from '@wordpress/i18n';
9
9
 
10
10
  import { useClassesProp } from '../../contexts/classes-prop-context';
11
11
  import { useElement } from '../../contexts/element-context';
12
12
  import { useStyle } from '../../contexts/style-context';
13
- import { EXPERIMENTAL_FEATURES } from '../../sync/experiments-flags';
14
13
 
15
14
  type UndoableClassActionPayload = {
16
15
  classId: StyleDefinitionID;
@@ -30,12 +29,10 @@ export function useApplyClass() {
30
29
  const { id: activeId, setId: setActiveId } = useStyle();
31
30
  const { element } = useElement();
32
31
 
33
- const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
34
-
35
32
  const applyClass = useApply();
36
33
  const unapplyClass = useUnapply();
37
34
 
38
- const undoableApply = useMemo( () => {
35
+ return useMemo( () => {
39
36
  return undoable(
40
37
  {
41
38
  do: ( { classId }: UndoableClassActionPayload ) => {
@@ -59,27 +56,16 @@ export function useApplyClass() {
59
56
  }
60
57
  );
61
58
  }, [ activeId, applyClass, element.id, unapplyClass, setActiveId ] );
62
-
63
- const applyWithoutHistory = useCallback(
64
- ( { classId }: UndoableClassActionPayload ) => {
65
- applyClass( classId );
66
- },
67
- [ applyClass ]
68
- );
69
-
70
- return isVersion330Active ? undoableApply : applyWithoutHistory;
71
59
  }
72
60
 
73
61
  export function useUnapplyClass() {
74
62
  const { id: activeId, setId: setActiveId } = useStyle();
75
63
  const { element } = useElement();
76
64
 
77
- const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
78
-
79
65
  const applyClass = useApply();
80
66
  const unapplyClass = useUnapply();
81
67
 
82
- const undoableUnapply = useMemo( () => {
68
+ return useMemo( () => {
83
69
  return undoable(
84
70
  {
85
71
  do: ( { classId }: UndoableClassActionPayload ) => {
@@ -103,22 +89,11 @@ export function useUnapplyClass() {
103
89
  }
104
90
  );
105
91
  }, [ activeId, applyClass, element.id, unapplyClass, setActiveId ] );
106
-
107
- const unapplyWithoutHistory = useCallback(
108
- ( { classId }: UndoableClassActionPayload ) => {
109
- unapplyClass( classId );
110
- },
111
- [ unapplyClass ]
112
- );
113
-
114
- return isVersion330Active ? undoableUnapply : unapplyWithoutHistory;
115
92
  }
116
93
 
117
94
  export function useCreateAndApplyClass() {
118
95
  const { id: activeId, setId: setActiveId } = useStyle();
119
96
 
120
- const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
121
-
122
97
  const [ provider, createAction ] = useGetStylesRepositoryCreateAction() ?? [ null, null ];
123
98
  const deleteAction = provider?.actions.delete;
124
99
 
@@ -157,25 +132,11 @@ export function useCreateAndApplyClass() {
157
132
  );
158
133
  }, [ activeId, applyClass, createAction, deleteAction, provider, setActiveId, unapplyClass ] );
159
134
 
160
- const createAndApplyWithoutHistory = useCallback(
161
- ( { classLabel }: CreateAndApplyClassPayload ) => {
162
- if ( ! createAction ) {
163
- return;
164
- }
165
-
166
- const createdId = createAction( classLabel );
167
- applyClass( createdId );
168
- },
169
- [ applyClass, createAction ]
170
- );
171
-
172
135
  if ( ! provider || ! undoableCreateAndApply ) {
173
136
  return [ null, null ];
174
137
  }
175
138
 
176
- return isVersion330Active
177
- ? ( [ provider, undoableCreateAndApply ] as const )
178
- : ( [ provider, createAndApplyWithoutHistory ] as const );
139
+ return [ provider, undoableCreateAndApply ] as const;
179
140
  }
180
141
 
181
142
  function useApply() {
@@ -231,24 +192,20 @@ function useClasses() {
231
192
  const { element } = useElement();
232
193
  const currentClassesProp = useClassesProp();
233
194
 
234
- const isVersion330Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
235
-
236
195
  return useMemo( () => {
237
196
  const setClasses = ( ids: StyleDefinitionID[] ) => {
238
197
  updateElementSettings( {
239
198
  id: element.id,
240
199
  props: { [ currentClassesProp ]: classesPropTypeUtil.create( ids ) },
241
- withHistory: isVersion330Active ? false : true,
200
+ withHistory: false,
242
201
  } );
243
202
 
244
- if ( isVersion330Active ) {
245
- setDocumentModifiedStatus( true );
246
- }
203
+ setDocumentModifiedStatus( true );
247
204
  };
248
205
 
249
206
  const getAppliedClasses = () =>
250
207
  getElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
251
208
 
252
209
  return { setClasses, getAppliedClasses };
253
- }, [ currentClassesProp, element.id, isVersion330Active ] );
210
+ }, [ currentClassesProp, element.id ] );
254
211
  }
@@ -0,0 +1,22 @@
1
+ import { isElementsStylesProvider } from '@elementor/editor-styles-repository';
2
+
3
+ import { useElement } from '../../contexts/element-context';
4
+ import { useStyle } from '../../contexts/style-context';
5
+
6
+ export const useCanConvertLocalClassToGlobal = () => {
7
+ const { element } = useElement();
8
+ const { provider, id, meta } = useStyle();
9
+ const styleDef = provider?.actions.get( id, { elementId: element.id, ...meta } );
10
+
11
+ const isLocalStylesProvider = provider && isElementsStylesProvider( provider?.getKey() );
12
+ const variants = styleDef?.variants || [];
13
+
14
+ const canConvert = !! ( isLocalStylesProvider && variants.length );
15
+
16
+ return {
17
+ canConvert,
18
+ isLocalStylesProvider,
19
+ id,
20
+ styleDef: styleDef || null,
21
+ };
22
+ };
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import { TextField } from '@elementor/ui';
3
+
4
+ import { useCustomCss } from '../hooks/use-custom-css';
5
+ import { SectionContent } from './section-content';
6
+
7
+ export const CustomCss = () => {
8
+ const { customCss, setCustomCss } = useCustomCss();
9
+
10
+ return (
11
+ <SectionContent>
12
+ <TextField
13
+ value={ customCss?.raw || '' }
14
+ onChange={ ( ev: React.ChangeEvent< HTMLInputElement > ) =>
15
+ setCustomCss( ev.target.value, { history: { propDisplayName: 'Custom CSS' } } )
16
+ }
17
+ multiline
18
+ />
19
+ </SectionContent>
20
+ );
21
+ };
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react';
2
2
  import { Fragment } from 'react';
3
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
3
  import { Divider, Stack, Tab, TabPanel, Tabs, useTabs } from '@elementor/ui';
5
4
  import { __ } from '@wordpress/i18n';
6
5
 
@@ -8,7 +7,6 @@ import { useElement } from '../contexts/element-context';
8
7
  import { ScrollProvider } from '../contexts/scroll-context';
9
8
  import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
10
9
  import { useStateByElement } from '../hooks/use-state-by-element';
11
- import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
12
10
  import { SettingsTab } from './settings-tab';
13
11
  import { stickyHeaderStyles, StyleTab } from './style-tab';
14
12
 
@@ -27,9 +25,7 @@ export const EditingPanelTabs = () => {
27
25
 
28
26
  const PanelTabContent = () => {
29
27
  const editorDefaults = useDefaultPanelSettings();
30
- const defaultComponentTab = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 )
31
- ? ( editorDefaults.defaultTab as TabValue )
32
- : 'settings';
28
+ const defaultComponentTab = editorDefaults.defaultTab as TabValue;
33
29
 
34
30
  const [ currentTab, setCurrentTab ] = useStateByElement< TabValue >( 'tab', defaultComponentTab );
35
31
  const { getTabProps, getTabPanelProps, getTabsProps } = useTabs< TabValue >( currentTab );
@@ -1,11 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { type PropsWithChildren, type ReactNode, useId, useRef } from 'react';
3
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
3
  import { Collapse, Divider, ListItemButton, ListItemText, Stack } from '@elementor/ui';
5
4
 
6
5
  import { SectionRefContext } from '../contexts/section-context';
7
6
  import { useStateByElement } from '../hooks/use-state-by-element';
8
- import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
9
7
  import { CollapseIcon } from './collapse-icon';
10
8
  import { type CollapsibleValue, getCollapsibleValue } from './collapsible-content';
11
9
 
@@ -27,8 +25,6 @@ export function Section( { title, children, defaultExpanded = false, titleEnd }:
27
25
  const labelId = `label-${ id }`;
28
26
  const contentId = `content-${ id }`;
29
27
 
30
- const isUsingTitleEnd = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 );
31
-
32
28
  return (
33
29
  <>
34
30
  <ListItemButton
@@ -43,7 +39,7 @@ export function Section( { title, children, defaultExpanded = false, titleEnd }:
43
39
  secondaryTypographyProps={ { color: 'text.primary', variant: 'caption', fontWeight: 'bold' } }
44
40
  sx={ { flexGrow: 0, flexShrink: 1, marginInlineEnd: 1 } }
45
41
  />
46
- { isUsingTitleEnd ? getCollapsibleValue( titleEnd, isOpen ) : null }
42
+ { getCollapsibleValue( titleEnd, isOpen ) }
47
43
  </Stack>
48
44
  <CollapseIcon open={ isOpen } color="secondary" fontSize="tiny" />
49
45
  </ListItemButton>
@@ -1,22 +1,15 @@
1
1
  import * as React from 'react';
2
2
  import { ControlFormLabel } from '@elementor/editor-controls';
3
3
  import { type Control } from '@elementor/editor-elements';
4
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
5
4
  import { SessionStorageProvider } from '@elementor/session';
6
5
  import { Divider } from '@elementor/ui';
7
6
 
8
7
  import { useElement } from '../contexts/element-context';
9
8
  import { Control as BaseControl } from '../controls-registry/control';
10
9
  import { ControlTypeContainer } from '../controls-registry/control-type-container';
11
- import {
12
- type ControlType,
13
- getControl,
14
- getDefaultLayout,
15
- getPropTypeUtil,
16
- } from '../controls-registry/controls-registry';
10
+ import { controlsRegistry, type ControlType } from '../controls-registry/controls-registry';
17
11
  import { SettingsField } from '../controls-registry/settings-field';
18
12
  import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
19
- import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
20
13
  import { Section } from './section';
21
14
  import { SectionsList } from './sections-list';
22
15
 
@@ -25,9 +18,7 @@ export const SettingsTab = () => {
25
18
  const settingsDefault = useDefaultPanelSettings();
26
19
 
27
20
  const isDefaultExpanded = ( sectionId: string ) =>
28
- isExperimentActive( EXPERIMENTAL_FEATURES.V_3_30 )
29
- ? settingsDefault.defaultSectionsExpanded.settings?.includes( sectionId )
30
- : true;
21
+ settingsDefault.defaultSectionsExpanded.settings?.includes( sectionId );
31
22
 
32
23
  return (
33
24
  <SessionStorageProvider prefix={ element.id }>
@@ -64,11 +55,11 @@ export const SettingsTab = () => {
64
55
  };
65
56
 
66
57
  const Control = ( { control }: { control: Control[ 'value' ] } ) => {
67
- if ( ! getControl( control.type as ControlType ) ) {
58
+ if ( ! controlsRegistry.get( control.type as ControlType ) ) {
68
59
  return null;
69
60
  }
70
61
 
71
- const layout = control.meta?.layout || getDefaultLayout( control.type as ControlType );
62
+ const layout = control.meta?.layout || controlsRegistry.getLayout( control.type as ControlType );
72
63
  const controlProps = populateChildControlProps( control.props );
73
64
  if ( layout === 'custom' ) {
74
65
  controlProps.label = control.label;
@@ -87,8 +78,8 @@ const Control = ( { control }: { control: Control[ 'value' ] } ) => {
87
78
 
88
79
  function populateChildControlProps( props: Record< string, unknown > ) {
89
80
  if ( props.childControlType ) {
90
- const childComponent = getControl( props.childControlType as ControlType );
91
- const childPropType = getPropTypeUtil( props.childControlType as ControlType );
81
+ const childComponent = controlsRegistry.get( props.childControlType as ControlType );
82
+ const childPropType = controlsRegistry.getPropTypeUtil( props.childControlType as ControlType );
92
83
  props = {
93
84
  ...props,
94
85
  childControlConfig: {
@@ -1,49 +1,57 @@
1
1
  import * as React from 'react';
2
- import { BoxShadowRepeaterControl, FilterRepeaterControl, TransformRepeaterControl } from '@elementor/editor-controls';
3
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
2
+ import {
3
+ BoxShadowRepeaterControl,
4
+ FilterRepeaterControl,
5
+ TransformRepeaterControl,
6
+ TransitionRepeaterControl,
7
+ UnstableTransformRepeaterControl,
8
+ } from '@elementor/editor-controls';
9
+ import { EXPERIMENTAL_FEATURES, isExperimentActive } from '@elementor/editor-v1-adapters';
4
10
  import { __ } from '@wordpress/i18n';
5
11
 
6
12
  import { StylesField } from '../../../controls-registry/styles-field';
7
- import { EXPERIMENTAL_FEATURES } from '../../../sync/experiments-flags';
8
13
  import { PanelDivider } from '../../panel-divider';
9
14
  import { SectionContent } from '../../section-content';
10
- import { OpacityControlField } from '../layout-section/opacity-control-field';
15
+ import { OpacityControlField } from './opacity-control-field';
11
16
 
12
17
  const BOX_SHADOW_LABEL = __( 'Box shadow', 'elementor' );
13
18
  const FILTER_LABEL = __( 'Filters', 'elementor' );
14
19
  const TRANSFORM_LABEL = __( 'Transform', 'elementor' );
15
20
  const BACKDROP_FILTER_LABEL = __( 'Backdrop filters', 'elementor' );
21
+ const TRANSITIONS_LABEL = __( 'Transitions', 'elementor' );
16
22
 
17
23
  export const EffectsSection = () => {
18
- const isVersion331Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_31 );
24
+ const shouldShowTransition = isExperimentActive( EXPERIMENTAL_FEATURES.TRANSITIONS );
25
+
26
+ const isUnstableRepeaterActive = isExperimentActive( EXPERIMENTAL_FEATURES.UNSTABLE_REPEATER );
19
27
 
20
28
  return (
21
29
  <SectionContent>
22
- { isVersion331Active && (
23
- <>
24
- <OpacityControlField />
25
- <PanelDivider />
26
- </>
27
- ) }
30
+ <OpacityControlField />
31
+ <PanelDivider />
28
32
  <StylesField bind="box-shadow" propDisplayName={ BOX_SHADOW_LABEL }>
29
33
  <BoxShadowRepeaterControl />
30
34
  </StylesField>
31
- { isVersion331Active && (
35
+ <PanelDivider />
36
+ <StylesField bind="transform" propDisplayName={ TRANSFORM_LABEL }>
37
+ { isUnstableRepeaterActive ? <UnstableTransformRepeaterControl /> : <TransformRepeaterControl /> }
38
+ </StylesField>
39
+ { shouldShowTransition && (
32
40
  <>
33
41
  <PanelDivider />
34
- <StylesField bind="transform" propDisplayName={ TRANSFORM_LABEL }>
35
- <TransformRepeaterControl />
36
- </StylesField>
37
- <PanelDivider />
38
- <StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
39
- <FilterRepeaterControl />
40
- </StylesField>
41
- <PanelDivider />
42
- <StylesField bind="backdrop-filter" propDisplayName={ BACKDROP_FILTER_LABEL }>
43
- <FilterRepeaterControl filterPropName="backdrop-filter" />
42
+ <StylesField bind="transition" propDisplayName={ TRANSITIONS_LABEL }>
43
+ <TransitionRepeaterControl />
44
44
  </StylesField>
45
45
  </>
46
46
  ) }
47
+ <PanelDivider />
48
+ <StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
49
+ <FilterRepeaterControl />
50
+ </StylesField>
51
+ <PanelDivider />
52
+ <StylesField bind="backdrop-filter" propDisplayName={ BACKDROP_FILTER_LABEL }>
53
+ <FilterRepeaterControl filterPropName="backdrop-filter" />
54
+ </StylesField>
47
55
  </SectionContent>
48
56
  );
49
57
  };