@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.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
- schema = schema ?? initialSchema;
444
+ async function resolve({ props, schema: schema2, signal }) {
445
+ schema2 = schema2 ?? initialSchema;
446
446
  const promises = Promise.all(
447
- Object.entries(schema).map(async ([key, type]) => {
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 z3 = getVal2(value.z);
1116
- if (x === DEFAULT_XY && y === DEFAULT_XY && z3 === DEFAULT_Z) {
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} ${z3}`;
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
- delete asJson.classes;
1549
- delete asJson._cssid;
1550
- delete asJson.attributes;
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 { getPropSchemaFromCache, Schema as Schema2 } from "@elementor/editor-props";
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(propertyMapValue[stylePropName])
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
- styleConfig: {
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
- "styleConfig",
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, rootContainer);
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
- deleteElement({
1955
- elementId: rootContainer.id,
1956
- options: { useHistory: false }
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 RESOURCES (Must read before using this tool)**
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
- Unless specifically noted, attempt to use the _style property "custom_css" for any styling, read the resource editor-canvas__elementor://styles/schema/custom_css for more information.
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. These properties are defined using a strict schema, which specifies the type and structure of each property's value.
2168
- All values are wrapped in a special structure called a "PropValue", which includes data and additional information about the type of the value.
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, you must 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.
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
- # Note about null values
2185
- If a PropValue's value is null, omit the entire PropValue object.
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 getElementStyles2,
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 getWidgetsCache5 } from "@elementor/editor-elements";
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 = getWidgetsCache5();
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 = getElementStyles2(container.id);
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 getElementStyles3 } from "@elementor/editor-elements";
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 = getElementStyles3(elementId);
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-291",
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-291",
41
- "@elementor/editor-controls": "3.33.0-291",
42
- "@elementor/editor-documents": "3.33.0-291",
43
- "@elementor/editor-elements": "3.33.0-291",
44
- "@elementor/editor-interactions": "3.33.0-291",
45
- "@elementor/editor-notifications": "3.33.0-291",
46
- "@elementor/editor-props": "3.33.0-291",
47
- "@elementor/editor-responsive": "3.33.0-291",
48
- "@elementor/editor-styles": "3.33.0-291",
49
- "@elementor/editor-styles-repository": "3.33.0-291",
50
- "@elementor/editor-v1-adapters": "3.33.0-291",
51
- "@elementor/editor-mcp": "3.33.0-291",
52
- "@elementor/schema": "3.33.0-291",
53
- "@elementor/twing": "3.33.0-291",
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-291",
56
- "@elementor/wp-media": "3.33.0-291",
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
  },
@@ -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. These properties are defined using a strict schema, which specifies the type and structure of each property's value.
8
- All values are wrapped in a special structure called a "PropValue", which includes data and additional information about the type of the value.
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, you must 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.
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
- # Note about null values
25
- If a PropValue's value is null, omit the entire PropValue object.
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
- delete asJson.classes;
98
- delete asJson._cssid;
99
- delete asJson.attributes;
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
- styleConfig: {
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
- 'styleConfig',
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