@kontakto/email-template-editor 2.2.0 → 2.2.2
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 +51 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import DOMPurify from 'dompurify';
|
|
2
2
|
import { marked, Renderer } from 'marked';
|
|
3
|
-
import React58, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, useContext, useState, useCallback, Fragment } from 'react';
|
|
3
|
+
import React58, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, useContext, useState, useCallback, useLayoutEffect, Fragment } from 'react';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { renderToStaticMarkup as renderToStaticMarkup$1 } from 'react-dom/server';
|
|
6
6
|
import { createTheme, alpha, lighten, darken } from '@mui/material/styles';
|
|
@@ -141,6 +141,13 @@ ${body}</tbody>
|
|
|
141
141
|
}
|
|
142
142
|
return `<a href="${href}" title="${title}" target="_blank">${text}</a>`;
|
|
143
143
|
}
|
|
144
|
+
// Give paragraphs an explicit bottom margin that matches a blank line in the
|
|
145
|
+
// raw source. Without this, click-to-edit swaps the rendered div (flattened
|
|
146
|
+
// by ambient CSS) for a textarea whose blank lines take a full line-height,
|
|
147
|
+
// causing a visible layout jump.
|
|
148
|
+
paragraph(text) {
|
|
149
|
+
return `<p style="margin:0 0 1em 0">${text}</p>`;
|
|
150
|
+
}
|
|
144
151
|
};
|
|
145
152
|
function renderMarkdownString(str) {
|
|
146
153
|
const html2 = marked.parse(str, {
|
|
@@ -6511,11 +6518,20 @@ function HeadingEditor({ style, props }) {
|
|
|
6511
6518
|
const handleTextChange = (e) => {
|
|
6512
6519
|
commitText(e.target.value);
|
|
6513
6520
|
};
|
|
6521
|
+
const displayRef = useRef(null);
|
|
6522
|
+
const lastDisplayHeightRef = useRef(0);
|
|
6523
|
+
useLayoutEffect(() => {
|
|
6524
|
+
if (!isSelected && displayRef.current) {
|
|
6525
|
+
const h = displayRef.current.offsetHeight;
|
|
6526
|
+
if (h > 0) lastDisplayHeightRef.current = h;
|
|
6527
|
+
}
|
|
6528
|
+
}, [isSelected, textContent, isMarkdown, level]);
|
|
6514
6529
|
const adjustTextareaHeight = (element) => {
|
|
6515
|
-
if (element)
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6530
|
+
if (!element) return;
|
|
6531
|
+
element.style.height = "auto";
|
|
6532
|
+
const scrollH = element.scrollHeight;
|
|
6533
|
+
const floor = lastDisplayHeightRef.current;
|
|
6534
|
+
element.style.height = `${Math.max(scrollH, floor)}px`;
|
|
6519
6535
|
};
|
|
6520
6536
|
const { textareaRef, trackFocus, handleKeyDown, toolbarProps } = useMarkdownToolbar({
|
|
6521
6537
|
text: localText,
|
|
@@ -6530,9 +6546,9 @@ function HeadingEditor({ style, props }) {
|
|
|
6530
6546
|
});
|
|
6531
6547
|
}
|
|
6532
6548
|
});
|
|
6533
|
-
|
|
6549
|
+
useLayoutEffect(() => {
|
|
6534
6550
|
if (textareaRef.current) adjustTextareaHeight(textareaRef.current);
|
|
6535
|
-
}, [localText,
|
|
6551
|
+
}, [localText, isSelected]);
|
|
6536
6552
|
if (isSelected) {
|
|
6537
6553
|
return /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(
|
|
6538
6554
|
"textarea",
|
|
@@ -6554,7 +6570,11 @@ function HeadingEditor({ style, props }) {
|
|
|
6554
6570
|
}
|
|
6555
6571
|
), /* @__PURE__ */ React58.createElement(InlineFormattingToolbar, __spreadValues({ anchorEl: textareaRef.current }, toolbarProps)));
|
|
6556
6572
|
}
|
|
6557
|
-
const headingProps = isMarkdown ? {
|
|
6573
|
+
const headingProps = isMarkdown ? {
|
|
6574
|
+
ref: displayRef,
|
|
6575
|
+
style: hStyle,
|
|
6576
|
+
dangerouslySetInnerHTML: { __html: renderInlineMarkdownString(textContent) }
|
|
6577
|
+
} : { ref: displayRef, style: hStyle, children: textContent };
|
|
6558
6578
|
switch (level) {
|
|
6559
6579
|
case "h1":
|
|
6560
6580
|
return /* @__PURE__ */ React58.createElement("h1", __spreadValues({}, headingProps));
|
|
@@ -6986,11 +7006,20 @@ function TextEditor({ style, props }) {
|
|
|
6986
7006
|
const handleTextChange = (e) => {
|
|
6987
7007
|
commitText(e.target.value);
|
|
6988
7008
|
};
|
|
7009
|
+
const displayRef = useRef(null);
|
|
7010
|
+
const lastDisplayHeightRef = useRef(0);
|
|
7011
|
+
useLayoutEffect(() => {
|
|
7012
|
+
if (!isSelected && displayRef.current) {
|
|
7013
|
+
const h = displayRef.current.offsetHeight;
|
|
7014
|
+
if (h > 0) lastDisplayHeightRef.current = h;
|
|
7015
|
+
}
|
|
7016
|
+
}, [isSelected, textContent, isMarkdown]);
|
|
6989
7017
|
const adjustTextareaHeight = (element) => {
|
|
6990
|
-
if (element)
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
7018
|
+
if (!element) return;
|
|
7019
|
+
element.style.height = "auto";
|
|
7020
|
+
const scrollH = element.scrollHeight;
|
|
7021
|
+
const floor = lastDisplayHeightRef.current;
|
|
7022
|
+
element.style.height = `${Math.max(scrollH, floor)}px`;
|
|
6994
7023
|
};
|
|
6995
7024
|
const { textareaRef, trackFocus, handleKeyDown, toolbarProps } = useMarkdownToolbar({
|
|
6996
7025
|
text: localText,
|
|
@@ -7005,9 +7034,9 @@ function TextEditor({ style, props }) {
|
|
|
7005
7034
|
});
|
|
7006
7035
|
}
|
|
7007
7036
|
});
|
|
7008
|
-
|
|
7037
|
+
useLayoutEffect(() => {
|
|
7009
7038
|
if (textareaRef.current) adjustTextareaHeight(textareaRef.current);
|
|
7010
|
-
}, [localText,
|
|
7039
|
+
}, [localText, isSelected]);
|
|
7011
7040
|
if (isSelected) {
|
|
7012
7041
|
return /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(
|
|
7013
7042
|
"textarea",
|
|
@@ -7030,9 +7059,16 @@ function TextEditor({ style, props }) {
|
|
|
7030
7059
|
), /* @__PURE__ */ React58.createElement(InlineFormattingToolbar, __spreadValues({ anchorEl: textareaRef.current }, toolbarProps)));
|
|
7031
7060
|
}
|
|
7032
7061
|
if (isMarkdown) {
|
|
7033
|
-
return /* @__PURE__ */ React58.createElement(
|
|
7062
|
+
return /* @__PURE__ */ React58.createElement(
|
|
7063
|
+
"div",
|
|
7064
|
+
{
|
|
7065
|
+
ref: displayRef,
|
|
7066
|
+
style: wStyle,
|
|
7067
|
+
dangerouslySetInnerHTML: { __html: renderMarkdownString(textContent) }
|
|
7068
|
+
}
|
|
7069
|
+
);
|
|
7034
7070
|
}
|
|
7035
|
-
return /* @__PURE__ */ React58.createElement("div", { style: wStyle }, textContent);
|
|
7071
|
+
return /* @__PURE__ */ React58.createElement("div", { ref: displayRef, style: wStyle }, textContent);
|
|
7036
7072
|
}
|
|
7037
7073
|
|
|
7038
7074
|
// src/editor/core.tsx
|