@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.
Files changed (45) hide show
  1. package/FontColorNode.js +94 -119
  2. package/FontColorNode.js.map +1 -1
  3. package/HeadingNode.js +160 -183
  4. package/HeadingNode.js.map +1 -1
  5. package/ImageNode.js +101 -131
  6. package/ImageNode.js.map +1 -1
  7. package/LinkNode.js +228 -315
  8. package/LinkNode.js.map +1 -1
  9. package/ListItemNode.js +249 -320
  10. package/ListItemNode.js.map +1 -1
  11. package/ListNode.js +174 -223
  12. package/ListNode.js.map +1 -1
  13. package/ParagraphNode.js +119 -148
  14. package/ParagraphNode.js.map +1 -1
  15. package/QuoteNode.js +97 -102
  16. package/QuoteNode.js.map +1 -1
  17. package/components/ImageNode/ImageComponent.js +117 -147
  18. package/components/ImageNode/ImageComponent.js.map +1 -1
  19. package/components/ImageNode/ImageResizer.js +167 -194
  20. package/components/ImageNode/ImageResizer.js.map +1 -1
  21. package/generateInitialLexicalValue.js +20 -23
  22. package/generateInitialLexicalValue.js.map +1 -1
  23. package/index.js +38 -26
  24. package/index.js.map +1 -1
  25. package/package.json +4 -4
  26. package/prepareLexicalState.js +30 -43
  27. package/prepareLexicalState.js.map +1 -1
  28. package/types.js +0 -3
  29. package/utils/clearNodeFormating.js +14 -15
  30. package/utils/clearNodeFormating.js.map +1 -1
  31. package/utils/formatList.js +277 -368
  32. package/utils/formatList.js.map +1 -1
  33. package/utils/formatToHeading.js +6 -13
  34. package/utils/formatToHeading.js.map +1 -1
  35. package/utils/formatToParagraph.js +6 -7
  36. package/utils/formatToParagraph.js.map +1 -1
  37. package/utils/formatToQuote.js +6 -13
  38. package/utils/formatToQuote.js.map +1 -1
  39. package/utils/getStyleId.js +6 -11
  40. package/utils/getStyleId.js.map +1 -1
  41. package/utils/listNode.js +60 -84
  42. package/utils/listNode.js.map +1 -1
  43. package/utils/toggleLink.js +67 -118
  44. package/utils/toggleLink.js.map +1 -1
  45. 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
- if (!imageCache.has(src)) {
19
- throw new Promise(resolve => {
20
- const img = new Image();
21
- img.src = src;
22
- img.onload = () => {
23
- imageCache.add(src);
24
- resolve(null);
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
- id,
31
- altText,
32
- className,
33
- imageRef,
34
- src,
35
- width,
36
- height,
37
- maxWidth
38
- }) {
39
- useSuspenseImage(src);
40
- return /*#__PURE__*/React.createElement("img", {
41
- id: id,
42
- className: className || undefined,
43
- src: src,
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
- export default function ImageComponent({
55
- id,
56
- src,
57
- altText,
58
- nodeKey,
59
- width,
60
- height,
61
- maxWidth,
62
- resizable
63
- }) {
64
- const imageRef = useRef(null);
65
- const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
66
- const [isResizing, setIsResizing] = useState(false);
67
- const [editor] = useLexicalComposerContext();
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 true;
106
- }
107
- return false;
108
- }, COMMAND_PRIORITY_LOW), editor.registerCommand(DRAGSTART_COMMAND, event => {
109
- if (event.target === imageRef.current) {
110
- // TODO This is just a temporary workaround for FF to behave like other browsers.
111
- // Ideally, this handles drag & drop too (and all browsers).
112
- event.preventDefault();
113
- return true;
114
- }
115
- return false;
116
- }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW));
117
- return () => {
118
- isMounted = false;
119
- unregister();
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
- }, [clearSelection, editor, isResizing, isSelected, nodeKey, onDelete, setSelected]);
122
- const onResizeEnd = (nextWidth, nextHeight) => {
123
- // Delay hiding the resize bars for click case
124
- setTimeout(() => {
125
- setIsResizing(false);
126
- }, 200);
127
- editor.update(() => {
128
- const node = $getNodeByKey(nodeKey);
129
- if ($isImageNode(node)) {
130
- node.setWidthAndHeight(nextWidth, nextHeight);
131
- }
132
- });
133
- };
134
- const onResizeStart = () => {
135
- setIsResizing(true);
136
- };
137
- const draggable = isSelected && $isNodeSelection(selection) && !isResizing;
138
- const isFocused = isSelected || isResizing;
139
- return /*#__PURE__*/React.createElement(Suspense, {
140
- fallback: null
141
- }, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
142
- draggable: draggable
143
- }, /*#__PURE__*/React.createElement(LazyImage, {
144
- id: id,
145
- className: isFocused ? `focused ${$isNodeSelection(selection) ? "draggable" : ""}` : null,
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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"}