@elementor/editor-canvas 3.33.0-291 → 3.33.0-293
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 +157 -57
- package/dist/index.mjs +150 -46
- package/package.json +17 -17
- package/src/mcp/canvas-mcp.ts +2 -0
- package/src/mcp/mcp-description.ts +18 -8
- package/src/mcp/resources/widgets-schema-resource.ts +22 -3
- package/src/mcp/tools/build-composition/prompt.ts +5 -2
- package/src/mcp/tools/build-composition/tool.ts +20 -15
- package/src/mcp/tools/configure-element/prompt.ts +6 -3
- package/src/mcp/tools/get-element-config/tool.ts +75 -0
- package/src/mcp/utils/do-update-element-property.ts +17 -3
package/dist/index.mjs
CHANGED
|
@@ -441,10 +441,10 @@ var getMultiPropsValue = (multiProps) => {
|
|
|
441
441
|
// src/renderers/create-props-resolver.ts
|
|
442
442
|
var TRANSFORM_DEPTH_LIMIT = 3;
|
|
443
443
|
function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
|
|
444
|
-
async function resolve({ props, schema, signal }) {
|
|
445
|
-
|
|
444
|
+
async function resolve({ props, schema: schema2, signal }) {
|
|
445
|
+
schema2 = schema2 ?? initialSchema;
|
|
446
446
|
const promises = Promise.all(
|
|
447
|
-
Object.entries(
|
|
447
|
+
Object.entries(schema2).map(async ([key, type]) => {
|
|
448
448
|
const value = props[key] ?? type.default;
|
|
449
449
|
const transformed = await transform({ value, key, type, signal });
|
|
450
450
|
onPropResolve?.({ key, value: transformed });
|
|
@@ -1112,11 +1112,11 @@ function getVal2(val) {
|
|
|
1112
1112
|
var transformOriginTransformer = createTransformer((value) => {
|
|
1113
1113
|
const x = getVal2(value.x);
|
|
1114
1114
|
const y = getVal2(value.y);
|
|
1115
|
-
const
|
|
1116
|
-
if (x === DEFAULT_XY && y === DEFAULT_XY &&
|
|
1115
|
+
const z4 = getVal2(value.z);
|
|
1116
|
+
if (x === DEFAULT_XY && y === DEFAULT_XY && z4 === DEFAULT_Z) {
|
|
1117
1117
|
return null;
|
|
1118
1118
|
}
|
|
1119
|
-
return `${x} ${y} ${
|
|
1119
|
+
return `${x} ${y} ${z4}`;
|
|
1120
1120
|
});
|
|
1121
1121
|
|
|
1122
1122
|
// src/transformers/styles/transform-rotate-transformer.ts
|
|
@@ -1467,8 +1467,24 @@ import {
|
|
|
1467
1467
|
import { getStylesSchema as getStylesSchema2 } from "@elementor/editor-styles";
|
|
1468
1468
|
var WIDGET_SCHEMA_URI = "elementor://widgets/schema/{widgetType}";
|
|
1469
1469
|
var STYLE_SCHEMA_URI = "elementor://styles/schema/{category}";
|
|
1470
|
+
var BEST_PRACTICES_URI = "elementor://styles/best-practices";
|
|
1470
1471
|
var initWidgetsSchemaResource = (reg) => {
|
|
1471
1472
|
const { mcpServer } = reg;
|
|
1473
|
+
mcpServer.resource("styles-best-practices", BEST_PRACTICES_URI, async () => {
|
|
1474
|
+
return {
|
|
1475
|
+
contents: [
|
|
1476
|
+
{
|
|
1477
|
+
uri: BEST_PRACTICES_URI,
|
|
1478
|
+
text: `# Styling best practices
|
|
1479
|
+
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
1480
|
+
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema, or in custom_css, depends on your needs.
|
|
1481
|
+
|
|
1482
|
+
When applicable for styles, use the "custom_css" property for free-form CSS styling. This property accepts a string of CSS rules that will be applied directly to the element.
|
|
1483
|
+
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.`
|
|
1484
|
+
}
|
|
1485
|
+
]
|
|
1486
|
+
};
|
|
1487
|
+
});
|
|
1472
1488
|
mcpServer.resource(
|
|
1473
1489
|
"styles-schema",
|
|
1474
1490
|
new ResourceTemplate(STYLE_SCHEMA_URI, {
|
|
@@ -1545,9 +1561,9 @@ var initWidgetsSchemaResource = (reg) => {
|
|
|
1545
1561
|
Schema.propTypeToJsonSchema(propType)
|
|
1546
1562
|
])
|
|
1547
1563
|
);
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1564
|
+
Schema.nonConfigurablePropKeys.forEach((key) => {
|
|
1565
|
+
delete asJson[key];
|
|
1566
|
+
});
|
|
1551
1567
|
return {
|
|
1552
1568
|
contents: [
|
|
1553
1569
|
{
|
|
@@ -1620,7 +1636,11 @@ import {
|
|
|
1620
1636
|
updateElementSettings,
|
|
1621
1637
|
updateElementStyle
|
|
1622
1638
|
} from "@elementor/editor-elements";
|
|
1623
|
-
import {
|
|
1639
|
+
import {
|
|
1640
|
+
getPropSchemaFromCache,
|
|
1641
|
+
Schema as Schema2,
|
|
1642
|
+
stringPropTypeUtil
|
|
1643
|
+
} from "@elementor/editor-props";
|
|
1624
1644
|
import { getStylesSchema as getStylesSchema3 } from "@elementor/editor-styles";
|
|
1625
1645
|
function resolvePropValue(value, forceKey) {
|
|
1626
1646
|
return Schema2.adjustLlmPropValueSchema(value, forceKey);
|
|
@@ -1647,8 +1667,12 @@ var doUpdateElementProperty = (params) => {
|
|
|
1647
1667
|
Object.keys(propertyMapValue).forEach((stylePropName) => {
|
|
1648
1668
|
const propertyRawSchema = styleSchema[stylePropName];
|
|
1649
1669
|
if (stylePropName === "custom_css") {
|
|
1670
|
+
let customCssValue = propertyMapValue[stylePropName];
|
|
1671
|
+
if (typeof customCssValue === "object") {
|
|
1672
|
+
customCssValue = stringPropTypeUtil.extract(customCssValue) || customCssValue?.value || "";
|
|
1673
|
+
}
|
|
1650
1674
|
customCss = {
|
|
1651
|
-
raw: btoa(
|
|
1675
|
+
raw: btoa(customCssValue)
|
|
1652
1676
|
};
|
|
1653
1677
|
return;
|
|
1654
1678
|
}
|
|
@@ -1670,7 +1694,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
1670
1694
|
if (!localStyle) {
|
|
1671
1695
|
createElementStyle({
|
|
1672
1696
|
elementId,
|
|
1673
|
-
custom_css: customCss,
|
|
1697
|
+
...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
|
|
1674
1698
|
classesProp: "classes",
|
|
1675
1699
|
label: "local",
|
|
1676
1700
|
meta: {
|
|
@@ -1689,6 +1713,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
1689
1713
|
breakpoint: "desktop",
|
|
1690
1714
|
state: null
|
|
1691
1715
|
},
|
|
1716
|
+
...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
|
|
1692
1717
|
props: {
|
|
1693
1718
|
...transformedStyleValues
|
|
1694
1719
|
}
|
|
@@ -1753,6 +1778,7 @@ Prefer this tool over any other tool for building HTML structure, unless you are
|
|
|
1753
1778
|
For easy execution, USE ONLY "custom_css" category from the styles schema resource to apply styles.
|
|
1754
1779
|
5. Ensure the XML structure is valid and parsable.
|
|
1755
1780
|
6. Do not add any attribute nodes, classes, id's, and no text nodes allowed, for inline styles prefer USE the [${CUSTOM_CSS_URI}] resource for custom_css.
|
|
1781
|
+
Layout properties, such as margin, padding, align, etc. must be applied using the [${STYLE_SCHEMA_URI}] PropValues.
|
|
1756
1782
|
7. Some elements allow nesting of other elements, and most of the DO NOT. The allowed elements that can have nested children are "e-div-block" and "e-flexbox".
|
|
1757
1783
|
8. Make sure that non-container elements do NOT have any nested elements.
|
|
1758
1784
|
9. Unsless the user specifically requires structure only, BE EXPRESSIVE AND VISUALLY CREATIVE AS POSSIBLE IN APPLYING STYLE CONFIGURATION.
|
|
@@ -1767,6 +1793,8 @@ Prefer this tool over any other tool for building HTML structure, unless you are
|
|
|
1767
1793
|
- Always aim for a clean and professional look that aligns with modern design principles.
|
|
1768
1794
|
- When you are required to create placeholder texts, use texts that have a length that fits the goal. When long texts are required, use longer placeholder texts. When the user specifies exact texts, use the exact texts.
|
|
1769
1795
|
- Image size does not affect the actual size on the screen, only which quality to use. If you use images, specifically add _styles PropValues to define the image sizes.
|
|
1796
|
+
- Attempt to use layout, margin, padding, size properties from the styles schema and not the custom_css, unless necessary.
|
|
1797
|
+
- If your elements library is limited, encourage use of nesting containers to achieve complex layouts.
|
|
1770
1798
|
|
|
1771
1799
|
# CONSTRAINTS
|
|
1772
1800
|
When a tool execution fails, retry up to 10 more times, read the error message carefully, and adjust the XML structure or the configurations accordingly.
|
|
@@ -1798,7 +1826,7 @@ A Heading and a button inside a flexbox
|
|
|
1798
1826
|
"value": "section"
|
|
1799
1827
|
},
|
|
1800
1828
|
},
|
|
1801
|
-
|
|
1829
|
+
stylesConfig: {
|
|
1802
1830
|
"heading1": {
|
|
1803
1831
|
"custom_css": "font-size: 24px; color: #333;"
|
|
1804
1832
|
}
|
|
@@ -1814,7 +1842,7 @@ A Heading and a button inside a flexbox
|
|
|
1814
1842
|
`**MANDATORY** A record mapping configuration IDs to their corresponding configuration objects, defining the PropValues for each element created.`
|
|
1815
1843
|
);
|
|
1816
1844
|
buildCompositionsToolPrompt.parameter(
|
|
1817
|
-
"
|
|
1845
|
+
"stylesConfig",
|
|
1818
1846
|
`**MANDATORY** A record mapping style PropTypes to their corresponding style configuration objects, defining the PropValues for styles to be applied to elements.`
|
|
1819
1847
|
);
|
|
1820
1848
|
buildCompositionsToolPrompt.instruction(
|
|
@@ -1862,16 +1890,9 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1862
1890
|
const { xmlStructure, elementConfig, stylesConfig } = params;
|
|
1863
1891
|
const errors = [];
|
|
1864
1892
|
const softErrors = [];
|
|
1893
|
+
const rootContainers = [];
|
|
1865
1894
|
const widgetsCache = getWidgetsCache4() || {};
|
|
1866
1895
|
const documentContainer = getContainer("document");
|
|
1867
|
-
const rootContainer = createElement5({
|
|
1868
|
-
containerId: documentContainer.id,
|
|
1869
|
-
model: {
|
|
1870
|
-
elType: "container",
|
|
1871
|
-
id: generateElementId()
|
|
1872
|
-
},
|
|
1873
|
-
options: { useHistory: false }
|
|
1874
|
-
});
|
|
1875
1896
|
try {
|
|
1876
1897
|
const parser = new DOMParser();
|
|
1877
1898
|
xml = parser.parseFromString(xmlStructure, "application/xml");
|
|
@@ -1880,7 +1901,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1880
1901
|
throw new Error("Failed to parse XML structure: " + errorNode.textContent);
|
|
1881
1902
|
}
|
|
1882
1903
|
const children = Array.from(xml.children);
|
|
1883
|
-
const iterate = (node, containerElement) => {
|
|
1904
|
+
const iterate = (node, containerElement = documentContainer) => {
|
|
1884
1905
|
const elementTag = node.tagName;
|
|
1885
1906
|
if (!widgetsCache[elementTag]) {
|
|
1886
1907
|
errors.push(new Error(`Unknown widget type: ${elementTag}`));
|
|
@@ -1902,6 +1923,9 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1902
1923
|
},
|
|
1903
1924
|
options: { useHistory: false }
|
|
1904
1925
|
});
|
|
1926
|
+
if (containerElement === documentContainer) {
|
|
1927
|
+
rootContainers.push(newElement);
|
|
1928
|
+
}
|
|
1905
1929
|
node.setAttribute("id", newElement.id);
|
|
1906
1930
|
const configId = node.getAttribute("configuration-id") || "";
|
|
1907
1931
|
try {
|
|
@@ -1910,7 +1934,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1910
1934
|
configObject._styles = styleObject;
|
|
1911
1935
|
for (const [propertyName, propertyValue] of Object.entries(configObject)) {
|
|
1912
1936
|
const widgetSchema = widgetsCache[elementTag];
|
|
1913
|
-
if (!widgetSchema?.atomic_props_schema?.[propertyName] && propertyName !== "_styles") {
|
|
1937
|
+
if (!widgetSchema?.atomic_props_schema?.[propertyName] && propertyName !== "_styles" && propertyName !== "custom_css") {
|
|
1914
1938
|
softErrors.push(
|
|
1915
1939
|
new Error(
|
|
1916
1940
|
`Property "${propertyName}" does not exist on element type "${elementTag}".`
|
|
@@ -1922,7 +1946,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1922
1946
|
doUpdateElementProperty({
|
|
1923
1947
|
elementId: newElement.id,
|
|
1924
1948
|
propertyName,
|
|
1925
|
-
propertyValue,
|
|
1949
|
+
propertyValue: propertyName === "custom_css" ? { _styles: propertyValue } : propertyValue,
|
|
1926
1950
|
elementType: elementTag
|
|
1927
1951
|
});
|
|
1928
1952
|
} catch (error) {
|
|
@@ -1941,7 +1965,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1941
1965
|
}
|
|
1942
1966
|
};
|
|
1943
1967
|
for (const childNode of children) {
|
|
1944
|
-
iterate(childNode,
|
|
1968
|
+
iterate(childNode, documentContainer);
|
|
1945
1969
|
try {
|
|
1946
1970
|
} catch (error) {
|
|
1947
1971
|
errors.push(error);
|
|
@@ -1951,9 +1975,11 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
1951
1975
|
errors.push(error);
|
|
1952
1976
|
}
|
|
1953
1977
|
if (errors.length) {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1978
|
+
rootContainers.forEach((rootContainer) => {
|
|
1979
|
+
deleteElement({
|
|
1980
|
+
elementId: rootContainer.id,
|
|
1981
|
+
options: { useHistory: false }
|
|
1982
|
+
});
|
|
1957
1983
|
});
|
|
1958
1984
|
}
|
|
1959
1985
|
if (errors.length > 0) {
|
|
@@ -1987,19 +2013,20 @@ Next Steps:
|
|
|
1987
2013
|
// src/mcp/tools/configure-element/prompt.ts
|
|
1988
2014
|
var configureElementToolPrompt = `Configure an existing element on the page.
|
|
1989
2015
|
|
|
1990
|
-
# **CRITICAL - REQUIRED
|
|
2016
|
+
# **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
|
|
1991
2017
|
1. [${WIDGET_SCHEMA_URI}]
|
|
1992
2018
|
Required to understand which widgets are available, and what are their configuration schemas.
|
|
1993
2019
|
Every widgetType (i.e. e-heading, e-button) that is supported has it's own property schema, that you must follow in order to apply property values correctly.
|
|
1994
2020
|
2. [${STYLE_SCHEMA_URI}]
|
|
1995
2021
|
Required to understand the styles schema for the widgets. All widgets share the same styles schema, grouped by categories.
|
|
1996
2022
|
Use this resource to understand which style properties are available for each element, and how to structure the "_styles" configuration property.
|
|
2023
|
+
3. If not sure about the PropValues schema, you can use the "get-element-configuration-values" tool to retreive the current PropValues configuration of the element.
|
|
1997
2024
|
|
|
1998
2025
|
Before using this tool, check the definitions of the elements PropTypes at the resource "widget-schema-by-type" at editor-canvas__elementor://widgets/schema/{widgetType}
|
|
1999
2026
|
All widgets share a common _style property for styling, which uses the common styles schema.
|
|
2000
2027
|
Retreive and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
|
|
2001
2028
|
|
|
2002
|
-
|
|
2029
|
+
Attempt to use the _style property "custom_css" for any styling that have complicated schemas (such as backgrounds), read the resource editor-canvas__elementor://styles/schema/custom_css for more information.
|
|
2003
2030
|
|
|
2004
2031
|
# Parameters
|
|
2005
2032
|
- propertiesToChange: An object containing the properties to change, with their new values. MANDATORY
|
|
@@ -2044,6 +2071,7 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
|
|
|
2044
2071
|
\`\`\`json
|
|
2045
2072
|
{
|
|
2046
2073
|
propertiesToChange: {
|
|
2074
|
+
// List of properties TO CHANGE, following the PropType schema for the element as defined in the resource [${WIDGET_SCHEMA_URI}]
|
|
2047
2075
|
title: {
|
|
2048
2076
|
$$type: 'string',
|
|
2049
2077
|
value: 'New Title Text'
|
|
@@ -2053,8 +2081,9 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
|
|
|
2053
2081
|
value: false
|
|
2054
2082
|
},
|
|
2055
2083
|
_styles: {
|
|
2084
|
+
// List of available keys available at the [${STYLE_SCHEMA_URI}] dynamic resource
|
|
2056
2085
|
'line-height': {
|
|
2057
|
-
$$type: 'size',
|
|
2086
|
+
$$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
|
|
2058
2087
|
value: {
|
|
2059
2088
|
size: {
|
|
2060
2089
|
$$type: 'number',
|
|
@@ -2148,6 +2177,70 @@ Check the element's PropType schema at the resource [${WIDGET_SCHEMA_URI.replace
|
|
|
2148
2177
|
Now that you have this information, ensure you have the schema and try again.`;
|
|
2149
2178
|
}
|
|
2150
2179
|
|
|
2180
|
+
// src/mcp/tools/get-element-config/tool.ts
|
|
2181
|
+
import { getContainer as getContainer2, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache5 } from "@elementor/editor-elements";
|
|
2182
|
+
import { Schema as Schema3 } from "@elementor/editor-props";
|
|
2183
|
+
import { z as z3 } from "@elementor/schema";
|
|
2184
|
+
import { decodeString as decodeString2 } from "@elementor/utils";
|
|
2185
|
+
var schema = {
|
|
2186
|
+
elementId: z3.string()
|
|
2187
|
+
};
|
|
2188
|
+
var outputSchema3 = {
|
|
2189
|
+
propValues: z3.record(z3.string(), z3.any()).describe(
|
|
2190
|
+
"A record mapping PropTypes to their corresponding PropValues, with _styles record for style-related PropValues"
|
|
2191
|
+
),
|
|
2192
|
+
customCss: z3.string().optional().describe("The custom CSS string associated with the element, if any.")
|
|
2193
|
+
};
|
|
2194
|
+
var initGetElementConfigTool = (reg) => {
|
|
2195
|
+
const { addTool } = reg;
|
|
2196
|
+
addTool({
|
|
2197
|
+
name: "get-element-configuration-values",
|
|
2198
|
+
description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
|
|
2199
|
+
schema,
|
|
2200
|
+
outputSchema: outputSchema3,
|
|
2201
|
+
handler: async ({ elementId }) => {
|
|
2202
|
+
const element = getContainer2(elementId);
|
|
2203
|
+
if (!element) {
|
|
2204
|
+
throw new Error(`Element with ID ${elementId} not found.`);
|
|
2205
|
+
}
|
|
2206
|
+
const elementRawSettings = element.settings;
|
|
2207
|
+
const propSchema = getWidgetsCache5()?.[element.model.get("widgetType") || ""]?.atomic_props_schema;
|
|
2208
|
+
if (!elementRawSettings || !propSchema) {
|
|
2209
|
+
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
2210
|
+
}
|
|
2211
|
+
const propValues = {};
|
|
2212
|
+
const stylePropValues = {};
|
|
2213
|
+
Schema3.configurableKeys(propSchema).forEach((key) => {
|
|
2214
|
+
propValues[key] = structuredClone(elementRawSettings.get(key));
|
|
2215
|
+
});
|
|
2216
|
+
const elementStyles = getElementStyles2(elementId) || {};
|
|
2217
|
+
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
2218
|
+
if (localStyle) {
|
|
2219
|
+
const defaultVariant = localStyle.variants.find(
|
|
2220
|
+
(variant) => variant.meta.breakpoint === "desktop" && !variant.meta.state
|
|
2221
|
+
);
|
|
2222
|
+
if (defaultVariant) {
|
|
2223
|
+
const styleProps = defaultVariant.props || {};
|
|
2224
|
+
Object.keys(styleProps).forEach((stylePropName) => {
|
|
2225
|
+
if (typeof styleProps[stylePropName] !== "undefined") {
|
|
2226
|
+
stylePropValues[stylePropName] = structuredClone(styleProps[stylePropName]);
|
|
2227
|
+
}
|
|
2228
|
+
});
|
|
2229
|
+
if (defaultVariant.custom_css?.raw) {
|
|
2230
|
+
stylePropValues.custom_css = decodeString2(defaultVariant.custom_css.raw, void 0);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
return {
|
|
2235
|
+
propValues: {
|
|
2236
|
+
...propValues,
|
|
2237
|
+
_styles: stylePropValues
|
|
2238
|
+
}
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
});
|
|
2242
|
+
};
|
|
2243
|
+
|
|
2151
2244
|
// src/mcp/canvas-mcp.ts
|
|
2152
2245
|
var initCanvasMcp = (reg) => {
|
|
2153
2246
|
const { setMCPDescription } = reg;
|
|
@@ -2156,6 +2249,7 @@ var initCanvasMcp = (reg) => {
|
|
|
2156
2249
|
);
|
|
2157
2250
|
initWidgetsSchemaResource(reg);
|
|
2158
2251
|
initBuildCompositionsTool(reg);
|
|
2252
|
+
initGetElementConfigTool(reg);
|
|
2159
2253
|
initConfigureElementTool(reg);
|
|
2160
2254
|
};
|
|
2161
2255
|
|
|
@@ -2164,32 +2258,42 @@ var mcpDescription = `Canvas MCP - Working with widgets and styles: how to use t
|
|
|
2164
2258
|
|
|
2165
2259
|
# Elementor's PropValue configuration system
|
|
2166
2260
|
|
|
2167
|
-
Every widget in Elementor has a set of properties that can be configured
|
|
2168
|
-
All values are
|
|
2261
|
+
Every widget in Elementor has a set of properties that can be configured, defined in a STRICT SCHEMA we call "PropType".
|
|
2262
|
+
All widget configuration values are represented using a structure we call "PropValue".
|
|
2169
2263
|
|
|
2170
|
-
To correctly configure a widget's properties,
|
|
2264
|
+
To correctly configure a widget's properties, FOLLOW THE PropType schema defined for that widget. This schema outlines the expected structure and types for each property, ensuring that the values you provide are valid and can be properly interpreted by Elementor.
|
|
2171
2265
|
Every widget has it's own PropType schema, retreivable from the resource [${WIDGET_SCHEMA_URI}].
|
|
2172
2266
|
ALL WIDGETS share a common _styles property with a uniform styles schema, retreivable from the resource [${STYLE_SCHEMA_URI}].
|
|
2173
2267
|
The style schema is grouped by categories, such as "typography", "background", "border", etc.
|
|
2174
2268
|
|
|
2269
|
+
# Tools and usage
|
|
2270
|
+
- Use the "get-element-configuration-values" tool to retrieve the current configuration of a specific element, including its PropValues and styles. It is recommended to use this tool when you are required to make changes to an existing element, to ensure you have the correct current configuration schema.
|
|
2271
|
+
If a PropValue changes it's type (only on union PropTypes), read the new schema from the resources mentioned above, and adjust the PropValue structure accordingly.
|
|
2272
|
+
- Use the "build-composition" tool to create a NEW ELEMENTS in a composition on the page. You can use this tool to also create a new single element.
|
|
2273
|
+
- Use the "configure-element" tool to update the configuration of an EXISTING element on the page.
|
|
2274
|
+
|
|
2175
2275
|
All array types that can receive union types, are typed as mixed array, which means that each item in the array can be of any of the allowed types defined in the PropType schema.
|
|
2176
2276
|
Example: the "background" can have a background-overlay property, which can contain multiple overlays, such as color, gradient, image, etc. Each item in the array must follow the PropType schema for each overlay type.
|
|
2177
2277
|
All _style properties are OPTIONAL. When a _style is defined, we MERGE the values with existing styles, so only the properties you define will be changed, and the rest will remain as is.
|
|
2178
2278
|
|
|
2279
|
+
# Styling best practices
|
|
2280
|
+
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
2281
|
+
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema, or in custom_css, depends on your needs.
|
|
2282
|
+
|
|
2179
2283
|
When applicable for styles, use the "custom_css" property for free-form CSS styling. This property accepts a string of CSS rules that will be applied directly to the element.
|
|
2180
2284
|
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.
|
|
2181
2285
|
|
|
2182
2286
|
Additionaly, some PropTypes have metadata information (meta property) that can help in understaind the PropType usage, such as description or other useful information.
|
|
2183
2287
|
|
|
2184
|
-
|
|
2185
|
-
|
|
2288
|
+
Example of null values:
|
|
2289
|
+
{
|
|
2290
|
+
$$type: 'as-defined-for-propValue',
|
|
2291
|
+
value: null
|
|
2292
|
+
}
|
|
2186
2293
|
|
|
2187
2294
|
Example of "image" PropValue structure:
|
|
2188
|
-
|
|
2189
|
-
PropValue structure:
|
|
2190
2295
|
{$$type:'image',value:{src:{$$type:'image-src',value:{url:{$$type:'url',value:'https://example.com/image.jpg'}}},size:{$$type:'string',value:'full'}}}
|
|
2191
2296
|
|
|
2192
|
-
Example of
|
|
2193
2297
|
`;
|
|
2194
2298
|
|
|
2195
2299
|
// src/prevent-link-in-link-commands.ts
|
|
@@ -2290,7 +2394,7 @@ import {
|
|
|
2290
2394
|
import {
|
|
2291
2395
|
createElementStyle as createElementStyle2,
|
|
2292
2396
|
deleteElementStyle,
|
|
2293
|
-
getElementStyles as
|
|
2397
|
+
getElementStyles as getElementStyles3,
|
|
2294
2398
|
updateElementStyle as updateElementStyle2
|
|
2295
2399
|
} from "@elementor/editor-elements";
|
|
2296
2400
|
import { ELEMENTS_STYLES_RESERVED_LABEL } from "@elementor/editor-styles-repository";
|
|
@@ -2298,7 +2402,7 @@ import { undoable } from "@elementor/editor-v1-adapters";
|
|
|
2298
2402
|
import { __ as __3 } from "@wordpress/i18n";
|
|
2299
2403
|
|
|
2300
2404
|
// src/style-commands/utils.ts
|
|
2301
|
-
import { getElementLabel, getWidgetsCache as
|
|
2405
|
+
import { getElementLabel, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
|
|
2302
2406
|
import { CLASSES_PROP_KEY } from "@elementor/editor-props";
|
|
2303
2407
|
import { __ as __2 } from "@wordpress/i18n";
|
|
2304
2408
|
function hasAtomicWidgets(args) {
|
|
@@ -2323,7 +2427,7 @@ function getClassesProp(container) {
|
|
|
2323
2427
|
}
|
|
2324
2428
|
function getContainerSchema(container) {
|
|
2325
2429
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
2326
|
-
const widgetsCache =
|
|
2430
|
+
const widgetsCache = getWidgetsCache6();
|
|
2327
2431
|
const elementType = widgetsCache?.[type];
|
|
2328
2432
|
return elementType?.atomic_props_schema ?? null;
|
|
2329
2433
|
}
|
|
@@ -2349,7 +2453,7 @@ var undoablePasteElementStyle = () => undoable(
|
|
|
2349
2453
|
if (!classesProp) {
|
|
2350
2454
|
return null;
|
|
2351
2455
|
}
|
|
2352
|
-
const originalStyles =
|
|
2456
|
+
const originalStyles = getElementStyles3(container.id);
|
|
2353
2457
|
const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
|
|
2354
2458
|
const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
|
|
2355
2459
|
const revertData = {
|
|
@@ -2452,7 +2556,7 @@ import {
|
|
|
2452
2556
|
} from "@elementor/editor-v1-adapters";
|
|
2453
2557
|
|
|
2454
2558
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
2455
|
-
import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as
|
|
2559
|
+
import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as getElementStyles4 } from "@elementor/editor-elements";
|
|
2456
2560
|
import { ELEMENTS_STYLES_RESERVED_LABEL as ELEMENTS_STYLES_RESERVED_LABEL2 } from "@elementor/editor-styles-repository";
|
|
2457
2561
|
import { undoable as undoable2 } from "@elementor/editor-v1-adapters";
|
|
2458
2562
|
import { __ as __4 } from "@wordpress/i18n";
|
|
@@ -2461,7 +2565,7 @@ var undoableResetElementStyle = () => undoable2(
|
|
|
2461
2565
|
do: ({ containers }) => {
|
|
2462
2566
|
return containers.map((container) => {
|
|
2463
2567
|
const elementId = container.model.get("id");
|
|
2464
|
-
const containerStyles =
|
|
2568
|
+
const containerStyles = getElementStyles4(elementId);
|
|
2465
2569
|
Object.keys(containerStyles ?? {}).forEach(
|
|
2466
2570
|
(styleId) => deleteElementStyle2(elementId, styleId)
|
|
2467
2571
|
);
|
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.33.0-
|
|
4
|
+
"version": "3.33.0-293",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,23 +37,23 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "3.33.0-
|
|
41
|
-
"@elementor/editor-controls": "3.33.0-
|
|
42
|
-
"@elementor/editor-documents": "3.33.0-
|
|
43
|
-
"@elementor/editor-elements": "3.33.0-
|
|
44
|
-
"@elementor/editor-interactions": "3.33.0-
|
|
45
|
-
"@elementor/editor-notifications": "3.33.0-
|
|
46
|
-
"@elementor/editor-props": "3.33.0-
|
|
47
|
-
"@elementor/editor-responsive": "3.33.0-
|
|
48
|
-
"@elementor/editor-styles": "3.33.0-
|
|
49
|
-
"@elementor/editor-styles-repository": "3.33.0-
|
|
50
|
-
"@elementor/editor-v1-adapters": "3.33.0-
|
|
51
|
-
"@elementor/editor-mcp": "3.33.0-
|
|
52
|
-
"@elementor/schema": "3.33.0-
|
|
53
|
-
"@elementor/twing": "3.33.0-
|
|
40
|
+
"@elementor/editor": "3.33.0-293",
|
|
41
|
+
"@elementor/editor-controls": "3.33.0-293",
|
|
42
|
+
"@elementor/editor-documents": "3.33.0-293",
|
|
43
|
+
"@elementor/editor-elements": "3.33.0-293",
|
|
44
|
+
"@elementor/editor-interactions": "3.33.0-293",
|
|
45
|
+
"@elementor/editor-notifications": "3.33.0-293",
|
|
46
|
+
"@elementor/editor-props": "3.33.0-293",
|
|
47
|
+
"@elementor/editor-responsive": "3.33.0-293",
|
|
48
|
+
"@elementor/editor-styles": "3.33.0-293",
|
|
49
|
+
"@elementor/editor-styles-repository": "3.33.0-293",
|
|
50
|
+
"@elementor/editor-v1-adapters": "3.33.0-293",
|
|
51
|
+
"@elementor/editor-mcp": "3.33.0-293",
|
|
52
|
+
"@elementor/schema": "3.33.0-293",
|
|
53
|
+
"@elementor/twing": "3.33.0-293",
|
|
54
54
|
"@elementor/ui": "1.36.17",
|
|
55
|
-
"@elementor/utils": "3.33.0-
|
|
56
|
-
"@elementor/wp-media": "3.33.0-
|
|
55
|
+
"@elementor/utils": "3.33.0-293",
|
|
56
|
+
"@elementor/wp-media": "3.33.0-293",
|
|
57
57
|
"@floating-ui/react": "^0.27.5",
|
|
58
58
|
"@wordpress/i18n": "^5.13.0"
|
|
59
59
|
},
|
package/src/mcp/canvas-mcp.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
|
3
3
|
import { initWidgetsSchemaResource } from './resources/widgets-schema-resource';
|
|
4
4
|
import { initBuildCompositionsTool } from './tools/build-composition/tool';
|
|
5
5
|
import { initConfigureElementTool } from './tools/configure-element/tool';
|
|
6
|
+
import { initGetElementConfigTool } from './tools/get-element-config/tool';
|
|
6
7
|
|
|
7
8
|
export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
|
|
8
9
|
const { setMCPDescription } = reg;
|
|
@@ -11,5 +12,6 @@ export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
|
|
|
11
12
|
);
|
|
12
13
|
initWidgetsSchemaResource( reg );
|
|
13
14
|
initBuildCompositionsTool( reg );
|
|
15
|
+
initGetElementConfigTool( reg );
|
|
14
16
|
initConfigureElementTool( reg );
|
|
15
17
|
};
|
|
@@ -4,30 +4,40 @@ export const mcpDescription = `Canvas MCP - Working with widgets and styles: how
|
|
|
4
4
|
|
|
5
5
|
# Elementor's PropValue configuration system
|
|
6
6
|
|
|
7
|
-
Every widget in Elementor has a set of properties that can be configured
|
|
8
|
-
All values are
|
|
7
|
+
Every widget in Elementor has a set of properties that can be configured, defined in a STRICT SCHEMA we call "PropType".
|
|
8
|
+
All widget configuration values are represented using a structure we call "PropValue".
|
|
9
9
|
|
|
10
|
-
To correctly configure a widget's properties,
|
|
10
|
+
To correctly configure a widget's properties, FOLLOW THE PropType schema defined for that widget. This schema outlines the expected structure and types for each property, ensuring that the values you provide are valid and can be properly interpreted by Elementor.
|
|
11
11
|
Every widget has it's own PropType schema, retreivable from the resource [${ WIDGET_SCHEMA_URI }].
|
|
12
12
|
ALL WIDGETS share a common _styles property with a uniform styles schema, retreivable from the resource [${ STYLE_SCHEMA_URI }].
|
|
13
13
|
The style schema is grouped by categories, such as "typography", "background", "border", etc.
|
|
14
14
|
|
|
15
|
+
# Tools and usage
|
|
16
|
+
- Use the "get-element-configuration-values" tool to retrieve the current configuration of a specific element, including its PropValues and styles. It is recommended to use this tool when you are required to make changes to an existing element, to ensure you have the correct current configuration schema.
|
|
17
|
+
If a PropValue changes it's type (only on union PropTypes), read the new schema from the resources mentioned above, and adjust the PropValue structure accordingly.
|
|
18
|
+
- Use the "build-composition" tool to create a NEW ELEMENTS in a composition on the page. You can use this tool to also create a new single element.
|
|
19
|
+
- Use the "configure-element" tool to update the configuration of an EXISTING element on the page.
|
|
20
|
+
|
|
15
21
|
All array types that can receive union types, are typed as mixed array, which means that each item in the array can be of any of the allowed types defined in the PropType schema.
|
|
16
22
|
Example: the "background" can have a background-overlay property, which can contain multiple overlays, such as color, gradient, image, etc. Each item in the array must follow the PropType schema for each overlay type.
|
|
17
23
|
All _style properties are OPTIONAL. When a _style is defined, we MERGE the values with existing styles, so only the properties you define will be changed, and the rest will remain as is.
|
|
18
24
|
|
|
25
|
+
# Styling best practices
|
|
26
|
+
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
27
|
+
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema, or in custom_css, depends on your needs.
|
|
28
|
+
|
|
19
29
|
When applicable for styles, use the "custom_css" property for free-form CSS styling. This property accepts a string of CSS rules that will be applied directly to the element.
|
|
20
30
|
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.
|
|
21
31
|
|
|
22
32
|
Additionaly, some PropTypes have metadata information (meta property) that can help in understaind the PropType usage, such as description or other useful information.
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
Example of null values:
|
|
35
|
+
{
|
|
36
|
+
$$type: 'as-defined-for-propValue',
|
|
37
|
+
value: null
|
|
38
|
+
}
|
|
26
39
|
|
|
27
40
|
Example of "image" PropValue structure:
|
|
28
|
-
|
|
29
|
-
PropValue structure:
|
|
30
41
|
{$$type:'image',value:{src:{$$type:'image-src',value:{url:{$$type:'url',value:'https://example.com/image.jpg'}}},size:{$$type:'string',value:'full'}}}
|
|
31
42
|
|
|
32
|
-
Example of
|
|
33
43
|
`;
|
|
@@ -12,10 +12,27 @@ import { getStylesSchema } from '@elementor/editor-styles';
|
|
|
12
12
|
|
|
13
13
|
export const WIDGET_SCHEMA_URI = 'elementor://widgets/schema/{widgetType}';
|
|
14
14
|
export const STYLE_SCHEMA_URI = 'elementor://styles/schema/{category}';
|
|
15
|
+
export const BEST_PRACTICES_URI = 'elementor://styles/best-practices';
|
|
15
16
|
|
|
16
17
|
export const initWidgetsSchemaResource = ( reg: MCPRegistryEntry ) => {
|
|
17
18
|
const { mcpServer } = reg;
|
|
18
19
|
|
|
20
|
+
mcpServer.resource( 'styles-best-practices', BEST_PRACTICES_URI, async () => {
|
|
21
|
+
return {
|
|
22
|
+
contents: [
|
|
23
|
+
{
|
|
24
|
+
uri: BEST_PRACTICES_URI,
|
|
25
|
+
text: `# Styling best practices
|
|
26
|
+
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
27
|
+
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema, or in custom_css, depends on your needs.
|
|
28
|
+
|
|
29
|
+
When applicable for styles, use the "custom_css" property for free-form CSS styling. This property accepts a string of CSS rules that will be applied directly to the element.
|
|
30
|
+
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.`,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
} );
|
|
35
|
+
|
|
19
36
|
mcpServer.resource(
|
|
20
37
|
'styles-schema',
|
|
21
38
|
new ResourceTemplate( STYLE_SCHEMA_URI, {
|
|
@@ -94,9 +111,11 @@ export const initWidgetsSchemaResource = ( reg: MCPRegistryEntry ) => {
|
|
|
94
111
|
Schema.propTypeToJsonSchema( propType ),
|
|
95
112
|
] )
|
|
96
113
|
);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
Schema.nonConfigurablePropKeys.forEach( ( key ) => {
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
116
|
+
delete asJson[ key ];
|
|
117
|
+
} );
|
|
118
|
+
|
|
100
119
|
return {
|
|
101
120
|
contents: [
|
|
102
121
|
{
|
|
@@ -37,6 +37,7 @@ Prefer this tool over any other tool for building HTML structure, unless you are
|
|
|
37
37
|
For easy execution, USE ONLY "custom_css" category from the styles schema resource to apply styles.
|
|
38
38
|
5. Ensure the XML structure is valid and parsable.
|
|
39
39
|
6. Do not add any attribute nodes, classes, id's, and no text nodes allowed, for inline styles prefer USE the [${ CUSTOM_CSS_URI }] resource for custom_css.
|
|
40
|
+
Layout properties, such as margin, padding, align, etc. must be applied using the [${ STYLE_SCHEMA_URI }] PropValues.
|
|
40
41
|
7. Some elements allow nesting of other elements, and most of the DO NOT. The allowed elements that can have nested children are "e-div-block" and "e-flexbox".
|
|
41
42
|
8. Make sure that non-container elements do NOT have any nested elements.
|
|
42
43
|
9. Unsless the user specifically requires structure only, BE EXPRESSIVE AND VISUALLY CREATIVE AS POSSIBLE IN APPLYING STYLE CONFIGURATION.
|
|
@@ -51,6 +52,8 @@ Prefer this tool over any other tool for building HTML structure, unless you are
|
|
|
51
52
|
- Always aim for a clean and professional look that aligns with modern design principles.
|
|
52
53
|
- When you are required to create placeholder texts, use texts that have a length that fits the goal. When long texts are required, use longer placeholder texts. When the user specifies exact texts, use the exact texts.
|
|
53
54
|
- Image size does not affect the actual size on the screen, only which quality to use. If you use images, specifically add _styles PropValues to define the image sizes.
|
|
55
|
+
- Attempt to use layout, margin, padding, size properties from the styles schema and not the custom_css, unless necessary.
|
|
56
|
+
- If your elements library is limited, encourage use of nesting containers to achieve complex layouts.
|
|
54
57
|
|
|
55
58
|
# CONSTRAINTS
|
|
56
59
|
When a tool execution fails, retry up to 10 more times, read the error message carefully, and adjust the XML structure or the configurations accordingly.
|
|
@@ -83,7 +86,7 @@ A Heading and a button inside a flexbox
|
|
|
83
86
|
"value": "section"
|
|
84
87
|
},
|
|
85
88
|
},
|
|
86
|
-
|
|
89
|
+
stylesConfig: {
|
|
87
90
|
"heading1": {
|
|
88
91
|
"custom_css": "font-size: 24px; color: #333;"
|
|
89
92
|
}
|
|
@@ -102,7 +105,7 @@ A Heading and a button inside a flexbox
|
|
|
102
105
|
);
|
|
103
106
|
|
|
104
107
|
buildCompositionsToolPrompt.parameter(
|
|
105
|
-
'
|
|
108
|
+
'stylesConfig',
|
|
106
109
|
`**MANDATORY** A record mapping style PropTypes to their corresponding style configuration objects, defining the PropValues for styles to be applied to elements.`
|
|
107
110
|
);
|
|
108
111
|
|