@elementor/editor-components 4.0.0-manual → 4.0.1

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 (106) hide show
  1. package/dist/index.d.mts +1422 -1
  2. package/dist/index.d.ts +1422 -1
  3. package/dist/index.js +2096 -4814
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +2028 -4837
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +23 -23
  8. package/src/components/components-tab/components-list.tsx +92 -4
  9. package/src/components/components-tab/components-pro-notification.tsx +9 -15
  10. package/src/components/components-tab/components-update-notification.tsx +13 -0
  11. package/src/components/components-tab/components.tsx +52 -3
  12. package/src/components/components-tab/loading-components.tsx +26 -14
  13. package/src/components/components-update-alert.tsx +40 -0
  14. package/src/components/components-upgrade-alert.tsx +39 -0
  15. package/src/components/detach-instance-confirmation-dialog.tsx +50 -0
  16. package/src/components/instance-editing-panel/detach-action.tsx +76 -0
  17. package/src/components/instance-editing-panel/empty-state.tsx +9 -2
  18. package/src/components/instance-editing-panel/instance-editing-panel.tsx +34 -6
  19. package/src/components/instance-editing-panel/override-prop-control.tsx +14 -6
  20. package/src/components/instance-editing-panel/use-instance-panel-data.ts +2 -2
  21. package/src/components/instance-editing-panel/utils/correct-exposed-empty-override.ts +28 -0
  22. package/src/consts.ts +1 -0
  23. package/src/create-component-type.ts +130 -29
  24. package/src/index.ts +92 -0
  25. package/src/init.ts +6 -4
  26. package/src/store/actions/update-overridable-prop.ts +4 -10
  27. package/src/store/dispatchers.ts +63 -0
  28. package/src/store/extensible-slice.ts +168 -0
  29. package/src/store/selectors.ts +53 -0
  30. package/src/store/store-types.ts +48 -0
  31. package/src/store/store.ts +7 -169
  32. package/src/sync/publish-draft-components-in-page-before-save.ts +42 -1
  33. package/src/types.ts +1 -1
  34. package/src/utils/detach-component-instance/detach-component-instance.ts +172 -0
  35. package/src/utils/detach-component-instance/index.ts +1 -0
  36. package/src/utils/detach-component-instance/regenerate-local-style-ids.ts +53 -0
  37. package/src/utils/detach-component-instance/resolve-detached-instance.ts +94 -0
  38. package/src/utils/detach-component-instance/resolve-overridable-settings.ts +121 -0
  39. package/src/utils/is-component-instance.ts +1 -1
  40. package/src/utils/is-pro-components-supported.ts +11 -0
  41. package/src/utils/tracking.ts +2 -1
  42. package/src/extended/components/component-introduction.tsx +0 -77
  43. package/src/extended/components/component-panel-header/component-badge.tsx +0 -73
  44. package/src/extended/components/component-panel-header/component-panel-header.tsx +0 -98
  45. package/src/extended/components/component-properties-panel/component-properties-panel-content.tsx +0 -176
  46. package/src/extended/components/component-properties-panel/component-properties-panel.tsx +0 -43
  47. package/src/extended/components/component-properties-panel/properties-empty-state.tsx +0 -51
  48. package/src/extended/components/component-properties-panel/properties-group.tsx +0 -196
  49. package/src/extended/components/component-properties-panel/property-item.tsx +0 -124
  50. package/src/extended/components/component-properties-panel/sortable.tsx +0 -92
  51. package/src/extended/components/component-properties-panel/use-current-editable-item.ts +0 -73
  52. package/src/extended/components/component-properties-panel/utils/generate-unique-label.ts +0 -21
  53. package/src/extended/components/component-properties-panel/utils/validate-group-label.ts +0 -24
  54. package/src/extended/components/components-tab/component-item.tsx +0 -180
  55. package/src/extended/components/components-tab/components.tsx +0 -58
  56. package/src/extended/components/components-tab/delete-confirmation-dialog.tsx +0 -26
  57. package/src/extended/components/create-component-form/create-component-form.tsx +0 -282
  58. package/src/extended/components/create-component-form/hooks/use-form.ts +0 -72
  59. package/src/extended/components/create-component-form/utils/get-component-event-data.ts +0 -54
  60. package/src/extended/components/edit-component/component-modal.tsx +0 -133
  61. package/src/extended/components/edit-component/edit-component.tsx +0 -166
  62. package/src/extended/components/edit-component/use-canvas-document.ts +0 -9
  63. package/src/extended/components/edit-component/use-element-rect.ts +0 -81
  64. package/src/extended/components/instance-editing-panel/instance-editing-panel.tsx +0 -60
  65. package/src/extended/components/overridable-props/indicator.tsx +0 -83
  66. package/src/extended/components/overridable-props/overridable-prop-control.tsx +0 -127
  67. package/src/extended/components/overridable-props/overridable-prop-form.tsx +0 -135
  68. package/src/extended/components/overridable-props/overridable-prop-indicator.tsx +0 -138
  69. package/src/extended/components/overridable-props/utils/validate-prop-label.ts +0 -38
  70. package/src/extended/consts.ts +0 -3
  71. package/src/extended/hooks/use-navigate-back.ts +0 -24
  72. package/src/extended/init.ts +0 -104
  73. package/src/extended/mcp/index.ts +0 -14
  74. package/src/extended/mcp/save-as-component-tool.ts +0 -436
  75. package/src/extended/store/actions/add-overridable-group.ts +0 -59
  76. package/src/extended/store/actions/archive-component.ts +0 -19
  77. package/src/extended/store/actions/create-unpublished-component.ts +0 -102
  78. package/src/extended/store/actions/delete-overridable-group.ts +0 -38
  79. package/src/extended/store/actions/delete-overridable-prop.ts +0 -70
  80. package/src/extended/store/actions/rename-component.ts +0 -49
  81. package/src/extended/store/actions/rename-overridable-group.ts +0 -39
  82. package/src/extended/store/actions/reorder-group-props.ts +0 -43
  83. package/src/extended/store/actions/reorder-overridable-groups.ts +0 -30
  84. package/src/extended/store/actions/reset-sanitized-components.ts +0 -7
  85. package/src/extended/store/actions/set-overridable-prop.ts +0 -117
  86. package/src/extended/store/actions/update-component-sanitized-attribute.ts +0 -8
  87. package/src/extended/store/actions/update-current-component.ts +0 -21
  88. package/src/extended/store/actions/update-overridable-prop-params.ts +0 -58
  89. package/src/extended/store/utils/groups-transformers.ts +0 -187
  90. package/src/extended/sync/before-save.ts +0 -52
  91. package/src/extended/sync/cleanup-overridable-props-on-delete.ts +0 -85
  92. package/src/extended/sync/create-components-before-save.ts +0 -113
  93. package/src/extended/sync/handle-component-edit-mode-container.ts +0 -114
  94. package/src/extended/sync/prevent-non-atomic-nesting.ts +0 -198
  95. package/src/extended/sync/revert-overridables-on-copy-or-duplicate.ts +0 -66
  96. package/src/extended/sync/sanitize-overridable-props.ts +0 -32
  97. package/src/extended/sync/set-component-overridable-props-settings-before-save.ts +0 -23
  98. package/src/extended/sync/update-archived-component-before-save.ts +0 -32
  99. package/src/extended/sync/update-component-title-before-save.ts +0 -19
  100. package/src/extended/utils/component-form-schema.ts +0 -32
  101. package/src/extended/utils/component-name-validation.ts +0 -27
  102. package/src/extended/utils/create-component-model.ts +0 -28
  103. package/src/extended/utils/get-container-for-new-element.ts +0 -49
  104. package/src/extended/utils/is-editing-component.ts +0 -13
  105. package/src/extended/utils/replace-element-with-component.ts +0 -11
  106. package/src/extended/utils/revert-overridable-settings.ts +0 -207
@@ -1,127 +0,0 @@
1
- import * as React from 'react';
2
- import { type ComponentType } from 'react';
3
- import {
4
- ControlReplacementsProvider,
5
- getControlReplacements,
6
- PropKeyProvider,
7
- PropProvider,
8
- useBoundProp,
9
- useControlReplacement,
10
- } from '@elementor/editor-controls';
11
- import { createTopLevelObjectType, useElement } from '@elementor/editor-editing-panel';
12
- import { type PropValue } from '@elementor/editor-props';
13
-
14
- import { type ComponentInstanceOverridePropValue } from '../../../prop-types/component-instance-override-prop-type';
15
- import {
16
- componentOverridablePropTypeUtil,
17
- type ComponentOverridablePropValue,
18
- } from '../../../prop-types/component-overridable-prop-type';
19
- import { OverridablePropProvider } from '../../../provider/overridable-prop-context';
20
- import { updateOverridableProp } from '../../../store/actions/update-overridable-prop';
21
- import { useCurrentComponentId, useOverridableProps } from '../../../store/store';
22
- import { getPropTypeForComponentOverride } from '../../../utils/get-prop-type-for-component-override';
23
- import { OVERRIDABLE_PROP_REPLACEMENT_ID } from '../../consts';
24
-
25
- export function OverridablePropControl< T extends object >( {
26
- OriginalControl,
27
- ...props
28
- }: T & { OriginalControl: ComponentType< T > } ) {
29
- const { elementType } = useElement();
30
-
31
- const { value, bind, setValue, placeholder, ...propContext } = useBoundProp( componentOverridablePropTypeUtil );
32
- const componentId = useCurrentComponentId();
33
- const overridableProps = useOverridableProps( componentId );
34
- const filteredReplacements = getControlReplacements().filter(
35
- ( r ) => ! r.id || r.id !== OVERRIDABLE_PROP_REPLACEMENT_ID
36
- );
37
-
38
- if ( ! componentId ) {
39
- return null;
40
- }
41
-
42
- if ( ! value?.override_key ) {
43
- throw new Error( 'Override key is required' );
44
- }
45
-
46
- const isComponentInstance = elementType.key === 'e-component';
47
- const overridablePropData = overridableProps?.props?.[ value.override_key ];
48
-
49
- const setOverridableValue = ( newValue: Record< typeof bind, PropValue | null > ) => {
50
- const propValue = {
51
- ...value,
52
- origin_value: newValue[ bind ],
53
- } as ComponentOverridablePropValue;
54
-
55
- setValue( propValue );
56
-
57
- if ( ! isComponentInstance ) {
58
- updateOverridableProp( componentId, propValue, overridablePropData?.originPropFields );
59
- }
60
- };
61
-
62
- const defaultPropType = elementType.propsSchema[ bind ];
63
- const overridePropType = overridablePropData ? getPropTypeForComponentOverride( overridablePropData ) : undefined;
64
-
65
- const resolvedPropType = overridePropType ?? defaultPropType;
66
-
67
- if ( ! resolvedPropType ) {
68
- return null;
69
- }
70
-
71
- const propType = createTopLevelObjectType( {
72
- schema: {
73
- [ bind ]: resolvedPropType,
74
- },
75
- } );
76
-
77
- const propValue = (
78
- isComponentInstance
79
- ? ( value.origin_value?.value as ComponentInstanceOverridePropValue ).override_value
80
- : value.origin_value
81
- ) as PropValue;
82
-
83
- const objectPlaceholder: Record< string, PropValue > | undefined = placeholder
84
- ? { [ bind ]: placeholder }
85
- : undefined;
86
-
87
- return (
88
- <OverridablePropProvider value={ value }>
89
- <PropProvider
90
- { ...propContext }
91
- propType={ propType }
92
- setValue={ setOverridableValue }
93
- value={ {
94
- [ bind ]: propValue,
95
- } }
96
- placeholder={ objectPlaceholder }
97
- >
98
- <PropKeyProvider bind={ bind }>
99
- <ControlReplacementsProvider replacements={ filteredReplacements }>
100
- <ControlWithReplacements OriginalControl={ OriginalControl } props={ props as T } />
101
- </ControlReplacementsProvider>
102
- </PropKeyProvider>
103
- </PropProvider>
104
- </OverridablePropProvider>
105
- );
106
- }
107
-
108
- type ControlComponentType = ComponentType< object & { OriginalControl: ComponentType } >;
109
-
110
- function ControlWithReplacements< T extends object >( {
111
- OriginalControl,
112
- props,
113
- }: {
114
- OriginalControl: ComponentType< T >;
115
- props: T;
116
- } ) {
117
- const { ControlToRender, isReplaced } = useControlReplacement( OriginalControl as ControlComponentType );
118
-
119
- if ( isReplaced ) {
120
- const ReplacementControl = ControlToRender as unknown as ComponentType<
121
- T & { OriginalControl: ComponentType< T > }
122
- >;
123
- return <ReplacementControl { ...props } OriginalControl={ OriginalControl } />;
124
- }
125
-
126
- return <OriginalControl { ...props } />;
127
- }
@@ -1,135 +0,0 @@
1
- import * as React from 'react';
2
- import { useState } from 'react';
3
- import { Form, MenuListItem } from '@elementor/editor-ui';
4
- import { Button, FormLabel, Grid, Select, Stack, type SxProps, TextField, Typography } from '@elementor/ui';
5
- import { __ } from '@wordpress/i18n';
6
-
7
- import { type OverridableProp } from '../../../types';
8
- import { validatePropLabel } from './utils/validate-prop-label';
9
-
10
- const SIZE = 'tiny';
11
-
12
- const DEFAULT_GROUP = { value: null, label: __( 'Default', 'elementor' ) };
13
-
14
- type Props = {
15
- onSubmit: ( data: { label: string; group: string | null } ) => void;
16
- currentValue?: OverridableProp;
17
- groups?: { value: string; label: string }[];
18
- existingLabels?: string[];
19
- sx?: SxProps;
20
- };
21
-
22
- export function OverridablePropForm( { onSubmit, groups, currentValue, existingLabels = [], sx }: Props ) {
23
- const selectGroups = groups?.length ? groups : [ DEFAULT_GROUP ];
24
-
25
- const [ propLabel, setPropLabel ] = useState< string | null >( currentValue?.label ?? null );
26
- const [ group, setGroup ] = useState< string | null >( currentValue?.groupId ?? selectGroups[ 0 ]?.value ?? null );
27
- const [ error, setError ] = useState< string | null >( null );
28
-
29
- const name = __( 'Name', 'elementor' );
30
- const groupName = __( 'Group Name', 'elementor' );
31
-
32
- const isCreate = currentValue === undefined;
33
-
34
- const title = isCreate ? __( 'Create new property', 'elementor' ) : __( 'Update property', 'elementor' );
35
- const ctaLabel = isCreate ? __( 'Create', 'elementor' ) : __( 'Update', 'elementor' );
36
-
37
- const handleSubmit = () => {
38
- const validationResult = validatePropLabel( propLabel ?? '', existingLabels, currentValue?.label );
39
-
40
- if ( ! validationResult.isValid ) {
41
- setError( validationResult.errorMessage );
42
- return;
43
- }
44
-
45
- onSubmit( { label: propLabel ?? '', group } );
46
- };
47
-
48
- return (
49
- <Form onSubmit={ handleSubmit } data-testid="overridable-prop-form">
50
- <Stack alignItems="start" sx={ { width: '268px', ...sx } }>
51
- <Stack
52
- direction="row"
53
- alignItems="center"
54
- py={ 1 }
55
- px={ 1.5 }
56
- sx={ { columnGap: 0.5, borderBottom: '1px solid', borderColor: 'divider', width: '100%', mb: 1.5 } }
57
- >
58
- <Typography variant="caption" sx={ { color: 'text.primary', fontWeight: '500', lineHeight: 1 } }>
59
- { title }
60
- </Typography>
61
- </Stack>
62
- <Grid container gap={ 0.75 } alignItems="start" px={ 1.5 } mb={ 1.5 }>
63
- <Grid item xs={ 12 }>
64
- <FormLabel size="tiny">{ name }</FormLabel>
65
- </Grid>
66
- <Grid item xs={ 12 }>
67
- <TextField
68
- name={ name }
69
- size={ SIZE }
70
- fullWidth
71
- placeholder={ __( 'Enter value', 'elementor' ) }
72
- value={ propLabel ?? '' }
73
- onChange={ ( e: React.ChangeEvent< HTMLInputElement > ) => {
74
- const newValue = e.target.value;
75
- setPropLabel( newValue );
76
- const validationResult = validatePropLabel(
77
- newValue,
78
- existingLabels,
79
- currentValue?.label
80
- );
81
- setError( validationResult.errorMessage );
82
- } }
83
- error={ Boolean( error ) }
84
- helperText={ error }
85
- />
86
- </Grid>
87
- </Grid>
88
- <Grid container gap={ 0.75 } alignItems="start" px={ 1.5 } mb={ 1.5 }>
89
- <Grid item xs={ 12 }>
90
- <FormLabel size="tiny">{ groupName }</FormLabel>
91
- </Grid>
92
- <Grid item xs={ 12 }>
93
- <Select
94
- name={ groupName }
95
- size={ SIZE }
96
- fullWidth
97
- value={ group ?? null }
98
- onChange={ ( e: React.ChangeEvent< HTMLSelectElement > ) =>
99
- setGroup( e.target.value as string | null )
100
- }
101
- displayEmpty
102
- renderValue={ ( selectedValue: string | null ) => {
103
- if ( ! selectedValue ) {
104
- return selectGroups[ 0 ].label;
105
- }
106
-
107
- return (
108
- selectGroups.find( ( { value } ) => value === selectedValue )?.label ??
109
- selectedValue
110
- );
111
- } }
112
- >
113
- { selectGroups.map( ( { label: groupLabel, ...props } ) => (
114
- <MenuListItem key={ props.value } { ...props } value={ props.value ?? '' }>
115
- { groupLabel }
116
- </MenuListItem>
117
- ) ) }
118
- </Select>
119
- </Grid>
120
- </Grid>
121
- <Stack direction="row" justifyContent="flex-end" alignSelf="end" mt={ 1.5 } py={ 1 } px={ 1.5 }>
122
- <Button
123
- type="submit"
124
- disabled={ ! propLabel || Boolean( error ) }
125
- variant="contained"
126
- color="primary"
127
- size="small"
128
- >
129
- { ctaLabel }
130
- </Button>
131
- </Stack>
132
- </Stack>
133
- </Form>
134
- );
135
- }
@@ -1,138 +0,0 @@
1
- import * as React from 'react';
2
- import { useBoundProp } from '@elementor/editor-controls';
3
- import { useElement } from '@elementor/editor-editing-panel';
4
- import { getWidgetsCache } from '@elementor/editor-elements';
5
- import { type PropType, type TransformablePropValue } from '@elementor/editor-props';
6
- import { bindPopover, bindTrigger, Popover, Tooltip, usePopupState } from '@elementor/ui';
7
- import { __ } from '@wordpress/i18n';
8
-
9
- import { useSanitizeOverridableProps } from '../../../hooks/use-sanitize-overridable-props';
10
- import { componentOverridablePropTypeUtil } from '../../../prop-types/component-overridable-prop-type';
11
- import { useComponentInstanceElement, useOverridablePropValue } from '../../../provider/overridable-prop-context';
12
- import { useCurrentComponentId } from '../../../store/store';
13
- import { type OverridableProps } from '../../../types';
14
- import { getOverridableProp } from '../../../utils/get-overridable-prop';
15
- import { resolveOverridePropValue } from '../../../utils/resolve-override-prop-value';
16
- import { setOverridableProp } from '../../store/actions/set-overridable-prop';
17
- import { Indicator } from './indicator';
18
- import { OverridablePropForm } from './overridable-prop-form';
19
-
20
- export function OverridablePropIndicator() {
21
- const { propType } = useBoundProp();
22
- const componentId = useCurrentComponentId();
23
- const overridableProps = useSanitizeOverridableProps( componentId );
24
-
25
- if ( ! isPropAllowed( propType ) || ! componentId || ! overridableProps ) {
26
- return null;
27
- }
28
-
29
- return <Content componentId={ componentId } overridableProps={ overridableProps } />;
30
- }
31
-
32
- type Props = {
33
- componentId: number;
34
- overridableProps?: OverridableProps;
35
- };
36
- export function Content( { componentId, overridableProps }: Props ) {
37
- const {
38
- element: { id: elementId },
39
- elementType,
40
- } = useElement();
41
- const { value, bind, propType } = useBoundProp();
42
-
43
- const contextOverridableValue = useOverridablePropValue();
44
- const componentInstanceElement = useComponentInstanceElement();
45
-
46
- const { value: boundPropOverridableValue, setValue: setOverridableValue } = useBoundProp(
47
- componentOverridablePropTypeUtil
48
- );
49
-
50
- /**
51
- * This is intended to handle custom layout controls, such as <LinkControl />, which has <ControlLabel /> nested within it
52
- * i.e. its bound prop value would be the one manipulated by the new <PropProvider /> thus won't be considered overridable
53
- */
54
- const overridableValue = boundPropOverridableValue ?? contextOverridableValue;
55
-
56
- const popupState = usePopupState( {
57
- variant: 'popover',
58
- } );
59
-
60
- const triggerProps = bindTrigger( popupState );
61
- const popoverProps = bindPopover( popupState );
62
-
63
- const { elType } = getWidgetsCache()?.[ elementType.key ] ?? { elType: 'widget' };
64
-
65
- const handleSubmit = ( { label, group }: { label: string; group: string | null } ) => {
66
- const propTypeDefault = propType.default ?? {};
67
-
68
- const originValue = resolveOverridePropValue( overridableValue?.origin_value ) ?? value ?? propTypeDefault;
69
-
70
- const matchingOverridableProp = overridableValue
71
- ? overridableProps?.props?.[ overridableValue.override_key ]
72
- : undefined;
73
-
74
- const overridablePropConfig = setOverridableProp( {
75
- componentId,
76
- overrideKey: overridableValue?.override_key ?? null,
77
- elementId: componentInstanceElement?.element.id ?? elementId,
78
- label,
79
- groupId: group,
80
- propKey: bind,
81
- elType: elType ?? 'widget',
82
- widgetType: componentInstanceElement?.elementType.key ?? elementType.key,
83
- originValue,
84
- originPropFields: matchingOverridableProp?.originPropFields,
85
- source: 'user',
86
- } );
87
-
88
- if ( ! overridableValue && overridablePropConfig ) {
89
- setOverridableValue( {
90
- override_key: overridablePropConfig.overrideKey,
91
- origin_value: originValue as TransformablePropValue< string, unknown >,
92
- } );
93
- }
94
-
95
- popupState.close();
96
- };
97
-
98
- const overridableConfig = overridableValue
99
- ? getOverridableProp( { componentId, overrideKey: overridableValue.override_key } )
100
- : undefined;
101
-
102
- return (
103
- <>
104
- <Tooltip placement="top" title={ __( 'Override Property', 'elementor' ) }>
105
- <Indicator { ...triggerProps } isOpen={ !! popoverProps.open } isOverridable={ !! overridableValue } />
106
- </Tooltip>
107
- <Popover
108
- disableScrollLock
109
- anchorOrigin={ {
110
- vertical: 'bottom',
111
- horizontal: 'right',
112
- } }
113
- transformOrigin={ {
114
- vertical: 'top',
115
- horizontal: 'right',
116
- } }
117
- PaperProps={ {
118
- sx: { my: 2.5 },
119
- } }
120
- { ...popoverProps }
121
- >
122
- <OverridablePropForm
123
- onSubmit={ handleSubmit }
124
- groups={ overridableProps?.groups.order.map( ( groupId ) => ( {
125
- value: groupId,
126
- label: overridableProps.groups.items[ groupId ].label,
127
- } ) ) }
128
- existingLabels={ Object.values( overridableProps?.props ?? {} ).map( ( prop ) => prop.label ) }
129
- currentValue={ overridableConfig }
130
- />
131
- </Popover>
132
- </>
133
- );
134
- }
135
-
136
- function isPropAllowed( propType: PropType ) {
137
- return propType.meta.overridable !== false;
138
- }
@@ -1,38 +0,0 @@
1
- import { __ } from '@wordpress/i18n';
2
-
3
- export const ERROR_MESSAGES = {
4
- EMPTY_NAME: __( 'Property name is required', 'elementor' ),
5
- DUPLICATE_NAME: __( 'Property name already exists', 'elementor' ),
6
- } as const;
7
-
8
- type ValidationResult = {
9
- isValid: boolean;
10
- errorMessage: string | null;
11
- };
12
-
13
- export function validatePropLabel( label: string, existingLabels: string[], currentLabel?: string ): ValidationResult {
14
- const trimmedLabel = label.trim();
15
-
16
- if ( ! trimmedLabel ) {
17
- return { isValid: false, errorMessage: ERROR_MESSAGES.EMPTY_NAME };
18
- }
19
-
20
- const normalizedLabel = trimmedLabel.toLowerCase();
21
- const normalizedCurrentLabel = currentLabel?.trim().toLowerCase();
22
-
23
- const isDuplicate = existingLabels.some( ( existingLabel ) => {
24
- const normalizedExisting = existingLabel.trim().toLowerCase();
25
-
26
- if ( normalizedCurrentLabel && normalizedExisting === normalizedCurrentLabel ) {
27
- return false;
28
- }
29
-
30
- return normalizedExisting === normalizedLabel;
31
- } );
32
-
33
- if ( isDuplicate ) {
34
- return { isValid: false, errorMessage: ERROR_MESSAGES.DUPLICATE_NAME };
35
- }
36
-
37
- return { isValid: true, errorMessage: null };
38
- }
@@ -1,3 +0,0 @@
1
- export const OVERRIDABLE_PROP_REPLACEMENT_ID = 'overridable-prop';
2
-
3
- export const COMPONENT_DOCUMENT_TYPE = 'elementor_component';
@@ -1,24 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { getV1DocumentsManager } from '@elementor/editor-documents';
3
- import { __useSelector as useSelector } from '@elementor/store';
4
-
5
- import { selectPath } from '../../store/store';
6
- import { switchToComponent } from '../../utils/switch-to-component';
7
-
8
- export function useNavigateBack() {
9
- const path = useSelector( selectPath );
10
-
11
- const documentsManager = getV1DocumentsManager();
12
-
13
- return useCallback( () => {
14
- const { componentId: prevComponentId, instanceId: prevComponentInstanceId } = path.at( -2 ) ?? {};
15
-
16
- if ( prevComponentId && prevComponentInstanceId ) {
17
- switchToComponent( prevComponentId, prevComponentInstanceId );
18
-
19
- return;
20
- }
21
-
22
- switchToComponent( documentsManager.getInitialId() );
23
- }, [ path, documentsManager ] );
24
- }
@@ -1,104 +0,0 @@
1
- import { injectIntoLogic, injectIntoTop } from '@elementor/editor';
2
- import { registerControlReplacement } from '@elementor/editor-controls';
3
- import { getV1CurrentDocument } from '@elementor/editor-documents';
4
- import {
5
- FIELD_TYPE,
6
- injectIntoPanelHeaderTop,
7
- registerEditingPanelReplacement,
8
- registerFieldIndicator,
9
- } from '@elementor/editor-editing-panel';
10
- import { registerTab } from '@elementor/editor-elements-panel';
11
- import { __registerPanel as registerPanel } from '@elementor/editor-panels';
12
- import { registerDataHook } from '@elementor/editor-v1-adapters';
13
- import { __ } from '@wordpress/i18n';
14
-
15
- import { componentOverridablePropTypeUtil } from '../prop-types/component-overridable-prop-type';
16
- import { type ExtendedWindow } from '../types';
17
- import { onElementDrop } from '../utils/tracking';
18
- import { ComponentPanelHeader } from './components/component-panel-header/component-panel-header';
19
- import { panel as componentPropertiesPanel } from './components/component-properties-panel/component-properties-panel';
20
- import { ExtendedComponents } from './components/components-tab/components';
21
- import { CreateComponentForm } from './components/create-component-form/create-component-form';
22
- import { EditComponent } from './components/edit-component/edit-component';
23
- import { ExtendedInstanceEditingPanel } from './components/instance-editing-panel/instance-editing-panel';
24
- import { OverridablePropControl } from './components/overridable-props/overridable-prop-control';
25
- import { OverridablePropIndicator } from './components/overridable-props/overridable-prop-indicator';
26
- import { COMPONENT_DOCUMENT_TYPE, OVERRIDABLE_PROP_REPLACEMENT_ID } from './consts';
27
- import { initMcp } from './mcp';
28
- import { beforeSave } from './sync/before-save';
29
- import { initCleanupOverridablePropsOnDelete } from './sync/cleanup-overridable-props-on-delete';
30
- import { initHandleComponentEditModeContainer } from './sync/handle-component-edit-mode-container';
31
- import { initNonAtomicNestingPrevention } from './sync/prevent-non-atomic-nesting';
32
- import { initRevertOverridablesOnCopyOrDuplicate } from './sync/revert-overridables-on-copy-or-duplicate';
33
- import { SanitizeOverridableProps } from './sync/sanitize-overridable-props';
34
-
35
- export function initExtended() {
36
- registerEditingPanelReplacement( {
37
- id: 'component-instance-edit-panel',
38
- condition: ( _, elementType ) => elementType.key === 'e-component',
39
- component: ExtendedInstanceEditingPanel,
40
- } );
41
-
42
- registerTab( {
43
- id: 'components',
44
- label: __( 'Components', 'elementor' ),
45
- component: ExtendedComponents,
46
- } );
47
-
48
- registerPanel( componentPropertiesPanel );
49
-
50
- registerDataHook( 'dependency', 'editor/documents/close', ( args ) => {
51
- const document = getV1CurrentDocument();
52
- if ( document.config.type === COMPONENT_DOCUMENT_TYPE ) {
53
- args.mode = 'autosave';
54
- }
55
- return true;
56
- } );
57
-
58
- registerDataHook( 'after', 'preview/drop', onElementDrop );
59
-
60
- ( window as unknown as ExtendedWindow ).elementorCommon.__beforeSave = beforeSave;
61
-
62
- injectIntoTop( {
63
- id: 'create-component-popup',
64
- component: CreateComponentForm,
65
- } );
66
-
67
- injectIntoTop( {
68
- id: 'edit-component',
69
- component: EditComponent,
70
- } );
71
-
72
- injectIntoPanelHeaderTop( {
73
- id: 'component-panel-header',
74
- component: ComponentPanelHeader,
75
- } );
76
-
77
- registerFieldIndicator( {
78
- fieldType: FIELD_TYPE.SETTINGS,
79
- id: 'component-overridable-prop',
80
- priority: 1,
81
- indicator: OverridablePropIndicator,
82
- } );
83
-
84
- registerControlReplacement( {
85
- id: OVERRIDABLE_PROP_REPLACEMENT_ID,
86
- component: OverridablePropControl,
87
- condition: ( { value } ) => componentOverridablePropTypeUtil.isValid( value ),
88
- } );
89
-
90
- initCleanupOverridablePropsOnDelete();
91
-
92
- initMcp();
93
-
94
- initNonAtomicNestingPrevention();
95
-
96
- initHandleComponentEditModeContainer();
97
-
98
- initRevertOverridablesOnCopyOrDuplicate();
99
-
100
- injectIntoLogic( {
101
- id: 'sanitize-overridable-props',
102
- component: SanitizeOverridableProps,
103
- } );
104
- }
@@ -1,14 +0,0 @@
1
- import { getMCPByDomain } from '@elementor/editor-mcp';
2
-
3
- import { initSaveAsComponentTool } from './save-as-component-tool';
4
-
5
- export function initMcp() {
6
- const { setMCPDescription } = getMCPByDomain( 'components' );
7
-
8
- setMCPDescription(
9
- `Elementor Editor Components MCP - Tools for creating and managing reusable components.
10
- Components are reusable blocks of content that can be used multiple times across the pages, its a widget which contains a set of elements and styles.`
11
- );
12
-
13
- initSaveAsComponentTool();
14
- }