@tarviks/lexical-rich-editor 1.0.4 → 1.0.6
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 +3 -3
- package/dist/index.css +23 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +55 -8
- package/dist/index.d.ts +55 -8
- package/dist/index.js +615 -316
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +617 -318
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var useLexicalNodeSelection = require('@lexical/react/useLexicalNodeSelection');
|
|
|
9
9
|
var lexical = require('lexical');
|
|
10
10
|
var react = require('@fluentui/react');
|
|
11
11
|
var reactComponents = require('@fluentui/react-components');
|
|
12
|
+
var reactIcons = require('@fluentui/react-icons');
|
|
12
13
|
var code = require('@lexical/code');
|
|
13
14
|
var link = require('@lexical/link');
|
|
14
15
|
var list = require('@lexical/list');
|
|
@@ -26,7 +27,6 @@ var richText = require('@lexical/rich-text');
|
|
|
26
27
|
var table = require('@lexical/table');
|
|
27
28
|
var LexicalBlockWithAlignableContents = require('@lexical/react/LexicalBlockWithAlignableContents');
|
|
28
29
|
var LexicalDecoratorBlockNode = require('@lexical/react/LexicalDecoratorBlockNode');
|
|
29
|
-
var reactIcons = require('@fluentui/react-icons');
|
|
30
30
|
var selection = require('@lexical/selection');
|
|
31
31
|
var reactDom = require('react-dom');
|
|
32
32
|
var html = require('@lexical/html');
|
|
@@ -243,80 +243,107 @@ var init_ImageResizer = __esm({
|
|
|
243
243
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
244
244
|
}
|
|
245
245
|
};
|
|
246
|
-
return
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
onPointerDown: (event) => {
|
|
252
|
-
handlePointerDown(event, Direction.north);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
),
|
|
256
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
257
|
-
"div",
|
|
258
|
-
{
|
|
259
|
-
className: "image-resizer image-resizer-ne",
|
|
260
|
-
onPointerDown: (event) => {
|
|
261
|
-
handlePointerDown(event, Direction.north | Direction.east);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
),
|
|
265
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
266
|
-
"div",
|
|
267
|
-
{
|
|
268
|
-
className: "image-resizer image-resizer-e",
|
|
269
|
-
onPointerDown: (event) => {
|
|
270
|
-
handlePointerDown(event, Direction.east);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
),
|
|
274
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
275
|
-
"div",
|
|
276
|
-
{
|
|
277
|
-
className: "image-resizer image-resizer-se",
|
|
278
|
-
onPointerDown: (event) => {
|
|
279
|
-
handlePointerDown(event, Direction.south | Direction.east);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
),
|
|
283
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
284
|
-
"div",
|
|
285
|
-
{
|
|
286
|
-
className: "image-resizer image-resizer-s",
|
|
287
|
-
onPointerDown: (event) => {
|
|
288
|
-
handlePointerDown(event, Direction.south);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
),
|
|
292
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
293
|
-
"div",
|
|
294
|
-
{
|
|
295
|
-
className: "image-resizer image-resizer-sw",
|
|
296
|
-
onPointerDown: (event) => {
|
|
297
|
-
handlePointerDown(event, Direction.south | Direction.west);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
),
|
|
301
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
302
|
-
"div",
|
|
303
|
-
{
|
|
304
|
-
className: "image-resizer image-resizer-w",
|
|
305
|
-
onPointerDown: (event) => {
|
|
306
|
-
handlePointerDown(event, Direction.west);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
),
|
|
310
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
246
|
+
return (
|
|
247
|
+
// Overlay that exactly covers the image container (position:relative parent).
|
|
248
|
+
// pointer-events:none lets clicks pass through to the image; each handle
|
|
249
|
+
// re-enables pointer-events so drag-resize still works.
|
|
250
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
311
251
|
"div",
|
|
312
252
|
{
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
253
|
+
ref: controlWrapperRef,
|
|
254
|
+
style: {
|
|
255
|
+
position: "absolute",
|
|
256
|
+
top: 0,
|
|
257
|
+
right: 0,
|
|
258
|
+
bottom: 0,
|
|
259
|
+
left: 0,
|
|
260
|
+
pointerEvents: "none"
|
|
261
|
+
},
|
|
262
|
+
children: [
|
|
263
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
264
|
+
"div",
|
|
265
|
+
{
|
|
266
|
+
className: "image-resizer image-resizer-n",
|
|
267
|
+
style: { pointerEvents: "auto" },
|
|
268
|
+
onPointerDown: (event) => {
|
|
269
|
+
handlePointerDown(event, Direction.north);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
),
|
|
273
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
274
|
+
"div",
|
|
275
|
+
{
|
|
276
|
+
className: "image-resizer image-resizer-ne",
|
|
277
|
+
style: { pointerEvents: "auto" },
|
|
278
|
+
onPointerDown: (event) => {
|
|
279
|
+
handlePointerDown(event, Direction.north | Direction.east);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
),
|
|
283
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
284
|
+
"div",
|
|
285
|
+
{
|
|
286
|
+
className: "image-resizer image-resizer-e",
|
|
287
|
+
style: { pointerEvents: "auto" },
|
|
288
|
+
onPointerDown: (event) => {
|
|
289
|
+
handlePointerDown(event, Direction.east);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
),
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
294
|
+
"div",
|
|
295
|
+
{
|
|
296
|
+
className: "image-resizer image-resizer-se",
|
|
297
|
+
style: { pointerEvents: "auto" },
|
|
298
|
+
onPointerDown: (event) => {
|
|
299
|
+
handlePointerDown(event, Direction.south | Direction.east);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
),
|
|
303
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
304
|
+
"div",
|
|
305
|
+
{
|
|
306
|
+
className: "image-resizer image-resizer-s",
|
|
307
|
+
style: { pointerEvents: "auto" },
|
|
308
|
+
onPointerDown: (event) => {
|
|
309
|
+
handlePointerDown(event, Direction.south);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
),
|
|
313
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
314
|
+
"div",
|
|
315
|
+
{
|
|
316
|
+
className: "image-resizer image-resizer-sw",
|
|
317
|
+
style: { pointerEvents: "auto" },
|
|
318
|
+
onPointerDown: (event) => {
|
|
319
|
+
handlePointerDown(event, Direction.south | Direction.west);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
),
|
|
323
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
324
|
+
"div",
|
|
325
|
+
{
|
|
326
|
+
className: "image-resizer image-resizer-w",
|
|
327
|
+
style: { pointerEvents: "auto" },
|
|
328
|
+
onPointerDown: (event) => {
|
|
329
|
+
handlePointerDown(event, Direction.west);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
),
|
|
333
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
334
|
+
"div",
|
|
335
|
+
{
|
|
336
|
+
className: "image-resizer image-resizer-nw",
|
|
337
|
+
style: { pointerEvents: "auto" },
|
|
338
|
+
onPointerDown: (event) => {
|
|
339
|
+
handlePointerDown(event, Direction.north | Direction.west);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
]
|
|
317
344
|
}
|
|
318
345
|
)
|
|
319
|
-
|
|
346
|
+
);
|
|
320
347
|
};
|
|
321
348
|
ImageResizer_default = ImageResizer;
|
|
322
349
|
}
|
|
@@ -3567,6 +3594,204 @@ function PageBreakPlugin() {
|
|
|
3567
3594
|
}, [editor]);
|
|
3568
3595
|
return null;
|
|
3569
3596
|
}
|
|
3597
|
+
|
|
3598
|
+
// src/Utils/Sanitize.ts
|
|
3599
|
+
var DROP_ENTIRELY = /* @__PURE__ */ new Set([
|
|
3600
|
+
"script",
|
|
3601
|
+
"noscript",
|
|
3602
|
+
"style",
|
|
3603
|
+
"object",
|
|
3604
|
+
"embed",
|
|
3605
|
+
"form",
|
|
3606
|
+
"input",
|
|
3607
|
+
"button",
|
|
3608
|
+
"select",
|
|
3609
|
+
"textarea",
|
|
3610
|
+
"meta",
|
|
3611
|
+
"link",
|
|
3612
|
+
"base"
|
|
3613
|
+
]);
|
|
3614
|
+
var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
3615
|
+
// Block
|
|
3616
|
+
"p",
|
|
3617
|
+
"h1",
|
|
3618
|
+
"h2",
|
|
3619
|
+
"h3",
|
|
3620
|
+
"h4",
|
|
3621
|
+
"h5",
|
|
3622
|
+
"h6",
|
|
3623
|
+
"ul",
|
|
3624
|
+
"ol",
|
|
3625
|
+
"li",
|
|
3626
|
+
"blockquote",
|
|
3627
|
+
"pre",
|
|
3628
|
+
"div",
|
|
3629
|
+
"table",
|
|
3630
|
+
"thead",
|
|
3631
|
+
"tbody",
|
|
3632
|
+
"tfoot",
|
|
3633
|
+
"tr",
|
|
3634
|
+
"td",
|
|
3635
|
+
"th",
|
|
3636
|
+
// Inline
|
|
3637
|
+
"span",
|
|
3638
|
+
"a",
|
|
3639
|
+
"strong",
|
|
3640
|
+
"b",
|
|
3641
|
+
"em",
|
|
3642
|
+
"i",
|
|
3643
|
+
"u",
|
|
3644
|
+
"s",
|
|
3645
|
+
"del",
|
|
3646
|
+
"strike",
|
|
3647
|
+
"sub",
|
|
3648
|
+
"sup",
|
|
3649
|
+
"mark",
|
|
3650
|
+
"code",
|
|
3651
|
+
"br",
|
|
3652
|
+
"hr",
|
|
3653
|
+
// Media / embeds
|
|
3654
|
+
"img",
|
|
3655
|
+
"iframe"
|
|
3656
|
+
]);
|
|
3657
|
+
var ALLOWED_ATTRS = /* @__PURE__ */ new Set([
|
|
3658
|
+
// Presentation
|
|
3659
|
+
"class",
|
|
3660
|
+
"style",
|
|
3661
|
+
"dir",
|
|
3662
|
+
"lang",
|
|
3663
|
+
// Anchors
|
|
3664
|
+
"href",
|
|
3665
|
+
"target",
|
|
3666
|
+
"rel",
|
|
3667
|
+
// Images
|
|
3668
|
+
"src",
|
|
3669
|
+
"alt",
|
|
3670
|
+
"width",
|
|
3671
|
+
"height",
|
|
3672
|
+
// Tables
|
|
3673
|
+
"colspan",
|
|
3674
|
+
"rowspan",
|
|
3675
|
+
// Lists — <ol type="a"> and <ol start="2">
|
|
3676
|
+
"start",
|
|
3677
|
+
"type",
|
|
3678
|
+
// Lexical-internal data markers
|
|
3679
|
+
"data-lex-block",
|
|
3680
|
+
"data-kind",
|
|
3681
|
+
"data-lexical-decorator",
|
|
3682
|
+
// Misc
|
|
3683
|
+
"title",
|
|
3684
|
+
"allowfullscreen"
|
|
3685
|
+
]);
|
|
3686
|
+
var DANGEROUS_URL = /^\s*(javascript|data\s*:|vbscript)/i;
|
|
3687
|
+
function sanitizeElement(el) {
|
|
3688
|
+
for (const child of Array.from(el.children)) {
|
|
3689
|
+
sanitizeElement(child);
|
|
3690
|
+
}
|
|
3691
|
+
const tag = el.tagName.toLowerCase();
|
|
3692
|
+
if (DROP_ENTIRELY.has(tag)) {
|
|
3693
|
+
el.parentNode?.removeChild(el);
|
|
3694
|
+
return;
|
|
3695
|
+
}
|
|
3696
|
+
if (tag === "iframe") {
|
|
3697
|
+
const src = el.getAttribute("src") ?? "";
|
|
3698
|
+
const isYouTube = /^\s*https:\/\/(www\.)?(youtube\.com|youtube-nocookie\.com)\/embed\/[^?&/]+/i.test(src);
|
|
3699
|
+
if (!isYouTube) {
|
|
3700
|
+
el.parentNode?.removeChild(el);
|
|
3701
|
+
return;
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
if (!ALLOWED_TAGS.has(tag)) {
|
|
3705
|
+
while (el.firstChild) {
|
|
3706
|
+
el.parentNode?.insertBefore(el.firstChild, el);
|
|
3707
|
+
}
|
|
3708
|
+
el.parentNode?.removeChild(el);
|
|
3709
|
+
return;
|
|
3710
|
+
}
|
|
3711
|
+
for (const { name, value } of Array.from(el.attributes)) {
|
|
3712
|
+
const lname = name.toLowerCase();
|
|
3713
|
+
if (!ALLOWED_ATTRS.has(lname)) {
|
|
3714
|
+
el.removeAttribute(name);
|
|
3715
|
+
continue;
|
|
3716
|
+
}
|
|
3717
|
+
if (lname === "href" || lname === "src") {
|
|
3718
|
+
if (DANGEROUS_URL.test(value)) {
|
|
3719
|
+
el.removeAttribute(name);
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
if (lname === "style") {
|
|
3723
|
+
const safe = value.replace(/expression\s*\(/gi, "(").replace(/url\s*\(\s*['"]?\s*javascript:/gi, "url(");
|
|
3724
|
+
el.setAttribute("style", safe);
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
if (tag === "a" && (el.getAttribute("target") || "").toLowerCase() === "_blank") {
|
|
3728
|
+
const rel = (el.getAttribute("rel") || "").trim();
|
|
3729
|
+
const tokens = new Set(
|
|
3730
|
+
rel.split(/\s+/).filter(Boolean).map((t) => t.toLowerCase())
|
|
3731
|
+
);
|
|
3732
|
+
tokens.add("noopener");
|
|
3733
|
+
tokens.add("noreferrer");
|
|
3734
|
+
el.setAttribute("rel", Array.from(tokens).join(" "));
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
function sanitizeHtml(html) {
|
|
3738
|
+
if (!html || typeof html !== "string") return "";
|
|
3739
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
3740
|
+
for (const child of Array.from(doc.body.children)) {
|
|
3741
|
+
sanitizeElement(child);
|
|
3742
|
+
}
|
|
3743
|
+
return doc.body.innerHTML;
|
|
3744
|
+
}
|
|
3745
|
+
var BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
3746
|
+
"p",
|
|
3747
|
+
"h1",
|
|
3748
|
+
"h2",
|
|
3749
|
+
"h3",
|
|
3750
|
+
"h4",
|
|
3751
|
+
"h5",
|
|
3752
|
+
"h6",
|
|
3753
|
+
"div",
|
|
3754
|
+
"ul",
|
|
3755
|
+
"ol",
|
|
3756
|
+
"li",
|
|
3757
|
+
"table",
|
|
3758
|
+
"blockquote",
|
|
3759
|
+
"pre",
|
|
3760
|
+
"hr"
|
|
3761
|
+
]);
|
|
3762
|
+
function normalizeToBlockHtml(html) {
|
|
3763
|
+
if (!html) return "";
|
|
3764
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
3765
|
+
const body = doc.body;
|
|
3766
|
+
const childNodes = Array.from(body.childNodes);
|
|
3767
|
+
const needsWrap = childNodes.some((node) => {
|
|
3768
|
+
if (node.nodeType === Node.TEXT_NODE) return !!node.nodeValue?.trim();
|
|
3769
|
+
if (node.nodeType === Node.ELEMENT_NODE)
|
|
3770
|
+
return !BLOCK_TAGS.has(node.tagName.toLowerCase());
|
|
3771
|
+
return false;
|
|
3772
|
+
});
|
|
3773
|
+
if (!needsWrap) return html;
|
|
3774
|
+
while (body.firstChild) body.removeChild(body.firstChild);
|
|
3775
|
+
let pendingP = null;
|
|
3776
|
+
for (const node of childNodes) {
|
|
3777
|
+
const isBlock = node.nodeType === Node.ELEMENT_NODE && BLOCK_TAGS.has(node.tagName.toLowerCase());
|
|
3778
|
+
const isWhitespace = node.nodeType === Node.TEXT_NODE && !node.nodeValue?.trim();
|
|
3779
|
+
if (isBlock) {
|
|
3780
|
+
if (pendingP) {
|
|
3781
|
+
body.appendChild(pendingP);
|
|
3782
|
+
pendingP = null;
|
|
3783
|
+
}
|
|
3784
|
+
body.appendChild(node);
|
|
3785
|
+
} else if (!isWhitespace) {
|
|
3786
|
+
if (!pendingP) pendingP = doc.createElement("p");
|
|
3787
|
+
pendingP.appendChild(node);
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
if (pendingP) body.appendChild(pendingP);
|
|
3791
|
+
return body.innerHTML;
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3794
|
+
// src/Utils/Helper.ts
|
|
3570
3795
|
function findBlockByKind(kind) {
|
|
3571
3796
|
const root = lexical.$getRoot();
|
|
3572
3797
|
for (const child of root.getChildren()) {
|
|
@@ -3575,8 +3800,9 @@ function findBlockByKind(kind) {
|
|
|
3575
3800
|
return null;
|
|
3576
3801
|
}
|
|
3577
3802
|
function importHtmlIntoBlock(editor, block, html$1) {
|
|
3803
|
+
const safe = normalizeToBlockHtml(sanitizeHtml(html$1));
|
|
3578
3804
|
const parser = new DOMParser();
|
|
3579
|
-
const doc = parser.parseFromString(
|
|
3805
|
+
const doc = parser.parseFromString(safe || "<p></p>", "text/html");
|
|
3580
3806
|
const nodes = html.$generateNodesFromDOM(editor, doc);
|
|
3581
3807
|
block.clear();
|
|
3582
3808
|
block.append(...nodes);
|
|
@@ -3615,7 +3841,8 @@ function hasBlock(editor, kind) {
|
|
|
3615
3841
|
function RefApiPlugin({
|
|
3616
3842
|
forwardedRef,
|
|
3617
3843
|
contentEditableDomRef,
|
|
3618
|
-
focusedRef
|
|
3844
|
+
focusedRef,
|
|
3845
|
+
setRefErrors
|
|
3619
3846
|
}) {
|
|
3620
3847
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
3621
3848
|
React6.useImperativeHandle(
|
|
@@ -3654,12 +3881,14 @@ function RefApiPlugin({
|
|
|
3654
3881
|
},
|
|
3655
3882
|
isFocused: () => focusedRef.current,
|
|
3656
3883
|
getEditor: () => editor,
|
|
3884
|
+
setErrors: (messages) => setRefErrors(messages),
|
|
3885
|
+
clearErrors: () => setRefErrors([]),
|
|
3657
3886
|
// Generic blocks (signature, footer, banner, etc.)
|
|
3658
3887
|
upsertBlock: (spec) => upsertBlock(editor, spec),
|
|
3659
3888
|
removeBlock: (kind) => removeBlock(editor, kind),
|
|
3660
3889
|
hasBlock: (kind) => hasBlock(editor, kind)
|
|
3661
3890
|
}),
|
|
3662
|
-
[editor, contentEditableDomRef, focusedRef]
|
|
3891
|
+
[editor, contentEditableDomRef, focusedRef, setRefErrors]
|
|
3663
3892
|
);
|
|
3664
3893
|
return null;
|
|
3665
3894
|
}
|
|
@@ -4299,8 +4528,8 @@ function SpellCheckPlugin({
|
|
|
4299
4528
|
function TableActionMenuPlugin({ disabled = false }) {
|
|
4300
4529
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
4301
4530
|
const [isInTable, setIsInTable] = React6__namespace.useState(false);
|
|
4531
|
+
const [anchorRect, setAnchorRect] = React6__namespace.useState(null);
|
|
4302
4532
|
const [open, setOpen] = React6__namespace.useState(false);
|
|
4303
|
-
const [menuPos, setMenuPos] = React6__namespace.useState(null);
|
|
4304
4533
|
const updateFromSelection = React6__namespace.useCallback(() => {
|
|
4305
4534
|
const root = editor.getRootElement();
|
|
4306
4535
|
if (!root) return;
|
|
@@ -4309,21 +4538,34 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4309
4538
|
if (table.$isTableSelection(selection)) {
|
|
4310
4539
|
const tableNode = selection.getNodes().find((n) => table.$isTableNode(n));
|
|
4311
4540
|
if (tableNode) {
|
|
4312
|
-
|
|
4313
|
-
|
|
4541
|
+
const dom = editor.getElementByKey(tableNode.getKey());
|
|
4542
|
+
if (dom) {
|
|
4543
|
+
setIsInTable(true);
|
|
4544
|
+
setAnchorRect(dom.getBoundingClientRect());
|
|
4545
|
+
return;
|
|
4546
|
+
}
|
|
4314
4547
|
}
|
|
4315
4548
|
}
|
|
4316
4549
|
if (!lexical.$isRangeSelection(selection)) {
|
|
4317
4550
|
setIsInTable(false);
|
|
4551
|
+
setAnchorRect(null);
|
|
4318
4552
|
return;
|
|
4319
4553
|
}
|
|
4320
4554
|
const anchorNode = selection.anchor.getNode();
|
|
4321
4555
|
const cellNode = table.$isTableCellNode(anchorNode) ? anchorNode : lexical.$findMatchingParent(anchorNode, (n) => table.$isTableCellNode(n));
|
|
4322
4556
|
if (!cellNode || !table.$isTableCellNode(cellNode)) {
|
|
4323
4557
|
setIsInTable(false);
|
|
4558
|
+
setAnchorRect(null);
|
|
4559
|
+
return;
|
|
4560
|
+
}
|
|
4561
|
+
const cellDom = editor.getElementByKey(cellNode.getKey());
|
|
4562
|
+
if (!cellDom) {
|
|
4563
|
+
setIsInTable(false);
|
|
4564
|
+
setAnchorRect(null);
|
|
4324
4565
|
return;
|
|
4325
4566
|
}
|
|
4326
4567
|
setIsInTable(true);
|
|
4568
|
+
setAnchorRect(cellDom.getBoundingClientRect());
|
|
4327
4569
|
});
|
|
4328
4570
|
}, [editor]);
|
|
4329
4571
|
React6__namespace.useEffect(() => {
|
|
@@ -4385,33 +4627,18 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4385
4627
|
React6__namespace.useEffect(() => {
|
|
4386
4628
|
if (!isInTable && open) setOpen(false);
|
|
4387
4629
|
}, [isInTable, open]);
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
if (!
|
|
4391
|
-
const
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
return;
|
|
4399
|
-
}
|
|
4400
|
-
if (lexical.$isRangeSelection(selection)) {
|
|
4401
|
-
const node = selection.anchor.getNode();
|
|
4402
|
-
const cell = table.$isTableCellNode(node) ? node : lexical.$findMatchingParent(node, (n) => table.$isTableCellNode(n));
|
|
4403
|
-
if (cell) inTable = true;
|
|
4404
|
-
}
|
|
4405
|
-
});
|
|
4406
|
-
if (inTable) {
|
|
4407
|
-
e.preventDefault();
|
|
4408
|
-
setMenuPos({ x: e.clientX, y: e.clientY });
|
|
4409
|
-
setOpen(true);
|
|
4410
|
-
}
|
|
4630
|
+
const canShow = isInTable && !!anchorRect && !disabled;
|
|
4631
|
+
const handleStyle = React6__namespace.useMemo(() => {
|
|
4632
|
+
if (!anchorRect) return void 0;
|
|
4633
|
+
const top = Math.max(8, anchorRect.top + 6);
|
|
4634
|
+
const left = Math.max(8, anchorRect.right - 34);
|
|
4635
|
+
return {
|
|
4636
|
+
position: "fixed",
|
|
4637
|
+
top,
|
|
4638
|
+
left,
|
|
4639
|
+
zIndex: 9999
|
|
4411
4640
|
};
|
|
4412
|
-
|
|
4413
|
-
return () => root.removeEventListener("contextmenu", handleContextMenu);
|
|
4414
|
-
}, [editor, disabled]);
|
|
4641
|
+
}, [anchorRect]);
|
|
4415
4642
|
const dangerStyle = {
|
|
4416
4643
|
color: "var(--colorPaletteRedForeground1)"
|
|
4417
4644
|
};
|
|
@@ -4444,55 +4671,63 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4444
4671
|
const table$1 = table.$getTableNodeFromLexicalNodeOrThrow(cell);
|
|
4445
4672
|
table$1.remove();
|
|
4446
4673
|
});
|
|
4447
|
-
|
|
4448
|
-
if (!menuPos) return void 0;
|
|
4449
|
-
return {
|
|
4450
|
-
getBoundingClientRect: () => new DOMRect(menuPos.x, menuPos.y, 0, 0)
|
|
4451
|
-
};
|
|
4452
|
-
}, [menuPos]);
|
|
4453
|
-
if (disabled) return null;
|
|
4674
|
+
if (!canShow || !handleStyle) return null;
|
|
4454
4675
|
return reactDom.createPortal(
|
|
4455
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4456
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4471
|
-
|
|
4676
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle, className: "aoTableActionHandleRoot", children: /* @__PURE__ */ jsxRuntime.jsxs(reactComponents.Menu, { open, onOpenChange: (_, data) => setOpen(data.open), children: [
|
|
4677
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4678
|
+
"button",
|
|
4679
|
+
{
|
|
4680
|
+
type: "button",
|
|
4681
|
+
className: "aoTableActionHandleBtn",
|
|
4682
|
+
"aria-label": "Table options",
|
|
4683
|
+
onMouseDown: (e) => {
|
|
4684
|
+
e.preventDefault();
|
|
4685
|
+
},
|
|
4686
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.ChevronDown12Regular, {})
|
|
4687
|
+
}
|
|
4688
|
+
) }),
|
|
4689
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuPopover, { className: "aoTableActionPopover", children: /* @__PURE__ */ jsxRuntime.jsxs(reactComponents.MenuList, { children: [
|
|
4690
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactComponents.MenuGroup, { children: [
|
|
4691
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuGroupHeader, { children: "Insert" }),
|
|
4692
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.RowTripleRegular, {}), onClick: insertRowAbove, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuRow", children: [
|
|
4693
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuLabel", children: [
|
|
4694
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowUpRegular, {}),
|
|
4695
|
+
" Row above"
|
|
4696
|
+
] }),
|
|
4697
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "aoMenuShortcut", children: "Alt \u21E7 \u2191" })
|
|
4698
|
+
] }) }),
|
|
4699
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.RowTripleRegular, {}), onClick: insertRowBelow, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuRow", children: [
|
|
4700
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuLabel", children: [
|
|
4701
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowDownRegular, {}),
|
|
4702
|
+
" Row below"
|
|
4703
|
+
] }),
|
|
4704
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "aoMenuShortcut", children: "Alt \u21E7 \u2193" })
|
|
4705
|
+
] }) }),
|
|
4706
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuDivider, {}),
|
|
4707
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.ColumnTripleRegular, {}), onClick: insertColLeft, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuRow", children: [
|
|
4708
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuLabel", children: [
|
|
4709
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowLeftRegular, {}),
|
|
4710
|
+
" Column left"
|
|
4711
|
+
] }),
|
|
4712
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "aoMenuShortcut", children: "Alt \u21E7 \u2190" })
|
|
4713
|
+
] }) }),
|
|
4714
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.ColumnTripleRegular, {}), onClick: insertColRight, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuRow", children: [
|
|
4715
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuLabel", children: [
|
|
4716
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowRightRegular, {}),
|
|
4717
|
+
" Column right"
|
|
4718
|
+
] }),
|
|
4719
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "aoMenuShortcut", children: "Alt \u21E7 \u2192" })
|
|
4720
|
+
] }) })
|
|
4721
|
+
] }),
|
|
4472
4722
|
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuDivider, {}),
|
|
4473
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4474
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aoMenuLabel", children: [
|
|
4482
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.ArrowRightRegular, {}),
|
|
4483
|
-
" Column right"
|
|
4484
|
-
] }),
|
|
4485
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "aoMenuShortcut", children: "Alt \u21E7 \u2192" })
|
|
4486
|
-
] }) })
|
|
4487
|
-
] }),
|
|
4488
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuDivider, {}),
|
|
4489
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactComponents.MenuGroup, { children: [
|
|
4490
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuGroupHeader, { children: "Delete" }),
|
|
4491
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, {}), onClick: deleteRow, style: dangerStyle, children: "Delete row" }),
|
|
4492
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, {}), onClick: deleteCol, style: dangerStyle, children: "Delete column" }),
|
|
4493
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, {}), onClick: deleteTable, style: dangerStyle, children: "Delete table" })
|
|
4494
|
-
] })
|
|
4495
|
-
] }) }) }),
|
|
4723
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactComponents.MenuGroup, { children: [
|
|
4724
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuGroupHeader, { children: "Delete" }),
|
|
4725
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, {}), onClick: deleteRow, style: dangerStyle, children: "Delete row" }),
|
|
4726
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, {}), onClick: deleteCol, style: dangerStyle, children: "Delete column" }),
|
|
4727
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.MenuItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, {}), onClick: deleteTable, style: dangerStyle, children: "Delete table" })
|
|
4728
|
+
] })
|
|
4729
|
+
] }) })
|
|
4730
|
+
] }) }),
|
|
4496
4731
|
document.body
|
|
4497
4732
|
);
|
|
4498
4733
|
}
|
|
@@ -4796,13 +5031,6 @@ function getToolbarGroupsByLevel(level) {
|
|
|
4796
5031
|
];
|
|
4797
5032
|
}
|
|
4798
5033
|
}
|
|
4799
|
-
var DEFAULT_FONT_SIZE = 15;
|
|
4800
|
-
var formatParagraph = (editor) => {
|
|
4801
|
-
editor.update(() => {
|
|
4802
|
-
const selection$1 = lexical.$getSelection();
|
|
4803
|
-
selection.$setBlocksType(selection$1, () => lexical.$createParagraphNode());
|
|
4804
|
-
});
|
|
4805
|
-
};
|
|
4806
5034
|
var PRESET = [
|
|
4807
5035
|
"#000000",
|
|
4808
5036
|
"#434343",
|
|
@@ -4878,11 +5106,12 @@ var hsvToRgb = (h, s, v) => {
|
|
|
4878
5106
|
b: Math.round((bb + m) * 255)
|
|
4879
5107
|
};
|
|
4880
5108
|
};
|
|
4881
|
-
function useDrag(onMove, onEnd) {
|
|
5109
|
+
function useDrag(onMove, onEnd, interactingRef) {
|
|
4882
5110
|
const draggingRef = React6__namespace.useRef(false);
|
|
4883
5111
|
const start = React6__namespace.useCallback(
|
|
4884
5112
|
(e) => {
|
|
4885
5113
|
draggingRef.current = true;
|
|
5114
|
+
if (interactingRef) interactingRef.current = true;
|
|
4886
5115
|
onMove(e.clientX, e.clientY);
|
|
4887
5116
|
const move = (ev) => {
|
|
4888
5117
|
if (!draggingRef.current) return;
|
|
@@ -4892,17 +5121,55 @@ function useDrag(onMove, onEnd) {
|
|
|
4892
5121
|
draggingRef.current = false;
|
|
4893
5122
|
window.removeEventListener("mousemove", move);
|
|
4894
5123
|
window.removeEventListener("mouseup", up);
|
|
5124
|
+
if (interactingRef) {
|
|
5125
|
+
const clearFlag = () => {
|
|
5126
|
+
interactingRef.current = false;
|
|
5127
|
+
};
|
|
5128
|
+
window.addEventListener("click", clearFlag, { once: true });
|
|
5129
|
+
setTimeout(() => {
|
|
5130
|
+
window.removeEventListener("click", clearFlag);
|
|
5131
|
+
interactingRef.current = false;
|
|
5132
|
+
}, 0);
|
|
5133
|
+
}
|
|
4895
5134
|
};
|
|
4896
5135
|
window.addEventListener("mousemove", move);
|
|
4897
5136
|
window.addEventListener("mouseup", up);
|
|
4898
5137
|
},
|
|
4899
|
-
[onMove, onEnd]
|
|
5138
|
+
[onMove, onEnd, interactingRef]
|
|
4900
5139
|
);
|
|
4901
5140
|
return start;
|
|
4902
5141
|
}
|
|
4903
5142
|
var ColorPickerControl = ({ value, title, disabled, onChange, icon }) => {
|
|
4904
5143
|
const [open, setOpen] = React6__namespace.useState(false);
|
|
4905
5144
|
const btnRef = React6__namespace.useRef(null);
|
|
5145
|
+
const interactingRef = React6__namespace.useRef(false);
|
|
5146
|
+
const handleDismiss = React6__namespace.useCallback(() => setOpen(false), []);
|
|
5147
|
+
const preventDismissOnEvent = React6__namespace.useCallback(
|
|
5148
|
+
(ev) => {
|
|
5149
|
+
if (interactingRef.current) return true;
|
|
5150
|
+
return ev.type !== "click";
|
|
5151
|
+
},
|
|
5152
|
+
[]
|
|
5153
|
+
);
|
|
5154
|
+
const [, forceReposition] = React6__namespace.useState(0);
|
|
5155
|
+
React6__namespace.useEffect(() => {
|
|
5156
|
+
if (!open) return;
|
|
5157
|
+
let rafId = null;
|
|
5158
|
+
const reposition = () => {
|
|
5159
|
+
if (rafId != null) return;
|
|
5160
|
+
rafId = requestAnimationFrame(() => {
|
|
5161
|
+
rafId = null;
|
|
5162
|
+
forceReposition((n) => n + 1);
|
|
5163
|
+
});
|
|
5164
|
+
};
|
|
5165
|
+
window.addEventListener("scroll", reposition, true);
|
|
5166
|
+
window.addEventListener("resize", reposition);
|
|
5167
|
+
return () => {
|
|
5168
|
+
if (rafId != null) cancelAnimationFrame(rafId);
|
|
5169
|
+
window.removeEventListener("scroll", reposition, true);
|
|
5170
|
+
window.removeEventListener("resize", reposition);
|
|
5171
|
+
};
|
|
5172
|
+
}, [open]);
|
|
4906
5173
|
const [hex, setHex] = React6__namespace.useState(normalizeHex(value || "#000000"));
|
|
4907
5174
|
const { r, g, b } = React6__namespace.useMemo(() => hexToRgb(hex), [hex]);
|
|
4908
5175
|
const hsv = React6__namespace.useMemo(() => rgbToHsv(r, g, b), [r, g, b]);
|
|
@@ -4943,7 +5210,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon }) => {
|
|
|
4943
5210
|
},
|
|
4944
5211
|
[h, commitHsv]
|
|
4945
5212
|
);
|
|
4946
|
-
const startSV = useDrag(onSVMove);
|
|
5213
|
+
const startSV = useDrag(onSVMove, void 0, interactingRef);
|
|
4947
5214
|
const hueRef = React6__namespace.useRef(null);
|
|
4948
5215
|
const onHueMove = React6__namespace.useCallback(
|
|
4949
5216
|
(clientX) => {
|
|
@@ -4956,7 +5223,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon }) => {
|
|
|
4956
5223
|
},
|
|
4957
5224
|
[s, v, commitHsv]
|
|
4958
5225
|
);
|
|
4959
|
-
const startHue = useDrag((x) => onHueMove(x));
|
|
5226
|
+
const startHue = useDrag((x) => onHueMove(x), void 0, interactingRef);
|
|
4960
5227
|
const svThumb = React6__namespace.useMemo(() => ({ left: `${s * 100}%`, top: `${(1 - v) * 100}%` }), [s, v]);
|
|
4961
5228
|
const hueThumb = React6__namespace.useMemo(() => ({ left: `${h / 360 * 100}%` }), [h]);
|
|
4962
5229
|
const hueColor = React6__namespace.useMemo(() => {
|
|
@@ -5005,10 +5272,11 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon }) => {
|
|
|
5005
5272
|
react.Callout,
|
|
5006
5273
|
{
|
|
5007
5274
|
target: btnRef,
|
|
5008
|
-
onDismiss:
|
|
5275
|
+
onDismiss: handleDismiss,
|
|
5009
5276
|
setInitialFocus: true,
|
|
5010
5277
|
directionalHint: 4,
|
|
5011
5278
|
className: "aoColorCallout",
|
|
5279
|
+
preventDismissOnEvent,
|
|
5012
5280
|
children: /* @__PURE__ */ jsxRuntime.jsxs(react.Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: 12, width: 320 } }, children: [
|
|
5013
5281
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aoLexRow", children: [
|
|
5014
5282
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexSwatch", style: { background: hex } }),
|
|
@@ -5108,7 +5376,9 @@ var ColorPickerPlugin = ({ disabled }) => {
|
|
|
5108
5376
|
}, [editor]);
|
|
5109
5377
|
const applyStyle = (args) => {
|
|
5110
5378
|
if (disabled) return;
|
|
5111
|
-
editor.
|
|
5379
|
+
const root = editor.getRootElement();
|
|
5380
|
+
const editorIsActive = !!lastRangeSelectionRef.current && !!root && (document.activeElement === root || root.contains(document.activeElement));
|
|
5381
|
+
if (editorIsActive) editor.focus();
|
|
5112
5382
|
editor.update(() => {
|
|
5113
5383
|
const saved = lastRangeSelectionRef.current;
|
|
5114
5384
|
if (saved) {
|
|
@@ -5247,6 +5517,7 @@ var FontFamilyPlugin = ({ disabled = false }) => {
|
|
|
5247
5517
|
"font-family"
|
|
5248
5518
|
);
|
|
5249
5519
|
};
|
|
5520
|
+
var DEFAULT_FONT_SIZE = 15;
|
|
5250
5521
|
var FONT_SIZE_OPTIONS = [
|
|
5251
5522
|
"8",
|
|
5252
5523
|
"9",
|
|
@@ -5547,21 +5818,27 @@ var TableItemPlugin = ({ disabled }) => {
|
|
|
5547
5818
|
reactComponents.Input,
|
|
5548
5819
|
{
|
|
5549
5820
|
autoFocus: !disabled,
|
|
5821
|
+
type: "number",
|
|
5822
|
+
min: 1,
|
|
5550
5823
|
value: rows,
|
|
5551
5824
|
placeholder: "Rows",
|
|
5552
5825
|
appearance: "underline",
|
|
5553
5826
|
disabled,
|
|
5554
|
-
|
|
5827
|
+
input: { style: { textAlign: "left" } },
|
|
5828
|
+
onChange: (_, v) => setRows(v.value.replace(/\D/g, ""))
|
|
5555
5829
|
}
|
|
5556
5830
|
) }),
|
|
5557
5831
|
/* @__PURE__ */ jsxRuntime.jsx(reactComponents.Field, { label: "Columns", orientation: "horizontal", size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5558
5832
|
reactComponents.Input,
|
|
5559
5833
|
{
|
|
5834
|
+
type: "number",
|
|
5835
|
+
min: 1,
|
|
5560
5836
|
value: columns,
|
|
5561
5837
|
placeholder: "Columns",
|
|
5562
5838
|
appearance: "underline",
|
|
5563
5839
|
disabled,
|
|
5564
|
-
|
|
5840
|
+
input: { style: { textAlign: "left" } },
|
|
5841
|
+
onChange: (_, v) => setColumns(v.value.replace(/\D/g, ""))
|
|
5565
5842
|
}
|
|
5566
5843
|
) }),
|
|
5567
5844
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Stack, { horizontal: true, horizontalAlign: "end", tokens: { childrenGap: 6 }, children: [
|
|
@@ -5718,8 +5995,7 @@ var ToolBarPlugins = (props) => {
|
|
|
5718
5995
|
const [isLowercase, setIsLowercase] = React6.useState(false);
|
|
5719
5996
|
const [isCapitalize, setIsCapitalize] = React6.useState(false);
|
|
5720
5997
|
const [alignment, setAlignment] = React6.useState("left");
|
|
5721
|
-
const
|
|
5722
|
-
const [tableNodeKey, setTableNodeKey] = React6.useState(null);
|
|
5998
|
+
const lastSelectionRef = React6__namespace.default.useRef(null);
|
|
5723
5999
|
const presetGroups = getToolbarGroupsByLevel(props.level);
|
|
5724
6000
|
const pluginGroups = React6.useMemo(() => sanitizePluginGroups(presetGroups), [presetGroups]);
|
|
5725
6001
|
const updateToolbarPlugins = () => {
|
|
@@ -5736,8 +6012,6 @@ var ToolBarPlugins = (props) => {
|
|
|
5736
6012
|
setIsLowercase(false);
|
|
5737
6013
|
setIsCapitalize(false);
|
|
5738
6014
|
setSelectNodeType("paragraph");
|
|
5739
|
-
setIsInTable(false);
|
|
5740
|
-
setTableNodeKey(null);
|
|
5741
6015
|
return;
|
|
5742
6016
|
}
|
|
5743
6017
|
setIsBold(selection.hasFormat("bold"));
|
|
@@ -5753,21 +6027,8 @@ var ToolBarPlugins = (props) => {
|
|
|
5753
6027
|
const anchorNode = selection.anchor.getNode();
|
|
5754
6028
|
if (anchorNode.getKey() === "root") {
|
|
5755
6029
|
setSelectNodeType("paragraph");
|
|
5756
|
-
setIsInTable(false);
|
|
5757
|
-
setTableNodeKey(null);
|
|
5758
6030
|
return;
|
|
5759
6031
|
}
|
|
5760
|
-
let tableAncestorKey = null;
|
|
5761
|
-
let cursor = anchorNode.getParent();
|
|
5762
|
-
while (cursor !== null) {
|
|
5763
|
-
if (cursor.getType() === "table") {
|
|
5764
|
-
tableAncestorKey = cursor.getKey();
|
|
5765
|
-
break;
|
|
5766
|
-
}
|
|
5767
|
-
cursor = cursor.getParent();
|
|
5768
|
-
}
|
|
5769
|
-
setIsInTable(tableAncestorKey !== null);
|
|
5770
|
-
setTableNodeKey(tableAncestorKey);
|
|
5771
6032
|
const element = anchorNode.getTopLevelElementOrThrow();
|
|
5772
6033
|
setAlignment(
|
|
5773
6034
|
typeof element.getFormatType === "function" ? element.getFormatType() || "left" : "left"
|
|
@@ -5788,12 +6049,21 @@ var ToolBarPlugins = (props) => {
|
|
|
5788
6049
|
["paragraph", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "quote", "code"].includes(type) ? type : "paragraph"
|
|
5789
6050
|
);
|
|
5790
6051
|
};
|
|
6052
|
+
const applyToBlock = React6__namespace.default.useCallback(
|
|
6053
|
+
(fn) => {
|
|
6054
|
+
editor.update(() => {
|
|
6055
|
+
const saved = lastSelectionRef.current;
|
|
6056
|
+
if (saved) lexical.$setSelection(saved.clone());
|
|
6057
|
+
const sel = lexical.$getSelection();
|
|
6058
|
+
if (lexical.$isRangeSelection(sel)) fn(sel);
|
|
6059
|
+
});
|
|
6060
|
+
},
|
|
6061
|
+
[editor]
|
|
6062
|
+
);
|
|
5791
6063
|
const formatQuote = () => {
|
|
5792
|
-
|
|
5793
|
-
const selection$1 = lexical.$getSelection();
|
|
5794
|
-
if (!lexical.$isRangeSelection(selection$1)) return;
|
|
6064
|
+
applyToBlock((selection$1) => {
|
|
5795
6065
|
if (selectNodeType === "quote") {
|
|
5796
|
-
|
|
6066
|
+
selection.$setBlocksType(selection$1, () => lexical.$createParagraphNode());
|
|
5797
6067
|
} else {
|
|
5798
6068
|
selection.$setBlocksType(selection$1, () => richText.$createQuoteNode());
|
|
5799
6069
|
}
|
|
@@ -5812,6 +6082,8 @@ var ToolBarPlugins = (props) => {
|
|
|
5812
6082
|
editor.registerCommand(
|
|
5813
6083
|
lexical.SELECTION_CHANGE_COMMAND,
|
|
5814
6084
|
() => {
|
|
6085
|
+
const sel = lexical.$getSelection();
|
|
6086
|
+
if (lexical.$isRangeSelection(sel)) lastSelectionRef.current = sel.clone();
|
|
5815
6087
|
updateToolbarPlugins();
|
|
5816
6088
|
return false;
|
|
5817
6089
|
},
|
|
@@ -5843,16 +6115,52 @@ var ToolBarPlugins = (props) => {
|
|
|
5843
6115
|
editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "highlight");
|
|
5844
6116
|
break;
|
|
5845
6117
|
case "leftAlign" /* LeftAlign */:
|
|
5846
|
-
|
|
6118
|
+
applyToBlock((sel) => {
|
|
6119
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6120
|
+
sel.getNodes().forEach((n) => {
|
|
6121
|
+
const t = n.getTopLevelElementOrThrow();
|
|
6122
|
+
if (!seen.has(t.getKey())) {
|
|
6123
|
+
seen.add(t.getKey());
|
|
6124
|
+
t.setFormat("left");
|
|
6125
|
+
}
|
|
6126
|
+
});
|
|
6127
|
+
});
|
|
5847
6128
|
break;
|
|
5848
6129
|
case "rightAlign" /* RightAlign */:
|
|
5849
|
-
|
|
6130
|
+
applyToBlock((sel) => {
|
|
6131
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6132
|
+
sel.getNodes().forEach((n) => {
|
|
6133
|
+
const t = n.getTopLevelElementOrThrow();
|
|
6134
|
+
if (!seen.has(t.getKey())) {
|
|
6135
|
+
seen.add(t.getKey());
|
|
6136
|
+
t.setFormat("right");
|
|
6137
|
+
}
|
|
6138
|
+
});
|
|
6139
|
+
});
|
|
5850
6140
|
break;
|
|
5851
6141
|
case "centerAlign" /* CenterAlign */:
|
|
5852
|
-
|
|
6142
|
+
applyToBlock((sel) => {
|
|
6143
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6144
|
+
sel.getNodes().forEach((n) => {
|
|
6145
|
+
const t = n.getTopLevelElementOrThrow();
|
|
6146
|
+
if (!seen.has(t.getKey())) {
|
|
6147
|
+
seen.add(t.getKey());
|
|
6148
|
+
t.setFormat("center");
|
|
6149
|
+
}
|
|
6150
|
+
});
|
|
6151
|
+
});
|
|
5853
6152
|
break;
|
|
5854
6153
|
case "justifyAlign" /* JustifyAlign */:
|
|
5855
|
-
|
|
6154
|
+
applyToBlock((sel) => {
|
|
6155
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6156
|
+
sel.getNodes().forEach((n) => {
|
|
6157
|
+
const t = n.getTopLevelElementOrThrow();
|
|
6158
|
+
if (!seen.has(t.getKey())) {
|
|
6159
|
+
seen.add(t.getKey());
|
|
6160
|
+
t.setFormat("justify");
|
|
6161
|
+
}
|
|
6162
|
+
});
|
|
6163
|
+
});
|
|
5856
6164
|
break;
|
|
5857
6165
|
case "undo" /* Undo */:
|
|
5858
6166
|
editor.dispatchCommand(lexical.UNDO_COMMAND, void 0);
|
|
@@ -5872,14 +6180,8 @@ var ToolBarPlugins = (props) => {
|
|
|
5872
6180
|
}
|
|
5873
6181
|
};
|
|
5874
6182
|
const updateHeading = (heading) => {
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
if (lexical.$isRangeSelection(selection$1)) {
|
|
5878
|
-
selection.$setBlocksType(selection$1, () => richText.$createHeadingNode(heading));
|
|
5879
|
-
}
|
|
5880
|
-
});
|
|
5881
|
-
editor.getEditorState().read(() => {
|
|
5882
|
-
updateToolbarPlugins();
|
|
6183
|
+
applyToBlock((selection$1) => {
|
|
6184
|
+
selection.$setBlocksType(selection$1, () => richText.$createHeadingNode(heading));
|
|
5883
6185
|
});
|
|
5884
6186
|
};
|
|
5885
6187
|
const renderToken = (token, groupIndex, tokenIndex) => {
|
|
@@ -6018,7 +6320,7 @@ var ToolBarPlugins = (props) => {
|
|
|
6018
6320
|
const val = data.optionValue;
|
|
6019
6321
|
if (!val) return;
|
|
6020
6322
|
if (val === "paragraph") {
|
|
6021
|
-
|
|
6323
|
+
applyToBlock((sel) => selection.$setBlocksType(sel, () => lexical.$createParagraphNode()));
|
|
6022
6324
|
setSelectNodeType("paragraph");
|
|
6023
6325
|
} else {
|
|
6024
6326
|
updateHeading(val);
|
|
@@ -6102,16 +6404,10 @@ var ToolBarPlugins = (props) => {
|
|
|
6102
6404
|
onHandleSelectOption("highlight" /* Highlight */);
|
|
6103
6405
|
break;
|
|
6104
6406
|
case "ul-list":
|
|
6105
|
-
editor.dispatchCommand(
|
|
6106
|
-
selectNodeType === "ul" ? list.REMOVE_LIST_COMMAND : list.INSERT_UNORDERED_LIST_COMMAND,
|
|
6107
|
-
void 0
|
|
6108
|
-
);
|
|
6407
|
+
editor.dispatchCommand(selectNodeType === "ul" ? list.REMOVE_LIST_COMMAND : list.INSERT_UNORDERED_LIST_COMMAND, void 0);
|
|
6109
6408
|
break;
|
|
6110
6409
|
case "ol-list":
|
|
6111
|
-
editor.dispatchCommand(
|
|
6112
|
-
selectNodeType === "ol" ? list.REMOVE_LIST_COMMAND : list.INSERT_ORDERED_LIST_COMMAND,
|
|
6113
|
-
void 0
|
|
6114
|
-
);
|
|
6410
|
+
editor.dispatchCommand(selectNodeType === "ol" ? list.REMOVE_LIST_COMMAND : list.INSERT_ORDERED_LIST_COMMAND, void 0);
|
|
6115
6411
|
break;
|
|
6116
6412
|
case "page-break":
|
|
6117
6413
|
editor.dispatchCommand(INSERT_PAGE_BREAK, void 0);
|
|
@@ -6147,12 +6443,7 @@ var ToolBarPlugins = (props) => {
|
|
|
6147
6443
|
"Superscript"
|
|
6148
6444
|
] }),
|
|
6149
6445
|
/* @__PURE__ */ jsxRuntime.jsxs(reactComponents.Option, { value: "highlight", text: "Highlight", children: [
|
|
6150
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6151
|
-
reactIcons.HighlightAccentFilled,
|
|
6152
|
-
{
|
|
6153
|
-
style: { ...optionIconStyle, color: isEditable ? brand : fgDisabled }
|
|
6154
|
-
}
|
|
6155
|
-
),
|
|
6446
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.HighlightAccentFilled, { style: { ...optionIconStyle, color: isEditable ? brand : fgDisabled } }),
|
|
6156
6447
|
"Highlight"
|
|
6157
6448
|
] }),
|
|
6158
6449
|
/* @__PURE__ */ jsxRuntime.jsxs(reactComponents.Option, { value: "ul-list", text: "Bullet list", children: [
|
|
@@ -6188,30 +6479,10 @@ var ToolBarPlugins = (props) => {
|
|
|
6188
6479
|
// );
|
|
6189
6480
|
case "Align": {
|
|
6190
6481
|
const ALIGN_OPTIONS = [
|
|
6191
|
-
{
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
action: "leftAlign" /* LeftAlign */
|
|
6196
|
-
},
|
|
6197
|
-
{
|
|
6198
|
-
value: "center",
|
|
6199
|
-
label: "Center Align",
|
|
6200
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignCenterFilled, { style: optionIconStyle }),
|
|
6201
|
-
action: "centerAlign" /* CenterAlign */
|
|
6202
|
-
},
|
|
6203
|
-
{
|
|
6204
|
-
value: "right",
|
|
6205
|
-
label: "Right Align",
|
|
6206
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignRightFilled, { style: optionIconStyle }),
|
|
6207
|
-
action: "rightAlign" /* RightAlign */
|
|
6208
|
-
},
|
|
6209
|
-
{
|
|
6210
|
-
value: "justify",
|
|
6211
|
-
label: "Justify Align",
|
|
6212
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignJustifyFilled, { style: optionIconStyle }),
|
|
6213
|
-
action: "justifyAlign" /* JustifyAlign */
|
|
6214
|
-
}
|
|
6482
|
+
{ value: "left", label: "Left Align", icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignLeftFilled, { style: optionIconStyle }), action: "leftAlign" /* LeftAlign */ },
|
|
6483
|
+
{ value: "center", label: "Center Align", icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignCenterFilled, { style: optionIconStyle }), action: "centerAlign" /* CenterAlign */ },
|
|
6484
|
+
{ value: "right", label: "Right Align", icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignRightFilled, { style: optionIconStyle }), action: "rightAlign" /* RightAlign */ },
|
|
6485
|
+
{ value: "justify", label: "Justify Align", icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.TextAlignJustifyFilled, { style: optionIconStyle }), action: "justifyAlign" /* JustifyAlign */ }
|
|
6215
6486
|
];
|
|
6216
6487
|
const alignLabel = ALIGN_OPTIONS.find((o) => o.value === alignment)?.label ?? "Left Align";
|
|
6217
6488
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6245,69 +6516,29 @@ var ToolBarPlugins = (props) => {
|
|
|
6245
6516
|
if (!pluginGroups || pluginGroups.length === 0) {
|
|
6246
6517
|
return null;
|
|
6247
6518
|
}
|
|
6248
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
),
|
|
6272
|
-
isInTable && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6273
|
-
"div",
|
|
6274
|
-
{
|
|
6275
|
-
style: {
|
|
6276
|
-
display: "flex",
|
|
6277
|
-
alignItems: "center",
|
|
6278
|
-
gap: 6,
|
|
6279
|
-
padding: "2px 8px",
|
|
6280
|
-
borderBottom: "1px solid #ccced1",
|
|
6281
|
-
background: "#fff8f8"
|
|
6282
|
-
},
|
|
6283
|
-
children: [
|
|
6284
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#888", userSelect: "none" }, children: "Table" }),
|
|
6285
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6286
|
-
reactComponents.Button,
|
|
6287
|
-
{
|
|
6288
|
-
size: "small",
|
|
6289
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons.DeleteRegular, { style: { color: "#c4272c" } }),
|
|
6290
|
-
title: "Delete table",
|
|
6291
|
-
style: {
|
|
6292
|
-
background: "transparent",
|
|
6293
|
-
border: "none",
|
|
6294
|
-
color: "#c4272c",
|
|
6295
|
-
fontWeight: 500
|
|
6296
|
-
},
|
|
6297
|
-
onClick: () => {
|
|
6298
|
-
editor.update(() => {
|
|
6299
|
-
if (!tableNodeKey) return;
|
|
6300
|
-
const node = lexical.$getNodeByKey(tableNodeKey);
|
|
6301
|
-
if (node?.getType() === "table") node.remove();
|
|
6302
|
-
});
|
|
6303
|
-
},
|
|
6304
|
-
children: "Delete Table"
|
|
6305
|
-
}
|
|
6306
|
-
)
|
|
6307
|
-
]
|
|
6308
|
-
}
|
|
6309
|
-
)
|
|
6310
|
-
] });
|
|
6519
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.Stack, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6520
|
+
"div",
|
|
6521
|
+
{
|
|
6522
|
+
role: "toolbar",
|
|
6523
|
+
"aria-label": "Editor toolbar",
|
|
6524
|
+
style: {
|
|
6525
|
+
display: "flex",
|
|
6526
|
+
flexWrap: "wrap",
|
|
6527
|
+
alignItems: "center",
|
|
6528
|
+
borderBottom: "1px solid #ccced1",
|
|
6529
|
+
background: "#ffffff",
|
|
6530
|
+
padding: "0px",
|
|
6531
|
+
minHeight: 36
|
|
6532
|
+
},
|
|
6533
|
+
children: pluginGroups.map((group, groupIndex) => /* @__PURE__ */ jsxRuntime.jsx(React6__namespace.default.Fragment, { children: group.map((token, tokenIndex) => {
|
|
6534
|
+
try {
|
|
6535
|
+
return renderToken(token, groupIndex, tokenIndex);
|
|
6536
|
+
} catch {
|
|
6537
|
+
return null;
|
|
6538
|
+
}
|
|
6539
|
+
}) }, `group-${groupIndex}`))
|
|
6540
|
+
}
|
|
6541
|
+
) });
|
|
6311
6542
|
};
|
|
6312
6543
|
function isYoutubeLikeNode(node) {
|
|
6313
6544
|
try {
|
|
@@ -6460,10 +6691,23 @@ function BrowserSpellCheckPlugin({ enabled }) {
|
|
|
6460
6691
|
function WordCountPlugin({ onCountChange }) {
|
|
6461
6692
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
6462
6693
|
React6.useEffect(() => {
|
|
6463
|
-
return editor.registerUpdateListener(() => {
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6694
|
+
return editor.registerUpdateListener(({ editorState }) => {
|
|
6695
|
+
editorState.read(() => {
|
|
6696
|
+
const text = lexical.$getRoot().getTextContent();
|
|
6697
|
+
const words = text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
|
|
6698
|
+
onCountChange(words);
|
|
6699
|
+
});
|
|
6700
|
+
});
|
|
6701
|
+
}, [editor, onCountChange]);
|
|
6702
|
+
return null;
|
|
6703
|
+
}
|
|
6704
|
+
function CharCountPlugin({ onCountChange }) {
|
|
6705
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
6706
|
+
React6.useEffect(() => {
|
|
6707
|
+
return editor.registerUpdateListener(({ editorState }) => {
|
|
6708
|
+
editorState.read(() => {
|
|
6709
|
+
onCountChange(lexical.$getRoot().getTextContent().length);
|
|
6710
|
+
});
|
|
6467
6711
|
});
|
|
6468
6712
|
}, [editor, onCountChange]);
|
|
6469
6713
|
return null;
|
|
@@ -6613,6 +6857,9 @@ var ContentEditorComponent = React6.forwardRef(
|
|
|
6613
6857
|
const [isLinkEditMode, setIsLinkEditMode] = React6.useState(false);
|
|
6614
6858
|
const [wordCount, setWordCount] = React6.useState(0);
|
|
6615
6859
|
const handleWordCount = React6.useCallback((count) => setWordCount(count), []);
|
|
6860
|
+
const [charCount, setCharCount] = React6.useState(0);
|
|
6861
|
+
const handleCharCount = React6.useCallback((count) => setCharCount(count), []);
|
|
6862
|
+
const [refErrors, setRefErrors] = React6.useState([]);
|
|
6616
6863
|
const contentEditableDomRef = React6.useRef(null);
|
|
6617
6864
|
const previousOverLimitRef = React6.useRef(false);
|
|
6618
6865
|
const focusedRef = React6.useRef(false);
|
|
@@ -6692,7 +6939,41 @@ var ContentEditorComponent = React6.forwardRef(
|
|
|
6692
6939
|
e.stopPropagation();
|
|
6693
6940
|
}
|
|
6694
6941
|
};
|
|
6942
|
+
const [touched, setTouched] = React6.useState(false);
|
|
6695
6943
|
const isOverLimit = props.wordLimit !== void 0 && wordCount > props.wordLimit;
|
|
6944
|
+
const internalErrors = [];
|
|
6945
|
+
if (isOverLimit) {
|
|
6946
|
+
const m = props.errorMessages?.wordLimitExceeded;
|
|
6947
|
+
internalErrors.push(
|
|
6948
|
+
typeof m === "function" ? m(wordCount, props.wordLimit) : m ?? `Word limit exceeded (${wordCount} / ${props.wordLimit} words used)`
|
|
6949
|
+
);
|
|
6950
|
+
}
|
|
6951
|
+
if (props.required && touched && wordCount === 0) {
|
|
6952
|
+
internalErrors.push(
|
|
6953
|
+
props.errorMessages?.required ?? "This field is required"
|
|
6954
|
+
);
|
|
6955
|
+
}
|
|
6956
|
+
if (props.minWords !== void 0 && touched && wordCount < props.minWords) {
|
|
6957
|
+
const m = props.errorMessages?.minWords;
|
|
6958
|
+
internalErrors.push(
|
|
6959
|
+
typeof m === "function" ? m(wordCount, props.minWords) : m ?? `Minimum ${props.minWords} words required (${wordCount} entered)`
|
|
6960
|
+
);
|
|
6961
|
+
}
|
|
6962
|
+
if (props.maxChars !== void 0 && charCount > props.maxChars) {
|
|
6963
|
+
const m = props.errorMessages?.maxCharsExceeded;
|
|
6964
|
+
internalErrors.push(
|
|
6965
|
+
typeof m === "function" ? m(charCount, props.maxChars) : m ?? `Character limit exceeded (${charCount} / ${props.maxChars} characters used)`
|
|
6966
|
+
);
|
|
6967
|
+
}
|
|
6968
|
+
if (props.minChars !== void 0 && touched && charCount < props.minChars && charCount > 0) {
|
|
6969
|
+
const m = props.errorMessages?.minCharsRequired;
|
|
6970
|
+
internalErrors.push(
|
|
6971
|
+
typeof m === "function" ? m(charCount, props.minChars) : m ?? `Minimum ${props.minChars} characters required (${charCount} entered)`
|
|
6972
|
+
);
|
|
6973
|
+
}
|
|
6974
|
+
const allErrors = [...internalErrors, ...props.errors ?? [], ...refErrors];
|
|
6975
|
+
const hasErrors = allErrors.length > 0;
|
|
6976
|
+
const hasRedBorder = hasErrors;
|
|
6696
6977
|
React6.useEffect(() => {
|
|
6697
6978
|
if (props.wordLimit === void 0 || !props.onWordLimitExceeded) return;
|
|
6698
6979
|
const wasOverLimit = previousOverLimitRef.current;
|
|
@@ -6715,7 +6996,7 @@ var ContentEditorComponent = React6.forwardRef(
|
|
|
6715
6996
|
width: props.width ?? "100%",
|
|
6716
6997
|
height: props.height ?? "100%",
|
|
6717
6998
|
margin: props.margin ?? "5px auto",
|
|
6718
|
-
border: `1px solid ${
|
|
6999
|
+
border: `1px solid ${hasRedBorder ? "#c4272c" : "var(--colorNeutralStroke1, #ccced1)"}`,
|
|
6719
7000
|
transition: "border-color 0.2s",
|
|
6720
7001
|
display: "flex",
|
|
6721
7002
|
flexDirection: "column"
|
|
@@ -6745,7 +7026,9 @@ var ContentEditorComponent = React6.forwardRef(
|
|
|
6745
7026
|
position: "relative",
|
|
6746
7027
|
flexGrow: 1,
|
|
6747
7028
|
padding: "15px 0px",
|
|
6748
|
-
overflowY: "scroll"
|
|
7029
|
+
overflowY: "scroll",
|
|
7030
|
+
overflowX: "auto",
|
|
7031
|
+
minWidth: 0
|
|
6749
7032
|
},
|
|
6750
7033
|
onClickCapture: handleReadOnlyClickCapture,
|
|
6751
7034
|
children: [
|
|
@@ -6809,13 +7092,33 @@ var ContentEditorComponent = React6.forwardRef(
|
|
|
6809
7092
|
]
|
|
6810
7093
|
}
|
|
6811
7094
|
),
|
|
7095
|
+
hasErrors && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7096
|
+
"div",
|
|
7097
|
+
{
|
|
7098
|
+
style: {
|
|
7099
|
+
borderTop: "1px solid #fbd5d5",
|
|
7100
|
+
background: "#fff8f8",
|
|
7101
|
+
padding: "6px 12px 8px",
|
|
7102
|
+
display: "flex",
|
|
7103
|
+
flexDirection: "column",
|
|
7104
|
+
gap: 4
|
|
7105
|
+
},
|
|
7106
|
+
children: allErrors.map((err, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
7107
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactIcons.ErrorCircleRegular, { style: { fontSize: 14, color: "#c4272c", flexShrink: 0 } }),
|
|
7108
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#c4272c" }, children: err })
|
|
7109
|
+
] }, i))
|
|
7110
|
+
}
|
|
7111
|
+
),
|
|
6812
7112
|
/* @__PURE__ */ jsxRuntime.jsx(ReadOnlyPlugin, { readonly: isReadOnly }),
|
|
6813
7113
|
/* @__PURE__ */ jsxRuntime.jsx(BrowserSpellCheckPlugin, { enabled: !resolvedSpellCheck }),
|
|
6814
7114
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6815
7115
|
FocusEventsPlugin,
|
|
6816
7116
|
{
|
|
6817
7117
|
onFocus: props.onFocus,
|
|
6818
|
-
onBlur:
|
|
7118
|
+
onBlur: () => {
|
|
7119
|
+
setTouched(true);
|
|
7120
|
+
props.onBlur?.();
|
|
7121
|
+
},
|
|
6819
7122
|
setFocused,
|
|
6820
7123
|
containerRef
|
|
6821
7124
|
}
|
|
@@ -6862,20 +7165,16 @@ var ContentEditorComponent = React6.forwardRef(
|
|
|
6862
7165
|
}
|
|
6863
7166
|
),
|
|
6864
7167
|
!isReadOnly && props.showFloatingToolbar && /* @__PURE__ */ jsxRuntime.jsx(CharacterStylesPopupPlugin, {}),
|
|
6865
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
value: props.value,
|
|
6869
|
-
onChange: props.onChange
|
|
6870
|
-
}
|
|
6871
|
-
),
|
|
6872
|
-
props.wordLimit !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(WordCountPlugin, { onCountChange: handleWordCount }),
|
|
7168
|
+
/* @__PURE__ */ jsxRuntime.jsx(CustomOnChangePlugin, { value: props.value, onChange: props.onChange }),
|
|
7169
|
+
(props.wordLimit !== void 0 || props.required || props.minWords !== void 0) && /* @__PURE__ */ jsxRuntime.jsx(WordCountPlugin, { onCountChange: handleWordCount }),
|
|
7170
|
+
(props.maxChars !== void 0 || props.minChars !== void 0) && /* @__PURE__ */ jsxRuntime.jsx(CharCountPlugin, { onCountChange: handleCharCount }),
|
|
6873
7171
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6874
7172
|
RefApiPlugin,
|
|
6875
7173
|
{
|
|
6876
7174
|
forwardedRef: ref,
|
|
6877
7175
|
contentEditableDomRef,
|
|
6878
|
-
focusedRef
|
|
7176
|
+
focusedRef,
|
|
7177
|
+
setRefErrors
|
|
6879
7178
|
}
|
|
6880
7179
|
)
|
|
6881
7180
|
]
|