@parathantl/react-email-editor 0.1.8 โ 0.1.10
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 +75 -0
- package/dist/index.cjs +92 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +74 -9
- package/dist/index.css.map +1 -1
- package/dist/index.js +92 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -165,6 +165,81 @@ Or pass MJML at init time without a ref:
|
|
|
165
165
|
| `className` | `string` | CSS class for the outer wrapper |
|
|
166
166
|
| `style` | `CSSProperties` | Inline styles for the outer wrapper |
|
|
167
167
|
|
|
168
|
+
## Custom Icons (`customIcons`)
|
|
169
|
+
|
|
170
|
+
You can pass `customIcons` to override built-in UI icons.
|
|
171
|
+
Every key is optional. If you skip a key, the editor uses its default emoji/icon.
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
<EmailEditor
|
|
175
|
+
customIcons={{
|
|
176
|
+
desktop: '๐ฅ๏ธ',
|
|
177
|
+
mobile: '๐ฑ',
|
|
178
|
+
undo: 'โฉ๏ธ',
|
|
179
|
+
redo: 'โช๏ธ',
|
|
180
|
+
addSection: 'โ',
|
|
181
|
+
sidebar: '๐',
|
|
182
|
+
properties: 'โ๏ธ',
|
|
183
|
+
visual: '๐จ',
|
|
184
|
+
source: '๐งพ',
|
|
185
|
+
preview: '๐๏ธ',
|
|
186
|
+
sectionDrag: 'โ๏ธ',
|
|
187
|
+
sectionDuplicate: '๐',
|
|
188
|
+
sectionRemove: '๐๏ธ',
|
|
189
|
+
blockDuplicate: '๐',
|
|
190
|
+
blockRemove: '๐๏ธ',
|
|
191
|
+
previewDesktop: '๐ฅ๏ธ',
|
|
192
|
+
previewMobile: '๐ฑ',
|
|
193
|
+
paletteText: '๐',
|
|
194
|
+
paletteHeading: '๐ค',
|
|
195
|
+
paletteButton: '๐',
|
|
196
|
+
paletteImage: '๐ผ๏ธ',
|
|
197
|
+
paletteVideo: 'โถ๏ธ',
|
|
198
|
+
paletteDivider: 'โ',
|
|
199
|
+
paletteSpacer: 'โ๏ธ',
|
|
200
|
+
paletteSocial: '๐',
|
|
201
|
+
paletteHtml: '๐ป',
|
|
202
|
+
paletteCountdown: 'โฐ',
|
|
203
|
+
paletteMenu: '๐',
|
|
204
|
+
paletteHero: 'โญ',
|
|
205
|
+
}}
|
|
206
|
+
/>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Available `customIcons` keys
|
|
210
|
+
|
|
211
|
+
| Key | Used In |
|
|
212
|
+
|-----|---------|
|
|
213
|
+
| `desktop` | Canvas desktop view toggle |
|
|
214
|
+
| `mobile` | Canvas mobile view toggle |
|
|
215
|
+
| `undo` | Canvas undo button |
|
|
216
|
+
| `redo` | Canvas redo button |
|
|
217
|
+
| `addSection` | Canvas "Add Section" button |
|
|
218
|
+
| `sidebar` | Toolbar sidebar toggle button |
|
|
219
|
+
| `properties` | Toolbar properties toggle button |
|
|
220
|
+
| `visual` | Toolbar Visual tab icon |
|
|
221
|
+
| `source` | Toolbar Source tab icon |
|
|
222
|
+
| `preview` | Toolbar Preview tab icon |
|
|
223
|
+
| `sectionDrag` | Section drag handle |
|
|
224
|
+
| `sectionDuplicate` | Section duplicate action |
|
|
225
|
+
| `sectionRemove` | Section remove action |
|
|
226
|
+
| `blockDuplicate` | Block duplicate action |
|
|
227
|
+
| `blockRemove` | Block remove action |
|
|
228
|
+
| `previewDesktop` | Preview panel desktop toggle |
|
|
229
|
+
| `previewMobile` | Preview panel mobile toggle |
|
|
230
|
+
| `paletteText` | Block palette icon for Text |
|
|
231
|
+
| `paletteHeading` | Block palette icon for Heading |
|
|
232
|
+
| `paletteButton` | Block palette icon for Button |
|
|
233
|
+
| `paletteImage` | Block palette icon for Image |
|
|
234
|
+
| `paletteVideo` | Block palette icon for Video |
|
|
235
|
+
| `paletteDivider` | Block palette icon for Divider |
|
|
236
|
+
| `paletteSpacer` | Block palette icon for Spacer |
|
|
237
|
+
| `paletteSocial` | Block palette icon for Social |
|
|
238
|
+
| `paletteHtml` | Block palette icon for HTML |
|
|
239
|
+
| `paletteCountdown` | Block palette icon for Countdown |
|
|
240
|
+
| `paletteMenu` | Block palette icon for Menu |
|
|
241
|
+
| `paletteHero` | Block palette icon for Hero |
|
|
242
|
+
|
|
168
243
|
## Block Types
|
|
169
244
|
|
|
170
245
|
| Type | Description | MJML Output |
|
package/dist/index.cjs
CHANGED
|
@@ -3080,7 +3080,6 @@ var editor_default = {
|
|
|
3080
3080
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3081
3081
|
var Toolbar = import_react15.default.memo(function Toolbar2({ sidebarOpen, propertiesOpen, onToggleSidebar, onToggleProperties, toolbarActions }) {
|
|
3082
3082
|
const { template, activeTab } = useTemplateContext();
|
|
3083
|
-
const { canUndo, canRedo } = useHistoryContext();
|
|
3084
3083
|
const dispatch = useEditorDispatch();
|
|
3085
3084
|
const fileInputRef = (0, import_react15.useRef)(null);
|
|
3086
3085
|
const [exportOpen, setExportOpen] = (0, import_react15.useState)(false);
|
|
@@ -3098,12 +3097,6 @@ var Toolbar = import_react15.default.memo(function Toolbar2({ sidebarOpen, prope
|
|
|
3098
3097
|
},
|
|
3099
3098
|
[dispatch]
|
|
3100
3099
|
);
|
|
3101
|
-
const handleUndo = (0, import_react15.useCallback)(() => {
|
|
3102
|
-
dispatch({ type: "UNDO" });
|
|
3103
|
-
}, [dispatch]);
|
|
3104
|
-
const handleRedo = (0, import_react15.useCallback)(() => {
|
|
3105
|
-
dispatch({ type: "REDO" });
|
|
3106
|
-
}, [dispatch]);
|
|
3107
3100
|
const handleExportMJML = (0, import_react15.useCallback)(() => {
|
|
3108
3101
|
const mjml = generateMJML(templateRef.current);
|
|
3109
3102
|
const blob = new Blob([mjml], { type: "text/xml" });
|
|
@@ -3171,30 +3164,6 @@ var Toolbar = import_react15.default.memo(function Toolbar2({ sidebarOpen, prope
|
|
|
3171
3164
|
[dispatch]
|
|
3172
3165
|
);
|
|
3173
3166
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `ee-toolbar ${toolbar_default.toolbar}`, role: "toolbar", "aria-label": "Editor toolbar", children: [
|
|
3174
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `ee-toolbar-history ${toolbar_default.toolbarGroup}`, role: "group", "aria-label": "History", children: [
|
|
3175
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3176
|
-
"button",
|
|
3177
|
-
{
|
|
3178
|
-
className: `ee-toolbar-undo ${toolbar_default.toolbarBtn}`,
|
|
3179
|
-
onClick: handleUndo,
|
|
3180
|
-
disabled: !canUndo,
|
|
3181
|
-
title: "Undo (Ctrl+Z)",
|
|
3182
|
-
"aria-label": "Undo",
|
|
3183
|
-
children: "Undo"
|
|
3184
|
-
}
|
|
3185
|
-
),
|
|
3186
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3187
|
-
"button",
|
|
3188
|
-
{
|
|
3189
|
-
className: `ee-toolbar-redo ${toolbar_default.toolbarBtn}`,
|
|
3190
|
-
onClick: handleRedo,
|
|
3191
|
-
disabled: !canRedo,
|
|
3192
|
-
title: "Redo (Ctrl+Shift+Z)",
|
|
3193
|
-
"aria-label": "Redo",
|
|
3194
|
-
children: "Redo"
|
|
3195
|
-
}
|
|
3196
|
-
)
|
|
3197
|
-
] }),
|
|
3198
3167
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: editor_default.panelToggle, children: [
|
|
3199
3168
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3200
3169
|
"button",
|
|
@@ -27547,6 +27516,12 @@ var import_react40 = __toESM(require("react"));
|
|
|
27547
27516
|
|
|
27548
27517
|
// src/styles/canvas.module.css
|
|
27549
27518
|
var canvas_default = {
|
|
27519
|
+
"canvasArea": "canvasArea",
|
|
27520
|
+
"canvasHeader": "canvasHeader",
|
|
27521
|
+
"canvasHeaderCenter": "canvasHeaderCenter",
|
|
27522
|
+
"canvasHeaderGroup": "canvasHeaderGroup",
|
|
27523
|
+
"canvasHeaderBtn": "canvasHeaderBtn",
|
|
27524
|
+
"canvasHeaderBtnActive": "canvasHeaderBtnActive",
|
|
27550
27525
|
"canvasWrapper": "canvasWrapper",
|
|
27551
27526
|
"canvasBody": "canvasBody",
|
|
27552
27527
|
"canvasBodyDragOver": "canvasBodyDragOver",
|
|
@@ -28088,10 +28063,13 @@ var SectionDropZone = import_react43.default.memo(function SectionDropZone2({ in
|
|
|
28088
28063
|
|
|
28089
28064
|
// src/components/Canvas/Canvas.tsx
|
|
28090
28065
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
28066
|
+
var MOBILE_WIDTH = 375;
|
|
28091
28067
|
var Canvas = import_react44.default.memo(function Canvas2() {
|
|
28092
28068
|
const { template } = useTemplateContext();
|
|
28069
|
+
const { canUndo, canRedo } = useHistoryContext();
|
|
28093
28070
|
const dispatch = useEditorDispatch();
|
|
28094
28071
|
const [isDragOver, setIsDragOver] = (0, import_react44.useState)(false);
|
|
28072
|
+
const [previewMode, setPreviewMode] = (0, import_react44.useState)("desktop");
|
|
28095
28073
|
const handleAddSection = (0, import_react44.useCallback)(() => {
|
|
28096
28074
|
dispatch({ type: "ADD_SECTION", payload: { section: createSection() } });
|
|
28097
28075
|
}, [dispatch]);
|
|
@@ -28129,30 +28107,89 @@ var Canvas = import_react44.default.memo(function Canvas2() {
|
|
|
28129
28107
|
},
|
|
28130
28108
|
[dispatch]
|
|
28131
28109
|
);
|
|
28132
|
-
|
|
28133
|
-
"
|
|
28134
|
-
|
|
28135
|
-
|
|
28136
|
-
|
|
28137
|
-
|
|
28138
|
-
|
|
28139
|
-
|
|
28140
|
-
|
|
28141
|
-
|
|
28142
|
-
|
|
28143
|
-
|
|
28144
|
-
|
|
28145
|
-
|
|
28146
|
-
|
|
28147
|
-
|
|
28148
|
-
|
|
28149
|
-
|
|
28150
|
-
|
|
28151
|
-
|
|
28152
|
-
|
|
28153
|
-
|
|
28154
|
-
|
|
28155
|
-
|
|
28110
|
+
const handleUndo = (0, import_react44.useCallback)(() => {
|
|
28111
|
+
dispatch({ type: "UNDO" });
|
|
28112
|
+
}, [dispatch]);
|
|
28113
|
+
const handleRedo = (0, import_react44.useCallback)(() => {
|
|
28114
|
+
dispatch({ type: "REDO" });
|
|
28115
|
+
}, [dispatch]);
|
|
28116
|
+
const canvasWidth = previewMode === "mobile" ? MOBILE_WIDTH : template.globalStyles.width;
|
|
28117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `ee-canvas-area ${canvas_default.canvasArea}`, children: [
|
|
28118
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `ee-canvas-header ${canvas_default.canvasHeader}`, children: [
|
|
28119
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: `ee-canvas-header-center ${canvas_default.canvasHeaderCenter}`, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `ee-canvas-view-toggle ${canvas_default.canvasHeaderGroup}`, role: "group", "aria-label": "Preview size", children: [
|
|
28120
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
28121
|
+
"button",
|
|
28122
|
+
{
|
|
28123
|
+
className: `ee-canvas-view-desktop ${canvas_default.canvasHeaderBtn} ${previewMode === "desktop" ? `ee-canvas-view--active ${canvas_default.canvasHeaderBtnActive}` : ""}`,
|
|
28124
|
+
onClick: () => setPreviewMode("desktop"),
|
|
28125
|
+
"aria-pressed": previewMode === "desktop",
|
|
28126
|
+
"aria-label": "Desktop view",
|
|
28127
|
+
title: `Desktop (${template.globalStyles.width}px)`,
|
|
28128
|
+
children: "\u{1F5A5}"
|
|
28129
|
+
}
|
|
28130
|
+
),
|
|
28131
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
28132
|
+
"button",
|
|
28133
|
+
{
|
|
28134
|
+
className: `ee-canvas-view-mobile ${canvas_default.canvasHeaderBtn} ${previewMode === "mobile" ? `ee-canvas-view--active ${canvas_default.canvasHeaderBtnActive}` : ""}`,
|
|
28135
|
+
onClick: () => setPreviewMode("mobile"),
|
|
28136
|
+
"aria-pressed": previewMode === "mobile",
|
|
28137
|
+
"aria-label": "Mobile view",
|
|
28138
|
+
title: "Mobile (375px)",
|
|
28139
|
+
children: "\u{1F4F1}"
|
|
28140
|
+
}
|
|
28141
|
+
)
|
|
28142
|
+
] }) }),
|
|
28143
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `ee-canvas-history ${canvas_default.canvasHeaderGroup}`, role: "group", "aria-label": "History", children: [
|
|
28144
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
28145
|
+
"button",
|
|
28146
|
+
{
|
|
28147
|
+
className: `ee-canvas-undo ${canvas_default.canvasHeaderBtn}`,
|
|
28148
|
+
onClick: handleUndo,
|
|
28149
|
+
disabled: !canUndo,
|
|
28150
|
+
title: "Undo (Ctrl+Z)",
|
|
28151
|
+
"aria-label": "Undo",
|
|
28152
|
+
children: "\u21A9"
|
|
28153
|
+
}
|
|
28154
|
+
),
|
|
28155
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
28156
|
+
"button",
|
|
28157
|
+
{
|
|
28158
|
+
className: `ee-canvas-redo ${canvas_default.canvasHeaderBtn}`,
|
|
28159
|
+
onClick: handleRedo,
|
|
28160
|
+
disabled: !canRedo,
|
|
28161
|
+
title: "Redo (Ctrl+Shift+Z)",
|
|
28162
|
+
"aria-label": "Redo",
|
|
28163
|
+
children: "\u21AA"
|
|
28164
|
+
}
|
|
28165
|
+
)
|
|
28166
|
+
] })
|
|
28167
|
+
] }),
|
|
28168
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: `ee-canvas-wrapper ${canvas_default.canvasWrapper}`, onClick: handleCanvasClick, role: "main", "aria-label": "Email canvas", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
28169
|
+
"div",
|
|
28170
|
+
{
|
|
28171
|
+
className: `ee-canvas-body ${canvas_default.canvasBody} ${isDragOver ? canvas_default.canvasBodyDragOver : ""}`,
|
|
28172
|
+
style: {
|
|
28173
|
+
width: canvasWidth,
|
|
28174
|
+
backgroundColor: template.globalStyles.backgroundColor,
|
|
28175
|
+
fontFamily: template.globalStyles.fontFamily
|
|
28176
|
+
},
|
|
28177
|
+
onClick: (e) => e.stopPropagation(),
|
|
28178
|
+
onDragOver: handleBodyDragOver,
|
|
28179
|
+
onDragLeave: handleBodyDragLeave,
|
|
28180
|
+
onDrop: handleBodyDrop,
|
|
28181
|
+
"aria-label": "Email content area",
|
|
28182
|
+
children: [
|
|
28183
|
+
template.sections.map((section, index) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react44.default.Fragment, { children: [
|
|
28184
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SectionDropZone, { index }),
|
|
28185
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Section, { section })
|
|
28186
|
+
] }, section.id)),
|
|
28187
|
+
template.sections.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SectionDropZone, { index: template.sections.length }),
|
|
28188
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { className: `ee-add-section ${canvas_default.addSectionBtn}`, onClick: handleAddSection, "aria-label": "Add new section", children: "+ Add Section" })
|
|
28189
|
+
]
|
|
28190
|
+
}
|
|
28191
|
+
) })
|
|
28192
|
+
] });
|
|
28156
28193
|
});
|
|
28157
28194
|
|
|
28158
28195
|
// src/components/Properties/SectionProperties.tsx
|