@webiny/lexical-nodes 6.3.0-beta.4 → 6.4.0-beta.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/FontColorNode.js +94 -119
- package/FontColorNode.js.map +1 -1
- package/HeadingNode.js +160 -183
- package/HeadingNode.js.map +1 -1
- package/ImageNode.js +101 -131
- package/ImageNode.js.map +1 -1
- package/LinkNode.js +228 -315
- package/LinkNode.js.map +1 -1
- package/ListItemNode.js +249 -320
- package/ListItemNode.js.map +1 -1
- package/ListNode.js +174 -223
- package/ListNode.js.map +1 -1
- package/ParagraphNode.js +119 -148
- package/ParagraphNode.js.map +1 -1
- package/QuoteNode.js +97 -102
- package/QuoteNode.js.map +1 -1
- package/components/ImageNode/ImageComponent.js +117 -147
- package/components/ImageNode/ImageComponent.js.map +1 -1
- package/components/ImageNode/ImageResizer.js +167 -194
- package/components/ImageNode/ImageResizer.js.map +1 -1
- package/generateInitialLexicalValue.js +20 -23
- package/generateInitialLexicalValue.js.map +1 -1
- package/index.js +38 -26
- package/index.js.map +1 -1
- package/package.json +4 -4
- package/prepareLexicalState.js +30 -43
- package/prepareLexicalState.js.map +1 -1
- package/types.js +0 -3
- package/utils/clearNodeFormating.js +14 -15
- package/utils/clearNodeFormating.js.map +1 -1
- package/utils/formatList.js +277 -368
- package/utils/formatList.js.map +1 -1
- package/utils/formatToHeading.js +6 -13
- package/utils/formatToHeading.js.map +1 -1
- package/utils/formatToParagraph.js +6 -7
- package/utils/formatToParagraph.js.map +1 -1
- package/utils/formatToQuote.js +6 -13
- package/utils/formatToQuote.js.map +1 -1
- package/utils/getStyleId.js +6 -11
- package/utils/getStyleId.js.map +1 -1
- package/utils/listNode.js +60 -84
- package/utils/listNode.js.map +1 -1
- package/utils/toggleLink.js +67 -118
- package/utils/toggleLink.js.map +1 -1
- package/types.js.map +0 -1
|
@@ -1,161 +1,131 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
import * as React from "react";
|
|
9
|
-
import { Suspense, useCallback, useEffect, useRef, useState } from "react";
|
|
10
|
-
import { mergeRegister } from "lexical";
|
|
1
|
+
import { $getNodeByKey, $getSelection, $isNodeSelection, CLICK_COMMAND, COMMAND_PRIORITY_LOW, DRAGSTART_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, SELECTION_CHANGE_COMMAND, mergeRegister } from "lexical";
|
|
11
2
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
12
3
|
import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
|
|
13
|
-
import { $getNodeByKey, $getSelection, $isNodeSelection, CLICK_COMMAND, COMMAND_PRIORITY_LOW, DRAGSTART_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, SELECTION_CHANGE_COMMAND } from "lexical";
|
|
14
4
|
import { ImageResizer } from "./ImageResizer.js";
|
|
15
5
|
import { $isImageNode } from "../../ImageNode.js";
|
|
6
|
+
import * as __rspack_external_react from "react";
|
|
16
7
|
const imageCache = new Set();
|
|
17
8
|
function useSuspenseImage(src) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
9
|
+
if (!imageCache.has(src)) throw new Promise((resolve)=>{
|
|
10
|
+
const img = new Image();
|
|
11
|
+
img.src = src;
|
|
12
|
+
img.onload = ()=>{
|
|
13
|
+
imageCache.add(src);
|
|
14
|
+
resolve(null);
|
|
15
|
+
};
|
|
26
16
|
});
|
|
27
|
-
}
|
|
28
17
|
}
|
|
29
|
-
function LazyImage({
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
alt: altText,
|
|
45
|
-
ref: imageRef,
|
|
46
|
-
style: {
|
|
47
|
-
height,
|
|
48
|
-
maxWidth,
|
|
49
|
-
width
|
|
50
|
-
},
|
|
51
|
-
draggable: "false"
|
|
52
|
-
});
|
|
18
|
+
function LazyImage({ id, altText, className, imageRef, src, width, height, maxWidth }) {
|
|
19
|
+
useSuspenseImage(src);
|
|
20
|
+
return /*#__PURE__*/ __rspack_external_react.createElement("img", {
|
|
21
|
+
id: id,
|
|
22
|
+
className: className || void 0,
|
|
23
|
+
src: src,
|
|
24
|
+
alt: altText,
|
|
25
|
+
ref: imageRef,
|
|
26
|
+
style: {
|
|
27
|
+
height,
|
|
28
|
+
maxWidth,
|
|
29
|
+
width
|
|
30
|
+
},
|
|
31
|
+
draggable: "false"
|
|
32
|
+
});
|
|
53
33
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const [selection, setSelection] = useState(null);
|
|
69
|
-
const activeEditorRef = useRef(null);
|
|
70
|
-
const onDelete = useCallback(payload => {
|
|
71
|
-
if (isSelected && $isNodeSelection($getSelection())) {
|
|
72
|
-
const event = payload;
|
|
73
|
-
event.preventDefault();
|
|
74
|
-
const node = $getNodeByKey(nodeKey);
|
|
75
|
-
if ($isImageNode(node)) {
|
|
76
|
-
node.remove();
|
|
77
|
-
}
|
|
78
|
-
setSelected(false);
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
}, [isSelected, nodeKey, setSelected]);
|
|
82
|
-
useEffect(() => {
|
|
83
|
-
let isMounted = true;
|
|
84
|
-
const unregister = mergeRegister(editor.registerUpdateListener(({
|
|
85
|
-
editorState
|
|
86
|
-
}) => {
|
|
87
|
-
if (isMounted) {
|
|
88
|
-
setSelection(editorState.read(() => $getSelection()));
|
|
89
|
-
}
|
|
90
|
-
}), editor.registerCommand(SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
|
|
91
|
-
activeEditorRef.current = activeEditor;
|
|
92
|
-
return false;
|
|
93
|
-
}, COMMAND_PRIORITY_LOW), editor.registerCommand(CLICK_COMMAND, payload => {
|
|
94
|
-
const event = payload;
|
|
95
|
-
if (isResizing) {
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
if (event.target === imageRef.current) {
|
|
99
|
-
if (event.shiftKey) {
|
|
100
|
-
setSelected(!isSelected);
|
|
101
|
-
} else {
|
|
102
|
-
clearSelection();
|
|
103
|
-
setSelected(true);
|
|
34
|
+
function ImageComponent({ id, src, altText, nodeKey, width, height, maxWidth, resizable }) {
|
|
35
|
+
const imageRef = (0, __rspack_external_react.useRef)(null);
|
|
36
|
+
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
|
|
37
|
+
const [isResizing, setIsResizing] = (0, __rspack_external_react.useState)(false);
|
|
38
|
+
const [editor] = useLexicalComposerContext();
|
|
39
|
+
const [selection, setSelection] = (0, __rspack_external_react.useState)(null);
|
|
40
|
+
const activeEditorRef = (0, __rspack_external_react.useRef)(null);
|
|
41
|
+
const onDelete = (0, __rspack_external_react.useCallback)((payload)=>{
|
|
42
|
+
if (isSelected && $isNodeSelection($getSelection())) {
|
|
43
|
+
const event = payload;
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
const node = $getNodeByKey(nodeKey);
|
|
46
|
+
if ($isImageNode(node)) node.remove();
|
|
47
|
+
setSelected(false);
|
|
104
48
|
}
|
|
105
|
-
return
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
49
|
+
return false;
|
|
50
|
+
}, [
|
|
51
|
+
isSelected,
|
|
52
|
+
nodeKey,
|
|
53
|
+
setSelected
|
|
54
|
+
]);
|
|
55
|
+
(0, __rspack_external_react.useEffect)(()=>{
|
|
56
|
+
let isMounted = true;
|
|
57
|
+
const unregister = mergeRegister(editor.registerUpdateListener(({ editorState })=>{
|
|
58
|
+
if (isMounted) setSelection(editorState.read(()=>$getSelection()));
|
|
59
|
+
}), editor.registerCommand(SELECTION_CHANGE_COMMAND, (_, activeEditor)=>{
|
|
60
|
+
activeEditorRef.current = activeEditor;
|
|
61
|
+
return false;
|
|
62
|
+
}, COMMAND_PRIORITY_LOW), editor.registerCommand(CLICK_COMMAND, (payload)=>{
|
|
63
|
+
const event = payload;
|
|
64
|
+
if (isResizing) return true;
|
|
65
|
+
if (event.target === imageRef.current) {
|
|
66
|
+
if (event.shiftKey) setSelected(!isSelected);
|
|
67
|
+
else {
|
|
68
|
+
clearSelection();
|
|
69
|
+
setSelected(true);
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}, COMMAND_PRIORITY_LOW), editor.registerCommand(DRAGSTART_COMMAND, (event)=>{
|
|
75
|
+
if (event.target === imageRef.current) {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW));
|
|
81
|
+
return ()=>{
|
|
82
|
+
isMounted = false;
|
|
83
|
+
unregister();
|
|
84
|
+
};
|
|
85
|
+
}, [
|
|
86
|
+
clearSelection,
|
|
87
|
+
editor,
|
|
88
|
+
isResizing,
|
|
89
|
+
isSelected,
|
|
90
|
+
nodeKey,
|
|
91
|
+
onDelete,
|
|
92
|
+
setSelected
|
|
93
|
+
]);
|
|
94
|
+
const onResizeEnd = (nextWidth, nextHeight)=>{
|
|
95
|
+
setTimeout(()=>{
|
|
96
|
+
setIsResizing(false);
|
|
97
|
+
}, 200);
|
|
98
|
+
editor.update(()=>{
|
|
99
|
+
const node = $getNodeByKey(nodeKey);
|
|
100
|
+
if ($isImageNode(node)) node.setWidthAndHeight(nextWidth, nextHeight);
|
|
101
|
+
});
|
|
120
102
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
src: src,
|
|
147
|
-
altText: altText,
|
|
148
|
-
imageRef: imageRef,
|
|
149
|
-
width: width,
|
|
150
|
-
height: height,
|
|
151
|
-
maxWidth: maxWidth
|
|
152
|
-
})), resizable && $isNodeSelection(selection) && isFocused ? /*#__PURE__*/React.createElement(ImageResizer, {
|
|
153
|
-
editor: editor,
|
|
154
|
-
imageRef: imageRef,
|
|
155
|
-
maxWidth: maxWidth,
|
|
156
|
-
onResizeStart: onResizeStart,
|
|
157
|
-
onResizeEnd: onResizeEnd
|
|
158
|
-
}) : null));
|
|
103
|
+
const onResizeStart = ()=>{
|
|
104
|
+
setIsResizing(true);
|
|
105
|
+
};
|
|
106
|
+
const draggable = isSelected && $isNodeSelection(selection) && !isResizing;
|
|
107
|
+
const isFocused = isSelected || isResizing;
|
|
108
|
+
return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Suspense, {
|
|
109
|
+
fallback: null
|
|
110
|
+
}, /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, /*#__PURE__*/ __rspack_external_react.createElement("div", {
|
|
111
|
+
draggable: draggable
|
|
112
|
+
}, /*#__PURE__*/ __rspack_external_react.createElement(LazyImage, {
|
|
113
|
+
id: id,
|
|
114
|
+
className: isFocused ? `focused ${$isNodeSelection(selection) ? "draggable" : ""}` : null,
|
|
115
|
+
src: src,
|
|
116
|
+
altText: altText,
|
|
117
|
+
imageRef: imageRef,
|
|
118
|
+
width: width,
|
|
119
|
+
height: height,
|
|
120
|
+
maxWidth: maxWidth
|
|
121
|
+
})), resizable && $isNodeSelection(selection) && isFocused ? /*#__PURE__*/ __rspack_external_react.createElement(ImageResizer, {
|
|
122
|
+
editor: editor,
|
|
123
|
+
imageRef: imageRef,
|
|
124
|
+
maxWidth: maxWidth,
|
|
125
|
+
onResizeStart: onResizeStart,
|
|
126
|
+
onResizeEnd: onResizeEnd
|
|
127
|
+
}) : null));
|
|
159
128
|
}
|
|
129
|
+
export default ImageComponent;
|
|
160
130
|
|
|
161
131
|
//# sourceMappingURL=ImageComponent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Suspense","useCallback","useEffect","useRef","useState","mergeRegister","useLexicalComposerContext","useLexicalNodeSelection","$getNodeByKey","$getSelection","$isNodeSelection","CLICK_COMMAND","COMMAND_PRIORITY_LOW","DRAGSTART_COMMAND","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","SELECTION_CHANGE_COMMAND","ImageResizer","$isImageNode","imageCache","Set","useSuspenseImage","src","has","Promise","resolve","img","Image","onload","add","LazyImage","id","altText","className","imageRef","width","height","maxWidth","createElement","undefined","alt","ref","style","draggable","ImageComponent","nodeKey","resizable","isSelected","setSelected","clearSelection","isResizing","setIsResizing","editor","selection","setSelection","activeEditorRef","onDelete","payload","event","preventDefault","node","remove","isMounted","unregister","registerUpdateListener","editorState","read","registerCommand","_","activeEditor","current","target","shiftKey","onResizeEnd","nextWidth","nextHeight","setTimeout","update","setWidthAndHeight","onResizeStart","isFocused","fallback","Fragment"],"sources":["ImageComponent.tsx"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nimport * as React from \"react\";\nimport { Suspense, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport type { LexicalEditor, NodeKey, BaseSelection } from \"lexical\";\nimport { mergeRegister } from \"lexical\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useLexicalNodeSelection } from \"@lexical/react/useLexicalNodeSelection\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n DRAGSTART_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n SELECTION_CHANGE_COMMAND\n} from \"lexical\";\nimport { ImageResizer } from \"./ImageResizer.js\";\nimport { $isImageNode } from \"~/ImageNode.js\";\n\nconst imageCache = new Set();\n\nfunction useSuspenseImage(src: string) {\n if (!imageCache.has(src)) {\n throw new Promise(resolve => {\n const img = new Image();\n img.src = src;\n img.onload = () => {\n imageCache.add(src);\n resolve(null);\n };\n });\n }\n}\n\nfunction LazyImage({\n id,\n altText,\n className,\n imageRef,\n src,\n width,\n height,\n maxWidth\n}: {\n id: string;\n altText: string;\n className: string | null;\n height: \"inherit\" | number;\n imageRef: { current: null | HTMLImageElement };\n maxWidth: number;\n src: string;\n width: \"inherit\" | number;\n}): React.JSX.Element {\n useSuspenseImage(src);\n return (\n <img\n id={id}\n className={className || undefined}\n src={src}\n alt={altText}\n ref={imageRef}\n style={{\n height,\n maxWidth,\n width\n }}\n draggable=\"false\"\n />\n );\n}\n\ninterface ImageComponentProps {\n id: string;\n altText: string;\n height: \"inherit\" | number;\n maxWidth: number;\n nodeKey: NodeKey;\n resizable: boolean;\n src: string;\n width: \"inherit\" | number;\n}\n\nexport default function ImageComponent({\n id,\n src,\n altText,\n nodeKey,\n width,\n height,\n maxWidth,\n resizable\n}: ImageComponentProps): React.JSX.Element {\n const imageRef = useRef<null | HTMLImageElement>(null);\n const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);\n const [isResizing, setIsResizing] = useState<boolean>(false);\n const [editor] = useLexicalComposerContext();\n const [selection, setSelection] = useState<BaseSelection | null>(null);\n const activeEditorRef = useRef<LexicalEditor | null>(null);\n\n const onDelete = useCallback(\n (payload: KeyboardEvent) => {\n if (isSelected && $isNodeSelection($getSelection())) {\n const event: KeyboardEvent = payload;\n event.preventDefault();\n const node = $getNodeByKey(nodeKey);\n if ($isImageNode(node)) {\n node.remove();\n }\n setSelected(false);\n }\n return false;\n },\n [isSelected, nodeKey, setSelected]\n );\n\n useEffect(() => {\n let isMounted = true;\n const unregister = mergeRegister(\n editor.registerUpdateListener(({ editorState }) => {\n if (isMounted) {\n setSelection(editorState.read(() => $getSelection()));\n }\n }),\n editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n (_, activeEditor) => {\n activeEditorRef.current = activeEditor;\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand<MouseEvent>(\n CLICK_COMMAND,\n payload => {\n const event = payload;\n if (isResizing) {\n return true;\n }\n if (event.target === imageRef.current) {\n if (event.shiftKey) {\n setSelected(!isSelected);\n } else {\n clearSelection();\n setSelected(true);\n }\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand(\n DRAGSTART_COMMAND,\n event => {\n if (event.target === imageRef.current) {\n // TODO This is just a temporary workaround for FF to behave like other browsers.\n // Ideally, this handles drag & drop too (and all browsers).\n event.preventDefault();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW),\n editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW)\n );\n return () => {\n isMounted = false;\n unregister();\n };\n }, [clearSelection, editor, isResizing, isSelected, nodeKey, onDelete, setSelected]);\n\n const onResizeEnd = (nextWidth: \"inherit\" | number, nextHeight: \"inherit\" | number) => {\n // Delay hiding the resize bars for click case\n setTimeout(() => {\n setIsResizing(false);\n }, 200);\n\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isImageNode(node)) {\n node.setWidthAndHeight(nextWidth, nextHeight);\n }\n });\n };\n\n const onResizeStart = () => {\n setIsResizing(true);\n };\n\n const draggable = isSelected && $isNodeSelection(selection) && !isResizing;\n const isFocused = isSelected || isResizing;\n return (\n <Suspense fallback={null}>\n <>\n <div draggable={draggable}>\n <LazyImage\n id={id}\n className={\n isFocused\n ? `focused ${$isNodeSelection(selection) ? \"draggable\" : \"\"}`\n : null\n }\n src={src}\n altText={altText}\n imageRef={imageRef}\n width={width}\n height={height}\n maxWidth={maxWidth}\n />\n </div>\n {resizable && $isNodeSelection(selection) && isFocused ? (\n <ImageResizer\n editor={editor}\n imageRef={imageRef}\n maxWidth={maxWidth}\n onResizeStart={onResizeStart}\n onResizeEnd={onResizeEnd}\n />\n ) : null}\n </>\n </Suspense>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"components/ImageNode/ImageComponent.js","sources":["../../../src/components/ImageNode/ImageComponent.tsx"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nimport * as React from \"react\";\nimport { Suspense, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport type { LexicalEditor, NodeKey, BaseSelection } from \"lexical\";\nimport { mergeRegister } from \"lexical\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useLexicalNodeSelection } from \"@lexical/react/useLexicalNodeSelection\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n DRAGSTART_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n SELECTION_CHANGE_COMMAND\n} from \"lexical\";\nimport { ImageResizer } from \"./ImageResizer.js\";\nimport { $isImageNode } from \"~/ImageNode.js\";\n\nconst imageCache = new Set();\n\nfunction useSuspenseImage(src: string) {\n if (!imageCache.has(src)) {\n throw new Promise(resolve => {\n const img = new Image();\n img.src = src;\n img.onload = () => {\n imageCache.add(src);\n resolve(null);\n };\n });\n }\n}\n\nfunction LazyImage({\n id,\n altText,\n className,\n imageRef,\n src,\n width,\n height,\n maxWidth\n}: {\n id: string;\n altText: string;\n className: string | null;\n height: \"inherit\" | number;\n imageRef: { current: null | HTMLImageElement };\n maxWidth: number;\n src: string;\n width: \"inherit\" | number;\n}): React.JSX.Element {\n useSuspenseImage(src);\n return (\n <img\n id={id}\n className={className || undefined}\n src={src}\n alt={altText}\n ref={imageRef}\n style={{\n height,\n maxWidth,\n width\n }}\n draggable=\"false\"\n />\n );\n}\n\ninterface ImageComponentProps {\n id: string;\n altText: string;\n height: \"inherit\" | number;\n maxWidth: number;\n nodeKey: NodeKey;\n resizable: boolean;\n src: string;\n width: \"inherit\" | number;\n}\n\nexport default function ImageComponent({\n id,\n src,\n altText,\n nodeKey,\n width,\n height,\n maxWidth,\n resizable\n}: ImageComponentProps): React.JSX.Element {\n const imageRef = useRef<null | HTMLImageElement>(null);\n const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);\n const [isResizing, setIsResizing] = useState<boolean>(false);\n const [editor] = useLexicalComposerContext();\n const [selection, setSelection] = useState<BaseSelection | null>(null);\n const activeEditorRef = useRef<LexicalEditor | null>(null);\n\n const onDelete = useCallback(\n (payload: KeyboardEvent) => {\n if (isSelected && $isNodeSelection($getSelection())) {\n const event: KeyboardEvent = payload;\n event.preventDefault();\n const node = $getNodeByKey(nodeKey);\n if ($isImageNode(node)) {\n node.remove();\n }\n setSelected(false);\n }\n return false;\n },\n [isSelected, nodeKey, setSelected]\n );\n\n useEffect(() => {\n let isMounted = true;\n const unregister = mergeRegister(\n editor.registerUpdateListener(({ editorState }) => {\n if (isMounted) {\n setSelection(editorState.read(() => $getSelection()));\n }\n }),\n editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n (_, activeEditor) => {\n activeEditorRef.current = activeEditor;\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand<MouseEvent>(\n CLICK_COMMAND,\n payload => {\n const event = payload;\n if (isResizing) {\n return true;\n }\n if (event.target === imageRef.current) {\n if (event.shiftKey) {\n setSelected(!isSelected);\n } else {\n clearSelection();\n setSelected(true);\n }\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand(\n DRAGSTART_COMMAND,\n event => {\n if (event.target === imageRef.current) {\n // TODO This is just a temporary workaround for FF to behave like other browsers.\n // Ideally, this handles drag & drop too (and all browsers).\n event.preventDefault();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW),\n editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW)\n );\n return () => {\n isMounted = false;\n unregister();\n };\n }, [clearSelection, editor, isResizing, isSelected, nodeKey, onDelete, setSelected]);\n\n const onResizeEnd = (nextWidth: \"inherit\" | number, nextHeight: \"inherit\" | number) => {\n // Delay hiding the resize bars for click case\n setTimeout(() => {\n setIsResizing(false);\n }, 200);\n\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isImageNode(node)) {\n node.setWidthAndHeight(nextWidth, nextHeight);\n }\n });\n };\n\n const onResizeStart = () => {\n setIsResizing(true);\n };\n\n const draggable = isSelected && $isNodeSelection(selection) && !isResizing;\n const isFocused = isSelected || isResizing;\n return (\n <Suspense fallback={null}>\n <>\n <div draggable={draggable}>\n <LazyImage\n id={id}\n className={\n isFocused\n ? `focused ${$isNodeSelection(selection) ? \"draggable\" : \"\"}`\n : null\n }\n src={src}\n altText={altText}\n imageRef={imageRef}\n width={width}\n height={height}\n maxWidth={maxWidth}\n />\n </div>\n {resizable && $isNodeSelection(selection) && isFocused ? (\n <ImageResizer\n editor={editor}\n imageRef={imageRef}\n maxWidth={maxWidth}\n onResizeStart={onResizeStart}\n onResizeEnd={onResizeEnd}\n />\n ) : null}\n </>\n </Suspense>\n );\n}\n"],"names":["imageCache","Set","useSuspenseImage","src","Promise","resolve","img","Image","LazyImage","id","altText","className","imageRef","width","height","maxWidth","undefined","ImageComponent","nodeKey","resizable","useRef","isSelected","setSelected","clearSelection","useLexicalNodeSelection","isResizing","setIsResizing","useState","editor","useLexicalComposerContext","selection","setSelection","activeEditorRef","onDelete","useCallback","payload","$isNodeSelection","$getSelection","event","node","$getNodeByKey","$isImageNode","useEffect","isMounted","unregister","mergeRegister","editorState","SELECTION_CHANGE_COMMAND","_","activeEditor","COMMAND_PRIORITY_LOW","CLICK_COMMAND","DRAGSTART_COMMAND","KEY_DELETE_COMMAND","KEY_BACKSPACE_COMMAND","onResizeEnd","nextWidth","nextHeight","setTimeout","onResizeStart","draggable","isFocused","Suspense","ImageResizer"],"mappings":"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"}
|