phx-react
Version:
PHX REACT
184 lines • 8.11 kB
JavaScript
"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