diff --git a/package-lock.json b/package-lock.json index 817d94e..ce99332 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "fast-deep-equal": "^3.1.3", "node-polyglot": "^2.4.0", "react-autosize-textarea": "^7.1.0", + "react-draggable": "^4.4.3", "react-select": "^4.3.1", "react-transition-group": "^4.4.2", "timeago-react": "^3.0.2", @@ -1641,6 +1642,11 @@ "fsevents": "~2.1.1" } }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -2956,6 +2962,15 @@ "react": "^16.14.0" } }, + "node_modules/react-draggable": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz", + "integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==", + "dependencies": { + "classnames": "^2.2.5", + "prop-types": "^15.6.0" + } + }, "node_modules/react-input-autosize": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", @@ -4903,6 +4918,11 @@ "readdirp": "~3.2.0" } }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -5881,6 +5901,15 @@ "scheduler": "^0.19.1" } }, + "react-draggable": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz", + "integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==", + "requires": { + "classnames": "^2.2.5", + "prop-types": "^15.6.0" + } + }, "react-input-autosize": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", diff --git a/package.json b/package.json index 137bde6..9c80e2d 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "fast-deep-equal": "^3.1.3", "node-polyglot": "^2.4.0", "react-autosize-textarea": "^7.1.0", + "react-draggable": "^4.4.3", "react-select": "^4.3.1", "react-transition-group": "^4.4.2", "timeago-react": "^3.0.2", diff --git a/src/editor/Editor.jsx b/src/editor/Editor.jsx index bfaac0a..ae3cb82 100644 --- a/src/editor/Editor.jsx +++ b/src/editor/Editor.jsx @@ -1,4 +1,5 @@ import React, { useState, useRef, useEffect } from 'react'; +import Draggable from 'react-draggable'; import { getWidget, DEFAULT_WIDGETS } from './widgets'; import { TrashIcon } from '../Icons'; import setPosition from './setPosition'; @@ -22,6 +23,8 @@ const Editor = props => { // The current state of the edited annotation vs. original const [ currentAnnotation, setCurrentAnnotation ] = useState(); + const [ dragged, setDragged ] = useState(false); + // Reference to the DOM element, so we can set position const element = useRef(); @@ -46,14 +49,16 @@ const Editor = props => { const initResizeObserver = () => { if (window?.ResizeObserver) { const resizeObserver = new ResizeObserver(() => { - setPosition(props.wrapperEl, element.current, props.selectedElement); + if (!dragged) + setPosition(props.wrapperEl, element.current, props.selectedElement); }); resizeObserver.observe(props.wrapperEl); return () => resizeObserver.disconnect(); } else { // Fire setPosition *only* for devices that don't support ResizeObserver - setPosition(props.wrapperEl, element.current, props.selectedElement); + if (!dragged) + setPosition(props.wrapperEl, element.current, props.selectedElement); } } @@ -164,51 +169,53 @@ const Editor = props => { !widgets.some(isReadOnlyWidget); // every widget is deletable return ( -