@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.d.mts +66 -62
- package/dist/index.d.ts +66 -62
- package/dist/index.js +757 -364
- package/dist/index.mjs +680 -293
- package/package.json +17 -17
- package/src/index.ts +12 -9
- package/src/mcp/canvas-mcp.ts +2 -0
- package/src/mcp/mcp-description.ts +67 -24
- package/src/mcp/resources/breakpoints-resource.ts +47 -0
- package/src/mcp/resources/widgets-schema-resource.ts +10 -7
- package/src/mcp/tools/build-composition/prompt.ts +222 -20
- package/src/mcp/tools/build-composition/schema.ts +7 -4
- package/src/mcp/tools/build-composition/tool.ts +23 -24
- package/src/mcp/tools/configure-element/prompt.ts +23 -20
- package/src/mcp/tools/configure-element/schema.ts +15 -7
- package/src/mcp/tools/configure-element/tool.ts +62 -18
- package/src/mcp/tools/get-element-config/tool.ts +15 -7
- package/src/mcp/utils/do-update-element-property.ts +16 -16
- package/src/mcp/utils/validate-input.ts +100 -0
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:
|
|
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(
|
|
1562
|
-
const config =
|
|
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
|
|
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:
|
|
1781
|
-
if (!
|
|
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,
|
|
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 =
|
|
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(`
|
|
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
|
|
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.
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
-
|
|
1912
|
-
-
|
|
1913
|
-
-
|
|
1914
|
-
|
|
1915
|
-
|
|
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(
|
|
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("
|
|
1998
|
-
z.any().describe(
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 "
|
|
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
|
|
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
|
|
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
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
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
|
-
|
|
2242
|
-
)
|
|
2243
|
-
|
|
2244
|
-
|
|
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
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
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
|
|
2310
|
-
import { Schema as
|
|
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
|
-
|
|
2317
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
2359
|
-
...propValues
|
|
2360
|
-
|
|
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
|
|
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
|
-
#
|
|
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
|
-
|
|
2385
|
-
|
|
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
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
The
|
|
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
|
-
#
|
|
2393
|
-
|
|
2394
|
-
|
|
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
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
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
|
-
|
|
2407
|
-
|
|
2408
|
-
Example of null values:
|
|
2409
|
-
{
|
|
2410
|
-
$$type: 'as-defined-for-propValue',
|
|
2411
|
-
value: null
|
|
2412
|
-
}
|
|
2775
|
+
# Examples:
|
|
2413
2776
|
|
|
2414
|
-
|
|
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
|
|
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 =
|
|
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,
|