@elementor/editor-canvas 3.35.0-470 → 3.35.0-471
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/dist/index.js +459 -511
- package/dist/index.mjs +448 -496
- package/package.json +18 -18
- package/src/composition-builder/composition-builder.ts +233 -0
- package/src/mcp/mcp-description.ts +99 -108
- package/src/mcp/resources/widgets-schema-resource.ts +1 -1
- package/src/mcp/tools/build-composition/prompt.ts +104 -280
- package/src/mcp/tools/build-composition/schema.ts +0 -1
- package/src/mcp/tools/build-composition/tool.ts +49 -125
- package/src/mcp/utils/do-update-element-property.ts +12 -3
- package/src/mcp/utils/validate-input.ts +9 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-canvas",
|
|
3
3
|
"description": "Elementor Editor Canvas",
|
|
4
|
-
"version": "3.35.0-
|
|
4
|
+
"version": "3.35.0-471",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,24 +37,24 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "3.35.0-
|
|
41
|
-
"@elementor/editor-controls": "3.35.0-
|
|
42
|
-
"@elementor/editor-documents": "3.35.0-
|
|
43
|
-
"@elementor/editor-elements": "3.35.0-
|
|
44
|
-
"@elementor/editor-interactions": "3.35.0-
|
|
45
|
-
"@elementor/editor-mcp": "3.35.0-
|
|
46
|
-
"@elementor/editor-notifications": "3.35.0-
|
|
47
|
-
"@elementor/editor-props": "3.35.0-
|
|
48
|
-
"@elementor/editor-responsive": "3.35.0-
|
|
49
|
-
"@elementor/editor-styles": "3.35.0-
|
|
50
|
-
"@elementor/editor-styles-repository": "3.35.0-
|
|
51
|
-
"@elementor/editor-ui": "3.35.0-
|
|
52
|
-
"@elementor/editor-v1-adapters": "3.35.0-
|
|
53
|
-
"@elementor/schema": "3.35.0-
|
|
54
|
-
"@elementor/twing": "3.35.0-
|
|
40
|
+
"@elementor/editor": "3.35.0-471",
|
|
41
|
+
"@elementor/editor-controls": "3.35.0-471",
|
|
42
|
+
"@elementor/editor-documents": "3.35.0-471",
|
|
43
|
+
"@elementor/editor-elements": "3.35.0-471",
|
|
44
|
+
"@elementor/editor-interactions": "3.35.0-471",
|
|
45
|
+
"@elementor/editor-mcp": "3.35.0-471",
|
|
46
|
+
"@elementor/editor-notifications": "3.35.0-471",
|
|
47
|
+
"@elementor/editor-props": "3.35.0-471",
|
|
48
|
+
"@elementor/editor-responsive": "3.35.0-471",
|
|
49
|
+
"@elementor/editor-styles": "3.35.0-471",
|
|
50
|
+
"@elementor/editor-styles-repository": "3.35.0-471",
|
|
51
|
+
"@elementor/editor-ui": "3.35.0-471",
|
|
52
|
+
"@elementor/editor-v1-adapters": "3.35.0-471",
|
|
53
|
+
"@elementor/schema": "3.35.0-471",
|
|
54
|
+
"@elementor/twing": "3.35.0-471",
|
|
55
55
|
"@elementor/ui": "1.36.17",
|
|
56
|
-
"@elementor/utils": "3.35.0-
|
|
57
|
-
"@elementor/wp-media": "3.35.0-
|
|
56
|
+
"@elementor/utils": "3.35.0-471",
|
|
57
|
+
"@elementor/wp-media": "3.35.0-471",
|
|
58
58
|
"@floating-ui/react": "^0.27.5",
|
|
59
59
|
"@wordpress/i18n": "^5.13.0"
|
|
60
60
|
},
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createElement,
|
|
3
|
+
generateElementId,
|
|
4
|
+
getContainer,
|
|
5
|
+
getWidgetsCache,
|
|
6
|
+
type V1Element,
|
|
7
|
+
} from '@elementor/editor-elements';
|
|
8
|
+
import { type z } from '@elementor/schema';
|
|
9
|
+
|
|
10
|
+
import { doUpdateElementProperty } from '../mcp/utils/do-update-element-property';
|
|
11
|
+
import { validateInput } from '../mcp/utils/validate-input';
|
|
12
|
+
|
|
13
|
+
type AnyValue = z.infer< z.ZodTypeAny >;
|
|
14
|
+
type AnyConfig = Record< string, Record< string, AnyValue > >;
|
|
15
|
+
|
|
16
|
+
type API = {
|
|
17
|
+
createElement: typeof createElement;
|
|
18
|
+
getWidgetsCache: typeof getWidgetsCache;
|
|
19
|
+
generateElementId: typeof generateElementId;
|
|
20
|
+
getContainer: typeof getContainer;
|
|
21
|
+
doUpdateElementProperty: typeof doUpdateElementProperty;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type CtorOptions = {
|
|
25
|
+
xml: Document;
|
|
26
|
+
api?: Partial< API >;
|
|
27
|
+
elementConfig?: AnyConfig;
|
|
28
|
+
stylesConfig?: AnyConfig;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export class CompositionBuilder {
|
|
32
|
+
private elementConfig: Record< string, Record< string, AnyValue > > = {};
|
|
33
|
+
private elementStylesConfig: Record< string, Record< string, AnyValue > > = {};
|
|
34
|
+
private rootContainers: V1Element[] = [];
|
|
35
|
+
private containerElements: string[] = [];
|
|
36
|
+
private api: API = {
|
|
37
|
+
createElement,
|
|
38
|
+
getWidgetsCache,
|
|
39
|
+
generateElementId,
|
|
40
|
+
getContainer,
|
|
41
|
+
doUpdateElementProperty,
|
|
42
|
+
};
|
|
43
|
+
private xml: Document;
|
|
44
|
+
|
|
45
|
+
public static fromXMLString( xmlString: string, api: Partial< API > = {} ): CompositionBuilder {
|
|
46
|
+
const parser = new DOMParser();
|
|
47
|
+
const xmlDoc = parser.parseFromString( xmlString, 'application/xml' );
|
|
48
|
+
const errorNode = xmlDoc.querySelector( 'parsererror' );
|
|
49
|
+
if ( errorNode ) {
|
|
50
|
+
throw new Error( 'Failed to parse XML string: ' + errorNode.textContent );
|
|
51
|
+
}
|
|
52
|
+
return new CompositionBuilder( {
|
|
53
|
+
xml: xmlDoc,
|
|
54
|
+
api,
|
|
55
|
+
} );
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
constructor( opts: CtorOptions ) {
|
|
59
|
+
const { api = {}, elementConfig = {}, stylesConfig = {}, xml } = opts;
|
|
60
|
+
this.xml = xml;
|
|
61
|
+
Object.assign( this.api, api );
|
|
62
|
+
this.setElementConfig( elementConfig );
|
|
63
|
+
this.setStylesConfig( stylesConfig );
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
setElementConfig( config: Record< string, Record< string, AnyValue > > ) {
|
|
67
|
+
this.elementConfig = config;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setStylesConfig( config: Record< string, Record< string, AnyValue > > ) {
|
|
71
|
+
this.elementStylesConfig = config;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getXML() {
|
|
75
|
+
return this.xml;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private iterateBuild( node: Element, containerElement: V1Element, childIndex: number ) {
|
|
79
|
+
const elementTag = node.tagName;
|
|
80
|
+
const isContainer = this.containerElements.includes( elementTag );
|
|
81
|
+
const parentElType = containerElement.model.get( 'elType' );
|
|
82
|
+
let targetContainerId =
|
|
83
|
+
parentElType === 'e-tabs'
|
|
84
|
+
? containerElement.children?.[ 1 ].children?.[ childIndex ]?.id || containerElement.children?.[ 1 ].id
|
|
85
|
+
: containerElement.id;
|
|
86
|
+
if ( ! targetContainerId ) {
|
|
87
|
+
targetContainerId = containerElement.id;
|
|
88
|
+
}
|
|
89
|
+
const newElement = isContainer
|
|
90
|
+
? this.api.createElement( {
|
|
91
|
+
containerId: targetContainerId,
|
|
92
|
+
model: {
|
|
93
|
+
elType: elementTag,
|
|
94
|
+
id: generateElementId(),
|
|
95
|
+
},
|
|
96
|
+
options: { useHistory: false },
|
|
97
|
+
} )
|
|
98
|
+
: this.api.createElement( {
|
|
99
|
+
containerId: targetContainerId,
|
|
100
|
+
model: {
|
|
101
|
+
elType: 'widget',
|
|
102
|
+
widgetType: elementTag,
|
|
103
|
+
id: generateElementId(),
|
|
104
|
+
},
|
|
105
|
+
options: { useHistory: false },
|
|
106
|
+
} );
|
|
107
|
+
if ( containerElement.id === 'document' ) {
|
|
108
|
+
this.rootContainers.push( newElement );
|
|
109
|
+
}
|
|
110
|
+
node.setAttribute( 'id', newElement.id );
|
|
111
|
+
let currentChild = 0;
|
|
112
|
+
for ( const childNode of Array.from( node.children ) ) {
|
|
113
|
+
this.iterateBuild( childNode, newElement, currentChild );
|
|
114
|
+
currentChild++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private findSchemaForNode( node: Element ) {
|
|
119
|
+
const widgetsCache = this.api.getWidgetsCache() || {};
|
|
120
|
+
const widgetType = node.tagName;
|
|
121
|
+
const widgetData = widgetsCache[ widgetType ]?.atomic_props_schema;
|
|
122
|
+
return widgetData || null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private matchNodeByConfigId( configId: string ) {
|
|
126
|
+
const node = this.xml.querySelector( `[configuration-id="${ configId }"]` );
|
|
127
|
+
if ( ! node ) {
|
|
128
|
+
throw new Error( `Configuration id "${ configId }" does not have target node.` );
|
|
129
|
+
}
|
|
130
|
+
const id = node.getAttribute( 'id' );
|
|
131
|
+
if ( ! id ) {
|
|
132
|
+
throw new Error( `Node with configuration id "${ configId }" does not have element id.` );
|
|
133
|
+
}
|
|
134
|
+
const element = this.api.getContainer( id );
|
|
135
|
+
if ( ! element ) {
|
|
136
|
+
throw new Error( `Element with id "${ id }" not found but should exist.` );
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
element,
|
|
140
|
+
node,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
applyStyles() {
|
|
145
|
+
const errors: string[] = [];
|
|
146
|
+
const invalidStyles: Record< string, string[] > = {};
|
|
147
|
+
const validStylesPropValues: Record< string, AnyValue > = {};
|
|
148
|
+
for ( const [ styleId, styleConfig ] of Object.entries( this.elementStylesConfig ) ) {
|
|
149
|
+
const { element, node } = this.matchNodeByConfigId( styleId );
|
|
150
|
+
for ( const [ styleName, stylePropValue ] of Object.entries( styleConfig ) ) {
|
|
151
|
+
const { valid, errors: validationErrors } = validateInput.validateStyles( {
|
|
152
|
+
[ styleName ]: stylePropValue,
|
|
153
|
+
} );
|
|
154
|
+
if ( ! valid ) {
|
|
155
|
+
if ( styleConfig.$intention ) {
|
|
156
|
+
invalidStyles[ element.id ] = invalidStyles[ element.id ] || [];
|
|
157
|
+
invalidStyles[ element.id ].push( styleName );
|
|
158
|
+
}
|
|
159
|
+
errors.push( ...( validationErrors || [] ) );
|
|
160
|
+
} else {
|
|
161
|
+
validStylesPropValues[ styleName ] = stylePropValue;
|
|
162
|
+
}
|
|
163
|
+
this.api.doUpdateElementProperty( {
|
|
164
|
+
elementId: element.id,
|
|
165
|
+
propertyName: '_styles',
|
|
166
|
+
propertyValue: validStylesPropValues,
|
|
167
|
+
elementType: node.tagName,
|
|
168
|
+
} );
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
errors,
|
|
173
|
+
invalidStyles,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
applyConfigs() {
|
|
178
|
+
const errors: string[] = [];
|
|
179
|
+
for ( const [ configId, config ] of Object.entries( this.elementConfig ) ) {
|
|
180
|
+
const { element, node } = this.matchNodeByConfigId( configId );
|
|
181
|
+
const propSchema = this.findSchemaForNode( node );
|
|
182
|
+
const result = validateInput.validateProps( propSchema, config );
|
|
183
|
+
if ( ! result.valid && result.errors?.length ) {
|
|
184
|
+
errors.push( ...result.errors );
|
|
185
|
+
} else {
|
|
186
|
+
for ( const [ propertyName, propertyValue ] of Object.entries( config ) ) {
|
|
187
|
+
try {
|
|
188
|
+
this.api.doUpdateElementProperty( {
|
|
189
|
+
elementId: element.id,
|
|
190
|
+
propertyName,
|
|
191
|
+
propertyValue,
|
|
192
|
+
elementType: node.tagName,
|
|
193
|
+
} );
|
|
194
|
+
} catch ( error ) {
|
|
195
|
+
errors.push( ( error as Error ).message );
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return errors;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
build( rootContainer: V1Element ) {
|
|
204
|
+
const widgetsCache = this.api.getWidgetsCache() || {};
|
|
205
|
+
const CONTAINER_ELEMENTS = Object.values( widgetsCache )
|
|
206
|
+
.filter( ( widget ) => widget.meta?.is_container )
|
|
207
|
+
.map( ( widget ) => widget.elType )
|
|
208
|
+
.filter( ( x ) => typeof x === 'string' );
|
|
209
|
+
this.containerElements = CONTAINER_ELEMENTS;
|
|
210
|
+
new Set( this.xml.querySelectorAll( '*' ) ).forEach( ( node ) => {
|
|
211
|
+
if ( ! widgetsCache[ node.tagName ] ) {
|
|
212
|
+
throw new Error( `Unknown widget type: ${ node.tagName }` );
|
|
213
|
+
}
|
|
214
|
+
} );
|
|
215
|
+
|
|
216
|
+
const children = Array.from( this.xml.children );
|
|
217
|
+
let currentChild = 0;
|
|
218
|
+
for ( const childNode of children ) {
|
|
219
|
+
this.iterateBuild( childNode, rootContainer, currentChild );
|
|
220
|
+
currentChild++;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const { errors: styleErrors, invalidStyles } = this.applyStyles();
|
|
224
|
+
const configErrors = this.applyConfigs();
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
configErrors,
|
|
228
|
+
styleErrors,
|
|
229
|
+
invalidStyles,
|
|
230
|
+
rootContainers: [ ...this.rootContainers ],
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -2,121 +2,112 @@ import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from './resources/widgets-schema-
|
|
|
2
2
|
|
|
3
3
|
const ELEMENT_SCHEMA_URI = WIDGET_SCHEMA_URI.replace( '{widgetType}', 'element-schema' );
|
|
4
4
|
|
|
5
|
-
export const mcpDescription = `Canvas MCP
|
|
6
|
-
This MCP enables
|
|
5
|
+
export const mcpDescription = `Elementor Canvas MCP
|
|
6
|
+
This MCP enables creation, configuration, and styling of elements on the Elementor canvas using the build_composition tool.
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
- Elementor presents global classes. Each global class is a a set of styles that can be applied to multiple elements. This allows for consistent styling across the design.
|
|
10
|
-
- Elementor also presents global variables, which can be colors, sizes or fonts. These variables can be used in any element's styles, or global classes, allowing for easy updates and consistency across the design.
|
|
11
|
-
- All data is stored in a PropValue structure, which is a wrapper for elementor values. The PropValues are derived from an internal "PropType" schema, which defines the structure and types of the values.
|
|
8
|
+
# Core Concepts
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
## PropValues Structure
|
|
11
|
+
All data in Elementor uses PropValues - a typed wrapper for values:
|
|
14
12
|
\`\`\`json
|
|
15
13
|
{
|
|
16
|
-
$$type:
|
|
17
|
-
value:
|
|
14
|
+
"$$type": "the-prop-type-schema-kind",
|
|
15
|
+
"value": "the-actual-value-as-defined-for-the-propType"
|
|
18
16
|
}
|
|
19
17
|
\`\`\`
|
|
20
|
-
The
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
18
|
+
The \`$$type\` defines how Elementor interprets the value. Providing the correct \`$$type\` is critical - incorrect types will be rejected.
|
|
19
|
+
|
|
20
|
+
## Design System Resources
|
|
21
|
+
- **Global Variables**: Reusable colors, sizes, and fonts (\`elementor://global-variables\`)
|
|
22
|
+
- **Global Classes**: Reusable style sets that can be applied to elements (\`elementor://global-classes\`)
|
|
23
|
+
- **Widget Schemas**: Configuration options for each widget type (\`${ WIDGET_SCHEMA_URI }\`)
|
|
24
|
+
- **Style Schema**: Common styles shared across all widgets and containers (\`${ STYLE_SCHEMA_URI }\`)
|
|
25
|
+
|
|
26
|
+
# Building Compositions with build_composition
|
|
27
|
+
|
|
28
|
+
The \`build_composition\` tool is the primary way to create elements. It accepts structure (XML), configuration, and styling in a single operation.
|
|
29
|
+
|
|
30
|
+
## Complete Workflow
|
|
31
|
+
|
|
32
|
+
### 1. Parse User Requirements
|
|
33
|
+
Understand what needs to be built: structure, content, and styling.
|
|
34
|
+
|
|
35
|
+
### 2. Check Global Resources FIRST
|
|
36
|
+
Always check existing resources before building:
|
|
37
|
+
- List \`elementor://global-variables\` for available variables (colors, sizes, fonts)
|
|
38
|
+
- List \`elementor://global-classes\` for available style sets
|
|
39
|
+
- **Always prefer using existing global resources over creating inline styles**
|
|
40
|
+
|
|
41
|
+
### 3. Retrieve Widget Schemas
|
|
42
|
+
For each widget you'll use:
|
|
43
|
+
- List \`${ WIDGET_SCHEMA_URI }\` to see available widgets
|
|
44
|
+
- Retrieve configuration schema from \`${ ELEMENT_SCHEMA_URI }\` for each widget
|
|
45
|
+
- Check the \`llm_guidance\` property to understand if a widget is a container (can have children)
|
|
46
|
+
|
|
47
|
+
### 4. Build XML Structure
|
|
48
|
+
Create valid XML with configuration-ids:
|
|
49
|
+
- Each element must have a unique \`configuration-id\` attribute
|
|
50
|
+
- No text nodes, classes, or IDs in XML - structure only
|
|
51
|
+
- Example:
|
|
52
|
+
\`\`\`xml
|
|
53
|
+
<e-container configuration-id="container-1">
|
|
54
|
+
<e-heading configuration-id="heading-1" />
|
|
55
|
+
<e-text configuration-id="text-1" />
|
|
56
|
+
</e-container>
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
### 5. Create elementConfig
|
|
60
|
+
Map each configuration-id to its widget properties using PropValues:
|
|
61
|
+
- Use correct \`$$type\` matching the widget's schema
|
|
62
|
+
- Use global variables in PropValues where applicable
|
|
63
|
+
- Example:
|
|
64
|
+
\`\`\`json
|
|
65
|
+
{
|
|
66
|
+
"heading-1": {
|
|
67
|
+
"text": { "$$type": "string", "value": "Welcome" },
|
|
68
|
+
"tag": { "$$type": "string", "value": "h1" }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
### 6. Create stylesConfig
|
|
74
|
+
Map each configuration-id to style PropValues from \`${ STYLE_SCHEMA_URI }\`:
|
|
75
|
+
- Use global variables for colors, sizes, and fonts
|
|
76
|
+
- Example using global variable:
|
|
78
77
|
\`\`\`json
|
|
79
|
-
{
|
|
78
|
+
{
|
|
79
|
+
"heading-1": {
|
|
80
|
+
"color": { "$$type": "global-color-variable", "value": "primary-color-id" },
|
|
81
|
+
"font-size": { "$$type": "size", "value": "2rem" }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
80
84
|
\`\`\`
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- Avoid names that reflect colors or values, use only purpose-based names.
|
|
110
|
-
|
|
111
|
-
# Advanced operations
|
|
112
|
-
You are encouraged to run multiple times multiple tools to achieve the desired result.
|
|
113
|
-
|
|
114
|
-
An Example scenario of creating fully styled composition:
|
|
115
|
-
1. Get the list of availble widgets using dynamic resource [${ WIDGET_SCHEMA_URI }]
|
|
116
|
-
2. For each element to create, retreive its configuration schema from [${ WIDGET_SCHEMA_URI }/element-name]
|
|
117
|
-
3. Get the list of available global classes using the always up-to-date resource
|
|
118
|
-
4. Get the list of available global variables using the dynamic resource
|
|
119
|
-
5. Build a composition using the "build-composition" tool, providing the structure, configuration and styles for each element. You may want to style the elements later.
|
|
120
|
-
6. Check you work: as you have the created IDs from the build-composition response, you can retreive each element configuration using the "get-element-configuration-values" tool.
|
|
121
|
-
7. If needed, update styles using the "configure-element" tool, providing only the styles or widget's properties to update.
|
|
86
|
+
### 7. Execute build_composition
|
|
87
|
+
Call the tool with your XML structure, elementConfig, and stylesConfig. The response will contain the created element IDs.
|
|
88
|
+
At the response you will also find llm_instructions for you to do afterwards, read and follow them!
|
|
89
|
+
|
|
90
|
+
## Key Points
|
|
91
|
+
|
|
92
|
+
- **PropValue Types**: Arrays that accept union types are typed as mixed arrays
|
|
93
|
+
- **Visual Sizing**: Widget sizes MUST be defined in stylesConfig. Widget properties like image "size" control resolution, not visual appearance
|
|
94
|
+
- **Global Variables**: Reference by ID in PropValues (e.g., \`{ "$$type": "global-color-variable", "value": "variable-id" }\`)
|
|
95
|
+
- **Naming Conventions**: Use meaningful, purpose-based names (e.g., "primary-button", "heading-large"), not value-based names (e.g., "blue-style", "20px-padding")
|
|
96
|
+
|
|
97
|
+
## Example: e-image PropValue Structure
|
|
98
|
+
\`\`\`json
|
|
99
|
+
{
|
|
100
|
+
"$$type": "image",
|
|
101
|
+
"value": {
|
|
102
|
+
"src": {
|
|
103
|
+
"$$type": "image-src",
|
|
104
|
+
"value": {
|
|
105
|
+
"url": { "$$type": "url", "value": "https://example.com/image.jpg" }
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"size": { "$$type": "string", "value": "full" }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
\`\`\`
|
|
112
|
+
Note: The "size" property controls image resolution/loading, not visual size. Set visual dimensions in stylesConfig.
|
|
122
113
|
`;
|
|
@@ -38,7 +38,7 @@ The css string must follow standard CSS syntax, with properties and values separ
|
|
|
38
38
|
'styles-schema',
|
|
39
39
|
new ResourceTemplate( STYLE_SCHEMA_URI, {
|
|
40
40
|
list: () => {
|
|
41
|
-
const categories = [ ...Object.keys( getStylesSchema() ) ];
|
|
41
|
+
const categories = [ ...Object.keys( getStylesSchema() ) ].filter( ( category ) => category !== 'all' );
|
|
42
42
|
return {
|
|
43
43
|
resources: categories.map( ( category ) => ( {
|
|
44
44
|
uri: `elementor://styles/schema/${ category }`,
|