@mjml-agent-editor/editor 0.1.17 → 0.2.0
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/README.md +8 -4
- package/dist/canvas.cjs +2891 -468
- package/dist/canvas.cjs.map +1 -1
- package/dist/canvas.js +2588 -386
- package/dist/canvas.js.map +1 -1
- package/dist/{chunk-VJRKDFM4.js → chunk-FTEJNUJL.js} +198 -2
- package/dist/chunk-FTEJNUJL.js.map +1 -0
- package/dist/index.cjs +197 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -4
- package/dist/index.d.ts +64 -4
- package/dist/index.js +1 -1
- package/package.json +2 -1
- package/src/components/editor/editor-theme.css +51 -80
- package/dist/chunk-VJRKDFM4.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -14,8 +14,10 @@ import { UIMessage, ChatTransport } from 'ai';
|
|
|
14
14
|
* keep existing hosts working unchanged, and a host overrides only the keys it cares about.
|
|
15
15
|
*
|
|
16
16
|
* Flat and shallow-merged on purpose. A nested dictionary reads better and merges worse —
|
|
17
|
-
* overriding one key inside a group would silently drop its siblings.
|
|
18
|
-
*
|
|
17
|
+
* overriding one key inside a group would silently drop its siblings. The only nested maps
|
|
18
|
+
* are the ones keyed by an id (`toolLabels`, `blockLabels`, `elementNames`,
|
|
19
|
+
* `inspectorLabels`), and those are
|
|
20
|
+
* merged key by key for exactly that reason.
|
|
19
21
|
*
|
|
20
22
|
* Values that interpolate are functions rather than templates with placeholders, so the
|
|
21
23
|
* translator controls word order instead of the format string.
|
|
@@ -38,10 +40,68 @@ interface EditorLabels {
|
|
|
38
40
|
readonly exportMjml: string;
|
|
39
41
|
/** `kind` is already upper-cased ("MJML", "HTML"). */
|
|
40
42
|
readonly copied: (kind: string) => string;
|
|
43
|
+
readonly tabBlocks: string;
|
|
44
|
+
readonly tabSettings: string;
|
|
45
|
+
readonly tabLayers: string;
|
|
41
46
|
readonly searchBlocks: string;
|
|
47
|
+
readonly noBlocksMatch: string;
|
|
48
|
+
readonly blockCategoryLayout: string;
|
|
49
|
+
readonly blockCategoryContent: string;
|
|
50
|
+
/** Keyed by grapesjs-mjml block id (`mj-1-column`, `mj-social-group`, …); merged key by key. */
|
|
51
|
+
readonly blockLabels: Readonly<Record<string, string>>;
|
|
52
|
+
/** Keyed by MJML tag, for the breadcrumb; merged key by key. */
|
|
53
|
+
readonly elementNames: Readonly<Record<string, string>>;
|
|
42
54
|
readonly expandAll: string;
|
|
43
55
|
readonly selectAnElement: string;
|
|
56
|
+
readonly settingsEmpty: string;
|
|
57
|
+
readonly emailSettings: string;
|
|
58
|
+
readonly loadingEditor: string;
|
|
59
|
+
readonly commentOnElement: string;
|
|
60
|
+
readonly groupContent: string;
|
|
61
|
+
readonly groupLayout: string;
|
|
62
|
+
readonly groupSpacing: string;
|
|
63
|
+
readonly groupStyle: string;
|
|
64
|
+
readonly groupAdvanced: string;
|
|
65
|
+
readonly otherAttributes: string;
|
|
66
|
+
readonly removeAttribute: string;
|
|
67
|
+
readonly resetToDefault: string;
|
|
68
|
+
readonly selectParent: string;
|
|
69
|
+
readonly duplicate: string;
|
|
70
|
+
readonly deleteElement: string;
|
|
71
|
+
readonly multipleSelected: (count: number) => string;
|
|
72
|
+
readonly editEachSide: string;
|
|
73
|
+
readonly increase: string;
|
|
74
|
+
readonly decrease: string;
|
|
75
|
+
/** The unit a length is in, on the button that changes it. */
|
|
76
|
+
readonly changeUnit: (unit: string) => string;
|
|
77
|
+
/** How a length without a unit (a line-height multiplier) shows its unit. */
|
|
78
|
+
readonly noUnit: string;
|
|
79
|
+
readonly sidesVertical: string;
|
|
80
|
+
readonly sidesHorizontal: string;
|
|
81
|
+
readonly sideTop: string;
|
|
82
|
+
readonly sideRight: string;
|
|
83
|
+
readonly sideBottom: string;
|
|
84
|
+
readonly sideLeft: string;
|
|
85
|
+
readonly linkTypeProfile: string;
|
|
86
|
+
readonly linkTypeShare: string;
|
|
87
|
+
readonly allScreenSizes: string;
|
|
88
|
+
readonly columnWidths: string;
|
|
89
|
+
/** A section's columns, by their proportions ("1:2"). */
|
|
90
|
+
readonly columnRatio: (ratio: string) => string;
|
|
91
|
+
readonly socialNetworks: string;
|
|
92
|
+
readonly addNetwork: string;
|
|
93
|
+
readonly navbarLinks: string;
|
|
94
|
+
readonly addLink: string;
|
|
95
|
+
/** The text a new navigation link starts with. */
|
|
96
|
+
readonly newLinkText: string;
|
|
97
|
+
/**
|
|
98
|
+
* Field names, help (`<key>.help`) and option names for the Settings tab, keyed as the
|
|
99
|
+
* schema in `inspector/schema.ts` names them; merged key by key.
|
|
100
|
+
*/
|
|
101
|
+
readonly inspectorLabels: Readonly<Record<string, string>>;
|
|
102
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
44
103
|
readonly attributes: string;
|
|
104
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
45
105
|
readonly style: string;
|
|
46
106
|
readonly rteFont: string;
|
|
47
107
|
readonly rteSize: string;
|
|
@@ -97,8 +157,8 @@ interface EditorLabels {
|
|
|
97
157
|
}
|
|
98
158
|
declare const DEFAULT_LABELS: EditorLabels;
|
|
99
159
|
/**
|
|
100
|
-
* Overrides on top of the defaults.
|
|
101
|
-
*
|
|
160
|
+
* Overrides on top of the defaults. The maps merge rather than replace, so a host renaming
|
|
161
|
+
* one step does not lose the other eight.
|
|
102
162
|
*/
|
|
103
163
|
declare function mergeLabels(overrides?: Partial<EditorLabels>): EditorLabels;
|
|
104
164
|
|
package/dist/index.d.ts
CHANGED
|
@@ -14,8 +14,10 @@ import { UIMessage, ChatTransport } from 'ai';
|
|
|
14
14
|
* keep existing hosts working unchanged, and a host overrides only the keys it cares about.
|
|
15
15
|
*
|
|
16
16
|
* Flat and shallow-merged on purpose. A nested dictionary reads better and merges worse —
|
|
17
|
-
* overriding one key inside a group would silently drop its siblings.
|
|
18
|
-
*
|
|
17
|
+
* overriding one key inside a group would silently drop its siblings. The only nested maps
|
|
18
|
+
* are the ones keyed by an id (`toolLabels`, `blockLabels`, `elementNames`,
|
|
19
|
+
* `inspectorLabels`), and those are
|
|
20
|
+
* merged key by key for exactly that reason.
|
|
19
21
|
*
|
|
20
22
|
* Values that interpolate are functions rather than templates with placeholders, so the
|
|
21
23
|
* translator controls word order instead of the format string.
|
|
@@ -38,10 +40,68 @@ interface EditorLabels {
|
|
|
38
40
|
readonly exportMjml: string;
|
|
39
41
|
/** `kind` is already upper-cased ("MJML", "HTML"). */
|
|
40
42
|
readonly copied: (kind: string) => string;
|
|
43
|
+
readonly tabBlocks: string;
|
|
44
|
+
readonly tabSettings: string;
|
|
45
|
+
readonly tabLayers: string;
|
|
41
46
|
readonly searchBlocks: string;
|
|
47
|
+
readonly noBlocksMatch: string;
|
|
48
|
+
readonly blockCategoryLayout: string;
|
|
49
|
+
readonly blockCategoryContent: string;
|
|
50
|
+
/** Keyed by grapesjs-mjml block id (`mj-1-column`, `mj-social-group`, …); merged key by key. */
|
|
51
|
+
readonly blockLabels: Readonly<Record<string, string>>;
|
|
52
|
+
/** Keyed by MJML tag, for the breadcrumb; merged key by key. */
|
|
53
|
+
readonly elementNames: Readonly<Record<string, string>>;
|
|
42
54
|
readonly expandAll: string;
|
|
43
55
|
readonly selectAnElement: string;
|
|
56
|
+
readonly settingsEmpty: string;
|
|
57
|
+
readonly emailSettings: string;
|
|
58
|
+
readonly loadingEditor: string;
|
|
59
|
+
readonly commentOnElement: string;
|
|
60
|
+
readonly groupContent: string;
|
|
61
|
+
readonly groupLayout: string;
|
|
62
|
+
readonly groupSpacing: string;
|
|
63
|
+
readonly groupStyle: string;
|
|
64
|
+
readonly groupAdvanced: string;
|
|
65
|
+
readonly otherAttributes: string;
|
|
66
|
+
readonly removeAttribute: string;
|
|
67
|
+
readonly resetToDefault: string;
|
|
68
|
+
readonly selectParent: string;
|
|
69
|
+
readonly duplicate: string;
|
|
70
|
+
readonly deleteElement: string;
|
|
71
|
+
readonly multipleSelected: (count: number) => string;
|
|
72
|
+
readonly editEachSide: string;
|
|
73
|
+
readonly increase: string;
|
|
74
|
+
readonly decrease: string;
|
|
75
|
+
/** The unit a length is in, on the button that changes it. */
|
|
76
|
+
readonly changeUnit: (unit: string) => string;
|
|
77
|
+
/** How a length without a unit (a line-height multiplier) shows its unit. */
|
|
78
|
+
readonly noUnit: string;
|
|
79
|
+
readonly sidesVertical: string;
|
|
80
|
+
readonly sidesHorizontal: string;
|
|
81
|
+
readonly sideTop: string;
|
|
82
|
+
readonly sideRight: string;
|
|
83
|
+
readonly sideBottom: string;
|
|
84
|
+
readonly sideLeft: string;
|
|
85
|
+
readonly linkTypeProfile: string;
|
|
86
|
+
readonly linkTypeShare: string;
|
|
87
|
+
readonly allScreenSizes: string;
|
|
88
|
+
readonly columnWidths: string;
|
|
89
|
+
/** A section's columns, by their proportions ("1:2"). */
|
|
90
|
+
readonly columnRatio: (ratio: string) => string;
|
|
91
|
+
readonly socialNetworks: string;
|
|
92
|
+
readonly addNetwork: string;
|
|
93
|
+
readonly navbarLinks: string;
|
|
94
|
+
readonly addLink: string;
|
|
95
|
+
/** The text a new navigation link starts with. */
|
|
96
|
+
readonly newLinkText: string;
|
|
97
|
+
/**
|
|
98
|
+
* Field names, help (`<key>.help`) and option names for the Settings tab, keyed as the
|
|
99
|
+
* schema in `inspector/schema.ts` names them; merged key by key.
|
|
100
|
+
*/
|
|
101
|
+
readonly inspectorLabels: Readonly<Record<string, string>>;
|
|
102
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
44
103
|
readonly attributes: string;
|
|
104
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
45
105
|
readonly style: string;
|
|
46
106
|
readonly rteFont: string;
|
|
47
107
|
readonly rteSize: string;
|
|
@@ -97,8 +157,8 @@ interface EditorLabels {
|
|
|
97
157
|
}
|
|
98
158
|
declare const DEFAULT_LABELS: EditorLabels;
|
|
99
159
|
/**
|
|
100
|
-
* Overrides on top of the defaults.
|
|
101
|
-
*
|
|
160
|
+
* Overrides on top of the defaults. The maps merge rather than replace, so a host renaming
|
|
161
|
+
* one step does not lose the other eight.
|
|
102
162
|
*/
|
|
103
163
|
declare function mergeLabels(overrides?: Partial<EditorLabels>): EditorLabels;
|
|
104
164
|
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mjml-agent-editor/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "React MJML editor with an agent chat panel and canvas comments.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mjml",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"@types/react-dom": "^19.2.3",
|
|
84
84
|
"ai": "^6.0.238",
|
|
85
85
|
"jsdom": "^26.1.0",
|
|
86
|
+
"mjml": "^4.18.0",
|
|
86
87
|
"react": "19.2.4",
|
|
87
88
|
"react-dom": "19.2.4",
|
|
88
89
|
"tsup": "^8.5.1",
|
|
@@ -189,92 +189,73 @@
|
|
|
189
189
|
display: none;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
/* ──
|
|
193
|
-
.editor-dark .gjs-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
background-color: var(--mjml-editor-panel-elevated);
|
|
197
|
-
border: 1px solid var(--mjml-editor-border);
|
|
198
|
-
border-radius: 6px;
|
|
199
|
-
color: var(--mjml-editor-fg);
|
|
192
|
+
/* ── Layers: rows named by content, with an icon for each kind ─────────────── */
|
|
193
|
+
.editor-dark .gjs-layer {
|
|
194
|
+
font-weight: 400;
|
|
195
|
+
font-size: 12px;
|
|
200
196
|
}
|
|
201
|
-
.editor-dark .gjs-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
197
|
+
.editor-dark .gjs-layer-item {
|
|
198
|
+
padding: 4px 8px;
|
|
199
|
+
border-bottom: none;
|
|
200
|
+
background-color: transparent;
|
|
201
|
+
}
|
|
202
|
+
.editor-dark .gjs-layer-title {
|
|
203
|
+
color: var(--mjml-editor-neutral);
|
|
207
204
|
}
|
|
208
|
-
.editor-dark .gjs-
|
|
209
|
-
.editor-dark .gjs-
|
|
210
|
-
|
|
211
|
-
border-top-color: var(--mjml-editor-fg-subtle);
|
|
205
|
+
.editor-dark .gjs-layer-title-c,
|
|
206
|
+
.editor-dark .gjs-layer-title-inn {
|
|
207
|
+
min-width: 0;
|
|
212
208
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
font-size: 11px;
|
|
219
|
-
font-weight: 500;
|
|
220
|
-
line-height: 1.4;
|
|
221
|
-
letter-spacing: normal;
|
|
222
|
-
text-transform: none;
|
|
209
|
+
.editor-dark .gjs-layer__icon {
|
|
210
|
+
flex-shrink: 0;
|
|
211
|
+
width: 14px;
|
|
212
|
+
height: 14px;
|
|
213
|
+
padding-left: 0;
|
|
223
214
|
color: var(--mjml-editor-fg-subtle);
|
|
224
215
|
}
|
|
225
|
-
.
|
|
226
|
-
.editor-dark .gjs-
|
|
227
|
-
|
|
216
|
+
/* GrapesJS fills its icons; these are drawn with strokes. */
|
|
217
|
+
.editor-dark .gjs-layer__icon svg {
|
|
218
|
+
display: block;
|
|
219
|
+
width: 14px;
|
|
220
|
+
height: 14px;
|
|
221
|
+
fill: none;
|
|
222
|
+
stroke: currentColor;
|
|
228
223
|
}
|
|
229
|
-
.editor-dark .gjs-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
padding: 0;
|
|
224
|
+
.editor-dark .gjs-layer-name {
|
|
225
|
+
max-width: none;
|
|
226
|
+
min-width: 0;
|
|
227
|
+
overflow: hidden;
|
|
228
|
+
text-overflow: ellipsis;
|
|
235
229
|
}
|
|
236
|
-
.editor-dark .gjs-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
font-size: 12px;
|
|
230
|
+
.editor-dark .gjs-layer-count {
|
|
231
|
+
font-size: 10px;
|
|
232
|
+
color: var(--mjml-editor-fg-faint);
|
|
240
233
|
}
|
|
241
|
-
|
|
242
|
-
.editor-dark .gjs-
|
|
243
|
-
|
|
244
|
-
.editor-dark .gjs-sm-field input,
|
|
245
|
-
.editor-dark .gjs-sm-field select {
|
|
246
|
-
font-size: 12px;
|
|
234
|
+
/* How many it holds matters while they are out of sight. */
|
|
235
|
+
.editor-dark .gjs-layer.open > .gjs-layer-item .gjs-layer-count {
|
|
236
|
+
visibility: hidden;
|
|
247
237
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
.editor-dark .gjs-trt-header {
|
|
252
|
-
padding: 8px 10px;
|
|
253
|
-
background-color: var(--mjml-editor-panel-sunken);
|
|
254
|
-
color: var(--mjml-editor-neutral);
|
|
255
|
-
border-bottom: 1px solid var(--mjml-editor-border);
|
|
256
|
-
font-size: 11px;
|
|
257
|
-
font-weight: 600;
|
|
258
|
-
text-transform: uppercase;
|
|
259
|
-
letter-spacing: 0.04em;
|
|
238
|
+
.editor-dark .gjs-layer-move {
|
|
239
|
+
opacity: 0;
|
|
240
|
+
color: var(--mjml-editor-fg-subtle);
|
|
260
241
|
}
|
|
261
|
-
.editor-dark .gjs-
|
|
262
|
-
|
|
263
|
-
border-bottom: 1px solid var(--mjml-editor-panel-elevated);
|
|
242
|
+
.editor-dark .gjs-layer-item:hover .gjs-layer-move {
|
|
243
|
+
opacity: 1;
|
|
264
244
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
.editor-dark .gjs-layer-title {
|
|
268
|
-
color: var(--mjml-editor-neutral);
|
|
245
|
+
.editor-dark .gjs-layer.gjs-hovered > .gjs-layer-item {
|
|
246
|
+
background-color: var(--mjml-editor-panel-elevated);
|
|
269
247
|
}
|
|
270
248
|
.editor-dark .gjs-layer.gjs-selected > .gjs-layer-item {
|
|
271
249
|
background-color: color-mix(in srgb, var(--mjml-editor-accent) 22%, transparent);
|
|
272
250
|
}
|
|
251
|
+
.editor-dark .gjs-layer.gjs-selected > .gjs-layer-item .gjs-layer__icon {
|
|
252
|
+
color: var(--mjml-editor-fg);
|
|
253
|
+
}
|
|
273
254
|
|
|
274
|
-
/*
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
255
|
+
/* The canvas badge's icon is one of the same stroked icons. */
|
|
256
|
+
:root .gjs-badge__icon svg {
|
|
257
|
+
fill: none;
|
|
258
|
+
stroke: currentColor;
|
|
278
259
|
}
|
|
279
260
|
|
|
280
261
|
/* ── Drop placeholder (was green) → violet ───────────────────────────────── */
|
|
@@ -428,13 +409,3 @@
|
|
|
428
409
|
height: 12px;
|
|
429
410
|
border-width: 2px;
|
|
430
411
|
}
|
|
431
|
-
|
|
432
|
-
/* Image properties take the full row: a thumbnail at half the sidebar is too small to judge. */
|
|
433
|
-
.editor-dark .gjs-sm-property.gjs-sm-file {
|
|
434
|
-
width: 100%;
|
|
435
|
-
flex-basis: 100%;
|
|
436
|
-
}
|
|
437
|
-
.editor-dark .gjs-sm-property.gjs-sm-file .gjs-fields > * {
|
|
438
|
-
flex: 1 1 auto;
|
|
439
|
-
width: 100%;
|
|
440
|
-
}
|