@elementor/editor-components 4.0.0-665 → 4.0.0-667

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 (72) hide show
  1. package/dist/index.js +191 -3870
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +184 -3904
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +23 -23
  6. package/src/init.ts +0 -13
  7. package/src/extended/components/component-introduction.tsx +0 -77
  8. package/src/extended/components/component-panel-header/component-badge.tsx +0 -73
  9. package/src/extended/components/component-panel-header/component-panel-header.tsx +0 -98
  10. package/src/extended/components/component-properties-panel/component-properties-panel-content.tsx +0 -176
  11. package/src/extended/components/component-properties-panel/component-properties-panel.tsx +0 -43
  12. package/src/extended/components/component-properties-panel/properties-empty-state.tsx +0 -51
  13. package/src/extended/components/component-properties-panel/properties-group.tsx +0 -196
  14. package/src/extended/components/component-properties-panel/property-item.tsx +0 -124
  15. package/src/extended/components/component-properties-panel/sortable.tsx +0 -92
  16. package/src/extended/components/component-properties-panel/use-current-editable-item.ts +0 -73
  17. package/src/extended/components/component-properties-panel/utils/generate-unique-label.ts +0 -21
  18. package/src/extended/components/component-properties-panel/utils/validate-group-label.ts +0 -24
  19. package/src/extended/components/components-tab/component-item.tsx +0 -180
  20. package/src/extended/components/components-tab/components.tsx +0 -58
  21. package/src/extended/components/components-tab/delete-confirmation-dialog.tsx +0 -26
  22. package/src/extended/components/create-component-form/create-component-form.tsx +0 -281
  23. package/src/extended/components/create-component-form/hooks/use-form.ts +0 -72
  24. package/src/extended/components/create-component-form/utils/get-component-event-data.ts +0 -54
  25. package/src/extended/components/edit-component/component-modal.tsx +0 -133
  26. package/src/extended/components/edit-component/edit-component.tsx +0 -166
  27. package/src/extended/components/edit-component/use-canvas-document.ts +0 -9
  28. package/src/extended/components/edit-component/use-element-rect.ts +0 -81
  29. package/src/extended/components/instance-editing-panel/instance-editing-panel.tsx +0 -60
  30. package/src/extended/components/overridable-props/indicator.tsx +0 -83
  31. package/src/extended/components/overridable-props/overridable-prop-control.tsx +0 -127
  32. package/src/extended/components/overridable-props/overridable-prop-form.tsx +0 -135
  33. package/src/extended/components/overridable-props/overridable-prop-indicator.tsx +0 -138
  34. package/src/extended/components/overridable-props/utils/validate-prop-label.ts +0 -38
  35. package/src/extended/consts.ts +0 -3
  36. package/src/extended/hooks/use-navigate-back.ts +0 -24
  37. package/src/extended/init.ts +0 -108
  38. package/src/extended/mcp/index.ts +0 -14
  39. package/src/extended/mcp/save-as-component-tool.ts +0 -436
  40. package/src/extended/shortcuts/create-component-shortcut.ts +0 -121
  41. package/src/extended/store/actions/add-overridable-group.ts +0 -53
  42. package/src/extended/store/actions/archive-component.ts +0 -18
  43. package/src/extended/store/actions/create-unpublished-component.ts +0 -99
  44. package/src/extended/store/actions/delete-overridable-group.ts +0 -32
  45. package/src/extended/store/actions/delete-overridable-prop.ts +0 -64
  46. package/src/extended/store/actions/rename-component.ts +0 -48
  47. package/src/extended/store/actions/rename-overridable-group.ts +0 -33
  48. package/src/extended/store/actions/reorder-group-props.ts +0 -37
  49. package/src/extended/store/actions/reorder-overridable-groups.ts +0 -24
  50. package/src/extended/store/actions/reset-sanitized-components.ts +0 -5
  51. package/src/extended/store/actions/set-overridable-prop.ts +0 -109
  52. package/src/extended/store/actions/update-component-sanitized-attribute.ts +0 -7
  53. package/src/extended/store/actions/update-current-component.ts +0 -12
  54. package/src/extended/store/actions/update-overridable-prop-params.ts +0 -52
  55. package/src/extended/store/utils/groups-transformers.ts +0 -187
  56. package/src/extended/sync/before-save.ts +0 -52
  57. package/src/extended/sync/cleanup-overridable-props-on-delete.ts +0 -78
  58. package/src/extended/sync/create-components-before-save.ts +0 -111
  59. package/src/extended/sync/handle-component-edit-mode-container.ts +0 -114
  60. package/src/extended/sync/prevent-non-atomic-nesting.ts +0 -198
  61. package/src/extended/sync/revert-overridables-on-copy-or-duplicate.ts +0 -66
  62. package/src/extended/sync/sanitize-overridable-props.ts +0 -32
  63. package/src/extended/sync/set-component-overridable-props-settings-before-save.ts +0 -22
  64. package/src/extended/sync/update-archived-component-before-save.ts +0 -31
  65. package/src/extended/sync/update-component-title-before-save.ts +0 -18
  66. package/src/extended/utils/component-form-schema.ts +0 -32
  67. package/src/extended/utils/component-name-validation.ts +0 -25
  68. package/src/extended/utils/create-component-model.ts +0 -28
  69. package/src/extended/utils/get-container-for-new-element.ts +0 -49
  70. package/src/extended/utils/is-editing-component.ts +0 -5
  71. package/src/extended/utils/replace-element-with-component.ts +0 -11
  72. package/src/extended/utils/revert-overridable-settings.ts +0 -207
@@ -1,436 +0,0 @@
1
- import { DOCUMENT_STRUCTURE_URI, WIDGET_SCHEMA_URI } from '@elementor/editor-canvas';
2
- import { getContainer, getElementType, getWidgetsCache, type V1ElementData } from '@elementor/editor-elements';
3
- import { getMCPByDomain, toolPrompts } from '@elementor/editor-mcp';
4
- import { type PropValue } from '@elementor/editor-props';
5
- import { AxiosError } from '@elementor/http-client';
6
- import { z } from '@elementor/schema';
7
- import { generateUniqueId } from '@elementor/utils';
8
-
9
- import { apiClient } from '../../api';
10
- import { type OverridableProps } from '../../types';
11
- import { createUnpublishedComponent } from '../store/actions/create-unpublished-component';
12
-
13
- const InputSchema = {
14
- element_id: z
15
- .string()
16
- .describe(
17
- 'The unique identifier of the element to save as a component. ' +
18
- 'Use the "list-elements" tool to find available element IDs in the current document.'
19
- ),
20
- component_name: z
21
- .string()
22
- .describe( 'The name for the new component. Should be descriptive and unique among existing components.' ),
23
- overridable_props: z
24
- .object( {
25
- props: z.record(
26
- z.object( {
27
- elementId: z
28
- .string()
29
- .describe( 'The id of the child element that you want to override its settings' ),
30
- propKey: z
31
- .string()
32
- .describe(
33
- 'The property key of the child element that you want to override its settings (e.g., "text", "url", "tag"). To get the available propKeys for an element, use the "get-element-type-config" tool.'
34
- ),
35
- label: z
36
- .string()
37
- .describe(
38
- 'A unique, user-friendly display name for this property (e.g., "Hero Headline", "CTA Button Text"). Must be unique within the same component.'
39
- ),
40
- group: z.string().optional().describe( 'Non unique, optional property grouping' ),
41
- } )
42
- ),
43
- } )
44
- .optional()
45
- .describe(
46
- 'Overridable properties configuration. Specify which CHILD element properties can be customized. ' +
47
- 'Only elementId and propKey are required; To get the available propKeys for a child element you must use the "get-element-type-config" tool.'
48
- ),
49
- groups: z.array( z.string() ).describe( 'Property Groups, by order, unique values' ).optional(),
50
- };
51
-
52
- const OutputSchema = {
53
- message: z.string().optional().describe( 'Additional information about the operation result' ),
54
- component_uid: z
55
- .string()
56
- .optional()
57
- .describe( 'The unique identifier of the newly created component (only present on success)' ),
58
- };
59
-
60
- export const ERROR_MESSAGES = {
61
- ELEMENT_NOT_FOUND: "Element not found. Use 'list-elements' to get valid element IDs.",
62
- ELEMENT_NOT_ONE_OF_TYPES: ( validTypes: string[] ) =>
63
- `Element is not one of the following types: ${ validTypes.join( ', ' ) }`,
64
- ELEMENT_IS_LOCKED: 'Cannot save a locked element as a component.',
65
- };
66
-
67
- export const handleSaveAsComponent = async ( params: z.infer< z.ZodObject< typeof InputSchema > > ) => {
68
- const {
69
- groups = [],
70
- element_id: elementId,
71
- component_name: componentName,
72
- overridable_props: overridablePropsInput,
73
- } = params;
74
- const validElementTypes = getValidElementTypes();
75
- const container = getContainer( elementId );
76
-
77
- if ( ! container ) {
78
- throw new Error( ERROR_MESSAGES.ELEMENT_NOT_FOUND );
79
- }
80
-
81
- const elType = container.model.get( 'elType' );
82
-
83
- if ( ! validElementTypes.includes( elType ) ) {
84
- throw new Error( ERROR_MESSAGES.ELEMENT_NOT_ONE_OF_TYPES( validElementTypes ) );
85
- }
86
-
87
- const element = container.model.toJSON( { remove: [ 'default' ] } ) as V1ElementData;
88
-
89
- if ( element?.isLocked ) {
90
- throw new Error( ERROR_MESSAGES.ELEMENT_IS_LOCKED );
91
- }
92
-
93
- const groupsWithDefaultGroup = groups.indexOf( 'Default' ) >= 0 ? [ ...groups ] : [ 'Default', ...groups ];
94
- const propertyGroups: PropertyGroup[] = groupsWithDefaultGroup.map( ( groupName ) => ( {
95
- id: generateUniqueId( 'group' ),
96
- label: groupName,
97
- props: < string[] >[],
98
- } ) );
99
-
100
- const overridableProps = overridablePropsInput
101
- ? enrichOverridableProps( overridablePropsInput, element, propertyGroups )
102
- : undefined;
103
-
104
- if ( overridableProps ) {
105
- updateElementDataWithOverridableProps( element, overridableProps );
106
- }
107
-
108
- const uid = generateUniqueId( 'component' );
109
-
110
- try {
111
- await apiClient.validate( {
112
- items: [
113
- { uid, title: componentName, elements: [ element ], settings: { overridable_props: overridableProps } },
114
- ],
115
- } );
116
- } catch ( error: unknown ) {
117
- if ( error instanceof AxiosError ) {
118
- throw new Error( error.response?.data.messge );
119
- }
120
- throw new Error( 'Unknown error' );
121
- }
122
-
123
- await createUnpublishedComponent( {
124
- name: componentName,
125
- element,
126
- eventData: null,
127
- uid,
128
- overridableProps,
129
- source: 'mcp_tool',
130
- } );
131
-
132
- return {
133
- status: 'ok' as const,
134
- message: `Component "${ componentName }" created successfully.`,
135
- component_uid: uid,
136
- };
137
- };
138
-
139
- type PropertyGroup = OverridableProps[ 'groups' ][ 'items' ][ string ];
140
-
141
- function enrichOverridableProps(
142
- input: { props: Record< string, { elementId: string; propKey: string; label: string; group?: string } > },
143
- rootElement: V1ElementData,
144
- propertGroups: PropertyGroup[]
145
- ): OverridableProps {
146
- const enrichedProps: OverridableProps[ 'props' ] = {};
147
- const enrichedGroups: OverridableProps[ 'groups' ][ 'items' ] = {};
148
- const defaultGroup = propertGroups.find( ( g ) => g.label === 'Default' );
149
-
150
- if ( ! defaultGroup ) {
151
- throw new Error( 'Internal mcp error: could not generate default group' );
152
- }
153
-
154
- Object.entries( input.props ).forEach( ( [ , prop ] ) => {
155
- const { elementId, propKey, label, group = 'Default' } = prop;
156
- const targetGroup = propertGroups.find( ( g ) => g.label === group ) || defaultGroup;
157
- const targetGroupId = targetGroup.id;
158
- const element = findElementById( rootElement, elementId );
159
-
160
- if ( ! element ) {
161
- throw new Error( `Element with ID "${ elementId }" not found in component` );
162
- }
163
-
164
- const elType = element.elType;
165
- const widgetType = element.widgetType || element.elType;
166
-
167
- // Validate that the propKey exists in the element's schema
168
- const elementType = getElementType( widgetType );
169
-
170
- if ( ! elementType ) {
171
- throw new Error(
172
- `Element type "${ widgetType }" is not atomic or does not have a settings schema. ` +
173
- `Cannot expose property "${ propKey }" for element "${ elementId }".`
174
- );
175
- }
176
-
177
- if ( ! elementType.propsSchema[ propKey ] ) {
178
- const availableProps = Object.keys( elementType.propsSchema ).join( ', ' );
179
- throw new Error(
180
- `Property "${ propKey }" does not exist in element "${ elementId }" (type: ${ widgetType }). ` +
181
- `Available properties: ${ availableProps }`
182
- );
183
- }
184
-
185
- const overrideKey = generateUniqueId( 'prop' );
186
- const originValue = element.settings?.[ propKey ]
187
- ? ( element.settings[ propKey ] as PropValue )
188
- : elementType.propsSchema[ propKey ].default ?? null;
189
-
190
- if ( ! enrichedGroups[ targetGroupId ] ) {
191
- enrichedGroups[ targetGroupId ] = {
192
- id: targetGroupId,
193
- label: targetGroup.label,
194
- props: [],
195
- };
196
- }
197
- enrichedGroups[ targetGroupId ].props.push( overrideKey );
198
-
199
- enrichedProps[ overrideKey ] = {
200
- overrideKey,
201
- label,
202
- elementId,
203
- propKey,
204
- elType,
205
- widgetType,
206
- originValue,
207
- groupId: targetGroupId,
208
- };
209
- } );
210
-
211
- return {
212
- props: enrichedProps,
213
- groups: {
214
- items: enrichedGroups,
215
- order: [ defaultGroup.id ],
216
- },
217
- };
218
- }
219
-
220
- function updateElementDataWithOverridableProps( rootElement: V1ElementData, overridableProps: OverridableProps ) {
221
- Object.values( overridableProps.props ).forEach( ( prop ) => {
222
- const element = findElementById( rootElement, prop.elementId );
223
-
224
- if ( ! element || ! element.settings ) {
225
- return;
226
- }
227
-
228
- element.settings[ prop.propKey ] = {
229
- $$type: 'overridable',
230
- value: {
231
- override_key: prop.overrideKey,
232
- origin_value: prop.originValue,
233
- },
234
- };
235
- } );
236
- }
237
-
238
- function findElementById( root: V1ElementData, targetId: string ): V1ElementData | null {
239
- if ( root.id === targetId ) {
240
- return root;
241
- }
242
-
243
- if ( root.elements ) {
244
- for ( const child of root.elements ) {
245
- const found = findElementById( child, targetId );
246
- if ( found ) {
247
- return found;
248
- }
249
- }
250
- }
251
-
252
- return null;
253
- }
254
-
255
- function getValidElementTypes(): string[] {
256
- const types = getWidgetsCache();
257
-
258
- if ( ! types ) {
259
- return [];
260
- }
261
-
262
- return Object.entries( types ).reduce( ( acc, [ type, value ] ) => {
263
- if ( ! value.atomic_props_schema || ! value.show_in_panel || value.elType === 'widget' ) {
264
- return acc;
265
- }
266
-
267
- acc.push( type );
268
- return acc;
269
- }, [] as string[] );
270
- }
271
-
272
- const generatePrompt = () => {
273
- const saveAsComponentPrompt = toolPrompts( 'save-as-component' );
274
-
275
- saveAsComponentPrompt.description( `
276
- Save an existing element as a reusable component in the Elementor editor.
277
-
278
- # When to use this tool
279
- Use this tool when the user wants to:
280
- - Create a reusable component from an existing element structure
281
- - Make specific child element properties customizable in component instances
282
- - Build a library of reusable design patterns
283
-
284
- # When NOT to use this tool
285
- - Element is already a component (widgetType: 'e-component')
286
- - Element is locked
287
- - Element is not an atomic element (atomic_props_schema is not defined)
288
- - Element elType is a 'widget'
289
-
290
- # **CRITICAL - REQUIRED RESOURCES (Must read before using this tool)**
291
- 1. [${ DOCUMENT_STRUCTURE_URI }]
292
- **MANDATORY** - Required to understand the document structure and identify child elements for overridable properties.
293
- Use this resource to find element IDs and understand the element hierarchy.
294
-
295
- 2. [${ WIDGET_SCHEMA_URI }]
296
- **MANDATORY** - Required to understand which properties are available for each widget type.
297
- Use this to identify available propKeys in the atomic_props_schema for child elements.
298
-
299
- # Instructions - MUST FOLLOW IN ORDER
300
- ## Step 1: Identify the Target Element
301
- 1. Read the [${ DOCUMENT_STRUCTURE_URI }] resource to understand the document structure
302
- 2. Locate the element you want to save as a component by its element_id
303
- 3. Verify the element type is a valid element type
304
- 4. Ensure the element is not locked and is not already a component
305
-
306
- ## Step 2: Define Overridable Properties
307
- Do this step to make child element properties customizable.
308
- Skip that step ONLY if the user explicitly requests to not make any properties customizable.
309
-
310
- 1. **Identify Child Elements**
311
- - Use the [${ DOCUMENT_STRUCTURE_URI }] resource to find all child elements
312
- - Note the elementId and widgetType/elType of each child element you want to customize
313
-
314
- 2. **Find Available Properties**
315
- - Use the [${ WIDGET_SCHEMA_URI }] resource to find the child element's widget type schema
316
- - Review the atomic_props_schema to find available propKeys (ONLY use top-level props)
317
- - Common propKeys include: "text", "url", "tag", "size", etc.
318
- - Use only the top level properties, do not use nested properties.
319
-
320
- 3. **Build the overridable_props Object**
321
- - For each property you want to make overridable, add an entry:
322
- \`{ "elementId": "<child-element-id>", "propKey": "<property-key>", "label": "<user-friendly-name>" }\`
323
- - The label must be unique within the component and should be meaningful to the user (e.g., "Hero Headline", "CTA Button Text")
324
- - Group all entries under the "props" object
325
-
326
- ## Step 3: Execute the Tool
327
- Call the tool with:
328
- - element_id: The ID of the parent element to save as component
329
- - component_name: A descriptive name for the component
330
- - overridable_props: (Optional) The properties configuration from Step 2
331
-
332
- # CONSTRAINTS
333
- - NEVER try to override properties of the parent element itself - ONLY child elements
334
- - NEVER use invalid propKeys - always verify against the widget's atomic_props_schema in [${ WIDGET_SCHEMA_URI }]
335
- - Property keys must exist in the child element's atomic_props_schema
336
- - Element IDs must exist within the target element's children
337
- - When tool execution fails, read the error message and adjust accordingly
338
- - The element being saved must not be inside another component
339
- ` );
340
-
341
- saveAsComponentPrompt.parameter(
342
- 'element_id',
343
- `**MANDATORY** The unique identifier of the element to save as a component.
344
- Use the [${ DOCUMENT_STRUCTURE_URI }] resource to find available element IDs.`
345
- );
346
-
347
- saveAsComponentPrompt.parameter(
348
- 'component_name',
349
- `**MANDATORY** A descriptive name for the new component.
350
- Should be unique and clearly describe the component's purpose (e.g., "Hero Section", "Feature Card").`
351
- );
352
-
353
- saveAsComponentPrompt.parameter(
354
- 'overridable_props',
355
- `**OPTIONAL** Configuration for which child element properties can be customized in component instances.
356
-
357
- Structure:
358
- \`\`\`json
359
- {
360
- "props": {
361
- "<unique-key>": {
362
- "elementId": "<child-element-id>",
363
- "propKey": "<property-key>",
364
- "label": "<user-friendly-name>"
365
- }
366
- }
367
- }
368
- \`\`\`
369
-
370
- To populate this correctly:
371
- 1. Use [${ DOCUMENT_STRUCTURE_URI }] to find child element IDs and their widgetType
372
- 2. Use [${ WIDGET_SCHEMA_URI }] to find the atomic_props_schema for each child element's widgetType
373
- 3. Only include properties you want to be customizable in component instances
374
- 4. Provide a unique, user-friendly label for each property (e.g., "Hero Headline", "CTA Button Text")`
375
- );
376
-
377
- saveAsComponentPrompt.example( `
378
- Basic component without overridable properties:
379
- \`\`\`json
380
- {
381
- "element_id": "abc123",
382
- "component_name": "Hero Section"
383
- }
384
- \`\`\`
385
-
386
- Component with overridable properties:
387
- \`\`\`json
388
- {
389
- "element_id": "abc123",
390
- "component_name": "Feature Card",
391
- "overridable_props": {
392
- "props": {
393
- "heading-text": {
394
- "elementId": "heading-123",
395
- "propKey": "text",
396
- "label": "Card Title",
397
- "group": "Content"
398
- },
399
- "button-text": {
400
- "elementId": "button-456",
401
- "propKey": "text",
402
- "label": "Button Text",
403
- "group": "Content"
404
- },
405
- "button-link": {
406
- "elementId": "button-456",
407
- "propKey": "url",
408
- "label": "Button Link",
409
- "group": "Settings"
410
- }
411
- }
412
- }
413
- }
414
- \`\`\`
415
- ` );
416
-
417
- saveAsComponentPrompt.instruction(
418
- `After successful creation, the component will be available in the components library and can be inserted into any page or template.`
419
- );
420
-
421
- saveAsComponentPrompt.instruction(
422
- `When overridable properties are defined, component instances will show customization controls for those specific properties in the editing panel.`
423
- );
424
-
425
- return saveAsComponentPrompt.prompt();
426
- };
427
-
428
- export const initSaveAsComponentTool = () => {
429
- return getMCPByDomain( 'components' ).addTool( {
430
- name: 'save-as-component',
431
- schema: InputSchema,
432
- outputSchema: OutputSchema,
433
- description: generatePrompt(),
434
- handler: handleSaveAsComponent,
435
- } );
436
- };
@@ -1,121 +0,0 @@
1
- import { getElementType, getSelectedElements, getWidgetsCache } from '@elementor/editor-elements';
2
- import { isProActive } from '@elementor/utils';
3
-
4
- type LegacyWindow = {
5
- $e: {
6
- shortcuts: {
7
- register: ( keys: string, config: ShortcutConfig ) => void;
8
- };
9
- };
10
- elementor: {
11
- getContainer: ( id: string ) => Container;
12
- $preview: Array< { getBoundingClientRect: () => DOMRect } >;
13
- };
14
- };
15
-
16
- type Container = {
17
- isLocked: () => boolean;
18
- model: {
19
- id: string;
20
- toJSON: ( options?: { remove?: string[] } ) => Record< string, unknown >;
21
- };
22
- view: {
23
- el: HTMLElement;
24
- };
25
- };
26
-
27
- type ShortcutConfig = {
28
- callback: () => void;
29
- dependency?: () => boolean;
30
- exclude?: string[];
31
- };
32
-
33
- export const CREATE_COMPONENT_SHORTCUT_KEYS = 'ctrl+shift+k';
34
- const OPEN_SAVE_AS_COMPONENT_FORM_EVENT = 'elementor/editor/open-save-as-component-form';
35
-
36
- type CreateComponentAllowedResult = { allowed: true; container: Container } | { allowed: false; container?: undefined };
37
-
38
- export function isCreateComponentAllowed(): CreateComponentAllowedResult {
39
- const selectedElements = getSelectedElements();
40
-
41
- if ( selectedElements.length !== 1 ) {
42
- return { allowed: false };
43
- }
44
-
45
- const element = selectedElements[ 0 ];
46
- const elementType = getElementType( element.type );
47
-
48
- if ( ! elementType ) {
49
- return { allowed: false };
50
- }
51
-
52
- if ( ! isProActive() ) {
53
- return { allowed: false };
54
- }
55
-
56
- const widgetsCache = getWidgetsCache();
57
- const elementConfig = widgetsCache?.[ element.type ];
58
-
59
- if (
60
- ! elementConfig?.atomic_props_schema ||
61
- ! elementConfig?.show_in_panel ||
62
- elementConfig?.elType === 'widget'
63
- ) {
64
- return { allowed: false };
65
- }
66
-
67
- const legacyWindow = window as unknown as LegacyWindow;
68
- const container = legacyWindow.elementor.getContainer( element.id );
69
-
70
- if ( ! container || container.isLocked() ) {
71
- return { allowed: false };
72
- }
73
-
74
- return { allowed: true, container };
75
- }
76
-
77
- export function triggerCreateComponentForm( container: Container ): void {
78
- const legacyWindow = window as unknown as LegacyWindow;
79
- const elementRect = container.view.el.getBoundingClientRect();
80
- const iframeRect = legacyWindow.elementor.$preview[ 0 ].getBoundingClientRect();
81
-
82
- const anchorPosition = {
83
- left: iframeRect.left + elementRect.left + elementRect.width / 2,
84
- top: iframeRect.top + elementRect.top,
85
- };
86
-
87
- window.dispatchEvent(
88
- new CustomEvent( OPEN_SAVE_AS_COMPONENT_FORM_EVENT, {
89
- detail: {
90
- element: container.model.toJSON( { remove: [ 'default' ] } ),
91
- anchorPosition,
92
- options: {
93
- trigger: 'keyboard',
94
- location: 'canvas',
95
- secondaryLocation: 'canvasElement',
96
- },
97
- },
98
- } )
99
- );
100
- }
101
-
102
- export function initCreateComponentShortcut(): void {
103
- const legacyWindow = window as unknown as LegacyWindow;
104
-
105
- legacyWindow.$e.shortcuts.register( CREATE_COMPONENT_SHORTCUT_KEYS, {
106
- callback: () => {
107
- const result = isCreateComponentAllowed();
108
-
109
- if ( ! result.allowed ) {
110
- return;
111
- }
112
-
113
- triggerCreateComponentForm( result.container );
114
- },
115
- dependency: () => {
116
- const result = isCreateComponentAllowed();
117
- return result.allowed;
118
- },
119
- exclude: [ 'input' ],
120
- } );
121
- }
@@ -1,53 +0,0 @@
1
- import { componentsActions } from '../../../store/dispatchers';
2
- import { componentsSelectors } from '../../../store/selectors';
3
- import { type ComponentId, type OverridablePropsGroup } from '../../../types';
4
- import { type Source, trackComponentEvent } from '../../../utils/tracking';
5
-
6
- type AddGroupParams = {
7
- componentId: ComponentId;
8
- groupId: string;
9
- label: string;
10
- source: Source;
11
- };
12
-
13
- export function addOverridableGroup( {
14
- componentId,
15
- groupId,
16
- label,
17
- source,
18
- }: AddGroupParams ): OverridablePropsGroup | undefined {
19
- const currentComponent = componentsSelectors.getCurrentComponent();
20
-
21
- const overridableProps = componentsSelectors.getOverridableProps( componentId );
22
-
23
- if ( ! overridableProps ) {
24
- return;
25
- }
26
-
27
- const newGroup: OverridablePropsGroup = {
28
- id: groupId,
29
- label,
30
- props: [],
31
- };
32
-
33
- componentsActions.setOverridableProps( componentId, {
34
- ...overridableProps,
35
- groups: {
36
- ...overridableProps.groups,
37
- items: {
38
- ...overridableProps.groups.items,
39
- [ groupId ]: newGroup,
40
- },
41
- order: [ groupId, ...overridableProps.groups.order ],
42
- },
43
- } );
44
-
45
- trackComponentEvent( {
46
- action: 'propertiesGroupCreated',
47
- source,
48
- component_uid: currentComponent?.uid,
49
- group_name: label,
50
- } );
51
-
52
- return newGroup;
53
- }
@@ -1,18 +0,0 @@
1
- import { setDocumentModifiedStatus } from '@elementor/editor-documents';
2
- import { type NotificationData, notify } from '@elementor/editor-notifications';
3
- import { __ } from '@wordpress/i18n';
4
-
5
- import { componentsActions } from '../../../store/dispatchers';
6
-
7
- const successNotification = ( componentId: number, componentName: string ): NotificationData => ( {
8
- type: 'success',
9
- /* translators: %s: component name */
10
- message: __( 'Successfully deleted component %s', 'elementor' ).replace( '%s', componentName ),
11
- id: `success-archived-components-notification-${ componentId }`,
12
- } );
13
-
14
- export const archiveComponent = ( componentId: number, componentName: string ) => {
15
- componentsActions.archive( componentId );
16
- setDocumentModifiedStatus( true );
17
- notify( successNotification( componentId, componentName ) );
18
- };