@elementor/editor-canvas 3.35.0-340 → 3.35.0-342

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
@@ -1,3 +1,163 @@
1
+ // src/mcp/resources/breakpoints-resource.ts
2
+ import { v1ReadyEvent } from "@elementor/editor-v1-adapters";
3
+ var BREAKPOINTS_SCHEMA_URI = "elementor://breakpoints/list";
4
+ var initBreakpointsResource = (reg) => {
5
+ const { mcpServer } = reg;
6
+ const getBreakpointsList = () => {
7
+ const { breakpoints } = window.elementor?.config?.responsive || {};
8
+ if (!breakpoints) {
9
+ return [];
10
+ }
11
+ return Object.values(breakpoints).filter((bp) => bp.is_enabled).map((bp) => {
12
+ const { direction: constraint, label, value } = bp;
13
+ return {
14
+ label,
15
+ constraint,
16
+ value
17
+ };
18
+ });
19
+ };
20
+ const buildResourceResponse = () => ({
21
+ contents: [
22
+ {
23
+ uri: BREAKPOINTS_SCHEMA_URI,
24
+ mimeType: "application/json",
25
+ text: JSON.stringify(getBreakpointsList())
26
+ }
27
+ ]
28
+ });
29
+ mcpServer.resource("breakpoints ", BREAKPOINTS_SCHEMA_URI, () => {
30
+ return buildResourceResponse();
31
+ });
32
+ window.addEventListener(v1ReadyEvent().name, () => {
33
+ mcpServer.server.sendResourceUpdated({
34
+ uri: BREAKPOINTS_SCHEMA_URI,
35
+ ...buildResourceResponse()
36
+ });
37
+ });
38
+ };
39
+
40
+ // src/mcp/resources/widgets-schema-resource.ts
41
+ import { getWidgetsCache } from "@elementor/editor-elements";
42
+ import { ResourceTemplate } from "@elementor/editor-mcp";
43
+ import {
44
+ Schema
45
+ } from "@elementor/editor-props";
46
+ import { getStylesSchema } from "@elementor/editor-styles";
47
+ var WIDGET_SCHEMA_URI = "elementor://widgets/schema/{widgetType}";
48
+ var STYLE_SCHEMA_URI = "elementor://styles/schema/{category}";
49
+ var BEST_PRACTICES_URI = "elementor://styles/best-practices";
50
+ var initWidgetsSchemaResource = (reg) => {
51
+ const { mcpServer } = reg;
52
+ mcpServer.resource("styles-best-practices", BEST_PRACTICES_URI, async () => {
53
+ return {
54
+ contents: [
55
+ {
56
+ uri: BEST_PRACTICES_URI,
57
+ text: `# Styling best practices
58
+ Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
59
+ 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.
60
+
61
+ When applicable for styles, apply style PropValues using the ${STYLE_SCHEMA_URI}. Custom css is for Elementor PRO users and intended to support only new CSS features not yet available in the UI.
62
+ The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.`
63
+ }
64
+ ]
65
+ };
66
+ });
67
+ mcpServer.resource(
68
+ "styles-schema",
69
+ new ResourceTemplate(STYLE_SCHEMA_URI, {
70
+ list: () => {
71
+ const categories = [...Object.keys(getStylesSchema()), "custom_css"];
72
+ return {
73
+ resources: categories.map((category) => ({
74
+ uri: `elementor://styles/schema/${category}`,
75
+ name: "Style schema for " + category
76
+ }))
77
+ };
78
+ }
79
+ }),
80
+ {
81
+ description: "Common styles schema for the specified category"
82
+ },
83
+ async (uri, variables) => {
84
+ const category = typeof variables.category === "string" ? variables.category : variables.category?.[0];
85
+ if (category === "custom_css") {
86
+ return {
87
+ contents: [
88
+ {
89
+ uri: uri.toString(),
90
+ text: "Free style inline CSS string of properties and their values. Applicable for a single element, only the properties and values are accepted. Use this as a last resort for properties that are not covered with the schema. Do not use selectors, only the CSS content"
91
+ }
92
+ ]
93
+ };
94
+ }
95
+ const stylesSchema = getStylesSchema()[category];
96
+ if (!stylesSchema) {
97
+ throw new Error(`No styles schema found for category: ${category}`);
98
+ }
99
+ const asJson = Schema.propTypeToJsonSchema(stylesSchema);
100
+ return {
101
+ contents: [
102
+ {
103
+ uri: uri.toString(),
104
+ mimeType: "application/json",
105
+ text: JSON.stringify(asJson)
106
+ }
107
+ ]
108
+ };
109
+ }
110
+ );
111
+ mcpServer.resource(
112
+ "widget-schema-by-type",
113
+ new ResourceTemplate(WIDGET_SCHEMA_URI, {
114
+ list: () => {
115
+ const cache = getWidgetsCache() || {};
116
+ const availableWidgets = Object.keys(cache || {}).filter(
117
+ (widgetType) => cache[widgetType]?.atomic_props_schema
118
+ );
119
+ return {
120
+ resources: availableWidgets.map((widgetType) => ({
121
+ uri: `elementor://widgets/schema/${widgetType}`,
122
+ name: "Widget schema for " + widgetType
123
+ }))
124
+ };
125
+ }
126
+ }),
127
+ {
128
+ description: "PropType schema for the specified widget type"
129
+ },
130
+ async (uri, variables) => {
131
+ const widgetType = typeof variables.widgetType === "string" ? variables.widgetType : variables.widgetType?.[0];
132
+ const propSchema = getWidgetsCache()?.[widgetType]?.atomic_props_schema;
133
+ if (!propSchema) {
134
+ throw new Error(`No prop schema found for element type: ${widgetType}`);
135
+ }
136
+ const asJson = Object.fromEntries(
137
+ Object.entries(propSchema).map(([key, propType]) => [
138
+ key,
139
+ Schema.propTypeToJsonSchema(propType)
140
+ ])
141
+ );
142
+ Schema.nonConfigurablePropKeys.forEach((key) => {
143
+ delete asJson[key];
144
+ });
145
+ return {
146
+ contents: [
147
+ {
148
+ uri: uri.toString(),
149
+ mimeType: "application/json",
150
+ text: JSON.stringify({
151
+ type: "object",
152
+ properties: asJson
153
+ })
154
+ }
155
+ ]
156
+ };
157
+ }
158
+ );
159
+ };
160
+
1
161
  // src/init.tsx
2
162
  import { injectIntoLogic, injectIntoTop } from "@elementor/editor";
3
163
  import { init as initInteractionsRepository } from "@elementor/editor-interactions";
@@ -533,7 +693,7 @@ function signalizedProcess(signal, steps = []) {
533
693
 
534
694
  // src/hooks/use-style-prop-resolver.ts
535
695
  import { useMemo as useMemo3 } from "react";
536
- import { getStylesSchema } from "@elementor/editor-styles";
696
+ import { getStylesSchema as getStylesSchema2 } from "@elementor/editor-styles";
537
697
 
538
698
  // src/renderers/create-props-resolver.ts
539
699
  import {
@@ -664,7 +824,7 @@ function useStylePropResolver() {
664
824
  return useMemo3(() => {
665
825
  return createPropsResolver({
666
826
  transformers: styleTransformersRegistry,
667
- schema: getStylesSchema(),
827
+ schema: getStylesSchema2(),
668
828
  onPropResolve: ({ key, value }) => {
669
829
  if (key !== "font-family" || typeof value !== "string") {
670
830
  return;
@@ -1330,8 +1490,8 @@ function initStyleTransformers() {
1330
1490
  }
1331
1491
 
1332
1492
  // src/legacy/init-legacy-views.ts
1333
- import { getWidgetsCache } from "@elementor/editor-elements";
1334
- import { __privateListenTo, v1ReadyEvent } from "@elementor/editor-v1-adapters";
1493
+ import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
1494
+ import { __privateListenTo, v1ReadyEvent as v1ReadyEvent2 } from "@elementor/editor-v1-adapters";
1335
1495
 
1336
1496
  // src/renderers/create-dom-renderer.ts
1337
1497
  import { createArrayLoader, createEnvironment } from "@elementor/twing";
@@ -1558,8 +1718,8 @@ function registerElementType(type, elementTypeGenerator) {
1558
1718
  elementsLegacyTypes[type] = elementTypeGenerator;
1559
1719
  }
1560
1720
  function initLegacyViews() {
1561
- __privateListenTo(v1ReadyEvent(), () => {
1562
- const config = getWidgetsCache() ?? {};
1721
+ __privateListenTo(v1ReadyEvent2(), () => {
1722
+ const config = getWidgetsCache2() ?? {};
1563
1723
  const legacyWindow = window;
1564
1724
  const renderer = createDomRenderer();
1565
1725
  Object.entries(config).forEach(([type, element]) => {
@@ -1579,174 +1739,13 @@ function initLegacyViews() {
1579
1739
  });
1580
1740
  }
1581
1741
 
1582
- // src/mcp/resources/widgets-schema-resource.ts
1583
- import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
1584
- import { ResourceTemplate } from "@elementor/editor-mcp";
1585
- import {
1586
- Schema
1587
- } from "@elementor/editor-props";
1588
- import { getStylesSchema as getStylesSchema2 } from "@elementor/editor-styles";
1589
- var WIDGET_SCHEMA_URI = "elementor://widgets/schema/{widgetType}";
1590
- var STYLE_SCHEMA_URI = "elementor://styles/schema/{category}";
1591
- var BEST_PRACTICES_URI = "elementor://styles/best-practices";
1592
- var initWidgetsSchemaResource = (reg) => {
1593
- const { mcpServer } = reg;
1594
- mcpServer.resource("styles-best-practices", BEST_PRACTICES_URI, async () => {
1595
- return {
1596
- contents: [
1597
- {
1598
- uri: BEST_PRACTICES_URI,
1599
- text: `# Styling best practices
1600
- Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
1601
- 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.
1602
-
1603
- 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.
1604
- The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.`
1605
- }
1606
- ]
1607
- };
1608
- });
1609
- mcpServer.resource(
1610
- "styles-schema",
1611
- new ResourceTemplate(STYLE_SCHEMA_URI, {
1612
- list: () => {
1613
- const categories = [...Object.keys(getStylesSchema2()), "custom_css"];
1614
- return {
1615
- resources: categories.map((category) => ({
1616
- uri: `elementor://styles/schema/${category}`,
1617
- name: "Style schema for " + category
1618
- }))
1619
- };
1620
- }
1621
- }),
1622
- {
1623
- description: "Common styles schema for the specified category"
1624
- },
1625
- async (uri, variables) => {
1626
- const category = typeof variables.category === "string" ? variables.category : variables.category?.[0];
1627
- if (category === "custom_css") {
1628
- return {
1629
- contents: [
1630
- {
1631
- uri: uri.toString(),
1632
- text: "Free style inline CSS string of properties and their values. Applicable for a single element, only the properties and values are accepted. Use this as a last resort for properties that are not covered with the schema."
1633
- }
1634
- ]
1635
- };
1636
- }
1637
- const stylesSchema = getStylesSchema2()[category];
1638
- if (!stylesSchema) {
1639
- throw new Error(`No styles schema found for category: ${category}`);
1640
- }
1641
- const cleanedupPropSchema = cleanupPropType(stylesSchema);
1642
- const asJson = Schema.propTypeToJsonSchema(cleanedupPropSchema);
1643
- return {
1644
- contents: [
1645
- {
1646
- uri: uri.toString(),
1647
- text: JSON.stringify(asJson)
1648
- }
1649
- ]
1650
- };
1651
- }
1652
- );
1653
- mcpServer.resource(
1654
- "widget-schema-by-type",
1655
- new ResourceTemplate(WIDGET_SCHEMA_URI, {
1656
- list: () => {
1657
- const cache = getWidgetsCache2() || {};
1658
- const availableWidgets = Object.keys(cache || {}).filter(
1659
- (widgetType) => cache[widgetType]?.atomic_props_schema
1660
- );
1661
- return {
1662
- resources: availableWidgets.map((widgetType) => ({
1663
- uri: `elementor://widgets/schema/${widgetType}`,
1664
- name: "Widget schema for " + widgetType
1665
- }))
1666
- };
1667
- }
1668
- }),
1669
- {
1670
- description: "PropType schema for the specified widget type"
1671
- },
1672
- async (uri, variables) => {
1673
- const widgetType = typeof variables.widgetType === "string" ? variables.widgetType : variables.widgetType?.[0];
1674
- const propSchema = getWidgetsCache2()?.[widgetType]?.atomic_props_schema;
1675
- if (!propSchema) {
1676
- throw new Error(`No prop schema found for element type: ${widgetType}`);
1677
- }
1678
- const cleanedupPropSchema = cleanupPropSchema(propSchema);
1679
- const asJson = Object.fromEntries(
1680
- Object.entries(cleanedupPropSchema).map(([key, propType]) => [
1681
- key,
1682
- Schema.propTypeToJsonSchema(propType)
1683
- ])
1684
- );
1685
- Schema.nonConfigurablePropKeys.forEach((key) => {
1686
- delete asJson[key];
1687
- });
1688
- return {
1689
- contents: [
1690
- {
1691
- uri: uri.toString(),
1692
- text: JSON.stringify(asJson)
1693
- }
1694
- ]
1695
- };
1696
- }
1697
- );
1698
- };
1699
- function cleanupPropSchema(propSchema) {
1700
- const result = {};
1701
- Object.keys(propSchema).forEach((propName) => {
1702
- result[propName] = cleanupPropType(propSchema[propName]);
1703
- });
1704
- return result;
1705
- }
1706
- function cleanupPropType(propType) {
1707
- const result = {};
1708
- Object.keys(propType).forEach((property) => {
1709
- switch (property) {
1710
- case "key":
1711
- case "kind":
1712
- result[property] = propType[property];
1713
- break;
1714
- case "meta":
1715
- case "settings":
1716
- {
1717
- if (Object.keys(propType[property] || {}).length > 0) {
1718
- result[property] = propType[property];
1719
- }
1720
- }
1721
- break;
1722
- }
1723
- });
1724
- if (result.kind === "plain") {
1725
- Object.defineProperty(result, "kind", { value: "string" });
1726
- } else if (result.kind === "array") {
1727
- result.item_prop_type = cleanupPropType(propType.item_prop_type);
1728
- } else if (result.kind === "object") {
1729
- const shape = propType.shape;
1730
- const cleanedShape = cleanupPropSchema(shape);
1731
- result.shape = cleanedShape;
1732
- } else if (result.kind === "union") {
1733
- const propTypes = propType.prop_types;
1734
- const cleanedPropTypes = {};
1735
- Object.keys(propTypes).forEach((key) => {
1736
- cleanedPropTypes[key] = cleanupPropType(propTypes[key]);
1737
- });
1738
- result.prop_types = cleanedPropTypes;
1739
- }
1740
- return result;
1741
- }
1742
-
1743
1742
  // src/mcp/tools/build-composition/tool.ts
1744
1743
  import {
1745
1744
  createElement as createElement6,
1746
1745
  deleteElement,
1747
1746
  generateElementId,
1748
1747
  getContainer as getContainer3,
1749
- getWidgetsCache as getWidgetsCache4
1748
+ getWidgetsCache as getWidgetsCache5
1750
1749
  } from "@elementor/editor-elements";
1751
1750
 
1752
1751
  // src/mcp/utils/do-update-element-property.ts
@@ -1757,14 +1756,10 @@ import {
1757
1756
  updateElementSettings as updateElementSettings2,
1758
1757
  updateElementStyle
1759
1758
  } from "@elementor/editor-elements";
1760
- import {
1761
- getPropSchemaFromCache,
1762
- Schema as Schema2,
1763
- stringPropTypeUtil
1764
- } from "@elementor/editor-props";
1759
+ import { getPropSchemaFromCache, Schema as Schema2 } from "@elementor/editor-props";
1765
1760
  import { getStylesSchema as getStylesSchema3 } from "@elementor/editor-styles";
1766
1761
  function resolvePropValue(value, forceKey) {
1767
- return Schema2.adjustLlmPropValueSchema(value, forceKey);
1762
+ return Schema2.adjustLlmPropValueSchema(value, { forceKey });
1768
1763
  }
1769
1764
  var doUpdateElementProperty = (params) => {
1770
1765
  const { elementId, propertyName, propertyValue, elementType } = params;
@@ -1777,11 +1772,11 @@ var doUpdateElementProperty = (params) => {
1777
1772
  if (key === "custom_css") {
1778
1773
  return [key, val];
1779
1774
  }
1780
- const { key: propKey, kind } = styleSchema?.[key] || {};
1781
- if (!propKey && kind !== "union") {
1775
+ const { key: propKey2, kind } = styleSchema?.[key] || {};
1776
+ if (!propKey2 && kind !== "union") {
1782
1777
  throw new Error(`_styles property ${key} is not supported.`);
1783
1778
  }
1784
- return [key, resolvePropValue(val, propKey)];
1779
+ return [key, resolvePropValue(val, propKey2)];
1785
1780
  })
1786
1781
  );
1787
1782
  let customCss;
@@ -1789,8 +1784,11 @@ var doUpdateElementProperty = (params) => {
1789
1784
  const propertyRawSchema = styleSchema[stylePropName];
1790
1785
  if (stylePropName === "custom_css") {
1791
1786
  let customCssValue = propertyMapValue[stylePropName];
1792
- if (typeof customCssValue === "object") {
1793
- customCssValue = stringPropTypeUtil.extract(customCssValue) || customCssValue?.value || "";
1787
+ if (typeof customCssValue === "object" && customCssValue && customCssValue.value) {
1788
+ customCssValue = String(customCssValue.value);
1789
+ }
1790
+ if (!customCssValue) {
1791
+ customCssValue = "";
1794
1792
  }
1795
1793
  customCss = {
1796
1794
  raw: btoa(customCssValue)
@@ -1799,7 +1797,7 @@ var doUpdateElementProperty = (params) => {
1799
1797
  }
1800
1798
  const isSupported = !!propertyRawSchema;
1801
1799
  if (!isSupported) {
1802
- throw new Error(`_styles property ${stylePropName} is not supported.`);
1800
+ throw new Error(`Style property ${stylePropName} is not supported.`);
1803
1801
  }
1804
1802
  if (propertyRawSchema.kind === "plain") {
1805
1803
  if (typeof propertyMapValue[stylePropName] !== "object") {
@@ -1811,6 +1809,7 @@ var doUpdateElementProperty = (params) => {
1811
1809
  }
1812
1810
  }
1813
1811
  });
1812
+ delete transformedStyleValues.custom_css;
1814
1813
  const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
1815
1814
  if (!localStyle) {
1816
1815
  createElementStyle({
@@ -1854,7 +1853,8 @@ var doUpdateElementProperty = (params) => {
1854
1853
  )}`
1855
1854
  );
1856
1855
  }
1857
- const value = resolvePropValue(propertyValue);
1856
+ const propKey = elementPropSchema[propertyName].key;
1857
+ const value = resolvePropValue(propertyValue, propKey);
1858
1858
  updateElementSettings2({
1859
1859
  id: elementId,
1860
1860
  props: {
@@ -1864,17 +1864,91 @@ var doUpdateElementProperty = (params) => {
1864
1864
  });
1865
1865
  };
1866
1866
 
1867
+ // src/mcp/utils/validate-input.ts
1868
+ import { getWidgetsCache as getWidgetsCache4 } from "@elementor/editor-elements";
1869
+ import { Schema as Schema3 } from "@elementor/editor-props";
1870
+ import { getStylesSchema as getStylesSchema4 } from "@elementor/editor-styles";
1871
+ var _widgetsSchema = null;
1872
+ var validateInput = {
1873
+ get widgetsSchema() {
1874
+ if (!_widgetsSchema) {
1875
+ const schema2 = {};
1876
+ const cache = getWidgetsCache4();
1877
+ if (!cache) {
1878
+ return {};
1879
+ }
1880
+ Object.entries(cache).forEach(([widgetType, widgetData]) => {
1881
+ if (widgetData.atomic_props_schema) {
1882
+ schema2[widgetType] = structuredClone(widgetData.atomic_props_schema);
1883
+ }
1884
+ });
1885
+ _widgetsSchema = schema2;
1886
+ }
1887
+ return _widgetsSchema;
1888
+ },
1889
+ validateProps(schema2, values, ignore = []) {
1890
+ if (!schema2) {
1891
+ throw new Error("No schema provided for validation.");
1892
+ }
1893
+ const errors = [];
1894
+ let hasInvalidKey = false;
1895
+ Object.entries(values).forEach(([propName, propValue]) => {
1896
+ if (ignore.includes(propName)) {
1897
+ return;
1898
+ }
1899
+ const propSchema = schema2[propName];
1900
+ if (!propSchema) {
1901
+ errors.push(`Property "${propName}" is not defined in the schema.`);
1902
+ hasInvalidKey = true;
1903
+ } else if (!Schema3.isPropKeyConfigurable(propName)) {
1904
+ errors.push(`Property "${propName}" is not configurable.`);
1905
+ } else {
1906
+ const { valid, errorMessages } = Schema3.validatePropValue(propSchema, propValue);
1907
+ if (!valid) {
1908
+ errors.push(`Invalid property "${propName}": ${errorMessages}`);
1909
+ }
1910
+ }
1911
+ });
1912
+ if (hasInvalidKey) {
1913
+ errors.push("Available properties: " + Object.keys(schema2).join(", "));
1914
+ }
1915
+ return {
1916
+ errors,
1917
+ valid: errors.length === 0
1918
+ };
1919
+ },
1920
+ validateStyles(values) {
1921
+ const styleSchema = getStylesSchema4();
1922
+ const customCssValue = values.custom_css;
1923
+ const result = this.validateProps(styleSchema, values, ["custom_css"]);
1924
+ const appendInvalidCustomCssErr = () => {
1925
+ result.valid = false;
1926
+ result.errors = result.errors || [];
1927
+ result.errors.push('Invalid property "custom_css". Expected a string value.');
1928
+ };
1929
+ if (customCssValue && typeof customCssValue === "object") {
1930
+ if (typeof customCssValue.value !== "string") {
1931
+ appendInvalidCustomCssErr();
1932
+ }
1933
+ } else if (typeof customCssValue !== "string" && typeof customCssValue !== "undefined" && customCssValue !== null) {
1934
+ appendInvalidCustomCssErr();
1935
+ }
1936
+ return result;
1937
+ },
1938
+ validatePropSchema(widgetType, values, ignore = []) {
1939
+ const schema2 = this.widgetsSchema[widgetType];
1940
+ if (!schema2) {
1941
+ return { valid: false, errors: [`No schema found for widget type "${widgetType}".`] };
1942
+ }
1943
+ return this.validateProps(schema2, values, ignore);
1944
+ }
1945
+ };
1946
+
1867
1947
  // src/mcp/tools/build-composition/prompt.ts
1868
1948
  import { toolPrompts } from "@elementor/editor-mcp";
1869
1949
  var generatePrompt = () => {
1870
1950
  const buildCompositionsToolPrompt = toolPrompts("build-compositions");
1871
1951
  buildCompositionsToolPrompt.description(`
1872
- Build entire elementor widget comositions representing complex structures of nested elements.
1873
-
1874
- # When to use this tool
1875
- Always prefer this tool when the user requires to build a composition of elements, such as cards, heros, or inspired from other pages or HTML compositions.
1876
- Prefer this tool over any other tool for building HTML structure, unless you are specified to use a different tool.
1877
-
1878
1952
  # **CRITICAL - REQUIRED RESOURCES (Must read before using this tool)**
1879
1953
  1. [${WIDGET_SCHEMA_URI}]
1880
1954
  Required to understand which widgets are available, and what are their configuration schemas.
@@ -1883,6 +1957,16 @@ Prefer this tool over any other tool for building HTML structure, unless you are
1883
1957
  Required to understand the styles schema for the widgets. All widgets share the same styles schema.
1884
1958
  3. List of allowed custom tags for building the structure is derived from the list of widgets schema resources.
1885
1959
 
1960
+ # DESIGN QUALITY IMPERATIVE
1961
+ You are generating designs for real users who expect distinctive, intentional aesthetics - NOT generic AI output.
1962
+ **The Core Challenge**: Large language models naturally converge toward statistically common design patterns during generation. This creates predictable, uninspired results that users describe as "AI slop": safe color schemes, default typography hierarchies, minimal contrast, and timid spacing.
1963
+ **Your Mission**: Actively resist distributional convergence by making intentional, distinctive design choices across all aesthetic dimensions. Every design decision should have a clear purpose tied to visual hierarchy, brand personality, or user experience goals.
1964
+ When in doubt between "safe" and "distinctive," choose distinctive - users can always request refinements, but they cannot salvage generic foundations.
1965
+
1966
+ # When to use this tool
1967
+ Always prefer this tool when the user requires to build a composition of elements, such as cards, heros, or inspired from other pages or HTML compositions.
1968
+ Prefer this tool over any other tool for building HTML structure, unless you are specified to use a different tool.
1969
+
1886
1970
  # Instructions
1887
1971
  1. Understand the user requirements carefully.
1888
1972
  2. Build a valid XML structure using only the allowed custom tags provided. For example, if you
@@ -1899,20 +1983,185 @@ Prefer this tool over any other tool for building HTML structure, unless you are
1899
1983
  Layout properties, such as margin, padding, align, etc. must be applied using the [${STYLE_SCHEMA_URI}] PropValues.
1900
1984
  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".
1901
1985
  8. Make sure that non-container elements do NOT have any nested elements.
1902
- 9. Unsless the user specifically requires structure only, BE EXPRESSIVE AND VISUALLY CREATIVE AS POSSIBLE IN APPLYING STYLE CONFIGURATION.
1903
- In the case of doubt, prefer adding more styles to make the composition visually appealing.
1904
-
1905
- # Additional Guidelines
1906
- - Most users expect the structure to be well designed and visually appealing.
1907
- - Use layout properties, ensure "white space" design approach is followed, and make sure the composition is visually balanced.
1908
- - Use appropriate spacing, alignment, and sizing to create a harmonious layout.
1909
- - Consider the visual hierarchy of elements to guide the user's attention effectively.
1910
- - You are encouraged to use colors, typography, and other style properties to enhance the visual appeal, as long as they are part of the configuration schema for the elements used.
1911
- - Always aim for a clean and professional look that aligns with modern design principles.
1912
- - 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.
1913
- - 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.
1914
- - Attempt to use layout, margin, padding, size properties from the styles schema.
1915
- - If your elements library is limited, encourage use of nesting containers to achieve complex layouts.
1986
+ 9. **CRITICAL - CUSTOM CSS PRIORITY**: Prefer using style schema. Custom CSS is ONLY FOR UNSUPPRTED schema styles.
1987
+ ALWAYS PRIORITIZE using the style schema PropValues for styling elements as they provide better user experience in the editor, and UI features for the end-users.
1988
+ - Use custom_css only for style attributes that ARE NOT SUPPORTED via the style schema.
1989
+
1990
+ # DESIGN VECTORS - Concrete Implementation Guidance
1991
+
1992
+ ## 1. Typography & Visual Hierarchy
1993
+
1994
+ **Avoid Distributional Defaults:**
1995
+ - NO generic sans-serifs as primary typefaces (Inter, Roboto, Arial, Helvetica)
1996
+ - NO timid size ratios (1.2x, 1.5x scaling)
1997
+ - NO uniform font weights (everything at 400 or 600)
1998
+
1999
+ **Intentional Alternatives:**
2000
+ - **For Technical/Modern**: Consider monospace headlines (JetBrains Mono, SF Mono) paired with clean body text
2001
+ - **For Editorial/Elegant**: Consider serif headlines (Playfair Display, Crimson Text) with sans-serif body
2002
+ - **For Playful/Creative**: Consider display fonts with character, paired with highly legible body text
2003
+
2004
+ **Scale & Contrast Implementation:**
2005
+ - Headline-to-body size ratios: 3x minimum (e.g., 48px headline vs 16px body)
2006
+ - Use extreme weight contrasts: pair weight-100 or 200 with weight-800 or 900
2007
+ - Line height contrasts: tight headlines (1.1) vs. generous body (1.7)
2008
+ - Letter spacing: compressed headlines (-0.02em to -0.05em) vs. open small text (0.03em+)
2009
+
2010
+ **Hierarchy Mapping:**
2011
+ /* Intentional hierarchy example */
2012
+ H1: font-size: 3.5rem; font-weight: 900; line-height: 1.1; letter-spacing: -0.03em;
2013
+ H2: font-size: 2rem; font-weight: 200; line-height: 1.2;
2014
+ Body: font-size: 1rem; font-weight: 400; line-height: 1.7;
2015
+ Caption: font-size: 0.75rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
2016
+
2017
+ ## 2. Color & Theme Strategy
2018
+
2019
+ **Avoid Distributional Defaults:**
2020
+ - NO purple gradients or blue-purple color schemes (massively overrepresented in AI output)
2021
+ - NO evenly-distributed color palettes (3-4 colors used equally)
2022
+ - NO timid pastels or all-neutral schemes
2023
+ - NO #333333, #666666, #999999 grays
2024
+
2025
+ **Intentional Alternatives:**
2026
+ - **Commit to a Dominant Color**: Choose ONE primary brand color that appears in 60-70% of colored elements
2027
+ - **Sharp Accent Strategy**: Use 1-2 high-contrast accent colors sparingly (10-15% of colored elements)
2028
+ - **Neutrals with Personality**: Replace pure grays with warm (#3d3228, #f5f1ed) or cool (#2a2f3d, #f0f2f5) tinted neutrals
2029
+
2030
+ **Color Psychology Mapping:**
2031
+ - Energy/Action \u2192 Warm reds, oranges, yellows (NOT purple/blue)
2032
+ - Trust/Calm \u2192 Deep teals, forest greens (NOT generic blue)
2033
+ - Luxury/Premium \u2192 Deep burgundy, emerald, charcoal with gold accents
2034
+ - Playful/Creative \u2192 Unexpected combinations (coral + mint, mustard + navy)
2035
+
2036
+ **Implementation:**
2037
+ /* Intentional color system example */
2038
+ --brand-primary: #d84315; /* Dominant: Deep orange */
2039
+ --brand-accent: #00bfa5; /* Accent: Teal (complementary) */
2040
+ --neutral-dark: #2d2622; /* Warm dark brown, not #333 */
2041
+ --neutral-light: #faf8f6; /* Warm off-white, not pure white */
2042
+ --background: linear-gradient(135deg, #faf8f6 0%, #f0ebe6 100%); /* Subtle warmth */
2043
+
2044
+ ## 3. Spatial Design & White Space
2045
+
2046
+ **Avoid Distributional Defaults:**
2047
+ - NO uniform spacing (everything 16px or 24px)
2048
+ - NO cramped layouts that maximize content density
2049
+ - NO default container widths (1200px, 1440px)
2050
+
2051
+ **Intentional Alternatives:**
2052
+ - **Breathing Room**: Use generous white space as a design element (80-120px vertical spacing between sections)
2053
+ - **Asymmetric Spacing**: Vary padding dramatically (small: 12px, medium: 48px, large: 96px)
2054
+ - **Content Width Strategy**:
2055
+ - Reading content: max 65-75 characters (600-700px)
2056
+ - Hero sections: asymmetric layouts, not centered blocks
2057
+ - Cards/components: vary sizes intentionally, not uniform grids
2058
+
2059
+ **Implementation:**
2060
+ /* Intentional spacing scale */
2061
+ --space-xs: 0.5rem; /* 8px */
2062
+ --space-sm: 1rem; /* 16px */
2063
+ --space-md: 3rem; /* 48px */
2064
+ --space-lg: 6rem; /* 96px */
2065
+ --space-xl: 10rem; /* 160px */
2066
+
2067
+ /* Use in combinations: */
2068
+ padding: var(--space-lg) var(--space-md); /* Not uniform padding */
2069
+ margin-bottom: var(--space-xl); /* Generous section breaks */
2070
+
2071
+ ## 4. Backgrounds & Atmospheric Depth
2072
+
2073
+ **Avoid Distributional Defaults:**
2074
+ - NO solid white or light gray backgrounds
2075
+ - NO single-color backgrounds
2076
+ - NO generic gradient overlays
2077
+
2078
+ **Intentional Alternatives:**
2079
+ - **Layered Gradients**: Combine 2-3 subtle gradients for depth
2080
+ - **Geometric Patterns**: SVG patterns, mesh gradients, or subtle noise textures
2081
+ - **Strategic Contrast**: Alternate between light and dark sections for rhythm
2082
+
2083
+ **Implementation:**
2084
+ /* Intentional background example */
2085
+ background:
2086
+ radial-gradient(circle at 20% 30%, rgba(216, 67, 21, 0.08) 0%, transparent 50%),
2087
+ radial-gradient(circle at 80% 70%, rgba(0, 191, 165, 0.06) 0%, transparent 50%),
2088
+ linear-gradient(135deg, #faf8f6 0%, #f0ebe6 100%);
2089
+
2090
+ ## 5. Visual Hierarchy Principles
2091
+
2092
+ **Clear Priority System:**
2093
+ 1. **Primary Focus (1 element)**: Largest, highest contrast, most visual weight
2094
+ 2. **Secondary Elements (2-3 elements)**: 40-60% of primary size, reduced contrast
2095
+ 3. **Tertiary/Support (everything else)**: Minimal visual weight, muted colors
2096
+
2097
+ **Contrast Techniques:**
2098
+ - Size: 3x+ differences between hierarchy levels
2099
+ - Weight: 300+ difference in font-weight values
2100
+ - Color: Primary gets brand color, secondary gets neutral, tertiary gets muted
2101
+ - Space: Primary gets 2x+ surrounding white space vs. secondary
2102
+
2103
+ ## 6. EXAMPLES - Intentional vs. Generic Design
2104
+
2105
+ ### \u274C GENERIC (Distributional Convergence)
2106
+
2107
+ {
2108
+ "xmlStructure": "<e-flexbox configuration-id="flex1"><e-heading configuration-id="heading1"></e-heading><e-button configuration-id="button1"></e-button></e-flexbox>",
2109
+ "elementConfig": {
2110
+ "heading1": {
2111
+ "title": { "$$type": "string", "value": "Welcome to Our Site" }
2112
+ }
2113
+ },
2114
+ "stylesConfig": {
2115
+ "heading1": {
2116
+ "font-size": {
2117
+ "$$type": "size",
2118
+ "value": {
2119
+ "size": { "$$type": "number", "value": 24 },
2120
+ "unit": { "$$type": "string", "value": "px" }
2121
+ }
2122
+ },
2123
+ },
2124
+ "button1": {
2125
+ "custom_css": "background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 12px 24px;"
2126
+ }
2127
+ }
2128
+ }
2129
+
2130
+ **Why Generic**: 24px default size, #333 safe gray, 600 weight (middle-ground), purple gradient (AI clich\xE9), uniform 12/24px padding
2131
+
2132
+ ### \u2705 INTENTIONAL (Resisting Convergence)
2133
+ {
2134
+ "xmlStructure": "<e-flexbox configuration-id="hero-section"><e-heading configuration-id="hero-title"></e-heading><e-text configuration-id="hero-subtitle"></e-text><e-button configuration-id="hero-cta"></e-button></e-flexbox>",
2135
+ "elementConfig": {
2136
+ "hero-title": {
2137
+ "title": { "$$type": "string", "value": "Transform Your Workflow" }
2138
+ },
2139
+ "hero-subtitle": {
2140
+ "content": { "$$type": "string", "value": "Built for teams who refuse to compromise on quality" }
2141
+ }
2142
+ },
2143
+ "stylesConfig": {
2144
+ "hero-section": {
2145
+ "custom_css": "display: flex; flex-direction: column; align-items: flex-start; gap: 3rem; background: radial-gradient(circle at 30% 20%, rgba(216, 67, 21, 0.1) 0%, transparent 60%), linear-gradient(135deg, #faf8f6 0%, #f0ebe6 100%); padding: 10rem 3rem;"
2146
+ },
2147
+ "hero-title": {
2148
+ "custom_css": "font-size: 4.5rem; font-weight: 900; line-height: 1.05; letter-spacing: -0.04em; color: #2d2622; max-width: 700px;"
2149
+ },
2150
+ "hero-subtitle": {
2151
+ "custom_css": "font-size: 1.25rem; font-weight: 200; line-height: 1.7; letter-spacing: 0.01em; color: #5a534d; max-width: 600px;"
2152
+ },
2153
+ "hero-cta": {
2154
+ "custom_css": "background: #d84315; color: #ffffff; padding: 1.25rem 3rem; font-size: 1rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; border-radius: 2px; box-shadow: 0 4px 16px rgba(216, 67, 21, 0.25); transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;"
2155
+ }
2156
+ }
2157
+ }
2158
+
2159
+
2160
+ **Why Intentional**:
2161
+ - Typography: 4.5rem headline (3.6x body), weight 900 vs 200 contrast, tight leading
2162
+ - Color: Warm orange primary (#d84315), warm neutrals (#2d2622, #5a534d) NOT #333/#666
2163
+ - Spacing: 10rem vertical padding (generous), 3rem gap, asymmetric alignment
2164
+ - Background: Layered gradients with subtle brand color accent
1916
2165
 
1917
2166
  # CONSTRAINTS
1918
2167
  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.
@@ -1923,6 +2172,28 @@ NO LINKS ALLOWED. Never apply links to elements, even if they appear in the Prop
1923
2172
  elementConfig values must align with the widget's PropType schema, available at the resource [${WIDGET_SCHEMA_URI}].
1924
2173
  stylesConfig values must align with the common styles PropType schema, available at the resource [${STYLE_SCHEMA_URI}].
1925
2174
 
2175
+ # DESIGN QUALITY CONSTRAINTS
2176
+
2177
+ **Typography Constraints:**
2178
+ - NEVER use Inter, Roboto, Arial, or Helvetica as primary display fonts
2179
+ - NEVER use font-size ratios smaller than 2.5x between headlines and body
2180
+ - NEVER use font-weight values between 500-700 for headlines (go lighter or heavier)
2181
+
2182
+ **Color Constraints:**
2183
+ - NEVER use purple gradients or blue-purple color schemes
2184
+ - NEVER use pure grays (#333, #666, #999) - use tinted neutrals instead
2185
+ - NEVER distribute colors evenly - commit to ONE dominant color
2186
+ - NEVER use more than 3 core colors (1 dominant, 1-2 accents)
2187
+
2188
+ **Spacing Constraints:**
2189
+ - NEVER use uniform spacing across all elements
2190
+ - NEVER use section padding less than 4rem (64px) for hero/major sections
2191
+ - NEVER center everything - use asymmetric layouts for visual interest
2192
+
2193
+ **Background Constraints:**
2194
+ - NEVER use solid white (#ffffff) or light gray (#f5f5f5) backgrounds without texture/gradients
2195
+ - ALWAYS layer at least 2 gradient or color elements for atmospheric depth
2196
+
1926
2197
  # Parameters
1927
2198
  All parameters are MANDATORY.
1928
2199
  - xmlStructure
@@ -1931,6 +2202,14 @@ All parameters are MANDATORY.
1931
2202
 
1932
2203
  If unsure about the configuration of a specific property, read the schema resources carefully.
1933
2204
 
2205
+ # About our widgets
2206
+ Most widgets are self-explanatory by their name. Here is some additional information.
2207
+ SVG elements are bound to internal content upload. Avoid usage, unless you have tools to upload SVG content.
2208
+ e-div-block - By default is ceneterd aligned and vertically stacked. To modify this, apply style configuration.
2209
+ e-flexbox - By default is a flex container with row direction. To modify this, apply style configuration.
2210
+
2211
+ When working with containers, do not forget to apply style schema for controlling the layout.
2212
+
1934
2213
 
1935
2214
  `);
1936
2215
  buildCompositionsToolPrompt.example(`
@@ -1945,6 +2224,9 @@ A Heading and a button inside a flexbox
1945
2224
  },
1946
2225
  },
1947
2226
  stylesConfig: {
2227
+ "flex1": {
2228
+ "custom_css": "background: radial-gradient(circle at 20% 30%, rgba(216, 67, 21, 0.08) 0%, transparent 50%), radial-gradient(circle at 80% 70%, rgba(0, 191, 165, 0.06) 0%, transparent 50%), linear-gradient(135deg, #faf8f6 0%, #f0ebe6 100%); display: flex; flex-direction: column; align-items: center; padding: 80px 32px; gap: 48px;"
2229
+ },
1948
2230
  "heading1": {
1949
2231
  "font-size": {
1950
2232
  "$$type": "size",
@@ -1989,13 +2271,16 @@ var inputSchema = {
1989
2271
  xmlStructure: z.string().describe("The XML structure representing the composition to be built"),
1990
2272
  elementConfig: z.record(
1991
2273
  z.string().describe("The configuration id"),
1992
- z.record(z.string().describe("property name"), z.any().describe("The PropValue for the property"))
2274
+ z.record(
2275
+ z.string().describe("property name"),
2276
+ z.any().describe(`The PropValue for the property, refer to ${WIDGET_SCHEMA_URI}`)
2277
+ )
1993
2278
  ).describe("A record mapping element IDs to their configuration objects. REQUIRED"),
1994
2279
  stylesConfig: z.record(
1995
2280
  z.string().describe("The configuration id"),
1996
2281
  z.record(
1997
- z.string().describe("_styles property name"),
1998
- z.any().describe("The PropValue for the style property. MANDATORY")
2282
+ z.string().describe("StyleSchema property name"),
2283
+ z.any().describe(`The PropValue for the style property. MANDATORY, refer to [${STYLE_SCHEMA_URI}]`)
1999
2284
  )
2000
2285
  ).describe(
2001
2286
  `A record mapping element IDs to their styles configuration objects. Use the actual styles schema from [${STYLE_SCHEMA_URI}].`
@@ -2014,6 +2299,13 @@ var initBuildCompositionsTool = (reg) => {
2014
2299
  name: "build-compositions",
2015
2300
  description: generatePrompt(),
2016
2301
  schema: inputSchema,
2302
+ requiredResources: [
2303
+ { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
2304
+ { description: "Global Classes", uri: "elementor://global-classes" },
2305
+ { description: "Styles schema", uri: STYLE_SCHEMA_URI },
2306
+ { description: "Global Variables", uri: "elementor://global-variables" },
2307
+ { description: "Styles best practices", uri: BEST_PRACTICES_URI }
2308
+ ],
2017
2309
  outputSchema,
2018
2310
  handler: async (params) => {
2019
2311
  let xml = null;
@@ -2021,7 +2313,7 @@ var initBuildCompositionsTool = (reg) => {
2021
2313
  const errors = [];
2022
2314
  const softErrors = [];
2023
2315
  const rootContainers = [];
2024
- const widgetsCache = getWidgetsCache4() || {};
2316
+ const widgetsCache = getWidgetsCache5() || {};
2025
2317
  const documentContainer = getContainer3("document");
2026
2318
  try {
2027
2319
  const parser = new DOMParser();
@@ -2061,22 +2353,23 @@ var initBuildCompositionsTool = (reg) => {
2061
2353
  try {
2062
2354
  const configObject = elementConfig[configId] || {};
2063
2355
  const styleObject = stylesConfig[configId] || {};
2064
- configObject._styles = styleObject;
2356
+ const { errors: propsValidationErrors } = validateInput.validatePropSchema(
2357
+ elementTag,
2358
+ configObject
2359
+ );
2360
+ errors.push(...(propsValidationErrors || []).map((msg) => new Error(msg)));
2361
+ const { errors: stylesValidationErrors } = validateInput.validateStyles(styleObject);
2362
+ errors.push(...(stylesValidationErrors || []).map((msg) => new Error(msg)));
2363
+ if (propsValidationErrors?.length || stylesValidationErrors?.length) {
2364
+ return;
2365
+ }
2366
+ configObject._styles = styleObject || {};
2065
2367
  for (const [propertyName, propertyValue] of Object.entries(configObject)) {
2066
- const widgetSchema = widgetsCache[elementTag];
2067
- if (!widgetSchema?.atomic_props_schema?.[propertyName] && propertyName !== "_styles" && propertyName !== "custom_css") {
2068
- softErrors.push(
2069
- new Error(
2070
- `Property "${propertyName}" does not exist on element type "${elementTag}".`
2071
- )
2072
- );
2073
- continue;
2074
- }
2075
2368
  try {
2076
2369
  doUpdateElementProperty({
2077
2370
  elementId: newElement.id,
2078
2371
  propertyName,
2079
- propertyValue: propertyName === "custom_css" ? { _styles: propertyValue } : propertyValue,
2372
+ propertyValue,
2080
2373
  elementType: elementTag
2081
2374
  });
2082
2375
  } catch (error) {
@@ -2111,14 +2404,12 @@ var initBuildCompositionsTool = (reg) => {
2111
2404
  options: { useHistory: false }
2112
2405
  });
2113
2406
  });
2114
- }
2115
- if (errors.length > 0) {
2116
2407
  const errorText = `Failed to build composition with the following errors:
2117
2408
 
2118
2409
 
2119
2410
  ${errors.map((e) => typeof e === "string" ? e : e.message).join("\n\n")}
2120
2411
  "Missing $$type" errors indicate that the configuration objects are invalid. Try again and apply **ALL** object entries with correct $$type.
2121
- Now that you have these errors, fix them and try again. Errors regarding configuration objects, please check again the PropType schemas`;
2412
+ Now that you have these errors, fix them and try again. Errors regarding configuration objects, please check against the PropType schemas`;
2122
2413
  throw new Error(errorText);
2123
2414
  }
2124
2415
  if (!xml) {
@@ -2146,10 +2437,10 @@ var configureElementToolPrompt = `Configure an existing element on the page.
2146
2437
  # **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
2147
2438
  1. [${WIDGET_SCHEMA_URI}]
2148
2439
  Required to understand which widgets are available, and what are their configuration schemas.
2149
- 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.
2440
+ 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 parameter values correctly.
2150
2441
  2. [${STYLE_SCHEMA_URI}]
2151
2442
  Required to understand the styles schema for the widgets. All widgets share the same styles schema, grouped by categories.
2152
- Use this resource to understand which style properties are available for each element, and how to structure the "_styles" configuration property.
2443
+ Use this resource to understand which style properties are available for each element, and how to structure the "stylePropertiesToChange" parameter.
2153
2444
  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.
2154
2445
 
2155
2446
  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}
@@ -2157,16 +2448,18 @@ All widgets share a common _style property for styling, which uses the common st
2157
2448
  Retreive and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
2158
2449
 
2159
2450
  # Parameters
2160
- - propertiesToChange: An object containing the properties to change, with their new values. MANDATORY
2451
+ - propertiesToChange: An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.
2452
+ - stylePropertiesToChange: An object containing the style properties to change, with their new values. OPTIONAL
2161
2453
  - elementId: The ID of the element to configure. MANDATORY
2162
2454
  - elementType: The type of the element to configure (i.e. e-heading, e-button). MANDATORY
2163
2455
 
2164
2456
  # When to use this tool
2165
2457
  When a user requires to change anything in an element, such as updating text, colors, sizes, or other configurable properties.
2166
2458
  This tool handles elements of type "widget".
2167
- This tool handles styling elements, using the _styles property in the configuration.
2459
+ This tool handles styling elements, using the "stylePropertiesToChange" parameter.
2168
2460
 
2169
2461
  The element's schema must be known before using this tool.
2462
+ The style schema must be known before using this tool.
2170
2463
 
2171
2464
  Attached resource link describing how PropType schema should be parsed as PropValue for this tool.
2172
2465
 
@@ -2184,13 +2477,13 @@ ALWAYS MAKE SURE you have the PropType schemas for the element you are configuri
2184
2477
 
2185
2478
  You can use multiple property changes at once by providing multiple entries in the propertiesToChange object, including _style alongside non-style props.
2186
2479
  Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
2187
- Nested properties, such as for the _styles, should include a "_styles" property with object containing the definitions to change.
2188
2480
 
2189
2481
  Make sure you have the "widget-schema-by-type" resource available to retreive the PropType schema for the element type you are configuring.
2482
+ Make sure you have to "styles-schema" resources available to retreive the common styles schema.
2190
2483
 
2191
2484
  # How to configure elements
2192
2485
  We use a dedicated PropType Schema for configuring elements, including styles. When you configure an element, you must use the EXACT PropType Value as defined in the schema.
2193
- For _styles, use the style schema provided, as it also uses the PropType format.
2486
+ For styleProperties, use the style schema provided, as it also uses the PropType format.
2194
2487
  For all non-primitive types, provide the key property as defined in the schema as $$type in the generated objecct, as it is MANDATORY for parsing.
2195
2488
 
2196
2489
  Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
@@ -2208,23 +2501,24 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
2208
2501
  $$type: 'boolean',
2209
2502
  value: false
2210
2503
  },
2211
- _styles: {
2212
- // List of available keys available at the [${STYLE_SCHEMA_URI}] dynamic resource
2213
- 'line-height': {
2214
- $$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
2215
- value: {
2216
- size: {
2217
- $$type: 'number',
2218
- value: 20
2219
- },
2220
- unit: {
2221
- $$type: 'string',
2222
- value: 'px'
2223
- }
2504
+ },
2505
+ stylePropertiesToChange: {
2506
+ 'line-height': {
2507
+ $$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
2508
+ value: {
2509
+ size: {
2510
+ $$type: 'number',
2511
+ value: 20
2512
+ },
2513
+ unit: {
2514
+ $$type: 'string',
2515
+ value: 'px'
2224
2516
  }
2225
2517
  }
2226
2518
  }
2227
- }
2519
+ },
2520
+ elementId: 'element-id',
2521
+ elementType: 'element-type'
2228
2522
  };
2229
2523
  \`\`\`
2230
2524
 
@@ -2237,11 +2531,15 @@ The $$type property is MANDATORY for every value, it is required to parse the va
2237
2531
  import { z as z2 } from "@elementor/schema";
2238
2532
  var inputSchema2 = {
2239
2533
  propertiesToChange: z2.record(
2240
- z2.string().describe(
2241
- "The property name. If nested property, provide the root property name, and the object delta only."
2242
- ),
2243
- z2.any().describe("The property's value")
2244
- ).describe("An object record containing property names and their new values to be set on the element").optional(),
2534
+ z2.string().describe("The property name."),
2535
+ z2.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
2536
+ z2.any()
2537
+ ).describe("An object record containing property names and their new values to be set on the element"),
2538
+ stylePropertiesToChange: z2.record(
2539
+ z2.string().describe("The style property name"),
2540
+ z2.any().describe(`The style PropValue, refer to [${STYLE_SCHEMA_URI}] how to generate values`),
2541
+ z2.any()
2542
+ ).describe("An object record containing style property names and their new values to be set on the element").default({}),
2245
2543
  elementType: z2.string().describe("The type of the element to retreive the schema"),
2246
2544
  elementId: z2.string().describe("The unique id of the element to configure")
2247
2545
  };
@@ -2259,19 +2557,29 @@ var initConfigureElementTool = (reg) => {
2259
2557
  description: configureElementToolPrompt,
2260
2558
  schema: inputSchema2,
2261
2559
  outputSchema: outputSchema2,
2262
- handler: ({ elementId, propertiesToChange, elementType }) => {
2263
- if (!propertiesToChange) {
2264
- throw new Error(
2265
- "propertiesToChange is required to configure an element. Now that you have this information, ensure you have the schema and try again."
2266
- );
2267
- }
2560
+ requiredResources: [
2561
+ { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
2562
+ { description: "Styles schema", uri: STYLE_SCHEMA_URI }
2563
+ ],
2564
+ handler: ({ elementId, propertiesToChange, elementType, stylePropertiesToChange }) => {
2268
2565
  const toUpdate = Object.entries(propertiesToChange);
2566
+ const { valid, errors } = validateInput.validatePropSchema(elementType, propertiesToChange);
2567
+ const { valid: stylesValid, errors: stylesErrors } = validateInput.validateStyles(
2568
+ stylePropertiesToChange || {}
2569
+ );
2570
+ if (!valid) {
2571
+ const errorMessage = `Failed to configure element "${elementId}" due to invalid properties: ${errors?.join(
2572
+ "\n- "
2573
+ )}`;
2574
+ throw new Error(errorMessage);
2575
+ }
2576
+ if (!stylesValid) {
2577
+ const errorMessage = `Failed to configure element "${elementId}" due to invalid style properties: ${stylesErrors?.join(
2578
+ "\n- "
2579
+ )}`;
2580
+ throw new Error(errorMessage);
2581
+ }
2269
2582
  for (const [propertyName, propertyValue] of toUpdate) {
2270
- if (!propertyName && !elementId && !elementType) {
2271
- throw new Error(
2272
- "propertyName, elementId, elementType are required to configure an element. If you want to retreive the schema, use the get-element-configuration-schema tool."
2273
- );
2274
- }
2275
2583
  try {
2276
2584
  doUpdateElementProperty({
2277
2585
  elementId,
@@ -2284,6 +2592,28 @@ var initConfigureElementTool = (reg) => {
2284
2592
  propertyName,
2285
2593
  elementId,
2286
2594
  elementType,
2595
+ error,
2596
+ propertyType: "prop"
2597
+ });
2598
+ throw new Error(errorMessage);
2599
+ }
2600
+ }
2601
+ for (const [stylePropertyName, stylePropertyValue] of Object.entries(stylePropertiesToChange || {})) {
2602
+ try {
2603
+ doUpdateElementProperty({
2604
+ elementId,
2605
+ elementType,
2606
+ propertyName: "_styles",
2607
+ propertyValue: {
2608
+ [stylePropertyName]: stylePropertyValue
2609
+ }
2610
+ });
2611
+ } catch (error) {
2612
+ const errorMessage = createUpdateErrorMessage({
2613
+ propertyName: `(style) ${stylePropertyName}`,
2614
+ elementId,
2615
+ elementType,
2616
+ propertyType: "style",
2287
2617
  error
2288
2618
  });
2289
2619
  throw new Error(errorMessage);
@@ -2296,26 +2626,32 @@ var initConfigureElementTool = (reg) => {
2296
2626
  });
2297
2627
  };
2298
2628
  function createUpdateErrorMessage(opts) {
2299
- const { propertyName, elementId, elementType, error } = opts;
2629
+ const { propertyName, elementId, elementType, error, propertyType } = opts;
2300
2630
  return `Failed to update property "${propertyName}" on element "${elementId}": ${error.message}.
2631
+ ${propertyType === "prop" ? `
2301
2632
  Check the element's PropType schema at the resource [${WIDGET_SCHEMA_URI.replace(
2302
2633
  "{widgetType}",
2303
2634
  elementType
2304
2635
  )}] for type "${elementType}" to ensure the property exists and the value matches the expected PropType.
2305
- Now that you have this information, ensure you have the schema and try again.`;
2636
+ Now that you have this information, ensure you have the schema and try again.` : `
2637
+ Check the styles schema at the resource [${STYLE_SCHEMA_URI.replace(
2638
+ "{category}",
2639
+ propertyName
2640
+ )}] at editor-canvas__elementor://styles/schema/{category} to ensure the style property exists and the value matches the expected PropType.
2641
+ `};
2642
+ }`;
2306
2643
  }
2307
2644
 
2308
2645
  // src/mcp/tools/get-element-config/tool.ts
2309
- import { getContainer as getContainer4, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache5 } from "@elementor/editor-elements";
2310
- import { Schema as Schema3 } from "@elementor/editor-props";
2646
+ import { getContainer as getContainer4, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
2647
+ import { Schema as Schema4 } from "@elementor/editor-props";
2311
2648
  import { z as z3 } from "@elementor/schema";
2312
2649
  var schema = {
2313
2650
  elementId: z3.string()
2314
2651
  };
2315
2652
  var outputSchema3 = {
2316
- propValues: z3.record(z3.string(), z3.any()).describe(
2317
- "A record mapping PropTypes to their corresponding PropValues, with _styles record for style-related PropValues"
2318
- )
2653
+ properties: z3.record(z3.string(), z3.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
2654
+ style: z3.record(z3.string(), z3.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues")
2319
2655
  };
2320
2656
  var initGetElementConfigTool = (reg) => {
2321
2657
  const { addTool } = reg;
@@ -2330,13 +2666,13 @@ var initGetElementConfigTool = (reg) => {
2330
2666
  throw new Error(`Element with ID ${elementId} not found.`);
2331
2667
  }
2332
2668
  const elementRawSettings = element.settings;
2333
- const propSchema = getWidgetsCache5()?.[element.model.get("widgetType") || ""]?.atomic_props_schema;
2669
+ const propSchema = getWidgetsCache6()?.[element.model.get("widgetType") || element.model.get("elType") || ""]?.atomic_props_schema;
2334
2670
  if (!elementRawSettings || !propSchema) {
2335
2671
  throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
2336
2672
  }
2337
2673
  const propValues = {};
2338
2674
  const stylePropValues = {};
2339
- Schema3.configurableKeys(propSchema).forEach((key) => {
2675
+ Schema4.configurableKeys(propSchema).forEach((key) => {
2340
2676
  propValues[key] = structuredClone(elementRawSettings.get(key));
2341
2677
  });
2342
2678
  const elementStyles = getElementStyles2(elementId) || {};
@@ -2352,12 +2688,17 @@ var initGetElementConfigTool = (reg) => {
2352
2688
  stylePropValues[stylePropName] = structuredClone(styleProps[stylePropName]);
2353
2689
  }
2354
2690
  });
2691
+ if (defaultVariant.custom_css) {
2692
+ stylePropValues.custom_css = atob(defaultVariant.custom_css.raw);
2693
+ }
2355
2694
  }
2356
2695
  }
2357
2696
  return {
2358
- propValues: {
2359
- ...propValues,
2360
- _styles: stylePropValues
2697
+ properties: {
2698
+ ...propValues
2699
+ },
2700
+ style: {
2701
+ ...stylePropValues
2361
2702
  }
2362
2703
  };
2363
2704
  }
@@ -2374,46 +2715,90 @@ var initCanvasMcp = (reg) => {
2374
2715
  initBuildCompositionsTool(reg);
2375
2716
  initGetElementConfigTool(reg);
2376
2717
  initConfigureElementTool(reg);
2718
+ initBreakpointsResource(reg);
2377
2719
  };
2378
2720
 
2379
2721
  // src/mcp/mcp-description.ts
2380
- var mcpDescription = `Canvas MCP - Working with widgets and styles: how to use the PropType schemas and generate PropValue structures
2722
+ var mcpDescription = `Canvas MCP
2723
+ This MCP enables everything related to creation, configuration, and styling of elements on the Elementor canvas.
2381
2724
 
2382
- # Elementor's PropValue configuration system
2725
+ # Design Systems in Elementor
2726
+ - 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.
2727
+ - 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.
2728
+ - 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.
2383
2729
 
2384
- Every widget in Elementor has a set of properties that can be configured, defined in a STRICT SCHEMA we call "PropType".
2385
- All widget configuration values are represented using a structure we call "PropValue".
2730
+ # PropValues structure and usage
2731
+ \`\`\`json
2732
+ {
2733
+ $$type: 'the-prop-type-schema-kind',
2734
+ value: 'the-actual-value-as-defined-for-the-propType'
2735
+ }
2736
+ \`\`\`
2737
+ The "value" property can be an object, string, number, boolean, array, etc. The $$type defines the kind of value, and the value is the actual value.
2738
+ It is critical to provide the correct $$type for each value, as it defines how Elementor will interpret the value or reject it.
2739
+
2740
+ All widgets properties and configuration is built from sets of PropValues, which can be retreived from the resource [${WIDGET_SCHEMA_URI}].
2741
+ All styles are SHARED ACCROSS widgets, containers and components, and are defined in a common styles schema, retreivable from the resource [${STYLE_SCHEMA_URI}].
2742
+ The style schema also defines the global classes.
2743
+
2744
+ To understand the configuration options for an element, refer to the PropType schema for that specific element. For example: "e-heading" configuration schema is available at the resource [${WIDGET_SCHEMA_URI}/e-heading]
2386
2745
 
2387
- 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.
2388
- Every widget has it's own PropType schema, retreivable from the resource [${WIDGET_SCHEMA_URI}].
2389
- ALL WIDGETS share a common _styles property with a uniform styles schema, retreivable from the resource [${STYLE_SCHEMA_URI}].
2390
- The style schema is grouped by categories, such as "typography", "background", "border", etc.
2746
+ # Modifying elements and styles
2747
+ When configuring an element, elementor does a MERGE PROPERTIES operation, which means that only the properties you provide will be updated, and the rest will remain as is.
2748
+ For deleting a property, the value must be set to null, instead of a PropValue. When adding a configuration, no need to provide the full configuration, only the properties you want to add or update.
2749
+ The same rule applies to styles as well and modifications to global classes.
2391
2750
 
2392
- # Tools and usage
2393
- - 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.
2394
- 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.
2395
- - 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.
2396
- - Use the "configure-element" tool to update the configuration of an EXISTING element on the page.
2751
+ # Building full compositions
2752
+ The "build-composition" tool allows creating multiple elements in a single operation.
2753
+ The tool accepts both the structure, the styling and the configuration of each element to be created.
2397
2754
 
2398
- 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.
2399
- 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.
2400
- 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.
2755
+ - First step: Retreive the available widgets by listing the [${WIDGET_SCHEMA_URI}] dynamic resource.
2756
+ - Second step: decide which elements to create, and their configuration and styles.
2757
+ Retrieve the used elements configuration schema from the resource [${WIDGET_SCHEMA_URI}/element-name]
2758
+ - Third step: define the styles for each element, using the common styles schema from the resource [${STYLE_SCHEMA_URI}]. List the resource to see all available style properties.
2759
+ For background and complicated layered styles, you can use "custom_css" property, which is supported only for ELEMENTOR PRO users ONLY.
2760
+ The custom css is intented to deal with yet unsupported CSS features that ARE NOT PART OF THE STYLE SCHEMA, to enable PRO users to support new CSS features.
2761
+
2762
+ # Configuring Elements / Adding Style to Elements
2763
+ An element configuration can be retrieved using the "get-element-configuration-values" tool.
2764
+ Updating an element requires only the UPDATED properties (including in the styles), as Elementor does a MERGE/PATCH operation.
2765
+
2766
+ <note>
2767
+ for PropValue with array as value:
2768
+ All array types that can receive union types, are typed as mixed array.
2769
+ </note>
2401
2770
 
2402
2771
  # Styling best practices
2403
2772
  Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
2404
2773
  This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema.
2405
2774
 
2406
- Additionaly, some PropTypes have metadata information (meta property) that can help in understaind the PropType usage, such as description or other useful information.
2407
-
2408
- Example of null values:
2409
- {
2410
- $$type: 'as-defined-for-propValue',
2411
- value: null
2412
- }
2775
+ # Examples:
2413
2776
 
2414
- Example of "image" PropValue structure:
2777
+ ## e-image PropValue structure:
2415
2778
  {$$type:'image',value:{src:{$$type:'image-src',value:{url:{$$type:'url',value:'https://example.com/image.jpg'}}},size:{$$type:'string',value:'full'}}}
2416
2779
 
2780
+ Widgets' sizes MUST be defined using the style schema. Images, for example, have a "size" property, but it DOES NOT AFFECT THE VISUAL size, but rather the image size/resolution to load.
2781
+
2782
+ # Working with Global Classes and Variables
2783
+ - To get the list of available global classes, use the resource at uri elementor://global-classes
2784
+ - To get the list of available global variables, use the resource at uri elementor://global-variables
2785
+ - Before creating a global variable or class, refer to the list and see if it already exists.
2786
+ - Naming conventions:
2787
+ - Global classes and global variables should have meaningful names that reflect their purpose and usage.
2788
+ - Avoid generic names like "style1" or "classA"; instead, use descriptive names like "primary-button" or "heading-level-1".
2789
+ - Avoid names that reflect colors or values, use only purpose-based names.
2790
+
2791
+ # Advanced operations
2792
+ You are encouraged to run multiple times multiple tools to achieve the desired result.
2793
+
2794
+ An Example scenario of creating fully styled composition:
2795
+ 1. Get the list of availble widgets using dynamic resource [${WIDGET_SCHEMA_URI}]
2796
+ 2. For each element to create, retreive its configuration schema from [${WIDGET_SCHEMA_URI}/element-name]
2797
+ 3. Get the list of available global classes using the always up-to-date resource
2798
+ 4. Get the list of available global variables using the dynamic resource
2799
+ 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.
2800
+ 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.
2801
+ 7. If needed, update styles using the "configure-element" tool, providing only the styles or widget's properties to update.
2417
2802
  `;
2418
2803
 
2419
2804
  // src/prevent-link-in-link-commands.ts
@@ -2522,7 +2907,7 @@ import { undoable } from "@elementor/editor-v1-adapters";
2522
2907
  import { __ as __3 } from "@wordpress/i18n";
2523
2908
 
2524
2909
  // src/style-commands/utils.ts
2525
- import { getElementLabel, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
2910
+ import { getElementLabel, getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
2526
2911
  import { CLASSES_PROP_KEY } from "@elementor/editor-props";
2527
2912
  import { __ as __2 } from "@wordpress/i18n";
2528
2913
  function hasAtomicWidgets(args) {
@@ -2547,7 +2932,7 @@ function getClassesProp(container) {
2547
2932
  }
2548
2933
  function getContainerSchema(container) {
2549
2934
  const type = container?.model.get("widgetType") || container?.model.get("elType");
2550
- const widgetsCache = getWidgetsCache6();
2935
+ const widgetsCache = getWidgetsCache7();
2551
2936
  const elementType = widgetsCache?.[type];
2552
2937
  return elementType?.atomic_props_schema ?? null;
2553
2938
  }
@@ -2814,6 +3199,8 @@ var getLegacyPanelElementView = ({ settings, ...rest }) => {
2814
3199
  return { model: elementModel };
2815
3200
  };
2816
3201
  export {
3202
+ BREAKPOINTS_SCHEMA_URI,
3203
+ STYLE_SCHEMA_URI,
2817
3204
  createPropsResolver,
2818
3205
  createTemplatedElementView,
2819
3206
  createTransformer,