UNPKG

phx-react

Version:

PHX REACT

184 lines • 8.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.INSERT_IMAGE_COMMAND = void 0; exports.InsertImageUriDialogBody = InsertImageUriDialogBody; exports.InsertImageModal = InsertImageModal; exports.default = ImagesPlugin; const tslib_1 = require("tslib"); const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext"); const utils_1 = require("@lexical/utils"); const lexical_1 = require("lexical"); const react_1 = require("react"); const React = tslib_1.__importStar(require("react")); const ImageNode_1 = require("../../nodes/ImageNode"); const canUseDOM_1 = require("../../shared/canUseDOM"); const Button_1 = tslib_1.__importDefault(require("../../ui/Button")); const Dialog_1 = require("../../ui/Dialog"); const TextInput_1 = tslib_1.__importDefault(require("../../ui/TextInput")); const Modal_1 = require("../../../Modal"); const Input_1 = require("../../../Input"); const UploadFile_1 = require("../../../UploadFile"); const getDOMSelection = (targetWindow) => canUseDOM_1.CAN_USE_DOM ? (targetWindow || window).getSelection() : null; exports.INSERT_IMAGE_COMMAND = (0, lexical_1.createCommand)('INSERT_IMAGE_COMMAND'); function InsertImageUriDialogBody({ onClick }) { const [src, setSrc] = (0, react_1.useState)(''); const [altText, setAltText] = (0, react_1.useState)(''); const isDisabled = src === ''; return (React.createElement(React.Fragment, null, React.createElement(TextInput_1.default, { "data-test-id": 'image-modal-url-input', label: 'Image URL', onChange: setSrc, placeholder: 'i.e. https://source.unsplash.com/random', value: src }), React.createElement(TextInput_1.default, { "data-test-id": 'image-modal-alt-text-input', label: 'Alt Text', onChange: setAltText, placeholder: 'Random unsplash image', value: altText }), React.createElement(Dialog_1.DialogActions, null, React.createElement(Button_1.default, { "data-test-id": 'image-modal-confirm-btn', disabled: isDisabled, onClick: () => onClick({ altText, src }) }, "Confirm")))); } function InsertImageModal({ activeEditor, setShow, show, }) { const [fileName, setFileName] = (0, react_1.useState)(''); const [cdnLink, setCdnLink] = (0, react_1.useState)(''); let altText = 'photo'; const onHide = () => { setShow(false); setCdnLink(''); setFileName(''); }; const handleListenUpload = (fileUpload, linkCdn) => { setFileName(fileUpload.name); setCdnLink(linkCdn[0]); }; const handleSubmit = () => { activeEditor.dispatchCommand(exports.INSERT_IMAGE_COMMAND, { altText, src: cdnLink }); onHide(); }; return (React.createElement(Modal_1.PHXModal, { onHide: onHide, onPrimaryClick: handleSubmit, show: show, title: 'Insert Image' }, React.createElement("div", { className: 'space-y-4' }, React.createElement(Input_1.PHXInput, { defaultValue: altText, label: 'Alt Text', onChange: (e) => (altText = e.target.value) }), React.createElement(UploadFile_1.PHXUploadFile, { apiCdnUpload: '/api/cdn-upload', basePath: '', defaultLink: [cdnLink], fileName: fileName, fileType: 'image', handleListenUpload: handleListenUpload, inCard: false, label: 'Image upload', moduleId: 'insert-editor-image', oneImg: true, projectId: 'phenikaa', titleHeaderAction: '' })))); } function ImagesPlugin({ captionsEnabled }) { const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)(); (0, react_1.useEffect)(() => { if (!editor.hasNodes([ImageNode_1.ImageNode])) { throw new Error('ImagesPlugin: ImageNode not registered on editor'); } return (0, utils_1.mergeRegister)(editor.registerCommand(exports.INSERT_IMAGE_COMMAND, (payload) => { const imageNode = (0, ImageNode_1.$createImageNode)(payload); (0, lexical_1.$insertNodes)([imageNode]); if ((0, lexical_1.$isRootOrShadowRoot)(imageNode.getParentOrThrow())) { (0, utils_1.$wrapNodeInElement)(imageNode, lexical_1.$createParagraphNode).selectEnd(); } return true; }, lexical_1.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical_1.DRAGSTART_COMMAND, (event) => onDragStart(event), lexical_1.COMMAND_PRIORITY_HIGH), editor.registerCommand(lexical_1.DRAGOVER_COMMAND, (event) => onDragover(event), lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.DROP_COMMAND, (event) => onDrop(event, editor), lexical_1.COMMAND_PRIORITY_HIGH)); }, [captionsEnabled, editor]); return null; } const TRANSPARENT_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; function onDragStart(event) { const img = document.createElement('img'); img.src = TRANSPARENT_IMAGE; const node = getImageNodeInSelection(); if (!node) { return false; } const dataTransfer = event.dataTransfer; if (!dataTransfer) { return false; } dataTransfer.setData('text/plain', '_'); dataTransfer.setDragImage(img, 0, 0); dataTransfer.setData('application/x-lexical-drag', JSON.stringify({ data: { altText: node.__altText, caption: node.__caption, height: node.__height, key: node.getKey(), maxWidth: node.__maxWidth, position: node.__position, showCaption: node.__showCaption, src: node.__src, width: node.__width, }, type: 'image', })); return true; } function onDragover(event) { const node = getImageNodeInSelection(); if (!node) { return false; } if (!canDropImage(event)) { event.preventDefault(); } return true; } function onDrop(event, editor) { const node = getImageNodeInSelection(); if (!node) { return false; } const data = getDragImageData(event); if (!data) { return false; } event.preventDefault(); if (canDropImage(event)) { const range = getDragSelection(event); node.remove(); const rangeSelection = (0, lexical_1.$createRangeSelection)(); if (range !== null && range !== undefined) { rangeSelection.applyDOMRange(range); } (0, lexical_1.$setSelection)(rangeSelection); editor.dispatchCommand(exports.INSERT_IMAGE_COMMAND, data); } return true; } function getImageNodeInSelection() { const selection = (0, lexical_1.$getSelection)(); if (!(0, lexical_1.$isNodeSelection)(selection)) { return null; } const nodes = selection.getNodes(); const node = nodes[0]; return (0, ImageNode_1.$isImageNode)(node) ? node : null; } function getDragImageData(event) { var _a; const dragData = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData('application/x-lexical-drag'); if (!dragData) { return null; } const { data, type } = JSON.parse(dragData); if (type !== 'image') { return null; } return data; } function canDropImage(event) { const target = event.target; return !!(target && target instanceof HTMLElement && !target.closest('code, span.editor-image') && target.parentElement && target.parentElement.closest('div.ContentEditable__root')); } function getDragSelection(event) { let range; const target = event.target; const targetWindow = target == null ? null : target.nodeType === 9 ? target.defaultView : target.ownerDocument.defaultView; const domSelection = getDOMSelection(targetWindow); if (document.caretRangeFromPoint) { range = document.caretRangeFromPoint(event.clientX, event.clientY); } else if (event.rangeParent && domSelection !== null) { domSelection.collapse(event.rangeParent, event.rangeOffset || 0); range = domSelection.getRangeAt(0); } else { throw Error(`Cannot get the selection when dragging`); } return range; } //# sourceMappingURL=index.js.map