@kontakto/email-template-editor 2.1.0 → 2.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/dist/index.cjs +294 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +296 -103
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -166,6 +166,20 @@ function renderMarkdownString(str) {
|
|
|
166
166
|
}
|
|
167
167
|
return sanitizer(html2);
|
|
168
168
|
}
|
|
169
|
+
function renderInlineMarkdownString(str) {
|
|
170
|
+
const html2 = marked.marked.parseInline(str, {
|
|
171
|
+
async: false,
|
|
172
|
+
breaks: true,
|
|
173
|
+
gfm: true,
|
|
174
|
+
pedantic: false,
|
|
175
|
+
silent: false,
|
|
176
|
+
renderer: new CustomRenderer()
|
|
177
|
+
});
|
|
178
|
+
if (typeof html2 !== "string") {
|
|
179
|
+
throw new Error("marked.parseInline did not return a string");
|
|
180
|
+
}
|
|
181
|
+
return sanitizer(html2);
|
|
182
|
+
}
|
|
169
183
|
function EmailMarkdown(_a) {
|
|
170
184
|
var _b = _a, { markdown } = _b, props = __objRest(_b, ["markdown"]);
|
|
171
185
|
const data = React58.useMemo(() => renderMarkdownString(markdown), [markdown]);
|
|
@@ -691,7 +705,8 @@ function getFontFamily3(fontFamily) {
|
|
|
691
705
|
var HeadingPropsSchema = zod.z.object({
|
|
692
706
|
props: zod.z.object({
|
|
693
707
|
text: zod.z.string().optional().nullable(),
|
|
694
|
-
level: zod.z.enum(["h1", "h2", "h3"]).optional().nullable()
|
|
708
|
+
level: zod.z.enum(["h1", "h2", "h3"]).optional().nullable(),
|
|
709
|
+
markdown: zod.z.boolean().optional().nullable()
|
|
695
710
|
}).optional().nullable(),
|
|
696
711
|
style: zod.z.object({
|
|
697
712
|
color: COLOR_SCHEMA6,
|
|
@@ -710,28 +725,31 @@ var HeadingPropsDefaults = {
|
|
|
710
725
|
text: ""
|
|
711
726
|
};
|
|
712
727
|
function Heading({ props, style }) {
|
|
713
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
728
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
714
729
|
const level = (_a = props == null ? void 0 : props.level) != null ? _a : HeadingPropsDefaults.level;
|
|
715
730
|
const text = (_b = props == null ? void 0 : props.text) != null ? _b : HeadingPropsDefaults.text;
|
|
731
|
+
const isMarkdown = (_c = props == null ? void 0 : props.markdown) != null ? _c : false;
|
|
716
732
|
const hStyle = {
|
|
717
|
-
color: (
|
|
718
|
-
backgroundColor: (
|
|
719
|
-
fontWeight: (
|
|
720
|
-
lineHeight: (
|
|
733
|
+
color: (_d = style == null ? void 0 : style.color) != null ? _d : void 0,
|
|
734
|
+
backgroundColor: (_e = style == null ? void 0 : style.backgroundColor) != null ? _e : void 0,
|
|
735
|
+
fontWeight: (_f = style == null ? void 0 : style.fontWeight) != null ? _f : "bold",
|
|
736
|
+
lineHeight: (_g = style == null ? void 0 : style.lineHeight) != null ? _g : void 0,
|
|
721
737
|
letterSpacing: (style == null ? void 0 : style.letterSpacing) != null ? `${style.letterSpacing}px` : void 0,
|
|
722
|
-
textAlign: (
|
|
738
|
+
textAlign: (_h = style == null ? void 0 : style.textAlign) != null ? _h : void 0,
|
|
723
739
|
margin: 0,
|
|
724
740
|
fontFamily: getFontFamily3(style == null ? void 0 : style.fontFamily),
|
|
725
741
|
fontSize: getFontSize(level),
|
|
726
742
|
padding: getPadding7(style == null ? void 0 : style.padding)
|
|
727
743
|
};
|
|
744
|
+
const html2 = React58.useMemo(() => isMarkdown ? renderInlineMarkdownString(text) : null, [isMarkdown, text]);
|
|
745
|
+
const renderProps = isMarkdown ? { style: hStyle, dangerouslySetInnerHTML: { __html: html2 != null ? html2 : "" } } : { style: hStyle, children: text };
|
|
728
746
|
switch (level) {
|
|
729
747
|
case "h1":
|
|
730
|
-
return /* @__PURE__ */ React58__default.default.createElement("h1", {
|
|
748
|
+
return /* @__PURE__ */ React58__default.default.createElement("h1", __spreadValues({}, renderProps));
|
|
731
749
|
case "h2":
|
|
732
|
-
return /* @__PURE__ */ React58__default.default.createElement("h2", {
|
|
750
|
+
return /* @__PURE__ */ React58__default.default.createElement("h2", __spreadValues({}, renderProps));
|
|
733
751
|
case "h3":
|
|
734
|
-
return /* @__PURE__ */ React58__default.default.createElement("h3", {
|
|
752
|
+
return /* @__PURE__ */ React58__default.default.createElement("h3", __spreadValues({}, renderProps));
|
|
735
753
|
}
|
|
736
754
|
}
|
|
737
755
|
function getFontSize(level) {
|
|
@@ -2504,59 +2522,46 @@ function FontWeightInput({ label, defaultValue, onChange }) {
|
|
|
2504
2522
|
);
|
|
2505
2523
|
}
|
|
2506
2524
|
function LetterSpacingInput({ label, defaultValue, onChange }) {
|
|
2507
|
-
const
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
onChange(isNaN(value) ? null : value);
|
|
2525
|
+
const [value, setValue] = React58.useState(defaultValue != null ? defaultValue : 0);
|
|
2526
|
+
React58.useEffect(() => {
|
|
2527
|
+
setValue(defaultValue != null ? defaultValue : 0);
|
|
2528
|
+
}, [defaultValue]);
|
|
2529
|
+
const handleChange = (v) => {
|
|
2530
|
+
setValue(v);
|
|
2531
|
+
onChange(v === 0 ? null : v);
|
|
2515
2532
|
};
|
|
2516
|
-
return /* @__PURE__ */ React58__default.default.createElement(material.Stack, { spacing: 1, alignItems: "flex-start" }, /* @__PURE__ */ React58__default.default.createElement(
|
|
2517
|
-
|
|
2533
|
+
return /* @__PURE__ */ React58__default.default.createElement(material.Stack, { spacing: 1, alignItems: "flex-start" }, /* @__PURE__ */ React58__default.default.createElement(material.InputLabel, { shrink: true }, label), /* @__PURE__ */ React58__default.default.createElement(
|
|
2534
|
+
RawSliderInput,
|
|
2518
2535
|
{
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
type: "number",
|
|
2527
|
-
inputProps: { step: 0.5 },
|
|
2528
|
-
InputProps: {
|
|
2529
|
-
startAdornment: /* @__PURE__ */ React58__default.default.createElement(material.InputAdornment, { position: "start" }, /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.SpaceBarOutlined, { sx: { fontSize: 16 } })),
|
|
2530
|
-
endAdornment: /* @__PURE__ */ React58__default.default.createElement(material.Typography, { variant: "body2", color: "text.secondary" }, "px")
|
|
2531
|
-
}
|
|
2536
|
+
iconLabel: /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.SpaceBarOutlined, { sx: { fontSize: 16 } }),
|
|
2537
|
+
value,
|
|
2538
|
+
setValue: handleChange,
|
|
2539
|
+
units: "px",
|
|
2540
|
+
step: 0.1,
|
|
2541
|
+
min: 0,
|
|
2542
|
+
max: 2
|
|
2532
2543
|
}
|
|
2533
2544
|
));
|
|
2534
2545
|
}
|
|
2535
2546
|
function LineHeightInput({ label, defaultValue, onChange }) {
|
|
2536
|
-
const
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
onChange(isNaN(value) ? null : value);
|
|
2547
|
+
const [value, setValue] = React58.useState(defaultValue != null ? defaultValue : 0);
|
|
2548
|
+
React58.useEffect(() => {
|
|
2549
|
+
setValue(defaultValue != null ? defaultValue : 0);
|
|
2550
|
+
}, [defaultValue]);
|
|
2551
|
+
const handleChange = (v) => {
|
|
2552
|
+
setValue(v);
|
|
2553
|
+
onChange(v === 0 ? null : v);
|
|
2544
2554
|
};
|
|
2545
|
-
return /* @__PURE__ */ React58__default.default.createElement(material.Stack, { spacing: 1, alignItems: "flex-start" }, /* @__PURE__ */ React58__default.default.createElement(
|
|
2546
|
-
|
|
2555
|
+
return /* @__PURE__ */ React58__default.default.createElement(material.Stack, { spacing: 1, alignItems: "flex-start" }, /* @__PURE__ */ React58__default.default.createElement(material.InputLabel, { shrink: true }, label), /* @__PURE__ */ React58__default.default.createElement(
|
|
2556
|
+
RawSliderInput,
|
|
2547
2557
|
{
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
type: "number",
|
|
2556
|
-
inputProps: { step: 0.1 },
|
|
2557
|
-
InputProps: {
|
|
2558
|
-
startAdornment: /* @__PURE__ */ React58__default.default.createElement(material.InputAdornment, { position: "start" }, /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.FormatLineSpacingOutlined, { sx: { fontSize: 16 } }))
|
|
2559
|
-
}
|
|
2558
|
+
iconLabel: /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.FormatLineSpacingOutlined, { sx: { fontSize: 16 } }),
|
|
2559
|
+
value,
|
|
2560
|
+
setValue: handleChange,
|
|
2561
|
+
units: "",
|
|
2562
|
+
step: 0.1,
|
|
2563
|
+
min: 0,
|
|
2564
|
+
max: 2
|
|
2560
2565
|
}
|
|
2561
2566
|
));
|
|
2562
2567
|
}
|
|
@@ -6229,6 +6234,174 @@ function ButtonEditor({ style, props }) {
|
|
|
6229
6234
|
}
|
|
6230
6235
|
return /* @__PURE__ */ React58__default.default.createElement("div", { style: wrapperStyle }, /* @__PURE__ */ React58__default.default.createElement("span", { style: linkStyle }, /* @__PURE__ */ React58__default.default.createElement("span", null, text)));
|
|
6231
6236
|
}
|
|
6237
|
+
function useMarkdownToolbar({ text, isSelected, commitText, trackSelection }) {
|
|
6238
|
+
const textareaRef = React58.useRef(null);
|
|
6239
|
+
const [selection, setSelection] = React58.useState({ start: 0, end: 0 });
|
|
6240
|
+
const [linkPrompt, setLinkPrompt] = React58.useState(false);
|
|
6241
|
+
const pendingSelectionRef = React58.useRef(null);
|
|
6242
|
+
const textRef = React58.useRef(text);
|
|
6243
|
+
React58.useEffect(() => {
|
|
6244
|
+
textRef.current = text;
|
|
6245
|
+
}, [text]);
|
|
6246
|
+
const syncSelection = React58.useCallback(
|
|
6247
|
+
(start, end) => {
|
|
6248
|
+
const next = { start, end };
|
|
6249
|
+
setSelection(next);
|
|
6250
|
+
trackSelection == null ? void 0 : trackSelection(next);
|
|
6251
|
+
},
|
|
6252
|
+
[trackSelection]
|
|
6253
|
+
);
|
|
6254
|
+
const trackFocus = React58.useCallback(
|
|
6255
|
+
(e) => {
|
|
6256
|
+
var _a, _b;
|
|
6257
|
+
const el = e.currentTarget;
|
|
6258
|
+
const start = (_a = el.selectionStart) != null ? _a : el.value.length;
|
|
6259
|
+
const end = (_b = el.selectionEnd) != null ? _b : el.value.length;
|
|
6260
|
+
syncSelection(start, end);
|
|
6261
|
+
},
|
|
6262
|
+
[syncSelection]
|
|
6263
|
+
);
|
|
6264
|
+
React58.useEffect(() => {
|
|
6265
|
+
const target = pendingSelectionRef.current;
|
|
6266
|
+
if (!target) return;
|
|
6267
|
+
const ta = textareaRef.current;
|
|
6268
|
+
if (!ta) return;
|
|
6269
|
+
ta.focus();
|
|
6270
|
+
ta.setSelectionRange(target.start, target.end);
|
|
6271
|
+
syncSelection(target.start, target.end);
|
|
6272
|
+
pendingSelectionRef.current = null;
|
|
6273
|
+
}, [text, syncSelection]);
|
|
6274
|
+
React58.useEffect(() => {
|
|
6275
|
+
if (!isSelected || selection.start === selection.end) {
|
|
6276
|
+
setLinkPrompt(false);
|
|
6277
|
+
}
|
|
6278
|
+
}, [isSelected, selection.start, selection.end]);
|
|
6279
|
+
const wrapSelection = (prefix, suffix) => {
|
|
6280
|
+
var _a, _b;
|
|
6281
|
+
const ta = textareaRef.current;
|
|
6282
|
+
if (!ta) return;
|
|
6283
|
+
const start = (_a = ta.selectionStart) != null ? _a : selection.start;
|
|
6284
|
+
const end = (_b = ta.selectionEnd) != null ? _b : selection.end;
|
|
6285
|
+
if (start === end) return;
|
|
6286
|
+
const current = textRef.current;
|
|
6287
|
+
const selected = current.slice(start, end);
|
|
6288
|
+
const before = current.slice(0, start);
|
|
6289
|
+
const after = current.slice(end);
|
|
6290
|
+
const wrapped = `${prefix}${selected}${suffix}`;
|
|
6291
|
+
const newText = `${before}${wrapped}${after}`;
|
|
6292
|
+
const newStart = start + prefix.length;
|
|
6293
|
+
const newEnd = newStart + selected.length;
|
|
6294
|
+
pendingSelectionRef.current = { start: newStart, end: newEnd };
|
|
6295
|
+
commitText(newText);
|
|
6296
|
+
};
|
|
6297
|
+
const handleBold = () => wrapSelection("**", "**");
|
|
6298
|
+
const handleItalic = () => wrapSelection("*", "*");
|
|
6299
|
+
const handleLinkRequest = () => {
|
|
6300
|
+
if (selection.start === selection.end) return;
|
|
6301
|
+
setLinkPrompt(true);
|
|
6302
|
+
};
|
|
6303
|
+
const handleLinkSubmit = (url) => {
|
|
6304
|
+
const start = selection.start;
|
|
6305
|
+
const end = selection.end;
|
|
6306
|
+
if (start === end) {
|
|
6307
|
+
setLinkPrompt(false);
|
|
6308
|
+
return;
|
|
6309
|
+
}
|
|
6310
|
+
const current = textRef.current;
|
|
6311
|
+
const selected = current.slice(start, end);
|
|
6312
|
+
const before = current.slice(0, start);
|
|
6313
|
+
const after = current.slice(end);
|
|
6314
|
+
const wrapped = `[${selected}](${url})`;
|
|
6315
|
+
const newText = `${before}${wrapped}${after}`;
|
|
6316
|
+
const newStart = start + wrapped.length;
|
|
6317
|
+
pendingSelectionRef.current = { start: newStart, end: newStart };
|
|
6318
|
+
commitText(newText);
|
|
6319
|
+
setLinkPrompt(false);
|
|
6320
|
+
};
|
|
6321
|
+
const handleLinkCancel = () => {
|
|
6322
|
+
var _a;
|
|
6323
|
+
setLinkPrompt(false);
|
|
6324
|
+
(_a = textareaRef.current) == null ? void 0 : _a.focus();
|
|
6325
|
+
};
|
|
6326
|
+
const handleKeyDown = (e) => {
|
|
6327
|
+
if (!(e.metaKey || e.ctrlKey)) return;
|
|
6328
|
+
const key = e.key.toLowerCase();
|
|
6329
|
+
if (key === "b") {
|
|
6330
|
+
e.preventDefault();
|
|
6331
|
+
handleBold();
|
|
6332
|
+
} else if (key === "i") {
|
|
6333
|
+
e.preventDefault();
|
|
6334
|
+
handleItalic();
|
|
6335
|
+
} else if (key === "k") {
|
|
6336
|
+
e.preventDefault();
|
|
6337
|
+
handleLinkRequest();
|
|
6338
|
+
}
|
|
6339
|
+
};
|
|
6340
|
+
const toolbarVisible = isSelected && (selection.start !== selection.end || linkPrompt);
|
|
6341
|
+
return {
|
|
6342
|
+
textareaRef,
|
|
6343
|
+
selection,
|
|
6344
|
+
trackFocus,
|
|
6345
|
+
handleKeyDown,
|
|
6346
|
+
toolbarProps: {
|
|
6347
|
+
visible: toolbarVisible,
|
|
6348
|
+
linkPrompt,
|
|
6349
|
+
onBold: handleBold,
|
|
6350
|
+
onItalic: handleItalic,
|
|
6351
|
+
onLinkRequest: handleLinkRequest,
|
|
6352
|
+
onLinkSubmit: handleLinkSubmit,
|
|
6353
|
+
onLinkCancel: handleLinkCancel
|
|
6354
|
+
}
|
|
6355
|
+
};
|
|
6356
|
+
}
|
|
6357
|
+
function InlineFormattingToolbar({
|
|
6358
|
+
anchorEl,
|
|
6359
|
+
visible,
|
|
6360
|
+
linkPrompt,
|
|
6361
|
+
onBold,
|
|
6362
|
+
onItalic,
|
|
6363
|
+
onLinkRequest,
|
|
6364
|
+
onLinkSubmit,
|
|
6365
|
+
onLinkCancel
|
|
6366
|
+
}) {
|
|
6367
|
+
const [url, setUrl] = React58.useState("");
|
|
6368
|
+
const inputRef = React58.useRef(null);
|
|
6369
|
+
React58.useEffect(() => {
|
|
6370
|
+
if (linkPrompt) {
|
|
6371
|
+
setUrl("");
|
|
6372
|
+
setTimeout(() => {
|
|
6373
|
+
var _a;
|
|
6374
|
+
return (_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
6375
|
+
}, 0);
|
|
6376
|
+
}
|
|
6377
|
+
}, [linkPrompt]);
|
|
6378
|
+
const preventBlur = (e) => e.preventDefault();
|
|
6379
|
+
return /* @__PURE__ */ React58__default.default.createElement(material.Popper, { open: visible, anchorEl, placement: "top-start", style: { zIndex: 1300 } }, /* @__PURE__ */ React58__default.default.createElement(material.Paper, { elevation: 4, sx: { px: 0.5, py: 0.25, mb: 0.5 }, onMouseDown: preventBlur }, linkPrompt ? /* @__PURE__ */ React58__default.default.createElement(material.Stack, { direction: "row", alignItems: "center", spacing: 0.5, sx: { px: 0.5 } }, /* @__PURE__ */ React58__default.default.createElement(
|
|
6380
|
+
material.TextField,
|
|
6381
|
+
{
|
|
6382
|
+
inputRef,
|
|
6383
|
+
value: url,
|
|
6384
|
+
onChange: (e) => setUrl(e.target.value),
|
|
6385
|
+
placeholder: "https://example.com",
|
|
6386
|
+
variant: "standard",
|
|
6387
|
+
size: "small",
|
|
6388
|
+
onKeyDown: (e) => {
|
|
6389
|
+
if (e.key === "Enter") {
|
|
6390
|
+
e.preventDefault();
|
|
6391
|
+
const trimmed = url.trim();
|
|
6392
|
+
if (trimmed) onLinkSubmit(trimmed);
|
|
6393
|
+
else onLinkCancel();
|
|
6394
|
+
} else if (e.key === "Escape") {
|
|
6395
|
+
e.preventDefault();
|
|
6396
|
+
onLinkCancel();
|
|
6397
|
+
}
|
|
6398
|
+
},
|
|
6399
|
+
sx: { width: 220 }
|
|
6400
|
+
}
|
|
6401
|
+
)) : /* @__PURE__ */ React58__default.default.createElement(material.Stack, { direction: "row", spacing: 0.25 }, /* @__PURE__ */ React58__default.default.createElement(material.IconButton, { size: "small", onClick: onBold, title: "Bold (Cmd+B)", "aria-label": "Bold" }, /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.FormatBoldOutlined, { fontSize: "small" })), /* @__PURE__ */ React58__default.default.createElement(material.IconButton, { size: "small", onClick: onItalic, title: "Italic (Cmd+I)", "aria-label": "Italic" }, /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.FormatItalicOutlined, { fontSize: "small" })), /* @__PURE__ */ React58__default.default.createElement(material.IconButton, { size: "small", onClick: onLinkRequest, title: "Link (Cmd+K)", "aria-label": "Link" }, /* @__PURE__ */ React58__default.default.createElement(iconsMaterial.LinkOutlined, { fontSize: "small" })))));
|
|
6402
|
+
}
|
|
6403
|
+
|
|
6404
|
+
// src/editor/blocks/heading/heading-editor.tsx
|
|
6232
6405
|
function getFontFamily9(fontFamily) {
|
|
6233
6406
|
switch (fontFamily) {
|
|
6234
6407
|
case "MODERN_SANS":
|
|
@@ -6291,7 +6464,7 @@ function getFontSize2(level) {
|
|
|
6291
6464
|
}
|
|
6292
6465
|
}
|
|
6293
6466
|
function HeadingEditor({ style, props }) {
|
|
6294
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
6467
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
6295
6468
|
const blockId = useCurrentBlockId();
|
|
6296
6469
|
const selectedBlockId = useSelectedBlockId();
|
|
6297
6470
|
const document2 = useDocument();
|
|
@@ -6299,6 +6472,7 @@ function HeadingEditor({ style, props }) {
|
|
|
6299
6472
|
const level = (_a = props == null ? void 0 : props.level) != null ? _a : HeadingPropsDefaults.level;
|
|
6300
6473
|
const textContent = (_b = props == null ? void 0 : props.text) != null ? _b : HeadingPropsDefaults.text;
|
|
6301
6474
|
const [localText, setLocalText] = React58.useState(textContent);
|
|
6475
|
+
const isMarkdown = (_c = props == null ? void 0 : props.markdown) != null ? _c : false;
|
|
6302
6476
|
const rootBlock = document2.root;
|
|
6303
6477
|
const rootFontFamily = rootBlock && rootBlock.type === "EmailLayout" ? getFontFamily9(rootBlock.data.fontFamily) : '"Helvetica Neue", Arial, sans-serif';
|
|
6304
6478
|
React58.useEffect(() => {
|
|
@@ -6306,12 +6480,12 @@ function HeadingEditor({ style, props }) {
|
|
|
6306
6480
|
}, [textContent]);
|
|
6307
6481
|
const fontFamily = getFontFamily9(style == null ? void 0 : style.fontFamily) || rootFontFamily;
|
|
6308
6482
|
const hStyle = {
|
|
6309
|
-
color: (
|
|
6310
|
-
backgroundColor: (
|
|
6311
|
-
fontWeight: (
|
|
6312
|
-
lineHeight: (
|
|
6483
|
+
color: (_d = style == null ? void 0 : style.color) != null ? _d : void 0,
|
|
6484
|
+
backgroundColor: (_e = style == null ? void 0 : style.backgroundColor) != null ? _e : void 0,
|
|
6485
|
+
fontWeight: (_f = style == null ? void 0 : style.fontWeight) != null ? _f : "bold",
|
|
6486
|
+
lineHeight: (_g = style == null ? void 0 : style.lineHeight) != null ? _g : void 0,
|
|
6313
6487
|
letterSpacing: (style == null ? void 0 : style.letterSpacing) != null ? `${style.letterSpacing}px` : void 0,
|
|
6314
|
-
textAlign: (
|
|
6488
|
+
textAlign: (_h = style == null ? void 0 : style.textAlign) != null ? _h : void 0,
|
|
6315
6489
|
margin: 0,
|
|
6316
6490
|
fontFamily,
|
|
6317
6491
|
fontSize: getFontSize2(level),
|
|
@@ -6325,69 +6499,79 @@ function HeadingEditor({ style, props }) {
|
|
|
6325
6499
|
resize: "none",
|
|
6326
6500
|
backgroundColor: "transparent",
|
|
6327
6501
|
overflow: "hidden",
|
|
6328
|
-
lineHeight: (
|
|
6502
|
+
lineHeight: (_i = hStyle.lineHeight) != null ? _i : "inherit",
|
|
6329
6503
|
margin: 0,
|
|
6330
6504
|
display: "block",
|
|
6331
6505
|
width: "100%"
|
|
6332
6506
|
});
|
|
6333
|
-
const
|
|
6334
|
-
const newText = e.target.value;
|
|
6507
|
+
const commitText = (newText, opts) => {
|
|
6335
6508
|
setLocalText(newText);
|
|
6336
6509
|
setDocument({
|
|
6337
6510
|
[blockId]: {
|
|
6338
6511
|
type: "Heading",
|
|
6339
6512
|
data: {
|
|
6340
6513
|
style,
|
|
6341
|
-
props: __spreadProps(__spreadValues({}, props), {
|
|
6514
|
+
props: __spreadValues(__spreadProps(__spreadValues({}, props), {
|
|
6342
6515
|
text: newText
|
|
6343
|
-
})
|
|
6516
|
+
}), (opts == null ? void 0 : opts.enableMarkdown) ? { markdown: true } : {})
|
|
6344
6517
|
}
|
|
6345
6518
|
}
|
|
6346
6519
|
});
|
|
6347
6520
|
};
|
|
6521
|
+
const handleTextChange = (e) => {
|
|
6522
|
+
commitText(e.target.value);
|
|
6523
|
+
};
|
|
6348
6524
|
const adjustTextareaHeight = (element) => {
|
|
6349
6525
|
if (element) {
|
|
6350
6526
|
element.style.height = "auto";
|
|
6351
6527
|
element.style.height = `${element.scrollHeight}px`;
|
|
6352
6528
|
}
|
|
6353
6529
|
};
|
|
6354
|
-
const trackFocus = (
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6530
|
+
const { textareaRef, trackFocus, handleKeyDown, toolbarProps } = useMarkdownToolbar({
|
|
6531
|
+
text: localText,
|
|
6532
|
+
isSelected,
|
|
6533
|
+
commitText: (newText) => commitText(newText, { enableMarkdown: true }),
|
|
6534
|
+
trackSelection: (sel) => {
|
|
6535
|
+
setLastFocusedEditable({
|
|
6536
|
+
blockId,
|
|
6537
|
+
field: "text",
|
|
6538
|
+
selectionStart: sel.start,
|
|
6539
|
+
selectionEnd: sel.end
|
|
6540
|
+
});
|
|
6541
|
+
}
|
|
6542
|
+
});
|
|
6543
|
+
React58.useEffect(() => {
|
|
6544
|
+
if (textareaRef.current) adjustTextareaHeight(textareaRef.current);
|
|
6545
|
+
}, [localText, textareaRef]);
|
|
6364
6546
|
if (isSelected) {
|
|
6365
|
-
return /* @__PURE__ */ React58__default.default.createElement(
|
|
6547
|
+
return /* @__PURE__ */ React58__default.default.createElement(React58__default.default.Fragment, null, /* @__PURE__ */ React58__default.default.createElement(
|
|
6366
6548
|
"textarea",
|
|
6367
6549
|
{
|
|
6550
|
+
ref: textareaRef,
|
|
6368
6551
|
value: localText,
|
|
6369
6552
|
onChange: handleTextChange,
|
|
6370
6553
|
onFocus: trackFocus,
|
|
6371
6554
|
onSelect: trackFocus,
|
|
6372
6555
|
onKeyUp: trackFocus,
|
|
6556
|
+
onKeyDown: handleKeyDown,
|
|
6373
6557
|
onClick: (e) => {
|
|
6374
6558
|
e.stopPropagation();
|
|
6375
6559
|
trackFocus(e);
|
|
6376
6560
|
},
|
|
6377
6561
|
style: textareaStyle,
|
|
6378
6562
|
rows: 1,
|
|
6379
|
-
onInput: (e) => adjustTextareaHeight(e.target)
|
|
6380
|
-
ref: (el) => el && adjustTextareaHeight(el)
|
|
6563
|
+
onInput: (e) => adjustTextareaHeight(e.target)
|
|
6381
6564
|
}
|
|
6382
|
-
);
|
|
6565
|
+
), /* @__PURE__ */ React58__default.default.createElement(InlineFormattingToolbar, __spreadValues({ anchorEl: textareaRef.current }, toolbarProps)));
|
|
6383
6566
|
}
|
|
6567
|
+
const headingProps = isMarkdown ? { style: hStyle, dangerouslySetInnerHTML: { __html: renderInlineMarkdownString(textContent) } } : { style: hStyle, children: textContent };
|
|
6384
6568
|
switch (level) {
|
|
6385
6569
|
case "h1":
|
|
6386
|
-
return /* @__PURE__ */ React58__default.default.createElement("h1", {
|
|
6570
|
+
return /* @__PURE__ */ React58__default.default.createElement("h1", __spreadValues({}, headingProps));
|
|
6387
6571
|
case "h2":
|
|
6388
|
-
return /* @__PURE__ */ React58__default.default.createElement("h2", {
|
|
6572
|
+
return /* @__PURE__ */ React58__default.default.createElement("h2", __spreadValues({}, headingProps));
|
|
6389
6573
|
case "h3":
|
|
6390
|
-
return /* @__PURE__ */ React58__default.default.createElement("h3", {
|
|
6574
|
+
return /* @__PURE__ */ React58__default.default.createElement("h3", __spreadValues({}, headingProps));
|
|
6391
6575
|
}
|
|
6392
6576
|
}
|
|
6393
6577
|
function HtmlEditor({ style, props }) {
|
|
@@ -6795,56 +6979,65 @@ function TextEditor({ style, props }) {
|
|
|
6795
6979
|
fontWeight: wStyle.fontWeight,
|
|
6796
6980
|
textAlign: wStyle.textAlign
|
|
6797
6981
|
});
|
|
6798
|
-
const
|
|
6799
|
-
const newText = e.target.value;
|
|
6982
|
+
const commitText = (newText, opts) => {
|
|
6800
6983
|
setLocalText(newText);
|
|
6801
6984
|
setDocument({
|
|
6802
6985
|
[blockId]: {
|
|
6803
6986
|
type: "Text",
|
|
6804
6987
|
data: {
|
|
6805
6988
|
style,
|
|
6806
|
-
props: __spreadProps(__spreadValues({}, props), {
|
|
6989
|
+
props: __spreadValues(__spreadProps(__spreadValues({}, props), {
|
|
6807
6990
|
text: newText
|
|
6808
|
-
})
|
|
6991
|
+
}), (opts == null ? void 0 : opts.enableMarkdown) ? { markdown: true } : {})
|
|
6809
6992
|
}
|
|
6810
6993
|
}
|
|
6811
6994
|
});
|
|
6812
6995
|
};
|
|
6996
|
+
const handleTextChange = (e) => {
|
|
6997
|
+
commitText(e.target.value);
|
|
6998
|
+
};
|
|
6813
6999
|
const adjustTextareaHeight = (element) => {
|
|
6814
7000
|
if (element) {
|
|
6815
7001
|
element.style.height = "auto";
|
|
6816
7002
|
element.style.height = `${element.scrollHeight}px`;
|
|
6817
7003
|
}
|
|
6818
7004
|
};
|
|
6819
|
-
const trackFocus = (
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
7005
|
+
const { textareaRef, trackFocus, handleKeyDown, toolbarProps } = useMarkdownToolbar({
|
|
7006
|
+
text: localText,
|
|
7007
|
+
isSelected,
|
|
7008
|
+
commitText: (newText) => commitText(newText, { enableMarkdown: true }),
|
|
7009
|
+
trackSelection: (sel) => {
|
|
7010
|
+
setLastFocusedEditable({
|
|
7011
|
+
blockId,
|
|
7012
|
+
field: "text",
|
|
7013
|
+
selectionStart: sel.start,
|
|
7014
|
+
selectionEnd: sel.end
|
|
7015
|
+
});
|
|
7016
|
+
}
|
|
7017
|
+
});
|
|
7018
|
+
React58.useEffect(() => {
|
|
7019
|
+
if (textareaRef.current) adjustTextareaHeight(textareaRef.current);
|
|
7020
|
+
}, [localText, textareaRef]);
|
|
6829
7021
|
if (isSelected) {
|
|
6830
|
-
return /* @__PURE__ */ React58__default.default.createElement(
|
|
7022
|
+
return /* @__PURE__ */ React58__default.default.createElement(React58__default.default.Fragment, null, /* @__PURE__ */ React58__default.default.createElement(
|
|
6831
7023
|
"textarea",
|
|
6832
7024
|
{
|
|
7025
|
+
ref: textareaRef,
|
|
6833
7026
|
value: localText,
|
|
6834
7027
|
onChange: handleTextChange,
|
|
6835
7028
|
onFocus: trackFocus,
|
|
6836
7029
|
onSelect: trackFocus,
|
|
6837
7030
|
onKeyUp: trackFocus,
|
|
7031
|
+
onKeyDown: handleKeyDown,
|
|
6838
7032
|
onClick: (e) => {
|
|
6839
7033
|
e.stopPropagation();
|
|
6840
7034
|
trackFocus(e);
|
|
6841
7035
|
},
|
|
6842
7036
|
style: textareaStyle,
|
|
6843
7037
|
rows: 1,
|
|
6844
|
-
onInput: (e) => adjustTextareaHeight(e.target)
|
|
6845
|
-
ref: (el) => el && adjustTextareaHeight(el)
|
|
7038
|
+
onInput: (e) => adjustTextareaHeight(e.target)
|
|
6846
7039
|
}
|
|
6847
|
-
);
|
|
7040
|
+
), /* @__PURE__ */ React58__default.default.createElement(InlineFormattingToolbar, __spreadValues({ anchorEl: textareaRef.current }, toolbarProps)));
|
|
6848
7041
|
}
|
|
6849
7042
|
if (isMarkdown) {
|
|
6850
7043
|
return /* @__PURE__ */ React58__default.default.createElement(EmailMarkdown, { style: wStyle, markdown: textContent });
|