@mjml-agent-editor/editor 0.1.17 → 0.3.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 +40 -5
- package/dist/canvas.cjs +3409 -624
- package/dist/canvas.cjs.map +1 -1
- package/dist/canvas.d.cts +30 -2
- package/dist/canvas.d.ts +30 -2
- package/dist/canvas.js +2946 -386
- package/dist/canvas.js.map +1 -1
- package/dist/{chunk-VJRKDFM4.js → chunk-K7KQC7LX.js} +201 -2
- package/dist/chunk-K7KQC7LX.js.map +1 -0
- package/dist/index.cjs +200 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -4
- package/dist/index.d.ts +69 -4
- package/dist/index.js +1 -1
- package/package.json +3 -2
- package/src/components/editor/editor-theme.css +55 -80
- package/dist/chunk-VJRKDFM4.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -5,6 +5,7 @@ export { CommentStore, CommentTarget, DocumentPatch, DocumentStore, EmailDocumen
|
|
|
5
5
|
import { EditorApi } from './canvas.cjs';
|
|
6
6
|
export { EditorState, SaveStatus } from './canvas.cjs';
|
|
7
7
|
import { UIMessage, ChatTransport } from 'ai';
|
|
8
|
+
import 'grapesjs';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Every word the editor puts on screen.
|
|
@@ -14,8 +15,10 @@ import { UIMessage, ChatTransport } from 'ai';
|
|
|
14
15
|
* keep existing hosts working unchanged, and a host overrides only the keys it cares about.
|
|
15
16
|
*
|
|
16
17
|
* 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
|
-
*
|
|
18
|
+
* overriding one key inside a group would silently drop its siblings. The only nested maps
|
|
19
|
+
* are the ones keyed by an id (`toolLabels`, `blockLabels`, `elementNames`,
|
|
20
|
+
* `inspectorLabels`), and those are
|
|
21
|
+
* merged key by key for exactly that reason.
|
|
19
22
|
*
|
|
20
23
|
* Values that interpolate are functions rather than templates with placeholders, so the
|
|
21
24
|
* translator controls word order instead of the format string.
|
|
@@ -38,10 +41,72 @@ interface EditorLabels {
|
|
|
38
41
|
readonly exportMjml: string;
|
|
39
42
|
/** `kind` is already upper-cased ("MJML", "HTML"). */
|
|
40
43
|
readonly copied: (kind: string) => string;
|
|
44
|
+
readonly tabBlocks: string;
|
|
45
|
+
readonly tabSettings: string;
|
|
46
|
+
readonly tabLayers: string;
|
|
41
47
|
readonly searchBlocks: string;
|
|
48
|
+
readonly noBlocksMatch: string;
|
|
49
|
+
/** Announced after a block is added from the keyboard, with the name on its tile. */
|
|
50
|
+
readonly blockAdded: (block: string) => string;
|
|
51
|
+
readonly blockCategoryLayout: string;
|
|
52
|
+
readonly blockCategoryContent: string;
|
|
53
|
+
/** Where the host's own sections (the `blocks` prop) are listed. */
|
|
54
|
+
readonly blockCategorySections: string;
|
|
55
|
+
/** Keyed by grapesjs-mjml block id (`mj-1-column`, `mj-social-group`, …); merged key by key. */
|
|
56
|
+
readonly blockLabels: Readonly<Record<string, string>>;
|
|
57
|
+
/** Keyed by MJML tag, for the breadcrumb; merged key by key. */
|
|
58
|
+
readonly elementNames: Readonly<Record<string, string>>;
|
|
42
59
|
readonly expandAll: string;
|
|
43
60
|
readonly selectAnElement: string;
|
|
61
|
+
readonly settingsEmpty: string;
|
|
62
|
+
readonly emailSettings: string;
|
|
63
|
+
readonly loadingEditor: string;
|
|
64
|
+
readonly commentOnElement: string;
|
|
65
|
+
readonly groupContent: string;
|
|
66
|
+
readonly groupLayout: string;
|
|
67
|
+
readonly groupSpacing: string;
|
|
68
|
+
readonly groupStyle: string;
|
|
69
|
+
readonly groupAdvanced: string;
|
|
70
|
+
readonly otherAttributes: string;
|
|
71
|
+
readonly removeAttribute: string;
|
|
72
|
+
readonly resetToDefault: string;
|
|
73
|
+
readonly selectParent: string;
|
|
74
|
+
readonly duplicate: string;
|
|
75
|
+
readonly deleteElement: string;
|
|
76
|
+
readonly multipleSelected: (count: number) => string;
|
|
77
|
+
readonly editEachSide: string;
|
|
78
|
+
readonly increase: string;
|
|
79
|
+
readonly decrease: string;
|
|
80
|
+
/** The unit a length is in, on the button that changes it. */
|
|
81
|
+
readonly changeUnit: (unit: string) => string;
|
|
82
|
+
/** How a length without a unit (a line-height multiplier) shows its unit. */
|
|
83
|
+
readonly noUnit: string;
|
|
84
|
+
readonly sidesVertical: string;
|
|
85
|
+
readonly sidesHorizontal: string;
|
|
86
|
+
readonly sideTop: string;
|
|
87
|
+
readonly sideRight: string;
|
|
88
|
+
readonly sideBottom: string;
|
|
89
|
+
readonly sideLeft: string;
|
|
90
|
+
readonly linkTypeProfile: string;
|
|
91
|
+
readonly linkTypeShare: string;
|
|
92
|
+
readonly allScreenSizes: string;
|
|
93
|
+
readonly columnWidths: string;
|
|
94
|
+
/** A section's columns, by their proportions ("1:2"). */
|
|
95
|
+
readonly columnRatio: (ratio: string) => string;
|
|
96
|
+
readonly socialNetworks: string;
|
|
97
|
+
readonly addNetwork: string;
|
|
98
|
+
readonly navbarLinks: string;
|
|
99
|
+
readonly addLink: string;
|
|
100
|
+
/** The text a new navigation link starts with. */
|
|
101
|
+
readonly newLinkText: string;
|
|
102
|
+
/**
|
|
103
|
+
* Field names, help (`<key>.help`) and option names for the Settings tab, keyed as the
|
|
104
|
+
* schema in `inspector/schema.ts` names them; merged key by key.
|
|
105
|
+
*/
|
|
106
|
+
readonly inspectorLabels: Readonly<Record<string, string>>;
|
|
107
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
44
108
|
readonly attributes: string;
|
|
109
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
45
110
|
readonly style: string;
|
|
46
111
|
readonly rteFont: string;
|
|
47
112
|
readonly rteSize: string;
|
|
@@ -97,8 +162,8 @@ interface EditorLabels {
|
|
|
97
162
|
}
|
|
98
163
|
declare const DEFAULT_LABELS: EditorLabels;
|
|
99
164
|
/**
|
|
100
|
-
* Overrides on top of the defaults.
|
|
101
|
-
*
|
|
165
|
+
* Overrides on top of the defaults. The maps merge rather than replace, so a host renaming
|
|
166
|
+
* one step does not lose the other eight.
|
|
102
167
|
*/
|
|
103
168
|
declare function mergeLabels(overrides?: Partial<EditorLabels>): EditorLabels;
|
|
104
169
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { CommentStore, CommentTarget, DocumentPatch, DocumentStore, EmailDocumen
|
|
|
5
5
|
import { EditorApi } from './canvas.js';
|
|
6
6
|
export { EditorState, SaveStatus } from './canvas.js';
|
|
7
7
|
import { UIMessage, ChatTransport } from 'ai';
|
|
8
|
+
import 'grapesjs';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Every word the editor puts on screen.
|
|
@@ -14,8 +15,10 @@ import { UIMessage, ChatTransport } from 'ai';
|
|
|
14
15
|
* keep existing hosts working unchanged, and a host overrides only the keys it cares about.
|
|
15
16
|
*
|
|
16
17
|
* 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
|
-
*
|
|
18
|
+
* overriding one key inside a group would silently drop its siblings. The only nested maps
|
|
19
|
+
* are the ones keyed by an id (`toolLabels`, `blockLabels`, `elementNames`,
|
|
20
|
+
* `inspectorLabels`), and those are
|
|
21
|
+
* merged key by key for exactly that reason.
|
|
19
22
|
*
|
|
20
23
|
* Values that interpolate are functions rather than templates with placeholders, so the
|
|
21
24
|
* translator controls word order instead of the format string.
|
|
@@ -38,10 +41,72 @@ interface EditorLabels {
|
|
|
38
41
|
readonly exportMjml: string;
|
|
39
42
|
/** `kind` is already upper-cased ("MJML", "HTML"). */
|
|
40
43
|
readonly copied: (kind: string) => string;
|
|
44
|
+
readonly tabBlocks: string;
|
|
45
|
+
readonly tabSettings: string;
|
|
46
|
+
readonly tabLayers: string;
|
|
41
47
|
readonly searchBlocks: string;
|
|
48
|
+
readonly noBlocksMatch: string;
|
|
49
|
+
/** Announced after a block is added from the keyboard, with the name on its tile. */
|
|
50
|
+
readonly blockAdded: (block: string) => string;
|
|
51
|
+
readonly blockCategoryLayout: string;
|
|
52
|
+
readonly blockCategoryContent: string;
|
|
53
|
+
/** Where the host's own sections (the `blocks` prop) are listed. */
|
|
54
|
+
readonly blockCategorySections: string;
|
|
55
|
+
/** Keyed by grapesjs-mjml block id (`mj-1-column`, `mj-social-group`, …); merged key by key. */
|
|
56
|
+
readonly blockLabels: Readonly<Record<string, string>>;
|
|
57
|
+
/** Keyed by MJML tag, for the breadcrumb; merged key by key. */
|
|
58
|
+
readonly elementNames: Readonly<Record<string, string>>;
|
|
42
59
|
readonly expandAll: string;
|
|
43
60
|
readonly selectAnElement: string;
|
|
61
|
+
readonly settingsEmpty: string;
|
|
62
|
+
readonly emailSettings: string;
|
|
63
|
+
readonly loadingEditor: string;
|
|
64
|
+
readonly commentOnElement: string;
|
|
65
|
+
readonly groupContent: string;
|
|
66
|
+
readonly groupLayout: string;
|
|
67
|
+
readonly groupSpacing: string;
|
|
68
|
+
readonly groupStyle: string;
|
|
69
|
+
readonly groupAdvanced: string;
|
|
70
|
+
readonly otherAttributes: string;
|
|
71
|
+
readonly removeAttribute: string;
|
|
72
|
+
readonly resetToDefault: string;
|
|
73
|
+
readonly selectParent: string;
|
|
74
|
+
readonly duplicate: string;
|
|
75
|
+
readonly deleteElement: string;
|
|
76
|
+
readonly multipleSelected: (count: number) => string;
|
|
77
|
+
readonly editEachSide: string;
|
|
78
|
+
readonly increase: string;
|
|
79
|
+
readonly decrease: string;
|
|
80
|
+
/** The unit a length is in, on the button that changes it. */
|
|
81
|
+
readonly changeUnit: (unit: string) => string;
|
|
82
|
+
/** How a length without a unit (a line-height multiplier) shows its unit. */
|
|
83
|
+
readonly noUnit: string;
|
|
84
|
+
readonly sidesVertical: string;
|
|
85
|
+
readonly sidesHorizontal: string;
|
|
86
|
+
readonly sideTop: string;
|
|
87
|
+
readonly sideRight: string;
|
|
88
|
+
readonly sideBottom: string;
|
|
89
|
+
readonly sideLeft: string;
|
|
90
|
+
readonly linkTypeProfile: string;
|
|
91
|
+
readonly linkTypeShare: string;
|
|
92
|
+
readonly allScreenSizes: string;
|
|
93
|
+
readonly columnWidths: string;
|
|
94
|
+
/** A section's columns, by their proportions ("1:2"). */
|
|
95
|
+
readonly columnRatio: (ratio: string) => string;
|
|
96
|
+
readonly socialNetworks: string;
|
|
97
|
+
readonly addNetwork: string;
|
|
98
|
+
readonly navbarLinks: string;
|
|
99
|
+
readonly addLink: string;
|
|
100
|
+
/** The text a new navigation link starts with. */
|
|
101
|
+
readonly newLinkText: string;
|
|
102
|
+
/**
|
|
103
|
+
* Field names, help (`<key>.help`) and option names for the Settings tab, keyed as the
|
|
104
|
+
* schema in `inspector/schema.ts` names them; merged key by key.
|
|
105
|
+
*/
|
|
106
|
+
readonly inspectorLabels: Readonly<Record<string, string>>;
|
|
107
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
44
108
|
readonly attributes: string;
|
|
109
|
+
/** @deprecated The Settings tab no longer splits attributes from style. */
|
|
45
110
|
readonly style: string;
|
|
46
111
|
readonly rteFont: string;
|
|
47
112
|
readonly rteSize: string;
|
|
@@ -97,8 +162,8 @@ interface EditorLabels {
|
|
|
97
162
|
}
|
|
98
163
|
declare const DEFAULT_LABELS: EditorLabels;
|
|
99
164
|
/**
|
|
100
|
-
* Overrides on top of the defaults.
|
|
101
|
-
*
|
|
165
|
+
* Overrides on top of the defaults. The maps merge rather than replace, so a host renaming
|
|
166
|
+
* one step does not lose the other eight.
|
|
102
167
|
*/
|
|
103
168
|
declare function mergeLabels(overrides?: Partial<EditorLabels>): EditorLabels;
|
|
104
169
|
|
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.3.0",
|
|
4
4
|
"description": "React MJML editor with an agent chat panel and canvas comments.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mjml",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"remark-gfm": "^4.0.1",
|
|
72
72
|
"sonner": "^2.0.7",
|
|
73
73
|
"tailwind-merge": "^3.6.0",
|
|
74
|
-
"@mjml-agent-editor/core": "0.
|
|
74
|
+
"@mjml-agent-editor/core": "0.2.0"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"ai": "^6.0.230",
|
|
@@ -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",
|
|
@@ -155,6 +155,10 @@
|
|
|
155
155
|
box-shadow 0.12s ease,
|
|
156
156
|
background-color 0.12s ease;
|
|
157
157
|
}
|
|
158
|
+
.editor-dark .gjs-block:focus-visible {
|
|
159
|
+
outline: 2px solid var(--mjml-editor-accent);
|
|
160
|
+
outline-offset: 1px;
|
|
161
|
+
}
|
|
158
162
|
.editor-dark .gjs-block:hover {
|
|
159
163
|
border-color: var(--mjml-editor-accent);
|
|
160
164
|
background-color: var(--mjml-editor-panel-raised);
|
|
@@ -189,92 +193,73 @@
|
|
|
189
193
|
display: none;
|
|
190
194
|
}
|
|
191
195
|
|
|
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);
|
|
196
|
+
/* ── Layers: rows named by content, with an icon for each kind ─────────────── */
|
|
197
|
+
.editor-dark .gjs-layer {
|
|
198
|
+
font-weight: 400;
|
|
199
|
+
font-size: 12px;
|
|
200
200
|
}
|
|
201
|
-
.editor-dark .gjs-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
.editor-dark .gjs-clm-field input {
|
|
206
|
-
color: var(--mjml-editor-fg);
|
|
201
|
+
.editor-dark .gjs-layer-item {
|
|
202
|
+
padding: 4px 8px;
|
|
203
|
+
border-bottom: none;
|
|
204
|
+
background-color: transparent;
|
|
207
205
|
}
|
|
208
|
-
.editor-dark .gjs-
|
|
209
|
-
|
|
210
|
-
border-bottom-color: var(--mjml-editor-fg-subtle);
|
|
211
|
-
border-top-color: var(--mjml-editor-fg-subtle);
|
|
206
|
+
.editor-dark .gjs-layer-title {
|
|
207
|
+
color: var(--mjml-editor-neutral);
|
|
212
208
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
.editor-dark .gjs-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
text-transform: none;
|
|
209
|
+
.editor-dark .gjs-layer-title-c,
|
|
210
|
+
.editor-dark .gjs-layer-title-inn {
|
|
211
|
+
min-width: 0;
|
|
212
|
+
}
|
|
213
|
+
.editor-dark .gjs-layer__icon {
|
|
214
|
+
flex-shrink: 0;
|
|
215
|
+
width: 14px;
|
|
216
|
+
height: 14px;
|
|
217
|
+
padding-left: 0;
|
|
223
218
|
color: var(--mjml-editor-fg-subtle);
|
|
224
219
|
}
|
|
225
|
-
.
|
|
226
|
-
.editor-dark .gjs-
|
|
227
|
-
|
|
220
|
+
/* GrapesJS fills its icons; these are drawn with strokes. */
|
|
221
|
+
.editor-dark .gjs-layer__icon svg {
|
|
222
|
+
display: block;
|
|
223
|
+
width: 14px;
|
|
224
|
+
height: 14px;
|
|
225
|
+
fill: none;
|
|
226
|
+
stroke: currentColor;
|
|
228
227
|
}
|
|
229
|
-
.editor-dark .gjs-
|
|
230
|
-
|
|
228
|
+
.editor-dark .gjs-layer-name {
|
|
229
|
+
max-width: none;
|
|
230
|
+
min-width: 0;
|
|
231
|
+
overflow: hidden;
|
|
232
|
+
text-overflow: ellipsis;
|
|
231
233
|
}
|
|
232
|
-
.editor-dark .gjs-
|
|
233
|
-
|
|
234
|
-
|
|
234
|
+
.editor-dark .gjs-layer-count {
|
|
235
|
+
font-size: 10px;
|
|
236
|
+
color: var(--mjml-editor-fg-faint);
|
|
235
237
|
}
|
|
236
|
-
.
|
|
237
|
-
.editor-dark .gjs-
|
|
238
|
-
|
|
239
|
-
font-size: 12px;
|
|
238
|
+
/* How many it holds matters while they are out of sight. */
|
|
239
|
+
.editor-dark .gjs-layer.open > .gjs-layer-item .gjs-layer-count {
|
|
240
|
+
visibility: hidden;
|
|
240
241
|
}
|
|
241
|
-
.editor-dark .gjs-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.editor-dark .gjs-sm-field input,
|
|
245
|
-
.editor-dark .gjs-sm-field select {
|
|
246
|
-
font-size: 12px;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/* Sector headers */
|
|
250
|
-
.editor-dark .gjs-sm-sector-title,
|
|
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;
|
|
242
|
+
.editor-dark .gjs-layer-move {
|
|
243
|
+
opacity: 0;
|
|
244
|
+
color: var(--mjml-editor-fg-subtle);
|
|
260
245
|
}
|
|
261
|
-
.editor-dark .gjs-
|
|
262
|
-
|
|
263
|
-
border-bottom: 1px solid var(--mjml-editor-panel-elevated);
|
|
246
|
+
.editor-dark .gjs-layer-item:hover .gjs-layer-move {
|
|
247
|
+
opacity: 1;
|
|
264
248
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
.editor-dark .gjs-layer-title {
|
|
268
|
-
color: var(--mjml-editor-neutral);
|
|
249
|
+
.editor-dark .gjs-layer.gjs-hovered > .gjs-layer-item {
|
|
250
|
+
background-color: var(--mjml-editor-panel-elevated);
|
|
269
251
|
}
|
|
270
252
|
.editor-dark .gjs-layer.gjs-selected > .gjs-layer-item {
|
|
271
253
|
background-color: color-mix(in srgb, var(--mjml-editor-accent) 22%, transparent);
|
|
272
254
|
}
|
|
255
|
+
.editor-dark .gjs-layer.gjs-selected > .gjs-layer-item .gjs-layer__icon {
|
|
256
|
+
color: var(--mjml-editor-fg);
|
|
257
|
+
}
|
|
273
258
|
|
|
274
|
-
/*
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
259
|
+
/* The canvas badge's icon is one of the same stroked icons. */
|
|
260
|
+
:root .gjs-badge__icon svg {
|
|
261
|
+
fill: none;
|
|
262
|
+
stroke: currentColor;
|
|
278
263
|
}
|
|
279
264
|
|
|
280
265
|
/* ── Drop placeholder (was green) → violet ───────────────────────────────── */
|
|
@@ -428,13 +413,3 @@
|
|
|
428
413
|
height: 12px;
|
|
429
414
|
border-width: 2px;
|
|
430
415
|
}
|
|
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
|
-
}
|