@tarviks/lexical-rich-editor 1.2.1 → 1.3.1
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.css +127 -85
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +362 -62
- package/dist/index.d.ts +362 -62
- package/dist/index.js +2185 -1385
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2193 -1394
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5,13 +5,12 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
5
5
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
6
6
|
import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
|
|
7
7
|
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
|
|
8
|
-
import { createCommand, DecoratorNode, COMMAND_PRIORITY_HIGH, TextNode, ElementNode,
|
|
8
|
+
import { createCommand, DecoratorNode, COMMAND_PRIORITY_HIGH, TextNode, ElementNode, SELECTION_CHANGE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, $getSelection, $isRangeSelection, $findMatchingParent, COMMAND_PRIORITY_LOW, KEY_DOWN_COMMAND, $getNodeByKey, $createRangeSelection, $setSelection, $createParagraphNode, $insertNodes, $isRootOrShadowRoot, COMMAND_PRIORITY_EDITOR, PASTE_COMMAND, DRAGSTART_COMMAND, DRAGOVER_COMMAND, DROP_COMMAND, $getRoot, $createTextNode, $isTextNode, $isElementNode, FORMAT_ELEMENT_COMMAND, CLICK_COMMAND, $isNodeSelection, $applyNodeReplacement, FORMAT_TEXT_COMMAND, $isDecoratorNode, $getNearestNodeFromDOMNode, COMMAND_PRIORITY_CRITICAL, REDO_COMMAND, UNDO_COMMAND, getDOMSelection, KEY_ESCAPE_COMMAND, isHTMLElement, getDOMSelectionFromTarget, $isLineBreakNode, SKIP_SELECTION_FOCUS_TAG, createEditor, KEY_ENTER_COMMAND } from 'lexical';
|
|
9
9
|
import { mergeStyleSets, Stack, css, useTheme, Callout, TextField } from '@fluentui/react';
|
|
10
|
-
import { makeStyles, FluentProvider, webLightTheme, Menu, MenuTrigger, MenuPopover, MenuList, MenuGroup, MenuGroupHeader, MenuItem, MenuDivider, Dropdown, Option,
|
|
11
|
-
import { ErrorCircleRegular, ChevronDown12Regular, ArrowUpRegular, RowTripleRegular, ArrowDownRegular, ArrowLeftRegular, ColumnTripleRegular, ArrowRightRegular, DeleteRegular, TextCaseUppercaseFilled, TextCaseLowercaseFilled, TextCaseTitleFilled, TextStrikethroughFilled, TextSubscriptFilled, TextSuperscriptFilled, HighlightAccentFilled, TextBulletListLtrFilled, TextNumberListLtrFilled, DocumentPageBreakRegular, CommentQuoteRegular, AddRegular, TableAddRegular, ImageAddRegular, ImageEditRegular, VideoClipRegular, TextUnderlineFilled, TextItalicFilled, TextBold24Regular, DocumentRegular, TextAlignLeftFilled, TextAlignCenterFilled, TextAlignRightFilled, TextAlignJustifyFilled, AttachFilled, LinkAddRegular, TextColorRegular, PaintBucket16Filled, Dismiss16Regular, Checkmark16Regular, Edit16Regular, Delete16Regular, CodeFilled, LinkFilled } from '@fluentui/react-icons';
|
|
10
|
+
import { makeStyles, FluentProvider, webLightTheme, Menu, MenuTrigger, MenuPopover, MenuList, MenuGroup, MenuGroupHeader, MenuItem, MenuDivider, Dropdown, Option, Button, ToolbarDivider, MenuItemRadio, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, DialogContent, Field, Input, DialogActions, MessageBar, MessageBarBody } from '@fluentui/react-components';
|
|
12
11
|
import { CodeHighlightNode, CodeNode, $isCodeHighlightNode } from '@lexical/code';
|
|
13
12
|
import { LinkNode, AutoLinkNode, $isLinkNode, $isAutoLinkNode, TOGGLE_LINK_COMMAND, $createLinkNode } from '@lexical/link';
|
|
14
|
-
import { ListNode, ListItemNode, $isListNode, REMOVE_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from '@lexical/list';
|
|
13
|
+
import { ListNode, ListItemNode, $isListNode, REMOVE_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, $removeList, $insertList, $isListItemNode } from '@lexical/list';
|
|
15
14
|
import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
|
|
16
15
|
import { createLinkMatcherWithRegExp, AutoLinkPlugin } from '@lexical/react/LexicalAutoLinkPlugin';
|
|
17
16
|
import { LexicalComposer } from '@lexical/react/LexicalComposer';
|
|
@@ -23,9 +22,9 @@ import { ListPlugin } from '@lexical/react/LexicalListPlugin';
|
|
|
23
22
|
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
|
24
23
|
import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
|
|
25
24
|
import { HeadingNode, QuoteNode, $isHeadingNode, $createQuoteNode, $createHeadingNode } from '@lexical/rich-text';
|
|
26
|
-
import { TableNode, TableRowNode, TableCellNode, $isTableSelection, $isTableNode, $isTableCellNode, $insertTableColumnAtSelection, $insertTableRowAtSelection, $deleteTableRowAtSelection, $deleteTableColumnAtSelection,
|
|
27
|
-
import { BlockWithAlignableContents } from '@lexical/react/LexicalBlockWithAlignableContents';
|
|
25
|
+
import { TableNode, TableRowNode, TableCellNode, $isTableSelection, $isTableNode, $isTableCellNode, $insertTableColumnAtSelection, $insertTableRowAtSelection, $deleteTableRowAtSelection, $deleteTableColumnAtSelection, getDOMCellFromTarget, getTableObserverFromTableElement, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $isTableRowNode, $getTableColumnIndexFromTableCellNode, $createTableNodeWithDimensions } from '@lexical/table';
|
|
28
26
|
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
|
|
27
|
+
import { ChevronDown12Regular, ArrowUpRegular, RowTripleRegular, ArrowDownRegular, ArrowLeftRegular, ColumnTripleRegular, ArrowRightRegular, DeleteRegular, TextCaseUppercaseFilled, TextCaseLowercaseFilled, TextCaseTitleFilled, TextStrikethroughFilled, TextSubscriptFilled, TextSuperscriptFilled, HighlightAccentFilled, TextBulletListLtrFilled, TextNumberListLtrFilled, DocumentPageBreakRegular, CommentQuoteRegular, TextUnderlineFilled, TextItalicFilled, TextBold24Regular, DocumentRegular, TextAlignLeftFilled, TextAlignCenterFilled, TextAlignRightFilled, TextAlignJustifyFilled, VideoClipRegular, ImageEditRegular, AttachFilled, ImageAddRegular, TableAddRegular, LinkAddRegular, TextColorRegular, PaintBucket16Filled, DismissRegular, CheckmarkRegular, EditRegular, CodeFilled, LinkFilled, Dismiss16Regular } from '@fluentui/react-icons';
|
|
29
28
|
import { $setBlocksType, $patchStyleText, $isAtNodeEnd, $getSelectionStyleValueForProperty } from '@lexical/selection';
|
|
30
29
|
import { createPortal } from 'react-dom';
|
|
31
30
|
import { $generateNodesFromDOM, $generateHtmlFromNodes } from '@lexical/html';
|
|
@@ -523,17 +522,6 @@ var init_ImageComponent = __esm({
|
|
|
523
522
|
onClick,
|
|
524
523
|
COMMAND_PRIORITY_LOW
|
|
525
524
|
),
|
|
526
|
-
editor.registerCommand(
|
|
527
|
-
DRAGSTART_COMMAND,
|
|
528
|
-
(event) => {
|
|
529
|
-
if (event.target === imageRef.current) {
|
|
530
|
-
event.preventDefault();
|
|
531
|
-
return true;
|
|
532
|
-
}
|
|
533
|
-
return false;
|
|
534
|
-
},
|
|
535
|
-
COMMAND_PRIORITY_LOW
|
|
536
|
-
),
|
|
537
525
|
editor.registerCommand(
|
|
538
526
|
KEY_DELETE_COMMAND,
|
|
539
527
|
$onDelete,
|
|
@@ -591,36 +579,44 @@ var init_ImageComponent = __esm({
|
|
|
591
579
|
const onResizeStart = () => {
|
|
592
580
|
setIsResizing(true);
|
|
593
581
|
};
|
|
594
|
-
const draggable =
|
|
582
|
+
const draggable = !isResizing;
|
|
595
583
|
const isFocused = (isSelected || isResizing) && isEditable;
|
|
596
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxs(
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
584
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxs(
|
|
585
|
+
"div",
|
|
586
|
+
{
|
|
587
|
+
draggable,
|
|
588
|
+
style: { position: "relative", display: "inline-block" },
|
|
589
|
+
children: [
|
|
590
|
+
isLoadError ? /* @__PURE__ */ jsx(BrokenImage, {}) : /* @__PURE__ */ jsx(
|
|
591
|
+
LazyImage,
|
|
592
|
+
{
|
|
593
|
+
className: isFocused ? `focused ${$isNodeSelection(selection) ? "draggable" : ""}` : null,
|
|
594
|
+
src,
|
|
595
|
+
altText,
|
|
596
|
+
imageRef,
|
|
597
|
+
width,
|
|
598
|
+
height,
|
|
599
|
+
maxWidth,
|
|
600
|
+
onError: () => setIsLoadError(true)
|
|
601
|
+
}
|
|
602
|
+
),
|
|
603
|
+
resizable && $isNodeSelection(selection) && isFocused && /* @__PURE__ */ jsx(
|
|
604
|
+
ImageResizer_default,
|
|
605
|
+
{
|
|
606
|
+
showCaption,
|
|
607
|
+
setShowCaption,
|
|
608
|
+
editor,
|
|
609
|
+
buttonRef,
|
|
610
|
+
imageRef,
|
|
611
|
+
maxWidth,
|
|
612
|
+
onResizeStart,
|
|
613
|
+
onResizeEnd,
|
|
614
|
+
captionsEnabled: !isLoadError && captionsEnabled
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
]
|
|
618
|
+
}
|
|
619
|
+
) });
|
|
624
620
|
};
|
|
625
621
|
ImageComponent_default = ImageComponent;
|
|
626
622
|
}
|
|
@@ -765,9 +761,6 @@ var init_ImageNode = __esm({
|
|
|
765
761
|
const writable = this.getWritable();
|
|
766
762
|
writable.__width = width;
|
|
767
763
|
writable.__height = height;
|
|
768
|
-
if (typeof width === "number" && width > writable.__maxWidth) {
|
|
769
|
-
writable.__maxWidth = width;
|
|
770
|
-
}
|
|
771
764
|
}
|
|
772
765
|
setShowCaption(showCaption) {
|
|
773
766
|
const writable = this.getWritable();
|
|
@@ -894,35 +887,13 @@ var init_InlineImageComponent = __esm({
|
|
|
894
887
|
};
|
|
895
888
|
InlineImageComponent = ({ src, altText, nodeKey, width, height, showCaption, caption, position }) => {
|
|
896
889
|
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
|
|
890
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
897
891
|
const [selection, setSelection] = useState(null);
|
|
898
892
|
const activeEditorRef = useRef(null);
|
|
899
893
|
const imageRef = useRef(null);
|
|
900
894
|
const buttonRef = useRef(null);
|
|
901
895
|
const [editor] = useLexicalComposerContext();
|
|
902
896
|
const isEditable = useLexicalEditable();
|
|
903
|
-
const [isResizing, setIsResizing] = useState(false);
|
|
904
|
-
const onResizeEnd = (nextWidth, nextHeight) => {
|
|
905
|
-
setTimeout(() => {
|
|
906
|
-
setIsResizing(false);
|
|
907
|
-
}, 200);
|
|
908
|
-
editor.update(() => {
|
|
909
|
-
const node = $getNodeByKey(nodeKey);
|
|
910
|
-
if ($isInlineImageNode(node)) {
|
|
911
|
-
node.setWidthAndHeight(nextWidth, nextHeight);
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
};
|
|
915
|
-
const onResizeStart = () => {
|
|
916
|
-
setIsResizing(true);
|
|
917
|
-
};
|
|
918
|
-
const setShowCaption = (show) => {
|
|
919
|
-
editor.update(() => {
|
|
920
|
-
const node = $getNodeByKey(nodeKey);
|
|
921
|
-
if ($isInlineImageNode(node)) {
|
|
922
|
-
node.setShowCaption(show);
|
|
923
|
-
}
|
|
924
|
-
});
|
|
925
|
-
};
|
|
926
897
|
const $onDelete = useCallback(
|
|
927
898
|
(payload) => {
|
|
928
899
|
const deleteSelection = $getSelection();
|
|
@@ -978,6 +949,25 @@ var init_InlineImageComponent = __esm({
|
|
|
978
949
|
},
|
|
979
950
|
[caption, editor, setSelected]
|
|
980
951
|
);
|
|
952
|
+
const onClick = useCallback(
|
|
953
|
+
(payload) => {
|
|
954
|
+
const event = payload;
|
|
955
|
+
if (isResizing) {
|
|
956
|
+
return true;
|
|
957
|
+
}
|
|
958
|
+
if (event.target === imageRef.current) {
|
|
959
|
+
if (event.shiftKey) {
|
|
960
|
+
setSelected(!isSelected);
|
|
961
|
+
} else {
|
|
962
|
+
clearSelection();
|
|
963
|
+
setSelected(true);
|
|
964
|
+
}
|
|
965
|
+
return true;
|
|
966
|
+
}
|
|
967
|
+
return false;
|
|
968
|
+
},
|
|
969
|
+
[isResizing, isSelected, setSelected, clearSelection]
|
|
970
|
+
);
|
|
981
971
|
useEffect(() => {
|
|
982
972
|
let isMounted = true;
|
|
983
973
|
const unregister = mergeRegister(
|
|
@@ -996,51 +986,13 @@ var init_InlineImageComponent = __esm({
|
|
|
996
986
|
),
|
|
997
987
|
editor.registerCommand(
|
|
998
988
|
CLICK_COMMAND,
|
|
999
|
-
|
|
1000
|
-
const event = payload;
|
|
1001
|
-
if (isResizing) {
|
|
1002
|
-
return true;
|
|
1003
|
-
}
|
|
1004
|
-
if (event.target === imageRef.current) {
|
|
1005
|
-
if (event.shiftKey) {
|
|
1006
|
-
setSelected(!isSelected);
|
|
1007
|
-
} else {
|
|
1008
|
-
clearSelection();
|
|
1009
|
-
setSelected(true);
|
|
1010
|
-
}
|
|
1011
|
-
return true;
|
|
1012
|
-
}
|
|
1013
|
-
return false;
|
|
1014
|
-
},
|
|
1015
|
-
COMMAND_PRIORITY_LOW
|
|
1016
|
-
),
|
|
1017
|
-
editor.registerCommand(
|
|
1018
|
-
DRAGSTART_COMMAND,
|
|
1019
|
-
(event) => {
|
|
1020
|
-
if (event.target === imageRef.current) {
|
|
1021
|
-
event.preventDefault();
|
|
1022
|
-
return true;
|
|
1023
|
-
}
|
|
1024
|
-
return false;
|
|
1025
|
-
},
|
|
1026
|
-
COMMAND_PRIORITY_LOW
|
|
1027
|
-
),
|
|
1028
|
-
editor.registerCommand(
|
|
1029
|
-
KEY_DELETE_COMMAND,
|
|
1030
|
-
$onDelete,
|
|
1031
|
-
COMMAND_PRIORITY_LOW
|
|
1032
|
-
),
|
|
1033
|
-
editor.registerCommand(
|
|
1034
|
-
KEY_BACKSPACE_COMMAND,
|
|
1035
|
-
$onDelete,
|
|
989
|
+
onClick,
|
|
1036
990
|
COMMAND_PRIORITY_LOW
|
|
1037
991
|
),
|
|
992
|
+
editor.registerCommand(KEY_DELETE_COMMAND, $onDelete, COMMAND_PRIORITY_LOW),
|
|
993
|
+
editor.registerCommand(KEY_BACKSPACE_COMMAND, $onDelete, COMMAND_PRIORITY_LOW),
|
|
1038
994
|
editor.registerCommand(KEY_ENTER_COMMAND, $onEnter, COMMAND_PRIORITY_LOW),
|
|
1039
|
-
editor.registerCommand(
|
|
1040
|
-
KEY_ESCAPE_COMMAND,
|
|
1041
|
-
$onEscape,
|
|
1042
|
-
COMMAND_PRIORITY_LOW
|
|
1043
|
-
)
|
|
995
|
+
editor.registerCommand(KEY_ESCAPE_COMMAND, $onEscape, COMMAND_PRIORITY_LOW)
|
|
1044
996
|
);
|
|
1045
997
|
return () => {
|
|
1046
998
|
isMounted = false;
|
|
@@ -1055,12 +1007,27 @@ var init_InlineImageComponent = __esm({
|
|
|
1055
1007
|
$onDelete,
|
|
1056
1008
|
$onEnter,
|
|
1057
1009
|
$onEscape,
|
|
1010
|
+
onClick,
|
|
1058
1011
|
setSelected
|
|
1059
1012
|
]);
|
|
1060
|
-
const
|
|
1013
|
+
const onResizeStart = () => {
|
|
1014
|
+
setIsResizing(true);
|
|
1015
|
+
};
|
|
1016
|
+
const onResizeEnd = (nextWidth, nextHeight) => {
|
|
1017
|
+
setTimeout(() => {
|
|
1018
|
+
setIsResizing(false);
|
|
1019
|
+
}, 200);
|
|
1020
|
+
editor.update(() => {
|
|
1021
|
+
const node = $getNodeByKey(nodeKey);
|
|
1022
|
+
if ($isInlineImageNode(node)) {
|
|
1023
|
+
node.setWidthAndHeight(nextWidth, nextHeight);
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
};
|
|
1027
|
+
const draggable = !isResizing;
|
|
1061
1028
|
const isFocused = (isSelected || isResizing) && isEditable;
|
|
1062
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxs(
|
|
1063
|
-
/* @__PURE__ */ jsx(
|
|
1029
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxs("span", { draggable, style: { position: "relative", display: "inline-block" }, children: [
|
|
1030
|
+
/* @__PURE__ */ jsx(
|
|
1064
1031
|
LazyImage2,
|
|
1065
1032
|
{
|
|
1066
1033
|
className: isFocused ? `focused ${$isNodeSelection(selection) ? "draggable" : ""}` : null,
|
|
@@ -1071,18 +1038,19 @@ var init_InlineImageComponent = __esm({
|
|
|
1071
1038
|
height,
|
|
1072
1039
|
position
|
|
1073
1040
|
}
|
|
1074
|
-
)
|
|
1075
|
-
|
|
1041
|
+
),
|
|
1042
|
+
$isNodeSelection(selection) && isFocused && /* @__PURE__ */ jsx(
|
|
1076
1043
|
ImageResizer_default,
|
|
1077
1044
|
{
|
|
1078
|
-
showCaption,
|
|
1079
|
-
setShowCaption
|
|
1045
|
+
showCaption: false,
|
|
1046
|
+
setShowCaption: () => {
|
|
1047
|
+
},
|
|
1048
|
+
captionsEnabled: false,
|
|
1080
1049
|
editor,
|
|
1081
1050
|
buttonRef,
|
|
1082
1051
|
imageRef,
|
|
1083
1052
|
onResizeStart,
|
|
1084
|
-
onResizeEnd
|
|
1085
|
-
captionsEnabled: false
|
|
1053
|
+
onResizeEnd
|
|
1086
1054
|
}
|
|
1087
1055
|
)
|
|
1088
1056
|
] }) });
|
|
@@ -1273,6 +1241,19 @@ var ContentEditorLevel = /* @__PURE__ */ ((ContentEditorLevel2) => {
|
|
|
1273
1241
|
ContentEditorLevel2["Pro"] = "pro";
|
|
1274
1242
|
return ContentEditorLevel2;
|
|
1275
1243
|
})(ContentEditorLevel || {});
|
|
1244
|
+
var DEFAULT_VALIDATION_MESSAGES = {
|
|
1245
|
+
required: "This field is required.",
|
|
1246
|
+
minWords: (current, min) => `Minimum ${min} word${min === 1 ? "" : "s"} required (${current} entered).`,
|
|
1247
|
+
maxWords: (current, max) => `Word limit exceeded: ${current} / ${max} words.`,
|
|
1248
|
+
minChars: (current, min) => `Minimum ${min} character${min === 1 ? "" : "s"} required (${current} entered).`,
|
|
1249
|
+
maxChars: (current, max) => `Character limit exceeded: ${current} / ${max} characters.`,
|
|
1250
|
+
noImages: "Images are not allowed in this field.",
|
|
1251
|
+
maxImages: (current, max) => `Too many images: ${current} / ${max} allowed.`,
|
|
1252
|
+
noLinks: "Hyperlinks are not allowed in this field.",
|
|
1253
|
+
maxLinks: (current, max) => `Too many links: ${current} / ${max} allowed.`,
|
|
1254
|
+
noTables: "Tables are not allowed in this field.",
|
|
1255
|
+
imageTooLarge: (fileMB, maxMB) => `Image size (${fileMB.toFixed(1)} MB) exceeds the ${maxMB} MB limit.`
|
|
1256
|
+
};
|
|
1276
1257
|
|
|
1277
1258
|
// src/Types/PageSetup.ts
|
|
1278
1259
|
var DEFAULT_PAGE_SETUP = {
|
|
@@ -1313,6 +1294,106 @@ function resolvePageCanvasMetrics(value) {
|
|
|
1313
1294
|
paddingPx: Math.round(margin.valueIn * CSS_PX_PER_INCH)
|
|
1314
1295
|
};
|
|
1315
1296
|
}
|
|
1297
|
+
createCommand(
|
|
1298
|
+
"INSERT_ALPHA_LIST_COMMAND"
|
|
1299
|
+
);
|
|
1300
|
+
var AlphaListNode = class _AlphaListNode extends ListNode {
|
|
1301
|
+
static getType() {
|
|
1302
|
+
return "alpha-list";
|
|
1303
|
+
}
|
|
1304
|
+
static clone(node) {
|
|
1305
|
+
return new _AlphaListNode(node.getStart(), node.__key);
|
|
1306
|
+
}
|
|
1307
|
+
constructor(start = 1, key) {
|
|
1308
|
+
super("number", start, key);
|
|
1309
|
+
this.__listType = "lower-alpha";
|
|
1310
|
+
}
|
|
1311
|
+
createDOM(config, _editor) {
|
|
1312
|
+
const element = document.createElement("ol");
|
|
1313
|
+
element.setAttribute("type", "a");
|
|
1314
|
+
if (this.getStart() !== 1) element.setAttribute("start", String(this.getStart()));
|
|
1315
|
+
element.style.listStyleType = "lower-alpha";
|
|
1316
|
+
const olClass = config.theme?.list?.ol;
|
|
1317
|
+
if (olClass) element.className = olClass;
|
|
1318
|
+
return element;
|
|
1319
|
+
}
|
|
1320
|
+
updateDOM() {
|
|
1321
|
+
return false;
|
|
1322
|
+
}
|
|
1323
|
+
exportDOM(_editor) {
|
|
1324
|
+
const element = document.createElement("ol");
|
|
1325
|
+
element.setAttribute("type", "a");
|
|
1326
|
+
if (this.getStart() !== 1) element.setAttribute("start", String(this.getStart()));
|
|
1327
|
+
element.style.listStyleType = "lower-alpha";
|
|
1328
|
+
return { element };
|
|
1329
|
+
}
|
|
1330
|
+
static importDOM() {
|
|
1331
|
+
return {
|
|
1332
|
+
ol: (domNode) => {
|
|
1333
|
+
if (domNode instanceof HTMLOListElement && (domNode.getAttribute("type") === "a" || domNode.style.listStyleType === "lower-alpha")) {
|
|
1334
|
+
return { conversion: convertAlphaOL, priority: 1 };
|
|
1335
|
+
}
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
exportJSON() {
|
|
1341
|
+
const base = super.exportJSON();
|
|
1342
|
+
return {
|
|
1343
|
+
...base,
|
|
1344
|
+
type: "alpha-list",
|
|
1345
|
+
listType: "lower-alpha",
|
|
1346
|
+
tag: "ol",
|
|
1347
|
+
version: 1,
|
|
1348
|
+
start: this.getStart()
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
static importJSON(serialized) {
|
|
1352
|
+
return new _AlphaListNode(serialized.start ?? 1);
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
function convertAlphaOL(domNode) {
|
|
1356
|
+
const start = domNode instanceof HTMLOListElement ? parseInt(domNode.getAttribute("start") || "1", 10) || 1 : 1;
|
|
1357
|
+
return { node: $createAlphaListNode(start) };
|
|
1358
|
+
}
|
|
1359
|
+
function $createAlphaListNode(start = 1) {
|
|
1360
|
+
return new AlphaListNode(start);
|
|
1361
|
+
}
|
|
1362
|
+
function $isAlphaListNode(node) {
|
|
1363
|
+
return node instanceof AlphaListNode;
|
|
1364
|
+
}
|
|
1365
|
+
function $toggleAlphaList() {
|
|
1366
|
+
const selection = $getSelection();
|
|
1367
|
+
if (!$isRangeSelection(selection)) return;
|
|
1368
|
+
const anchor = selection.anchor.getNode();
|
|
1369
|
+
const currentList = $findMatchingParent$1(anchor, $isListNode);
|
|
1370
|
+
if ($isAlphaListNode(currentList)) {
|
|
1371
|
+
$removeList();
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1374
|
+
$insertList("number");
|
|
1375
|
+
const sel2 = $getSelection();
|
|
1376
|
+
if (!$isRangeSelection(sel2)) return;
|
|
1377
|
+
const newAnchor = sel2.anchor.getNode();
|
|
1378
|
+
const newList = $findMatchingParent$1(newAnchor, (n) => $isListNode(n) && !$isAlphaListNode(n));
|
|
1379
|
+
if (!newList || !$isListNode(newList)) return;
|
|
1380
|
+
const start = newList.getStart();
|
|
1381
|
+
const formatType = typeof newList.getFormatType === "function" ? newList.getFormatType() : void 0;
|
|
1382
|
+
const alpha = $createAlphaListNode(start);
|
|
1383
|
+
for (const child of newList.getChildren()) {
|
|
1384
|
+
alpha.append(child);
|
|
1385
|
+
}
|
|
1386
|
+
newList.replace(alpha);
|
|
1387
|
+
if (formatType && typeof alpha.setFormat === "function") {
|
|
1388
|
+
alpha.setFormat(formatType);
|
|
1389
|
+
}
|
|
1390
|
+
const firstItem = alpha.getFirstChild();
|
|
1391
|
+
if ($isListItemNode(firstItem)) {
|
|
1392
|
+
firstItem.selectStart();
|
|
1393
|
+
} else {
|
|
1394
|
+
alpha.select();
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1316
1397
|
var AutocompleteNode = class _AutocompleteNode extends TextNode {
|
|
1317
1398
|
static getType() {
|
|
1318
1399
|
return "autocomplete";
|
|
@@ -1323,6 +1404,13 @@ var AutocompleteNode = class _AutocompleteNode extends TextNode {
|
|
|
1323
1404
|
static importJSON(serializedNode) {
|
|
1324
1405
|
return new _AutocompleteNode(serializedNode.text, serializedNode.uuid);
|
|
1325
1406
|
}
|
|
1407
|
+
// AutocompleteNode is excluded from copy via excludeFromCopy(), so it is
|
|
1408
|
+
// never placed on the clipboard and never needs to be reconstructed from
|
|
1409
|
+
// HTML. Returning null here satisfies Lexical's exportDOM/importDOM
|
|
1410
|
+
// contract check and silences the console warning.
|
|
1411
|
+
static importDOM() {
|
|
1412
|
+
return null;
|
|
1413
|
+
}
|
|
1326
1414
|
exportJSON() {
|
|
1327
1415
|
return { ...super.exportJSON(), uuid: this.__uuid };
|
|
1328
1416
|
}
|
|
@@ -1637,13 +1725,20 @@ function VideoResizer({
|
|
|
1637
1725
|
const dy = ev.clientY - rs.startY;
|
|
1638
1726
|
let newW = rs.startW;
|
|
1639
1727
|
let newH = rs.startH;
|
|
1640
|
-
if (dir === "se") {
|
|
1728
|
+
if (dir === "se" || dir === "ne") {
|
|
1641
1729
|
newW = Math.max(MIN_WIDTH, rs.startW + dx);
|
|
1642
1730
|
newH = newW / rs.ratio;
|
|
1731
|
+
} else if (dir === "nw" || dir === "sw") {
|
|
1732
|
+
newW = Math.max(MIN_WIDTH, rs.startW - dx);
|
|
1733
|
+
newH = newW / rs.ratio;
|
|
1643
1734
|
} else if (dir === "e") {
|
|
1644
1735
|
newW = Math.max(MIN_WIDTH, rs.startW + dx);
|
|
1736
|
+
} else if (dir === "w") {
|
|
1737
|
+
newW = Math.max(MIN_WIDTH, rs.startW - dx);
|
|
1645
1738
|
} else if (dir === "s") {
|
|
1646
1739
|
newH = Math.max(MIN_HEIGHT, rs.startH + dy);
|
|
1740
|
+
} else if (dir === "n") {
|
|
1741
|
+
newH = Math.max(MIN_HEIGHT, rs.startH - dy);
|
|
1647
1742
|
}
|
|
1648
1743
|
container.style.width = `${newW}px`;
|
|
1649
1744
|
container.style.height = `${newH}px`;
|
|
@@ -1663,13 +1758,23 @@ function VideoResizer({
|
|
|
1663
1758
|
/* @__PURE__ */ jsx(
|
|
1664
1759
|
"div",
|
|
1665
1760
|
{
|
|
1666
|
-
style: {
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1761
|
+
style: { ...handleBase, top: -5, left: "50%", transform: "translateX(-50%)", cursor: "n-resize" },
|
|
1762
|
+
onPointerDown: (e) => startResize(e, "n"),
|
|
1763
|
+
title: "Resize height"
|
|
1764
|
+
}
|
|
1765
|
+
),
|
|
1766
|
+
/* @__PURE__ */ jsx(
|
|
1767
|
+
"div",
|
|
1768
|
+
{
|
|
1769
|
+
style: { ...handleBase, top: -5, right: -5, cursor: "ne-resize" },
|
|
1770
|
+
onPointerDown: (e) => startResize(e, "ne"),
|
|
1771
|
+
title: "Resize (proportional)"
|
|
1772
|
+
}
|
|
1773
|
+
),
|
|
1774
|
+
/* @__PURE__ */ jsx(
|
|
1775
|
+
"div",
|
|
1776
|
+
{
|
|
1777
|
+
style: { ...handleBase, top: "50%", right: -5, transform: "translateY(-50%)", cursor: "ew-resize" },
|
|
1673
1778
|
onPointerDown: (e) => startResize(e, "e"),
|
|
1674
1779
|
title: "Resize width"
|
|
1675
1780
|
}
|
|
@@ -1677,13 +1782,15 @@ function VideoResizer({
|
|
|
1677
1782
|
/* @__PURE__ */ jsx(
|
|
1678
1783
|
"div",
|
|
1679
1784
|
{
|
|
1680
|
-
style: {
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1785
|
+
style: { ...handleBase, bottom: -5, right: -5, cursor: "se-resize" },
|
|
1786
|
+
onPointerDown: (e) => startResize(e, "se"),
|
|
1787
|
+
title: "Resize (proportional)"
|
|
1788
|
+
}
|
|
1789
|
+
),
|
|
1790
|
+
/* @__PURE__ */ jsx(
|
|
1791
|
+
"div",
|
|
1792
|
+
{
|
|
1793
|
+
style: { ...handleBase, bottom: -5, left: "50%", transform: "translateX(-50%)", cursor: "s-resize" },
|
|
1687
1794
|
onPointerDown: (e) => startResize(e, "s"),
|
|
1688
1795
|
title: "Resize height"
|
|
1689
1796
|
}
|
|
@@ -1691,15 +1798,30 @@ function VideoResizer({
|
|
|
1691
1798
|
/* @__PURE__ */ jsx(
|
|
1692
1799
|
"div",
|
|
1693
1800
|
{
|
|
1694
|
-
style: { ...handleBase, bottom: -5,
|
|
1695
|
-
onPointerDown: (e) => startResize(e, "
|
|
1801
|
+
style: { ...handleBase, bottom: -5, left: -5, cursor: "sw-resize" },
|
|
1802
|
+
onPointerDown: (e) => startResize(e, "sw"),
|
|
1803
|
+
title: "Resize (proportional)"
|
|
1804
|
+
}
|
|
1805
|
+
),
|
|
1806
|
+
/* @__PURE__ */ jsx(
|
|
1807
|
+
"div",
|
|
1808
|
+
{
|
|
1809
|
+
style: { ...handleBase, top: "50%", left: -5, transform: "translateY(-50%)", cursor: "ew-resize" },
|
|
1810
|
+
onPointerDown: (e) => startResize(e, "w"),
|
|
1811
|
+
title: "Resize width"
|
|
1812
|
+
}
|
|
1813
|
+
),
|
|
1814
|
+
/* @__PURE__ */ jsx(
|
|
1815
|
+
"div",
|
|
1816
|
+
{
|
|
1817
|
+
style: { ...handleBase, top: -5, left: -5, cursor: "nw-resize" },
|
|
1818
|
+
onPointerDown: (e) => startResize(e, "nw"),
|
|
1696
1819
|
title: "Resize (proportional)"
|
|
1697
1820
|
}
|
|
1698
1821
|
)
|
|
1699
1822
|
] });
|
|
1700
1823
|
}
|
|
1701
1824
|
function YouTubeComponent({
|
|
1702
|
-
className,
|
|
1703
1825
|
format,
|
|
1704
1826
|
nodeKey,
|
|
1705
1827
|
videoID,
|
|
@@ -1707,9 +1829,48 @@ function YouTubeComponent({
|
|
|
1707
1829
|
height,
|
|
1708
1830
|
editor
|
|
1709
1831
|
}) {
|
|
1832
|
+
const wrapperRef = React9.useRef(null);
|
|
1710
1833
|
const containerRef = React9.useRef(null);
|
|
1834
|
+
const iframeRef = React9.useRef(null);
|
|
1835
|
+
const isResizingRef = React9.useRef(false);
|
|
1836
|
+
const [isNodeSelected, setNodeSelected, clearNodeSelection] = useLexicalNodeSelection(nodeKey);
|
|
1711
1837
|
const [isHovered, setIsHovered] = React9.useState(false);
|
|
1712
1838
|
const [isResizing, setIsResizing] = React9.useState(false);
|
|
1839
|
+
const [isPlaying, setIsPlaying] = React9.useState(false);
|
|
1840
|
+
React9.useEffect(() => {
|
|
1841
|
+
return mergeRegister(
|
|
1842
|
+
editor.registerCommand(
|
|
1843
|
+
FORMAT_ELEMENT_COMMAND,
|
|
1844
|
+
(formatType) => {
|
|
1845
|
+
if (isNodeSelected) {
|
|
1846
|
+
editor.update(() => {
|
|
1847
|
+
const node = $getNodeByKey(nodeKey);
|
|
1848
|
+
if ($isYouTubeNode(node)) node.setFormat(formatType);
|
|
1849
|
+
});
|
|
1850
|
+
return true;
|
|
1851
|
+
}
|
|
1852
|
+
return false;
|
|
1853
|
+
},
|
|
1854
|
+
COMMAND_PRIORITY_LOW
|
|
1855
|
+
),
|
|
1856
|
+
// Select this node on click. When the thumbnail is shown the <img> is
|
|
1857
|
+
// in the parent DOM so CLICK_COMMAND fires naturally. When the iframe is
|
|
1858
|
+
// live, clicks land in the iframe's browsing context — the node stays
|
|
1859
|
+
// selected via wrapperRef boundary detection on the wrapper div.
|
|
1860
|
+
editor.registerCommand(
|
|
1861
|
+
CLICK_COMMAND,
|
|
1862
|
+
(event) => {
|
|
1863
|
+
if (wrapperRef.current?.contains(event.target)) {
|
|
1864
|
+
if (!event.shiftKey) clearNodeSelection();
|
|
1865
|
+
setNodeSelected(true);
|
|
1866
|
+
return true;
|
|
1867
|
+
}
|
|
1868
|
+
return false;
|
|
1869
|
+
},
|
|
1870
|
+
COMMAND_PRIORITY_LOW
|
|
1871
|
+
)
|
|
1872
|
+
);
|
|
1873
|
+
}, [editor, isNodeSelected, nodeKey, clearNodeSelection, setNodeSelected]);
|
|
1713
1874
|
const handleDelete = (e) => {
|
|
1714
1875
|
e.preventDefault();
|
|
1715
1876
|
e.stopPropagation();
|
|
@@ -1718,76 +1879,177 @@ function YouTubeComponent({
|
|
|
1718
1879
|
node?.remove();
|
|
1719
1880
|
});
|
|
1720
1881
|
};
|
|
1882
|
+
const handleResizeStart = () => {
|
|
1883
|
+
isResizingRef.current = true;
|
|
1884
|
+
setIsResizing(true);
|
|
1885
|
+
if (iframeRef.current) iframeRef.current.style.pointerEvents = "none";
|
|
1886
|
+
};
|
|
1721
1887
|
const handleResizeEnd = (w, h) => {
|
|
1888
|
+
isResizingRef.current = false;
|
|
1722
1889
|
setIsResizing(false);
|
|
1890
|
+
if (iframeRef.current) iframeRef.current.style.pointerEvents = "";
|
|
1891
|
+
setIsHovered(true);
|
|
1723
1892
|
editor.update(() => {
|
|
1724
1893
|
const node = $getNodeByKey(nodeKey);
|
|
1725
|
-
if ($isYouTubeNode(node))
|
|
1726
|
-
node.setSize(Math.round(w), Math.round(h));
|
|
1727
|
-
}
|
|
1894
|
+
if ($isYouTubeNode(node)) node.setSize(Math.round(w), Math.round(h));
|
|
1728
1895
|
});
|
|
1729
1896
|
};
|
|
1730
|
-
|
|
1897
|
+
const actionBtnStyle = (side) => ({
|
|
1898
|
+
position: "absolute",
|
|
1899
|
+
top: 8,
|
|
1900
|
+
[side]: 8,
|
|
1901
|
+
width: 28,
|
|
1902
|
+
height: 28,
|
|
1903
|
+
borderRadius: "50%",
|
|
1904
|
+
background: "rgba(0,0,0,0.65)",
|
|
1905
|
+
color: "#fff",
|
|
1906
|
+
border: "none",
|
|
1907
|
+
cursor: "pointer",
|
|
1908
|
+
fontSize: side === "right" ? 18 : 14,
|
|
1909
|
+
lineHeight: 1,
|
|
1910
|
+
padding: 0,
|
|
1911
|
+
zIndex: 10,
|
|
1912
|
+
display: "flex",
|
|
1913
|
+
alignItems: "center",
|
|
1914
|
+
justifyContent: "center"
|
|
1915
|
+
});
|
|
1916
|
+
return /* @__PURE__ */ jsx("div", { ref: wrapperRef, style: { display: "block", textAlign: format || void 0 }, children: /* @__PURE__ */ jsxs(
|
|
1731
1917
|
"div",
|
|
1732
1918
|
{
|
|
1733
1919
|
ref: containerRef,
|
|
1734
|
-
style: {
|
|
1920
|
+
style: {
|
|
1921
|
+
position: "relative",
|
|
1922
|
+
display: "inline-block",
|
|
1923
|
+
width,
|
|
1924
|
+
height,
|
|
1925
|
+
lineHeight: 0,
|
|
1926
|
+
outline: isNodeSelected ? "2px solid #0078d4" : void 0,
|
|
1927
|
+
outlineOffset: 2
|
|
1928
|
+
},
|
|
1735
1929
|
onMouseEnter: () => setIsHovered(true),
|
|
1736
1930
|
onMouseLeave: () => {
|
|
1737
|
-
if (!
|
|
1931
|
+
if (!isResizingRef.current) setIsHovered(false);
|
|
1738
1932
|
},
|
|
1739
1933
|
children: [
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
1747
|
-
allowFullScreen: true,
|
|
1748
|
-
title: "YouTube video",
|
|
1749
|
-
style: { display: "block", border: "none", pointerEvents: isResizing ? "none" : "auto" }
|
|
1750
|
-
}
|
|
1751
|
-
),
|
|
1752
|
-
isHovered && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1753
|
-
/* @__PURE__ */ jsx(
|
|
1754
|
-
"button",
|
|
1755
|
-
{
|
|
1756
|
-
type: "button",
|
|
1757
|
-
onClick: handleDelete,
|
|
1758
|
-
title: "Remove video",
|
|
1759
|
-
style: {
|
|
1760
|
-
position: "absolute",
|
|
1761
|
-
top: 8,
|
|
1762
|
-
right: 8,
|
|
1763
|
-
width: 28,
|
|
1764
|
-
height: 28,
|
|
1765
|
-
borderRadius: "50%",
|
|
1766
|
-
background: "rgba(0,0,0,0.65)",
|
|
1767
|
-
color: "#fff",
|
|
1768
|
-
border: "none",
|
|
1769
|
-
cursor: "pointer",
|
|
1770
|
-
fontSize: 18,
|
|
1771
|
-
lineHeight: 1,
|
|
1772
|
-
padding: 0,
|
|
1773
|
-
zIndex: 10,
|
|
1774
|
-
display: "flex",
|
|
1775
|
-
alignItems: "center",
|
|
1776
|
-
justifyContent: "center"
|
|
1777
|
-
},
|
|
1778
|
-
children: "\xD7"
|
|
1779
|
-
}
|
|
1780
|
-
),
|
|
1934
|
+
isPlaying ? (
|
|
1935
|
+
/* ── Playing state ─────────────────────────────────────────────────
|
|
1936
|
+
* Show the real YouTube iframe in-place at the same dimensions.
|
|
1937
|
+
* autoplay=1 starts playback immediately.
|
|
1938
|
+
* pointer-events are set to 'none' during resize (handleResizeStart)
|
|
1939
|
+
* so drag events are not lost to the iframe's browsing context. */
|
|
1781
1940
|
/* @__PURE__ */ jsx(
|
|
1782
|
-
|
|
1941
|
+
"iframe",
|
|
1783
1942
|
{
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1943
|
+
ref: iframeRef,
|
|
1944
|
+
width: "100%",
|
|
1945
|
+
height: "100%",
|
|
1946
|
+
src: `https://www.youtube.com/embed/${videoID}?autoplay=1`,
|
|
1947
|
+
sandbox: "allow-same-origin allow-scripts allow-popups allow-presentation",
|
|
1948
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
1949
|
+
allowFullScreen: true,
|
|
1950
|
+
title: "YouTube video",
|
|
1951
|
+
style: { display: "block", border: "none" }
|
|
1787
1952
|
}
|
|
1788
1953
|
)
|
|
1789
|
-
|
|
1790
|
-
|
|
1954
|
+
) : (
|
|
1955
|
+
/* ── Thumbnail state ───────────────────────────────────────────────
|
|
1956
|
+
* Static <img> keeps all clicks in the parent DOM so Lexical's
|
|
1957
|
+
* CLICK_COMMAND fires correctly and the node can be selected.
|
|
1958
|
+
* Clicking the red ▶ badge switches to playing state. */
|
|
1959
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1960
|
+
/* @__PURE__ */ jsx(
|
|
1961
|
+
"img",
|
|
1962
|
+
{
|
|
1963
|
+
src: `https://img.youtube.com/vi/${videoID}/hqdefault.jpg`,
|
|
1964
|
+
alt: "YouTube video",
|
|
1965
|
+
draggable: false,
|
|
1966
|
+
style: {
|
|
1967
|
+
width: "100%",
|
|
1968
|
+
height: "100%",
|
|
1969
|
+
objectFit: "cover",
|
|
1970
|
+
display: "block",
|
|
1971
|
+
userSelect: "none",
|
|
1972
|
+
cursor: "pointer"
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
),
|
|
1976
|
+
/* @__PURE__ */ jsx(
|
|
1977
|
+
"div",
|
|
1978
|
+
{
|
|
1979
|
+
role: "button",
|
|
1980
|
+
"aria-label": "Play video",
|
|
1981
|
+
onClick: () => setIsPlaying(true),
|
|
1982
|
+
style: {
|
|
1983
|
+
position: "absolute",
|
|
1984
|
+
top: "50%",
|
|
1985
|
+
left: "50%",
|
|
1986
|
+
transform: "translate(-50%, -50%)",
|
|
1987
|
+
width: 56,
|
|
1988
|
+
height: 56,
|
|
1989
|
+
background: "rgba(255, 0, 0, 0.85)",
|
|
1990
|
+
borderRadius: "50%",
|
|
1991
|
+
display: "flex",
|
|
1992
|
+
alignItems: "center",
|
|
1993
|
+
justifyContent: "center",
|
|
1994
|
+
cursor: "pointer"
|
|
1995
|
+
},
|
|
1996
|
+
children: /* @__PURE__ */ jsx("span", { style: { color: "#fff", fontSize: 20, lineHeight: 1, marginLeft: 5 }, children: "\u25B6" })
|
|
1997
|
+
}
|
|
1998
|
+
)
|
|
1999
|
+
] })
|
|
2000
|
+
),
|
|
2001
|
+
(isHovered || isResizing) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2002
|
+
/* @__PURE__ */ jsx(
|
|
2003
|
+
"button",
|
|
2004
|
+
{
|
|
2005
|
+
type: "button",
|
|
2006
|
+
onClick: handleDelete,
|
|
2007
|
+
title: "Remove video",
|
|
2008
|
+
style: actionBtnStyle("right"),
|
|
2009
|
+
children: "\xD7"
|
|
2010
|
+
}
|
|
2011
|
+
),
|
|
2012
|
+
isPlaying && /* @__PURE__ */ jsx(
|
|
2013
|
+
"button",
|
|
2014
|
+
{
|
|
2015
|
+
type: "button",
|
|
2016
|
+
onClick: (e) => {
|
|
2017
|
+
e.stopPropagation();
|
|
2018
|
+
setIsPlaying(false);
|
|
2019
|
+
},
|
|
2020
|
+
title: "Stop video",
|
|
2021
|
+
style: actionBtnStyle("left"),
|
|
2022
|
+
children: "\u23F9"
|
|
2023
|
+
}
|
|
2024
|
+
),
|
|
2025
|
+
/* @__PURE__ */ jsx(
|
|
2026
|
+
"button",
|
|
2027
|
+
{
|
|
2028
|
+
type: "button",
|
|
2029
|
+
onClick: (e) => {
|
|
2030
|
+
e.stopPropagation();
|
|
2031
|
+
window.open(`https://www.youtube.com/watch?v=${videoID}`, "_blank", "noopener,noreferrer");
|
|
2032
|
+
},
|
|
2033
|
+
title: "Open in browser",
|
|
2034
|
+
style: {
|
|
2035
|
+
...actionBtnStyle("left"),
|
|
2036
|
+
top: isPlaying ? 44 : 8,
|
|
2037
|
+
// stack below stop button when playing
|
|
2038
|
+
fontSize: 13
|
|
2039
|
+
},
|
|
2040
|
+
children: "\u2197"
|
|
2041
|
+
}
|
|
2042
|
+
),
|
|
2043
|
+
/* @__PURE__ */ jsx(
|
|
2044
|
+
VideoResizer,
|
|
2045
|
+
{
|
|
2046
|
+
containerRef,
|
|
2047
|
+
onResizeStart: handleResizeStart,
|
|
2048
|
+
onResizeEnd: handleResizeEnd
|
|
2049
|
+
}
|
|
2050
|
+
)
|
|
2051
|
+
] })
|
|
2052
|
+
]
|
|
1791
2053
|
}
|
|
1792
2054
|
) });
|
|
1793
2055
|
}
|
|
@@ -1843,6 +2105,7 @@ var YouTubeNode = class _YouTubeNode extends DecoratorBlockNode {
|
|
|
1843
2105
|
iframe.setAttribute("width", String(this.__width));
|
|
1844
2106
|
iframe.setAttribute("height", String(this.__height));
|
|
1845
2107
|
iframe.style.border = "none";
|
|
2108
|
+
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-popups allow-presentation");
|
|
1846
2109
|
iframe.setAttribute(
|
|
1847
2110
|
"allow",
|
|
1848
2111
|
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
@@ -1870,16 +2133,10 @@ var YouTubeNode = class _YouTubeNode extends DecoratorBlockNode {
|
|
|
1870
2133
|
writable.__width = width;
|
|
1871
2134
|
writable.__height = height;
|
|
1872
2135
|
}
|
|
1873
|
-
decorate(_editor,
|
|
1874
|
-
const embedBlockTheme = config.theme.embedBlock || {};
|
|
1875
|
-
const className = {
|
|
1876
|
-
base: embedBlockTheme.base || "",
|
|
1877
|
-
focus: embedBlockTheme.focus || ""
|
|
1878
|
-
};
|
|
2136
|
+
decorate(_editor, _config) {
|
|
1879
2137
|
return /* @__PURE__ */ jsx(
|
|
1880
2138
|
YouTubeComponent,
|
|
1881
2139
|
{
|
|
1882
|
-
className,
|
|
1883
2140
|
format: this.__format,
|
|
1884
2141
|
nodeKey: this.getKey(),
|
|
1885
2142
|
videoID: this.__id,
|
|
@@ -2245,12 +2502,12 @@ function useFloatingPortalContainer(editor) {
|
|
|
2245
2502
|
}, [editor]);
|
|
2246
2503
|
return container;
|
|
2247
2504
|
}
|
|
2248
|
-
function setPopupPositionFixed(popupEl, rect) {
|
|
2505
|
+
function setPopupPositionFixed(popupEl, rect, topBoundary) {
|
|
2249
2506
|
const GAP = 8;
|
|
2250
2507
|
const MARGIN = 8;
|
|
2251
2508
|
let top = rect.top - popupEl.offsetHeight - GAP;
|
|
2252
|
-
let left = rect.left
|
|
2253
|
-
if (top <
|
|
2509
|
+
let left = rect.left;
|
|
2510
|
+
if (top < topBoundary) top = rect.bottom + GAP;
|
|
2254
2511
|
left = clamp2(left, MARGIN, window.innerWidth - popupEl.offsetWidth - MARGIN);
|
|
2255
2512
|
popupEl.style.top = `${top}px`;
|
|
2256
2513
|
popupEl.style.left = `${left}px`;
|
|
@@ -2292,10 +2549,22 @@ function FloatingCharacterStylesEditor({
|
|
|
2292
2549
|
popupEl.classList.remove("is-open");
|
|
2293
2550
|
return;
|
|
2294
2551
|
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2552
|
+
let rect;
|
|
2553
|
+
try {
|
|
2554
|
+
const focusRange = document.createRange();
|
|
2555
|
+
focusRange.setStart(sel.focusNode, sel.focusOffset);
|
|
2556
|
+
focusRange.setEnd(sel.focusNode, sel.focusOffset);
|
|
2557
|
+
rect = focusRange.getBoundingClientRect();
|
|
2558
|
+
if (rect.width === 0 && rect.height === 0 && rect.top === 0 && rect.left === 0) {
|
|
2559
|
+
throw new Error("empty focus rect");
|
|
2560
|
+
}
|
|
2561
|
+
} catch {
|
|
2562
|
+
rect = sel.getRangeAt(0).getBoundingClientRect();
|
|
2563
|
+
}
|
|
2564
|
+
const toolbarEl = root?.closest(".lexical-rich-editor-root")?.querySelector(".editor-toolbar-root");
|
|
2565
|
+
const topBoundary = toolbarEl ? toolbarEl.getBoundingClientRect().bottom + 8 : 8;
|
|
2297
2566
|
if (!mouseDownRef.current) {
|
|
2298
|
-
setPopupPositionFixed(popupEl, rect);
|
|
2567
|
+
setPopupPositionFixed(popupEl, rect, topBoundary);
|
|
2299
2568
|
}
|
|
2300
2569
|
popupEl.classList.add("is-open");
|
|
2301
2570
|
}, [editor]);
|
|
@@ -2503,6 +2772,11 @@ function useCharacterStylesPopup(editor, opts) {
|
|
|
2503
2772
|
setIsText(false);
|
|
2504
2773
|
return;
|
|
2505
2774
|
}
|
|
2775
|
+
const activeElement = document.activeElement;
|
|
2776
|
+
if (activeElement && activeElement !== document.body && rootElement && !rootElement.contains(activeElement)) {
|
|
2777
|
+
setIsText(false);
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2506
2780
|
if (!$isRangeSelection(selection)) return;
|
|
2507
2781
|
const node = getSelectedNode(selection);
|
|
2508
2782
|
setIsBold(selection.hasFormat("bold"));
|
|
@@ -2523,7 +2797,11 @@ function useCharacterStylesPopup(editor, opts) {
|
|
|
2523
2797
|
}, [editor]);
|
|
2524
2798
|
useEffect(() => {
|
|
2525
2799
|
document.addEventListener("selectionchange", updatePopupState);
|
|
2526
|
-
|
|
2800
|
+
document.addEventListener("focusin", updatePopupState);
|
|
2801
|
+
return () => {
|
|
2802
|
+
document.removeEventListener("selectionchange", updatePopupState);
|
|
2803
|
+
document.removeEventListener("focusin", updatePopupState);
|
|
2804
|
+
};
|
|
2527
2805
|
}, [updatePopupState]);
|
|
2528
2806
|
useEffect(() => editor.registerUpdateListener(updatePopupState), [editor, updatePopupState]);
|
|
2529
2807
|
if (!portalContainer || !isText || isLink) return null;
|
|
@@ -2781,34 +3059,57 @@ function normalizeToBlockHtml(html) {
|
|
|
2781
3059
|
if (pendingP) body.appendChild(pendingP);
|
|
2782
3060
|
return body.innerHTML;
|
|
2783
3061
|
}
|
|
3062
|
+
function splitHeadingsAtBrSequences(html) {
|
|
3063
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
3064
|
+
const headings = Array.from(doc.querySelectorAll("h1, h2, h3, h4, h5, h6"));
|
|
3065
|
+
headings.forEach((el) => {
|
|
3066
|
+
const inner = el.innerHTML;
|
|
3067
|
+
const SEP = /<br\s*\/?>\s*(?:<br\s*\/?>)+/gi;
|
|
3068
|
+
if (!SEP.test(inner)) return;
|
|
3069
|
+
SEP.lastIndex = 0;
|
|
3070
|
+
const parts = inner.split(SEP).map((p) => p.trim()).filter(Boolean);
|
|
3071
|
+
if (parts.length <= 1) return;
|
|
3072
|
+
const parent = el.parentNode;
|
|
3073
|
+
if (!parent) return;
|
|
3074
|
+
const tagName = el.tagName.toLowerCase();
|
|
3075
|
+
const attrs = Array.from(el.attributes);
|
|
3076
|
+
const fragment = doc.createDocumentFragment();
|
|
3077
|
+
parts.forEach((part) => {
|
|
3078
|
+
const newEl = doc.createElement(tagName);
|
|
3079
|
+
attrs.forEach((a) => newEl.setAttribute(a.name, a.value));
|
|
3080
|
+
newEl.innerHTML = part;
|
|
3081
|
+
fragment.appendChild(newEl);
|
|
3082
|
+
});
|
|
3083
|
+
parent.replaceChild(fragment, el);
|
|
3084
|
+
});
|
|
3085
|
+
return doc.body.innerHTML;
|
|
3086
|
+
}
|
|
2784
3087
|
var CustomOnChangePlugin = ({ value, onChange }) => {
|
|
2785
3088
|
const [editor] = useLexicalComposerContext();
|
|
2786
3089
|
const initializedRef = useRef(false);
|
|
2787
|
-
const onChangeRef = useRef(onChange);
|
|
2788
|
-
onChangeRef.current = onChange;
|
|
2789
3090
|
useEffect(() => {
|
|
2790
3091
|
if (!value || initializedRef.current) return;
|
|
2791
3092
|
initializedRef.current = true;
|
|
2792
3093
|
editor.update(() => {
|
|
2793
3094
|
const root = $getRoot();
|
|
2794
3095
|
root.clear();
|
|
3096
|
+
const safe = sanitizeHtml(value);
|
|
3097
|
+
const cleaned = normalizeToBlockHtml(splitHeadingsAtBrSequences(safe));
|
|
2795
3098
|
const parser = new DOMParser();
|
|
2796
|
-
const dom = parser.parseFromString(
|
|
3099
|
+
const dom = parser.parseFromString(cleaned, "text/html");
|
|
2797
3100
|
const nodes = $generateNodesFromDOM(editor, dom);
|
|
2798
3101
|
root.append(...nodes);
|
|
2799
|
-
$setSelection(null);
|
|
2800
3102
|
});
|
|
2801
3103
|
}, [editor, value]);
|
|
2802
|
-
const handleChange = useCallback((editorState) => {
|
|
2803
|
-
editorState.read(() => {
|
|
2804
|
-
onChangeRef.current(postProcessOutput($generateHtmlFromNodes(editor)));
|
|
2805
|
-
});
|
|
2806
|
-
}, [editor]);
|
|
2807
3104
|
return /* @__PURE__ */ jsx(
|
|
2808
3105
|
OnChangePlugin,
|
|
2809
3106
|
{
|
|
2810
|
-
onChange:
|
|
2811
|
-
|
|
3107
|
+
onChange: (editorState) => {
|
|
3108
|
+
editorState.read(() => {
|
|
3109
|
+
const raw = $generateHtmlFromNodes(editor);
|
|
3110
|
+
onChange(postProcessOutput(splitHeadingsAtBrSequences(raw)));
|
|
3111
|
+
});
|
|
3112
|
+
}
|
|
2812
3113
|
}
|
|
2813
3114
|
);
|
|
2814
3115
|
};
|
|
@@ -2909,7 +3210,7 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
2909
3210
|
setFloatingElemPositionForLinkEditor(domRect, editorElem, anchorElem);
|
|
2910
3211
|
}
|
|
2911
3212
|
setLastSelection(selection);
|
|
2912
|
-
} else if (!activeElement || activeElement.className !== "
|
|
3213
|
+
} else if (!activeElement || activeElement.className !== "aoLinkInput") {
|
|
2913
3214
|
if (rootElement !== null) {
|
|
2914
3215
|
setFloatingElemPositionForLinkEditor(null, editorElem, anchorElem);
|
|
2915
3216
|
}
|
|
@@ -2918,7 +3219,7 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
2918
3219
|
setLinkUrl("");
|
|
2919
3220
|
}
|
|
2920
3221
|
return true;
|
|
2921
|
-
}, [anchorElem, editor,
|
|
3222
|
+
}, [anchorElem, editor, setIsLinkEditMode, isLinkEditMode, isLink, linkUrl]);
|
|
2922
3223
|
useEffect(() => {
|
|
2923
3224
|
const scrollerElem = anchorElem.parentElement;
|
|
2924
3225
|
const update = () => {
|
|
@@ -3010,13 +3311,12 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
3010
3311
|
setIsLinkEditMode(false);
|
|
3011
3312
|
}
|
|
3012
3313
|
};
|
|
3013
|
-
return /* @__PURE__ */ jsx("div", { ref: editorRef, className: "
|
|
3314
|
+
return /* @__PURE__ */ jsx("div", { ref: editorRef, className: "aoLinkEditor", children: !isLink ? null : isLinkEditMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3014
3315
|
/* @__PURE__ */ jsx(
|
|
3015
3316
|
"input",
|
|
3016
3317
|
{
|
|
3017
3318
|
ref: inputRef,
|
|
3018
|
-
className: "
|
|
3019
|
-
placeholder: "https://",
|
|
3319
|
+
className: "aoLinkInput",
|
|
3020
3320
|
value: editedLinkUrl,
|
|
3021
3321
|
onChange: (event) => {
|
|
3022
3322
|
setEditedLinkUrl(event.target.value);
|
|
@@ -3026,35 +3326,37 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
3026
3326
|
}
|
|
3027
3327
|
}
|
|
3028
3328
|
),
|
|
3029
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
3329
|
+
/* @__PURE__ */ jsxs("div", { className: "aoLinkInputActions", children: [
|
|
3030
3330
|
/* @__PURE__ */ jsx(
|
|
3031
|
-
"
|
|
3331
|
+
"div",
|
|
3032
3332
|
{
|
|
3033
|
-
|
|
3034
|
-
|
|
3333
|
+
className: "aoLinkCancel",
|
|
3334
|
+
role: "button",
|
|
3335
|
+
tabIndex: 0,
|
|
3035
3336
|
title: "Cancel",
|
|
3036
3337
|
"aria-label": "Cancel",
|
|
3037
3338
|
onMouseDown: preventDefault,
|
|
3038
3339
|
onClick: () => {
|
|
3039
3340
|
setIsLinkEditMode(false);
|
|
3040
3341
|
},
|
|
3041
|
-
children: /* @__PURE__ */ jsx(
|
|
3342
|
+
children: /* @__PURE__ */ jsx(DismissRegular, { fontSize: 16 })
|
|
3042
3343
|
}
|
|
3043
3344
|
),
|
|
3044
3345
|
/* @__PURE__ */ jsx(
|
|
3045
|
-
"
|
|
3346
|
+
"div",
|
|
3046
3347
|
{
|
|
3047
|
-
|
|
3048
|
-
|
|
3348
|
+
className: "aoLinkConfirm",
|
|
3349
|
+
role: "button",
|
|
3350
|
+
tabIndex: 0,
|
|
3049
3351
|
title: "Confirm",
|
|
3050
3352
|
"aria-label": "Confirm",
|
|
3051
3353
|
onMouseDown: preventDefault,
|
|
3052
3354
|
onClick: handleLinkSubmission,
|
|
3053
|
-
children: /* @__PURE__ */ jsx(
|
|
3355
|
+
children: /* @__PURE__ */ jsx(CheckmarkRegular, { fontSize: 16 })
|
|
3054
3356
|
}
|
|
3055
3357
|
)
|
|
3056
3358
|
] })
|
|
3057
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "
|
|
3359
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "aoLinkView", children: [
|
|
3058
3360
|
/* @__PURE__ */ jsx(
|
|
3059
3361
|
"a",
|
|
3060
3362
|
{
|
|
@@ -3064,38 +3366,38 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
3064
3366
|
children: linkUrl
|
|
3065
3367
|
}
|
|
3066
3368
|
),
|
|
3067
|
-
/* @__PURE__ */
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
}
|
|
3097
|
-
|
|
3098
|
-
|
|
3369
|
+
/* @__PURE__ */ jsx(
|
|
3370
|
+
"div",
|
|
3371
|
+
{
|
|
3372
|
+
className: "aoLinkEdit",
|
|
3373
|
+
role: "button",
|
|
3374
|
+
tabIndex: 0,
|
|
3375
|
+
title: "Edit link",
|
|
3376
|
+
"aria-label": "Edit link",
|
|
3377
|
+
onMouseDown: preventDefault,
|
|
3378
|
+
onClick: (event) => {
|
|
3379
|
+
event.preventDefault();
|
|
3380
|
+
setEditedLinkUrl(linkUrl);
|
|
3381
|
+
setIsLinkEditMode(true);
|
|
3382
|
+
},
|
|
3383
|
+
children: /* @__PURE__ */ jsx(EditRegular, { fontSize: 16 })
|
|
3384
|
+
}
|
|
3385
|
+
),
|
|
3386
|
+
/* @__PURE__ */ jsx(
|
|
3387
|
+
"div",
|
|
3388
|
+
{
|
|
3389
|
+
className: "aoLinkTrash",
|
|
3390
|
+
role: "button",
|
|
3391
|
+
tabIndex: 0,
|
|
3392
|
+
title: "Remove link",
|
|
3393
|
+
"aria-label": "Remove link",
|
|
3394
|
+
onMouseDown: preventDefault,
|
|
3395
|
+
onClick: () => {
|
|
3396
|
+
editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
|
|
3397
|
+
},
|
|
3398
|
+
children: /* @__PURE__ */ jsx(DeleteRegular, { fontSize: 16 })
|
|
3399
|
+
}
|
|
3400
|
+
)
|
|
3099
3401
|
] }) });
|
|
3100
3402
|
};
|
|
3101
3403
|
var useFloatingLinkEditorToolbar = (editor, anchorElem, isLinkEditMode, setIsLinkEditMode) => {
|
|
@@ -3176,8 +3478,6 @@ var FloatingLinkEditorPlugin = ({ anchorElem, isLinkEditMode, setIsLinkEditMode
|
|
|
3176
3478
|
setIsLinkEditMode
|
|
3177
3479
|
);
|
|
3178
3480
|
};
|
|
3179
|
-
|
|
3180
|
-
// src/Plugins/ImagePlugin.tsx
|
|
3181
3481
|
init_ImageNode();
|
|
3182
3482
|
var INSERT_IMAGE_COMMAND = createCommand("INSERT_IMAGE_COMMAND");
|
|
3183
3483
|
var readClipboardImageAsDataURL = async (event) => {
|
|
@@ -3196,28 +3496,77 @@ var readClipboardImageAsDataURL = async (event) => {
|
|
|
3196
3496
|
}
|
|
3197
3497
|
return null;
|
|
3198
3498
|
};
|
|
3499
|
+
var InsertImageByURL = ({
|
|
3500
|
+
setIsOpen,
|
|
3501
|
+
onClick,
|
|
3502
|
+
disabled
|
|
3503
|
+
}) => {
|
|
3504
|
+
const [altText, setAltText] = useState("");
|
|
3505
|
+
const [src, setSrc] = useState("");
|
|
3506
|
+
const isDisabled = disabled || src === "";
|
|
3507
|
+
return /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 6, padding: "10px 0px 0px 0px" }, children: [
|
|
3508
|
+
/* @__PURE__ */ jsx(Field, { label: "Enter URL", size: "small", children: /* @__PURE__ */ jsx(
|
|
3509
|
+
Input,
|
|
3510
|
+
{
|
|
3511
|
+
autoFocus: !disabled,
|
|
3512
|
+
appearance: "underline",
|
|
3513
|
+
placeholder: "Add URL",
|
|
3514
|
+
disabled,
|
|
3515
|
+
onChange: (_, v) => setSrc(v.value),
|
|
3516
|
+
value: src
|
|
3517
|
+
}
|
|
3518
|
+
) }),
|
|
3519
|
+
/* @__PURE__ */ jsx(Field, { label: "Alt Text", size: "small", children: /* @__PURE__ */ jsx(
|
|
3520
|
+
Input,
|
|
3521
|
+
{
|
|
3522
|
+
placeholder: "Alt text",
|
|
3523
|
+
disabled,
|
|
3524
|
+
onChange: (_, v) => setAltText(v.value),
|
|
3525
|
+
value: altText
|
|
3526
|
+
},
|
|
3527
|
+
"alt-text-url"
|
|
3528
|
+
) }),
|
|
3529
|
+
/* @__PURE__ */ jsxs(Stack, { horizontal: true, horizontalAlign: "end", tokens: { childrenGap: 6 }, children: [
|
|
3530
|
+
/* @__PURE__ */ jsx(
|
|
3531
|
+
Button,
|
|
3532
|
+
{
|
|
3533
|
+
style: { width: "150px" },
|
|
3534
|
+
onClick: () => !disabled && onClick({ altText, src }),
|
|
3535
|
+
disabled: isDisabled,
|
|
3536
|
+
size: "small",
|
|
3537
|
+
children: "Confirm"
|
|
3538
|
+
},
|
|
3539
|
+
"url-confirm-btn"
|
|
3540
|
+
),
|
|
3541
|
+
/* @__PURE__ */ jsx(
|
|
3542
|
+
Button,
|
|
3543
|
+
{
|
|
3544
|
+
style: { width: "150px" },
|
|
3545
|
+
onClick: () => setIsOpen(false),
|
|
3546
|
+
disabled,
|
|
3547
|
+
size: "small",
|
|
3548
|
+
children: "Cancel"
|
|
3549
|
+
},
|
|
3550
|
+
"file-url-cancel"
|
|
3551
|
+
)
|
|
3552
|
+
] })
|
|
3553
|
+
] });
|
|
3554
|
+
};
|
|
3199
3555
|
var InsertImageDialog = ({
|
|
3200
3556
|
activeEditor,
|
|
3201
3557
|
disabled,
|
|
3202
|
-
|
|
3203
|
-
|
|
3558
|
+
maxImageSizeMB,
|
|
3559
|
+
validationMessages
|
|
3204
3560
|
}) => {
|
|
3205
3561
|
const [src, setSrc] = useState("");
|
|
3206
3562
|
const [altText, setAltText] = useState("");
|
|
3207
|
-
const [
|
|
3563
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
3564
|
+
const [selectedValue, setSelectedValue] = useState("Upload");
|
|
3208
3565
|
const [fileName, setFileName] = useState("");
|
|
3566
|
+
const [fileSizeError, setFileSizeError] = useState(null);
|
|
3209
3567
|
const hasModifier = useRef(false);
|
|
3210
3568
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
3211
|
-
const
|
|
3212
|
-
const isOpen = isControlled ? !!externalOpen && !disabled : internalOpen && !disabled;
|
|
3213
|
-
const isAddDisabled = disabled || src === "";
|
|
3214
|
-
const handleClose = () => {
|
|
3215
|
-
setSrc("");
|
|
3216
|
-
setAltText("");
|
|
3217
|
-
setFileName("");
|
|
3218
|
-
if (isControlled) onClose?.();
|
|
3219
|
-
else setInternalOpen(false);
|
|
3220
|
-
};
|
|
3569
|
+
const isDisabled = disabled || src === "" || !!fileSizeError;
|
|
3221
3570
|
useEffect(() => {
|
|
3222
3571
|
hasModifier.current = false;
|
|
3223
3572
|
const handler = (e) => {
|
|
@@ -3229,57 +3578,75 @@ var InsertImageDialog = ({
|
|
|
3229
3578
|
const onClick = (payload) => {
|
|
3230
3579
|
if (disabled) return;
|
|
3231
3580
|
activeEditor.dispatchCommand(INSERT_IMAGE_COMMAND, payload);
|
|
3232
|
-
|
|
3581
|
+
setIsOpen(false);
|
|
3582
|
+
setAltText("");
|
|
3583
|
+
setSrc("");
|
|
3584
|
+
setFileName("");
|
|
3585
|
+
setFileSizeError(null);
|
|
3233
3586
|
};
|
|
3234
3587
|
const loadImage = (event) => {
|
|
3235
3588
|
if (disabled) return;
|
|
3236
3589
|
const files = event.target.files;
|
|
3237
3590
|
if (!files || files.length === 0) return;
|
|
3591
|
+
const file = files[0];
|
|
3592
|
+
if (maxImageSizeMB !== void 0) {
|
|
3593
|
+
const fileMB = file.size / (1024 * 1024);
|
|
3594
|
+
if (fileMB > maxImageSizeMB) {
|
|
3595
|
+
const override = validationMessages?.imageTooLarge;
|
|
3596
|
+
const msg = override !== void 0 ? typeof override === "function" ? override(fileMB, maxImageSizeMB) : override : DEFAULT_VALIDATION_MESSAGES.imageTooLarge(fileMB, maxImageSizeMB);
|
|
3597
|
+
setFileSizeError(msg);
|
|
3598
|
+
setSrc("");
|
|
3599
|
+
setFileName("");
|
|
3600
|
+
event.target.value = "";
|
|
3601
|
+
return;
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
setFileSizeError(null);
|
|
3238
3605
|
const reader = new FileReader();
|
|
3239
3606
|
reader.onload = () => {
|
|
3240
3607
|
if (typeof reader.result === "string") {
|
|
3241
3608
|
setSrc(reader.result);
|
|
3242
|
-
setFileName(
|
|
3609
|
+
setFileName(file.name);
|
|
3243
3610
|
}
|
|
3244
3611
|
};
|
|
3245
|
-
reader.readAsDataURL(
|
|
3612
|
+
reader.readAsDataURL(file);
|
|
3246
3613
|
};
|
|
3247
|
-
return /* @__PURE__ */ jsxs(
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
disabled,
|
|
3254
|
-
icon: /* @__PURE__ */ jsx(ImageAddRegular, { style: { color: iconColor } }),
|
|
3255
|
-
style: {
|
|
3256
|
-
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
3257
|
-
border: "none",
|
|
3258
|
-
margin: 2,
|
|
3259
|
-
opacity: disabled ? 0.55 : 1,
|
|
3260
|
-
cursor: disabled ? "not-allowed" : "pointer"
|
|
3261
|
-
},
|
|
3262
|
-
onClick: () => {
|
|
3263
|
-
if (disabled) return;
|
|
3264
|
-
setSrc("");
|
|
3265
|
-
setAltText("");
|
|
3266
|
-
setFileName("");
|
|
3267
|
-
setInternalOpen(true);
|
|
3268
|
-
}
|
|
3614
|
+
return /* @__PURE__ */ jsxs(
|
|
3615
|
+
Dialog,
|
|
3616
|
+
{
|
|
3617
|
+
open: disabled ? false : isOpen,
|
|
3618
|
+
onOpenChange: (_, data) => {
|
|
3619
|
+
if (!disabled) setIsOpen(data.open);
|
|
3269
3620
|
},
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3621
|
+
children: [
|
|
3622
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
3623
|
+
Button,
|
|
3624
|
+
{
|
|
3625
|
+
size: "small",
|
|
3626
|
+
title: "Add Image",
|
|
3627
|
+
disabled,
|
|
3628
|
+
icon: /* @__PURE__ */ jsx(ImageAddRegular, { style: { color: iconColor } }),
|
|
3629
|
+
style: {
|
|
3630
|
+
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
3631
|
+
border: "none",
|
|
3632
|
+
margin: 2,
|
|
3633
|
+
opacity: disabled ? 0.55 : 1,
|
|
3634
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
3635
|
+
},
|
|
3636
|
+
onClick: () => {
|
|
3637
|
+
if (disabled) return;
|
|
3638
|
+
setIsOpen((prev) => !prev);
|
|
3639
|
+
setSrc("");
|
|
3640
|
+
setAltText("");
|
|
3641
|
+
setFileName("");
|
|
3642
|
+
}
|
|
3643
|
+
},
|
|
3644
|
+
"upload-image"
|
|
3645
|
+
) }),
|
|
3646
|
+
/* @__PURE__ */ jsx(DialogSurface, { style: { maxWidth: 340 }, children: /* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
3647
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Insert image" }),
|
|
3648
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 8 }, children: [
|
|
3649
|
+
/* @__PURE__ */ jsx(Field, { label: "Upload", size: "small", children: /* @__PURE__ */ jsxs(
|
|
3283
3650
|
"label",
|
|
3284
3651
|
{
|
|
3285
3652
|
style: {
|
|
@@ -3318,7 +3685,8 @@ var InsertImageDialog = ({
|
|
|
3318
3685
|
]
|
|
3319
3686
|
}
|
|
3320
3687
|
) }),
|
|
3321
|
-
/* @__PURE__ */ jsx(
|
|
3688
|
+
fileSizeError && /* @__PURE__ */ jsx(MessageBar, { intent: "error", style: { marginTop: 4 }, children: /* @__PURE__ */ jsx(MessageBarBody, { children: fileSizeError }) }),
|
|
3689
|
+
/* @__PURE__ */ jsx(Field, { label: "Alt Text", size: "small", children: /* @__PURE__ */ jsx(
|
|
3322
3690
|
Input,
|
|
3323
3691
|
{
|
|
3324
3692
|
placeholder: "Alt text",
|
|
@@ -3327,25 +3695,24 @@ var InsertImageDialog = ({
|
|
|
3327
3695
|
onChange: (_, d) => setAltText(d.value),
|
|
3328
3696
|
value: altText
|
|
3329
3697
|
}
|
|
3330
|
-
) })
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
/* @__PURE__ */ jsx(
|
|
3334
|
-
Button,
|
|
3698
|
+
) }),
|
|
3699
|
+
selectedValue === "URL" && /* @__PURE__ */ jsx(
|
|
3700
|
+
InsertImageByURL,
|
|
3335
3701
|
{
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
onClick: () => onClick({ altText, src }),
|
|
3340
|
-
children: "Add"
|
|
3702
|
+
disabled,
|
|
3703
|
+
setIsOpen: (open) => setIsOpen(open),
|
|
3704
|
+
onClick: (payload) => onClick(payload)
|
|
3341
3705
|
}
|
|
3342
|
-
)
|
|
3343
|
-
|
|
3706
|
+
)
|
|
3707
|
+
] }) }),
|
|
3708
|
+
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
3709
|
+
/* @__PURE__ */ jsx(Button, { size: "small", disabled: isDisabled, onClick: () => onClick({ altText, src }), children: "Add" }),
|
|
3710
|
+
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
3344
3711
|
] })
|
|
3345
3712
|
] }) })
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3713
|
+
]
|
|
3714
|
+
}
|
|
3715
|
+
);
|
|
3349
3716
|
};
|
|
3350
3717
|
var ImagesPlugin = ({ captionsEnabled }) => {
|
|
3351
3718
|
const [editor] = useLexicalComposerContext();
|
|
@@ -3358,9 +3725,21 @@ var ImagesPlugin = ({ captionsEnabled }) => {
|
|
|
3358
3725
|
INSERT_IMAGE_COMMAND,
|
|
3359
3726
|
(payload) => {
|
|
3360
3727
|
const imageNode = $createImageNode(payload);
|
|
3361
|
-
$
|
|
3362
|
-
if ($
|
|
3363
|
-
|
|
3728
|
+
const selection = $getSelection();
|
|
3729
|
+
if ($isRangeSelection(selection)) {
|
|
3730
|
+
const anchorNode = selection.anchor.getNode();
|
|
3731
|
+
const topLevel = anchorNode.getTopLevelElementOrThrow();
|
|
3732
|
+
const imageParagraph = $createParagraphNode();
|
|
3733
|
+
imageParagraph.append(imageNode);
|
|
3734
|
+
topLevel.insertAfter(imageParagraph);
|
|
3735
|
+
const tail = $createParagraphNode();
|
|
3736
|
+
imageParagraph.insertAfter(tail);
|
|
3737
|
+
tail.select();
|
|
3738
|
+
} else {
|
|
3739
|
+
$insertNodes([imageNode]);
|
|
3740
|
+
if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) {
|
|
3741
|
+
$wrapNodeInElement(imageNode, $createParagraphNode).selectEnd();
|
|
3742
|
+
}
|
|
3364
3743
|
}
|
|
3365
3744
|
return true;
|
|
3366
3745
|
},
|
|
@@ -3411,12 +3790,25 @@ var TRANSPARENT_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAA
|
|
|
3411
3790
|
var img = document.createElement("img");
|
|
3412
3791
|
img.src = TRANSPARENT_IMAGE;
|
|
3413
3792
|
var $onDragStart = (event) => {
|
|
3414
|
-
|
|
3793
|
+
let node = $getImageNodeInSelection();
|
|
3794
|
+
if (!node) {
|
|
3795
|
+
const target = event.target;
|
|
3796
|
+
if (!target) return false;
|
|
3797
|
+
const lexicalNode = $getNearestNodeFromDOMNode(target);
|
|
3798
|
+
if ($isImageNode(lexicalNode)) {
|
|
3799
|
+
node = lexicalNode;
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3415
3802
|
if (!node) return false;
|
|
3416
3803
|
const dataTransfer = event.dataTransfer;
|
|
3417
3804
|
if (!dataTransfer) return false;
|
|
3805
|
+
const imgEl = event.target?.closest?.("span.editor-image")?.querySelector?.("img") ?? event.target;
|
|
3806
|
+
if (imgEl instanceof HTMLElement) {
|
|
3807
|
+
dataTransfer.setDragImage(imgEl, 20, 20);
|
|
3808
|
+
} else {
|
|
3809
|
+
dataTransfer.setDragImage(img, 0, 0);
|
|
3810
|
+
}
|
|
3418
3811
|
dataTransfer.setData("text/plain", "_");
|
|
3419
|
-
dataTransfer.setDragImage(img, 0, 0);
|
|
3420
3812
|
dataTransfer.setData(
|
|
3421
3813
|
"application/x-lexical-drag",
|
|
3422
3814
|
JSON.stringify({
|
|
@@ -3444,20 +3836,23 @@ var $onDragover = (event) => {
|
|
|
3444
3836
|
return true;
|
|
3445
3837
|
};
|
|
3446
3838
|
var $onDrop = (event, editor) => {
|
|
3447
|
-
const node = $getImageNodeInSelection();
|
|
3448
|
-
if (!node) return false;
|
|
3449
3839
|
const data = getDragImageData(event);
|
|
3450
3840
|
if (!data) return false;
|
|
3451
3841
|
event.preventDefault();
|
|
3452
3842
|
if (canDropImage(event)) {
|
|
3843
|
+
const sourceKey = data.key;
|
|
3844
|
+
if (sourceKey) {
|
|
3845
|
+
const sourceNode = $getNodeByKey(sourceKey);
|
|
3846
|
+
if (sourceNode) sourceNode.remove();
|
|
3847
|
+
}
|
|
3453
3848
|
const range = getDragSelection(event);
|
|
3454
|
-
node.remove();
|
|
3455
3849
|
const rangeSelection = $createRangeSelection();
|
|
3456
3850
|
if (range !== null && range !== void 0) {
|
|
3457
3851
|
rangeSelection.applyDOMRange(range);
|
|
3458
3852
|
}
|
|
3459
3853
|
$setSelection(rangeSelection);
|
|
3460
|
-
|
|
3854
|
+
const { key: _key, ...insertPayload } = data;
|
|
3855
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, insertPayload);
|
|
3461
3856
|
}
|
|
3462
3857
|
return true;
|
|
3463
3858
|
};
|
|
@@ -3477,7 +3872,7 @@ var getDragImageData = (event) => {
|
|
|
3477
3872
|
};
|
|
3478
3873
|
var canDropImage = (event) => {
|
|
3479
3874
|
const target = event.target;
|
|
3480
|
-
return !!(isHTMLElement(target) && !target.closest("code, span.editor-image") &&
|
|
3875
|
+
return !!(isHTMLElement(target) && !target.closest("code, span.editor-image") && target.closest('[contenteditable="true"]'));
|
|
3481
3876
|
};
|
|
3482
3877
|
var getDragSelection = (event) => {
|
|
3483
3878
|
let range;
|
|
@@ -3492,8 +3887,6 @@ var getDragSelection = (event) => {
|
|
|
3492
3887
|
}
|
|
3493
3888
|
return range;
|
|
3494
3889
|
};
|
|
3495
|
-
|
|
3496
|
-
// src/Plugins/InlineImage.tsx
|
|
3497
3890
|
init_InlineImage();
|
|
3498
3891
|
init_InlineImageNode();
|
|
3499
3892
|
var INSERT_INLINE_IMAGE_COMMAND = createCommand(
|
|
@@ -3512,39 +3905,45 @@ var useStyles = makeStyles({
|
|
|
3512
3905
|
var InsertInlineImageDialog = ({
|
|
3513
3906
|
disabled,
|
|
3514
3907
|
activeEditor,
|
|
3515
|
-
|
|
3516
|
-
|
|
3908
|
+
maxImageSizeMB,
|
|
3909
|
+
validationMessages
|
|
3517
3910
|
}) => {
|
|
3518
3911
|
const hasModifier = useRef(false);
|
|
3519
3912
|
const [src, setSrc] = useState("");
|
|
3520
|
-
const [
|
|
3913
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
3521
3914
|
const [altText, setAltText] = useState("");
|
|
3522
3915
|
const [fileName, setFileName] = useState("");
|
|
3523
3916
|
const [position, setPosition] = useState("left");
|
|
3917
|
+
const [fileSizeError, setFileSizeError] = useState(null);
|
|
3524
3918
|
const styles = useStyles();
|
|
3525
3919
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
3526
|
-
const
|
|
3527
|
-
const isOpen = isControlled ? !!externalOpen && !disabled : internalOpen && !disabled;
|
|
3528
|
-
const isAddDisabled = disabled || src === "";
|
|
3529
|
-
const handleClose = () => {
|
|
3530
|
-
setSrc("");
|
|
3531
|
-
setAltText("");
|
|
3532
|
-
setFileName("");
|
|
3533
|
-
if (isControlled) onClose?.();
|
|
3534
|
-
else setInternalOpen(false);
|
|
3535
|
-
};
|
|
3920
|
+
const isDisabled = disabled || src === "" || !!fileSizeError;
|
|
3536
3921
|
const loadImage = (event) => {
|
|
3537
3922
|
if (disabled) return;
|
|
3538
3923
|
const files = event.target.files;
|
|
3539
3924
|
if (!files || files.length === 0) return;
|
|
3925
|
+
const file = files[0];
|
|
3926
|
+
if (maxImageSizeMB !== void 0) {
|
|
3927
|
+
const fileMB = file.size / (1024 * 1024);
|
|
3928
|
+
if (fileMB > maxImageSizeMB) {
|
|
3929
|
+
const override = validationMessages?.imageTooLarge;
|
|
3930
|
+
const msg = override !== void 0 ? typeof override === "function" ? override(fileMB, maxImageSizeMB) : override : DEFAULT_VALIDATION_MESSAGES.imageTooLarge(fileMB, maxImageSizeMB);
|
|
3931
|
+
setFileSizeError(msg);
|
|
3932
|
+
setSrc("");
|
|
3933
|
+
setFileName("");
|
|
3934
|
+
event.target.value = "";
|
|
3935
|
+
return;
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
setFileSizeError(null);
|
|
3540
3939
|
const reader = new FileReader();
|
|
3541
3940
|
reader.onload = () => {
|
|
3542
3941
|
if (typeof reader.result === "string") {
|
|
3543
3942
|
setSrc(reader.result);
|
|
3544
|
-
setFileName(
|
|
3943
|
+
setFileName(file.name);
|
|
3545
3944
|
}
|
|
3546
3945
|
};
|
|
3547
|
-
reader.readAsDataURL(
|
|
3946
|
+
reader.readAsDataURL(file);
|
|
3548
3947
|
};
|
|
3549
3948
|
useEffect(() => {
|
|
3550
3949
|
const handler = (e) => {
|
|
@@ -3557,44 +3956,48 @@ var InsertInlineImageDialog = ({
|
|
|
3557
3956
|
if (disabled) return;
|
|
3558
3957
|
const payload = { altText, position, src };
|
|
3559
3958
|
activeEditor.dispatchCommand(INSERT_INLINE_IMAGE_COMMAND, payload);
|
|
3560
|
-
|
|
3959
|
+
setIsOpen(false);
|
|
3960
|
+
setAltText("");
|
|
3961
|
+
setSrc("");
|
|
3962
|
+
setFileName("");
|
|
3963
|
+
setFileSizeError(null);
|
|
3561
3964
|
};
|
|
3562
|
-
return /* @__PURE__ */ jsxs(
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
disabled,
|
|
3569
|
-
icon: /* @__PURE__ */ jsx(ImageEditRegular, { style: { color: iconColor } }),
|
|
3570
|
-
style: {
|
|
3571
|
-
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
3572
|
-
border: "none",
|
|
3573
|
-
margin: 2,
|
|
3574
|
-
opacity: disabled ? 0.55 : 1,
|
|
3575
|
-
cursor: disabled ? "not-allowed" : "pointer"
|
|
3576
|
-
},
|
|
3577
|
-
onClick: () => {
|
|
3578
|
-
if (disabled) return;
|
|
3579
|
-
setSrc("");
|
|
3580
|
-
setAltText("");
|
|
3581
|
-
setFileName("");
|
|
3582
|
-
setInternalOpen(true);
|
|
3583
|
-
}
|
|
3965
|
+
return /* @__PURE__ */ jsxs(
|
|
3966
|
+
Dialog,
|
|
3967
|
+
{
|
|
3968
|
+
open: disabled ? false : isOpen,
|
|
3969
|
+
onOpenChange: (_, data) => {
|
|
3970
|
+
if (!disabled) setIsOpen(data.open);
|
|
3584
3971
|
},
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3972
|
+
children: [
|
|
3973
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
3974
|
+
Button,
|
|
3975
|
+
{
|
|
3976
|
+
size: "small",
|
|
3977
|
+
title: "Add Inline Image",
|
|
3978
|
+
disabled,
|
|
3979
|
+
icon: /* @__PURE__ */ jsx(ImageEditRegular, { style: { color: iconColor } }),
|
|
3980
|
+
style: {
|
|
3981
|
+
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
3982
|
+
border: "none",
|
|
3983
|
+
margin: 2,
|
|
3984
|
+
opacity: disabled ? 0.55 : 1,
|
|
3985
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
3986
|
+
},
|
|
3987
|
+
onClick: () => {
|
|
3988
|
+
if (disabled) return;
|
|
3989
|
+
setIsOpen((prev) => !prev);
|
|
3990
|
+
setAltText("");
|
|
3991
|
+
setSrc("");
|
|
3992
|
+
setFileName("");
|
|
3993
|
+
}
|
|
3994
|
+
},
|
|
3995
|
+
"upload-inline-image"
|
|
3996
|
+
) }),
|
|
3997
|
+
/* @__PURE__ */ jsx(DialogSurface, { style: { maxWidth: 360 }, children: /* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
3998
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Insert inline image" }),
|
|
3999
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 8 }, children: [
|
|
4000
|
+
/* @__PURE__ */ jsx(Field, { label: "Upload", size: "small", children: /* @__PURE__ */ jsxs(
|
|
3598
4001
|
"label",
|
|
3599
4002
|
{
|
|
3600
4003
|
style: {
|
|
@@ -3633,22 +4036,25 @@ var InsertInlineImageDialog = ({
|
|
|
3633
4036
|
]
|
|
3634
4037
|
}
|
|
3635
4038
|
) }),
|
|
3636
|
-
/* @__PURE__ */ jsx(Field, { label: "Position",
|
|
4039
|
+
/* @__PURE__ */ jsx(Field, { label: "Position", size: "small", children: /* @__PURE__ */ jsxs(
|
|
3637
4040
|
Dropdown,
|
|
3638
4041
|
{
|
|
3639
|
-
placeholder: "Left Align",
|
|
3640
4042
|
className: styles.alignDropdown,
|
|
3641
4043
|
disabled,
|
|
4044
|
+
value: position === "full" ? "Full" : position === "right" ? "Right" : "Left",
|
|
4045
|
+
selectedOptions: [position ?? "left"],
|
|
3642
4046
|
listbox: { style: { width: "120px" } },
|
|
3643
4047
|
root: { style: { borderBottom: "1px solid black" } },
|
|
4048
|
+
onOptionSelect: (_, data) => setPosition(data.optionValue),
|
|
3644
4049
|
children: [
|
|
3645
|
-
/* @__PURE__ */ jsx(Option, {
|
|
3646
|
-
/* @__PURE__ */ jsx(Option, {
|
|
3647
|
-
/* @__PURE__ */ jsx(Option, {
|
|
4050
|
+
/* @__PURE__ */ jsx(Option, { value: "left", children: "Left" }, "left"),
|
|
4051
|
+
/* @__PURE__ */ jsx(Option, { value: "right", children: "Right" }, "right"),
|
|
4052
|
+
/* @__PURE__ */ jsx(Option, { value: "full", children: "Full" }, "full")
|
|
3648
4053
|
]
|
|
3649
4054
|
}
|
|
3650
4055
|
) }),
|
|
3651
|
-
/* @__PURE__ */ jsx(
|
|
4056
|
+
fileSizeError && /* @__PURE__ */ jsx(MessageBar, { intent: "error", style: { marginTop: 4 }, children: /* @__PURE__ */ jsx(MessageBarBody, { children: fileSizeError }) }),
|
|
4057
|
+
/* @__PURE__ */ jsx(Field, { label: "Alt Text", size: "small", children: /* @__PURE__ */ jsx(
|
|
3652
4058
|
Input,
|
|
3653
4059
|
{
|
|
3654
4060
|
placeholder: "Alt text",
|
|
@@ -3663,9 +4069,8 @@ var InsertInlineImageDialog = ({
|
|
|
3663
4069
|
/* @__PURE__ */ jsx(
|
|
3664
4070
|
Button,
|
|
3665
4071
|
{
|
|
3666
|
-
appearance: "primary",
|
|
3667
4072
|
size: "small",
|
|
3668
|
-
disabled:
|
|
4073
|
+
disabled: isDisabled,
|
|
3669
4074
|
onClick: handleOnClick,
|
|
3670
4075
|
children: "Add"
|
|
3671
4076
|
},
|
|
@@ -3676,16 +4081,16 @@ var InsertInlineImageDialog = ({
|
|
|
3676
4081
|
{
|
|
3677
4082
|
size: "small",
|
|
3678
4083
|
disabled,
|
|
3679
|
-
onClick:
|
|
4084
|
+
onClick: () => setIsOpen(false),
|
|
3680
4085
|
children: "Cancel"
|
|
3681
4086
|
},
|
|
3682
4087
|
"file-inline-upload-cancel"
|
|
3683
4088
|
)
|
|
3684
4089
|
] })
|
|
3685
4090
|
] }) })
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
4091
|
+
]
|
|
4092
|
+
}
|
|
4093
|
+
);
|
|
3689
4094
|
};
|
|
3690
4095
|
var InlineImagePlugin = () => {
|
|
3691
4096
|
const [editor] = useLexicalComposerContext();
|
|
@@ -3702,6 +4107,11 @@ var InlineImagePlugin = () => {
|
|
|
3702
4107
|
if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) {
|
|
3703
4108
|
$wrapNodeInElement(imageNode, $createParagraphNode).selectEnd();
|
|
3704
4109
|
}
|
|
4110
|
+
const parent = imageNode.getParent();
|
|
4111
|
+
if (parent && typeof parent.setFormat === "function") {
|
|
4112
|
+
const fmt = payload.position === "right" ? "right" : payload.position === "full" ? "center" : "left";
|
|
4113
|
+
parent.setFormat(fmt);
|
|
4114
|
+
}
|
|
3705
4115
|
return true;
|
|
3706
4116
|
},
|
|
3707
4117
|
COMMAND_PRIORITY_EDITOR
|
|
@@ -3730,12 +4140,23 @@ var TRANSPARENT_IMAGE2 = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEA
|
|
|
3730
4140
|
var img2 = document.createElement("img");
|
|
3731
4141
|
img2.src = TRANSPARENT_IMAGE2;
|
|
3732
4142
|
function $onDragStart2(event) {
|
|
3733
|
-
|
|
4143
|
+
let node = $getImageNodeInSelection2();
|
|
4144
|
+
if (!node) {
|
|
4145
|
+
const target = event.target;
|
|
4146
|
+
if (!target) return false;
|
|
4147
|
+
const lexicalNode = $getNearestNodeFromDOMNode(target);
|
|
4148
|
+
if ($isInlineImageNode(lexicalNode)) node = lexicalNode;
|
|
4149
|
+
}
|
|
3734
4150
|
if (!node) return false;
|
|
3735
4151
|
const dataTransfer = event.dataTransfer;
|
|
3736
4152
|
if (!dataTransfer) return false;
|
|
3737
|
-
|
|
3738
|
-
|
|
4153
|
+
const imgEl = event.target?.closest?.(".inline-editor-image")?.querySelector?.("img") ?? event.target;
|
|
4154
|
+
if (imgEl instanceof HTMLElement) {
|
|
4155
|
+
dataTransfer.setDragImage(imgEl, 20, 20);
|
|
4156
|
+
} else {
|
|
4157
|
+
dataTransfer.setDragImage(img2, 0, 0);
|
|
4158
|
+
}
|
|
4159
|
+
dataTransfer.setData("text/plain", "_");
|
|
3739
4160
|
dataTransfer.setData(
|
|
3740
4161
|
"application/x-lexical-drag",
|
|
3741
4162
|
JSON.stringify({
|
|
@@ -3754,28 +4175,31 @@ function $onDragStart2(event) {
|
|
|
3754
4175
|
return true;
|
|
3755
4176
|
}
|
|
3756
4177
|
var $onDragover2 = (event) => {
|
|
3757
|
-
const
|
|
3758
|
-
if (!
|
|
4178
|
+
const hasDragData = !!event.dataTransfer?.types.includes("application/x-lexical-drag");
|
|
4179
|
+
if (!hasDragData) return false;
|
|
3759
4180
|
if (!canDropImage2(event)) {
|
|
3760
4181
|
event.preventDefault();
|
|
3761
4182
|
}
|
|
3762
4183
|
return true;
|
|
3763
4184
|
};
|
|
3764
4185
|
var $onDrop2 = (event, editor) => {
|
|
3765
|
-
const node = $getImageNodeInSelection2();
|
|
3766
|
-
if (!node) return false;
|
|
3767
4186
|
const data = getDragImageData2(event);
|
|
3768
4187
|
if (!data) return false;
|
|
3769
4188
|
event.preventDefault();
|
|
3770
4189
|
if (canDropImage2(event)) {
|
|
4190
|
+
const sourceKey = data.key;
|
|
4191
|
+
if (sourceKey) {
|
|
4192
|
+
const sourceNode = $getNodeByKey(sourceKey);
|
|
4193
|
+
if (sourceNode) sourceNode.remove();
|
|
4194
|
+
}
|
|
3771
4195
|
const range = getDragSelection2(event);
|
|
3772
|
-
node.remove();
|
|
3773
4196
|
const rangeSelection = $createRangeSelection();
|
|
3774
4197
|
if (range !== null && range !== void 0) {
|
|
3775
4198
|
rangeSelection.applyDOMRange(range);
|
|
3776
4199
|
}
|
|
3777
4200
|
$setSelection(rangeSelection);
|
|
3778
|
-
|
|
4201
|
+
const { key: _key, ...insertPayload } = data;
|
|
4202
|
+
editor.dispatchCommand(INSERT_INLINE_IMAGE_COMMAND, insertPayload);
|
|
3779
4203
|
}
|
|
3780
4204
|
return true;
|
|
3781
4205
|
};
|
|
@@ -3795,7 +4219,7 @@ var getDragImageData2 = (event) => {
|
|
|
3795
4219
|
};
|
|
3796
4220
|
var canDropImage2 = (event) => {
|
|
3797
4221
|
const target = event.target;
|
|
3798
|
-
return !!(isHTMLElement(target) && !target.closest("code, span.editor-image
|
|
4222
|
+
return !!(isHTMLElement(target) && !target.closest("code, span.editor-image, .inline-editor-image") && target.closest('[contenteditable="true"]'));
|
|
3799
4223
|
};
|
|
3800
4224
|
var getDragSelection2 = (event) => {
|
|
3801
4225
|
let range;
|
|
@@ -3886,20 +4310,79 @@ function hasBlock(editor, kind) {
|
|
|
3886
4310
|
}
|
|
3887
4311
|
|
|
3888
4312
|
// src/Plugins/RefApiPlugin.tsx
|
|
4313
|
+
function getUserContentSignature(editor) {
|
|
4314
|
+
const parts = [];
|
|
4315
|
+
editor.getEditorState().read(() => {
|
|
4316
|
+
const root = $getRoot();
|
|
4317
|
+
const collectNode = (node) => {
|
|
4318
|
+
if ($isHtmlBlockNode(node)) return;
|
|
4319
|
+
if ($isDecoratorNode(node)) {
|
|
4320
|
+
parts.push(`D:${node.getKey()}`);
|
|
4321
|
+
return;
|
|
4322
|
+
}
|
|
4323
|
+
if ($isLineBreakNode(node)) {
|
|
4324
|
+
parts.push("BR");
|
|
4325
|
+
return;
|
|
4326
|
+
}
|
|
4327
|
+
if ($isTextNode(node)) {
|
|
4328
|
+
parts.push(`T${node.getFormat()}:${node.getStyle()}:${node.getTextContent()}`);
|
|
4329
|
+
return;
|
|
4330
|
+
}
|
|
4331
|
+
if ($isElementNode(node)) {
|
|
4332
|
+
const type = node.getType();
|
|
4333
|
+
const tag = typeof node.getTag === "function" ? node.getTag() : "";
|
|
4334
|
+
const list = typeof node.getListType === "function" ? node.getListType() : "";
|
|
4335
|
+
const fmt = typeof node.getFormat === "function" ? node.getFormat() : "";
|
|
4336
|
+
parts.push(`[${type}:${tag}:${list}:${fmt}]`);
|
|
4337
|
+
for (const child of node.getChildren()) {
|
|
4338
|
+
collectNode(child);
|
|
4339
|
+
}
|
|
4340
|
+
parts.push("[/]");
|
|
4341
|
+
}
|
|
4342
|
+
};
|
|
4343
|
+
for (const child of root.getChildren()) {
|
|
4344
|
+
if ($isHtmlBlockNode(child)) continue;
|
|
4345
|
+
collectNode(child);
|
|
4346
|
+
}
|
|
4347
|
+
});
|
|
4348
|
+
return JSON.stringify(parts);
|
|
4349
|
+
}
|
|
3889
4350
|
function RefApiPlugin({
|
|
3890
4351
|
forwardedRef,
|
|
3891
4352
|
contentEditableDomRef,
|
|
3892
|
-
focusedRef
|
|
3893
|
-
setRefErrors
|
|
4353
|
+
focusedRef
|
|
3894
4354
|
}) {
|
|
3895
4355
|
const [editor] = useLexicalComposerContext();
|
|
4356
|
+
const cleanBaselineRef = React9__default.useRef(null);
|
|
4357
|
+
React9__default.useEffect(() => {
|
|
4358
|
+
const capture = () => {
|
|
4359
|
+
if (cleanBaselineRef.current === null) {
|
|
4360
|
+
cleanBaselineRef.current = getUserContentSignature(editor);
|
|
4361
|
+
}
|
|
4362
|
+
};
|
|
4363
|
+
const unregister = editor.registerUpdateListener(({ dirtyElements, dirtyLeaves }) => {
|
|
4364
|
+
if (cleanBaselineRef.current !== null) {
|
|
4365
|
+
unregister();
|
|
4366
|
+
return;
|
|
4367
|
+
}
|
|
4368
|
+
if (dirtyElements.size === 0 && dirtyLeaves.size === 0) return;
|
|
4369
|
+
capture();
|
|
4370
|
+
unregister();
|
|
4371
|
+
});
|
|
4372
|
+
const timerId = setTimeout(capture, 0);
|
|
4373
|
+
return () => {
|
|
4374
|
+
clearTimeout(timerId);
|
|
4375
|
+
unregister();
|
|
4376
|
+
};
|
|
4377
|
+
}, [editor]);
|
|
3896
4378
|
useImperativeHandle(
|
|
3897
4379
|
forwardedRef,
|
|
3898
4380
|
() => ({
|
|
3899
4381
|
setValue: (html) => {
|
|
3900
4382
|
editor.update(() => {
|
|
4383
|
+
const safe = normalizeToBlockHtml(sanitizeHtml(html || ""));
|
|
3901
4384
|
const parser = new DOMParser();
|
|
3902
|
-
const dom = parser.parseFromString(
|
|
4385
|
+
const dom = parser.parseFromString(safe || "<p></p>", "text/html");
|
|
3903
4386
|
const nodes = $generateNodesFromDOM(editor, dom);
|
|
3904
4387
|
const root = $getRoot();
|
|
3905
4388
|
root.clear();
|
|
@@ -3909,9 +4392,9 @@ function RefApiPlugin({
|
|
|
3909
4392
|
getValue: () => {
|
|
3910
4393
|
let html = "";
|
|
3911
4394
|
editor.getEditorState().read(() => {
|
|
3912
|
-
html = $generateHtmlFromNodes(editor, null);
|
|
4395
|
+
html = postProcessOutput(splitHeadingsAtBrSequences($generateHtmlFromNodes(editor, null)));
|
|
3913
4396
|
});
|
|
3914
|
-
return
|
|
4397
|
+
return html;
|
|
3915
4398
|
},
|
|
3916
4399
|
clear: () => {
|
|
3917
4400
|
editor.update(() => {
|
|
@@ -3929,14 +4412,20 @@ function RefApiPlugin({
|
|
|
3929
4412
|
},
|
|
3930
4413
|
isFocused: () => focusedRef.current,
|
|
3931
4414
|
getEditor: () => editor,
|
|
3932
|
-
setErrors: (messages) => setRefErrors(messages),
|
|
3933
|
-
clearErrors: () => setRefErrors([]),
|
|
3934
4415
|
// Generic blocks (signature, footer, banner, etc.)
|
|
3935
4416
|
upsertBlock: (spec) => upsertBlock(editor, spec),
|
|
3936
4417
|
removeBlock: (kind) => removeBlock(editor, kind),
|
|
3937
|
-
hasBlock: (kind) => hasBlock(editor, kind)
|
|
4418
|
+
hasBlock: (kind) => hasBlock(editor, kind),
|
|
4419
|
+
checkDirty: () => {
|
|
4420
|
+
if (cleanBaselineRef.current === null) return false;
|
|
4421
|
+
const current = getUserContentSignature(editor);
|
|
4422
|
+
return current !== cleanBaselineRef.current;
|
|
4423
|
+
},
|
|
4424
|
+
markClean: () => {
|
|
4425
|
+
cleanBaselineRef.current = getUserContentSignature(editor);
|
|
4426
|
+
}
|
|
3938
4427
|
}),
|
|
3939
|
-
[editor, contentEditableDomRef, focusedRef
|
|
4428
|
+
[editor, contentEditableDomRef, focusedRef]
|
|
3940
4429
|
);
|
|
3941
4430
|
return null;
|
|
3942
4431
|
}
|
|
@@ -4577,8 +5066,22 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4577
5066
|
const [editor] = useLexicalComposerContext();
|
|
4578
5067
|
const [isInTable, setIsInTable] = React9.useState(false);
|
|
4579
5068
|
const [anchorRect, setAnchorRect] = React9.useState(null);
|
|
5069
|
+
const [contentRight, setContentRight] = React9.useState(null);
|
|
4580
5070
|
const [open, setOpen] = React9.useState(false);
|
|
5071
|
+
const openRef = React9.useRef(false);
|
|
5072
|
+
const savedAnchorRef = React9.useRef(null);
|
|
5073
|
+
const measureContentRight = React9.useCallback((cellDom) => {
|
|
5074
|
+
try {
|
|
5075
|
+
const range = document.createRange();
|
|
5076
|
+
range.selectNodeContents(cellDom);
|
|
5077
|
+
const cr = range.getBoundingClientRect();
|
|
5078
|
+
return cr.width > 2 ? cr.right : null;
|
|
5079
|
+
} catch {
|
|
5080
|
+
return null;
|
|
5081
|
+
}
|
|
5082
|
+
}, []);
|
|
4581
5083
|
const updateFromSelection = React9.useCallback(() => {
|
|
5084
|
+
if (openRef.current) return;
|
|
4582
5085
|
const root = editor.getRootElement();
|
|
4583
5086
|
if (!root) return;
|
|
4584
5087
|
editor.getEditorState().read(() => {
|
|
@@ -4590,6 +5093,7 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4590
5093
|
if (dom) {
|
|
4591
5094
|
setIsInTable(true);
|
|
4592
5095
|
setAnchorRect(dom.getBoundingClientRect());
|
|
5096
|
+
setContentRight(null);
|
|
4593
5097
|
return;
|
|
4594
5098
|
}
|
|
4595
5099
|
}
|
|
@@ -4597,6 +5101,7 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4597
5101
|
if (!$isRangeSelection(selection)) {
|
|
4598
5102
|
setIsInTable(false);
|
|
4599
5103
|
setAnchorRect(null);
|
|
5104
|
+
setContentRight(null);
|
|
4600
5105
|
return;
|
|
4601
5106
|
}
|
|
4602
5107
|
const anchorNode = selection.anchor.getNode();
|
|
@@ -4604,18 +5109,28 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4604
5109
|
if (!cellNode || !$isTableCellNode(cellNode)) {
|
|
4605
5110
|
setIsInTable(false);
|
|
4606
5111
|
setAnchorRect(null);
|
|
5112
|
+
setContentRight(null);
|
|
4607
5113
|
return;
|
|
4608
5114
|
}
|
|
4609
5115
|
const cellDom = editor.getElementByKey(cellNode.getKey());
|
|
4610
5116
|
if (!cellDom) {
|
|
4611
5117
|
setIsInTable(false);
|
|
4612
5118
|
setAnchorRect(null);
|
|
5119
|
+
setContentRight(null);
|
|
4613
5120
|
return;
|
|
4614
5121
|
}
|
|
4615
5122
|
setIsInTable(true);
|
|
4616
5123
|
setAnchorRect(cellDom.getBoundingClientRect());
|
|
5124
|
+
setContentRight(measureContentRight(cellDom));
|
|
5125
|
+
if ($isRangeSelection(selection)) {
|
|
5126
|
+
savedAnchorRef.current = {
|
|
5127
|
+
key: selection.anchor.key,
|
|
5128
|
+
offset: selection.anchor.offset,
|
|
5129
|
+
type: selection.anchor.type
|
|
5130
|
+
};
|
|
5131
|
+
}
|
|
4617
5132
|
});
|
|
4618
|
-
}, [editor]);
|
|
5133
|
+
}, [editor, measureContentRight]);
|
|
4619
5134
|
React9.useEffect(() => {
|
|
4620
5135
|
return mergeRegister(
|
|
4621
5136
|
editor.registerCommand(
|
|
@@ -4672,30 +5187,37 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4672
5187
|
COMMAND_PRIORITY_HIGH
|
|
4673
5188
|
);
|
|
4674
5189
|
}, [editor, disabled]);
|
|
4675
|
-
React9.useEffect(() => {
|
|
4676
|
-
if (!isInTable && open) setOpen(false);
|
|
4677
|
-
}, [isInTable, open]);
|
|
4678
5190
|
const canShow = isInTable && !!anchorRect && !disabled;
|
|
4679
5191
|
const handleStyle = React9.useMemo(() => {
|
|
4680
5192
|
if (!anchorRect) return void 0;
|
|
4681
5193
|
const top = Math.max(8, anchorRect.top + 6);
|
|
4682
|
-
const
|
|
5194
|
+
const clampedCellRight = Math.min(anchorRect.right, window.innerWidth - 8);
|
|
5195
|
+
const left = contentRight !== null ? Math.max(anchorRect.left + 4, Math.min(contentRight + 4, clampedCellRight - 32)) : Math.max(8, anchorRect.left + 8);
|
|
4683
5196
|
return {
|
|
4684
5197
|
position: "fixed",
|
|
4685
5198
|
top,
|
|
4686
5199
|
left,
|
|
4687
5200
|
zIndex: 9999
|
|
4688
5201
|
};
|
|
4689
|
-
}, [anchorRect]);
|
|
5202
|
+
}, [anchorRect, contentRight]);
|
|
4690
5203
|
const dangerStyle = {
|
|
4691
5204
|
color: "var(--colorPaletteRedForeground1)"
|
|
4692
5205
|
};
|
|
4693
5206
|
const run = React9.useCallback(
|
|
4694
5207
|
(fn) => {
|
|
4695
5208
|
if (disabled) return;
|
|
4696
|
-
|
|
4697
|
-
editor.update(() => fn());
|
|
5209
|
+
openRef.current = false;
|
|
4698
5210
|
setOpen(false);
|
|
5211
|
+
editor.update(() => {
|
|
5212
|
+
const saved = savedAnchorRef.current;
|
|
5213
|
+
if (saved && $getNodeByKey(saved.key)) {
|
|
5214
|
+
const sel = $createRangeSelection();
|
|
5215
|
+
sel.anchor.set(saved.key, saved.offset, saved.type);
|
|
5216
|
+
sel.focus.set(saved.key, saved.offset, saved.type);
|
|
5217
|
+
$setSelection(sel);
|
|
5218
|
+
}
|
|
5219
|
+
fn();
|
|
5220
|
+
});
|
|
4699
5221
|
},
|
|
4700
5222
|
[disabled, editor]
|
|
4701
5223
|
);
|
|
@@ -4705,32 +5227,31 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4705
5227
|
const insertColLeft = () => run(() => $insertTableColumnAtSelection(false));
|
|
4706
5228
|
const deleteRow = () => run(() => $deleteTableRowAtSelection());
|
|
4707
5229
|
const deleteCol = () => run(() => $deleteTableColumnAtSelection());
|
|
4708
|
-
const deleteTable = () =>
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
5230
|
+
const deleteTable = () => {
|
|
5231
|
+
if (disabled) return;
|
|
5232
|
+
openRef.current = false;
|
|
5233
|
+
setOpen(false);
|
|
5234
|
+
editor.update(() => {
|
|
5235
|
+
const saved = savedAnchorRef.current;
|
|
5236
|
+
if (!saved) return;
|
|
5237
|
+
const anchorNode = $getNodeByKey(saved.key);
|
|
5238
|
+
if (!anchorNode) return;
|
|
5239
|
+
const tableNode = $findMatchingParent(anchorNode, (n) => $isTableNode(n));
|
|
4712
5240
|
if (tableNode) tableNode.remove();
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
if (!$isRangeSelection(selection)) return;
|
|
4716
|
-
const node = selection.anchor.getNode();
|
|
4717
|
-
const cell = $findMatchingParent(node, (n) => $isTableCellNode(n)) ?? ($isTableCellNode(node) ? node : null);
|
|
4718
|
-
if (!cell) return;
|
|
4719
|
-
const table = $getTableNodeFromLexicalNodeOrThrow(cell);
|
|
4720
|
-
table.remove();
|
|
4721
|
-
});
|
|
5241
|
+
});
|
|
5242
|
+
};
|
|
4722
5243
|
if (!canShow || !handleStyle) return null;
|
|
4723
5244
|
return createPortal(
|
|
4724
|
-
/* @__PURE__ */ jsx("div", { style: handleStyle, className: "aoTableActionHandleRoot", children: /* @__PURE__ */ jsxs(Menu, { open, onOpenChange: (_, data) =>
|
|
5245
|
+
/* @__PURE__ */ jsx("div", { style: handleStyle, className: "aoTableActionHandleRoot", "data-lexical-editor-portal": "true", children: /* @__PURE__ */ jsxs(Menu, { open, onOpenChange: (_, data) => {
|
|
5246
|
+
openRef.current = data.open;
|
|
5247
|
+
setOpen(data.open);
|
|
5248
|
+
}, children: [
|
|
4725
5249
|
/* @__PURE__ */ jsx(MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
4726
5250
|
"button",
|
|
4727
5251
|
{
|
|
4728
5252
|
type: "button",
|
|
4729
5253
|
className: "aoTableActionHandleBtn",
|
|
4730
5254
|
"aria-label": "Table options",
|
|
4731
|
-
onMouseDown: (e) => {
|
|
4732
|
-
e.preventDefault();
|
|
4733
|
-
},
|
|
4734
5255
|
children: /* @__PURE__ */ jsx(ChevronDown12Regular, {})
|
|
4735
5256
|
}
|
|
4736
5257
|
) }),
|
|
@@ -5054,8 +5575,8 @@ function getToolbarGroupsByLevel(level) {
|
|
|
5054
5575
|
// ['undo', 'redo', '|'],
|
|
5055
5576
|
["Bold", "Italic", "Underline", "|"],
|
|
5056
5577
|
["ColorPicker", "|"],
|
|
5057
|
-
["Link", "|"],
|
|
5058
|
-
[
|
|
5578
|
+
["Link", "Table", "|"],
|
|
5579
|
+
// ['Image', 'Youtube', 'InlineImage', '|'],
|
|
5059
5580
|
["Heading", "|"],
|
|
5060
5581
|
["FontFamily", "|"],
|
|
5061
5582
|
["FontSize", "|"],
|
|
@@ -5069,8 +5590,9 @@ function getToolbarGroupsByLevel(level) {
|
|
|
5069
5590
|
// ['undo', 'redo', '|'],
|
|
5070
5591
|
["Bold", "Italic", "Underline", "|"],
|
|
5071
5592
|
["ColorPicker", "|"],
|
|
5072
|
-
["Link", "|"],
|
|
5073
|
-
[
|
|
5593
|
+
["Link", "Table", "|"],
|
|
5594
|
+
// ['CodeBlock', '|'],
|
|
5595
|
+
["Image", "Youtube", "InlineImage", "|"],
|
|
5074
5596
|
["Heading", "|"],
|
|
5075
5597
|
["FontFamily", "|"],
|
|
5076
5598
|
["FontSize", "|"],
|
|
@@ -5080,6 +5602,85 @@ function getToolbarGroupsByLevel(level) {
|
|
|
5080
5602
|
];
|
|
5081
5603
|
}
|
|
5082
5604
|
}
|
|
5605
|
+
var DEFAULT_FONT_SIZE = 15;
|
|
5606
|
+
function $splitBlocksAtLineBreaks(selection) {
|
|
5607
|
+
const blocksToSplit = /* @__PURE__ */ new Set();
|
|
5608
|
+
for (const node of selection.getNodes()) {
|
|
5609
|
+
const block = node.getTopLevelElement();
|
|
5610
|
+
if (block && $isElementNode(block)) {
|
|
5611
|
+
const children = block.getChildren();
|
|
5612
|
+
if (children.some($isLineBreakNode)) {
|
|
5613
|
+
blocksToSplit.add(block);
|
|
5614
|
+
}
|
|
5615
|
+
}
|
|
5616
|
+
}
|
|
5617
|
+
for (const block of blocksToSplit) {
|
|
5618
|
+
const children = [...block.getChildren()];
|
|
5619
|
+
const groups = [[]];
|
|
5620
|
+
for (const child of children) {
|
|
5621
|
+
if ($isLineBreakNode(child)) {
|
|
5622
|
+
groups.push([]);
|
|
5623
|
+
} else {
|
|
5624
|
+
groups[groups.length - 1].push(child);
|
|
5625
|
+
}
|
|
5626
|
+
}
|
|
5627
|
+
const nonEmptyCount = groups.filter((g) => g.length > 0).length;
|
|
5628
|
+
if (nonEmptyCount <= 1) continue;
|
|
5629
|
+
for (let i = groups.length - 1; i >= 1; i--) {
|
|
5630
|
+
const group = groups[i];
|
|
5631
|
+
const newBlock = group.length === 0 ? $createParagraphNode() : $isHeadingNode(block) ? $createHeadingNode(block.getTag()) : $createParagraphNode();
|
|
5632
|
+
group.forEach((child) => newBlock.append(child));
|
|
5633
|
+
block.insertAfter(newBlock);
|
|
5634
|
+
}
|
|
5635
|
+
[...block.getChildren()].filter($isLineBreakNode).forEach((br) => br.remove());
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5638
|
+
function $splitBlockAtPartialSelection(selection) {
|
|
5639
|
+
if (selection.isCollapsed()) return false;
|
|
5640
|
+
const anchorBlock = selection.anchor.getNode().getTopLevelElement();
|
|
5641
|
+
const focusBlock = selection.focus.getNode().getTopLevelElement();
|
|
5642
|
+
if (!anchorBlock || !focusBlock || !anchorBlock.is(focusBlock)) return false;
|
|
5643
|
+
if (!$isElementNode(anchorBlock)) return false;
|
|
5644
|
+
const block = anchorBlock;
|
|
5645
|
+
const extractedNodes = selection.extract();
|
|
5646
|
+
if (!extractedNodes.length) return false;
|
|
5647
|
+
const allDirect = extractedNodes.every((n) => {
|
|
5648
|
+
const parent = n.getParent();
|
|
5649
|
+
return parent !== null && parent.is(block);
|
|
5650
|
+
});
|
|
5651
|
+
if (!allDirect) return false;
|
|
5652
|
+
const allChildren = [...block.getChildren()];
|
|
5653
|
+
const firstSelected = extractedNodes[0];
|
|
5654
|
+
const lastSelected = extractedNodes[extractedNodes.length - 1];
|
|
5655
|
+
const firstIdx = allChildren.findIndex((n) => n.is(firstSelected));
|
|
5656
|
+
const lastIdx = allChildren.findIndex((n) => n.is(lastSelected));
|
|
5657
|
+
if (firstIdx === -1 || lastIdx === -1) return false;
|
|
5658
|
+
if (firstIdx === 0 && lastIdx === allChildren.length - 1) return false;
|
|
5659
|
+
const selectedNodes = allChildren.slice(firstIdx, lastIdx + 1);
|
|
5660
|
+
const afterNodes = allChildren.slice(lastIdx + 1);
|
|
5661
|
+
if (afterNodes.length > 0) {
|
|
5662
|
+
const afterBlock = $isHeadingNode(block) ? $createHeadingNode(block.getTag()) : $createParagraphNode();
|
|
5663
|
+
afterNodes.forEach((n) => afterBlock.append(n));
|
|
5664
|
+
block.insertAfter(afterBlock);
|
|
5665
|
+
}
|
|
5666
|
+
const selectedBlock = $createParagraphNode();
|
|
5667
|
+
selectedNodes.forEach((n) => selectedBlock.append(n));
|
|
5668
|
+
block.insertAfter(selectedBlock);
|
|
5669
|
+
if (block.getChildrenSize() === 0) {
|
|
5670
|
+
block.remove();
|
|
5671
|
+
}
|
|
5672
|
+
selectedBlock.select();
|
|
5673
|
+
return true;
|
|
5674
|
+
}
|
|
5675
|
+
var formatParagraph = (editor) => {
|
|
5676
|
+
editor.update(() => {
|
|
5677
|
+
const selection = $getSelection();
|
|
5678
|
+
if ($isRangeSelection(selection)) {
|
|
5679
|
+
$splitBlocksAtLineBreaks(selection);
|
|
5680
|
+
}
|
|
5681
|
+
$setBlocksType($getSelection(), () => $createParagraphNode());
|
|
5682
|
+
});
|
|
5683
|
+
};
|
|
5083
5684
|
var PRESET = [
|
|
5084
5685
|
"#000000",
|
|
5085
5686
|
"#434343",
|
|
@@ -5363,7 +5964,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5363
5964
|
directionalHint: 4,
|
|
5364
5965
|
className: "aoColorCallout",
|
|
5365
5966
|
preventDismissOnEvent,
|
|
5366
|
-
children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 14 }, styles: { root: { padding: "14px 16px 16px", width:
|
|
5967
|
+
children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 14 }, styles: { root: { padding: "14px 16px 16px", width: 250 } }, children: [
|
|
5367
5968
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
5368
5969
|
/* @__PURE__ */ jsx("div", { style: { fontSize: 13, fontWeight: 600, color: "#242424", letterSpacing: 0.1 }, children: title }),
|
|
5369
5970
|
/* @__PURE__ */ jsx(
|
|
@@ -5376,8 +5977,8 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5376
5977
|
display: "flex",
|
|
5377
5978
|
alignItems: "center",
|
|
5378
5979
|
justifyContent: "center",
|
|
5379
|
-
width:
|
|
5380
|
-
height:
|
|
5980
|
+
width: 18,
|
|
5981
|
+
height: 18,
|
|
5381
5982
|
padding: 0,
|
|
5382
5983
|
border: "none",
|
|
5383
5984
|
borderRadius: 4,
|
|
@@ -5400,7 +6001,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5400
6001
|
style: {
|
|
5401
6002
|
position: "relative",
|
|
5402
6003
|
width: "100%",
|
|
5403
|
-
height:
|
|
6004
|
+
height: 125,
|
|
5404
6005
|
borderRadius: 8,
|
|
5405
6006
|
overflow: "hidden",
|
|
5406
6007
|
cursor: "crosshair",
|
|
@@ -5489,8 +6090,8 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5489
6090
|
"div",
|
|
5490
6091
|
{
|
|
5491
6092
|
style: {
|
|
5492
|
-
width:
|
|
5493
|
-
height:
|
|
6093
|
+
width: 20,
|
|
6094
|
+
height: 20,
|
|
5494
6095
|
borderRadius: 6,
|
|
5495
6096
|
flexShrink: 0,
|
|
5496
6097
|
background: hex,
|
|
@@ -5531,10 +6132,10 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5531
6132
|
title: c,
|
|
5532
6133
|
"aria-label": c,
|
|
5533
6134
|
style: {
|
|
5534
|
-
width:
|
|
5535
|
-
height:
|
|
6135
|
+
width: 18,
|
|
6136
|
+
height: 18,
|
|
5536
6137
|
padding: 0,
|
|
5537
|
-
borderRadius:
|
|
6138
|
+
borderRadius: 4,
|
|
5538
6139
|
background: c,
|
|
5539
6140
|
cursor: "pointer",
|
|
5540
6141
|
boxShadow: isSelected ? "0 0 0 2px #fff, 0 0 0 3px #4a86e8" : "inset 0 0 0 1px rgba(0,0,0,0.15)",
|
|
@@ -5744,7 +6345,6 @@ var FontFamilyPlugin = ({ disabled = false }) => {
|
|
|
5744
6345
|
"font-family"
|
|
5745
6346
|
);
|
|
5746
6347
|
};
|
|
5747
|
-
var DEFAULT_FONT_SIZE = 15;
|
|
5748
6348
|
var FONT_SIZE_OPTIONS = [
|
|
5749
6349
|
"8",
|
|
5750
6350
|
"9",
|
|
@@ -5880,135 +6480,43 @@ var FontSizePlugin = ({ disabled }) => {
|
|
|
5880
6480
|
"fontsize"
|
|
5881
6481
|
) });
|
|
5882
6482
|
};
|
|
5883
|
-
var VERBATIM_LINK_RE = /^https?:\/\/|^mailto:|^tel:|^#|^\//i;
|
|
5884
|
-
function getLinkValidationMessage(raw) {
|
|
5885
|
-
const trimmed = raw.trim();
|
|
5886
|
-
if (!trimmed) return void 0;
|
|
5887
|
-
if (/\s/.test(trimmed)) return "URL cannot contain spaces";
|
|
5888
|
-
if (!VERBATIM_LINK_RE.test(trimmed) && !trimmed.includes(".")) {
|
|
5889
|
-
return "Enter a valid URL (e.g. example.com)";
|
|
5890
|
-
}
|
|
5891
|
-
return void 0;
|
|
5892
|
-
}
|
|
5893
6483
|
var InsertLinkPlugin = ({
|
|
5894
6484
|
disabled,
|
|
5895
|
-
|
|
5896
|
-
onClose
|
|
6485
|
+
setIsLinkEditMode
|
|
5897
6486
|
}) => {
|
|
5898
6487
|
const [editor] = useLexicalComposerContext();
|
|
5899
|
-
const [internalOpen, setInternalOpen] = useState(false);
|
|
5900
|
-
const [text, setText] = useState("");
|
|
5901
|
-
const [link, setLink] = useState("");
|
|
5902
6488
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
5903
|
-
const
|
|
5904
|
-
const isOpen = isControlled ? !!externalOpen && !disabled : internalOpen && !disabled;
|
|
5905
|
-
const linkError = getLinkValidationMessage(link);
|
|
5906
|
-
const handleClose = () => {
|
|
5907
|
-
setText("");
|
|
5908
|
-
setLink("");
|
|
5909
|
-
if (isControlled) onClose?.();
|
|
5910
|
-
else setInternalOpen(false);
|
|
5911
|
-
};
|
|
5912
|
-
const insertLink = (text2, link2) => {
|
|
6489
|
+
const insertLink = () => {
|
|
5913
6490
|
if (disabled) return;
|
|
5914
|
-
if (getLinkValidationMessage(link2)) return;
|
|
5915
|
-
const trimmedLink = link2.trim();
|
|
5916
|
-
const href = VERBATIM_LINK_RE.test(trimmedLink) ? trimmedLink : `https://${trimmedLink}`;
|
|
5917
6491
|
editor.update(() => {
|
|
5918
6492
|
const selection = $getSelection();
|
|
5919
|
-
if (
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
6493
|
+
if (!$isRangeSelection(selection)) return;
|
|
6494
|
+
const node = getSelectedNode2(selection);
|
|
6495
|
+
const linkParent = $findMatchingParent$1(node, $isLinkNode);
|
|
6496
|
+
if (!linkParent && !$isLinkNode(node)) {
|
|
6497
|
+
editor.dispatchCommand(TOGGLE_LINK_COMMAND, "https://");
|
|
5924
6498
|
}
|
|
5925
6499
|
});
|
|
5926
|
-
|
|
6500
|
+
setIsLinkEditMode(true);
|
|
5927
6501
|
};
|
|
5928
|
-
return /* @__PURE__ */
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
cursor: disabled ? "not-allowed" : "pointer"
|
|
5942
|
-
},
|
|
5943
|
-
onClick: () => {
|
|
5944
|
-
if (disabled) return;
|
|
5945
|
-
setInternalOpen((prev) => !prev);
|
|
5946
|
-
}
|
|
6502
|
+
return /* @__PURE__ */ jsx(
|
|
6503
|
+
Button,
|
|
6504
|
+
{
|
|
6505
|
+
size: "small",
|
|
6506
|
+
title: "Add link",
|
|
6507
|
+
disabled,
|
|
6508
|
+
icon: /* @__PURE__ */ jsx(LinkAddRegular, { style: { color: iconColor } }),
|
|
6509
|
+
style: {
|
|
6510
|
+
background: "none",
|
|
6511
|
+
border: "none",
|
|
6512
|
+
margin: 2,
|
|
6513
|
+
opacity: disabled ? 0.55 : 1,
|
|
6514
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
5947
6515
|
},
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
{
|
|
5953
|
-
open: isOpen,
|
|
5954
|
-
onOpenChange: (_, data) => {
|
|
5955
|
-
if (!data.open) handleClose();
|
|
5956
|
-
},
|
|
5957
|
-
children: /* @__PURE__ */ jsx(DialogSurface, { style: { maxWidth: "380px" }, children: /* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
5958
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "Insert Link" }),
|
|
5959
|
-
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 10 }, style: { paddingTop: 8 }, children: [
|
|
5960
|
-
/* @__PURE__ */ jsx(Field, { label: "Text", orientation: "horizontal", size: "small", children: /* @__PURE__ */ jsx(
|
|
5961
|
-
Input,
|
|
5962
|
-
{
|
|
5963
|
-
autoFocus: !disabled,
|
|
5964
|
-
value: text,
|
|
5965
|
-
appearance: "underline",
|
|
5966
|
-
placeholder: "Text",
|
|
5967
|
-
disabled,
|
|
5968
|
-
onChange: (_, v) => setText(v.value)
|
|
5969
|
-
}
|
|
5970
|
-
) }),
|
|
5971
|
-
/* @__PURE__ */ jsx(
|
|
5972
|
-
Field,
|
|
5973
|
-
{
|
|
5974
|
-
label: "Link",
|
|
5975
|
-
orientation: "horizontal",
|
|
5976
|
-
size: "small",
|
|
5977
|
-
validationState: linkError ? "error" : "none",
|
|
5978
|
-
validationMessage: linkError,
|
|
5979
|
-
children: /* @__PURE__ */ jsx(
|
|
5980
|
-
Input,
|
|
5981
|
-
{
|
|
5982
|
-
value: link,
|
|
5983
|
-
appearance: "underline",
|
|
5984
|
-
placeholder: "Link",
|
|
5985
|
-
disabled,
|
|
5986
|
-
onChange: (_, v) => setLink(v.value),
|
|
5987
|
-
onKeyDown: (e) => {
|
|
5988
|
-
if (e.key === "Enter" && text && link && !linkError) insertLink(text, link);
|
|
5989
|
-
}
|
|
5990
|
-
}
|
|
5991
|
-
)
|
|
5992
|
-
}
|
|
5993
|
-
)
|
|
5994
|
-
] }) }),
|
|
5995
|
-
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
5996
|
-
/* @__PURE__ */ jsx(
|
|
5997
|
-
Button,
|
|
5998
|
-
{
|
|
5999
|
-
appearance: "primary",
|
|
6000
|
-
size: "small",
|
|
6001
|
-
disabled: disabled || !text || !link || !!linkError,
|
|
6002
|
-
onClick: () => insertLink(text, link),
|
|
6003
|
-
children: "Add"
|
|
6004
|
-
}
|
|
6005
|
-
),
|
|
6006
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: handleClose, children: "Cancel" })
|
|
6007
|
-
] })
|
|
6008
|
-
] }) })
|
|
6009
|
-
}
|
|
6010
|
-
)
|
|
6011
|
-
] });
|
|
6516
|
+
onClick: insertLink
|
|
6517
|
+
},
|
|
6518
|
+
"insert-link"
|
|
6519
|
+
);
|
|
6012
6520
|
};
|
|
6013
6521
|
function PageSetupPlugin({ disabled, value, onChange }) {
|
|
6014
6522
|
const sizeLabel = value.size === "pageless" ? "Pageless" : PAGE_SIZE_OPTIONS.find((o) => o.key === value.size)?.label ?? "Pageless";
|
|
@@ -6064,281 +6572,177 @@ function PageSetupPlugin({ disabled, value, onChange }) {
|
|
|
6064
6572
|
}
|
|
6065
6573
|
);
|
|
6066
6574
|
}
|
|
6067
|
-
var
|
|
6068
|
-
var MAX_COLS = 50;
|
|
6069
|
-
var TableItemPlugin = ({
|
|
6070
|
-
disabled,
|
|
6071
|
-
open: externalOpen,
|
|
6072
|
-
onClose
|
|
6073
|
-
}) => {
|
|
6575
|
+
var TableItemPlugin = ({ disabled }) => {
|
|
6074
6576
|
const [editor] = useLexicalComposerContext();
|
|
6075
6577
|
const [columns, setColumns] = useState("");
|
|
6076
6578
|
const [rows, setRows] = useState("");
|
|
6077
|
-
const [
|
|
6078
|
-
const [rowError, setRowError] = useState("");
|
|
6079
|
-
const [colError, setColError] = useState("");
|
|
6080
|
-
const isControlled = externalOpen !== void 0;
|
|
6081
|
-
const isOpen = isControlled ? !!externalOpen && !disabled : internalOpen && !disabled;
|
|
6579
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6082
6580
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
6083
|
-
const handleClose = () => {
|
|
6084
|
-
setRows("");
|
|
6085
|
-
setColumns("");
|
|
6086
|
-
setRowError("");
|
|
6087
|
-
setColError("");
|
|
6088
|
-
if (isControlled) onClose?.();
|
|
6089
|
-
else setInternalOpen(false);
|
|
6090
|
-
};
|
|
6091
|
-
const onRowsChange = (val) => {
|
|
6092
|
-
const clean = val.replace(/\D/g, "");
|
|
6093
|
-
setRows(clean);
|
|
6094
|
-
const n = Number(clean);
|
|
6095
|
-
if (clean && n > MAX_ROWS) setRowError(`Maximum ${MAX_ROWS} rows allowed`);
|
|
6096
|
-
else setRowError("");
|
|
6097
|
-
};
|
|
6098
|
-
const onColsChange = (val) => {
|
|
6099
|
-
const clean = val.replace(/\D/g, "");
|
|
6100
|
-
setColumns(clean);
|
|
6101
|
-
const n = Number(clean);
|
|
6102
|
-
if (clean && n > MAX_COLS) setColError(`Maximum ${MAX_COLS} columns allowed`);
|
|
6103
|
-
else setColError("");
|
|
6104
|
-
};
|
|
6105
6581
|
const onAddTable = () => {
|
|
6106
6582
|
if (disabled) return;
|
|
6107
6583
|
const row = Number(rows);
|
|
6108
6584
|
const col = Number(columns);
|
|
6109
6585
|
if (!row || !col) return;
|
|
6110
|
-
if (row > MAX_ROWS || col > MAX_COLS) return;
|
|
6111
6586
|
editor.update(() => {
|
|
6112
6587
|
const tableNode = $createTableNodeWithDimensions(row, col, true);
|
|
6113
6588
|
$insertNodeToNearestRoot(tableNode);
|
|
6114
6589
|
});
|
|
6115
|
-
|
|
6590
|
+
setRows("");
|
|
6591
|
+
setColumns("");
|
|
6592
|
+
setIsOpen(false);
|
|
6116
6593
|
};
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
{
|
|
6122
|
-
|
|
6123
|
-
title: "Add table",
|
|
6124
|
-
disabled,
|
|
6125
|
-
icon: /* @__PURE__ */ jsx(TableAddRegular, { style: { color: iconColor } }),
|
|
6126
|
-
style: {
|
|
6127
|
-
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
6128
|
-
border: "none",
|
|
6129
|
-
margin: 2,
|
|
6130
|
-
opacity: disabled ? 0.55 : 1,
|
|
6131
|
-
cursor: disabled ? "not-allowed" : "pointer"
|
|
6132
|
-
},
|
|
6133
|
-
onClick: () => {
|
|
6134
|
-
if (disabled) return;
|
|
6135
|
-
setRows("");
|
|
6136
|
-
setColumns("");
|
|
6137
|
-
setRowError("");
|
|
6138
|
-
setColError("");
|
|
6139
|
-
setInternalOpen(true);
|
|
6140
|
-
}
|
|
6594
|
+
return /* @__PURE__ */ jsxs(
|
|
6595
|
+
Dialog,
|
|
6596
|
+
{
|
|
6597
|
+
open: disabled ? false : isOpen,
|
|
6598
|
+
onOpenChange: (_, data) => {
|
|
6599
|
+
if (!disabled) setIsOpen(data.open);
|
|
6141
6600
|
},
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6601
|
+
children: [
|
|
6602
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
6603
|
+
Button,
|
|
6604
|
+
{
|
|
6605
|
+
size: "small",
|
|
6606
|
+
title: "Add table",
|
|
6607
|
+
disabled,
|
|
6608
|
+
icon: /* @__PURE__ */ jsx(TableAddRegular, { style: { color: iconColor } }),
|
|
6609
|
+
style: {
|
|
6610
|
+
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
6611
|
+
border: "none",
|
|
6612
|
+
margin: 2,
|
|
6613
|
+
opacity: disabled ? 0.55 : 1,
|
|
6614
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
6615
|
+
},
|
|
6616
|
+
onClick: () => {
|
|
6617
|
+
if (disabled) return;
|
|
6618
|
+
setIsOpen((prev) => !prev);
|
|
6619
|
+
setRows("");
|
|
6620
|
+
setColumns("");
|
|
6621
|
+
}
|
|
6622
|
+
},
|
|
6623
|
+
"insert-table-nodes"
|
|
6624
|
+
) }),
|
|
6625
|
+
/* @__PURE__ */ jsx(DialogSurface, { style: { maxWidth: 300 }, children: /* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
6626
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Insert table" }),
|
|
6627
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 8 }, children: [
|
|
6628
|
+
/* @__PURE__ */ jsx(Field, { label: "Rows", size: "small", children: /* @__PURE__ */ jsx(
|
|
6629
|
+
Input,
|
|
6156
6630
|
{
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
Input,
|
|
6164
|
-
{
|
|
6165
|
-
autoFocus: !disabled,
|
|
6166
|
-
type: "number",
|
|
6167
|
-
min: 1,
|
|
6168
|
-
max: MAX_ROWS,
|
|
6169
|
-
value: rows,
|
|
6170
|
-
placeholder: "Rows",
|
|
6171
|
-
appearance: "underline",
|
|
6172
|
-
disabled,
|
|
6173
|
-
input: { style: { textAlign: "left" } },
|
|
6174
|
-
onChange: (_, v) => onRowsChange(v.value)
|
|
6175
|
-
}
|
|
6176
|
-
)
|
|
6631
|
+
autoFocus: !disabled,
|
|
6632
|
+
value: rows,
|
|
6633
|
+
placeholder: "Rows",
|
|
6634
|
+
appearance: "underline",
|
|
6635
|
+
disabled,
|
|
6636
|
+
onChange: (_, v) => setRows(v.value)
|
|
6177
6637
|
}
|
|
6178
|
-
),
|
|
6179
|
-
/* @__PURE__ */ jsx(
|
|
6180
|
-
|
|
6638
|
+
) }),
|
|
6639
|
+
/* @__PURE__ */ jsx(Field, { label: "Columns", size: "small", children: /* @__PURE__ */ jsx(
|
|
6640
|
+
Input,
|
|
6181
6641
|
{
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
children: /* @__PURE__ */ jsx(
|
|
6188
|
-
Input,
|
|
6189
|
-
{
|
|
6190
|
-
type: "number",
|
|
6191
|
-
min: 1,
|
|
6192
|
-
max: MAX_COLS,
|
|
6193
|
-
value: columns,
|
|
6194
|
-
placeholder: "Columns",
|
|
6195
|
-
appearance: "underline",
|
|
6196
|
-
disabled,
|
|
6197
|
-
input: { style: { textAlign: "left" } },
|
|
6198
|
-
onChange: (_, v) => onColsChange(v.value)
|
|
6199
|
-
}
|
|
6200
|
-
)
|
|
6642
|
+
value: columns,
|
|
6643
|
+
placeholder: "Columns",
|
|
6644
|
+
appearance: "underline",
|
|
6645
|
+
disabled,
|
|
6646
|
+
onChange: (_, v) => setColumns(v.value)
|
|
6201
6647
|
}
|
|
6202
|
-
)
|
|
6648
|
+
) })
|
|
6203
6649
|
] }) }),
|
|
6204
6650
|
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
6205
6651
|
/* @__PURE__ */ jsx(
|
|
6206
6652
|
Button,
|
|
6207
6653
|
{
|
|
6208
|
-
appearance: "primary",
|
|
6209
6654
|
size: "small",
|
|
6210
|
-
|
|
6655
|
+
appearance: "primary",
|
|
6656
|
+
disabled: disabled || !rows || !columns,
|
|
6211
6657
|
onClick: onAddTable,
|
|
6212
6658
|
children: "Add"
|
|
6213
6659
|
}
|
|
6214
6660
|
),
|
|
6215
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick:
|
|
6661
|
+
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
6216
6662
|
] })
|
|
6217
6663
|
] }) })
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6664
|
+
]
|
|
6665
|
+
}
|
|
6666
|
+
);
|
|
6221
6667
|
};
|
|
6222
|
-
|
|
6223
|
-
const trimmed = url.trim();
|
|
6224
|
-
if (/^[\w-]{11}$/.test(trimmed)) return trimmed;
|
|
6225
|
-
const match = /(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|v\/|shorts\/|live\/|u\/\w\/))([^#&?]{11})/.exec(trimmed);
|
|
6226
|
-
return match ? match[1] : null;
|
|
6227
|
-
}
|
|
6228
|
-
var YoutubeUploadPlugin = ({
|
|
6229
|
-
disabled,
|
|
6230
|
-
open: externalOpen,
|
|
6231
|
-
onClose
|
|
6232
|
-
}) => {
|
|
6668
|
+
var YoutubeUploadPlugin = ({ disabled }) => {
|
|
6233
6669
|
const [url, setURL] = useState("");
|
|
6234
|
-
const [
|
|
6235
|
-
const [internalOpen, setInternalOpen] = useState(false);
|
|
6670
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6236
6671
|
const [editor] = useLexicalComposerContext();
|
|
6237
6672
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#424242";
|
|
6238
|
-
const isControlled = externalOpen !== void 0;
|
|
6239
|
-
const isOpen = isControlled ? !!externalOpen && !disabled : internalOpen && !disabled;
|
|
6240
|
-
const handleClose = () => {
|
|
6241
|
-
setURL("");
|
|
6242
|
-
setUrlError("");
|
|
6243
|
-
if (isControlled) onClose?.();
|
|
6244
|
-
else setInternalOpen(false);
|
|
6245
|
-
};
|
|
6246
6673
|
const onHandleEmbeded = () => {
|
|
6247
6674
|
if (disabled) return;
|
|
6248
6675
|
if (!url) return;
|
|
6249
|
-
const
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
return;
|
|
6253
|
-
}
|
|
6254
|
-
setUrlError("");
|
|
6676
|
+
const match = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/.exec(url);
|
|
6677
|
+
const id = match && match[2]?.length === 11 ? match[2] : null;
|
|
6678
|
+
if (!id) return;
|
|
6255
6679
|
editor.update(() => {
|
|
6256
6680
|
const node = $createYouTubeNode(id);
|
|
6257
6681
|
$insertNodes([node]);
|
|
6258
6682
|
});
|
|
6259
|
-
|
|
6683
|
+
setURL("");
|
|
6684
|
+
setIsOpen(false);
|
|
6260
6685
|
};
|
|
6261
|
-
return /* @__PURE__ */ jsxs(
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
disabled,
|
|
6268
|
-
icon: /* @__PURE__ */ jsx(VideoClipRegular, { style: { color: iconColor } }),
|
|
6269
|
-
style: {
|
|
6270
|
-
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
6271
|
-
border: "none",
|
|
6272
|
-
margin: 2,
|
|
6273
|
-
opacity: disabled ? 0.55 : 1,
|
|
6274
|
-
cursor: disabled ? "not-allowed" : "pointer"
|
|
6275
|
-
},
|
|
6276
|
-
onClick: () => {
|
|
6277
|
-
if (disabled) return;
|
|
6278
|
-
setURL("");
|
|
6279
|
-
setUrlError("");
|
|
6280
|
-
setInternalOpen(true);
|
|
6281
|
-
}
|
|
6686
|
+
return /* @__PURE__ */ jsxs(
|
|
6687
|
+
Dialog,
|
|
6688
|
+
{
|
|
6689
|
+
open: disabled ? false : isOpen,
|
|
6690
|
+
onOpenChange: (_, data) => {
|
|
6691
|
+
if (!disabled) setIsOpen(data.open);
|
|
6282
6692
|
},
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
),
|
|
6322
|
-
/* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "#94a3b8", lineHeight: 1.5 }, children: "Supports: youtube.com/watch?v=\u2026, youtu.be/\u2026, /shorts/\u2026, /live/\u2026" })
|
|
6323
|
-
] }) }),
|
|
6324
|
-
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
6325
|
-
/* @__PURE__ */ jsx(
|
|
6326
|
-
Button,
|
|
6327
|
-
{
|
|
6328
|
-
appearance: "primary",
|
|
6329
|
-
size: "small",
|
|
6330
|
-
disabled: disabled || !url,
|
|
6331
|
-
onClick: onHandleEmbeded,
|
|
6332
|
-
children: "Add"
|
|
6333
|
-
}
|
|
6334
|
-
),
|
|
6335
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: handleClose, children: "Cancel" })
|
|
6693
|
+
children: [
|
|
6694
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
6695
|
+
Button,
|
|
6696
|
+
{
|
|
6697
|
+
title: "Add youtube URL",
|
|
6698
|
+
size: "small",
|
|
6699
|
+
disabled,
|
|
6700
|
+
icon: /* @__PURE__ */ jsx(VideoClipRegular, { style: { color: iconColor } }),
|
|
6701
|
+
style: {
|
|
6702
|
+
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
6703
|
+
border: "none",
|
|
6704
|
+
margin: 2,
|
|
6705
|
+
opacity: disabled ? 0.55 : 1,
|
|
6706
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
6707
|
+
},
|
|
6708
|
+
onClick: () => {
|
|
6709
|
+
if (disabled) return;
|
|
6710
|
+
setIsOpen((prev) => !prev);
|
|
6711
|
+
setURL("");
|
|
6712
|
+
}
|
|
6713
|
+
},
|
|
6714
|
+
"upload-video"
|
|
6715
|
+
) }),
|
|
6716
|
+
/* @__PURE__ */ jsx(DialogSurface, { style: { maxWidth: 320 }, children: /* @__PURE__ */ jsxs(DialogBody, { children: [
|
|
6717
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Embed YouTube video" }),
|
|
6718
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(Stack, { tokens: { childrenGap: 8 }, children: /* @__PURE__ */ jsx(Field, { label: "URL", size: "small", children: /* @__PURE__ */ jsx(
|
|
6719
|
+
Input,
|
|
6720
|
+
{
|
|
6721
|
+
autoFocus: !disabled,
|
|
6722
|
+
disabled,
|
|
6723
|
+
value: url,
|
|
6724
|
+
appearance: "underline",
|
|
6725
|
+
placeholder: "Add Youtube video URL",
|
|
6726
|
+
onChange: (_, v) => setURL(v.value)
|
|
6727
|
+
}
|
|
6728
|
+
) }) }) }),
|
|
6729
|
+
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
6730
|
+
/* @__PURE__ */ jsx(Button, { size: "small", disabled: disabled || !url, onClick: onHandleEmbeded, children: "Add" }),
|
|
6731
|
+
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
6336
6732
|
] })
|
|
6337
6733
|
] }) })
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6734
|
+
]
|
|
6735
|
+
}
|
|
6736
|
+
);
|
|
6341
6737
|
};
|
|
6738
|
+
var TextAlphaListLtrFilled = ({ style }) => /* @__PURE__ */ jsxs("svg", { width: "1em", height: "1em", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", style, children: [
|
|
6739
|
+
/* @__PURE__ */ jsx("path", { d: "M8.75 4a.75.75 0 1 0 0 1.5h7.5a.75.75 0 0 0 0-1.5h-7.5Z" }),
|
|
6740
|
+
/* @__PURE__ */ jsx("path", { d: "M8.75 9a.75.75 0 1 0 0 1.5h7.5a.75.75 0 0 0 0-1.5h-7.5Z" }),
|
|
6741
|
+
/* @__PURE__ */ jsx("path", { d: "M8 14.75c0-.41.34-.75.75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5a.75.75 0 0 1-.75-.75Z" }),
|
|
6742
|
+
/* @__PURE__ */ jsx("text", { x: "3.5", y: "6", fontSize: "5.5", fontWeight: "bold", textAnchor: "middle", children: "a" }),
|
|
6743
|
+
/* @__PURE__ */ jsx("text", { x: "3.5", y: "11", fontSize: "5.5", fontWeight: "bold", textAnchor: "middle", children: "b" }),
|
|
6744
|
+
/* @__PURE__ */ jsx("text", { x: "3.5", y: "16", fontSize: "5.5", fontWeight: "bold", textAnchor: "middle", children: "c" })
|
|
6745
|
+
] });
|
|
6342
6746
|
var useStyles4 = makeStyles({
|
|
6343
6747
|
dropdown: {
|
|
6344
6748
|
minInlineSize: "90px",
|
|
@@ -6356,25 +6760,42 @@ var ALLOWED_TOKENS = {
|
|
|
6356
6760
|
Bold: true,
|
|
6357
6761
|
Italic: true,
|
|
6358
6762
|
Underline: true,
|
|
6763
|
+
Strikethrough: true,
|
|
6764
|
+
Subscript: true,
|
|
6765
|
+
Superscript: true,
|
|
6766
|
+
Highlight: true,
|
|
6767
|
+
Uppercase: true,
|
|
6768
|
+
Lowercase: true,
|
|
6769
|
+
Capitalize: true,
|
|
6770
|
+
BulletList: true,
|
|
6771
|
+
NumberList: true,
|
|
6772
|
+
AlphabeticalList: true,
|
|
6773
|
+
Quote: true,
|
|
6774
|
+
PageBreak: true,
|
|
6775
|
+
H1: true,
|
|
6776
|
+
H2: true,
|
|
6777
|
+
H3: true,
|
|
6778
|
+
H4: true,
|
|
6779
|
+
H5: true,
|
|
6780
|
+
H6: true,
|
|
6359
6781
|
ColorPicker: true,
|
|
6360
6782
|
Link: true,
|
|
6361
6783
|
Table: true,
|
|
6362
6784
|
Image: true,
|
|
6363
6785
|
InlineImage: true,
|
|
6364
6786
|
Youtube: true,
|
|
6365
|
-
Insert: true,
|
|
6366
|
-
Heading: true,
|
|
6367
6787
|
FontFamily: true,
|
|
6368
6788
|
FontSize: true,
|
|
6789
|
+
Align: true,
|
|
6790
|
+
Heading: true,
|
|
6369
6791
|
Decorators: true,
|
|
6370
6792
|
CodeBlock: true,
|
|
6371
|
-
Align: true,
|
|
6372
6793
|
PageSetup: true
|
|
6373
6794
|
};
|
|
6374
6795
|
function sanitizePluginGroups(groups) {
|
|
6375
|
-
if (!groups || groups.length === 0) return [];
|
|
6796
|
+
if (!Array.isArray(groups) || groups.length === 0) return [];
|
|
6376
6797
|
return groups.map(
|
|
6377
|
-
(g) => (g
|
|
6798
|
+
(g) => (Array.isArray(g) ? g : []).map((t) => typeof t === "string" ? t.trim() : "").filter((t) => ALLOWED_TOKENS[t] === true)
|
|
6378
6799
|
).filter((g) => g.length > 0);
|
|
6379
6800
|
}
|
|
6380
6801
|
var ToolBarPlugins = (props) => {
|
|
@@ -6394,9 +6815,9 @@ var ToolBarPlugins = (props) => {
|
|
|
6394
6815
|
const [isLowercase, setIsLowercase] = useState(false);
|
|
6395
6816
|
const [isCapitalize, setIsCapitalize] = useState(false);
|
|
6396
6817
|
const [alignment, setAlignment] = useState("left");
|
|
6397
|
-
const [
|
|
6398
|
-
const
|
|
6399
|
-
const presetGroups = getToolbarGroupsByLevel(props.level);
|
|
6818
|
+
const [decoratorOpen, setDecoratorOpen] = useState(false);
|
|
6819
|
+
const decoratorSelectingRef = React9__default.useRef(false);
|
|
6820
|
+
const presetGroups = props.customToolbar ?? getToolbarGroupsByLevel(props.level);
|
|
6400
6821
|
const pluginGroups = useMemo(() => sanitizePluginGroups(presetGroups), [presetGroups]);
|
|
6401
6822
|
const updateToolbarPlugins = () => {
|
|
6402
6823
|
const selection = $getSelection();
|
|
@@ -6438,6 +6859,10 @@ var ToolBarPlugins = (props) => {
|
|
|
6438
6859
|
setSelectNodeType("paragraph");
|
|
6439
6860
|
return;
|
|
6440
6861
|
}
|
|
6862
|
+
if ($isAlphaListNode(element)) {
|
|
6863
|
+
setSelectNodeType("alpha");
|
|
6864
|
+
return;
|
|
6865
|
+
}
|
|
6441
6866
|
if ($isListNode(element)) {
|
|
6442
6867
|
const parentList = $getNearestNodeOfType(anchorNode, ListNode);
|
|
6443
6868
|
const type2 = parentList ? parentList.getTag() : element.getTag();
|
|
@@ -6449,23 +6874,15 @@ var ToolBarPlugins = (props) => {
|
|
|
6449
6874
|
["paragraph", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "quote", "code"].includes(type) ? type : "paragraph"
|
|
6450
6875
|
);
|
|
6451
6876
|
};
|
|
6452
|
-
const applyToBlock = React9__default.useCallback(
|
|
6453
|
-
(fn) => {
|
|
6454
|
-
editor.update(() => {
|
|
6455
|
-
const saved = lastSelectionRef.current;
|
|
6456
|
-
if (saved) $setSelection(saved.clone());
|
|
6457
|
-
const sel = $getSelection();
|
|
6458
|
-
if ($isRangeSelection(sel)) fn(sel);
|
|
6459
|
-
});
|
|
6460
|
-
},
|
|
6461
|
-
[editor]
|
|
6462
|
-
);
|
|
6463
6877
|
const formatQuote = () => {
|
|
6464
|
-
|
|
6878
|
+
editor.update(() => {
|
|
6879
|
+
const selection = $getSelection();
|
|
6880
|
+
if (!$isRangeSelection(selection)) return;
|
|
6465
6881
|
if (selectNodeType === "quote") {
|
|
6466
|
-
|
|
6882
|
+
formatParagraph(editor);
|
|
6467
6883
|
} else {
|
|
6468
|
-
$
|
|
6884
|
+
$splitBlocksAtLineBreaks(selection);
|
|
6885
|
+
$setBlocksType($getSelection(), () => $createQuoteNode());
|
|
6469
6886
|
}
|
|
6470
6887
|
});
|
|
6471
6888
|
};
|
|
@@ -6482,8 +6899,6 @@ var ToolBarPlugins = (props) => {
|
|
|
6482
6899
|
editor.registerCommand(
|
|
6483
6900
|
SELECTION_CHANGE_COMMAND,
|
|
6484
6901
|
() => {
|
|
6485
|
-
const sel = $getSelection();
|
|
6486
|
-
if ($isRangeSelection(sel)) lastSelectionRef.current = sel.clone();
|
|
6487
6902
|
updateToolbarPlugins();
|
|
6488
6903
|
return false;
|
|
6489
6904
|
},
|
|
@@ -6515,52 +6930,16 @@ var ToolBarPlugins = (props) => {
|
|
|
6515
6930
|
editor.dispatchCommand(FORMAT_TEXT_COMMAND, "highlight");
|
|
6516
6931
|
break;
|
|
6517
6932
|
case "leftAlign" /* LeftAlign */:
|
|
6518
|
-
|
|
6519
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6520
|
-
sel.getNodes().forEach((n) => {
|
|
6521
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6522
|
-
if (!seen.has(t.getKey())) {
|
|
6523
|
-
seen.add(t.getKey());
|
|
6524
|
-
t.setFormat("left");
|
|
6525
|
-
}
|
|
6526
|
-
});
|
|
6527
|
-
});
|
|
6933
|
+
applyAlignmentWithSplit("left");
|
|
6528
6934
|
break;
|
|
6529
6935
|
case "rightAlign" /* RightAlign */:
|
|
6530
|
-
|
|
6531
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6532
|
-
sel.getNodes().forEach((n) => {
|
|
6533
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6534
|
-
if (!seen.has(t.getKey())) {
|
|
6535
|
-
seen.add(t.getKey());
|
|
6536
|
-
t.setFormat("right");
|
|
6537
|
-
}
|
|
6538
|
-
});
|
|
6539
|
-
});
|
|
6936
|
+
applyAlignmentWithSplit("right");
|
|
6540
6937
|
break;
|
|
6541
6938
|
case "centerAlign" /* CenterAlign */:
|
|
6542
|
-
|
|
6543
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6544
|
-
sel.getNodes().forEach((n) => {
|
|
6545
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6546
|
-
if (!seen.has(t.getKey())) {
|
|
6547
|
-
seen.add(t.getKey());
|
|
6548
|
-
t.setFormat("center");
|
|
6549
|
-
}
|
|
6550
|
-
});
|
|
6551
|
-
});
|
|
6939
|
+
applyAlignmentWithSplit("center");
|
|
6552
6940
|
break;
|
|
6553
6941
|
case "justifyAlign" /* JustifyAlign */:
|
|
6554
|
-
|
|
6555
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6556
|
-
sel.getNodes().forEach((n) => {
|
|
6557
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6558
|
-
if (!seen.has(t.getKey())) {
|
|
6559
|
-
seen.add(t.getKey());
|
|
6560
|
-
t.setFormat("justify");
|
|
6561
|
-
}
|
|
6562
|
-
});
|
|
6563
|
-
});
|
|
6942
|
+
applyAlignmentWithSplit("justify");
|
|
6564
6943
|
break;
|
|
6565
6944
|
case "undo" /* Undo */:
|
|
6566
6945
|
editor.dispatchCommand(UNDO_COMMAND, void 0);
|
|
@@ -6579,9 +6958,32 @@ var ToolBarPlugins = (props) => {
|
|
|
6579
6958
|
break;
|
|
6580
6959
|
}
|
|
6581
6960
|
};
|
|
6961
|
+
const applyAlignmentWithSplit = (formatType) => {
|
|
6962
|
+
editor.update(() => {
|
|
6963
|
+
const selection = $getSelection();
|
|
6964
|
+
if (!$isRangeSelection(selection)) return;
|
|
6965
|
+
$splitBlocksAtLineBreaks(selection);
|
|
6966
|
+
const sel = $getSelection();
|
|
6967
|
+
if ($isRangeSelection(sel)) {
|
|
6968
|
+
$splitBlockAtPartialSelection(sel);
|
|
6969
|
+
}
|
|
6970
|
+
});
|
|
6971
|
+
editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, formatType);
|
|
6972
|
+
};
|
|
6582
6973
|
const updateHeading = (heading) => {
|
|
6583
|
-
|
|
6584
|
-
|
|
6974
|
+
editor.update(() => {
|
|
6975
|
+
const selection = $getSelection();
|
|
6976
|
+
if ($isRangeSelection(selection)) {
|
|
6977
|
+
$splitBlocksAtLineBreaks(selection);
|
|
6978
|
+
const sel = $getSelection();
|
|
6979
|
+
if ($isRangeSelection(sel)) {
|
|
6980
|
+
$splitBlockAtPartialSelection(sel);
|
|
6981
|
+
}
|
|
6982
|
+
$setBlocksType($getSelection(), () => $createHeadingNode(heading));
|
|
6983
|
+
}
|
|
6984
|
+
});
|
|
6985
|
+
editor.getEditorState().read(() => {
|
|
6986
|
+
updateToolbarPlugins();
|
|
6585
6987
|
});
|
|
6586
6988
|
};
|
|
6587
6989
|
const renderToken = (token, groupIndex, tokenIndex) => {
|
|
@@ -6593,7 +6995,6 @@ var ToolBarPlugins = (props) => {
|
|
|
6593
6995
|
const brand = palette.themePrimary;
|
|
6594
6996
|
const brandHover = palette.themeDarkAlt ?? brand;
|
|
6595
6997
|
const brandPressed = palette.themeDark ?? brand;
|
|
6596
|
-
palette.white;
|
|
6597
6998
|
const bgHover = palette.neutralLighter;
|
|
6598
6999
|
const bgPressed = palette.neutralLight;
|
|
6599
7000
|
const bgActive = palette.neutralLighterAlt ?? palette.neutralLighter;
|
|
@@ -6640,13 +7041,14 @@ var ToolBarPlugins = (props) => {
|
|
|
6640
7041
|
marginRight: 8,
|
|
6641
7042
|
verticalAlign: "middle"
|
|
6642
7043
|
};
|
|
6643
|
-
const isDisabled = !isEditable || !!props.readOnly;
|
|
6644
7044
|
switch (token) {
|
|
6645
7045
|
case "Bold":
|
|
6646
7046
|
return /* @__PURE__ */ jsx(
|
|
6647
7047
|
Button,
|
|
6648
7048
|
{
|
|
6649
7049
|
size: "small",
|
|
7050
|
+
"aria-label": "Bold",
|
|
7051
|
+
"aria-pressed": isBold,
|
|
6650
7052
|
disabled: !isEditable || props.readOnly,
|
|
6651
7053
|
icon: /* @__PURE__ */ jsx(TextBold24Regular, { style: { color: getIconColor(isBold) } }),
|
|
6652
7054
|
style: getButtonStyle(isBold),
|
|
@@ -6659,6 +7061,8 @@ var ToolBarPlugins = (props) => {
|
|
|
6659
7061
|
Button,
|
|
6660
7062
|
{
|
|
6661
7063
|
size: "small",
|
|
7064
|
+
"aria-label": "Italic",
|
|
7065
|
+
"aria-pressed": isItalic,
|
|
6662
7066
|
disabled: !isEditable || props.readOnly,
|
|
6663
7067
|
icon: /* @__PURE__ */ jsx(TextItalicFilled, { style: { color: getIconColor(isItalic) } }),
|
|
6664
7068
|
style: getButtonStyle(isItalic),
|
|
@@ -6671,6 +7075,8 @@ var ToolBarPlugins = (props) => {
|
|
|
6671
7075
|
Button,
|
|
6672
7076
|
{
|
|
6673
7077
|
size: "small",
|
|
7078
|
+
"aria-label": "Underline",
|
|
7079
|
+
"aria-pressed": isUnderline,
|
|
6674
7080
|
disabled: !isEditable || props.readOnly,
|
|
6675
7081
|
icon: /* @__PURE__ */ jsx(TextUnderlineFilled, { style: { color: getIconColor(isUnderline) } }),
|
|
6676
7082
|
style: getButtonStyle(isUnderline),
|
|
@@ -6681,7 +7087,14 @@ var ToolBarPlugins = (props) => {
|
|
|
6681
7087
|
case "ColorPicker":
|
|
6682
7088
|
return /* @__PURE__ */ jsx(ColorPickerPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6683
7089
|
case "Link":
|
|
6684
|
-
return /* @__PURE__ */ jsx(
|
|
7090
|
+
return /* @__PURE__ */ jsx(
|
|
7091
|
+
InsertLinkPlugin,
|
|
7092
|
+
{
|
|
7093
|
+
disabled: !isEditable || props.readOnly,
|
|
7094
|
+
setIsLinkEditMode: props.setIsLinkEditMode
|
|
7095
|
+
},
|
|
7096
|
+
key
|
|
7097
|
+
);
|
|
6685
7098
|
case "Table":
|
|
6686
7099
|
return /* @__PURE__ */ jsx(TableItemPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6687
7100
|
case "Image":
|
|
@@ -6689,7 +7102,9 @@ var ToolBarPlugins = (props) => {
|
|
|
6689
7102
|
InsertImageDialog,
|
|
6690
7103
|
{
|
|
6691
7104
|
activeEditor: editor,
|
|
6692
|
-
disabled: !isEditable || props.readOnly
|
|
7105
|
+
disabled: !isEditable || props.readOnly,
|
|
7106
|
+
maxImageSizeMB: props.maxImageSizeMB,
|
|
7107
|
+
validationMessages: props.validationMessages
|
|
6693
7108
|
},
|
|
6694
7109
|
key
|
|
6695
7110
|
);
|
|
@@ -6698,139 +7113,405 @@ var ToolBarPlugins = (props) => {
|
|
|
6698
7113
|
InsertInlineImageDialog,
|
|
6699
7114
|
{
|
|
6700
7115
|
activeEditor: editor,
|
|
6701
|
-
disabled: !isEditable || props.readOnly
|
|
7116
|
+
disabled: !isEditable || props.readOnly,
|
|
7117
|
+
maxImageSizeMB: props.maxImageSizeMB,
|
|
7118
|
+
validationMessages: props.validationMessages
|
|
6702
7119
|
},
|
|
6703
7120
|
key
|
|
6704
7121
|
);
|
|
6705
7122
|
case "Youtube":
|
|
6706
7123
|
return /* @__PURE__ */ jsx(YoutubeUploadPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6707
|
-
case "Insert": {
|
|
6708
|
-
const menuIconColor = isDisabled ? fgDisabled : fg;
|
|
6709
|
-
return /* @__PURE__ */ jsxs(React9__default.Fragment, { children: [
|
|
6710
|
-
/* @__PURE__ */ jsxs(Menu, { children: [
|
|
6711
|
-
/* @__PURE__ */ jsx(MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
6712
|
-
Button,
|
|
6713
|
-
{
|
|
6714
|
-
size: "small",
|
|
6715
|
-
disabled: isDisabled,
|
|
6716
|
-
icon: /* @__PURE__ */ jsx(AddRegular, { style: { color: menuIconColor } }),
|
|
6717
|
-
style: {
|
|
6718
|
-
...getButtonStyle(false),
|
|
6719
|
-
gap: 4,
|
|
6720
|
-
paddingInline: 8
|
|
6721
|
-
},
|
|
6722
|
-
children: "Insert"
|
|
6723
|
-
}
|
|
6724
|
-
) }),
|
|
6725
|
-
/* @__PURE__ */ jsx(MenuPopover, { children: /* @__PURE__ */ jsxs(MenuList, { children: [
|
|
6726
|
-
/* @__PURE__ */ jsx(
|
|
6727
|
-
MenuItem,
|
|
6728
|
-
{
|
|
6729
|
-
icon: /* @__PURE__ */ jsx(TableAddRegular, { style: { color: menuIconColor } }),
|
|
6730
|
-
onClick: () => !isDisabled && setActiveInsertDialog("table"),
|
|
6731
|
-
children: "Table"
|
|
6732
|
-
}
|
|
6733
|
-
),
|
|
6734
|
-
/* @__PURE__ */ jsx(
|
|
6735
|
-
MenuItem,
|
|
6736
|
-
{
|
|
6737
|
-
icon: /* @__PURE__ */ jsx(ImageAddRegular, { style: { color: menuIconColor } }),
|
|
6738
|
-
onClick: () => !isDisabled && setActiveInsertDialog("image"),
|
|
6739
|
-
children: "Image"
|
|
6740
|
-
}
|
|
6741
|
-
),
|
|
6742
|
-
/* @__PURE__ */ jsx(
|
|
6743
|
-
MenuItem,
|
|
6744
|
-
{
|
|
6745
|
-
icon: /* @__PURE__ */ jsx(ImageEditRegular, { style: { color: menuIconColor } }),
|
|
6746
|
-
onClick: () => !isDisabled && setActiveInsertDialog("inlineImage"),
|
|
6747
|
-
children: "Inline Image"
|
|
6748
|
-
}
|
|
6749
|
-
),
|
|
6750
|
-
/* @__PURE__ */ jsx(
|
|
6751
|
-
MenuItem,
|
|
6752
|
-
{
|
|
6753
|
-
icon: /* @__PURE__ */ jsx(VideoClipRegular, { style: { color: menuIconColor } }),
|
|
6754
|
-
onClick: () => !isDisabled && setActiveInsertDialog("youtube"),
|
|
6755
|
-
children: "YouTube"
|
|
6756
|
-
}
|
|
6757
|
-
)
|
|
6758
|
-
] }) })
|
|
6759
|
-
] }),
|
|
6760
|
-
/* @__PURE__ */ jsx(
|
|
6761
|
-
TableItemPlugin,
|
|
6762
|
-
{
|
|
6763
|
-
disabled: isDisabled,
|
|
6764
|
-
open: activeInsertDialog === "table",
|
|
6765
|
-
onClose: () => setActiveInsertDialog(null)
|
|
6766
|
-
}
|
|
6767
|
-
),
|
|
6768
|
-
/* @__PURE__ */ jsx(
|
|
6769
|
-
InsertImageDialog,
|
|
6770
|
-
{
|
|
6771
|
-
activeEditor: editor,
|
|
6772
|
-
disabled: isDisabled,
|
|
6773
|
-
open: activeInsertDialog === "image",
|
|
6774
|
-
onClose: () => setActiveInsertDialog(null)
|
|
6775
|
-
}
|
|
6776
|
-
),
|
|
6777
|
-
/* @__PURE__ */ jsx(
|
|
6778
|
-
InsertInlineImageDialog,
|
|
6779
|
-
{
|
|
6780
|
-
activeEditor: editor,
|
|
6781
|
-
disabled: isDisabled,
|
|
6782
|
-
open: activeInsertDialog === "inlineImage",
|
|
6783
|
-
onClose: () => setActiveInsertDialog(null)
|
|
6784
|
-
}
|
|
6785
|
-
),
|
|
6786
|
-
/* @__PURE__ */ jsx(
|
|
6787
|
-
YoutubeUploadPlugin,
|
|
6788
|
-
{
|
|
6789
|
-
disabled: isDisabled,
|
|
6790
|
-
open: activeInsertDialog === "youtube",
|
|
6791
|
-
onClose: () => setActiveInsertDialog(null)
|
|
6792
|
-
}
|
|
6793
|
-
)
|
|
6794
|
-
] }, key);
|
|
6795
|
-
}
|
|
6796
7124
|
case "Heading": {
|
|
6797
7125
|
const headingLabel = selectNodeType === "paragraph" ? "Normal" : HEADING_OPTION.find((h) => h.key === selectNodeType)?.text ?? selectNodeType;
|
|
6798
7126
|
return /* @__PURE__ */ jsxs(
|
|
6799
7127
|
Dropdown,
|
|
6800
7128
|
{
|
|
6801
|
-
title: "Add heading",
|
|
6802
|
-
id: `heading-option-${groupIndex}`,
|
|
6803
|
-
placeholder: "Format",
|
|
6804
|
-
disabled: !isEditable,
|
|
6805
|
-
style: { minWidth: "100px" },
|
|
6806
|
-
className: styles.dropdown,
|
|
6807
|
-
value: headingLabel,
|
|
6808
|
-
selectedOptions: [selectNodeType],
|
|
6809
|
-
onOptionSelect: (_, data) => {
|
|
6810
|
-
const val = data.optionValue;
|
|
6811
|
-
if (!val) return;
|
|
6812
|
-
if (val === "paragraph") {
|
|
6813
|
-
|
|
7129
|
+
title: "Add heading",
|
|
7130
|
+
id: `heading-option-${groupIndex}`,
|
|
7131
|
+
placeholder: "Format",
|
|
7132
|
+
disabled: !isEditable,
|
|
7133
|
+
style: { minWidth: "100px" },
|
|
7134
|
+
className: styles.dropdown,
|
|
7135
|
+
value: headingLabel,
|
|
7136
|
+
selectedOptions: [selectNodeType],
|
|
7137
|
+
onOptionSelect: (_, data) => {
|
|
7138
|
+
const val = data.optionValue;
|
|
7139
|
+
if (!val) return;
|
|
7140
|
+
if (val === "paragraph") {
|
|
7141
|
+
formatParagraph(editor);
|
|
7142
|
+
setSelectNodeType("paragraph");
|
|
7143
|
+
} else {
|
|
7144
|
+
updateHeading(val);
|
|
7145
|
+
setSelectNodeType(val);
|
|
7146
|
+
}
|
|
7147
|
+
},
|
|
7148
|
+
children: [
|
|
7149
|
+
/* @__PURE__ */ jsx(Option, { value: "paragraph", children: "Normal" }),
|
|
7150
|
+
HEADING_OPTION.map((option, idx) => /* @__PURE__ */ jsx(Option, { value: option.key, children: option.text }, `${option.key}-${idx}`))
|
|
7151
|
+
]
|
|
7152
|
+
},
|
|
7153
|
+
key
|
|
7154
|
+
);
|
|
7155
|
+
}
|
|
7156
|
+
case "FontFamily":
|
|
7157
|
+
return /* @__PURE__ */ jsx(FontFamilyPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
7158
|
+
case "FontSize":
|
|
7159
|
+
return /* @__PURE__ */ jsx(FontSizePlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
7160
|
+
case "|":
|
|
7161
|
+
return /* @__PURE__ */ jsx(ToolbarDivider, {}, key);
|
|
7162
|
+
// ── Standalone text-format toggle buttons ─────────────────────────────
|
|
7163
|
+
// These were previously only accessible inside the 'Decorators' dropdown.
|
|
7164
|
+
// Use them directly in customToolbar to show individual buttons instead.
|
|
7165
|
+
case "Strikethrough":
|
|
7166
|
+
return /* @__PURE__ */ jsx(
|
|
7167
|
+
Button,
|
|
7168
|
+
{
|
|
7169
|
+
size: "small",
|
|
7170
|
+
"aria-label": "Strikethrough",
|
|
7171
|
+
"aria-pressed": isStrikethrough,
|
|
7172
|
+
disabled: !isEditable || props.readOnly,
|
|
7173
|
+
icon: /* @__PURE__ */ jsx(TextStrikethroughFilled, { style: { color: getIconColor(isStrikethrough) } }),
|
|
7174
|
+
style: getButtonStyle(isStrikethrough),
|
|
7175
|
+
onClick: () => onHandleSelectOption("strike" /* Strikethrough */)
|
|
7176
|
+
},
|
|
7177
|
+
key
|
|
7178
|
+
);
|
|
7179
|
+
case "Subscript":
|
|
7180
|
+
return /* @__PURE__ */ jsx(
|
|
7181
|
+
Button,
|
|
7182
|
+
{
|
|
7183
|
+
size: "small",
|
|
7184
|
+
"aria-label": "Subscript",
|
|
7185
|
+
"aria-pressed": isSubscript,
|
|
7186
|
+
disabled: !isEditable || props.readOnly,
|
|
7187
|
+
icon: /* @__PURE__ */ jsx(TextSubscriptFilled, { style: { color: getIconColor(isSubscript) } }),
|
|
7188
|
+
style: getButtonStyle(isSubscript),
|
|
7189
|
+
onClick: () => onHandleSelectOption("subscript" /* Subscript */)
|
|
7190
|
+
},
|
|
7191
|
+
key
|
|
7192
|
+
);
|
|
7193
|
+
case "Superscript":
|
|
7194
|
+
return /* @__PURE__ */ jsx(
|
|
7195
|
+
Button,
|
|
7196
|
+
{
|
|
7197
|
+
size: "small",
|
|
7198
|
+
"aria-label": "Superscript",
|
|
7199
|
+
"aria-pressed": isSuperscript,
|
|
7200
|
+
disabled: !isEditable || props.readOnly,
|
|
7201
|
+
icon: /* @__PURE__ */ jsx(TextSuperscriptFilled, { style: { color: getIconColor(isSuperscript) } }),
|
|
7202
|
+
style: getButtonStyle(isSuperscript),
|
|
7203
|
+
onClick: () => onHandleSelectOption("superscript" /* Superscript */)
|
|
7204
|
+
},
|
|
7205
|
+
key
|
|
7206
|
+
);
|
|
7207
|
+
case "Highlight":
|
|
7208
|
+
return /* @__PURE__ */ jsx(
|
|
7209
|
+
Button,
|
|
7210
|
+
{
|
|
7211
|
+
size: "small",
|
|
7212
|
+
"aria-label": "Highlight",
|
|
7213
|
+
"aria-pressed": isHighlight,
|
|
7214
|
+
disabled: !isEditable || props.readOnly,
|
|
7215
|
+
icon: /* @__PURE__ */ jsx(
|
|
7216
|
+
HighlightAccentFilled,
|
|
7217
|
+
{
|
|
7218
|
+
style: { color: isEditable ? isHighlight ? brand : fg : fgDisabled }
|
|
7219
|
+
}
|
|
7220
|
+
),
|
|
7221
|
+
style: getButtonStyle(isHighlight),
|
|
7222
|
+
onClick: () => onHandleSelectOption("highlight" /* Highlight */)
|
|
7223
|
+
},
|
|
7224
|
+
key
|
|
7225
|
+
);
|
|
7226
|
+
case "Uppercase":
|
|
7227
|
+
return /* @__PURE__ */ jsx(
|
|
7228
|
+
Button,
|
|
7229
|
+
{
|
|
7230
|
+
size: "small",
|
|
7231
|
+
"aria-label": "Uppercase",
|
|
7232
|
+
"aria-pressed": isUppercase,
|
|
7233
|
+
disabled: !isEditable || props.readOnly,
|
|
7234
|
+
icon: /* @__PURE__ */ jsx(TextCaseUppercaseFilled, { style: { color: getIconColor(isUppercase) } }),
|
|
7235
|
+
style: getButtonStyle(isUppercase),
|
|
7236
|
+
onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "uppercase")
|
|
7237
|
+
},
|
|
7238
|
+
key
|
|
7239
|
+
);
|
|
7240
|
+
case "Lowercase":
|
|
7241
|
+
return /* @__PURE__ */ jsx(
|
|
7242
|
+
Button,
|
|
7243
|
+
{
|
|
7244
|
+
size: "small",
|
|
7245
|
+
"aria-label": "Lowercase",
|
|
7246
|
+
"aria-pressed": isLowercase,
|
|
7247
|
+
disabled: !isEditable || props.readOnly,
|
|
7248
|
+
icon: /* @__PURE__ */ jsx(TextCaseLowercaseFilled, { style: { color: getIconColor(isLowercase) } }),
|
|
7249
|
+
style: getButtonStyle(isLowercase),
|
|
7250
|
+
onClick: () => onHandleSelectOption("lowercase" /* Lowercase */)
|
|
7251
|
+
},
|
|
7252
|
+
key
|
|
7253
|
+
);
|
|
7254
|
+
case "Capitalize":
|
|
7255
|
+
return /* @__PURE__ */ jsx(
|
|
7256
|
+
Button,
|
|
7257
|
+
{
|
|
7258
|
+
size: "small",
|
|
7259
|
+
"aria-label": "Capitalize",
|
|
7260
|
+
"aria-pressed": isCapitalize,
|
|
7261
|
+
disabled: !isEditable || props.readOnly,
|
|
7262
|
+
icon: /* @__PURE__ */ jsx(TextCaseTitleFilled, { style: { color: getIconColor(isCapitalize) } }),
|
|
7263
|
+
style: getButtonStyle(isCapitalize),
|
|
7264
|
+
onClick: () => onHandleSelectOption("capitalize" /* Capitalize */)
|
|
7265
|
+
},
|
|
7266
|
+
key
|
|
7267
|
+
);
|
|
7268
|
+
// ── Standalone list toggle buttons ────────────────────────────────────
|
|
7269
|
+
case "BulletList":
|
|
7270
|
+
return /* @__PURE__ */ jsx(
|
|
7271
|
+
Button,
|
|
7272
|
+
{
|
|
7273
|
+
size: "small",
|
|
7274
|
+
"aria-label": "Bullet list",
|
|
7275
|
+
"aria-pressed": selectNodeType === "ul",
|
|
7276
|
+
disabled: !isEditable || props.readOnly,
|
|
7277
|
+
icon: /* @__PURE__ */ jsx(TextBulletListLtrFilled, { style: { color: getIconColor(selectNodeType === "ul") } }),
|
|
7278
|
+
style: getButtonStyle(selectNodeType === "ul"),
|
|
7279
|
+
onClick: () => editor.dispatchCommand(
|
|
7280
|
+
selectNodeType === "ul" ? REMOVE_LIST_COMMAND : INSERT_UNORDERED_LIST_COMMAND,
|
|
7281
|
+
void 0
|
|
7282
|
+
)
|
|
7283
|
+
},
|
|
7284
|
+
key
|
|
7285
|
+
);
|
|
7286
|
+
case "NumberList":
|
|
7287
|
+
return /* @__PURE__ */ jsx(
|
|
7288
|
+
Button,
|
|
7289
|
+
{
|
|
7290
|
+
size: "small",
|
|
7291
|
+
"aria-label": "Number list",
|
|
7292
|
+
"aria-pressed": selectNodeType === "ol",
|
|
7293
|
+
disabled: !isEditable || props.readOnly,
|
|
7294
|
+
icon: /* @__PURE__ */ jsx(TextNumberListLtrFilled, { style: { color: getIconColor(selectNodeType === "ol") } }),
|
|
7295
|
+
style: getButtonStyle(selectNodeType === "ol"),
|
|
7296
|
+
onClick: () => editor.dispatchCommand(
|
|
7297
|
+
selectNodeType === "ol" ? REMOVE_LIST_COMMAND : INSERT_ORDERED_LIST_COMMAND,
|
|
7298
|
+
void 0
|
|
7299
|
+
)
|
|
7300
|
+
},
|
|
7301
|
+
key
|
|
7302
|
+
);
|
|
7303
|
+
case "AlphabeticalList":
|
|
7304
|
+
return /* @__PURE__ */ jsx(
|
|
7305
|
+
Button,
|
|
7306
|
+
{
|
|
7307
|
+
size: "small",
|
|
7308
|
+
"aria-label": "Alphabetical list",
|
|
7309
|
+
"aria-pressed": selectNodeType === "alpha",
|
|
7310
|
+
disabled: !isEditable || props.readOnly,
|
|
7311
|
+
icon: /* @__PURE__ */ jsx(
|
|
7312
|
+
TextAlphaListLtrFilled,
|
|
7313
|
+
{
|
|
7314
|
+
style: { color: getIconColor(selectNodeType === "alpha") }
|
|
7315
|
+
}
|
|
7316
|
+
),
|
|
7317
|
+
style: getButtonStyle(selectNodeType === "alpha"),
|
|
7318
|
+
onClick: () => editor.update(() => $toggleAlphaList())
|
|
7319
|
+
},
|
|
7320
|
+
key
|
|
7321
|
+
);
|
|
7322
|
+
// ── Standalone block buttons ──────────────────────────────────────────
|
|
7323
|
+
case "Quote":
|
|
7324
|
+
return /* @__PURE__ */ jsx(
|
|
7325
|
+
Button,
|
|
7326
|
+
{
|
|
7327
|
+
size: "small",
|
|
7328
|
+
"aria-label": "Quote",
|
|
7329
|
+
"aria-pressed": selectNodeType === "quote",
|
|
7330
|
+
disabled: !isEditable || props.readOnly,
|
|
7331
|
+
icon: /* @__PURE__ */ jsx(CommentQuoteRegular, { style: { color: getIconColor(selectNodeType === "quote") } }),
|
|
7332
|
+
style: getButtonStyle(selectNodeType === "quote"),
|
|
7333
|
+
onClick: () => formatQuote()
|
|
7334
|
+
},
|
|
7335
|
+
key
|
|
7336
|
+
);
|
|
7337
|
+
case "PageBreak":
|
|
7338
|
+
return /* @__PURE__ */ jsx(
|
|
7339
|
+
Button,
|
|
7340
|
+
{
|
|
7341
|
+
size: "small",
|
|
7342
|
+
"aria-label": "Page break",
|
|
7343
|
+
disabled: !isEditable || props.readOnly,
|
|
7344
|
+
icon: /* @__PURE__ */ jsx(DocumentPageBreakRegular, { style: { color: getIconColor() } }),
|
|
7345
|
+
style: getButtonStyle(),
|
|
7346
|
+
onClick: () => editor.dispatchCommand(INSERT_PAGE_BREAK, void 0)
|
|
7347
|
+
},
|
|
7348
|
+
key
|
|
7349
|
+
);
|
|
7350
|
+
// ── Standalone heading-level toggle buttons ───────────────────────────
|
|
7351
|
+
// Each button sets (or toggles off) that specific heading level.
|
|
7352
|
+
// Clicking an active heading reverts to normal paragraph.
|
|
7353
|
+
case "H1":
|
|
7354
|
+
return /* @__PURE__ */ jsx(
|
|
7355
|
+
Button,
|
|
7356
|
+
{
|
|
7357
|
+
size: "small",
|
|
7358
|
+
"aria-label": "Heading 1",
|
|
7359
|
+
"aria-pressed": selectNodeType === "h1",
|
|
7360
|
+
disabled: !isEditable || props.readOnly,
|
|
7361
|
+
style: {
|
|
7362
|
+
...getButtonStyle(selectNodeType === "h1"),
|
|
7363
|
+
color: getIconColor(selectNodeType === "h1"),
|
|
7364
|
+
fontSize: 12,
|
|
7365
|
+
fontWeight: 600
|
|
7366
|
+
},
|
|
7367
|
+
onClick: () => {
|
|
7368
|
+
if (selectNodeType === "h1") {
|
|
7369
|
+
formatParagraph(editor);
|
|
7370
|
+
setSelectNodeType("paragraph");
|
|
7371
|
+
} else {
|
|
7372
|
+
updateHeading("h1");
|
|
7373
|
+
setSelectNodeType("h1");
|
|
7374
|
+
}
|
|
7375
|
+
},
|
|
7376
|
+
children: "H1"
|
|
7377
|
+
},
|
|
7378
|
+
key
|
|
7379
|
+
);
|
|
7380
|
+
case "H2":
|
|
7381
|
+
return /* @__PURE__ */ jsx(
|
|
7382
|
+
Button,
|
|
7383
|
+
{
|
|
7384
|
+
size: "small",
|
|
7385
|
+
"aria-label": "Heading 2",
|
|
7386
|
+
"aria-pressed": selectNodeType === "h2",
|
|
7387
|
+
disabled: !isEditable || props.readOnly,
|
|
7388
|
+
style: {
|
|
7389
|
+
...getButtonStyle(selectNodeType === "h2"),
|
|
7390
|
+
color: getIconColor(selectNodeType === "h2"),
|
|
7391
|
+
fontSize: 12,
|
|
7392
|
+
fontWeight: 600
|
|
7393
|
+
},
|
|
7394
|
+
onClick: () => {
|
|
7395
|
+
if (selectNodeType === "h2") {
|
|
7396
|
+
formatParagraph(editor);
|
|
7397
|
+
setSelectNodeType("paragraph");
|
|
7398
|
+
} else {
|
|
7399
|
+
updateHeading("h2");
|
|
7400
|
+
setSelectNodeType("h2");
|
|
7401
|
+
}
|
|
7402
|
+
},
|
|
7403
|
+
children: "H2"
|
|
7404
|
+
},
|
|
7405
|
+
key
|
|
7406
|
+
);
|
|
7407
|
+
case "H3":
|
|
7408
|
+
return /* @__PURE__ */ jsx(
|
|
7409
|
+
Button,
|
|
7410
|
+
{
|
|
7411
|
+
size: "small",
|
|
7412
|
+
"aria-label": "Heading 3",
|
|
7413
|
+
"aria-pressed": selectNodeType === "h3",
|
|
7414
|
+
disabled: !isEditable || props.readOnly,
|
|
7415
|
+
style: {
|
|
7416
|
+
...getButtonStyle(selectNodeType === "h3"),
|
|
7417
|
+
color: getIconColor(selectNodeType === "h3"),
|
|
7418
|
+
fontSize: 12,
|
|
7419
|
+
fontWeight: 600
|
|
7420
|
+
},
|
|
7421
|
+
onClick: () => {
|
|
7422
|
+
if (selectNodeType === "h3") {
|
|
7423
|
+
formatParagraph(editor);
|
|
7424
|
+
setSelectNodeType("paragraph");
|
|
7425
|
+
} else {
|
|
7426
|
+
updateHeading("h3");
|
|
7427
|
+
setSelectNodeType("h3");
|
|
7428
|
+
}
|
|
7429
|
+
},
|
|
7430
|
+
children: "H3"
|
|
7431
|
+
},
|
|
7432
|
+
key
|
|
7433
|
+
);
|
|
7434
|
+
case "H4":
|
|
7435
|
+
return /* @__PURE__ */ jsx(
|
|
7436
|
+
Button,
|
|
7437
|
+
{
|
|
7438
|
+
size: "small",
|
|
7439
|
+
"aria-label": "Heading 4",
|
|
7440
|
+
"aria-pressed": selectNodeType === "h4",
|
|
7441
|
+
disabled: !isEditable || props.readOnly,
|
|
7442
|
+
style: {
|
|
7443
|
+
...getButtonStyle(selectNodeType === "h4"),
|
|
7444
|
+
color: getIconColor(selectNodeType === "h4"),
|
|
7445
|
+
fontSize: 12,
|
|
7446
|
+
fontWeight: 600
|
|
7447
|
+
},
|
|
7448
|
+
onClick: () => {
|
|
7449
|
+
if (selectNodeType === "h4") {
|
|
7450
|
+
formatParagraph(editor);
|
|
7451
|
+
setSelectNodeType("paragraph");
|
|
7452
|
+
} else {
|
|
7453
|
+
updateHeading("h4");
|
|
7454
|
+
setSelectNodeType("h4");
|
|
7455
|
+
}
|
|
7456
|
+
},
|
|
7457
|
+
children: "H4"
|
|
7458
|
+
},
|
|
7459
|
+
key
|
|
7460
|
+
);
|
|
7461
|
+
case "H5":
|
|
7462
|
+
return /* @__PURE__ */ jsx(
|
|
7463
|
+
Button,
|
|
7464
|
+
{
|
|
7465
|
+
size: "small",
|
|
7466
|
+
"aria-label": "Heading 5",
|
|
7467
|
+
"aria-pressed": selectNodeType === "h5",
|
|
7468
|
+
disabled: !isEditable || props.readOnly,
|
|
7469
|
+
style: {
|
|
7470
|
+
...getButtonStyle(selectNodeType === "h5"),
|
|
7471
|
+
color: getIconColor(selectNodeType === "h5"),
|
|
7472
|
+
fontSize: 12,
|
|
7473
|
+
fontWeight: 600
|
|
7474
|
+
},
|
|
7475
|
+
onClick: () => {
|
|
7476
|
+
if (selectNodeType === "h5") {
|
|
7477
|
+
formatParagraph(editor);
|
|
6814
7478
|
setSelectNodeType("paragraph");
|
|
6815
7479
|
} else {
|
|
6816
|
-
updateHeading(
|
|
6817
|
-
setSelectNodeType(
|
|
7480
|
+
updateHeading("h5");
|
|
7481
|
+
setSelectNodeType("h5");
|
|
6818
7482
|
}
|
|
6819
7483
|
},
|
|
6820
|
-
children:
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
7484
|
+
children: "H5"
|
|
7485
|
+
},
|
|
7486
|
+
key
|
|
7487
|
+
);
|
|
7488
|
+
case "H6":
|
|
7489
|
+
return /* @__PURE__ */ jsx(
|
|
7490
|
+
Button,
|
|
7491
|
+
{
|
|
7492
|
+
size: "small",
|
|
7493
|
+
"aria-label": "Heading 6",
|
|
7494
|
+
"aria-pressed": selectNodeType === "h6",
|
|
7495
|
+
disabled: !isEditable || props.readOnly,
|
|
7496
|
+
style: {
|
|
7497
|
+
...getButtonStyle(selectNodeType === "h6"),
|
|
7498
|
+
color: getIconColor(selectNodeType === "h6"),
|
|
7499
|
+
fontSize: 12,
|
|
7500
|
+
fontWeight: 600
|
|
7501
|
+
},
|
|
7502
|
+
onClick: () => {
|
|
7503
|
+
if (selectNodeType === "h6") {
|
|
7504
|
+
formatParagraph(editor);
|
|
7505
|
+
setSelectNodeType("paragraph");
|
|
7506
|
+
} else {
|
|
7507
|
+
updateHeading("h6");
|
|
7508
|
+
setSelectNodeType("h6");
|
|
7509
|
+
}
|
|
7510
|
+
},
|
|
7511
|
+
children: "H6"
|
|
6824
7512
|
},
|
|
6825
7513
|
key
|
|
6826
7514
|
);
|
|
6827
|
-
}
|
|
6828
|
-
case "FontFamily":
|
|
6829
|
-
return /* @__PURE__ */ jsx(FontFamilyPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6830
|
-
case "FontSize":
|
|
6831
|
-
return /* @__PURE__ */ jsx(FontSizePlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6832
|
-
case "|":
|
|
6833
|
-
return /* @__PURE__ */ jsx(ToolbarDivider, {}, key);
|
|
6834
7515
|
case "Decorators": {
|
|
6835
7516
|
const activeDecorators = [
|
|
6836
7517
|
...isUppercase ? ["uppercase"] : [],
|
|
@@ -6842,6 +7523,7 @@ var ToolBarPlugins = (props) => {
|
|
|
6842
7523
|
...isHighlight ? ["highlight"] : [],
|
|
6843
7524
|
...selectNodeType === "ul" ? ["ul-list"] : [],
|
|
6844
7525
|
...selectNodeType === "ol" ? ["ol-list"] : [],
|
|
7526
|
+
...selectNodeType === "alpha" ? ["al-list"] : [],
|
|
6845
7527
|
...selectNodeType === "quote" ? ["quote"] : []
|
|
6846
7528
|
];
|
|
6847
7529
|
const DECORATOR_LABEL = {
|
|
@@ -6854,6 +7536,7 @@ var ToolBarPlugins = (props) => {
|
|
|
6854
7536
|
highlight: "Highlight",
|
|
6855
7537
|
"ul-list": "Bullet list",
|
|
6856
7538
|
"ol-list": "Number list",
|
|
7539
|
+
"al-list": "Alphabetical list",
|
|
6857
7540
|
quote: "Quote"
|
|
6858
7541
|
};
|
|
6859
7542
|
const decoratorValue = activeDecorators.length === 0 ? "" : activeDecorators.length === 1 ? DECORATOR_LABEL[activeDecorators[0]] : `${DECORATOR_LABEL[activeDecorators[0]]} +${activeDecorators.length - 1}`;
|
|
@@ -6870,7 +7553,16 @@ var ToolBarPlugins = (props) => {
|
|
|
6870
7553
|
button: { style: dropdownButtonStyle },
|
|
6871
7554
|
expandIcon: { style: dropdownExpandIconStyle },
|
|
6872
7555
|
listbox: { style: { minInlineSize: "180px" } },
|
|
7556
|
+
open: decoratorOpen,
|
|
7557
|
+
onOpenChange: (_, data) => {
|
|
7558
|
+
if (decoratorSelectingRef.current) {
|
|
7559
|
+
decoratorSelectingRef.current = false;
|
|
7560
|
+
return;
|
|
7561
|
+
}
|
|
7562
|
+
setDecoratorOpen(data.open);
|
|
7563
|
+
},
|
|
6873
7564
|
onOptionSelect: (_, data) => {
|
|
7565
|
+
decoratorSelectingRef.current = true;
|
|
6874
7566
|
switch (data.optionValue) {
|
|
6875
7567
|
case "uppercase":
|
|
6876
7568
|
editor.dispatchCommand(FORMAT_TEXT_COMMAND, "uppercase");
|
|
@@ -6894,10 +7586,19 @@ var ToolBarPlugins = (props) => {
|
|
|
6894
7586
|
onHandleSelectOption("highlight" /* Highlight */);
|
|
6895
7587
|
break;
|
|
6896
7588
|
case "ul-list":
|
|
6897
|
-
editor.dispatchCommand(
|
|
7589
|
+
editor.dispatchCommand(
|
|
7590
|
+
selectNodeType === "ul" ? REMOVE_LIST_COMMAND : INSERT_UNORDERED_LIST_COMMAND,
|
|
7591
|
+
void 0
|
|
7592
|
+
);
|
|
6898
7593
|
break;
|
|
6899
7594
|
case "ol-list":
|
|
6900
|
-
editor.dispatchCommand(
|
|
7595
|
+
editor.dispatchCommand(
|
|
7596
|
+
selectNodeType === "ol" ? REMOVE_LIST_COMMAND : INSERT_ORDERED_LIST_COMMAND,
|
|
7597
|
+
void 0
|
|
7598
|
+
);
|
|
7599
|
+
break;
|
|
7600
|
+
case "al-list":
|
|
7601
|
+
editor.update(() => $toggleAlphaList());
|
|
6901
7602
|
break;
|
|
6902
7603
|
case "page-break":
|
|
6903
7604
|
editor.dispatchCommand(INSERT_PAGE_BREAK, void 0);
|
|
@@ -6933,7 +7634,12 @@ var ToolBarPlugins = (props) => {
|
|
|
6933
7634
|
"Superscript"
|
|
6934
7635
|
] }),
|
|
6935
7636
|
/* @__PURE__ */ jsxs(Option, { value: "highlight", text: "Highlight", children: [
|
|
6936
|
-
/* @__PURE__ */ jsx(
|
|
7637
|
+
/* @__PURE__ */ jsx(
|
|
7638
|
+
HighlightAccentFilled,
|
|
7639
|
+
{
|
|
7640
|
+
style: { ...optionIconStyle, color: isEditable ? brand : fgDisabled }
|
|
7641
|
+
}
|
|
7642
|
+
),
|
|
6937
7643
|
"Highlight"
|
|
6938
7644
|
] }),
|
|
6939
7645
|
/* @__PURE__ */ jsxs(Option, { value: "ul-list", text: "Bullet list", children: [
|
|
@@ -6944,6 +7650,10 @@ var ToolBarPlugins = (props) => {
|
|
|
6944
7650
|
/* @__PURE__ */ jsx(TextNumberListLtrFilled, { style: optionIconStyle }),
|
|
6945
7651
|
"Number list"
|
|
6946
7652
|
] }),
|
|
7653
|
+
/* @__PURE__ */ jsxs(Option, { value: "al-list", text: "Alphabetical list", children: [
|
|
7654
|
+
/* @__PURE__ */ jsx(TextAlphaListLtrFilled, { style: optionIconStyle }),
|
|
7655
|
+
"Alphabetical list"
|
|
7656
|
+
] }),
|
|
6947
7657
|
/* @__PURE__ */ jsxs(Option, { value: "page-break", text: "Page Break", children: [
|
|
6948
7658
|
/* @__PURE__ */ jsx(DocumentPageBreakRegular, { style: optionIconStyle }),
|
|
6949
7659
|
"Page break"
|
|
@@ -6969,10 +7679,30 @@ var ToolBarPlugins = (props) => {
|
|
|
6969
7679
|
// );
|
|
6970
7680
|
case "Align": {
|
|
6971
7681
|
const ALIGN_OPTIONS = [
|
|
6972
|
-
{
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
7682
|
+
{
|
|
7683
|
+
value: "left",
|
|
7684
|
+
label: "Left Align",
|
|
7685
|
+
icon: /* @__PURE__ */ jsx(TextAlignLeftFilled, { style: optionIconStyle }),
|
|
7686
|
+
action: "leftAlign" /* LeftAlign */
|
|
7687
|
+
},
|
|
7688
|
+
{
|
|
7689
|
+
value: "center",
|
|
7690
|
+
label: "Center Align",
|
|
7691
|
+
icon: /* @__PURE__ */ jsx(TextAlignCenterFilled, { style: optionIconStyle }),
|
|
7692
|
+
action: "centerAlign" /* CenterAlign */
|
|
7693
|
+
},
|
|
7694
|
+
{
|
|
7695
|
+
value: "right",
|
|
7696
|
+
label: "Right Align",
|
|
7697
|
+
icon: /* @__PURE__ */ jsx(TextAlignRightFilled, { style: optionIconStyle }),
|
|
7698
|
+
action: "rightAlign" /* RightAlign */
|
|
7699
|
+
},
|
|
7700
|
+
{
|
|
7701
|
+
value: "justify",
|
|
7702
|
+
label: "Justify Align",
|
|
7703
|
+
icon: /* @__PURE__ */ jsx(TextAlignJustifyFilled, { style: optionIconStyle }),
|
|
7704
|
+
action: "justifyAlign" /* JustifyAlign */
|
|
7705
|
+
}
|
|
6976
7706
|
];
|
|
6977
7707
|
const alignLabel = ALIGN_OPTIONS.find((o) => o.value === alignment)?.label ?? "Left Align";
|
|
6978
7708
|
return /* @__PURE__ */ jsx(
|
|
@@ -7188,32 +7918,31 @@ function BrowserSpellCheckPlugin({ enabled }) {
|
|
|
7188
7918
|
}, [editor, enabled]);
|
|
7189
7919
|
return null;
|
|
7190
7920
|
}
|
|
7191
|
-
function
|
|
7192
|
-
|
|
7193
|
-
}) {
|
|
7194
|
-
const [editor] = useLexicalComposerContext();
|
|
7195
|
-
useEffect(() => {
|
|
7196
|
-
return editor.registerUpdateListener(({ editorState }) => {
|
|
7197
|
-
editorState.read(() => {
|
|
7198
|
-
const text = $getRoot().getTextContent();
|
|
7199
|
-
const words = text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
|
|
7200
|
-
onCountChange(words);
|
|
7201
|
-
});
|
|
7202
|
-
});
|
|
7203
|
-
}, [editor, onCountChange]);
|
|
7204
|
-
return null;
|
|
7205
|
-
}
|
|
7206
|
-
function CharCountPlugin({
|
|
7207
|
-
onCountChange
|
|
7921
|
+
function ContentMetricsPlugin({
|
|
7922
|
+
onMetricsChange
|
|
7208
7923
|
}) {
|
|
7209
7924
|
const [editor] = useLexicalComposerContext();
|
|
7925
|
+
const prevRef = useRef({ words: 0, chars: 0, images: 0, links: 0, tables: 0 });
|
|
7210
7926
|
useEffect(() => {
|
|
7211
|
-
return editor.registerUpdateListener(({
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7927
|
+
return editor.registerUpdateListener(({ dirtyElements, dirtyLeaves }) => {
|
|
7928
|
+
if (dirtyElements.size === 0 && dirtyLeaves.size === 0) return;
|
|
7929
|
+
const root = editor.getRootElement();
|
|
7930
|
+
if (!root) return;
|
|
7931
|
+
const text = root.innerText ?? "";
|
|
7932
|
+
const trimmed = text.trim();
|
|
7933
|
+
const words = trimmed === "" ? 0 : trimmed.split(/\s+/).length;
|
|
7934
|
+
const chars = trimmed.length;
|
|
7935
|
+
const images = root.querySelectorAll("img").length;
|
|
7936
|
+
const links = root.querySelectorAll("a[href]").length;
|
|
7937
|
+
const tables = root.querySelectorAll("table").length;
|
|
7938
|
+
const prev = prevRef.current;
|
|
7939
|
+
if (prev.words !== words || prev.chars !== chars || prev.images !== images || prev.links !== links || prev.tables !== tables) {
|
|
7940
|
+
const next = { words, chars, images, links, tables };
|
|
7941
|
+
prevRef.current = next;
|
|
7942
|
+
onMetricsChange(next);
|
|
7943
|
+
}
|
|
7215
7944
|
});
|
|
7216
|
-
}, [editor,
|
|
7945
|
+
}, [editor, onMetricsChange]);
|
|
7217
7946
|
return null;
|
|
7218
7947
|
}
|
|
7219
7948
|
function FocusEventsPlugin({
|
|
@@ -7234,7 +7963,8 @@ function FocusEventsPlugin({
|
|
|
7234
7963
|
const next = e.relatedTarget;
|
|
7235
7964
|
const container = containerRef.current;
|
|
7236
7965
|
const stillInside = !!next && (container ? container.contains(next) : root.contains(next));
|
|
7237
|
-
|
|
7966
|
+
const isEditorPortal = !!next?.closest?.("[data-lexical-editor-portal]");
|
|
7967
|
+
if (stillInside || isEditorPortal) return;
|
|
7238
7968
|
editor.update(() => {
|
|
7239
7969
|
$setSelection(null);
|
|
7240
7970
|
});
|
|
@@ -7289,10 +8019,7 @@ function _adaptRawSpell(data, text) {
|
|
|
7289
8019
|
}
|
|
7290
8020
|
const rawGrammar = data.grammar_correction ?? data.improved_text;
|
|
7291
8021
|
const grammarCorrection = rawGrammar && rawGrammar.trim() !== text.trim() ? rawGrammar.trim() : void 0;
|
|
7292
|
-
return {
|
|
7293
|
-
issues: issues.sort((a, b) => a.offset - b.offset),
|
|
7294
|
-
grammarCorrection
|
|
7295
|
-
};
|
|
8022
|
+
return { issues: issues.sort((a, b) => a.offset - b.offset), grammarCorrection };
|
|
7296
8023
|
}
|
|
7297
8024
|
function _adaptRawSuggest(data) {
|
|
7298
8025
|
if (!data) return null;
|
|
@@ -7347,386 +8074,458 @@ function _makeQueryFn(fn) {
|
|
|
7347
8074
|
};
|
|
7348
8075
|
};
|
|
7349
8076
|
}
|
|
7350
|
-
|
|
7351
|
-
const
|
|
7352
|
-
const
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
)
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
[]
|
|
7368
|
-
);
|
|
7369
|
-
const [charCount, setCharCount] = useState(0);
|
|
7370
|
-
const handleCharCount = useCallback(
|
|
7371
|
-
(count) => setCharCount(count),
|
|
7372
|
-
[]
|
|
7373
|
-
);
|
|
7374
|
-
const [refErrors, setRefErrors] = useState([]);
|
|
7375
|
-
const [pageSetup, setPageSetup] = useState(DEFAULT_PAGE_SETUP);
|
|
7376
|
-
const pageCanvas = resolvePageCanvasMetrics(pageSetup);
|
|
7377
|
-
const contentEditableDomRef = useRef(null);
|
|
7378
|
-
const previousOverLimitRef = useRef(false);
|
|
7379
|
-
const focusedRef = useRef(false);
|
|
7380
|
-
const setFocused = (focused) => {
|
|
7381
|
-
focusedRef.current = focused;
|
|
7382
|
-
};
|
|
7383
|
-
const containerRef = useRef(null);
|
|
7384
|
-
const onAnchorRef = (elem) => {
|
|
7385
|
-
if (elem) setFloatingAnchorElem(elem);
|
|
7386
|
-
};
|
|
7387
|
-
const initialConfig = {
|
|
7388
|
-
namespace: props.namespace,
|
|
7389
|
-
theme,
|
|
7390
|
-
onError: () => {
|
|
7391
|
-
},
|
|
7392
|
-
nodes: [
|
|
7393
|
-
HeadingNode,
|
|
7394
|
-
QuoteNode,
|
|
7395
|
-
CodeHighlightNode,
|
|
7396
|
-
CodeNode,
|
|
7397
|
-
ListNode,
|
|
7398
|
-
ListItemNode,
|
|
7399
|
-
LinkNode,
|
|
7400
|
-
AutoLinkNode,
|
|
7401
|
-
TableNode,
|
|
7402
|
-
TableRowNode,
|
|
7403
|
-
TableCellNode,
|
|
7404
|
-
ImageNode,
|
|
7405
|
-
InlineImageNode,
|
|
7406
|
-
YouTubeNode,
|
|
7407
|
-
PageBreakNode,
|
|
7408
|
-
AutocompleteNode,
|
|
7409
|
-
SpellErrorNode,
|
|
7410
|
-
HtmlBlockNode
|
|
7411
|
-
]
|
|
7412
|
-
};
|
|
7413
|
-
const EditorStyles = mergeStyleSets({
|
|
7414
|
-
editorPlaceholder: {
|
|
7415
|
-
color: "var(--colorNeutralForeground3, grey)",
|
|
7416
|
-
position: "absolute",
|
|
7417
|
-
top: props.level !== "none" /* None */ ? "17px" : "27px",
|
|
7418
|
-
left: pageCanvas.paddingPx,
|
|
7419
|
-
right: pageCanvas.paddingPx,
|
|
7420
|
-
fontSize: "14px",
|
|
7421
|
-
pointerEvents: "none",
|
|
7422
|
-
userSelect: "none"
|
|
7423
|
-
},
|
|
7424
|
-
contentEditor: {
|
|
7425
|
-
zIndex: 0,
|
|
7426
|
-
flex: "auto",
|
|
7427
|
-
outline: "none",
|
|
7428
|
-
overflow: "auto",
|
|
7429
|
-
marginTop: "0px",
|
|
7430
|
-
position: "relative",
|
|
7431
|
-
background: "var(--colorNeutralBackground1, #ffffff)",
|
|
7432
|
-
justifyContent: "center",
|
|
7433
|
-
height: props.contentHeight ?? "100%",
|
|
7434
|
-
...isReadOnly && {
|
|
7435
|
-
cursor: "not-allowed",
|
|
7436
|
-
opacity: 0.75,
|
|
7437
|
-
userSelect: "text"
|
|
7438
|
-
}
|
|
7439
|
-
}
|
|
7440
|
-
});
|
|
7441
|
-
const urlRegExp = new RegExp(
|
|
7442
|
-
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/
|
|
7443
|
-
);
|
|
7444
|
-
const validateUrl = (url) => url === "https://" || urlRegExp.test(url);
|
|
7445
|
-
const handleReadOnlyClickCapture = (e) => {
|
|
7446
|
-
if (!isReadOnly) return;
|
|
7447
|
-
const target = e.target;
|
|
7448
|
-
const anchor = target?.closest?.("a");
|
|
7449
|
-
if (anchor) {
|
|
7450
|
-
e.preventDefault();
|
|
7451
|
-
e.stopPropagation();
|
|
7452
|
-
}
|
|
7453
|
-
};
|
|
7454
|
-
const [touched, setTouched] = useState(false);
|
|
7455
|
-
const isOverLimit = props.wordLimit !== void 0 && wordCount > props.wordLimit;
|
|
7456
|
-
const internalErrors = [];
|
|
7457
|
-
if (isOverLimit) {
|
|
7458
|
-
const m = props.errorMessages?.wordLimitExceeded;
|
|
7459
|
-
internalErrors.push(
|
|
7460
|
-
typeof m === "function" ? m(wordCount, props.wordLimit) : m ?? `Word limit exceeded (${wordCount} / ${props.wordLimit} words used)`
|
|
7461
|
-
);
|
|
7462
|
-
}
|
|
7463
|
-
if (props.required && touched && wordCount === 0) {
|
|
7464
|
-
internalErrors.push(
|
|
7465
|
-
props.errorMessages?.required ?? "This field is required"
|
|
7466
|
-
);
|
|
7467
|
-
}
|
|
7468
|
-
if (props.minWords !== void 0 && touched && wordCount < props.minWords) {
|
|
7469
|
-
const m = props.errorMessages?.minWords;
|
|
7470
|
-
internalErrors.push(
|
|
7471
|
-
typeof m === "function" ? m(wordCount, props.minWords) : m ?? `Minimum ${props.minWords} words required (${wordCount} entered)`
|
|
7472
|
-
);
|
|
7473
|
-
}
|
|
7474
|
-
if (props.maxChars !== void 0 && charCount > props.maxChars) {
|
|
7475
|
-
const m = props.errorMessages?.maxCharsExceeded;
|
|
7476
|
-
internalErrors.push(
|
|
7477
|
-
typeof m === "function" ? m(charCount, props.maxChars) : m ?? `Character limit exceeded (${charCount} / ${props.maxChars} characters used)`
|
|
8077
|
+
function EditorReadyPlugin({ onReady }) {
|
|
8078
|
+
const [editor] = useLexicalComposerContext();
|
|
8079
|
+
const calledRef = useRef(false);
|
|
8080
|
+
useEffect(() => {
|
|
8081
|
+
if (!onReady || calledRef.current) return;
|
|
8082
|
+
calledRef.current = true;
|
|
8083
|
+
onReady(editor);
|
|
8084
|
+
}, [editor, onReady]);
|
|
8085
|
+
return null;
|
|
8086
|
+
}
|
|
8087
|
+
var ContentEditorComponent = forwardRef(
|
|
8088
|
+
(props, ref) => {
|
|
8089
|
+
const isReadOnly = !!props.readOnly;
|
|
8090
|
+
const resolvedSpellCheck = React9__default.useMemo(
|
|
8091
|
+
() => props.spellCheckFn ? _makeSpellCheckFn(props.spellCheckFn) : props.useSpellCheck,
|
|
8092
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
8093
|
+
[props.spellCheckFn, props.useSpellCheck]
|
|
7478
8094
|
);
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
typeof m === "function" ? m(charCount, props.minChars) : m ?? `Minimum ${props.minChars} characters required (${charCount} entered)`
|
|
8095
|
+
const resolvedQuery = React9__default.useMemo(
|
|
8096
|
+
() => props.suggestFn ? _makeQueryFn(props.suggestFn) : props.useQuery,
|
|
8097
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
8098
|
+
[props.suggestFn, props.useQuery]
|
|
7484
8099
|
);
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
const
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
}
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
8100
|
+
const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
|
|
8101
|
+
const [isLinkEditMode, setIsLinkEditMode] = useState(false);
|
|
8102
|
+
const [metrics, setMetrics] = useState({
|
|
8103
|
+
words: 0,
|
|
8104
|
+
chars: 0,
|
|
8105
|
+
images: 0,
|
|
8106
|
+
links: 0,
|
|
8107
|
+
tables: 0
|
|
8108
|
+
});
|
|
8109
|
+
const handleMetrics = useCallback((m) => setMetrics(m), []);
|
|
8110
|
+
const [pageSetup, setPageSetup] = useState(DEFAULT_PAGE_SETUP);
|
|
8111
|
+
const pageCanvas = resolvePageCanvasMetrics(pageSetup);
|
|
8112
|
+
const wordCount = metrics.words;
|
|
8113
|
+
const contentEditableDomRef = useRef(null);
|
|
8114
|
+
const previousOverLimitRef = useRef(false);
|
|
8115
|
+
const focusedRef = useRef(false);
|
|
8116
|
+
const setFocused = (focused) => {
|
|
8117
|
+
focusedRef.current = focused;
|
|
8118
|
+
};
|
|
8119
|
+
const containerRef = useRef(null);
|
|
8120
|
+
const onAnchorRef = (elem) => {
|
|
8121
|
+
if (elem) setFloatingAnchorElem(elem);
|
|
8122
|
+
};
|
|
8123
|
+
const initialConfig = React9__default.useMemo(() => {
|
|
8124
|
+
const config = {
|
|
8125
|
+
namespace: props.namespace ?? "",
|
|
8126
|
+
theme,
|
|
8127
|
+
onError: () => {
|
|
8128
|
+
},
|
|
8129
|
+
nodes: [
|
|
8130
|
+
HeadingNode,
|
|
8131
|
+
QuoteNode,
|
|
8132
|
+
CodeHighlightNode,
|
|
8133
|
+
CodeNode,
|
|
8134
|
+
ListNode,
|
|
8135
|
+
ListItemNode,
|
|
8136
|
+
AlphaListNode,
|
|
8137
|
+
LinkNode,
|
|
8138
|
+
AutoLinkNode,
|
|
8139
|
+
TableNode,
|
|
8140
|
+
TableRowNode,
|
|
8141
|
+
TableCellNode,
|
|
8142
|
+
ImageNode,
|
|
8143
|
+
InlineImageNode,
|
|
8144
|
+
YouTubeNode,
|
|
8145
|
+
PageBreakNode,
|
|
8146
|
+
AutocompleteNode,
|
|
8147
|
+
SpellErrorNode,
|
|
8148
|
+
HtmlBlockNode
|
|
8149
|
+
]
|
|
8150
|
+
};
|
|
8151
|
+
props.onBeforeInitialize?.(config);
|
|
8152
|
+
return config;
|
|
8153
|
+
}, []);
|
|
8154
|
+
const EditorStyles = mergeStyleSets({
|
|
8155
|
+
editorPlaceholder: {
|
|
8156
|
+
color: "var(--colorNeutralForeground3, grey)",
|
|
8157
|
+
position: "absolute",
|
|
8158
|
+
top: props.level !== "none" /* None */ ? "17px" : "27px",
|
|
8159
|
+
left: pageCanvas.paddingPx,
|
|
8160
|
+
right: pageCanvas.paddingPx,
|
|
8161
|
+
fontSize: "14px",
|
|
8162
|
+
pointerEvents: "none",
|
|
8163
|
+
userSelect: "none"
|
|
7519
8164
|
},
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
8165
|
+
contentEditor: {
|
|
8166
|
+
zIndex: 0,
|
|
8167
|
+
flex: "auto",
|
|
8168
|
+
outline: "none",
|
|
8169
|
+
overflow: "auto",
|
|
8170
|
+
marginTop: "0px",
|
|
8171
|
+
position: "relative",
|
|
8172
|
+
background: "var(--colorNeutralBackground1, #ffffff)",
|
|
8173
|
+
justifyContent: "center",
|
|
8174
|
+
height: props.contentHeight ?? "100%",
|
|
8175
|
+
...isReadOnly && {
|
|
8176
|
+
cursor: "not-allowed",
|
|
8177
|
+
opacity: 0.75,
|
|
8178
|
+
userSelect: "text"
|
|
8179
|
+
}
|
|
8180
|
+
}
|
|
8181
|
+
});
|
|
8182
|
+
const urlRegExp = new RegExp(
|
|
8183
|
+
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/
|
|
8184
|
+
);
|
|
8185
|
+
const validateUrl = (url) => url === "https://" || urlRegExp.test(url);
|
|
8186
|
+
const handleReadOnlyClickCapture = (e) => {
|
|
8187
|
+
if (!isReadOnly) return;
|
|
8188
|
+
const target = e.target;
|
|
8189
|
+
const anchor = target?.closest?.("a");
|
|
8190
|
+
if (anchor) {
|
|
8191
|
+
e.preventDefault();
|
|
8192
|
+
e.stopPropagation();
|
|
8193
|
+
}
|
|
8194
|
+
};
|
|
8195
|
+
const isOverLimit = props.wordLimit !== void 0 && wordCount > props.wordLimit;
|
|
8196
|
+
useEffect(() => {
|
|
8197
|
+
if (props.wordLimit === void 0 || !props.onWordLimitExceeded) return;
|
|
8198
|
+
const wasOverLimit = previousOverLimitRef.current;
|
|
8199
|
+
if (isOverLimit !== wasOverLimit) {
|
|
8200
|
+
props.onWordLimitExceeded({
|
|
8201
|
+
wordCount,
|
|
8202
|
+
wordLimit: props.wordLimit,
|
|
8203
|
+
exceeded: isOverLimit
|
|
8204
|
+
});
|
|
8205
|
+
previousOverLimitRef.current = isOverLimit;
|
|
8206
|
+
}
|
|
8207
|
+
}, [isOverLimit, wordCount, props.wordLimit, props.onWordLimitExceeded]);
|
|
8208
|
+
const validationErrors = React9__default.useMemo(() => {
|
|
8209
|
+
const errors = [];
|
|
8210
|
+
const custom = props.validationMessages ?? {};
|
|
8211
|
+
const { words, chars, images, links, tables } = metrics;
|
|
8212
|
+
const msg = (key, ...args) => {
|
|
8213
|
+
const override = custom[key];
|
|
8214
|
+
if (override !== void 0) {
|
|
8215
|
+
return typeof override === "function" ? override(...args) : override;
|
|
8216
|
+
}
|
|
8217
|
+
const def = DEFAULT_VALIDATION_MESSAGES[key];
|
|
8218
|
+
return typeof def === "function" ? def(...args) : def;
|
|
8219
|
+
};
|
|
8220
|
+
const requiredFired = props.required && words === 0;
|
|
8221
|
+
if (requiredFired) {
|
|
8222
|
+
errors.push({ type: "required", message: msg("required") });
|
|
8223
|
+
} else if (props.minWords !== void 0 && words < props.minWords) {
|
|
8224
|
+
errors.push({ type: "minWords", message: msg("minWords", words, props.minWords) });
|
|
8225
|
+
}
|
|
8226
|
+
const effectiveMaxWords = props.maxWords ?? props.wordLimit;
|
|
8227
|
+
if (effectiveMaxWords !== void 0 && words > effectiveMaxWords) {
|
|
8228
|
+
errors.push({ type: "maxWords", message: msg("maxWords", words, effectiveMaxWords) });
|
|
8229
|
+
}
|
|
8230
|
+
if (!requiredFired && props.minChars !== void 0 && chars < props.minChars) {
|
|
8231
|
+
errors.push({ type: "minChars", message: msg("minChars", chars, props.minChars) });
|
|
8232
|
+
}
|
|
8233
|
+
if (props.maxChars !== void 0 && chars > props.maxChars) {
|
|
8234
|
+
errors.push({ type: "maxChars", message: msg("maxChars", chars, props.maxChars) });
|
|
8235
|
+
}
|
|
8236
|
+
if (props.noImages && images > 0) {
|
|
8237
|
+
errors.push({ type: "noImages", message: msg("noImages") });
|
|
8238
|
+
} else if (props.maxImages !== void 0 && images > props.maxImages) {
|
|
8239
|
+
errors.push({ type: "maxImages", message: msg("maxImages", images, props.maxImages) });
|
|
8240
|
+
}
|
|
8241
|
+
if (props.noLinks && links > 0) {
|
|
8242
|
+
errors.push({ type: "noLinks", message: msg("noLinks") });
|
|
8243
|
+
} else if (props.maxLinks !== void 0 && links > props.maxLinks) {
|
|
8244
|
+
errors.push({ type: "maxLinks", message: msg("maxLinks", links, props.maxLinks) });
|
|
8245
|
+
}
|
|
8246
|
+
if (props.noTables && tables > 0) {
|
|
8247
|
+
errors.push({ type: "noTables", message: msg("noTables") });
|
|
8248
|
+
}
|
|
8249
|
+
return errors;
|
|
8250
|
+
}, [
|
|
8251
|
+
metrics,
|
|
8252
|
+
props.required,
|
|
8253
|
+
props.minWords,
|
|
8254
|
+
props.maxWords,
|
|
8255
|
+
props.wordLimit,
|
|
8256
|
+
props.minChars,
|
|
8257
|
+
props.maxChars,
|
|
8258
|
+
props.noImages,
|
|
8259
|
+
props.maxImages,
|
|
8260
|
+
props.noLinks,
|
|
8261
|
+
props.maxLinks,
|
|
8262
|
+
props.noTables,
|
|
8263
|
+
props.validationMessages
|
|
8264
|
+
]);
|
|
8265
|
+
const previousErrorTypesRef = useRef("");
|
|
8266
|
+
useEffect(() => {
|
|
8267
|
+
if (!props.onValidationChange) return;
|
|
8268
|
+
const key = validationErrors.map((e) => e.type).join(",");
|
|
8269
|
+
if (key !== previousErrorTypesRef.current) {
|
|
8270
|
+
previousErrorTypesRef.current = key;
|
|
8271
|
+
props.onValidationChange(validationErrors);
|
|
8272
|
+
}
|
|
8273
|
+
}, [validationErrors, props.onValidationChange]);
|
|
8274
|
+
const trimmedErrorMessage = props.errorMessage?.trim() || "";
|
|
8275
|
+
const hasValidationError = validationErrors.length > 0 || !!trimmedErrorMessage;
|
|
8276
|
+
return /* @__PURE__ */ jsx(FluentProvider, { theme: webLightTheme, style: { height: "100%" }, children: /* @__PURE__ */ jsxs(LexicalComposer, { initialConfig, children: [
|
|
8277
|
+
/* @__PURE__ */ jsx("div", { ref: containerRef, className: "lexical-rich-editor-root", style: { height: "100%" }, children: /* @__PURE__ */ jsxs(
|
|
8278
|
+
Stack,
|
|
8279
|
+
{
|
|
8280
|
+
style: {
|
|
8281
|
+
zIndex: 1e3,
|
|
8282
|
+
background: "#fff",
|
|
8283
|
+
borderRadius: "2px",
|
|
8284
|
+
width: props.width ?? "100%",
|
|
8285
|
+
height: props.height ?? "100%",
|
|
8286
|
+
margin: props.margin ?? "5px auto",
|
|
8287
|
+
border: `1px solid ${isOverLimit || hasValidationError ? "#c4272c" : "var(--colorNeutralStroke1, #ccced1)"}`,
|
|
8288
|
+
transition: "border-color 0.2s",
|
|
8289
|
+
display: "flex",
|
|
8290
|
+
flexDirection: "column"
|
|
8291
|
+
},
|
|
8292
|
+
children: [
|
|
8293
|
+
/* @__PURE__ */ jsx(
|
|
8294
|
+
"div",
|
|
7531
8295
|
{
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
8296
|
+
className: "editor-toolbar-root",
|
|
8297
|
+
style: {
|
|
8298
|
+
pointerEvents: isReadOnly ? "none" : "auto",
|
|
8299
|
+
position: "sticky",
|
|
8300
|
+
opacity: isReadOnly ? 0.85 : 1
|
|
8301
|
+
},
|
|
8302
|
+
children: /* @__PURE__ */ jsx(
|
|
8303
|
+
ToolBarPlugins,
|
|
8304
|
+
{
|
|
8305
|
+
level: props.level ?? "basic" /* Basic */,
|
|
8306
|
+
customToolbar: props.customToolbar,
|
|
8307
|
+
readOnly: props.readOnly,
|
|
8308
|
+
pageSetup,
|
|
8309
|
+
onPageSetupChange: setPageSetup,
|
|
8310
|
+
maxImageSizeMB: props.maxImageSizeMB,
|
|
8311
|
+
validationMessages: props.validationMessages,
|
|
8312
|
+
setIsLinkEditMode
|
|
8313
|
+
}
|
|
8314
|
+
)
|
|
7536
8315
|
}
|
|
7537
|
-
)
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
/* @__PURE__ */ jsx(
|
|
7555
|
-
RichTextPlugin,
|
|
7556
|
-
{
|
|
7557
|
-
ErrorBoundary: LexicalErrorBoundary,
|
|
7558
|
-
contentEditable: /* @__PURE__ */ jsx(
|
|
7559
|
-
"div",
|
|
8316
|
+
),
|
|
8317
|
+
/* @__PURE__ */ jsxs(
|
|
8318
|
+
"div",
|
|
8319
|
+
{
|
|
8320
|
+
style: {
|
|
8321
|
+
position: "relative",
|
|
8322
|
+
flexGrow: 1,
|
|
8323
|
+
padding: "15px 0px",
|
|
8324
|
+
overflowY: "scroll",
|
|
8325
|
+
overflowX: "auto",
|
|
8326
|
+
minWidth: 0,
|
|
8327
|
+
background: pageCanvas.widthPx !== void 0 ? "#eef0f2" : void 0
|
|
8328
|
+
},
|
|
8329
|
+
onClickCapture: handleReadOnlyClickCapture,
|
|
8330
|
+
children: [
|
|
8331
|
+
/* @__PURE__ */ jsx(
|
|
8332
|
+
RichTextPlugin,
|
|
7560
8333
|
{
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
children: /* @__PURE__ */ jsx(
|
|
7565
|
-
ContentEditable,
|
|
8334
|
+
ErrorBoundary: LexicalErrorBoundary,
|
|
8335
|
+
contentEditable: /* @__PURE__ */ jsx(
|
|
8336
|
+
"div",
|
|
7566
8337
|
{
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
8338
|
+
className: "editor",
|
|
8339
|
+
style: { height: "100%", position: "relative" },
|
|
8340
|
+
ref: onAnchorRef,
|
|
8341
|
+
children: /* @__PURE__ */ jsx(
|
|
8342
|
+
ContentEditable,
|
|
8343
|
+
{
|
|
8344
|
+
ref: contentEditableDomRef,
|
|
8345
|
+
className: css(EditorStyles.contentEditor),
|
|
8346
|
+
style: {
|
|
8347
|
+
paddingTop: props.level !== "none" /* None */ ? 0 : 10,
|
|
8348
|
+
paddingLeft: pageCanvas.paddingPx,
|
|
8349
|
+
paddingRight: pageCanvas.paddingPx,
|
|
8350
|
+
maxWidth: pageCanvas.widthPx,
|
|
8351
|
+
marginLeft: pageCanvas.widthPx !== void 0 ? "auto" : void 0,
|
|
8352
|
+
marginRight: pageCanvas.widthPx !== void 0 ? "auto" : void 0,
|
|
8353
|
+
boxShadow: pageCanvas.widthPx !== void 0 ? "0 0 0 1px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.08)" : void 0
|
|
8354
|
+
},
|
|
8355
|
+
spellCheck: !resolvedSpellCheck,
|
|
8356
|
+
autoCorrect: resolvedSpellCheck ? "off" : void 0,
|
|
8357
|
+
autoCapitalize: resolvedSpellCheck ? "off" : void 0
|
|
8358
|
+
}
|
|
8359
|
+
)
|
|
7581
8360
|
}
|
|
7582
|
-
)
|
|
8361
|
+
),
|
|
8362
|
+
placeholder: /* @__PURE__ */ jsx(Stack, { className: css(EditorStyles.editorPlaceholder), children: props.placeholder })
|
|
7583
8363
|
}
|
|
7584
8364
|
),
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
),
|
|
7588
|
-
props.wordLimit !== void 0 && /* @__PURE__ */ jsx(
|
|
7589
|
-
"div",
|
|
7590
|
-
{
|
|
7591
|
-
style: {
|
|
7592
|
-
position: "sticky",
|
|
7593
|
-
bottom: 0,
|
|
7594
|
-
display: "flex",
|
|
7595
|
-
justifyContent: "flex-end",
|
|
7596
|
-
paddingRight: 14,
|
|
7597
|
-
pointerEvents: "none",
|
|
7598
|
-
userSelect: "none"
|
|
7599
|
-
},
|
|
7600
|
-
children: /* @__PURE__ */ jsxs(
|
|
7601
|
-
"span",
|
|
8365
|
+
(props.wordLimit !== void 0 || props.maxWords !== void 0 || props.minWords !== void 0 || props.maxChars !== void 0 || props.minChars !== void 0) && /* @__PURE__ */ jsxs(
|
|
8366
|
+
"div",
|
|
7602
8367
|
{
|
|
7603
8368
|
style: {
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
8369
|
+
position: "sticky",
|
|
8370
|
+
bottom: 0,
|
|
8371
|
+
display: "flex",
|
|
8372
|
+
justifyContent: "flex-end",
|
|
8373
|
+
gap: 10,
|
|
8374
|
+
paddingRight: 14,
|
|
8375
|
+
pointerEvents: "none",
|
|
8376
|
+
userSelect: "none"
|
|
7608
8377
|
},
|
|
7609
8378
|
children: [
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
8379
|
+
(props.wordLimit !== void 0 || props.maxWords !== void 0 || props.minWords !== void 0) && /* @__PURE__ */ jsxs(
|
|
8380
|
+
"span",
|
|
8381
|
+
{
|
|
8382
|
+
style: {
|
|
8383
|
+
fontSize: "11px",
|
|
8384
|
+
color: hasValidationError ? "#c4272c" : "var(--colorNeutralForeground3, #aaa)",
|
|
8385
|
+
fontWeight: hasValidationError ? 600 : 400,
|
|
8386
|
+
transition: "color 0.2s, font-weight 0.2s"
|
|
8387
|
+
},
|
|
8388
|
+
children: [
|
|
8389
|
+
wordCount,
|
|
8390
|
+
(props.maxWords ?? props.wordLimit) !== void 0 && ` / ${props.maxWords ?? props.wordLimit}`,
|
|
8391
|
+
props.minWords !== void 0 && props.maxWords === void 0 && props.wordLimit === void 0 && ` (min ${props.minWords})`,
|
|
8392
|
+
" words"
|
|
8393
|
+
]
|
|
8394
|
+
}
|
|
8395
|
+
),
|
|
8396
|
+
(props.maxChars !== void 0 || props.minChars !== void 0) && /* @__PURE__ */ jsxs(
|
|
8397
|
+
"span",
|
|
8398
|
+
{
|
|
8399
|
+
style: {
|
|
8400
|
+
fontSize: "11px",
|
|
8401
|
+
color: hasValidationError ? "#c4272c" : "var(--colorNeutralForeground3, #aaa)",
|
|
8402
|
+
fontWeight: hasValidationError ? 600 : 400,
|
|
8403
|
+
transition: "color 0.2s, font-weight 0.2s"
|
|
8404
|
+
},
|
|
8405
|
+
children: [
|
|
8406
|
+
metrics.chars,
|
|
8407
|
+
props.maxChars !== void 0 && ` / ${props.maxChars}`,
|
|
8408
|
+
props.minChars !== void 0 && props.maxChars === void 0 && ` (min ${props.minChars})`,
|
|
8409
|
+
" chars"
|
|
8410
|
+
]
|
|
8411
|
+
}
|
|
8412
|
+
)
|
|
7614
8413
|
]
|
|
7615
8414
|
}
|
|
7616
8415
|
)
|
|
8416
|
+
]
|
|
8417
|
+
}
|
|
8418
|
+
),
|
|
8419
|
+
/* @__PURE__ */ jsx(ReadOnlyPlugin, { readonly: isReadOnly }),
|
|
8420
|
+
/* @__PURE__ */ jsx(BrowserSpellCheckPlugin, { enabled: !resolvedSpellCheck }),
|
|
8421
|
+
/* @__PURE__ */ jsx(
|
|
8422
|
+
FocusEventsPlugin,
|
|
8423
|
+
{
|
|
8424
|
+
onFocus: props.onFocus,
|
|
8425
|
+
onBlur: props.onBlur,
|
|
8426
|
+
setFocused,
|
|
8427
|
+
containerRef
|
|
8428
|
+
}
|
|
8429
|
+
),
|
|
8430
|
+
props.autoFocus && !isReadOnly && /* @__PURE__ */ jsx(AutoFocusPlugin, {}),
|
|
8431
|
+
/* @__PURE__ */ jsx(HistoryPlugin, {}),
|
|
8432
|
+
/* @__PURE__ */ jsx(ListPlugin, {}),
|
|
8433
|
+
/* @__PURE__ */ jsx(LinkPlugin, { validateUrl }),
|
|
8434
|
+
/* @__PURE__ */ jsx(AutoLinkPlugin, { matchers: MATCHERS }),
|
|
8435
|
+
/* @__PURE__ */ jsx(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true }),
|
|
8436
|
+
!isReadOnly && /* @__PURE__ */ jsx(YoutubeDeletePlugin, {}),
|
|
8437
|
+
!isReadOnly && floatingAnchorElem && /* @__PURE__ */ jsx(TableActionMenuPlugin, {}),
|
|
8438
|
+
!isReadOnly && floatingAnchorElem && /* @__PURE__ */ jsx(TableCellResizerPlugin, { anchorElem: floatingAnchorElem }),
|
|
8439
|
+
!isReadOnly && /* @__PURE__ */ jsx(
|
|
8440
|
+
FloatingLinkEditorPlugin,
|
|
8441
|
+
{
|
|
8442
|
+
anchorElem: floatingAnchorElem,
|
|
8443
|
+
isLinkEditMode,
|
|
8444
|
+
setIsLinkEditMode
|
|
8445
|
+
}
|
|
8446
|
+
),
|
|
8447
|
+
!isReadOnly && /* @__PURE__ */ jsx(ImagePlugin_default, {}),
|
|
8448
|
+
!isReadOnly && /* @__PURE__ */ jsx(InlineImage_default, {}),
|
|
8449
|
+
!isReadOnly && /* @__PURE__ */ jsx(PageBreakPlugin, {}),
|
|
8450
|
+
!!resolvedQuery && !isReadOnly && /* @__PURE__ */ jsx(
|
|
8451
|
+
AutocompletePlugin,
|
|
8452
|
+
{
|
|
8453
|
+
useQuery: resolvedQuery,
|
|
8454
|
+
isReadOnly,
|
|
8455
|
+
onSuggestionShown: props.onSuggestionShown,
|
|
8456
|
+
onSuggestionAccept: props.onSuggestionAccept,
|
|
8457
|
+
idleMs: props.suggestIdleMs ?? 300,
|
|
8458
|
+
minWords: 4,
|
|
8459
|
+
prefixWindow: 300
|
|
8460
|
+
}
|
|
8461
|
+
),
|
|
8462
|
+
!!resolvedSpellCheck && !isReadOnly && /* @__PURE__ */ jsx(
|
|
8463
|
+
SpellCheckPlugin,
|
|
8464
|
+
{
|
|
8465
|
+
useSpellCheck: resolvedSpellCheck,
|
|
8466
|
+
onSpellCheckAccept: props.onSpellCheckAccept,
|
|
8467
|
+
idleMs: props.spellCheckIdleMs ?? 1200,
|
|
8468
|
+
enabled: props.spellCheckEnabled !== false
|
|
8469
|
+
}
|
|
8470
|
+
),
|
|
8471
|
+
!isReadOnly && props.showFloatingToolbar && /* @__PURE__ */ jsx(CharacterStylesPopupPlugin, {}),
|
|
8472
|
+
/* @__PURE__ */ jsx(CustomOnChangePlugin, { value: props.value, onChange: props.onChange }),
|
|
8473
|
+
(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__ */ jsx(ContentMetricsPlugin, { onMetricsChange: handleMetrics }),
|
|
8474
|
+
/* @__PURE__ */ jsx(
|
|
8475
|
+
RefApiPlugin,
|
|
8476
|
+
{
|
|
8477
|
+
forwardedRef: ref,
|
|
8478
|
+
contentEditableDomRef,
|
|
8479
|
+
focusedRef
|
|
8480
|
+
}
|
|
8481
|
+
),
|
|
8482
|
+
(validationErrors.length > 0 || trimmedErrorMessage) && /* @__PURE__ */ jsxs("div", { style: { flexShrink: 0, padding: "6px 20px 8px" }, children: [
|
|
8483
|
+
validationErrors.map((err) => /* @__PURE__ */ jsxs(
|
|
8484
|
+
"div",
|
|
8485
|
+
{
|
|
8486
|
+
style: {
|
|
8487
|
+
display: "flex",
|
|
8488
|
+
alignItems: "flex-start",
|
|
8489
|
+
gap: 6,
|
|
8490
|
+
marginTop: 2,
|
|
8491
|
+
color: "#c4272c",
|
|
8492
|
+
fontSize: 12,
|
|
8493
|
+
lineHeight: "18px"
|
|
8494
|
+
},
|
|
8495
|
+
children: [
|
|
8496
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600, flexShrink: 0 }, children: "\u26A0" }),
|
|
8497
|
+
/* @__PURE__ */ jsx("span", { children: err.message })
|
|
8498
|
+
]
|
|
8499
|
+
},
|
|
8500
|
+
err.type
|
|
8501
|
+
)),
|
|
8502
|
+
trimmedErrorMessage && /* @__PURE__ */ jsxs(
|
|
8503
|
+
"div",
|
|
8504
|
+
{
|
|
8505
|
+
style: {
|
|
8506
|
+
display: "flex",
|
|
8507
|
+
alignItems: "flex-start",
|
|
8508
|
+
gap: 6,
|
|
8509
|
+
marginTop: 2,
|
|
8510
|
+
color: "#c4272c",
|
|
8511
|
+
fontSize: 12,
|
|
8512
|
+
lineHeight: "18px"
|
|
8513
|
+
},
|
|
8514
|
+
children: [
|
|
8515
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600, flexShrink: 0 }, children: "\u26A0" }),
|
|
8516
|
+
/* @__PURE__ */ jsx("span", { children: trimmedErrorMessage })
|
|
8517
|
+
]
|
|
7617
8518
|
}
|
|
7618
8519
|
)
|
|
7619
|
-
]
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
background: "#fff8f8",
|
|
7628
|
-
padding: "6px 12px 8px",
|
|
7629
|
-
display: "flex",
|
|
7630
|
-
flexDirection: "column",
|
|
7631
|
-
gap: 4
|
|
7632
|
-
},
|
|
7633
|
-
children: allErrors.map((err, i) => /* @__PURE__ */ jsxs(
|
|
7634
|
-
"div",
|
|
7635
|
-
{
|
|
7636
|
-
style: { display: "flex", alignItems: "center", gap: 6 },
|
|
7637
|
-
children: [
|
|
7638
|
-
/* @__PURE__ */ jsx(
|
|
7639
|
-
ErrorCircleRegular,
|
|
7640
|
-
{
|
|
7641
|
-
style: { fontSize: 14, color: "#c4272c", flexShrink: 0 }
|
|
7642
|
-
}
|
|
7643
|
-
),
|
|
7644
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#c4272c" }, children: err })
|
|
7645
|
-
]
|
|
7646
|
-
},
|
|
7647
|
-
i
|
|
7648
|
-
))
|
|
7649
|
-
}
|
|
7650
|
-
),
|
|
7651
|
-
/* @__PURE__ */ jsx(ReadOnlyPlugin, { readonly: isReadOnly }),
|
|
7652
|
-
/* @__PURE__ */ jsx(BrowserSpellCheckPlugin, { enabled: !resolvedSpellCheck }),
|
|
7653
|
-
/* @__PURE__ */ jsx(
|
|
7654
|
-
FocusEventsPlugin,
|
|
7655
|
-
{
|
|
7656
|
-
onFocus: props.onFocus,
|
|
7657
|
-
onBlur: () => {
|
|
7658
|
-
setTouched(true);
|
|
7659
|
-
props.onBlur?.();
|
|
7660
|
-
},
|
|
7661
|
-
setFocused,
|
|
7662
|
-
containerRef
|
|
7663
|
-
}
|
|
7664
|
-
),
|
|
7665
|
-
props.autoFocus && !isReadOnly && /* @__PURE__ */ jsx(AutoFocusPlugin, {}),
|
|
7666
|
-
/* @__PURE__ */ jsx(HistoryPlugin, {}),
|
|
7667
|
-
/* @__PURE__ */ jsx(ListPlugin, {}),
|
|
7668
|
-
/* @__PURE__ */ jsx(LinkPlugin, { validateUrl }),
|
|
7669
|
-
/* @__PURE__ */ jsx(AutoLinkPlugin, { matchers: MATCHERS }),
|
|
7670
|
-
/* @__PURE__ */ jsx(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true }),
|
|
7671
|
-
!isReadOnly && /* @__PURE__ */ jsx(YoutubeDeletePlugin, {}),
|
|
7672
|
-
!isReadOnly && floatingAnchorElem && /* @__PURE__ */ jsx(TableActionMenuPlugin, {}),
|
|
7673
|
-
!isReadOnly && floatingAnchorElem && /* @__PURE__ */ jsx(TableCellResizerPlugin, { anchorElem: floatingAnchorElem }),
|
|
7674
|
-
!isReadOnly && /* @__PURE__ */ jsx(
|
|
7675
|
-
FloatingLinkEditorPlugin,
|
|
7676
|
-
{
|
|
7677
|
-
anchorElem: floatingAnchorElem,
|
|
7678
|
-
isLinkEditMode,
|
|
7679
|
-
setIsLinkEditMode
|
|
7680
|
-
}
|
|
7681
|
-
),
|
|
7682
|
-
!isReadOnly && /* @__PURE__ */ jsx(ImagePlugin_default, {}),
|
|
7683
|
-
!isReadOnly && /* @__PURE__ */ jsx(InlineImage_default, {}),
|
|
7684
|
-
!isReadOnly && /* @__PURE__ */ jsx(PageBreakPlugin, {}),
|
|
7685
|
-
!!resolvedQuery && !isReadOnly && /* @__PURE__ */ jsx(
|
|
7686
|
-
AutocompletePlugin,
|
|
7687
|
-
{
|
|
7688
|
-
useQuery: resolvedQuery,
|
|
7689
|
-
isReadOnly,
|
|
7690
|
-
onSuggestionShown: props.onSuggestionShown,
|
|
7691
|
-
onSuggestionAccept: props.onSuggestionAccept,
|
|
7692
|
-
idleMs: props.suggestIdleMs ?? 300,
|
|
7693
|
-
minWords: 4,
|
|
7694
|
-
prefixWindow: 300
|
|
7695
|
-
}
|
|
7696
|
-
),
|
|
7697
|
-
!!resolvedSpellCheck && !isReadOnly && /* @__PURE__ */ jsx(
|
|
7698
|
-
SpellCheckPlugin,
|
|
7699
|
-
{
|
|
7700
|
-
useSpellCheck: resolvedSpellCheck,
|
|
7701
|
-
onSpellCheckAccept: props.onSpellCheckAccept,
|
|
7702
|
-
idleMs: props.spellCheckIdleMs ?? 1200,
|
|
7703
|
-
enabled: props.spellCheckEnabled !== false
|
|
7704
|
-
}
|
|
7705
|
-
),
|
|
7706
|
-
!isReadOnly && props.showFloatingToolbar && /* @__PURE__ */ jsx(CharacterStylesPopupPlugin, {}),
|
|
7707
|
-
/* @__PURE__ */ jsx(
|
|
7708
|
-
CustomOnChangePlugin,
|
|
7709
|
-
{
|
|
7710
|
-
value: props.value,
|
|
7711
|
-
onChange: props.onChange
|
|
7712
|
-
}
|
|
7713
|
-
),
|
|
7714
|
-
(props.wordLimit !== void 0 || props.required || props.minWords !== void 0) && /* @__PURE__ */ jsx(WordCountPlugin, { onCountChange: handleWordCount }),
|
|
7715
|
-
(props.maxChars !== void 0 || props.minChars !== void 0) && /* @__PURE__ */ jsx(CharCountPlugin, { onCountChange: handleCharCount }),
|
|
7716
|
-
/* @__PURE__ */ jsx(
|
|
7717
|
-
RefApiPlugin,
|
|
7718
|
-
{
|
|
7719
|
-
forwardedRef: ref,
|
|
7720
|
-
contentEditableDomRef,
|
|
7721
|
-
focusedRef,
|
|
7722
|
-
setRefErrors
|
|
7723
|
-
}
|
|
7724
|
-
)
|
|
7725
|
-
]
|
|
7726
|
-
}
|
|
7727
|
-
) }) }) });
|
|
7728
|
-
});
|
|
8520
|
+
] })
|
|
8521
|
+
]
|
|
8522
|
+
}
|
|
8523
|
+
) }),
|
|
8524
|
+
/* @__PURE__ */ jsx(EditorReadyPlugin, { onReady: props.onReady })
|
|
8525
|
+
] }) });
|
|
8526
|
+
}
|
|
8527
|
+
);
|
|
7729
8528
|
|
|
7730
|
-
export { ContentEditorComponent, ContentEditorLevel };
|
|
8529
|
+
export { ContentEditorComponent, ContentEditorLevel, DEFAULT_VALIDATION_MESSAGES };
|
|
7731
8530
|
//# sourceMappingURL=index.mjs.map
|
|
7732
8531
|
//# sourceMappingURL=index.mjs.map
|