UNPKG

phx-react

Version:

PHX REACT

110 lines 5.14 kB
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection'; import { mergeRegister } from '@lexical/utils'; import { $getNodeByKey, $getSelection, $isNodeSelection, CLICK_COMMAND, COMMAND_PRIORITY_LOW, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, } from 'lexical'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import * as React from 'react'; import ImageResizer from '../../ui/ImageResizer'; import ExcalidrawImage from './ExcalidrawImage'; import ExcalidrawModal from './ExcalidrawModal'; import { $isExcalidrawNode } from '.'; export default function ExcalidrawComponent({ data, nodeKey }) { const [editor] = useLexicalComposerContext(); const [isModalOpen, setModalOpen] = useState(data === '[]' && editor.isEditable()); const imageContainerRef = useRef(null); const buttonRef = useRef(null); const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey); const [isResizing, setIsResizing] = useState(false); const onDelete = useCallback((event) => { if (isSelected && $isNodeSelection($getSelection())) { event.preventDefault(); editor.update(() => { const node = $getNodeByKey(nodeKey); if ($isExcalidrawNode(node)) { node.remove(); } }); } return false; }, [editor, isSelected, nodeKey]); // Set editor to readOnly if excalidraw is open to prevent unwanted changes useEffect(() => { if (isModalOpen) { editor.setEditable(false); } else { editor.setEditable(true); } }, [isModalOpen, editor]); useEffect(() => mergeRegister(editor.registerCommand(CLICK_COMMAND, (event) => { const buttonElem = buttonRef.current; const eventTarget = event.target; if (isResizing) { return true; } if (buttonElem !== null && buttonElem.contains(eventTarget)) { if (!event.shiftKey) { clearSelection(); } setSelected(!isSelected); if (event.detail > 1) { setModalOpen(true); } return true; } return false; }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW)), [clearSelection, editor, isSelected, isResizing, onDelete, setSelected]); const deleteNode = useCallback(() => { setModalOpen(false); return editor.update(() => { const node = $getNodeByKey(nodeKey); if ($isExcalidrawNode(node)) { node.remove(); } }); }, [editor, nodeKey]); const setData = (els, aps, fls) => { if (!editor.isEditable()) { return; } return editor.update(() => { const node = $getNodeByKey(nodeKey); if ($isExcalidrawNode(node)) { if (els.length > 0 || Object.keys(fls).length > 0) { node.setData(JSON.stringify({ appState: aps, elements: els, files: fls, })); } else { node.remove(); } } }); }; const onResizeStart = () => { setIsResizing(true); }; const onResizeEnd = () => { // Delay hiding the resize bars for click case setTimeout(() => { setIsResizing(false); }, 200); }; const openModal = useCallback(() => { setModalOpen(true); }, []); const { appState = {}, elements = [], files = {} } = useMemo(() => JSON.parse(data), [data]); return (React.createElement(React.Fragment, null, React.createElement(ExcalidrawModal, { closeOnClickOutside: false, initialAppState: appState, initialElements: elements, initialFiles: files, isShown: isModalOpen, onClose: () => setModalOpen(false), onDelete: deleteNode, onSave: (els, aps, fls) => { editor.setEditable(true); setData(els, aps, fls); setModalOpen(false); } }), elements.length > 0 && (React.createElement("button", { ref: buttonRef, className: `excalidraw-button ${isSelected ? 'selected' : ''}`, type: 'button' }, React.createElement(ExcalidrawImage, { appState: appState, className: 'image', elements: elements, files: files, imageContainerRef: imageContainerRef }), isSelected && (React.createElement("div", { className: 'image-edit-button', onClick: openModal, onMouseDown: (event) => event.preventDefault(), role: 'button', tabIndex: 0 })), (isSelected || isResizing) && (React.createElement(ImageResizer, { editor: editor, imageRef: imageContainerRef, onResizeEnd: onResizeEnd, onResizeStart: onResizeStart })))))); } //# sourceMappingURL=ExcalidrawComponent.js.map