@tarviks/lexical-rich-editor 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +137 -49
- 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 +2095 -1058
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2097 -1061
- 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, TextUnderlineFilled, TextItalicFilled, TextBold24Regular, DocumentRegular, TextAlignLeftFilled, TextAlignCenterFilled, TextAlignRightFilled, TextAlignJustifyFilled, VideoClipRegular, ImageEditRegular, AttachFilled, ImageAddRegular, TableAddRegular, LinkAddRegular, TextColorRegular, PaintBucket16Filled, CodeFilled, LinkFilled, Dismiss16Regular } 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,37 +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
|
-
|
|
624
|
-
|
|
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
|
+
) });
|
|
625
620
|
};
|
|
626
621
|
ImageComponent_default = ImageComponent;
|
|
627
622
|
}
|
|
@@ -855,6 +850,7 @@ __export(InlineImageComponent_exports, {
|
|
|
855
850
|
var imageCache2, useSuspenseImage2, LazyImage2, InlineImageComponent, InlineImageComponent_default;
|
|
856
851
|
var init_InlineImageComponent = __esm({
|
|
857
852
|
"src/Nodes/InlineImageComponent.tsx"() {
|
|
853
|
+
init_ImageResizer();
|
|
858
854
|
init_InlineImage();
|
|
859
855
|
init_InlineImageNode();
|
|
860
856
|
imageCache2 = /* @__PURE__ */ new Set();
|
|
@@ -891,6 +887,7 @@ var init_InlineImageComponent = __esm({
|
|
|
891
887
|
};
|
|
892
888
|
InlineImageComponent = ({ src, altText, nodeKey, width, height, showCaption, caption, position }) => {
|
|
893
889
|
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
|
|
890
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
894
891
|
const [selection, setSelection] = useState(null);
|
|
895
892
|
const activeEditorRef = useRef(null);
|
|
896
893
|
const imageRef = useRef(null);
|
|
@@ -952,6 +949,25 @@ var init_InlineImageComponent = __esm({
|
|
|
952
949
|
},
|
|
953
950
|
[caption, editor, setSelected]
|
|
954
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
|
+
);
|
|
955
971
|
useEffect(() => {
|
|
956
972
|
let isMounted = true;
|
|
957
973
|
const unregister = mergeRegister(
|
|
@@ -970,48 +986,13 @@ var init_InlineImageComponent = __esm({
|
|
|
970
986
|
),
|
|
971
987
|
editor.registerCommand(
|
|
972
988
|
CLICK_COMMAND,
|
|
973
|
-
|
|
974
|
-
const event = payload;
|
|
975
|
-
if (event.target === imageRef.current) {
|
|
976
|
-
if (event.shiftKey) {
|
|
977
|
-
setSelected(!isSelected);
|
|
978
|
-
} else {
|
|
979
|
-
clearSelection();
|
|
980
|
-
setSelected(true);
|
|
981
|
-
}
|
|
982
|
-
return true;
|
|
983
|
-
}
|
|
984
|
-
return false;
|
|
985
|
-
},
|
|
986
|
-
COMMAND_PRIORITY_LOW
|
|
987
|
-
),
|
|
988
|
-
editor.registerCommand(
|
|
989
|
-
DRAGSTART_COMMAND,
|
|
990
|
-
(event) => {
|
|
991
|
-
if (event.target === imageRef.current) {
|
|
992
|
-
event.preventDefault();
|
|
993
|
-
return true;
|
|
994
|
-
}
|
|
995
|
-
return false;
|
|
996
|
-
},
|
|
997
|
-
COMMAND_PRIORITY_LOW
|
|
998
|
-
),
|
|
999
|
-
editor.registerCommand(
|
|
1000
|
-
KEY_DELETE_COMMAND,
|
|
1001
|
-
$onDelete,
|
|
1002
|
-
COMMAND_PRIORITY_LOW
|
|
1003
|
-
),
|
|
1004
|
-
editor.registerCommand(
|
|
1005
|
-
KEY_BACKSPACE_COMMAND,
|
|
1006
|
-
$onDelete,
|
|
989
|
+
onClick,
|
|
1007
990
|
COMMAND_PRIORITY_LOW
|
|
1008
991
|
),
|
|
992
|
+
editor.registerCommand(KEY_DELETE_COMMAND, $onDelete, COMMAND_PRIORITY_LOW),
|
|
993
|
+
editor.registerCommand(KEY_BACKSPACE_COMMAND, $onDelete, COMMAND_PRIORITY_LOW),
|
|
1009
994
|
editor.registerCommand(KEY_ENTER_COMMAND, $onEnter, COMMAND_PRIORITY_LOW),
|
|
1010
|
-
editor.registerCommand(
|
|
1011
|
-
KEY_ESCAPE_COMMAND,
|
|
1012
|
-
$onEscape,
|
|
1013
|
-
COMMAND_PRIORITY_LOW
|
|
1014
|
-
)
|
|
995
|
+
editor.registerCommand(KEY_ESCAPE_COMMAND, $onEscape, COMMAND_PRIORITY_LOW)
|
|
1015
996
|
);
|
|
1016
997
|
return () => {
|
|
1017
998
|
isMounted = false;
|
|
@@ -1020,27 +1001,59 @@ var init_InlineImageComponent = __esm({
|
|
|
1020
1001
|
}, [
|
|
1021
1002
|
clearSelection,
|
|
1022
1003
|
editor,
|
|
1004
|
+
isResizing,
|
|
1023
1005
|
isSelected,
|
|
1024
1006
|
nodeKey,
|
|
1025
1007
|
$onDelete,
|
|
1026
1008
|
$onEnter,
|
|
1027
1009
|
$onEscape,
|
|
1010
|
+
onClick,
|
|
1028
1011
|
setSelected
|
|
1029
1012
|
]);
|
|
1030
|
-
const
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
{
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
|
|
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;
|
|
1028
|
+
const isFocused = (isSelected || isResizing) && isEditable;
|
|
1029
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxs("span", { draggable, style: { position: "relative", display: "inline-block" }, children: [
|
|
1030
|
+
/* @__PURE__ */ jsx(
|
|
1031
|
+
LazyImage2,
|
|
1032
|
+
{
|
|
1033
|
+
className: isFocused ? `focused ${$isNodeSelection(selection) ? "draggable" : ""}` : null,
|
|
1034
|
+
src,
|
|
1035
|
+
altText,
|
|
1036
|
+
imageRef,
|
|
1037
|
+
width,
|
|
1038
|
+
height,
|
|
1039
|
+
position
|
|
1040
|
+
}
|
|
1041
|
+
),
|
|
1042
|
+
$isNodeSelection(selection) && isFocused && /* @__PURE__ */ jsx(
|
|
1043
|
+
ImageResizer_default,
|
|
1044
|
+
{
|
|
1045
|
+
showCaption: false,
|
|
1046
|
+
setShowCaption: () => {
|
|
1047
|
+
},
|
|
1048
|
+
captionsEnabled: false,
|
|
1049
|
+
editor,
|
|
1050
|
+
buttonRef,
|
|
1051
|
+
imageRef,
|
|
1052
|
+
onResizeStart,
|
|
1053
|
+
onResizeEnd
|
|
1054
|
+
}
|
|
1055
|
+
)
|
|
1056
|
+
] }) });
|
|
1044
1057
|
};
|
|
1045
1058
|
InlineImageComponent_default = InlineImageComponent;
|
|
1046
1059
|
}
|
|
@@ -1228,6 +1241,19 @@ var ContentEditorLevel = /* @__PURE__ */ ((ContentEditorLevel2) => {
|
|
|
1228
1241
|
ContentEditorLevel2["Pro"] = "pro";
|
|
1229
1242
|
return ContentEditorLevel2;
|
|
1230
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
|
+
};
|
|
1231
1257
|
|
|
1232
1258
|
// src/Types/PageSetup.ts
|
|
1233
1259
|
var DEFAULT_PAGE_SETUP = {
|
|
@@ -1268,6 +1294,106 @@ function resolvePageCanvasMetrics(value) {
|
|
|
1268
1294
|
paddingPx: Math.round(margin.valueIn * CSS_PX_PER_INCH)
|
|
1269
1295
|
};
|
|
1270
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
|
+
}
|
|
1271
1397
|
var AutocompleteNode = class _AutocompleteNode extends TextNode {
|
|
1272
1398
|
static getType() {
|
|
1273
1399
|
return "autocomplete";
|
|
@@ -1278,6 +1404,13 @@ var AutocompleteNode = class _AutocompleteNode extends TextNode {
|
|
|
1278
1404
|
static importJSON(serializedNode) {
|
|
1279
1405
|
return new _AutocompleteNode(serializedNode.text, serializedNode.uuid);
|
|
1280
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
|
+
}
|
|
1281
1414
|
exportJSON() {
|
|
1282
1415
|
return { ...super.exportJSON(), uuid: this.__uuid };
|
|
1283
1416
|
}
|
|
@@ -1592,13 +1725,20 @@ function VideoResizer({
|
|
|
1592
1725
|
const dy = ev.clientY - rs.startY;
|
|
1593
1726
|
let newW = rs.startW;
|
|
1594
1727
|
let newH = rs.startH;
|
|
1595
|
-
if (dir === "se") {
|
|
1728
|
+
if (dir === "se" || dir === "ne") {
|
|
1596
1729
|
newW = Math.max(MIN_WIDTH, rs.startW + dx);
|
|
1597
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;
|
|
1598
1734
|
} else if (dir === "e") {
|
|
1599
1735
|
newW = Math.max(MIN_WIDTH, rs.startW + dx);
|
|
1736
|
+
} else if (dir === "w") {
|
|
1737
|
+
newW = Math.max(MIN_WIDTH, rs.startW - dx);
|
|
1600
1738
|
} else if (dir === "s") {
|
|
1601
1739
|
newH = Math.max(MIN_HEIGHT, rs.startH + dy);
|
|
1740
|
+
} else if (dir === "n") {
|
|
1741
|
+
newH = Math.max(MIN_HEIGHT, rs.startH - dy);
|
|
1602
1742
|
}
|
|
1603
1743
|
container.style.width = `${newW}px`;
|
|
1604
1744
|
container.style.height = `${newH}px`;
|
|
@@ -1618,13 +1758,23 @@ function VideoResizer({
|
|
|
1618
1758
|
/* @__PURE__ */ jsx(
|
|
1619
1759
|
"div",
|
|
1620
1760
|
{
|
|
1621
|
-
style: {
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
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" },
|
|
1628
1778
|
onPointerDown: (e) => startResize(e, "e"),
|
|
1629
1779
|
title: "Resize width"
|
|
1630
1780
|
}
|
|
@@ -1632,13 +1782,15 @@ function VideoResizer({
|
|
|
1632
1782
|
/* @__PURE__ */ jsx(
|
|
1633
1783
|
"div",
|
|
1634
1784
|
{
|
|
1635
|
-
style: {
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
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" },
|
|
1642
1794
|
onPointerDown: (e) => startResize(e, "s"),
|
|
1643
1795
|
title: "Resize height"
|
|
1644
1796
|
}
|
|
@@ -1646,15 +1798,30 @@ function VideoResizer({
|
|
|
1646
1798
|
/* @__PURE__ */ jsx(
|
|
1647
1799
|
"div",
|
|
1648
1800
|
{
|
|
1649
|
-
style: { ...handleBase, bottom: -5,
|
|
1650
|
-
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"),
|
|
1651
1819
|
title: "Resize (proportional)"
|
|
1652
1820
|
}
|
|
1653
1821
|
)
|
|
1654
1822
|
] });
|
|
1655
1823
|
}
|
|
1656
1824
|
function YouTubeComponent({
|
|
1657
|
-
className,
|
|
1658
1825
|
format,
|
|
1659
1826
|
nodeKey,
|
|
1660
1827
|
videoID,
|
|
@@ -1662,9 +1829,48 @@ function YouTubeComponent({
|
|
|
1662
1829
|
height,
|
|
1663
1830
|
editor
|
|
1664
1831
|
}) {
|
|
1832
|
+
const wrapperRef = React9.useRef(null);
|
|
1665
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);
|
|
1666
1837
|
const [isHovered, setIsHovered] = React9.useState(false);
|
|
1667
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]);
|
|
1668
1874
|
const handleDelete = (e) => {
|
|
1669
1875
|
e.preventDefault();
|
|
1670
1876
|
e.stopPropagation();
|
|
@@ -1673,72 +1879,173 @@ function YouTubeComponent({
|
|
|
1673
1879
|
node?.remove();
|
|
1674
1880
|
});
|
|
1675
1881
|
};
|
|
1882
|
+
const handleResizeStart = () => {
|
|
1883
|
+
isResizingRef.current = true;
|
|
1884
|
+
setIsResizing(true);
|
|
1885
|
+
if (iframeRef.current) iframeRef.current.style.pointerEvents = "none";
|
|
1886
|
+
};
|
|
1676
1887
|
const handleResizeEnd = (w, h) => {
|
|
1888
|
+
isResizingRef.current = false;
|
|
1677
1889
|
setIsResizing(false);
|
|
1890
|
+
if (iframeRef.current) iframeRef.current.style.pointerEvents = "";
|
|
1891
|
+
setIsHovered(true);
|
|
1678
1892
|
editor.update(() => {
|
|
1679
1893
|
const node = $getNodeByKey(nodeKey);
|
|
1680
|
-
if ($isYouTubeNode(node))
|
|
1681
|
-
node.setSize(Math.round(w), Math.round(h));
|
|
1682
|
-
}
|
|
1894
|
+
if ($isYouTubeNode(node)) node.setSize(Math.round(w), Math.round(h));
|
|
1683
1895
|
});
|
|
1684
1896
|
};
|
|
1685
|
-
|
|
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(
|
|
1686
1917
|
"div",
|
|
1687
1918
|
{
|
|
1688
1919
|
ref: containerRef,
|
|
1689
|
-
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
|
+
},
|
|
1690
1929
|
onMouseEnter: () => setIsHovered(true),
|
|
1691
1930
|
onMouseLeave: () => {
|
|
1692
|
-
if (!
|
|
1931
|
+
if (!isResizingRef.current) setIsHovered(false);
|
|
1693
1932
|
},
|
|
1694
1933
|
children: [
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
1702
|
-
allowFullScreen: true,
|
|
1703
|
-
title: "YouTube video",
|
|
1704
|
-
style: { display: "block", border: "none", pointerEvents: isResizing ? "none" : "auto" }
|
|
1705
|
-
}
|
|
1706
|
-
),
|
|
1707
|
-
isHovered && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1708
|
-
/* @__PURE__ */ jsx(
|
|
1709
|
-
"button",
|
|
1710
|
-
{
|
|
1711
|
-
type: "button",
|
|
1712
|
-
onClick: handleDelete,
|
|
1713
|
-
title: "Remove video",
|
|
1714
|
-
style: {
|
|
1715
|
-
position: "absolute",
|
|
1716
|
-
top: 8,
|
|
1717
|
-
right: 8,
|
|
1718
|
-
width: 28,
|
|
1719
|
-
height: 28,
|
|
1720
|
-
borderRadius: "50%",
|
|
1721
|
-
background: "rgba(0,0,0,0.65)",
|
|
1722
|
-
color: "#fff",
|
|
1723
|
-
border: "none",
|
|
1724
|
-
cursor: "pointer",
|
|
1725
|
-
fontSize: 18,
|
|
1726
|
-
lineHeight: 1,
|
|
1727
|
-
padding: 0,
|
|
1728
|
-
zIndex: 10,
|
|
1729
|
-
display: "flex",
|
|
1730
|
-
alignItems: "center",
|
|
1731
|
-
justifyContent: "center"
|
|
1732
|
-
},
|
|
1733
|
-
children: "\xD7"
|
|
1734
|
-
}
|
|
1735
|
-
),
|
|
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. */
|
|
1736
1940
|
/* @__PURE__ */ jsx(
|
|
1737
|
-
|
|
1941
|
+
"iframe",
|
|
1738
1942
|
{
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
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" }
|
|
1952
|
+
}
|
|
1953
|
+
)
|
|
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
|
|
1742
2049
|
}
|
|
1743
2050
|
)
|
|
1744
2051
|
] })
|
|
@@ -1798,6 +2105,7 @@ var YouTubeNode = class _YouTubeNode extends DecoratorBlockNode {
|
|
|
1798
2105
|
iframe.setAttribute("width", String(this.__width));
|
|
1799
2106
|
iframe.setAttribute("height", String(this.__height));
|
|
1800
2107
|
iframe.style.border = "none";
|
|
2108
|
+
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-popups allow-presentation");
|
|
1801
2109
|
iframe.setAttribute(
|
|
1802
2110
|
"allow",
|
|
1803
2111
|
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
@@ -1825,16 +2133,10 @@ var YouTubeNode = class _YouTubeNode extends DecoratorBlockNode {
|
|
|
1825
2133
|
writable.__width = width;
|
|
1826
2134
|
writable.__height = height;
|
|
1827
2135
|
}
|
|
1828
|
-
decorate(_editor,
|
|
1829
|
-
const embedBlockTheme = config.theme.embedBlock || {};
|
|
1830
|
-
const className = {
|
|
1831
|
-
base: embedBlockTheme.base || "",
|
|
1832
|
-
focus: embedBlockTheme.focus || ""
|
|
1833
|
-
};
|
|
2136
|
+
decorate(_editor, _config) {
|
|
1834
2137
|
return /* @__PURE__ */ jsx(
|
|
1835
2138
|
YouTubeComponent,
|
|
1836
2139
|
{
|
|
1837
|
-
className,
|
|
1838
2140
|
format: this.__format,
|
|
1839
2141
|
nodeKey: this.getKey(),
|
|
1840
2142
|
videoID: this.__id,
|
|
@@ -2200,12 +2502,12 @@ function useFloatingPortalContainer(editor) {
|
|
|
2200
2502
|
}, [editor]);
|
|
2201
2503
|
return container;
|
|
2202
2504
|
}
|
|
2203
|
-
function setPopupPositionFixed(popupEl, rect) {
|
|
2505
|
+
function setPopupPositionFixed(popupEl, rect, topBoundary) {
|
|
2204
2506
|
const GAP = 8;
|
|
2205
2507
|
const MARGIN = 8;
|
|
2206
2508
|
let top = rect.top - popupEl.offsetHeight - GAP;
|
|
2207
|
-
let left = rect.left
|
|
2208
|
-
if (top <
|
|
2509
|
+
let left = rect.left;
|
|
2510
|
+
if (top < topBoundary) top = rect.bottom + GAP;
|
|
2209
2511
|
left = clamp2(left, MARGIN, window.innerWidth - popupEl.offsetWidth - MARGIN);
|
|
2210
2512
|
popupEl.style.top = `${top}px`;
|
|
2211
2513
|
popupEl.style.left = `${left}px`;
|
|
@@ -2247,10 +2549,22 @@ function FloatingCharacterStylesEditor({
|
|
|
2247
2549
|
popupEl.classList.remove("is-open");
|
|
2248
2550
|
return;
|
|
2249
2551
|
}
|
|
2250
|
-
|
|
2251
|
-
|
|
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;
|
|
2252
2566
|
if (!mouseDownRef.current) {
|
|
2253
|
-
setPopupPositionFixed(popupEl, rect);
|
|
2567
|
+
setPopupPositionFixed(popupEl, rect, topBoundary);
|
|
2254
2568
|
}
|
|
2255
2569
|
popupEl.classList.add("is-open");
|
|
2256
2570
|
}, [editor]);
|
|
@@ -2458,6 +2772,11 @@ function useCharacterStylesPopup(editor, opts) {
|
|
|
2458
2772
|
setIsText(false);
|
|
2459
2773
|
return;
|
|
2460
2774
|
}
|
|
2775
|
+
const activeElement = document.activeElement;
|
|
2776
|
+
if (activeElement && activeElement !== document.body && rootElement && !rootElement.contains(activeElement)) {
|
|
2777
|
+
setIsText(false);
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2461
2780
|
if (!$isRangeSelection(selection)) return;
|
|
2462
2781
|
const node = getSelectedNode(selection);
|
|
2463
2782
|
setIsBold(selection.hasFormat("bold"));
|
|
@@ -2478,7 +2797,11 @@ function useCharacterStylesPopup(editor, opts) {
|
|
|
2478
2797
|
}, [editor]);
|
|
2479
2798
|
useEffect(() => {
|
|
2480
2799
|
document.addEventListener("selectionchange", updatePopupState);
|
|
2481
|
-
|
|
2800
|
+
document.addEventListener("focusin", updatePopupState);
|
|
2801
|
+
return () => {
|
|
2802
|
+
document.removeEventListener("selectionchange", updatePopupState);
|
|
2803
|
+
document.removeEventListener("focusin", updatePopupState);
|
|
2804
|
+
};
|
|
2482
2805
|
}, [updatePopupState]);
|
|
2483
2806
|
useEffect(() => editor.registerUpdateListener(updatePopupState), [editor, updatePopupState]);
|
|
2484
2807
|
if (!portalContainer || !isText || isLink) return null;
|
|
@@ -2736,34 +3059,57 @@ function normalizeToBlockHtml(html) {
|
|
|
2736
3059
|
if (pendingP) body.appendChild(pendingP);
|
|
2737
3060
|
return body.innerHTML;
|
|
2738
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
|
+
}
|
|
2739
3087
|
var CustomOnChangePlugin = ({ value, onChange }) => {
|
|
2740
3088
|
const [editor] = useLexicalComposerContext();
|
|
2741
3089
|
const initializedRef = useRef(false);
|
|
2742
|
-
const onChangeRef = useRef(onChange);
|
|
2743
|
-
onChangeRef.current = onChange;
|
|
2744
3090
|
useEffect(() => {
|
|
2745
3091
|
if (!value || initializedRef.current) return;
|
|
2746
3092
|
initializedRef.current = true;
|
|
2747
3093
|
editor.update(() => {
|
|
2748
3094
|
const root = $getRoot();
|
|
2749
3095
|
root.clear();
|
|
3096
|
+
const safe = sanitizeHtml(value);
|
|
3097
|
+
const cleaned = normalizeToBlockHtml(splitHeadingsAtBrSequences(safe));
|
|
2750
3098
|
const parser = new DOMParser();
|
|
2751
|
-
const dom = parser.parseFromString(
|
|
3099
|
+
const dom = parser.parseFromString(cleaned, "text/html");
|
|
2752
3100
|
const nodes = $generateNodesFromDOM(editor, dom);
|
|
2753
3101
|
root.append(...nodes);
|
|
2754
|
-
$setSelection(null);
|
|
2755
3102
|
});
|
|
2756
3103
|
}, [editor, value]);
|
|
2757
|
-
const handleChange = useCallback((editorState) => {
|
|
2758
|
-
editorState.read(() => {
|
|
2759
|
-
onChangeRef.current(postProcessOutput($generateHtmlFromNodes(editor)));
|
|
2760
|
-
});
|
|
2761
|
-
}, [editor]);
|
|
2762
3104
|
return /* @__PURE__ */ jsx(
|
|
2763
3105
|
OnChangePlugin,
|
|
2764
3106
|
{
|
|
2765
|
-
onChange:
|
|
2766
|
-
|
|
3107
|
+
onChange: (editorState) => {
|
|
3108
|
+
editorState.read(() => {
|
|
3109
|
+
const raw = $generateHtmlFromNodes(editor);
|
|
3110
|
+
onChange(postProcessOutput(splitHeadingsAtBrSequences(raw)));
|
|
3111
|
+
});
|
|
3112
|
+
}
|
|
2767
3113
|
}
|
|
2768
3114
|
);
|
|
2769
3115
|
};
|
|
@@ -2857,7 +3203,7 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
2857
3203
|
return;
|
|
2858
3204
|
}
|
|
2859
3205
|
const rootElement = editor.getRootElement();
|
|
2860
|
-
if (selection !== null && nativeSelection !== null && rootElement !== null && rootElement.contains(nativeSelection.anchorNode) && editor.isEditable()) {
|
|
3206
|
+
if (isLink && selection !== null && nativeSelection !== null && rootElement !== null && rootElement.contains(nativeSelection.anchorNode) && editor.isEditable()) {
|
|
2861
3207
|
const domRect = nativeSelection.focusNode?.parentElement?.getBoundingClientRect();
|
|
2862
3208
|
if (domRect) {
|
|
2863
3209
|
domRect.y += 40;
|
|
@@ -2873,7 +3219,7 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
2873
3219
|
setLinkUrl("");
|
|
2874
3220
|
}
|
|
2875
3221
|
return true;
|
|
2876
|
-
}, [anchorElem, editor, setIsLinkEditMode, isLinkEditMode, linkUrl]);
|
|
3222
|
+
}, [anchorElem, editor, setIsLinkEditMode, isLinkEditMode, isLink, linkUrl]);
|
|
2877
3223
|
useEffect(() => {
|
|
2878
3224
|
const scrollerElem = anchorElem.parentElement;
|
|
2879
3225
|
const update = () => {
|
|
@@ -2980,17 +3326,20 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
2980
3326
|
}
|
|
2981
3327
|
}
|
|
2982
3328
|
),
|
|
2983
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3329
|
+
/* @__PURE__ */ jsxs("div", { className: "link-input-actions", children: [
|
|
2984
3330
|
/* @__PURE__ */ jsx(
|
|
2985
3331
|
"div",
|
|
2986
3332
|
{
|
|
2987
3333
|
className: "link-cancel",
|
|
2988
3334
|
role: "button",
|
|
2989
3335
|
tabIndex: 0,
|
|
3336
|
+
title: "Cancel",
|
|
3337
|
+
"aria-label": "Cancel",
|
|
2990
3338
|
onMouseDown: preventDefault,
|
|
2991
3339
|
onClick: () => {
|
|
2992
3340
|
setIsLinkEditMode(false);
|
|
2993
|
-
}
|
|
3341
|
+
},
|
|
3342
|
+
children: /* @__PURE__ */ jsx(DismissRegular, { fontSize: 16 })
|
|
2994
3343
|
}
|
|
2995
3344
|
),
|
|
2996
3345
|
/* @__PURE__ */ jsx(
|
|
@@ -2999,8 +3348,11 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
2999
3348
|
className: "link-confirm",
|
|
3000
3349
|
role: "button",
|
|
3001
3350
|
tabIndex: 0,
|
|
3351
|
+
title: "Confirm",
|
|
3352
|
+
"aria-label": "Confirm",
|
|
3002
3353
|
onMouseDown: preventDefault,
|
|
3003
|
-
onClick: handleLinkSubmission
|
|
3354
|
+
onClick: handleLinkSubmission,
|
|
3355
|
+
children: /* @__PURE__ */ jsx(CheckmarkRegular, { fontSize: 16 })
|
|
3004
3356
|
}
|
|
3005
3357
|
)
|
|
3006
3358
|
] })
|
|
@@ -3020,12 +3372,15 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
3020
3372
|
className: "link-edit",
|
|
3021
3373
|
role: "button",
|
|
3022
3374
|
tabIndex: 0,
|
|
3375
|
+
title: "Edit link",
|
|
3376
|
+
"aria-label": "Edit link",
|
|
3023
3377
|
onMouseDown: preventDefault,
|
|
3024
3378
|
onClick: (event) => {
|
|
3025
3379
|
event.preventDefault();
|
|
3026
3380
|
setEditedLinkUrl(linkUrl);
|
|
3027
3381
|
setIsLinkEditMode(true);
|
|
3028
|
-
}
|
|
3382
|
+
},
|
|
3383
|
+
children: /* @__PURE__ */ jsx(EditRegular, { fontSize: 16 })
|
|
3029
3384
|
}
|
|
3030
3385
|
),
|
|
3031
3386
|
/* @__PURE__ */ jsx(
|
|
@@ -3034,10 +3389,13 @@ var FloatingLinkEditor = ({ editor, isLink, setIsLink, anchorElem, isLinkEditMod
|
|
|
3034
3389
|
className: "link-trash",
|
|
3035
3390
|
role: "button",
|
|
3036
3391
|
tabIndex: 0,
|
|
3392
|
+
title: "Remove link",
|
|
3393
|
+
"aria-label": "Remove link",
|
|
3037
3394
|
onMouseDown: preventDefault,
|
|
3038
3395
|
onClick: () => {
|
|
3039
3396
|
editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
|
|
3040
|
-
}
|
|
3397
|
+
},
|
|
3398
|
+
children: /* @__PURE__ */ jsx(DeleteRegular, { fontSize: 16 })
|
|
3041
3399
|
}
|
|
3042
3400
|
)
|
|
3043
3401
|
] }) });
|
|
@@ -3120,8 +3478,6 @@ var FloatingLinkEditorPlugin = ({ anchorElem, isLinkEditMode, setIsLinkEditMode
|
|
|
3120
3478
|
setIsLinkEditMode
|
|
3121
3479
|
);
|
|
3122
3480
|
};
|
|
3123
|
-
|
|
3124
|
-
// src/Plugins/ImagePlugin.tsx
|
|
3125
3481
|
init_ImageNode();
|
|
3126
3482
|
var INSERT_IMAGE_COMMAND = createCommand("INSERT_IMAGE_COMMAND");
|
|
3127
3483
|
var readClipboardImageAsDataURL = async (event) => {
|
|
@@ -3149,7 +3505,7 @@ var InsertImageByURL = ({
|
|
|
3149
3505
|
const [src, setSrc] = useState("");
|
|
3150
3506
|
const isDisabled = disabled || src === "";
|
|
3151
3507
|
return /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 6, padding: "10px 0px 0px 0px" }, children: [
|
|
3152
|
-
/* @__PURE__ */ jsx(Field, { label: "Enter URL",
|
|
3508
|
+
/* @__PURE__ */ jsx(Field, { label: "Enter URL", size: "small", children: /* @__PURE__ */ jsx(
|
|
3153
3509
|
Input,
|
|
3154
3510
|
{
|
|
3155
3511
|
autoFocus: !disabled,
|
|
@@ -3160,7 +3516,7 @@ var InsertImageByURL = ({
|
|
|
3160
3516
|
value: src
|
|
3161
3517
|
}
|
|
3162
3518
|
) }),
|
|
3163
|
-
/* @__PURE__ */ jsx(Field, { label: "Alt Text",
|
|
3519
|
+
/* @__PURE__ */ jsx(Field, { label: "Alt Text", size: "small", children: /* @__PURE__ */ jsx(
|
|
3164
3520
|
Input,
|
|
3165
3521
|
{
|
|
3166
3522
|
placeholder: "Alt text",
|
|
@@ -3198,16 +3554,19 @@ var InsertImageByURL = ({
|
|
|
3198
3554
|
};
|
|
3199
3555
|
var InsertImageDialog = ({
|
|
3200
3556
|
activeEditor,
|
|
3201
|
-
disabled
|
|
3557
|
+
disabled,
|
|
3558
|
+
maxImageSizeMB,
|
|
3559
|
+
validationMessages
|
|
3202
3560
|
}) => {
|
|
3203
3561
|
const [src, setSrc] = useState("");
|
|
3204
3562
|
const [altText, setAltText] = useState("");
|
|
3205
3563
|
const [isOpen, setIsOpen] = useState(false);
|
|
3206
3564
|
const [selectedValue, setSelectedValue] = useState("Upload");
|
|
3207
3565
|
const [fileName, setFileName] = useState("");
|
|
3566
|
+
const [fileSizeError, setFileSizeError] = useState(null);
|
|
3208
3567
|
const hasModifier = useRef(false);
|
|
3209
3568
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
3210
|
-
const isDisabled = disabled || src === "";
|
|
3569
|
+
const isDisabled = disabled || src === "" || !!fileSizeError;
|
|
3211
3570
|
useEffect(() => {
|
|
3212
3571
|
hasModifier.current = false;
|
|
3213
3572
|
const handler = (e) => {
|
|
@@ -3223,31 +3582,44 @@ var InsertImageDialog = ({
|
|
|
3223
3582
|
setAltText("");
|
|
3224
3583
|
setSrc("");
|
|
3225
3584
|
setFileName("");
|
|
3585
|
+
setFileSizeError(null);
|
|
3226
3586
|
};
|
|
3227
3587
|
const loadImage = (event) => {
|
|
3228
3588
|
if (disabled) return;
|
|
3229
3589
|
const files = event.target.files;
|
|
3230
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);
|
|
3231
3605
|
const reader = new FileReader();
|
|
3232
3606
|
reader.onload = () => {
|
|
3233
3607
|
if (typeof reader.result === "string") {
|
|
3234
3608
|
setSrc(reader.result);
|
|
3235
|
-
setFileName(
|
|
3609
|
+
setFileName(file.name);
|
|
3236
3610
|
}
|
|
3237
3611
|
};
|
|
3238
|
-
reader.readAsDataURL(
|
|
3612
|
+
reader.readAsDataURL(file);
|
|
3239
3613
|
};
|
|
3240
3614
|
return /* @__PURE__ */ jsxs(
|
|
3241
|
-
|
|
3615
|
+
Dialog,
|
|
3242
3616
|
{
|
|
3243
|
-
trapFocus: true,
|
|
3244
|
-
withArrow: true,
|
|
3245
3617
|
open: disabled ? false : isOpen,
|
|
3246
3618
|
onOpenChange: (_, data) => {
|
|
3247
3619
|
if (!disabled) setIsOpen(data.open);
|
|
3248
3620
|
},
|
|
3249
3621
|
children: [
|
|
3250
|
-
/* @__PURE__ */ jsx(
|
|
3622
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
3251
3623
|
Button,
|
|
3252
3624
|
{
|
|
3253
3625
|
size: "small",
|
|
@@ -3271,81 +3643,73 @@ var InsertImageDialog = ({
|
|
|
3271
3643
|
},
|
|
3272
3644
|
"upload-image"
|
|
3273
3645
|
) }),
|
|
3274
|
-
/* @__PURE__ */ jsxs(
|
|
3275
|
-
|
|
3276
|
-
{
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
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(
|
|
3650
|
+
"label",
|
|
3651
|
+
{
|
|
3652
|
+
style: {
|
|
3653
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
3654
|
+
display: "flex",
|
|
3655
|
+
alignItems: "center",
|
|
3656
|
+
gap: 8,
|
|
3657
|
+
opacity: disabled ? 0.75 : 1
|
|
3658
|
+
},
|
|
3659
|
+
children: [
|
|
3660
|
+
/* @__PURE__ */ jsx(
|
|
3661
|
+
"input",
|
|
3662
|
+
{
|
|
3663
|
+
type: "file",
|
|
3664
|
+
accept: "image/*",
|
|
3665
|
+
style: { display: "none" },
|
|
3666
|
+
disabled,
|
|
3667
|
+
onChange: loadImage
|
|
3293
3668
|
},
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
selectedValue === "URL" && /* @__PURE__ */ jsx(
|
|
3339
|
-
InsertImageByURL,
|
|
3340
|
-
{
|
|
3341
|
-
disabled,
|
|
3342
|
-
setIsOpen: (open) => setIsOpen(open),
|
|
3343
|
-
onClick: (payload) => onClick(payload)
|
|
3344
|
-
}
|
|
3345
|
-
)
|
|
3346
|
-
]
|
|
3347
|
-
}
|
|
3348
|
-
)
|
|
3669
|
+
"inline-image-upload"
|
|
3670
|
+
),
|
|
3671
|
+
/* @__PURE__ */ jsxs(Stack, { horizontal: true, children: [
|
|
3672
|
+
/* @__PURE__ */ jsx(
|
|
3673
|
+
AttachFilled,
|
|
3674
|
+
{
|
|
3675
|
+
style: {
|
|
3676
|
+
fontSize: "16px",
|
|
3677
|
+
color: disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#808080",
|
|
3678
|
+
marginTop: 2
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
),
|
|
3682
|
+
!fileName && /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#808080" }, children: "Upload File" })
|
|
3683
|
+
] }),
|
|
3684
|
+
fileName && /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#808080" }, children: fileName })
|
|
3685
|
+
]
|
|
3686
|
+
}
|
|
3687
|
+
) }),
|
|
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(
|
|
3690
|
+
Input,
|
|
3691
|
+
{
|
|
3692
|
+
placeholder: "Alt text",
|
|
3693
|
+
appearance: "underline",
|
|
3694
|
+
disabled,
|
|
3695
|
+
onChange: (_, d) => setAltText(d.value),
|
|
3696
|
+
value: altText
|
|
3697
|
+
}
|
|
3698
|
+
) }),
|
|
3699
|
+
selectedValue === "URL" && /* @__PURE__ */ jsx(
|
|
3700
|
+
InsertImageByURL,
|
|
3701
|
+
{
|
|
3702
|
+
disabled,
|
|
3703
|
+
setIsOpen: (open) => setIsOpen(open),
|
|
3704
|
+
onClick: (payload) => onClick(payload)
|
|
3705
|
+
}
|
|
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" })
|
|
3711
|
+
] })
|
|
3712
|
+
] }) })
|
|
3349
3713
|
]
|
|
3350
3714
|
}
|
|
3351
3715
|
);
|
|
@@ -3361,9 +3725,21 @@ var ImagesPlugin = ({ captionsEnabled }) => {
|
|
|
3361
3725
|
INSERT_IMAGE_COMMAND,
|
|
3362
3726
|
(payload) => {
|
|
3363
3727
|
const imageNode = $createImageNode(payload);
|
|
3364
|
-
$
|
|
3365
|
-
if ($
|
|
3366
|
-
|
|
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
|
+
}
|
|
3367
3743
|
}
|
|
3368
3744
|
return true;
|
|
3369
3745
|
},
|
|
@@ -3414,12 +3790,25 @@ var TRANSPARENT_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAA
|
|
|
3414
3790
|
var img = document.createElement("img");
|
|
3415
3791
|
img.src = TRANSPARENT_IMAGE;
|
|
3416
3792
|
var $onDragStart = (event) => {
|
|
3417
|
-
|
|
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
|
+
}
|
|
3418
3802
|
if (!node) return false;
|
|
3419
3803
|
const dataTransfer = event.dataTransfer;
|
|
3420
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
|
+
}
|
|
3421
3811
|
dataTransfer.setData("text/plain", "_");
|
|
3422
|
-
dataTransfer.setDragImage(img, 0, 0);
|
|
3423
3812
|
dataTransfer.setData(
|
|
3424
3813
|
"application/x-lexical-drag",
|
|
3425
3814
|
JSON.stringify({
|
|
@@ -3447,20 +3836,23 @@ var $onDragover = (event) => {
|
|
|
3447
3836
|
return true;
|
|
3448
3837
|
};
|
|
3449
3838
|
var $onDrop = (event, editor) => {
|
|
3450
|
-
const node = $getImageNodeInSelection();
|
|
3451
|
-
if (!node) return false;
|
|
3452
3839
|
const data = getDragImageData(event);
|
|
3453
3840
|
if (!data) return false;
|
|
3454
3841
|
event.preventDefault();
|
|
3455
3842
|
if (canDropImage(event)) {
|
|
3843
|
+
const sourceKey = data.key;
|
|
3844
|
+
if (sourceKey) {
|
|
3845
|
+
const sourceNode = $getNodeByKey(sourceKey);
|
|
3846
|
+
if (sourceNode) sourceNode.remove();
|
|
3847
|
+
}
|
|
3456
3848
|
const range = getDragSelection(event);
|
|
3457
|
-
node.remove();
|
|
3458
3849
|
const rangeSelection = $createRangeSelection();
|
|
3459
3850
|
if (range !== null && range !== void 0) {
|
|
3460
3851
|
rangeSelection.applyDOMRange(range);
|
|
3461
3852
|
}
|
|
3462
3853
|
$setSelection(rangeSelection);
|
|
3463
|
-
|
|
3854
|
+
const { key: _key, ...insertPayload } = data;
|
|
3855
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, insertPayload);
|
|
3464
3856
|
}
|
|
3465
3857
|
return true;
|
|
3466
3858
|
};
|
|
@@ -3480,7 +3872,7 @@ var getDragImageData = (event) => {
|
|
|
3480
3872
|
};
|
|
3481
3873
|
var canDropImage = (event) => {
|
|
3482
3874
|
const target = event.target;
|
|
3483
|
-
return !!(isHTMLElement(target) && !target.closest("code, span.editor-image") &&
|
|
3875
|
+
return !!(isHTMLElement(target) && !target.closest("code, span.editor-image") && target.closest('[contenteditable="true"]'));
|
|
3484
3876
|
};
|
|
3485
3877
|
var getDragSelection = (event) => {
|
|
3486
3878
|
let range;
|
|
@@ -3495,8 +3887,6 @@ var getDragSelection = (event) => {
|
|
|
3495
3887
|
}
|
|
3496
3888
|
return range;
|
|
3497
3889
|
};
|
|
3498
|
-
|
|
3499
|
-
// src/Plugins/InlineImage.tsx
|
|
3500
3890
|
init_InlineImage();
|
|
3501
3891
|
init_InlineImageNode();
|
|
3502
3892
|
var INSERT_INLINE_IMAGE_COMMAND = createCommand(
|
|
@@ -3514,7 +3904,9 @@ var useStyles = makeStyles({
|
|
|
3514
3904
|
});
|
|
3515
3905
|
var InsertInlineImageDialog = ({
|
|
3516
3906
|
disabled,
|
|
3517
|
-
activeEditor
|
|
3907
|
+
activeEditor,
|
|
3908
|
+
maxImageSizeMB,
|
|
3909
|
+
validationMessages
|
|
3518
3910
|
}) => {
|
|
3519
3911
|
const hasModifier = useRef(false);
|
|
3520
3912
|
const [src, setSrc] = useState("");
|
|
@@ -3522,21 +3914,36 @@ var InsertInlineImageDialog = ({
|
|
|
3522
3914
|
const [altText, setAltText] = useState("");
|
|
3523
3915
|
const [fileName, setFileName] = useState("");
|
|
3524
3916
|
const [position, setPosition] = useState("left");
|
|
3917
|
+
const [fileSizeError, setFileSizeError] = useState(null);
|
|
3525
3918
|
const styles = useStyles();
|
|
3526
3919
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
3527
|
-
const isDisabled = disabled || src === "";
|
|
3920
|
+
const isDisabled = disabled || src === "" || !!fileSizeError;
|
|
3528
3921
|
const loadImage = (event) => {
|
|
3529
3922
|
if (disabled) return;
|
|
3530
3923
|
const files = event.target.files;
|
|
3531
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);
|
|
3532
3939
|
const reader = new FileReader();
|
|
3533
3940
|
reader.onload = () => {
|
|
3534
3941
|
if (typeof reader.result === "string") {
|
|
3535
3942
|
setSrc(reader.result);
|
|
3536
|
-
setFileName(
|
|
3943
|
+
setFileName(file.name);
|
|
3537
3944
|
}
|
|
3538
3945
|
};
|
|
3539
|
-
reader.readAsDataURL(
|
|
3946
|
+
reader.readAsDataURL(file);
|
|
3540
3947
|
};
|
|
3541
3948
|
useEffect(() => {
|
|
3542
3949
|
const handler = (e) => {
|
|
@@ -3553,18 +3960,17 @@ var InsertInlineImageDialog = ({
|
|
|
3553
3960
|
setAltText("");
|
|
3554
3961
|
setSrc("");
|
|
3555
3962
|
setFileName("");
|
|
3963
|
+
setFileSizeError(null);
|
|
3556
3964
|
};
|
|
3557
3965
|
return /* @__PURE__ */ jsxs(
|
|
3558
|
-
|
|
3966
|
+
Dialog,
|
|
3559
3967
|
{
|
|
3560
|
-
trapFocus: true,
|
|
3561
|
-
withArrow: true,
|
|
3562
3968
|
open: disabled ? false : isOpen,
|
|
3563
3969
|
onOpenChange: (_, data) => {
|
|
3564
3970
|
if (!disabled) setIsOpen(data.open);
|
|
3565
3971
|
},
|
|
3566
3972
|
children: [
|
|
3567
|
-
/* @__PURE__ */ jsx(
|
|
3973
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
3568
3974
|
Button,
|
|
3569
3975
|
{
|
|
3570
3976
|
size: "small",
|
|
@@ -3588,104 +3994,100 @@ var InsertInlineImageDialog = ({
|
|
|
3588
3994
|
},
|
|
3589
3995
|
"upload-inline-image"
|
|
3590
3996
|
) }),
|
|
3591
|
-
/* @__PURE__ */ jsx(
|
|
3592
|
-
|
|
3593
|
-
{
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
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(
|
|
4001
|
+
"label",
|
|
4002
|
+
{
|
|
4003
|
+
style: {
|
|
4004
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
4005
|
+
display: "flex",
|
|
4006
|
+
alignItems: "center",
|
|
4007
|
+
gap: 8,
|
|
4008
|
+
opacity: disabled ? 0.75 : 1
|
|
4009
|
+
},
|
|
4010
|
+
children: [
|
|
4011
|
+
/* @__PURE__ */ jsx(
|
|
4012
|
+
"input",
|
|
4013
|
+
{
|
|
4014
|
+
type: "file",
|
|
4015
|
+
accept: "image/*",
|
|
4016
|
+
style: { display: "none" },
|
|
4017
|
+
disabled,
|
|
4018
|
+
onChange: loadImage
|
|
4019
|
+
},
|
|
4020
|
+
"inline-image-upload"
|
|
4021
|
+
),
|
|
4022
|
+
/* @__PURE__ */ jsxs(Stack, { horizontal: true, children: [
|
|
3611
4023
|
/* @__PURE__ */ jsx(
|
|
3612
|
-
|
|
4024
|
+
AttachFilled,
|
|
3613
4025
|
{
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
onChange: loadImage
|
|
3619
|
-
},
|
|
3620
|
-
"inline-image-upload"
|
|
3621
|
-
),
|
|
3622
|
-
/* @__PURE__ */ jsxs(Stack, { horizontal: true, children: [
|
|
3623
|
-
/* @__PURE__ */ jsx(
|
|
3624
|
-
AttachFilled,
|
|
3625
|
-
{
|
|
3626
|
-
style: {
|
|
3627
|
-
fontSize: "16px",
|
|
3628
|
-
color: disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#808080",
|
|
3629
|
-
marginTop: 2
|
|
3630
|
-
}
|
|
4026
|
+
style: {
|
|
4027
|
+
fontSize: "16px",
|
|
4028
|
+
color: disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#808080",
|
|
4029
|
+
marginTop: 2
|
|
3631
4030
|
}
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
4031
|
+
}
|
|
4032
|
+
),
|
|
4033
|
+
!fileName && /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#808080" }, children: "Upload File" })
|
|
4034
|
+
] }),
|
|
4035
|
+
fileName && /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#808080" }, children: fileName })
|
|
4036
|
+
]
|
|
4037
|
+
}
|
|
4038
|
+
) }),
|
|
4039
|
+
/* @__PURE__ */ jsx(Field, { label: "Position", size: "small", children: /* @__PURE__ */ jsxs(
|
|
4040
|
+
Dropdown,
|
|
4041
|
+
{
|
|
4042
|
+
className: styles.alignDropdown,
|
|
4043
|
+
disabled,
|
|
4044
|
+
value: position === "full" ? "Full" : position === "right" ? "Right" : "Left",
|
|
4045
|
+
selectedOptions: [position ?? "left"],
|
|
4046
|
+
listbox: { style: { width: "120px" } },
|
|
4047
|
+
root: { style: { borderBottom: "1px solid black" } },
|
|
4048
|
+
onOptionSelect: (_, data) => setPosition(data.optionValue),
|
|
4049
|
+
children: [
|
|
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")
|
|
4053
|
+
]
|
|
4054
|
+
}
|
|
4055
|
+
) }),
|
|
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(
|
|
4058
|
+
Input,
|
|
4059
|
+
{
|
|
4060
|
+
placeholder: "Alt text",
|
|
4061
|
+
appearance: "underline",
|
|
4062
|
+
disabled,
|
|
4063
|
+
value: altText,
|
|
4064
|
+
onChange: (_, d) => setAltText(d.value)
|
|
4065
|
+
}
|
|
4066
|
+
) })
|
|
4067
|
+
] }) }),
|
|
4068
|
+
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
4069
|
+
/* @__PURE__ */ jsx(
|
|
4070
|
+
Button,
|
|
4071
|
+
{
|
|
4072
|
+
size: "small",
|
|
4073
|
+
disabled: isDisabled,
|
|
4074
|
+
onClick: handleOnClick,
|
|
4075
|
+
children: "Add"
|
|
4076
|
+
},
|
|
4077
|
+
"file-inline-upload-btn"
|
|
4078
|
+
),
|
|
4079
|
+
/* @__PURE__ */ jsx(
|
|
4080
|
+
Button,
|
|
4081
|
+
{
|
|
4082
|
+
size: "small",
|
|
4083
|
+
disabled,
|
|
4084
|
+
onClick: () => setIsOpen(false),
|
|
4085
|
+
children: "Cancel"
|
|
4086
|
+
},
|
|
4087
|
+
"file-inline-upload-cancel"
|
|
4088
|
+
)
|
|
4089
|
+
] })
|
|
4090
|
+
] }) })
|
|
3689
4091
|
]
|
|
3690
4092
|
}
|
|
3691
4093
|
);
|
|
@@ -3705,6 +4107,11 @@ var InlineImagePlugin = () => {
|
|
|
3705
4107
|
if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) {
|
|
3706
4108
|
$wrapNodeInElement(imageNode, $createParagraphNode).selectEnd();
|
|
3707
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
|
+
}
|
|
3708
4115
|
return true;
|
|
3709
4116
|
},
|
|
3710
4117
|
COMMAND_PRIORITY_EDITOR
|
|
@@ -3733,12 +4140,23 @@ var TRANSPARENT_IMAGE2 = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEA
|
|
|
3733
4140
|
var img2 = document.createElement("img");
|
|
3734
4141
|
img2.src = TRANSPARENT_IMAGE2;
|
|
3735
4142
|
function $onDragStart2(event) {
|
|
3736
|
-
|
|
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
|
+
}
|
|
3737
4150
|
if (!node) return false;
|
|
3738
4151
|
const dataTransfer = event.dataTransfer;
|
|
3739
4152
|
if (!dataTransfer) return false;
|
|
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
|
+
}
|
|
3740
4159
|
dataTransfer.setData("text/plain", "_");
|
|
3741
|
-
dataTransfer.setDragImage(img2, 0, 0);
|
|
3742
4160
|
dataTransfer.setData(
|
|
3743
4161
|
"application/x-lexical-drag",
|
|
3744
4162
|
JSON.stringify({
|
|
@@ -3757,28 +4175,31 @@ function $onDragStart2(event) {
|
|
|
3757
4175
|
return true;
|
|
3758
4176
|
}
|
|
3759
4177
|
var $onDragover2 = (event) => {
|
|
3760
|
-
const
|
|
3761
|
-
if (!
|
|
4178
|
+
const hasDragData = !!event.dataTransfer?.types.includes("application/x-lexical-drag");
|
|
4179
|
+
if (!hasDragData) return false;
|
|
3762
4180
|
if (!canDropImage2(event)) {
|
|
3763
4181
|
event.preventDefault();
|
|
3764
4182
|
}
|
|
3765
4183
|
return true;
|
|
3766
4184
|
};
|
|
3767
4185
|
var $onDrop2 = (event, editor) => {
|
|
3768
|
-
const node = $getImageNodeInSelection2();
|
|
3769
|
-
if (!node) return false;
|
|
3770
4186
|
const data = getDragImageData2(event);
|
|
3771
4187
|
if (!data) return false;
|
|
3772
4188
|
event.preventDefault();
|
|
3773
4189
|
if (canDropImage2(event)) {
|
|
4190
|
+
const sourceKey = data.key;
|
|
4191
|
+
if (sourceKey) {
|
|
4192
|
+
const sourceNode = $getNodeByKey(sourceKey);
|
|
4193
|
+
if (sourceNode) sourceNode.remove();
|
|
4194
|
+
}
|
|
3774
4195
|
const range = getDragSelection2(event);
|
|
3775
|
-
node.remove();
|
|
3776
4196
|
const rangeSelection = $createRangeSelection();
|
|
3777
4197
|
if (range !== null && range !== void 0) {
|
|
3778
4198
|
rangeSelection.applyDOMRange(range);
|
|
3779
4199
|
}
|
|
3780
4200
|
$setSelection(rangeSelection);
|
|
3781
|
-
|
|
4201
|
+
const { key: _key, ...insertPayload } = data;
|
|
4202
|
+
editor.dispatchCommand(INSERT_INLINE_IMAGE_COMMAND, insertPayload);
|
|
3782
4203
|
}
|
|
3783
4204
|
return true;
|
|
3784
4205
|
};
|
|
@@ -3798,7 +4219,7 @@ var getDragImageData2 = (event) => {
|
|
|
3798
4219
|
};
|
|
3799
4220
|
var canDropImage2 = (event) => {
|
|
3800
4221
|
const target = event.target;
|
|
3801
|
-
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"]'));
|
|
3802
4223
|
};
|
|
3803
4224
|
var getDragSelection2 = (event) => {
|
|
3804
4225
|
let range;
|
|
@@ -3889,20 +4310,79 @@ function hasBlock(editor, kind) {
|
|
|
3889
4310
|
}
|
|
3890
4311
|
|
|
3891
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
|
+
}
|
|
3892
4350
|
function RefApiPlugin({
|
|
3893
4351
|
forwardedRef,
|
|
3894
4352
|
contentEditableDomRef,
|
|
3895
|
-
focusedRef
|
|
3896
|
-
setRefErrors
|
|
4353
|
+
focusedRef
|
|
3897
4354
|
}) {
|
|
3898
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]);
|
|
3899
4378
|
useImperativeHandle(
|
|
3900
4379
|
forwardedRef,
|
|
3901
4380
|
() => ({
|
|
3902
4381
|
setValue: (html) => {
|
|
3903
4382
|
editor.update(() => {
|
|
4383
|
+
const safe = normalizeToBlockHtml(sanitizeHtml(html || ""));
|
|
3904
4384
|
const parser = new DOMParser();
|
|
3905
|
-
const dom = parser.parseFromString(
|
|
4385
|
+
const dom = parser.parseFromString(safe || "<p></p>", "text/html");
|
|
3906
4386
|
const nodes = $generateNodesFromDOM(editor, dom);
|
|
3907
4387
|
const root = $getRoot();
|
|
3908
4388
|
root.clear();
|
|
@@ -3912,9 +4392,9 @@ function RefApiPlugin({
|
|
|
3912
4392
|
getValue: () => {
|
|
3913
4393
|
let html = "";
|
|
3914
4394
|
editor.getEditorState().read(() => {
|
|
3915
|
-
html = $generateHtmlFromNodes(editor, null);
|
|
4395
|
+
html = postProcessOutput(splitHeadingsAtBrSequences($generateHtmlFromNodes(editor, null)));
|
|
3916
4396
|
});
|
|
3917
|
-
return
|
|
4397
|
+
return html;
|
|
3918
4398
|
},
|
|
3919
4399
|
clear: () => {
|
|
3920
4400
|
editor.update(() => {
|
|
@@ -3932,14 +4412,20 @@ function RefApiPlugin({
|
|
|
3932
4412
|
},
|
|
3933
4413
|
isFocused: () => focusedRef.current,
|
|
3934
4414
|
getEditor: () => editor,
|
|
3935
|
-
setErrors: (messages) => setRefErrors(messages),
|
|
3936
|
-
clearErrors: () => setRefErrors([]),
|
|
3937
4415
|
// Generic blocks (signature, footer, banner, etc.)
|
|
3938
4416
|
upsertBlock: (spec) => upsertBlock(editor, spec),
|
|
3939
4417
|
removeBlock: (kind) => removeBlock(editor, kind),
|
|
3940
|
-
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
|
+
}
|
|
3941
4427
|
}),
|
|
3942
|
-
[editor, contentEditableDomRef, focusedRef
|
|
4428
|
+
[editor, contentEditableDomRef, focusedRef]
|
|
3943
4429
|
);
|
|
3944
4430
|
return null;
|
|
3945
4431
|
}
|
|
@@ -4580,8 +5066,22 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4580
5066
|
const [editor] = useLexicalComposerContext();
|
|
4581
5067
|
const [isInTable, setIsInTable] = React9.useState(false);
|
|
4582
5068
|
const [anchorRect, setAnchorRect] = React9.useState(null);
|
|
5069
|
+
const [contentRight, setContentRight] = React9.useState(null);
|
|
4583
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
|
+
}, []);
|
|
4584
5083
|
const updateFromSelection = React9.useCallback(() => {
|
|
5084
|
+
if (openRef.current) return;
|
|
4585
5085
|
const root = editor.getRootElement();
|
|
4586
5086
|
if (!root) return;
|
|
4587
5087
|
editor.getEditorState().read(() => {
|
|
@@ -4593,6 +5093,7 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4593
5093
|
if (dom) {
|
|
4594
5094
|
setIsInTable(true);
|
|
4595
5095
|
setAnchorRect(dom.getBoundingClientRect());
|
|
5096
|
+
setContentRight(null);
|
|
4596
5097
|
return;
|
|
4597
5098
|
}
|
|
4598
5099
|
}
|
|
@@ -4600,6 +5101,7 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4600
5101
|
if (!$isRangeSelection(selection)) {
|
|
4601
5102
|
setIsInTable(false);
|
|
4602
5103
|
setAnchorRect(null);
|
|
5104
|
+
setContentRight(null);
|
|
4603
5105
|
return;
|
|
4604
5106
|
}
|
|
4605
5107
|
const anchorNode = selection.anchor.getNode();
|
|
@@ -4607,18 +5109,28 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4607
5109
|
if (!cellNode || !$isTableCellNode(cellNode)) {
|
|
4608
5110
|
setIsInTable(false);
|
|
4609
5111
|
setAnchorRect(null);
|
|
5112
|
+
setContentRight(null);
|
|
4610
5113
|
return;
|
|
4611
5114
|
}
|
|
4612
5115
|
const cellDom = editor.getElementByKey(cellNode.getKey());
|
|
4613
5116
|
if (!cellDom) {
|
|
4614
5117
|
setIsInTable(false);
|
|
4615
5118
|
setAnchorRect(null);
|
|
5119
|
+
setContentRight(null);
|
|
4616
5120
|
return;
|
|
4617
5121
|
}
|
|
4618
5122
|
setIsInTable(true);
|
|
4619
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
|
+
}
|
|
4620
5132
|
});
|
|
4621
|
-
}, [editor]);
|
|
5133
|
+
}, [editor, measureContentRight]);
|
|
4622
5134
|
React9.useEffect(() => {
|
|
4623
5135
|
return mergeRegister(
|
|
4624
5136
|
editor.registerCommand(
|
|
@@ -4675,31 +5187,38 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4675
5187
|
COMMAND_PRIORITY_HIGH
|
|
4676
5188
|
);
|
|
4677
5189
|
}, [editor, disabled]);
|
|
4678
|
-
React9.useEffect(() => {
|
|
4679
|
-
if (!isInTable && open) setOpen(false);
|
|
4680
|
-
}, [isInTable, open]);
|
|
4681
5190
|
const canShow = isInTable && !!anchorRect && !disabled;
|
|
4682
5191
|
const handleStyle = React9.useMemo(() => {
|
|
4683
5192
|
if (!anchorRect) return void 0;
|
|
4684
5193
|
const top = Math.max(8, anchorRect.top + 6);
|
|
4685
|
-
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);
|
|
4686
5196
|
return {
|
|
4687
5197
|
position: "fixed",
|
|
4688
5198
|
top,
|
|
4689
5199
|
left,
|
|
4690
5200
|
zIndex: 9999
|
|
4691
5201
|
};
|
|
4692
|
-
}, [anchorRect]);
|
|
5202
|
+
}, [anchorRect, contentRight]);
|
|
4693
5203
|
const dangerStyle = {
|
|
4694
5204
|
color: "var(--colorPaletteRedForeground1)"
|
|
4695
5205
|
};
|
|
4696
5206
|
const run = React9.useCallback(
|
|
4697
5207
|
(fn) => {
|
|
4698
5208
|
if (disabled) return;
|
|
4699
|
-
|
|
4700
|
-
editor.update(() => fn());
|
|
5209
|
+
openRef.current = false;
|
|
4701
5210
|
setOpen(false);
|
|
4702
|
-
|
|
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
|
+
});
|
|
5221
|
+
},
|
|
4703
5222
|
[disabled, editor]
|
|
4704
5223
|
);
|
|
4705
5224
|
const insertRowBelow = () => run(() => $insertTableRowAtSelection(true));
|
|
@@ -4708,32 +5227,31 @@ function TableActionMenuPlugin({ disabled = false }) {
|
|
|
4708
5227
|
const insertColLeft = () => run(() => $insertTableColumnAtSelection(false));
|
|
4709
5228
|
const deleteRow = () => run(() => $deleteTableRowAtSelection());
|
|
4710
5229
|
const deleteCol = () => run(() => $deleteTableColumnAtSelection());
|
|
4711
|
-
const deleteTable = () =>
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
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));
|
|
4715
5240
|
if (tableNode) tableNode.remove();
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
if (!$isRangeSelection(selection)) return;
|
|
4719
|
-
const node = selection.anchor.getNode();
|
|
4720
|
-
const cell = $findMatchingParent(node, (n) => $isTableCellNode(n)) ?? ($isTableCellNode(node) ? node : null);
|
|
4721
|
-
if (!cell) return;
|
|
4722
|
-
const table = $getTableNodeFromLexicalNodeOrThrow(cell);
|
|
4723
|
-
table.remove();
|
|
4724
|
-
});
|
|
5241
|
+
});
|
|
5242
|
+
};
|
|
4725
5243
|
if (!canShow || !handleStyle) return null;
|
|
4726
5244
|
return createPortal(
|
|
4727
|
-
/* @__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: [
|
|
4728
5249
|
/* @__PURE__ */ jsx(MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
4729
5250
|
"button",
|
|
4730
5251
|
{
|
|
4731
5252
|
type: "button",
|
|
4732
5253
|
className: "aoTableActionHandleBtn",
|
|
4733
5254
|
"aria-label": "Table options",
|
|
4734
|
-
onMouseDown: (e) => {
|
|
4735
|
-
e.preventDefault();
|
|
4736
|
-
},
|
|
4737
5255
|
children: /* @__PURE__ */ jsx(ChevronDown12Regular, {})
|
|
4738
5256
|
}
|
|
4739
5257
|
) }),
|
|
@@ -5084,6 +5602,85 @@ function getToolbarGroupsByLevel(level) {
|
|
|
5084
5602
|
];
|
|
5085
5603
|
}
|
|
5086
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
|
+
};
|
|
5087
5684
|
var PRESET = [
|
|
5088
5685
|
"#000000",
|
|
5089
5686
|
"#434343",
|
|
@@ -5367,7 +5964,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5367
5964
|
directionalHint: 4,
|
|
5368
5965
|
className: "aoColorCallout",
|
|
5369
5966
|
preventDismissOnEvent,
|
|
5370
|
-
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: [
|
|
5371
5968
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
5372
5969
|
/* @__PURE__ */ jsx("div", { style: { fontSize: 13, fontWeight: 600, color: "#242424", letterSpacing: 0.1 }, children: title }),
|
|
5373
5970
|
/* @__PURE__ */ jsx(
|
|
@@ -5380,8 +5977,8 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5380
5977
|
display: "flex",
|
|
5381
5978
|
alignItems: "center",
|
|
5382
5979
|
justifyContent: "center",
|
|
5383
|
-
width:
|
|
5384
|
-
height:
|
|
5980
|
+
width: 18,
|
|
5981
|
+
height: 18,
|
|
5385
5982
|
padding: 0,
|
|
5386
5983
|
border: "none",
|
|
5387
5984
|
borderRadius: 4,
|
|
@@ -5404,7 +6001,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5404
6001
|
style: {
|
|
5405
6002
|
position: "relative",
|
|
5406
6003
|
width: "100%",
|
|
5407
|
-
height:
|
|
6004
|
+
height: 125,
|
|
5408
6005
|
borderRadius: 8,
|
|
5409
6006
|
overflow: "hidden",
|
|
5410
6007
|
cursor: "crosshair",
|
|
@@ -5493,8 +6090,8 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5493
6090
|
"div",
|
|
5494
6091
|
{
|
|
5495
6092
|
style: {
|
|
5496
|
-
width:
|
|
5497
|
-
height:
|
|
6093
|
+
width: 20,
|
|
6094
|
+
height: 20,
|
|
5498
6095
|
borderRadius: 6,
|
|
5499
6096
|
flexShrink: 0,
|
|
5500
6097
|
background: hex,
|
|
@@ -5535,10 +6132,10 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
|
|
|
5535
6132
|
title: c,
|
|
5536
6133
|
"aria-label": c,
|
|
5537
6134
|
style: {
|
|
5538
|
-
width:
|
|
5539
|
-
height:
|
|
6135
|
+
width: 18,
|
|
6136
|
+
height: 18,
|
|
5540
6137
|
padding: 0,
|
|
5541
|
-
borderRadius:
|
|
6138
|
+
borderRadius: 4,
|
|
5542
6139
|
background: c,
|
|
5543
6140
|
cursor: "pointer",
|
|
5544
6141
|
boxShadow: isSelected ? "0 0 0 2px #fff, 0 0 0 3px #4a86e8" : "inset 0 0 0 1px rgba(0,0,0,0.15)",
|
|
@@ -5748,7 +6345,6 @@ var FontFamilyPlugin = ({ disabled = false }) => {
|
|
|
5748
6345
|
"font-family"
|
|
5749
6346
|
);
|
|
5750
6347
|
};
|
|
5751
|
-
var DEFAULT_FONT_SIZE = 15;
|
|
5752
6348
|
var FONT_SIZE_OPTIONS = [
|
|
5753
6349
|
"8",
|
|
5754
6350
|
"9",
|
|
@@ -5884,104 +6480,42 @@ var FontSizePlugin = ({ disabled }) => {
|
|
|
5884
6480
|
"fontsize"
|
|
5885
6481
|
) });
|
|
5886
6482
|
};
|
|
5887
|
-
var InsertLinkPlugin = ({
|
|
6483
|
+
var InsertLinkPlugin = ({
|
|
6484
|
+
disabled,
|
|
6485
|
+
setIsLinkEditMode
|
|
6486
|
+
}) => {
|
|
5888
6487
|
const [editor] = useLexicalComposerContext();
|
|
5889
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
5890
|
-
const [text, setText] = useState("");
|
|
5891
|
-
const [link, setLink] = useState("");
|
|
5892
6488
|
const iconColor = disabled ? "var(--colorNeutralForegroundDisabled, #A6A6A6)" : "#333333";
|
|
5893
|
-
const insertLink = (
|
|
6489
|
+
const insertLink = () => {
|
|
5894
6490
|
if (disabled) return;
|
|
5895
6491
|
editor.update(() => {
|
|
5896
|
-
setText("");
|
|
5897
|
-
setLink("");
|
|
5898
6492
|
const selection = $getSelection();
|
|
5899
|
-
if (
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
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://");
|
|
5904
6498
|
}
|
|
5905
|
-
setIsOpen(false);
|
|
5906
6499
|
});
|
|
6500
|
+
setIsLinkEditMode(true);
|
|
5907
6501
|
};
|
|
5908
|
-
return /* @__PURE__ */
|
|
5909
|
-
|
|
6502
|
+
return /* @__PURE__ */ jsx(
|
|
6503
|
+
Button,
|
|
5910
6504
|
{
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
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"
|
|
5916
6515
|
},
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
{
|
|
5921
|
-
size: "small",
|
|
5922
|
-
title: "Add link",
|
|
5923
|
-
disabled,
|
|
5924
|
-
icon: /* @__PURE__ */ jsx(LinkAddRegular, { style: { color: iconColor } }),
|
|
5925
|
-
style: {
|
|
5926
|
-
background: isOpen && !disabled ? "#ebebeb" : "none",
|
|
5927
|
-
border: "none",
|
|
5928
|
-
margin: 2,
|
|
5929
|
-
opacity: disabled ? 0.55 : 1,
|
|
5930
|
-
cursor: disabled ? "not-allowed" : "pointer"
|
|
5931
|
-
},
|
|
5932
|
-
onClick: () => {
|
|
5933
|
-
if (!disabled) setIsOpen((prev) => !prev);
|
|
5934
|
-
}
|
|
5935
|
-
},
|
|
5936
|
-
"upload-link"
|
|
5937
|
-
) }),
|
|
5938
|
-
/* @__PURE__ */ jsx(
|
|
5939
|
-
PopoverSurface,
|
|
5940
|
-
{
|
|
5941
|
-
style: {
|
|
5942
|
-
width: "270px",
|
|
5943
|
-
opacity: disabled ? 0.6 : 1,
|
|
5944
|
-
pointerEvents: disabled ? "none" : "auto"
|
|
5945
|
-
},
|
|
5946
|
-
children: /* @__PURE__ */ jsxs(Stack, { tokens: { childrenGap: 10 }, children: [
|
|
5947
|
-
/* @__PURE__ */ jsx(Field, { label: "Text", orientation: "horizontal", size: "small", children: /* @__PURE__ */ jsx(
|
|
5948
|
-
Input,
|
|
5949
|
-
{
|
|
5950
|
-
autoFocus: !disabled,
|
|
5951
|
-
value: text,
|
|
5952
|
-
appearance: "underline",
|
|
5953
|
-
placeholder: "Text",
|
|
5954
|
-
disabled,
|
|
5955
|
-
onChange: (_, v) => setText(v.value)
|
|
5956
|
-
}
|
|
5957
|
-
) }),
|
|
5958
|
-
/* @__PURE__ */ jsx(Field, { label: "Link", orientation: "horizontal", size: "small", children: /* @__PURE__ */ jsx(
|
|
5959
|
-
Input,
|
|
5960
|
-
{
|
|
5961
|
-
value: link,
|
|
5962
|
-
appearance: "underline",
|
|
5963
|
-
placeholder: "Link",
|
|
5964
|
-
disabled,
|
|
5965
|
-
onChange: (_, v) => setLink(v.value)
|
|
5966
|
-
}
|
|
5967
|
-
) }),
|
|
5968
|
-
/* @__PURE__ */ jsxs(Stack, { horizontal: true, horizontalAlign: "end", tokens: { childrenGap: 6 }, children: [
|
|
5969
|
-
/* @__PURE__ */ jsx(
|
|
5970
|
-
Button,
|
|
5971
|
-
{
|
|
5972
|
-
size: "small",
|
|
5973
|
-
disabled: disabled || !text || !link,
|
|
5974
|
-
onClick: () => insertLink(text, link),
|
|
5975
|
-
children: "Add"
|
|
5976
|
-
}
|
|
5977
|
-
),
|
|
5978
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
5979
|
-
] })
|
|
5980
|
-
] })
|
|
5981
|
-
}
|
|
5982
|
-
)
|
|
5983
|
-
]
|
|
5984
|
-
}
|
|
6516
|
+
onClick: insertLink
|
|
6517
|
+
},
|
|
6518
|
+
"insert-link"
|
|
5985
6519
|
);
|
|
5986
6520
|
};
|
|
5987
6521
|
function PageSetupPlugin({ disabled, value, onChange }) {
|
|
@@ -6058,16 +6592,14 @@ var TableItemPlugin = ({ disabled }) => {
|
|
|
6058
6592
|
setIsOpen(false);
|
|
6059
6593
|
};
|
|
6060
6594
|
return /* @__PURE__ */ jsxs(
|
|
6061
|
-
|
|
6595
|
+
Dialog,
|
|
6062
6596
|
{
|
|
6063
|
-
trapFocus: true,
|
|
6064
|
-
withArrow: true,
|
|
6065
6597
|
open: disabled ? false : isOpen,
|
|
6066
6598
|
onOpenChange: (_, data) => {
|
|
6067
6599
|
if (!disabled) setIsOpen(data.open);
|
|
6068
6600
|
},
|
|
6069
6601
|
children: [
|
|
6070
|
-
/* @__PURE__ */ jsx(
|
|
6602
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
6071
6603
|
Button,
|
|
6072
6604
|
{
|
|
6073
6605
|
size: "small",
|
|
@@ -6090,58 +6622,45 @@ var TableItemPlugin = ({ disabled }) => {
|
|
|
6090
6622
|
},
|
|
6091
6623
|
"insert-table-nodes"
|
|
6092
6624
|
) }),
|
|
6093
|
-
/* @__PURE__ */ jsx(
|
|
6094
|
-
|
|
6095
|
-
{
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
{
|
|
6133
|
-
size: "small",
|
|
6134
|
-
appearance: "primary",
|
|
6135
|
-
disabled: disabled || !rows || !columns,
|
|
6136
|
-
onClick: onAddTable,
|
|
6137
|
-
children: "Add"
|
|
6138
|
-
}
|
|
6139
|
-
),
|
|
6140
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
6141
|
-
] })
|
|
6142
|
-
] })
|
|
6143
|
-
}
|
|
6144
|
-
)
|
|
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,
|
|
6630
|
+
{
|
|
6631
|
+
autoFocus: !disabled,
|
|
6632
|
+
value: rows,
|
|
6633
|
+
placeholder: "Rows",
|
|
6634
|
+
appearance: "underline",
|
|
6635
|
+
disabled,
|
|
6636
|
+
onChange: (_, v) => setRows(v.value)
|
|
6637
|
+
}
|
|
6638
|
+
) }),
|
|
6639
|
+
/* @__PURE__ */ jsx(Field, { label: "Columns", size: "small", children: /* @__PURE__ */ jsx(
|
|
6640
|
+
Input,
|
|
6641
|
+
{
|
|
6642
|
+
value: columns,
|
|
6643
|
+
placeholder: "Columns",
|
|
6644
|
+
appearance: "underline",
|
|
6645
|
+
disabled,
|
|
6646
|
+
onChange: (_, v) => setColumns(v.value)
|
|
6647
|
+
}
|
|
6648
|
+
) })
|
|
6649
|
+
] }) }),
|
|
6650
|
+
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
6651
|
+
/* @__PURE__ */ jsx(
|
|
6652
|
+
Button,
|
|
6653
|
+
{
|
|
6654
|
+
size: "small",
|
|
6655
|
+
appearance: "primary",
|
|
6656
|
+
disabled: disabled || !rows || !columns,
|
|
6657
|
+
onClick: onAddTable,
|
|
6658
|
+
children: "Add"
|
|
6659
|
+
}
|
|
6660
|
+
),
|
|
6661
|
+
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
6662
|
+
] })
|
|
6663
|
+
] }) })
|
|
6145
6664
|
]
|
|
6146
6665
|
}
|
|
6147
6666
|
);
|
|
@@ -6165,16 +6684,14 @@ var YoutubeUploadPlugin = ({ disabled }) => {
|
|
|
6165
6684
|
setIsOpen(false);
|
|
6166
6685
|
};
|
|
6167
6686
|
return /* @__PURE__ */ jsxs(
|
|
6168
|
-
|
|
6687
|
+
Dialog,
|
|
6169
6688
|
{
|
|
6170
|
-
trapFocus: true,
|
|
6171
|
-
withArrow: true,
|
|
6172
6689
|
open: disabled ? false : isOpen,
|
|
6173
6690
|
onOpenChange: (_, data) => {
|
|
6174
6691
|
if (!disabled) setIsOpen(data.open);
|
|
6175
6692
|
},
|
|
6176
6693
|
children: [
|
|
6177
|
-
/* @__PURE__ */ jsx(
|
|
6694
|
+
/* @__PURE__ */ jsx(DialogTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsx(
|
|
6178
6695
|
Button,
|
|
6179
6696
|
{
|
|
6180
6697
|
title: "Add youtube URL",
|
|
@@ -6196,37 +6713,36 @@ var YoutubeUploadPlugin = ({ disabled }) => {
|
|
|
6196
6713
|
},
|
|
6197
6714
|
"upload-video"
|
|
6198
6715
|
) }),
|
|
6199
|
-
/* @__PURE__ */ jsx(
|
|
6200
|
-
|
|
6201
|
-
{
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
}
|
|
6218
|
-
) }),
|
|
6219
|
-
/* @__PURE__ */ jsxs(Stack, { horizontal: true, horizontalAlign: "end", tokens: { childrenGap: 6 }, children: [
|
|
6220
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled: disabled || !url, onClick: onHandleEmbeded, children: "Add" }),
|
|
6221
|
-
/* @__PURE__ */ jsx(Button, { size: "small", disabled, onClick: () => setIsOpen(false), children: "Cancel" })
|
|
6222
|
-
] })
|
|
6223
|
-
] })
|
|
6224
|
-
}
|
|
6225
|
-
)
|
|
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" })
|
|
6732
|
+
] })
|
|
6733
|
+
] }) })
|
|
6226
6734
|
]
|
|
6227
6735
|
}
|
|
6228
6736
|
);
|
|
6229
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
|
+
] });
|
|
6230
6746
|
var useStyles4 = makeStyles({
|
|
6231
6747
|
dropdown: {
|
|
6232
6748
|
minInlineSize: "90px",
|
|
@@ -6244,24 +6760,42 @@ var ALLOWED_TOKENS = {
|
|
|
6244
6760
|
Bold: true,
|
|
6245
6761
|
Italic: true,
|
|
6246
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,
|
|
6247
6781
|
ColorPicker: true,
|
|
6248
6782
|
Link: true,
|
|
6249
6783
|
Table: true,
|
|
6250
6784
|
Image: true,
|
|
6251
6785
|
InlineImage: true,
|
|
6252
6786
|
Youtube: true,
|
|
6253
|
-
Heading: true,
|
|
6254
6787
|
FontFamily: true,
|
|
6255
6788
|
FontSize: true,
|
|
6789
|
+
Align: true,
|
|
6790
|
+
Heading: true,
|
|
6256
6791
|
Decorators: true,
|
|
6257
6792
|
CodeBlock: true,
|
|
6258
|
-
Align: true,
|
|
6259
6793
|
PageSetup: true
|
|
6260
6794
|
};
|
|
6261
6795
|
function sanitizePluginGroups(groups) {
|
|
6262
|
-
if (!groups || groups.length === 0) return [];
|
|
6796
|
+
if (!Array.isArray(groups) || groups.length === 0) return [];
|
|
6263
6797
|
return groups.map(
|
|
6264
|
-
(g) => (g
|
|
6798
|
+
(g) => (Array.isArray(g) ? g : []).map((t) => typeof t === "string" ? t.trim() : "").filter((t) => ALLOWED_TOKENS[t] === true)
|
|
6265
6799
|
).filter((g) => g.length > 0);
|
|
6266
6800
|
}
|
|
6267
6801
|
var ToolBarPlugins = (props) => {
|
|
@@ -6281,8 +6815,9 @@ var ToolBarPlugins = (props) => {
|
|
|
6281
6815
|
const [isLowercase, setIsLowercase] = useState(false);
|
|
6282
6816
|
const [isCapitalize, setIsCapitalize] = useState(false);
|
|
6283
6817
|
const [alignment, setAlignment] = useState("left");
|
|
6284
|
-
const
|
|
6285
|
-
const
|
|
6818
|
+
const [decoratorOpen, setDecoratorOpen] = useState(false);
|
|
6819
|
+
const decoratorSelectingRef = React9__default.useRef(false);
|
|
6820
|
+
const presetGroups = props.customToolbar ?? getToolbarGroupsByLevel(props.level);
|
|
6286
6821
|
const pluginGroups = useMemo(() => sanitizePluginGroups(presetGroups), [presetGroups]);
|
|
6287
6822
|
const updateToolbarPlugins = () => {
|
|
6288
6823
|
const selection = $getSelection();
|
|
@@ -6324,6 +6859,10 @@ var ToolBarPlugins = (props) => {
|
|
|
6324
6859
|
setSelectNodeType("paragraph");
|
|
6325
6860
|
return;
|
|
6326
6861
|
}
|
|
6862
|
+
if ($isAlphaListNode(element)) {
|
|
6863
|
+
setSelectNodeType("alpha");
|
|
6864
|
+
return;
|
|
6865
|
+
}
|
|
6327
6866
|
if ($isListNode(element)) {
|
|
6328
6867
|
const parentList = $getNearestNodeOfType(anchorNode, ListNode);
|
|
6329
6868
|
const type2 = parentList ? parentList.getTag() : element.getTag();
|
|
@@ -6335,23 +6874,15 @@ var ToolBarPlugins = (props) => {
|
|
|
6335
6874
|
["paragraph", "h1", "h2", "h3", "h4", "h5", "h6", "ul", "ol", "quote", "code"].includes(type) ? type : "paragraph"
|
|
6336
6875
|
);
|
|
6337
6876
|
};
|
|
6338
|
-
const applyToBlock = React9__default.useCallback(
|
|
6339
|
-
(fn) => {
|
|
6340
|
-
editor.update(() => {
|
|
6341
|
-
const saved = lastSelectionRef.current;
|
|
6342
|
-
if (saved) $setSelection(saved.clone());
|
|
6343
|
-
const sel = $getSelection();
|
|
6344
|
-
if ($isRangeSelection(sel)) fn(sel);
|
|
6345
|
-
});
|
|
6346
|
-
},
|
|
6347
|
-
[editor]
|
|
6348
|
-
);
|
|
6349
6877
|
const formatQuote = () => {
|
|
6350
|
-
|
|
6878
|
+
editor.update(() => {
|
|
6879
|
+
const selection = $getSelection();
|
|
6880
|
+
if (!$isRangeSelection(selection)) return;
|
|
6351
6881
|
if (selectNodeType === "quote") {
|
|
6352
|
-
|
|
6882
|
+
formatParagraph(editor);
|
|
6353
6883
|
} else {
|
|
6354
|
-
$
|
|
6884
|
+
$splitBlocksAtLineBreaks(selection);
|
|
6885
|
+
$setBlocksType($getSelection(), () => $createQuoteNode());
|
|
6355
6886
|
}
|
|
6356
6887
|
});
|
|
6357
6888
|
};
|
|
@@ -6368,8 +6899,6 @@ var ToolBarPlugins = (props) => {
|
|
|
6368
6899
|
editor.registerCommand(
|
|
6369
6900
|
SELECTION_CHANGE_COMMAND,
|
|
6370
6901
|
() => {
|
|
6371
|
-
const sel = $getSelection();
|
|
6372
|
-
if ($isRangeSelection(sel)) lastSelectionRef.current = sel.clone();
|
|
6373
6902
|
updateToolbarPlugins();
|
|
6374
6903
|
return false;
|
|
6375
6904
|
},
|
|
@@ -6401,52 +6930,16 @@ var ToolBarPlugins = (props) => {
|
|
|
6401
6930
|
editor.dispatchCommand(FORMAT_TEXT_COMMAND, "highlight");
|
|
6402
6931
|
break;
|
|
6403
6932
|
case "leftAlign" /* LeftAlign */:
|
|
6404
|
-
|
|
6405
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6406
|
-
sel.getNodes().forEach((n) => {
|
|
6407
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6408
|
-
if (!seen.has(t.getKey())) {
|
|
6409
|
-
seen.add(t.getKey());
|
|
6410
|
-
t.setFormat("left");
|
|
6411
|
-
}
|
|
6412
|
-
});
|
|
6413
|
-
});
|
|
6933
|
+
applyAlignmentWithSplit("left");
|
|
6414
6934
|
break;
|
|
6415
6935
|
case "rightAlign" /* RightAlign */:
|
|
6416
|
-
|
|
6417
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6418
|
-
sel.getNodes().forEach((n) => {
|
|
6419
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6420
|
-
if (!seen.has(t.getKey())) {
|
|
6421
|
-
seen.add(t.getKey());
|
|
6422
|
-
t.setFormat("right");
|
|
6423
|
-
}
|
|
6424
|
-
});
|
|
6425
|
-
});
|
|
6936
|
+
applyAlignmentWithSplit("right");
|
|
6426
6937
|
break;
|
|
6427
6938
|
case "centerAlign" /* CenterAlign */:
|
|
6428
|
-
|
|
6429
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6430
|
-
sel.getNodes().forEach((n) => {
|
|
6431
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6432
|
-
if (!seen.has(t.getKey())) {
|
|
6433
|
-
seen.add(t.getKey());
|
|
6434
|
-
t.setFormat("center");
|
|
6435
|
-
}
|
|
6436
|
-
});
|
|
6437
|
-
});
|
|
6939
|
+
applyAlignmentWithSplit("center");
|
|
6438
6940
|
break;
|
|
6439
6941
|
case "justifyAlign" /* JustifyAlign */:
|
|
6440
|
-
|
|
6441
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6442
|
-
sel.getNodes().forEach((n) => {
|
|
6443
|
-
const t = n.getTopLevelElementOrThrow();
|
|
6444
|
-
if (!seen.has(t.getKey())) {
|
|
6445
|
-
seen.add(t.getKey());
|
|
6446
|
-
t.setFormat("justify");
|
|
6447
|
-
}
|
|
6448
|
-
});
|
|
6449
|
-
});
|
|
6942
|
+
applyAlignmentWithSplit("justify");
|
|
6450
6943
|
break;
|
|
6451
6944
|
case "undo" /* Undo */:
|
|
6452
6945
|
editor.dispatchCommand(UNDO_COMMAND, void 0);
|
|
@@ -6465,9 +6958,32 @@ var ToolBarPlugins = (props) => {
|
|
|
6465
6958
|
break;
|
|
6466
6959
|
}
|
|
6467
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
|
+
};
|
|
6468
6973
|
const updateHeading = (heading) => {
|
|
6469
|
-
|
|
6470
|
-
|
|
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();
|
|
6471
6987
|
});
|
|
6472
6988
|
};
|
|
6473
6989
|
const renderToken = (token, groupIndex, tokenIndex) => {
|
|
@@ -6479,7 +6995,6 @@ var ToolBarPlugins = (props) => {
|
|
|
6479
6995
|
const brand = palette.themePrimary;
|
|
6480
6996
|
const brandHover = palette.themeDarkAlt ?? brand;
|
|
6481
6997
|
const brandPressed = palette.themeDark ?? brand;
|
|
6482
|
-
palette.white;
|
|
6483
6998
|
const bgHover = palette.neutralLighter;
|
|
6484
6999
|
const bgPressed = palette.neutralLight;
|
|
6485
7000
|
const bgActive = palette.neutralLighterAlt ?? palette.neutralLighter;
|
|
@@ -6532,6 +7047,8 @@ var ToolBarPlugins = (props) => {
|
|
|
6532
7047
|
Button,
|
|
6533
7048
|
{
|
|
6534
7049
|
size: "small",
|
|
7050
|
+
"aria-label": "Bold",
|
|
7051
|
+
"aria-pressed": isBold,
|
|
6535
7052
|
disabled: !isEditable || props.readOnly,
|
|
6536
7053
|
icon: /* @__PURE__ */ jsx(TextBold24Regular, { style: { color: getIconColor(isBold) } }),
|
|
6537
7054
|
style: getButtonStyle(isBold),
|
|
@@ -6544,6 +7061,8 @@ var ToolBarPlugins = (props) => {
|
|
|
6544
7061
|
Button,
|
|
6545
7062
|
{
|
|
6546
7063
|
size: "small",
|
|
7064
|
+
"aria-label": "Italic",
|
|
7065
|
+
"aria-pressed": isItalic,
|
|
6547
7066
|
disabled: !isEditable || props.readOnly,
|
|
6548
7067
|
icon: /* @__PURE__ */ jsx(TextItalicFilled, { style: { color: getIconColor(isItalic) } }),
|
|
6549
7068
|
style: getButtonStyle(isItalic),
|
|
@@ -6556,6 +7075,8 @@ var ToolBarPlugins = (props) => {
|
|
|
6556
7075
|
Button,
|
|
6557
7076
|
{
|
|
6558
7077
|
size: "small",
|
|
7078
|
+
"aria-label": "Underline",
|
|
7079
|
+
"aria-pressed": isUnderline,
|
|
6559
7080
|
disabled: !isEditable || props.readOnly,
|
|
6560
7081
|
icon: /* @__PURE__ */ jsx(TextUnderlineFilled, { style: { color: getIconColor(isUnderline) } }),
|
|
6561
7082
|
style: getButtonStyle(isUnderline),
|
|
@@ -6566,7 +7087,14 @@ var ToolBarPlugins = (props) => {
|
|
|
6566
7087
|
case "ColorPicker":
|
|
6567
7088
|
return /* @__PURE__ */ jsx(ColorPickerPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6568
7089
|
case "Link":
|
|
6569
|
-
return /* @__PURE__ */ jsx(
|
|
7090
|
+
return /* @__PURE__ */ jsx(
|
|
7091
|
+
InsertLinkPlugin,
|
|
7092
|
+
{
|
|
7093
|
+
disabled: !isEditable || props.readOnly,
|
|
7094
|
+
setIsLinkEditMode: props.setIsLinkEditMode
|
|
7095
|
+
},
|
|
7096
|
+
key
|
|
7097
|
+
);
|
|
6570
7098
|
case "Table":
|
|
6571
7099
|
return /* @__PURE__ */ jsx(TableItemPlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6572
7100
|
case "Image":
|
|
@@ -6574,7 +7102,9 @@ var ToolBarPlugins = (props) => {
|
|
|
6574
7102
|
InsertImageDialog,
|
|
6575
7103
|
{
|
|
6576
7104
|
activeEditor: editor,
|
|
6577
|
-
disabled: !isEditable || props.readOnly
|
|
7105
|
+
disabled: !isEditable || props.readOnly,
|
|
7106
|
+
maxImageSizeMB: props.maxImageSizeMB,
|
|
7107
|
+
validationMessages: props.validationMessages
|
|
6578
7108
|
},
|
|
6579
7109
|
key
|
|
6580
7110
|
);
|
|
@@ -6583,7 +7113,9 @@ var ToolBarPlugins = (props) => {
|
|
|
6583
7113
|
InsertInlineImageDialog,
|
|
6584
7114
|
{
|
|
6585
7115
|
activeEditor: editor,
|
|
6586
|
-
disabled: !isEditable || props.readOnly
|
|
7116
|
+
disabled: !isEditable || props.readOnly,
|
|
7117
|
+
maxImageSizeMB: props.maxImageSizeMB,
|
|
7118
|
+
validationMessages: props.validationMessages
|
|
6587
7119
|
},
|
|
6588
7120
|
key
|
|
6589
7121
|
);
|
|
@@ -6606,7 +7138,7 @@ var ToolBarPlugins = (props) => {
|
|
|
6606
7138
|
const val = data.optionValue;
|
|
6607
7139
|
if (!val) return;
|
|
6608
7140
|
if (val === "paragraph") {
|
|
6609
|
-
|
|
7141
|
+
formatParagraph(editor);
|
|
6610
7142
|
setSelectNodeType("paragraph");
|
|
6611
7143
|
} else {
|
|
6612
7144
|
updateHeading(val);
|
|
@@ -6627,78 +7159,451 @@ var ToolBarPlugins = (props) => {
|
|
|
6627
7159
|
return /* @__PURE__ */ jsx(FontSizePlugin, { disabled: !isEditable || props.readOnly }, key);
|
|
6628
7160
|
case "|":
|
|
6629
7161
|
return /* @__PURE__ */ jsx(ToolbarDivider, {}, key);
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
...isSubscript ? ["subscript"] : [],
|
|
6637
|
-
...isSuperscript ? ["superscript"] : [],
|
|
6638
|
-
...isHighlight ? ["highlight"] : [],
|
|
6639
|
-
...selectNodeType === "ul" ? ["ul-list"] : [],
|
|
6640
|
-
...selectNodeType === "ol" ? ["ol-list"] : [],
|
|
6641
|
-
...selectNodeType === "quote" ? ["quote"] : []
|
|
6642
|
-
];
|
|
6643
|
-
const DECORATOR_LABEL = {
|
|
6644
|
-
uppercase: "Uppercase",
|
|
6645
|
-
lowercase: "Lowercase",
|
|
6646
|
-
capitalize: "Capitalize",
|
|
6647
|
-
strike: "Strikethrough",
|
|
6648
|
-
subscript: "Subscript",
|
|
6649
|
-
superscript: "Superscript",
|
|
6650
|
-
highlight: "Highlight",
|
|
6651
|
-
"ul-list": "Bullet list",
|
|
6652
|
-
"ol-list": "Number list",
|
|
6653
|
-
quote: "Quote"
|
|
6654
|
-
};
|
|
6655
|
-
const decoratorValue = activeDecorators.length === 0 ? "" : activeDecorators.length === 1 ? DECORATOR_LABEL[activeDecorators[0]] : `${DECORATOR_LABEL[activeDecorators[0]]} +${activeDecorators.length - 1}`;
|
|
6656
|
-
return /* @__PURE__ */ jsxs(
|
|
6657
|
-
Dropdown,
|
|
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,
|
|
6658
7168
|
{
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
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);
|
|
7478
|
+
setSelectNodeType("paragraph");
|
|
7479
|
+
} else {
|
|
7480
|
+
updateHeading("h5");
|
|
7481
|
+
setSelectNodeType("h5");
|
|
7482
|
+
}
|
|
7483
|
+
},
|
|
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"
|
|
7512
|
+
},
|
|
7513
|
+
key
|
|
7514
|
+
);
|
|
7515
|
+
case "Decorators": {
|
|
7516
|
+
const activeDecorators = [
|
|
7517
|
+
...isUppercase ? ["uppercase"] : [],
|
|
7518
|
+
...isLowercase ? ["lowercase"] : [],
|
|
7519
|
+
...isCapitalize ? ["capitalize"] : [],
|
|
7520
|
+
...isStrikethrough ? ["strike"] : [],
|
|
7521
|
+
...isSubscript ? ["subscript"] : [],
|
|
7522
|
+
...isSuperscript ? ["superscript"] : [],
|
|
7523
|
+
...isHighlight ? ["highlight"] : [],
|
|
7524
|
+
...selectNodeType === "ul" ? ["ul-list"] : [],
|
|
7525
|
+
...selectNodeType === "ol" ? ["ol-list"] : [],
|
|
7526
|
+
...selectNodeType === "alpha" ? ["al-list"] : [],
|
|
7527
|
+
...selectNodeType === "quote" ? ["quote"] : []
|
|
7528
|
+
];
|
|
7529
|
+
const DECORATOR_LABEL = {
|
|
7530
|
+
uppercase: "Uppercase",
|
|
7531
|
+
lowercase: "Lowercase",
|
|
7532
|
+
capitalize: "Capitalize",
|
|
7533
|
+
strike: "Strikethrough",
|
|
7534
|
+
subscript: "Subscript",
|
|
7535
|
+
superscript: "Superscript",
|
|
7536
|
+
highlight: "Highlight",
|
|
7537
|
+
"ul-list": "Bullet list",
|
|
7538
|
+
"ol-list": "Number list",
|
|
7539
|
+
"al-list": "Alphabetical list",
|
|
7540
|
+
quote: "Quote"
|
|
7541
|
+
};
|
|
7542
|
+
const decoratorValue = activeDecorators.length === 0 ? "" : activeDecorators.length === 1 ? DECORATOR_LABEL[activeDecorators[0]] : `${DECORATOR_LABEL[activeDecorators[0]]} +${activeDecorators.length - 1}`;
|
|
7543
|
+
return /* @__PURE__ */ jsxs(
|
|
7544
|
+
Dropdown,
|
|
7545
|
+
{
|
|
7546
|
+
multiselect: true,
|
|
7547
|
+
id: `${groupIndex}-set-decorators`,
|
|
7548
|
+
placeholder: "Text",
|
|
7549
|
+
value: decoratorValue,
|
|
7550
|
+
selectedOptions: activeDecorators,
|
|
7551
|
+
disabled: !isEditable,
|
|
7552
|
+
className: styles.alignDropdown,
|
|
7553
|
+
button: { style: dropdownButtonStyle },
|
|
7554
|
+
expandIcon: { style: dropdownExpandIconStyle },
|
|
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
|
+
},
|
|
7564
|
+
onOptionSelect: (_, data) => {
|
|
7565
|
+
decoratorSelectingRef.current = true;
|
|
7566
|
+
switch (data.optionValue) {
|
|
7567
|
+
case "uppercase":
|
|
7568
|
+
editor.dispatchCommand(FORMAT_TEXT_COMMAND, "uppercase");
|
|
7569
|
+
break;
|
|
7570
|
+
case "lowercase":
|
|
7571
|
+
onHandleSelectOption("lowercase" /* Lowercase */);
|
|
7572
|
+
break;
|
|
7573
|
+
case "capitalize":
|
|
7574
|
+
onHandleSelectOption("capitalize" /* Capitalize */);
|
|
7575
|
+
break;
|
|
7576
|
+
case "strike":
|
|
7577
|
+
onHandleSelectOption("strike" /* Strikethrough */);
|
|
7578
|
+
break;
|
|
7579
|
+
case "subscript":
|
|
7580
|
+
onHandleSelectOption("subscript" /* Subscript */);
|
|
7581
|
+
break;
|
|
7582
|
+
case "superscript":
|
|
7583
|
+
onHandleSelectOption("superscript" /* Superscript */);
|
|
7584
|
+
break;
|
|
7585
|
+
case "highlight":
|
|
7586
|
+
onHandleSelectOption("highlight" /* Highlight */);
|
|
7587
|
+
break;
|
|
7588
|
+
case "ul-list":
|
|
7589
|
+
editor.dispatchCommand(
|
|
7590
|
+
selectNodeType === "ul" ? REMOVE_LIST_COMMAND : INSERT_UNORDERED_LIST_COMMAND,
|
|
7591
|
+
void 0
|
|
7592
|
+
);
|
|
7593
|
+
break;
|
|
7594
|
+
case "ol-list":
|
|
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());
|
|
7602
|
+
break;
|
|
7603
|
+
case "page-break":
|
|
7604
|
+
editor.dispatchCommand(INSERT_PAGE_BREAK, void 0);
|
|
7605
|
+
break;
|
|
7606
|
+
case "quote":
|
|
6702
7607
|
formatQuote();
|
|
6703
7608
|
break;
|
|
6704
7609
|
}
|
|
@@ -6729,7 +7634,12 @@ var ToolBarPlugins = (props) => {
|
|
|
6729
7634
|
"Superscript"
|
|
6730
7635
|
] }),
|
|
6731
7636
|
/* @__PURE__ */ jsxs(Option, { value: "highlight", text: "Highlight", children: [
|
|
6732
|
-
/* @__PURE__ */ jsx(
|
|
7637
|
+
/* @__PURE__ */ jsx(
|
|
7638
|
+
HighlightAccentFilled,
|
|
7639
|
+
{
|
|
7640
|
+
style: { ...optionIconStyle, color: isEditable ? brand : fgDisabled }
|
|
7641
|
+
}
|
|
7642
|
+
),
|
|
6733
7643
|
"Highlight"
|
|
6734
7644
|
] }),
|
|
6735
7645
|
/* @__PURE__ */ jsxs(Option, { value: "ul-list", text: "Bullet list", children: [
|
|
@@ -6740,6 +7650,10 @@ var ToolBarPlugins = (props) => {
|
|
|
6740
7650
|
/* @__PURE__ */ jsx(TextNumberListLtrFilled, { style: optionIconStyle }),
|
|
6741
7651
|
"Number list"
|
|
6742
7652
|
] }),
|
|
7653
|
+
/* @__PURE__ */ jsxs(Option, { value: "al-list", text: "Alphabetical list", children: [
|
|
7654
|
+
/* @__PURE__ */ jsx(TextAlphaListLtrFilled, { style: optionIconStyle }),
|
|
7655
|
+
"Alphabetical list"
|
|
7656
|
+
] }),
|
|
6743
7657
|
/* @__PURE__ */ jsxs(Option, { value: "page-break", text: "Page Break", children: [
|
|
6744
7658
|
/* @__PURE__ */ jsx(DocumentPageBreakRegular, { style: optionIconStyle }),
|
|
6745
7659
|
"Page break"
|
|
@@ -6765,10 +7679,30 @@ var ToolBarPlugins = (props) => {
|
|
|
6765
7679
|
// );
|
|
6766
7680
|
case "Align": {
|
|
6767
7681
|
const ALIGN_OPTIONS = [
|
|
6768
|
-
{
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
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
|
+
}
|
|
6772
7706
|
];
|
|
6773
7707
|
const alignLabel = ALIGN_OPTIONS.find((o) => o.value === alignment)?.label ?? "Left Align";
|
|
6774
7708
|
return /* @__PURE__ */ jsx(
|
|
@@ -6984,28 +7918,31 @@ function BrowserSpellCheckPlugin({ enabled }) {
|
|
|
6984
7918
|
}, [editor, enabled]);
|
|
6985
7919
|
return null;
|
|
6986
7920
|
}
|
|
6987
|
-
function
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
return editor.registerUpdateListener(({ editorState }) => {
|
|
6991
|
-
editorState.read(() => {
|
|
6992
|
-
const text = $getRoot().getTextContent();
|
|
6993
|
-
const words = text.trim() === "" ? 0 : text.trim().split(/\s+/).length;
|
|
6994
|
-
onCountChange(words);
|
|
6995
|
-
});
|
|
6996
|
-
});
|
|
6997
|
-
}, [editor, onCountChange]);
|
|
6998
|
-
return null;
|
|
6999
|
-
}
|
|
7000
|
-
function CharCountPlugin({ onCountChange }) {
|
|
7921
|
+
function ContentMetricsPlugin({
|
|
7922
|
+
onMetricsChange
|
|
7923
|
+
}) {
|
|
7001
7924
|
const [editor] = useLexicalComposerContext();
|
|
7925
|
+
const prevRef = useRef({ words: 0, chars: 0, images: 0, links: 0, tables: 0 });
|
|
7002
7926
|
useEffect(() => {
|
|
7003
|
-
return editor.registerUpdateListener(({
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
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
|
+
}
|
|
7007
7944
|
});
|
|
7008
|
-
}, [editor,
|
|
7945
|
+
}, [editor, onMetricsChange]);
|
|
7009
7946
|
return null;
|
|
7010
7947
|
}
|
|
7011
7948
|
function FocusEventsPlugin({
|
|
@@ -7026,7 +7963,8 @@ function FocusEventsPlugin({
|
|
|
7026
7963
|
const next = e.relatedTarget;
|
|
7027
7964
|
const container = containerRef.current;
|
|
7028
7965
|
const stillInside = !!next && (container ? container.contains(next) : root.contains(next));
|
|
7029
|
-
|
|
7966
|
+
const isEditorPortal = !!next?.closest?.("[data-lexical-editor-portal]");
|
|
7967
|
+
if (stillInside || isEditorPortal) return;
|
|
7030
7968
|
editor.update(() => {
|
|
7031
7969
|
$setSelection(null);
|
|
7032
7970
|
});
|
|
@@ -7136,6 +8074,16 @@ function _makeQueryFn(fn) {
|
|
|
7136
8074
|
};
|
|
7137
8075
|
};
|
|
7138
8076
|
}
|
|
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
|
+
}
|
|
7139
8087
|
var ContentEditorComponent = forwardRef(
|
|
7140
8088
|
(props, ref) => {
|
|
7141
8089
|
const isReadOnly = !!props.readOnly;
|
|
@@ -7151,13 +8099,17 @@ var ContentEditorComponent = forwardRef(
|
|
|
7151
8099
|
);
|
|
7152
8100
|
const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
|
|
7153
8101
|
const [isLinkEditMode, setIsLinkEditMode] = useState(false);
|
|
7154
|
-
const [
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
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), []);
|
|
7159
8110
|
const [pageSetup, setPageSetup] = useState(DEFAULT_PAGE_SETUP);
|
|
7160
8111
|
const pageCanvas = resolvePageCanvasMetrics(pageSetup);
|
|
8112
|
+
const wordCount = metrics.words;
|
|
7161
8113
|
const contentEditableDomRef = useRef(null);
|
|
7162
8114
|
const previousOverLimitRef = useRef(false);
|
|
7163
8115
|
const focusedRef = useRef(false);
|
|
@@ -7168,32 +8120,37 @@ var ContentEditorComponent = forwardRef(
|
|
|
7168
8120
|
const onAnchorRef = (elem) => {
|
|
7169
8121
|
if (elem) setFloatingAnchorElem(elem);
|
|
7170
8122
|
};
|
|
7171
|
-
const initialConfig = {
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
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
|
+
}, []);
|
|
7197
8154
|
const EditorStyles = mergeStyleSets({
|
|
7198
8155
|
editorPlaceholder: {
|
|
7199
8156
|
color: "var(--colorNeutralForeground3, grey)",
|
|
@@ -7235,41 +8192,7 @@ var ContentEditorComponent = forwardRef(
|
|
|
7235
8192
|
e.stopPropagation();
|
|
7236
8193
|
}
|
|
7237
8194
|
};
|
|
7238
|
-
const [touched, setTouched] = useState(false);
|
|
7239
8195
|
const isOverLimit = props.wordLimit !== void 0 && wordCount > props.wordLimit;
|
|
7240
|
-
const internalErrors = [];
|
|
7241
|
-
if (isOverLimit) {
|
|
7242
|
-
const m = props.errorMessages?.wordLimitExceeded;
|
|
7243
|
-
internalErrors.push(
|
|
7244
|
-
typeof m === "function" ? m(wordCount, props.wordLimit) : m ?? `Word limit exceeded (${wordCount} / ${props.wordLimit} words used)`
|
|
7245
|
-
);
|
|
7246
|
-
}
|
|
7247
|
-
if (props.required && touched && wordCount === 0) {
|
|
7248
|
-
internalErrors.push(
|
|
7249
|
-
props.errorMessages?.required ?? "This field is required"
|
|
7250
|
-
);
|
|
7251
|
-
}
|
|
7252
|
-
if (props.minWords !== void 0 && touched && wordCount < props.minWords) {
|
|
7253
|
-
const m = props.errorMessages?.minWords;
|
|
7254
|
-
internalErrors.push(
|
|
7255
|
-
typeof m === "function" ? m(wordCount, props.minWords) : m ?? `Minimum ${props.minWords} words required (${wordCount} entered)`
|
|
7256
|
-
);
|
|
7257
|
-
}
|
|
7258
|
-
if (props.maxChars !== void 0 && charCount > props.maxChars) {
|
|
7259
|
-
const m = props.errorMessages?.maxCharsExceeded;
|
|
7260
|
-
internalErrors.push(
|
|
7261
|
-
typeof m === "function" ? m(charCount, props.maxChars) : m ?? `Character limit exceeded (${charCount} / ${props.maxChars} characters used)`
|
|
7262
|
-
);
|
|
7263
|
-
}
|
|
7264
|
-
if (props.minChars !== void 0 && touched && charCount < props.minChars && charCount > 0) {
|
|
7265
|
-
const m = props.errorMessages?.minCharsRequired;
|
|
7266
|
-
internalErrors.push(
|
|
7267
|
-
typeof m === "function" ? m(charCount, props.minChars) : m ?? `Minimum ${props.minChars} characters required (${charCount} entered)`
|
|
7268
|
-
);
|
|
7269
|
-
}
|
|
7270
|
-
const allErrors = [...internalErrors, ...props.errors ?? [], ...refErrors];
|
|
7271
|
-
const hasErrors = allErrors.length > 0;
|
|
7272
|
-
const hasRedBorder = hasErrors;
|
|
7273
8196
|
useEffect(() => {
|
|
7274
8197
|
if (props.wordLimit === void 0 || !props.onWordLimitExceeded) return;
|
|
7275
8198
|
const wasOverLimit = previousOverLimitRef.current;
|
|
@@ -7282,214 +8205,327 @@ var ContentEditorComponent = forwardRef(
|
|
|
7282
8205
|
previousOverLimitRef.current = isOverLimit;
|
|
7283
8206
|
}
|
|
7284
8207
|
}, [isOverLimit, wordCount, props.wordLimit, props.onWordLimitExceeded]);
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
{
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
}
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
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",
|
|
8295
|
+
{
|
|
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,
|
|
7336
8304
|
{
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
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
|
+
)
|
|
8315
|
+
}
|
|
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,
|
|
8333
|
+
{
|
|
8334
|
+
ErrorBoundary: LexicalErrorBoundary,
|
|
8335
|
+
contentEditable: /* @__PURE__ */ jsx(
|
|
8336
|
+
"div",
|
|
8337
|
+
{
|
|
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
|
+
)
|
|
8360
|
+
}
|
|
8361
|
+
),
|
|
8362
|
+
placeholder: /* @__PURE__ */ jsx(Stack, { className: css(EditorStyles.editorPlaceholder), children: props.placeholder })
|
|
8363
|
+
}
|
|
8364
|
+
),
|
|
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",
|
|
8367
|
+
{
|
|
8368
|
+
style: {
|
|
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"
|
|
8377
|
+
},
|
|
8378
|
+
children: [
|
|
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",
|
|
7346
8398
|
{
|
|
7347
|
-
ref: contentEditableDomRef,
|
|
7348
|
-
className: css(EditorStyles.contentEditor),
|
|
7349
8399
|
style: {
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
marginLeft: pageCanvas.widthPx !== void 0 ? "auto" : void 0,
|
|
7355
|
-
marginRight: pageCanvas.widthPx !== void 0 ? "auto" : void 0,
|
|
7356
|
-
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
|
|
8400
|
+
fontSize: "11px",
|
|
8401
|
+
color: hasValidationError ? "#c4272c" : "var(--colorNeutralForeground3, #aaa)",
|
|
8402
|
+
fontWeight: hasValidationError ? 600 : 400,
|
|
8403
|
+
transition: "color 0.2s, font-weight 0.2s"
|
|
7357
8404
|
},
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
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
|
+
]
|
|
7361
8411
|
}
|
|
7362
8412
|
)
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
{
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
(props.wordLimit !== void 0 || props.required || props.minWords !== void 0) && /* @__PURE__ */ jsx(WordCountPlugin, { onCountChange: handleWordCount }),
|
|
7477
|
-
(props.maxChars !== void 0 || props.minChars !== void 0) && /* @__PURE__ */ jsx(CharCountPlugin, { onCountChange: handleCharCount }),
|
|
7478
|
-
/* @__PURE__ */ jsx(
|
|
7479
|
-
RefApiPlugin,
|
|
7480
|
-
{
|
|
7481
|
-
forwardedRef: ref,
|
|
7482
|
-
contentEditableDomRef,
|
|
7483
|
-
focusedRef,
|
|
7484
|
-
setRefErrors
|
|
7485
|
-
}
|
|
7486
|
-
)
|
|
7487
|
-
]
|
|
7488
|
-
}
|
|
7489
|
-
) }) }) });
|
|
8413
|
+
]
|
|
8414
|
+
}
|
|
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
|
+
]
|
|
8518
|
+
}
|
|
8519
|
+
)
|
|
8520
|
+
] })
|
|
8521
|
+
]
|
|
8522
|
+
}
|
|
8523
|
+
) }),
|
|
8524
|
+
/* @__PURE__ */ jsx(EditorReadyPlugin, { onReady: props.onReady })
|
|
8525
|
+
] }) });
|
|
7490
8526
|
}
|
|
7491
8527
|
);
|
|
7492
8528
|
|
|
7493
|
-
export { ContentEditorComponent, ContentEditorLevel };
|
|
8529
|
+
export { ContentEditorComponent, ContentEditorLevel, DEFAULT_VALIDATION_MESSAGES };
|
|
7494
8530
|
//# sourceMappingURL=index.mjs.map
|
|
7495
8531
|
//# sourceMappingURL=index.mjs.map
|