@elementor/editor-canvas 4.0.0-621 → 4.0.0-manual
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +203 -182
- package/dist/index.mjs +166 -145
- package/package.json +18 -18
- package/src/composition-builder/composition-builder.ts +31 -2
- package/src/mcp/canvas-mcp.ts +8 -1
- package/src/mcp/resources/best-practices.ts +159 -0
- package/src/mcp/resources/widgets-schema-resource.ts +7 -1
- package/src/mcp/tools/build-composition/prompt.ts +110 -134
- package/src/mcp/tools/build-composition/schema.ts +8 -1
- package/src/mcp/tools/build-composition/tool.ts +4 -4
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
export const BEST_PRACTICES_PROMPT = `
|
|
2
|
+
# DESIGN QUALITY IMPERATIVE
|
|
3
|
+
|
|
4
|
+
You are generating designs for real users who expect distinctive, intentional aesthetics - NOT generic AI output.
|
|
5
|
+
|
|
6
|
+
**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.
|
|
7
|
+
|
|
8
|
+
**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.
|
|
9
|
+
|
|
10
|
+
When in doubt between "safe" and "distinctive," choose distinctive - users can always request refinements, but they cannot salvage generic foundations.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# DESIGN VECTORS - Concrete Implementation Guidance
|
|
15
|
+
|
|
16
|
+
## 1. Typography & Visual Hierarchy
|
|
17
|
+
|
|
18
|
+
### Avoid Distributional Defaults:
|
|
19
|
+
- NO generic sans-serifs as primary typefaces (Inter, Roboto, Arial, Helvetica)
|
|
20
|
+
- NO timid size ratios (1.2x, 1.5x scaling)
|
|
21
|
+
- NO uniform font weights (everything at 400 or 600)
|
|
22
|
+
|
|
23
|
+
### Intentional Alternatives:
|
|
24
|
+
- **For Technical/Modern**: Consider monospace headlines (JetBrains Mono, SF Mono) paired with clean body text
|
|
25
|
+
- **For Editorial/Elegant**: Consider serif headlines (Playfair Display, Crimson Text) with sans-serif body
|
|
26
|
+
- **For Playful/Creative**: Consider display fonts with character, paired with highly legible body text
|
|
27
|
+
|
|
28
|
+
### Scale & Contrast Implementation:
|
|
29
|
+
- Headline-to-body size ratios: 3x minimum (e.g., 48px headline vs 16px body)
|
|
30
|
+
- Use extreme weight contrasts: pair weight-100 or 200 with weight-800 or 900
|
|
31
|
+
- Line height contrasts: tight headlines (1.1) vs. generous body (1.7)
|
|
32
|
+
- Letter spacing: compressed headlines (-0.02em to -0.05em) vs. open small text (0.03em+)
|
|
33
|
+
|
|
34
|
+
## 2. Color & Theme Strategy
|
|
35
|
+
|
|
36
|
+
### Avoid Distributional Defaults:
|
|
37
|
+
- NO purple gradients or blue-purple color schemes (massively overrepresented in AI output)
|
|
38
|
+
- NO evenly-distributed color palettes (3-4 colors used equally)
|
|
39
|
+
- NO timid pastels or all-neutral schemes
|
|
40
|
+
- NO #333333, #666666, #999999 grays
|
|
41
|
+
|
|
42
|
+
### Intentional Alternatives:
|
|
43
|
+
- **Commit to a Dominant Color**: Choose ONE primary brand color that appears in 60-70% of colored elements
|
|
44
|
+
- **Sharp Accent Strategy**: Use 1-2 high-contrast accent colors sparingly (10-15% of colored elements)
|
|
45
|
+
- **Neutrals with Personality**: Replace pure grays with warm (#3d3228, #f5f1ed) or cool (#2a2f3d, #f0f2f5) tinted neutrals
|
|
46
|
+
|
|
47
|
+
### Color Psychology Mapping:
|
|
48
|
+
- Energy/Action → Warm reds, oranges, yellows (NOT purple/blue)
|
|
49
|
+
- Trust/Calm → Deep teals, forest greens (NOT generic blue)
|
|
50
|
+
- Luxury/Premium → Deep burgundy, emerald, charcoal with gold accents
|
|
51
|
+
- Playful/Creative → Unexpected combinations (coral + mint, mustard + navy)
|
|
52
|
+
|
|
53
|
+
## 3. Spatial Design & White Space
|
|
54
|
+
|
|
55
|
+
### Avoid Distributional Defaults:
|
|
56
|
+
- NO uniform spacing (everything 16px or 24px)
|
|
57
|
+
- NO cramped layouts that maximize content density
|
|
58
|
+
- NO default container widths (1200px, 1440px)
|
|
59
|
+
|
|
60
|
+
### Intentional Alternatives:
|
|
61
|
+
- **Breathing Room**: Use generous white space as a design element (80-120px vertical spacing between sections)
|
|
62
|
+
- **Asymmetric Spacing**: Vary padding dramatically (small: 12px, medium: 48px, large: 96px)
|
|
63
|
+
- **Content Width Strategy**:
|
|
64
|
+
- Reading content: max 65-75 characters (600-700px)
|
|
65
|
+
- Hero sections: asymmetric layouts, not centered blocks
|
|
66
|
+
- Cards/components: vary sizes intentionally, not uniform grids
|
|
67
|
+
|
|
68
|
+
## 4. Motion & Interaction Design
|
|
69
|
+
|
|
70
|
+
### Avoid Distributional Defaults:
|
|
71
|
+
- NO scattered micro-interactions on every element
|
|
72
|
+
- NO generic fade-in animations
|
|
73
|
+
- NO 0.3s ease-in-out transitions everywhere
|
|
74
|
+
|
|
75
|
+
### Intentional Alternatives:
|
|
76
|
+
- **High-Impact Moments**: Use animation for 2-3 key moments (page load hero, primary CTA, section reveals)
|
|
77
|
+
- **Staggered Reveals**: When animating multiple items, use staggered delays (0.1s increments)
|
|
78
|
+
- **Purposeful Timing**: Fast interactions (0.15s) for responsiveness, slow reveals (0.6s+) for drama
|
|
79
|
+
|
|
80
|
+
## 5. Backgrounds & Atmospheric Depth
|
|
81
|
+
|
|
82
|
+
### Avoid Distributional Defaults:
|
|
83
|
+
- NO solid white or light gray backgrounds
|
|
84
|
+
- NO single-color backgrounds
|
|
85
|
+
- NO generic gradient overlays
|
|
86
|
+
|
|
87
|
+
### Intentional Alternatives:
|
|
88
|
+
- **Layered Gradients**: Combine 2-3 subtle gradients for depth
|
|
89
|
+
- **Geometric Patterns**: SVG patterns, mesh gradients, or subtle noise textures
|
|
90
|
+
- **Strategic Contrast**: Alternate between light and dark sections for rhythm
|
|
91
|
+
|
|
92
|
+
## 6. Visual Hierarchy Principles
|
|
93
|
+
|
|
94
|
+
### Clear Priority System:
|
|
95
|
+
1. **Primary Focus (1 element)**: Largest, highest contrast, most visual weight
|
|
96
|
+
2. **Secondary Elements (2-3 elements)**: 40-60% of primary size, reduced contrast
|
|
97
|
+
3. **Tertiary/Support (everything else)**: Minimal visual weight, muted colors
|
|
98
|
+
|
|
99
|
+
### Contrast Techniques:
|
|
100
|
+
- Size: 3x+ differences between hierarchy levels
|
|
101
|
+
- Weight: 300+ difference in font-weight values
|
|
102
|
+
- Color: Primary gets brand color, secondary gets neutral, tertiary gets muted
|
|
103
|
+
- Space: Primary gets 2x+ surrounding white space vs. secondary
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# IMPLEMENTATION WORKFLOW
|
|
107
|
+
|
|
108
|
+
When building a composition:
|
|
109
|
+
|
|
110
|
+
1. **Define the Visual Goal First**
|
|
111
|
+
- What emotion/brand personality? (Professional, playful, elegant, bold)
|
|
112
|
+
- What's the single most important element?
|
|
113
|
+
- What color family (warm/cool/neutral) supports the goal?
|
|
114
|
+
|
|
115
|
+
2. **Choose Typography Personality**
|
|
116
|
+
- Select font pairings that match the personality (NOT defaults)
|
|
117
|
+
- Define scale (3x+ headline ratio)
|
|
118
|
+
- Set weight extremes (light/heavy contrast)
|
|
119
|
+
|
|
120
|
+
3. **Commit to Color Strategy**
|
|
121
|
+
- Pick ONE dominant color (NOT purple, NOT generic blue)
|
|
122
|
+
- Choose 1 sharp accent
|
|
123
|
+
- Define warm or cool neutrals
|
|
124
|
+
|
|
125
|
+
4. **Design Spatial Rhythm**
|
|
126
|
+
- Use generous white space (3-6rem between sections)
|
|
127
|
+
- Create asymmetry (not everything centered)
|
|
128
|
+
- Vary component sizes intentionally
|
|
129
|
+
|
|
130
|
+
5. **Add Strategic Motion**
|
|
131
|
+
- Identify 2-3 high-impact animation moments
|
|
132
|
+
- Use staggered timing for multiple elements
|
|
133
|
+
- Keep interactions purposeful, not decorative
|
|
134
|
+
|
|
135
|
+
6. **Layer Atmospheric Depth**
|
|
136
|
+
- Use gradient combinations for backgrounds
|
|
137
|
+
- Add subtle patterns or textures
|
|
138
|
+
- Alternate light/dark sections for rhythm
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
# CONTEXT-AWARE DESIGN PERSONALITIES
|
|
142
|
+
|
|
143
|
+
Brand personality should influence your choices:
|
|
144
|
+
|
|
145
|
+
- **Corporate/Professional**: Deep neutrals, serif headlines, structured spacing
|
|
146
|
+
- **Creative/Agency**: Bold color, display fonts, asymmetric layouts
|
|
147
|
+
- **Tech/Startup**: Monospace accents, sharp colors, modern spacing
|
|
148
|
+
- **Elegant/Luxury**: Serif dominance, muted colors with metallic accents, generous white space
|
|
149
|
+
|
|
150
|
+
# USER OVERRIDE CAPABILITY
|
|
151
|
+
|
|
152
|
+
Always respect user specifications:
|
|
153
|
+
|
|
154
|
+
If user specifies:
|
|
155
|
+
- Specific colors → use them
|
|
156
|
+
- Specific fonts → use them
|
|
157
|
+
- Specific spacing → use it
|
|
158
|
+
- "Minimal/simple" → reduce ornamentation but maintain quality principles
|
|
159
|
+
`;
|
|
@@ -28,7 +28,13 @@ Prefer using "em" and "rem" values for text-related sizes, padding and spacing.
|
|
|
28
28
|
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema.
|
|
29
29
|
|
|
30
30
|
When applicable for styles, apply style PropValues using the ${ STYLE_SCHEMA_URI }.
|
|
31
|
-
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed
|
|
31
|
+
The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.
|
|
32
|
+
|
|
33
|
+
** CRITICAL - VARIABLES **
|
|
34
|
+
When using global variables, ensure that the variables are defined in the ${ 'elementor://global-variables' } resource.
|
|
35
|
+
Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
36
|
+
|
|
37
|
+
`,
|
|
32
38
|
},
|
|
33
39
|
],
|
|
34
40
|
};
|
|
@@ -1,167 +1,143 @@
|
|
|
1
1
|
import { toolPrompts } from '@elementor/editor-mcp';
|
|
2
2
|
|
|
3
|
-
import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
|
|
4
|
-
|
|
5
3
|
export const generatePrompt = () => {
|
|
6
4
|
const buildCompositionsToolPrompt = toolPrompts( 'build-compositions' );
|
|
7
5
|
|
|
8
6
|
buildCompositionsToolPrompt.description( `
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
4. Build valid XML with minimal inline styles (layout/positioning only)
|
|
23
|
-
5. Avoid duplicating styles that should be global classes
|
|
24
|
-
|
|
25
|
-
## Phase 3: Apply Classes
|
|
26
|
-
6. Use "apply-global-class" tool to apply global classes to elements
|
|
27
|
-
|
|
28
|
-
# CORE INSTRUCTIONS
|
|
29
|
-
|
|
30
|
-
**Structure:**
|
|
31
|
-
- Build valid XML using allowed widget tags (e.g., \`<e-button configuration-id="btn1"></e-button>\`)
|
|
32
|
-
- Containers only: "e-flexbox", "e-div-block", "e-tabs"
|
|
33
|
-
- Every element MUST have unique "configuration-id" attribute
|
|
7
|
+
# RESOURCES (Read before use)
|
|
8
|
+
- [elementor://global-classes] - Check FIRST for reusable classes
|
|
9
|
+
- [elementor://global-variables] - ONLY use variables defined here
|
|
10
|
+
|
|
11
|
+
# WORKFLOW
|
|
12
|
+
1. Check/create global classes via "create-global-class" tool
|
|
13
|
+
2. Build composition (THIS TOOL) - minimal inline styles
|
|
14
|
+
3. Apply classes via "apply-global-class" tool
|
|
15
|
+
|
|
16
|
+
# XML STRUCTURE
|
|
17
|
+
- Use widget tags: \`<e-button configuration-id="btn1"></e-button>\`
|
|
18
|
+
- Containers: "e-flexbox", "e-div-block", "e-tabs"
|
|
19
|
+
- Every element needs unique "configuration-id"
|
|
34
20
|
- No attributes, classes, IDs, or text nodes in XML
|
|
35
21
|
|
|
36
|
-
|
|
37
|
-
- Map
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
22
|
+
# CONFIGURATION
|
|
23
|
+
- Map configuration-id → elementConfig (props) + stylesConfig (layout only)
|
|
24
|
+
- All PropValues require \`$$type\` matching schema
|
|
25
|
+
- NO LINKS in configuration
|
|
26
|
+
- Retry on errors up to 10x
|
|
27
|
+
|
|
28
|
+
Note about configuration ids: These names are visible to the end-user, make sure they make sense, related and relevant.
|
|
29
|
+
|
|
30
|
+
# DESIGN PHILOSOPHY: CONTEXT-DRIVEN CREATIVITY
|
|
31
|
+
|
|
32
|
+
**Use the user's context aggressively.** Business type, brand personality, target audience, and purpose should drive every design decision. A law firm needs gravitas; a children's app needs playfulness. Don't default to generic.
|
|
33
|
+
|
|
34
|
+
## SIZING: DEFAULT IS NO SIZE (CRITICAL)
|
|
35
|
+
|
|
36
|
+
**DO NOT specify height or width unless you have a specific visual reason.**
|
|
37
|
+
|
|
38
|
+
Flexbox and CSS already handle sizing automatically:
|
|
39
|
+
- Containers grow to fit their content
|
|
40
|
+
- Flex children distribute space via flex properties, not width/height
|
|
41
|
+
- Text elements size to their content
|
|
42
|
+
|
|
43
|
+
WHEN TO SPECIFY SIZE:
|
|
44
|
+
- min-height on ROOT section for viewport-spanning hero (use min-height, NOT height)
|
|
45
|
+
- max-width for contained content areas (e.g., max-width: 60rem)
|
|
46
|
+
- Explicit aspect ratios for media containers
|
|
47
|
+
|
|
48
|
+
NEVER SPECIFY:
|
|
49
|
+
- height on nested containers (causes overflow)
|
|
50
|
+
- width on flex children (use flex-basis or gap instead)
|
|
51
|
+
- 100vh on anything except root-level sections
|
|
52
|
+
- Any size "just to be safe" - if unsure, OMIT IT
|
|
53
|
+
|
|
54
|
+
vh units are VIEWPORT-relative. Nested 100vh inside 100vh = 200vh overflow.
|
|
55
|
+
|
|
56
|
+
GOOD: \`<e-flexbox>content naturally sizes</e-flexbox>\`
|
|
57
|
+
BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflow</e-div-block></e-flexbox>\`
|
|
58
|
+
|
|
59
|
+
## Layout Variety (Break the Template)
|
|
60
|
+
- AVOID: Full-width 100vh hero → three columns → testimonials → CTA (every AI does this)
|
|
61
|
+
- VARY heights: Use auto-height sections with generous padding (6rem+). Let content breathe
|
|
62
|
+
- VARY widths: Not everything spans full width. Use contained sections (max-width: 960px) mixed with edge-to-edge
|
|
63
|
+
- ASYMMETRIC grids: 2:1, 1:3, offset layouts. Avoid equal column widths
|
|
64
|
+
- Negative space as design element: Large margins create focus and sophistication
|
|
65
|
+
- Break alignment intentionally: Offset headings, overlapping elements, broken grids
|
|
66
|
+
|
|
67
|
+
## Visual Depth & Effects
|
|
68
|
+
- Layer elements: Overlapping cards, text over images, floating elements
|
|
69
|
+
- Subtle shadows with color tint (not pure black): \`box-shadow: 0 20px 60px rgba(<brand-color-here>, 0.15)\`
|
|
70
|
+
- Gradient overlays on images for text readability
|
|
71
|
+
- Border radius variation: Mix sharp (0) and soft (1rem+) corners purposefully
|
|
72
|
+
- Backdrop blur for glassmorphism where appropriate
|
|
73
|
+
- Micro-interactions via CSS: hover transforms, transitions (0.3s ease)
|
|
74
|
+
|
|
75
|
+
## Typography with Character
|
|
76
|
+
- Display fonts for headlines (from user's brand or contextually appropriate)
|
|
77
|
+
- Size contrast: 4rem+ headlines vs 1rem body. Make hierarchy unmistakable
|
|
78
|
+
- Letter-spacing: Tight for large headlines (-0.02em), loose for small caps (0.1em)
|
|
79
|
+
- Line-height: Tight for headlines (1.1), generous for body (1.6-1.8)
|
|
80
|
+
- Text decoration: Underlines, highlights, gradient text for emphasis
|
|
81
|
+
|
|
82
|
+
## Color with Purpose
|
|
83
|
+
- Extract palette from user context (brand colors, industry norms, mood)
|
|
84
|
+
- 60-30-10 rule: dominant, secondary, accent
|
|
85
|
+
- Tinted neutrals over pure grays: warm (#faf8f5, #2d2a26) or cool (#f5f7fa, #1e2430)
|
|
86
|
+
- Color blocking: Large colored sections create visual rhythm
|
|
87
|
+
- Gradient directions: Diagonal (135deg, 225deg) feel more dynamic than vertical
|
|
88
|
+
|
|
89
|
+
## Spacing Strategy
|
|
90
|
+
- Section padding: 6rem-10rem vertical, creating breathing room
|
|
91
|
+
- Rhythm variation: Tight groups (2rem) with generous gaps between (6rem)
|
|
92
|
+
- Use rem/em exclusively for responsive scaling
|
|
93
|
+
- Generous padding on CTAs: min 1rem 2.5rem
|
|
94
|
+
|
|
95
|
+
# HARD CONSTRAINTS
|
|
96
|
+
- Variables ONLY from [elementor://global-variables] (others throw errors)
|
|
97
|
+
- Avoid SVG widgets unless assets are pre-uploaded
|
|
98
|
+
- Check \`llm_guidance\` in widget schemas
|
|
99
|
+
|
|
100
|
+
# PARAMETERS
|
|
104
101
|
- **xmlStructure**: Valid XML with configuration-id attributes
|
|
105
|
-
- **elementConfig**:
|
|
106
|
-
- **stylesConfig**:
|
|
102
|
+
- **elementConfig**: configuration-id → widget PropValues
|
|
103
|
+
- **stylesConfig**: configuration-id → style PropValues (layout only)
|
|
104
|
+
- **customCSS**: configuration-id → CSS rules (no selectors, semicolon-separated)
|
|
107
105
|
` );
|
|
108
106
|
|
|
109
107
|
buildCompositionsToolPrompt.example( `
|
|
110
|
-
|
|
108
|
+
Section with heading + button (NO explicit heights - content sizes naturally):
|
|
111
109
|
{
|
|
112
|
-
xmlStructure: "<e-flexbox configuration-id="
|
|
110
|
+
xmlStructure: "<e-flexbox configuration-id="Main Section"><e-heading configuration-id="Section Title"></e-heading><e-button configuration-id="Call to Action"></e-button></e-flexbox>",
|
|
113
111
|
elementConfig: {
|
|
114
|
-
"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
},
|
|
112
|
+
"section1": { "tag": { "$$type": "string", "value": "section" } }
|
|
113
|
+
},
|
|
114
|
+
customCSS: {
|
|
115
|
+
"Section Title": "padding: 6rem 4rem; background: linear-gradient(135deg, #faf8f5 0%, #f0ebe4 100%);"
|
|
119
116
|
},
|
|
120
117
|
stylesConfig: {
|
|
121
|
-
"
|
|
122
|
-
"font-size": {
|
|
123
|
-
|
|
124
|
-
"value": {
|
|
125
|
-
"size": { "$$type": "number", "value": 24 },
|
|
126
|
-
"unit": { "$$type": "string", "value": "px" }
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
"color": {
|
|
130
|
-
"$$type": "color",
|
|
131
|
-
"value": { "$$type": "string", "value": "#333" }
|
|
132
|
-
}
|
|
118
|
+
"Section Title": {
|
|
119
|
+
"font-size": { "$$type": "size", "value": { "size": { "$$type": "number", "value": 3.5 }, "unit": { "$$type": "string", "value": "rem" } } },
|
|
120
|
+
"color": { "$$type": "color", "value": { "$$type": "string", "value": "#2d2a26" } }
|
|
133
121
|
}
|
|
134
|
-
}
|
|
122
|
+
}
|
|
135
123
|
}
|
|
124
|
+
Note: No height/width specified on any element - flexbox handles layout automatically.
|
|
136
125
|
` );
|
|
137
126
|
|
|
138
127
|
buildCompositionsToolPrompt.parameter(
|
|
139
128
|
'xmlStructure',
|
|
140
|
-
|
|
129
|
+
`Valid XML structure with custom elementor tags and configuration-id attributes.`
|
|
141
130
|
);
|
|
142
131
|
|
|
143
|
-
buildCompositionsToolPrompt.parameter(
|
|
144
|
-
'elementConfig',
|
|
145
|
-
`**MANDATORY** A record mapping configuration IDs to their corresponding configuration objects, defining the PropValues for each element created.`
|
|
146
|
-
);
|
|
132
|
+
buildCompositionsToolPrompt.parameter( 'elementConfig', `Record mapping configuration IDs to widget PropValues.` );
|
|
147
133
|
|
|
148
134
|
buildCompositionsToolPrompt.parameter(
|
|
149
135
|
'stylesConfig',
|
|
150
|
-
|
|
136
|
+
`Record mapping configuration IDs to style PropValues (layout/positioning only).`
|
|
151
137
|
);
|
|
152
138
|
|
|
153
139
|
buildCompositionsToolPrompt.instruction(
|
|
154
|
-
`
|
|
155
|
-
You should use these IDs as reference for further configuration, styling or changing elements later on.`
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
buildCompositionsToolPrompt.instruction(
|
|
159
|
-
`**CRITICAL WORKFLOW REMINDER**:
|
|
160
|
-
1. FIRST: Create reusable global classes for typography, colors, spacing patterns using "create-global-class" tool
|
|
161
|
-
2. SECOND: Use THIS tool with minimal inline styles (only layout & unique properties)
|
|
162
|
-
3. THIRD: Apply global classes to elements using "apply-global-class" tool
|
|
163
|
-
|
|
164
|
-
This ensures maximum reusability and consistency across your design system. ALWAYS check [elementor://global-classes] for existing classes before creating new ones.`
|
|
140
|
+
`Element IDs in the returned XML represent actual widgets. Use these IDs for subsequent styling or configuration changes.`
|
|
165
141
|
);
|
|
166
142
|
|
|
167
143
|
return buildCompositionsToolPrompt.prompt();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from '@elementor/
|
|
1
|
+
import { zod as z } from '@elementor/editor-mcp';
|
|
2
2
|
|
|
3
3
|
import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
|
|
4
4
|
|
|
@@ -25,6 +25,13 @@ export const inputSchema = {
|
|
|
25
25
|
`A record mapping element IDs to their styles configuration objects. Use the actual styles schema from [${ STYLE_SCHEMA_URI }].`
|
|
26
26
|
)
|
|
27
27
|
.default( {} ),
|
|
28
|
+
customCSS: z
|
|
29
|
+
.record(
|
|
30
|
+
z.string().describe( 'The configuration id' ),
|
|
31
|
+
z.string().describe( 'The custom CSS for the element. MANDATORY' )
|
|
32
|
+
)
|
|
33
|
+
.describe( 'A record mapping element IDs to their custom CSS.' )
|
|
34
|
+
.default( {} ),
|
|
28
35
|
};
|
|
29
36
|
|
|
30
37
|
export const outputSchema = {
|
|
@@ -32,7 +32,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
32
32
|
hints: [ { name: 'claude-sonnet-4-5' } ],
|
|
33
33
|
},
|
|
34
34
|
handler: async ( params ) => {
|
|
35
|
-
const { xmlStructure, elementConfig, stylesConfig } = params;
|
|
35
|
+
const { xmlStructure, elementConfig, stylesConfig, customCSS } = params;
|
|
36
36
|
let generatedXML: string = '';
|
|
37
37
|
const errors: Error[] = [];
|
|
38
38
|
const rootContainers: V1Element[] = [];
|
|
@@ -44,6 +44,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
44
44
|
} );
|
|
45
45
|
compositionBuilder.setElementConfig( elementConfig );
|
|
46
46
|
compositionBuilder.setStylesConfig( stylesConfig );
|
|
47
|
+
compositionBuilder.setCustomCSS( customCSS );
|
|
47
48
|
|
|
48
49
|
const {
|
|
49
50
|
configErrors,
|
|
@@ -51,6 +52,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
51
52
|
rootContainers: generatedRootContainers,
|
|
52
53
|
} = compositionBuilder.build( documentContainer );
|
|
53
54
|
|
|
55
|
+
rootContainers.push( ...generatedRootContainers );
|
|
54
56
|
generatedXML = new XMLSerializer().serializeToString( compositionBuilder.getXML() );
|
|
55
57
|
|
|
56
58
|
if ( configErrors.length ) {
|
|
@@ -58,8 +60,6 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
58
60
|
throw new Error( 'Configuration errors occurred during composition building.' );
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
rootContainers.push( ...generatedRootContainers );
|
|
62
|
-
|
|
63
63
|
Object.entries( invalidStyles ).forEach( ( [ elementId, rawCssRules ] ) => {
|
|
64
64
|
const customCss = {
|
|
65
65
|
value: rawCssRules.join( ';\n' ),
|
|
@@ -113,7 +113,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
113
113
|
|
|
114
114
|
const errorText = `Failed to build composition with the following errors:\n\n${ errorMessages.join(
|
|
115
115
|
'\n\n'
|
|
116
|
-
) }
|
|
116
|
+
) }`;
|
|
117
117
|
throw new Error( errorText );
|
|
118
118
|
}
|
|
119
119
|
return {
|