@tarviks/lexical-rich-editor 1.3.11 → 1.3.13
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.js +94 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2230,6 +2230,48 @@ function $createYouTubeNode(videoID, width = DEFAULT_WIDTH, height = DEFAULT_HEI
|
|
|
2230
2230
|
function $isYouTubeNode(node) {
|
|
2231
2231
|
return node instanceof YouTubeNode;
|
|
2232
2232
|
}
|
|
2233
|
+
var PRESERVED_STYLE_PROPS = [
|
|
2234
|
+
["fontFamily", "font-family"],
|
|
2235
|
+
["fontSize", "font-size"],
|
|
2236
|
+
["color", "color"],
|
|
2237
|
+
["backgroundColor", "background-color"]
|
|
2238
|
+
];
|
|
2239
|
+
var $convertSpanElementWithStyle = (domNode) => {
|
|
2240
|
+
const style = domNode.style;
|
|
2241
|
+
const cssParts = [];
|
|
2242
|
+
for (const [domProp, cssProp] of PRESERVED_STYLE_PROPS) {
|
|
2243
|
+
const value = style[domProp];
|
|
2244
|
+
if (value) cssParts.push(`${cssProp}: ${value}`);
|
|
2245
|
+
}
|
|
2246
|
+
const cssText = cssParts.length > 0 ? `${cssParts.join("; ")};` : "";
|
|
2247
|
+
const fontWeight = style.fontWeight;
|
|
2248
|
+
const textDecoration = style.textDecoration.split(" ");
|
|
2249
|
+
const hasBoldFontWeight = fontWeight === "700" || fontWeight === "bold";
|
|
2250
|
+
const hasLinethroughTextDecoration = textDecoration.includes("line-through");
|
|
2251
|
+
const hasItalicFontStyle = style.fontStyle === "italic";
|
|
2252
|
+
const hasUnderlineTextDecoration = textDecoration.includes("underline");
|
|
2253
|
+
const verticalAlign = style.verticalAlign;
|
|
2254
|
+
return {
|
|
2255
|
+
node: null,
|
|
2256
|
+
forChild: (lexicalNode) => {
|
|
2257
|
+
if (!lexical.$isTextNode(lexicalNode)) return lexicalNode;
|
|
2258
|
+
if (cssText) lexicalNode.setStyle(cssText);
|
|
2259
|
+
if (hasBoldFontWeight && !lexicalNode.hasFormat("bold")) lexicalNode.toggleFormat("bold");
|
|
2260
|
+
if (hasLinethroughTextDecoration && !lexicalNode.hasFormat("strikethrough")) lexicalNode.toggleFormat("strikethrough");
|
|
2261
|
+
if (hasItalicFontStyle && !lexicalNode.hasFormat("italic")) lexicalNode.toggleFormat("italic");
|
|
2262
|
+
if (hasUnderlineTextDecoration && !lexicalNode.hasFormat("underline")) lexicalNode.toggleFormat("underline");
|
|
2263
|
+
if (verticalAlign === "sub" && !lexicalNode.hasFormat("subscript")) lexicalNode.toggleFormat("subscript");
|
|
2264
|
+
if (verticalAlign === "super" && !lexicalNode.hasFormat("superscript")) lexicalNode.toggleFormat("superscript");
|
|
2265
|
+
return lexicalNode;
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
2268
|
+
};
|
|
2269
|
+
var preserveTextStyleImportMap = {
|
|
2270
|
+
span: () => ({
|
|
2271
|
+
conversion: $convertSpanElementWithStyle,
|
|
2272
|
+
priority: 0
|
|
2273
|
+
})
|
|
2274
|
+
};
|
|
2233
2275
|
var normalize = (s) => (s ?? "").replace(/\s+/g, " ").trim();
|
|
2234
2276
|
function readContextWindow(maxChars = 300, cursorIndex) {
|
|
2235
2277
|
const full = normalize(lexical.$getRoot().getTextContent());
|
|
@@ -3177,12 +3219,16 @@ function splitHeadingsAtBrSequences(html) {
|
|
|
3177
3219
|
});
|
|
3178
3220
|
return doc.body.innerHTML;
|
|
3179
3221
|
}
|
|
3180
|
-
var CustomOnChangePlugin = ({ value, onChange }) => {
|
|
3222
|
+
var CustomOnChangePlugin = ({ value, onChange, isReadOnly }) => {
|
|
3181
3223
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
3182
3224
|
const initializedRef = React9.useRef(false);
|
|
3225
|
+
const lastImportedValueRef = React9.useRef(null);
|
|
3183
3226
|
React9.useEffect(() => {
|
|
3184
|
-
if (!value
|
|
3227
|
+
if (!value) return;
|
|
3228
|
+
if (!isReadOnly && initializedRef.current) return;
|
|
3229
|
+
if (value === lastImportedValueRef.current) return;
|
|
3185
3230
|
initializedRef.current = true;
|
|
3231
|
+
lastImportedValueRef.current = value;
|
|
3186
3232
|
editor.update(() => {
|
|
3187
3233
|
const root = lexical.$getRoot();
|
|
3188
3234
|
root.clear();
|
|
@@ -3193,14 +3239,17 @@ var CustomOnChangePlugin = ({ value, onChange }) => {
|
|
|
3193
3239
|
const nodes = html.$generateNodesFromDOM(editor, dom);
|
|
3194
3240
|
root.append(...nodes);
|
|
3195
3241
|
});
|
|
3196
|
-
}, [editor, value]);
|
|
3242
|
+
}, [editor, value, isReadOnly]);
|
|
3197
3243
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3198
3244
|
LexicalOnChangePlugin.OnChangePlugin,
|
|
3199
3245
|
{
|
|
3246
|
+
ignoreSelectionChange: true,
|
|
3200
3247
|
onChange: (editorState) => {
|
|
3201
3248
|
editorState.read(() => {
|
|
3202
3249
|
const raw = html.$generateHtmlFromNodes(editor);
|
|
3203
|
-
|
|
3250
|
+
const html$1 = postProcessOutput(splitHeadingsAtBrSequences(raw));
|
|
3251
|
+
lastImportedValueRef.current = html$1;
|
|
3252
|
+
onChange(html$1);
|
|
3204
3253
|
});
|
|
3205
3254
|
}
|
|
3206
3255
|
}
|
|
@@ -5170,16 +5219,18 @@ function getScrollClipAncestor(el) {
|
|
|
5170
5219
|
}
|
|
5171
5220
|
return null;
|
|
5172
5221
|
}
|
|
5222
|
+
var BUTTON_VERTICAL_FOOTPRINT = 34;
|
|
5173
5223
|
function isRectVisible(rect, cellDom) {
|
|
5174
5224
|
if (rect.width === 0 && rect.height === 0) return false;
|
|
5175
|
-
if (rect.bottom <= 0 || rect.top >= window.innerHeight) return false;
|
|
5176
|
-
if (rect.right <= 0 || rect.left >= window.innerWidth) return false;
|
|
5177
5225
|
const clipAncestor = getScrollClipAncestor(cellDom);
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5226
|
+
const containerRect = clipAncestor?.getBoundingClientRect();
|
|
5227
|
+
const visibleTop = containerRect ? Math.max(0, containerRect.top) : 0;
|
|
5228
|
+
const visibleBottom = containerRect ? Math.min(window.innerHeight, containerRect.bottom) : window.innerHeight;
|
|
5229
|
+
const visibleLeft = containerRect ? Math.max(0, containerRect.left) : 0;
|
|
5230
|
+
const visibleRight = containerRect ? Math.min(window.innerWidth, containerRect.right) : window.innerWidth;
|
|
5231
|
+
if (rect.top < visibleTop) return false;
|
|
5232
|
+
if (rect.top + BUTTON_VERTICAL_FOOTPRINT > visibleBottom) return false;
|
|
5233
|
+
if (rect.left >= visibleRight || rect.right <= visibleLeft) return false;
|
|
5183
5234
|
return true;
|
|
5184
5235
|
}
|
|
5185
5236
|
function TableActionMenuPlugin({ disabled = false }) {
|
|
@@ -5331,9 +5382,25 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
5331
5382
|
const canShow = isInTable && !!anchorRect && isAnchorVisible && !disabled;
|
|
5332
5383
|
const handleStyle = React9__namespace.useMemo(() => {
|
|
5333
5384
|
if (!anchorRect) return void 0;
|
|
5334
|
-
const
|
|
5335
|
-
const
|
|
5336
|
-
const
|
|
5385
|
+
const BUTTON_SIZE = 28;
|
|
5386
|
+
const PAD = 8;
|
|
5387
|
+
const editorRect = editor.getRootElement()?.getBoundingClientRect();
|
|
5388
|
+
const clipRect = editorRect ? {
|
|
5389
|
+
top: Math.max(editorRect.top, 0),
|
|
5390
|
+
left: Math.max(editorRect.left, 0),
|
|
5391
|
+
right: Math.min(editorRect.right, window.innerWidth),
|
|
5392
|
+
bottom: Math.min(editorRect.bottom, window.innerHeight)
|
|
5393
|
+
} : { top: 0, left: 0, right: window.innerWidth, bottom: window.innerHeight };
|
|
5394
|
+
const isCellVisible = anchorRect.bottom > clipRect.top && anchorRect.top < clipRect.bottom && anchorRect.right > clipRect.left && anchorRect.left < clipRect.right;
|
|
5395
|
+
if (!isCellVisible) return void 0;
|
|
5396
|
+
const minTop = editorRect ? editorRect.top + PAD : PAD;
|
|
5397
|
+
const maxTop = editorRect ? Math.max(minTop, editorRect.bottom - BUTTON_SIZE - PAD) : window.innerHeight - BUTTON_SIZE - PAD;
|
|
5398
|
+
const minLeft = editorRect ? editorRect.left + PAD : PAD;
|
|
5399
|
+
const maxLeft = editorRect ? Math.max(minLeft, editorRect.right - BUTTON_SIZE - PAD) : window.innerWidth - BUTTON_SIZE - PAD;
|
|
5400
|
+
const top = Math.min(Math.max(anchorRect.top + 6, minTop), maxTop);
|
|
5401
|
+
const clampedCellRight = Math.min(anchorRect.right, maxLeft + BUTTON_SIZE);
|
|
5402
|
+
const rawLeft = contentRight !== null ? Math.max(anchorRect.left + 4, Math.min(contentRight + 4, clampedCellRight - 32)) : anchorRect.left + 8;
|
|
5403
|
+
const left = Math.min(Math.max(rawLeft, minLeft), maxLeft);
|
|
5337
5404
|
return {
|
|
5338
5405
|
position: "fixed",
|
|
5339
5406
|
top,
|
|
@@ -5343,7 +5410,7 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
5343
5410
|
// button renders behind the modal chrome in a full-page/Panel view.
|
|
5344
5411
|
zIndex: 10000010
|
|
5345
5412
|
};
|
|
5346
|
-
}, [anchorRect, contentRight]);
|
|
5413
|
+
}, [anchorRect, contentRight, editor]);
|
|
5347
5414
|
const dangerStyle = {
|
|
5348
5415
|
color: "var(--colorPaletteRedForeground1)"
|
|
5349
5416
|
};
|
|
@@ -8287,7 +8354,10 @@ var ContentEditorComponent = React9.forwardRef(
|
|
|
8287
8354
|
AutocompleteNode,
|
|
8288
8355
|
SpellErrorNode,
|
|
8289
8356
|
HtmlBlockNode
|
|
8290
|
-
]
|
|
8357
|
+
],
|
|
8358
|
+
html: {
|
|
8359
|
+
import: preserveTextStyleImportMap
|
|
8360
|
+
}
|
|
8291
8361
|
};
|
|
8292
8362
|
props.onBeforeInitialize?.(config);
|
|
8293
8363
|
return config;
|
|
@@ -8615,7 +8685,14 @@ var ContentEditorComponent = React9.forwardRef(
|
|
|
8615
8685
|
}
|
|
8616
8686
|
),
|
|
8617
8687
|
!isReadOnly && props.showFloatingToolbar && /* @__PURE__ */ jsxRuntime.jsx(CharacterStylesPopupPlugin, {}),
|
|
8618
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8688
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8689
|
+
CustomOnChangePlugin,
|
|
8690
|
+
{
|
|
8691
|
+
value: props.value,
|
|
8692
|
+
onChange: props.onChange,
|
|
8693
|
+
isReadOnly
|
|
8694
|
+
}
|
|
8695
|
+
),
|
|
8619
8696
|
(props.wordLimit !== void 0 || props.required || props.minWords !== void 0 || props.maxWords !== void 0 || props.minChars !== void 0 || props.maxChars !== void 0 || props.noImages || props.maxImages !== void 0 || props.noLinks || props.maxLinks !== void 0 || props.noTables) && /* @__PURE__ */ jsxRuntime.jsx(ContentMetricsPlugin, { onMetricsChange: handleMetrics }),
|
|
8620
8697
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8621
8698
|
RefApiPlugin,
|