@elementor/editor-editing-panel 4.0.0-607 → 4.0.0-619

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-editing-panel",
3
- "version": "4.0.0-607",
3
+ "version": "4.0.0-619",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,28 +39,28 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "4.0.0-607",
43
- "@elementor/editor-canvas": "4.0.0-607",
44
- "@elementor/editor-controls": "4.0.0-607",
45
- "@elementor/editor-documents": "4.0.0-607",
46
- "@elementor/editor-elements": "4.0.0-607",
47
- "@elementor/editor-interactions": "4.0.0-607",
48
- "@elementor/editor-panels": "4.0.0-607",
49
- "@elementor/editor-props": "4.0.0-607",
50
- "@elementor/editor-responsive": "4.0.0-607",
51
- "@elementor/editor-styles": "4.0.0-607",
52
- "@elementor/editor-styles-repository": "4.0.0-607",
53
- "@elementor/editor-ui": "4.0.0-607",
54
- "@elementor/editor-v1-adapters": "4.0.0-607",
42
+ "@elementor/editor": "4.0.0-619",
43
+ "@elementor/editor-canvas": "4.0.0-619",
44
+ "@elementor/editor-controls": "4.0.0-619",
45
+ "@elementor/editor-documents": "4.0.0-619",
46
+ "@elementor/editor-elements": "4.0.0-619",
47
+ "@elementor/editor-interactions": "4.0.0-619",
48
+ "@elementor/editor-panels": "4.0.0-619",
49
+ "@elementor/editor-props": "4.0.0-619",
50
+ "@elementor/editor-responsive": "4.0.0-619",
51
+ "@elementor/editor-styles": "4.0.0-619",
52
+ "@elementor/editor-styles-repository": "4.0.0-619",
53
+ "@elementor/editor-ui": "4.0.0-619",
54
+ "@elementor/editor-v1-adapters": "4.0.0-619",
55
55
  "@elementor/icons": "^1.68.0",
56
- "@elementor/editor-variables": "4.0.0-607",
57
- "@elementor/locations": "4.0.0-607",
58
- "@elementor/menus": "4.0.0-607",
59
- "@elementor/schema": "4.0.0-607",
60
- "@elementor/session": "4.0.0-607",
56
+ "@elementor/editor-variables": "4.0.0-619",
57
+ "@elementor/locations": "4.0.0-619",
58
+ "@elementor/menus": "4.0.0-619",
59
+ "@elementor/schema": "4.0.0-619",
60
+ "@elementor/session": "4.0.0-619",
61
61
  "@elementor/ui": "1.36.17",
62
- "@elementor/utils": "4.0.0-607",
63
- "@elementor/wp-media": "4.0.0-607",
62
+ "@elementor/utils": "4.0.0-619",
63
+ "@elementor/wp-media": "4.0.0-619",
64
64
  "@wordpress/i18n": "^5.13.0"
65
65
  },
66
66
  "peerDependencies": {
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react';
2
2
  import { type ReactElement, useRef, useState } from 'react';
3
- import { useElementSetting } from '@elementor/editor-elements';
4
3
  import { type ClassesPropValue } from '@elementor/editor-props';
5
4
  import {
6
5
  isElementsStylesProvider,
@@ -27,7 +26,7 @@ import {
27
26
  import { __ } from '@wordpress/i18n';
28
27
 
29
28
  import { useClassesProp } from '../../contexts/classes-prop-context';
30
- import { useElement } from '../../contexts/element-context';
29
+ import { useElement, usePanelElementSetting } from '../../contexts/element-context';
31
30
  import { useStyle } from '../../contexts/style-context';
32
31
  import { getStylesProviderColorName } from '../../utils/get-styles-provider-color';
33
32
  import { trackStyles } from '../../utils/tracking/subscribe';
@@ -287,10 +286,9 @@ function hasReachedLimit( provider: StylesProvider ) {
287
286
  }
288
287
 
289
288
  function useAppliedOptions( options: StyleDefOption[] ) {
290
- const { element } = useElement();
291
289
  const currentClassesProp = useClassesProp();
292
290
 
293
- const appliedIds = useElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
291
+ const appliedIds = usePanelElementSetting< ClassesPropValue >( currentClassesProp )?.value ?? [];
294
292
  const appliedOptions = options.filter( ( option ) => option.value && appliedIds.includes( option.value ) );
295
293
 
296
294
  const hasElementsProviderStyleApplied = appliedOptions.some(
@@ -4,7 +4,7 @@ import {
4
4
  ControlReplacementsProvider,
5
5
  getControlReplacements,
6
6
  } from '@elementor/editor-controls';
7
- import { useSelectedElement } from '@elementor/editor-elements';
7
+ import { useSelectedElementSettings } from '@elementor/editor-elements';
8
8
  import { Panel, PanelBody, PanelHeader, PanelHeaderTitle } from '@elementor/editor-panels';
9
9
  import { ThemeProvider } from '@elementor/editor-ui';
10
10
  import { AtomIcon } from '@elementor/icons';
@@ -24,7 +24,7 @@ export const { Slot: PanelHeaderTopSlot, inject: injectIntoPanelHeaderTop } = cr
24
24
  const { useMenuItems } = controlActionsMenu;
25
25
 
26
26
  export const EditingPanel = () => {
27
- const { element, elementType } = useSelectedElement();
27
+ const { element, elementType, settings } = useSelectedElementSettings();
28
28
  const controlReplacements = getControlReplacements();
29
29
  const menuItems = useMenuItems().default;
30
30
 
@@ -59,7 +59,7 @@ export const EditingPanel = () => {
59
59
  <ThemeProvider>
60
60
  <ControlActionsProvider items={ menuItems }>
61
61
  <ControlReplacementsProvider replacements={ controlReplacements }>
62
- <ElementProvider element={ element } elementType={ elementType }>
62
+ <ElementProvider element={ element } elementType={ elementType } settings={ settings }>
63
63
  <Panel>
64
64
  <PanelHeaderTopSlot />
65
65
  { panelContent }
@@ -47,7 +47,6 @@ const ControlLayout = ( {
47
47
  controlProps: Record< string, unknown >;
48
48
  } ) => {
49
49
  const controlType = control.type as ControlType;
50
-
51
50
  return (
52
51
  <ControlAdornmentsProvider items={ getFieldIndicators( 'settings' ) }>
53
52
  { control.meta?.topDivider && <Divider /> }
@@ -5,11 +5,12 @@ import {
5
5
  TransformRepeaterControl,
6
6
  TransitionRepeaterControl,
7
7
  } from '@elementor/editor-controls';
8
- import { useSelectedElement } from '@elementor/editor-elements';
9
8
  import { __ } from '@wordpress/i18n';
10
9
 
10
+ import { useElement } from '../../../contexts/element-context';
11
11
  import { useStyle } from '../../../contexts/style-context';
12
12
  import { StylesField } from '../../../controls-registry/styles-field';
13
+ import { canElementHaveChildren } from '../../../utils/can-element-have-children';
13
14
  import { getRecentlyUsedList } from '../../../utils/get-recently-used-styles';
14
15
  import { PanelDivider } from '../../panel-divider';
15
16
  import { SectionContent } from '../../section-content';
@@ -23,9 +24,11 @@ const BACKDROP_FILTER_LABEL = __( 'Backdrop filters', 'elementor' );
23
24
  const TRANSITIONS_LABEL = __( 'Transitions', 'elementor' );
24
25
 
25
26
  export const EffectsSection = () => {
26
- const { element } = useSelectedElement();
27
+ const { element } = useElement();
27
28
  const { meta } = useStyle();
28
29
 
30
+ const canHaveChildren = canElementHaveChildren( element?.id ?? '' );
31
+
29
32
  return (
30
33
  <SectionContent gap={ 1 }>
31
34
  <BlendModeField />
@@ -37,7 +40,7 @@ export const EffectsSection = () => {
37
40
  </StylesField>
38
41
  <PanelDivider />
39
42
  <StylesField bind="transform" propDisplayName={ TRANSFORM_LABEL }>
40
- <TransformRepeaterControl />
43
+ <TransformRepeaterControl showChildrenPerspective={ canHaveChildren } />
41
44
  </StylesField>
42
45
  <PanelDivider />
43
46
  <StylesField bind="transition" propDisplayName={ TRANSITIONS_LABEL }>
@@ -1,18 +1,20 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, type PropsWithChildren, useContext } from 'react';
3
3
  import { type Element, type ElementType } from '@elementor/editor-elements';
4
+ import { type AnyTransformable } from '@elementor/editor-props';
4
5
 
5
6
  type ContextValue = {
6
7
  element: Element;
7
8
  elementType: ElementType;
9
+ settings: Record< string, AnyTransformable | null >;
8
10
  };
9
11
 
10
12
  const Context = createContext< ContextValue | null >( null );
11
13
 
12
14
  type Props = PropsWithChildren< ContextValue >;
13
15
 
14
- export function ElementProvider( { children, element, elementType }: Props ) {
15
- return <Context.Provider value={ { element, elementType } }>{ children }</Context.Provider>;
16
+ export function ElementProvider( { children, element, elementType, settings }: Props ) {
17
+ return <Context.Provider value={ { element, elementType, settings } }>{ children }</Context.Provider>;
16
18
  }
17
19
 
18
20
  export function useElement() {
@@ -24,3 +26,13 @@ export function useElement() {
24
26
 
25
27
  return context;
26
28
  }
29
+
30
+ export function usePanelElementSetting< TValue = AnyTransformable | null >( propKey: string ) {
31
+ const context = useContext( Context );
32
+
33
+ if ( ! context ) {
34
+ throw new Error( 'usePanelElementSetting must be used within a ElementProvider' );
35
+ }
36
+
37
+ return ( context.settings[ propKey ] ?? null ) as TValue | null;
38
+ }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, type PropsWithChildren, useContext } from 'react';
3
- import { getWidgetsCache, useElementSetting } from '@elementor/editor-elements';
3
+ import { getWidgetsCache } from '@elementor/editor-elements';
4
4
  import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
5
5
  import { getBreakpointsTree } from '@elementor/editor-responsive';
6
6
  import { getStylesSchema } from '@elementor/editor-styles';
@@ -14,7 +14,7 @@ import {
14
14
  type StylesInheritanceSnapshot,
15
15
  } from '../styles-inheritance/types';
16
16
  import { useClassesProp } from './classes-prop-context';
17
- import { useElement } from './element-context';
17
+ import { useElement, usePanelElementSetting } from './element-context';
18
18
  import { useStyle } from './style-context';
19
19
 
20
20
  const Context = createContext< StylesInheritanceAPI | null >( null );
@@ -65,13 +65,12 @@ export function useStylesInheritanceChain( path: string[] ): SnapshotPropValue[]
65
65
  }
66
66
 
67
67
  const useAppliedStyles = () => {
68
- const { element } = useElement();
69
68
  const currentClassesProp = useClassesProp();
70
69
  const baseStyles = useBaseStyles();
71
70
 
72
71
  useStylesRerender();
73
72
 
74
- const classesProp = useElementSetting< ClassesPropValue >( element.id, currentClassesProp );
73
+ const classesProp = usePanelElementSetting< ClassesPropValue >( currentClassesProp );
75
74
 
76
75
  const appliedStyles = classesPropTypeUtil.extract( classesProp ) ?? [];
77
76
 
@@ -19,6 +19,7 @@ import {
19
19
  TextControl,
20
20
  ToggleControl,
21
21
  UrlControl,
22
+ VideoMediaControl,
22
23
  } from '@elementor/editor-controls';
23
24
  import { type ControlLayout } from '@elementor/editor-elements';
24
25
  import {
@@ -36,6 +37,7 @@ import {
36
37
  sizePropTypeUtil,
37
38
  stringArrayPropTypeUtil,
38
39
  stringPropTypeUtil,
40
+ videoSrcPropTypeUtil,
39
41
  } from '@elementor/editor-props';
40
42
 
41
43
  import { ControlTypeAlreadyRegisteredError, ControlTypeNotRegisteredError } from '../errors';
@@ -64,6 +66,7 @@ const controlTypes = {
64
66
  'html-tag': { component: HtmlTagControl, layout: 'two-columns', propTypeUtil: stringPropTypeUtil },
65
67
  toggle: { component: ToggleControl, layout: 'full', propTypeUtil: stringPropTypeUtil },
66
68
  'date-time': { component: DateTimeControl, layout: 'full', propTypeUtil: DateTimePropTypeUtil },
69
+ video: { component: VideoMediaControl, layout: 'full', propTypeUtil: videoSrcPropTypeUtil },
67
70
  'inline-editing': { component: InlineEditingControl, layout: 'full', propTypeUtil: htmlV3PropTypeUtil },
68
71
  email: { component: EmailFormActionControl, layout: 'custom', propTypeUtil: emailPropTypeUtil },
69
72
  } as const satisfies ControlRegistry;
@@ -2,21 +2,15 @@ import * as React from 'react';
2
2
  import { useMemo } from 'react';
3
3
  import { PropKeyProvider, PropProvider, type SetValueMeta } from '@elementor/editor-controls';
4
4
  import { setDocumentModifiedStatus } from '@elementor/editor-documents';
5
- import {
6
- type ElementID,
7
- getElementLabel,
8
- getElementSettings,
9
- updateElementSettings,
10
- useElementSettings,
11
- } from '@elementor/editor-elements';
5
+ import { type ElementID, getElementLabel, getElementSettings, updateElementSettings } from '@elementor/editor-elements';
12
6
  import {
13
7
  type CreateOptions,
14
8
  isDependency,
15
9
  isDependencyMet,
16
10
  type PropKey,
17
11
  type Props,
12
+ type PropsSchema,
18
13
  type PropType,
19
- type PropValue,
20
14
  } from '@elementor/editor-props';
21
15
  import { undoable } from '@elementor/editor-v1-adapters';
22
16
  import { __ } from '@wordpress/i18n';
@@ -33,15 +27,44 @@ type SettingsFieldProps = {
33
27
 
34
28
  const HISTORY_DEBOUNCE_WAIT = 800;
35
29
 
30
+ const getElementSettigsWithDefaults = ( propsSchema: PropsSchema, elementSettings?: Props ) => {
31
+ const elementSettingsWithDefaults = { ...elementSettings };
32
+ Object.keys( propsSchema ).forEach( ( key ) => {
33
+ if ( ! ( key in elementSettingsWithDefaults ) ) {
34
+ if ( propsSchema[ key ].default !== null ) {
35
+ elementSettingsWithDefaults[ key ] = propsSchema[ key ].default as Values[ keyof Values ];
36
+ }
37
+ }
38
+ } );
39
+ return elementSettingsWithDefaults;
40
+ };
41
+
42
+ const extractDependencyEffect = ( bind: string, propsSchema: PropsSchema, currentElementSettings: Props ) => {
43
+ const elementSettingsForDepCheck = getElementSettigsWithDefaults( propsSchema, currentElementSettings );
44
+ const propType = propsSchema[ bind ];
45
+ const depCheck = isDependencyMet( propType?.dependencies, elementSettingsForDepCheck );
46
+ const isHidden =
47
+ ! depCheck.isMet &&
48
+ ! isDependency( depCheck.failingDependencies[ 0 ] ) &&
49
+ depCheck.failingDependencies[ 0 ]?.effect === 'hide';
50
+ return {
51
+ isDisabled: ( prop: PropType ) => {
52
+ const result = ! isDependencyMet( prop?.dependencies, elementSettingsForDepCheck ).isMet;
53
+ return result;
54
+ },
55
+ isHidden,
56
+ settingsWithDefaults: elementSettingsForDepCheck as Values,
57
+ };
58
+ };
59
+
36
60
  export const SettingsField = ( { bind, children, propDisplayName }: SettingsFieldProps ) => {
37
61
  const {
38
62
  element: { id: elementId },
39
63
  elementType: { propsSchema, dependenciesPerTargetMapping = {} },
64
+ settings: currentElementSettings,
40
65
  } = useElement();
41
66
 
42
- const elementSettingValues = useElementSettings< PropValue >( elementId, Object.keys( propsSchema ) ) as Values;
43
-
44
- const value = { [ bind ]: elementSettingValues?.[ bind ] ?? null };
67
+ const value = { [ bind ]: currentElementSettings?.[ bind ] ?? null };
45
68
 
46
69
  const propType = createTopLevelObjectType( { schema: propsSchema } );
47
70
 
@@ -49,13 +72,21 @@ export const SettingsField = ( { bind, children, propDisplayName }: SettingsFiel
49
72
  elementId,
50
73
  propDisplayName,
51
74
  } );
75
+ const { isDisabled, isHidden, settingsWithDefaults } = extractDependencyEffect(
76
+ bind,
77
+ propsSchema,
78
+ currentElementSettings
79
+ );
80
+ if ( isHidden ) {
81
+ return null;
82
+ }
52
83
 
53
84
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
54
85
  const setValue = ( newValue: Values, _: CreateOptions = {}, meta?: SetValueMeta ) => {
55
86
  const { withHistory = true } = meta ?? {};
56
87
  const dependents = extractOrderedDependencies( dependenciesPerTargetMapping );
57
88
 
58
- const settings = getUpdatedValues( newValue, dependents, propsSchema, elementSettingValues, elementId );
89
+ const settings = getUpdatedValues( newValue, dependents, propsSchema, settingsWithDefaults, elementId );
59
90
  if ( withHistory ) {
60
91
  undoableUpdateElementProp( settings );
61
92
  } else {
@@ -63,19 +94,6 @@ export const SettingsField = ( { bind, children, propDisplayName }: SettingsFiel
63
94
  }
64
95
  };
65
96
 
66
- const isDisabled = ( prop: PropType ) => ! isDependencyMet( prop?.dependencies, elementSettingValues ).isMet;
67
-
68
- const propTypeToBind = propsSchema[ bind ];
69
- const dependenciesResult = isDependencyMet( propTypeToBind?.dependencies, elementSettingValues );
70
- const shouldHide =
71
- ! dependenciesResult.isMet &&
72
- ! isDependency( dependenciesResult.failingDependencies[ 0 ] ) &&
73
- dependenciesResult.failingDependencies[ 0 ]?.effect === 'hide';
74
-
75
- if ( shouldHide ) {
76
- return null;
77
- }
78
-
79
97
  return (
80
98
  <PropProvider propType={ propType } value={ value } setValue={ setValue } isDisabled={ isDisabled }>
81
99
  <PropKeyProvider bind={ bind }>{ children }</PropKeyProvider>
@@ -1,8 +1,8 @@
1
- import { getElementStyles, useElementSetting } from '@elementor/editor-elements';
1
+ import { getElementStyles } from '@elementor/editor-elements';
2
2
  import { type ClassesPropValue, type PropKey } from '@elementor/editor-props';
3
3
  import { type StyleDefinitionID } from '@elementor/editor-styles';
4
4
 
5
- import { useElement } from '../contexts/element-context';
5
+ import { useElement, usePanelElementSetting } from '../contexts/element-context';
6
6
  import { useStateByElement } from './use-state-by-element';
7
7
 
8
8
  export function useActiveStyleDefId( classProp: PropKey ) {
@@ -11,7 +11,7 @@ export function useActiveStyleDefId( classProp: PropKey ) {
11
11
  null
12
12
  );
13
13
 
14
- const appliedClassesIds = useAppliedClassesIds( classProp )?.value || [];
14
+ const appliedClassesIds = usePanelElementSetting< ClassesPropValue >( classProp )?.value || [];
15
15
 
16
16
  const fallback = useFirstAppliedClass( appliedClassesIds );
17
17
 
@@ -26,12 +26,6 @@ function useFirstAppliedClass( appliedClassesIds: string[] ) {
26
26
  return Object.values( stylesDefs ).find( ( styleDef ) => appliedClassesIds.includes( styleDef.id ) );
27
27
  }
28
28
 
29
- function useAppliedClassesIds( classProp: PropKey ) {
30
- const { element } = useElement();
31
-
32
- return useElementSetting< ClassesPropValue >( element.id, classProp );
33
- }
34
-
35
29
  function useActiveAndAppliedClassId( id: StyleDefinitionID | null, appliedClassesIds: string[] ) {
36
30
  const isClassApplied = !! id && appliedClassesIds.includes( id );
37
31
 
@@ -0,0 +1,11 @@
1
+ import { getContainer } from '@elementor/editor-elements';
2
+
3
+ export const canElementHaveChildren = ( elementId: string ): boolean => {
4
+ const container = getContainer( elementId );
5
+
6
+ if ( ! container ) {
7
+ return false;
8
+ }
9
+
10
+ return container.model.get( 'elType' ) !== 'widget';
11
+ };