Added token dragging from side bar into map view
This commit is contained in:
parent
a22b3231fb
commit
81d311eb7f
@ -7,12 +7,13 @@
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"hookrouter": "^1.2.3",
|
||||
"interactjs": "^1.9.7",
|
||||
"peerjs": "^1.2.0",
|
||||
"react": "^16.13.0",
|
||||
"react-dom": "^16.13.0",
|
||||
"react-draggable": "^4.2.0",
|
||||
"react-modal": "^3.11.2",
|
||||
"react-scripts": "3.4.0",
|
||||
"shortid": "^2.2.15",
|
||||
"theme-ui": "^0.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -1,9 +1,36 @@
|
||||
import React from "react";
|
||||
import { Image, Flex } from "theme-ui";
|
||||
import { Image, Flex, Box } from "theme-ui";
|
||||
|
||||
function Map({ imageSource }) {
|
||||
import Token from "../components/Token";
|
||||
|
||||
function Map({ imageSource, tokens }) {
|
||||
return (
|
||||
<Flex sx={{ justifyContent: "center", flexGrow: 1 }} bg="background">
|
||||
<Flex
|
||||
className="map"
|
||||
sx={{ justifyContent: "center", flexGrow: 1 }}
|
||||
bg="background"
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
{Object.values(tokens).map(token => (
|
||||
<Box
|
||||
key={token.id}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
transform: `translate(${token.x}px, ${token.y}px)`
|
||||
}}
|
||||
>
|
||||
<Token image={token.image} className="map-token" />
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
<Image src={imageSource} sx={{ objectFit: "contain" }} />
|
||||
</Flex>
|
||||
);
|
||||
|
126
src/components/ProxyToken.js
Normal file
126
src/components/ProxyToken.js
Normal file
@ -0,0 +1,126 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Image, Box } from "theme-ui";
|
||||
import interact from "interactjs";
|
||||
|
||||
import usePortal from "../helpers/usePortal";
|
||||
|
||||
function ProxyToken({ tokenClassName, onProxyDragEnd }) {
|
||||
const proxyContainer = usePortal("root");
|
||||
|
||||
const [imageSource, setImageSource] = useState("");
|
||||
const imageRef = useRef();
|
||||
|
||||
const proxyOnMap = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
interact(`.${tokenClassName}`).draggable({
|
||||
listeners: {
|
||||
start: event => {
|
||||
let target = event.target;
|
||||
// Hide the token and copy it's image to the proxy
|
||||
target.style.opacity = "0.25";
|
||||
setImageSource(target.src);
|
||||
|
||||
let proxy = imageRef.current;
|
||||
if (proxy) {
|
||||
// Find and set the initial offset of the token to the proxy
|
||||
const proxyRect = proxy.getBoundingClientRect();
|
||||
const targetRect = target.getBoundingClientRect();
|
||||
const xOffset = targetRect.left - proxyRect.left;
|
||||
const yOffset = targetRect.top - proxyRect.top;
|
||||
proxy.style.transform = `translate(${xOffset}px, ${yOffset}px)`;
|
||||
proxy.setAttribute("data-x", xOffset);
|
||||
proxy.setAttribute("data-y", yOffset);
|
||||
}
|
||||
},
|
||||
|
||||
move: event => {
|
||||
let proxy = imageRef.current;
|
||||
// Move the proxy based off of the movment of the token
|
||||
if (proxy) {
|
||||
// keep the dragged position in the data-x/data-y attributes
|
||||
const x =
|
||||
(parseFloat(proxy.getAttribute("data-x")) || 0) + event.dx;
|
||||
const y =
|
||||
(parseFloat(proxy.getAttribute("data-y")) || 0) + event.dy;
|
||||
proxy.style.transform = `translate(${x}px, ${y}px)`;
|
||||
|
||||
// Check whether the proxy is on the right or left hand side of the screen
|
||||
// if not set proxyOnMap to true
|
||||
if (proxyContainer) {
|
||||
const proxyContainerRect = proxyContainer.getBoundingClientRect();
|
||||
const proxyRect = proxy.getBoundingClientRect();
|
||||
proxyOnMap.current =
|
||||
proxyContainerRect.right - proxyRect.right > 80 &&
|
||||
proxyRect.left > 192;
|
||||
}
|
||||
|
||||
// update the posiion attributes
|
||||
proxy.setAttribute("data-x", x);
|
||||
proxy.setAttribute("data-y", y);
|
||||
}
|
||||
},
|
||||
|
||||
end: event => {
|
||||
let target = event.target;
|
||||
let proxy = imageRef.current;
|
||||
if (proxy) {
|
||||
if (onProxyDragEnd) {
|
||||
const endX = parseFloat(proxy.getAttribute("data-x")) || 0;
|
||||
const endY = parseFloat(proxy.getAttribute("data-y")) || 0;
|
||||
onProxyDragEnd(proxyOnMap.current, {
|
||||
image: imageSource,
|
||||
x: endX,
|
||||
y: endY
|
||||
});
|
||||
}
|
||||
|
||||
// Reset the proxy position
|
||||
proxy.style.transform = "translate(0px, 0px)";
|
||||
proxy.setAttribute("data-x", 0);
|
||||
proxy.setAttribute("data-y", 0);
|
||||
}
|
||||
|
||||
// Show the token
|
||||
target.style.opacity = "1";
|
||||
setImageSource("");
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [imageSource, onProxyDragEnd, tokenClassName, proxyContainer]);
|
||||
|
||||
if (!imageSource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a portal to allow the proxy to move past the bounds of the token
|
||||
return ReactDOM.createPortal(
|
||||
<Box
|
||||
sx={{
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
position: "absolute",
|
||||
overflow: "hidden",
|
||||
top: 0,
|
||||
left: 0
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
p={2}
|
||||
src={imageSource}
|
||||
sx={{
|
||||
width: "64px",
|
||||
height: "64px",
|
||||
touchAction: "none",
|
||||
userSelect: "none",
|
||||
position: "absolute"
|
||||
}}
|
||||
ref={imageRef}
|
||||
/>
|
||||
</Box>,
|
||||
proxyContainer
|
||||
);
|
||||
}
|
||||
|
||||
export default ProxyToken;
|
@ -1,18 +1,17 @@
|
||||
import React from "react";
|
||||
import Draggable from "react-draggable";
|
||||
import { Image } from "theme-ui";
|
||||
|
||||
function Token({ onDrag, position }) {
|
||||
function Token({ image, className }) {
|
||||
return (
|
||||
<Draggable onDrag={onDrag} position={position}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: "50%",
|
||||
width: "50px",
|
||||
height: "50px",
|
||||
background: "blue"
|
||||
}}
|
||||
></div>
|
||||
</Draggable>
|
||||
<Image
|
||||
p={2}
|
||||
className={className}
|
||||
src={image}
|
||||
sx={{
|
||||
width: "64px",
|
||||
height: "64px"
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,31 +1,43 @@
|
||||
import React from "react";
|
||||
import { Flex, Image } from "theme-ui";
|
||||
import { Flex } from "theme-ui";
|
||||
import shortid from "shortid";
|
||||
|
||||
import * as tokens from "../tokens";
|
||||
|
||||
// import Token from "./Token";
|
||||
import Token from "./Token";
|
||||
import ProxyToken from "./ProxyToken";
|
||||
|
||||
function Tokens({ onCreateMapToken }) {
|
||||
const tokenClassName = "list-token";
|
||||
|
||||
function handleProxyDragEnd(isOnMap, token) {
|
||||
if (isOnMap && onCreateMapToken) {
|
||||
// Give the token an id
|
||||
onCreateMapToken({ id: shortid.generate(), ...token });
|
||||
}
|
||||
}
|
||||
|
||||
function Tokens() {
|
||||
return (
|
||||
<Flex
|
||||
bg="background"
|
||||
sx={{
|
||||
width: "80px",
|
||||
minWidth: "80px",
|
||||
flexDirection: "column",
|
||||
overflow: "auto"
|
||||
}}
|
||||
px={2}
|
||||
>
|
||||
{Object.entries(tokens).map(([id, image]) => (
|
||||
<Image
|
||||
p={2}
|
||||
key={id}
|
||||
src={image}
|
||||
sx={{ width: "64px", height: "64px" }}
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
<>
|
||||
<Flex
|
||||
bg="background"
|
||||
sx={{
|
||||
width: "80px",
|
||||
minWidth: "80px",
|
||||
flexDirection: "column",
|
||||
overflow: "auto"
|
||||
}}
|
||||
px={2}
|
||||
>
|
||||
{Object.entries(tokens).map(([id, image]) => (
|
||||
<Token key={id} image={image} className={tokenClassName} />
|
||||
))}
|
||||
</Flex>
|
||||
<ProxyToken
|
||||
tokenClassName={tokenClassName}
|
||||
onProxyDragEnd={handleProxyDragEnd}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
85
src/helpers/usePortal.js
Normal file
85
src/helpers/usePortal.js
Normal file
@ -0,0 +1,85 @@
|
||||
import { useRef, useEffect } from "react";
|
||||
|
||||
// Based on https://www.jayfreestone.com/writing/react-portals-with-hooks/
|
||||
|
||||
/**
|
||||
* Creates DOM element to be used as React root.
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function createRootElement(id) {
|
||||
const rootContainer = document.createElement("div");
|
||||
rootContainer.setAttribute("id", id);
|
||||
return rootContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends element as last child of body.
|
||||
* @param {HTMLElement} rootElem
|
||||
*/
|
||||
function addRootElement(rootElem) {
|
||||
document.body.insertBefore(
|
||||
rootElem,
|
||||
document.body.lastElementChild.nextElementSibling
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to create a React Portal.
|
||||
* Automatically handles creating and tearing-down the root elements (no SRR
|
||||
* makes this trivial), so there is no need to ensure the parent target already
|
||||
* exists.
|
||||
* @example
|
||||
* const target = usePortal(id, [id]);
|
||||
* return createPortal(children, target);
|
||||
* @param {String} id The id of the target container, e.g 'modal' or 'spotlight'
|
||||
* @returns {HTMLElement} The DOM node to use as the Portal target.
|
||||
*/
|
||||
function usePortal(id) {
|
||||
const rootElemRef = useRef(null);
|
||||
|
||||
useEffect(
|
||||
function setupElement() {
|
||||
// Look for existing target dom element to append to
|
||||
const existingParent = document.querySelector(`#${id}`);
|
||||
// Parent is either a new root or the existing dom element
|
||||
const parentElem = existingParent || createRootElement(id);
|
||||
|
||||
// If there is no existing DOM element, add a new one.
|
||||
if (!existingParent) {
|
||||
addRootElement(parentElem);
|
||||
}
|
||||
|
||||
// Add the detached element to the parent
|
||||
parentElem.appendChild(rootElemRef.current);
|
||||
|
||||
return function removeElement() {
|
||||
rootElemRef.current.remove();
|
||||
if (parentElem.childNodes.length === -1) {
|
||||
parentElem.remove();
|
||||
}
|
||||
};
|
||||
},
|
||||
[id]
|
||||
);
|
||||
|
||||
/**
|
||||
* It's important we evaluate this lazily:
|
||||
* - We need first render to contain the DOM element, so it shouldn't happen
|
||||
* in useEffect. We would normally put this in the constructor().
|
||||
* - We can't do 'const rootElemRef = useRef(document.createElement('div))',
|
||||
* since this will run every single render (that's a lot).
|
||||
* - We want the ref to consistently point to the same DOM element and only
|
||||
* ever run once.
|
||||
* @link https://reactjs.org/docs/hooks-faq.html#how-to-create-expensive-objects-lazily
|
||||
*/
|
||||
function getRootElem() {
|
||||
if (!rootElemRef.current) {
|
||||
rootElemRef.current = document.createElement("div");
|
||||
}
|
||||
return rootElemRef.current;
|
||||
}
|
||||
|
||||
return getRootElem();
|
||||
}
|
||||
|
||||
export default usePortal;
|
@ -10,7 +10,6 @@ import { Box, Flex } from "theme-ui";
|
||||
import GameContext from "../contexts/GameContext";
|
||||
import useSession from "../helpers/useSession";
|
||||
|
||||
import Token from "../components/Token";
|
||||
import Party from "../components/Party";
|
||||
import Tokens from "../components/Tokens";
|
||||
import Map from "../components/Map";
|
||||
@ -42,6 +41,18 @@ function Game() {
|
||||
}
|
||||
}
|
||||
|
||||
const [mapTokens, setMapTokens] = useState({});
|
||||
|
||||
function handleCreateMapToken(token) {
|
||||
setMapTokens(prevMapTokens => ({
|
||||
...prevMapTokens,
|
||||
[token.id]: token
|
||||
}));
|
||||
for (let connection of Object.values(connections)) {
|
||||
connection.send({ id: "token", data: token });
|
||||
}
|
||||
}
|
||||
|
||||
function handleConnectionOpen(connection) {
|
||||
connection.on("data", data => {
|
||||
if (data.id === "image") {
|
||||
@ -50,7 +61,11 @@ function Game() {
|
||||
setImageSource(URL.createObjectURL(imageDataRef.current));
|
||||
}
|
||||
if (data.id === "token") {
|
||||
setTokenPosition(data.data);
|
||||
const token = data.data;
|
||||
setMapTokens(prevMapTokens => ({
|
||||
...prevMapTokens,
|
||||
[token.id]: token
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -59,17 +74,7 @@ function Game() {
|
||||
if (imageSource) {
|
||||
connection.send({ id: "image", data: imageDataRef.current });
|
||||
}
|
||||
connection.send({ id: "token", data: tokenPosition });
|
||||
}
|
||||
|
||||
const [tokenPosition, setTokenPosition] = useState({ x: 0, y: 0 });
|
||||
|
||||
function handleTokenDrag(event, data) {
|
||||
const position = { x: data.x, y: data.y };
|
||||
setTokenPosition(position);
|
||||
for (let connection of Object.values(connections)) {
|
||||
connection.send({ id: "token", data: position });
|
||||
}
|
||||
connection.send({ id: "token", data: mapTokens });
|
||||
}
|
||||
|
||||
return (
|
||||
@ -89,9 +94,8 @@ function Game() {
|
||||
sx={{ justifyContent: "space-between", flexGrow: 1, height: "100%" }}
|
||||
>
|
||||
<Party streams={streams} localStreamId={peerId} />
|
||||
<Map imageSource={imageSource} />
|
||||
<Tokens />
|
||||
{/* <Token onDrag={handleTokenDrag} position={tokenPosition} /> */}
|
||||
<Map imageSource={imageSource} tokens={mapTokens} />
|
||||
<Tokens onCreateMapToken={handleCreateMapToken} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
207
yarn.lock
207
yarn.lock
@ -1048,6 +1048,178 @@
|
||||
dependencies:
|
||||
"@hapi/hoek" "^8.3.0"
|
||||
|
||||
"@interactjs/actions@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/actions/-/actions-1.9.7.tgz#b015931f406e090e48d3244343cf7b2cc53c90f1"
|
||||
integrity sha512-j5+2Cj1Ra3/0BgfCqL7hKGw7kOZyOBg3HXi+EJ9AT0sJzetjwsRt5YlvCm9URH8XcY7sNlFi8gD5mPFjD8DZaw==
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/arrange@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/arrange/-/arrange-1.9.7.tgz#42323ce4b1af905d6e4ab76fc066cd1573bd41ee"
|
||||
integrity sha512-gXcj4Gti3WsRmJ4Ohr5toUl7AjsBOY6Ik5SX69X3AZKrQpDJfkNBcOZJ/AlAPLXIwjBV8rRQiddYgB+SXCJcBg==
|
||||
|
||||
"@interactjs/auto-scroll@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/auto-scroll/-/auto-scroll-1.9.7.tgz#e6c2e67b6ed43dd0dd6a84e96b5d1389a20a647a"
|
||||
integrity sha512-/753R5h8z1VQ/aS5VsqI6C0V6fwb3934tP7s+htHL27aPVxyz20kfZVd74t5BmPSUAxAyDqwNVZ1vgjGLCSyAQ==
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/auto-start@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/auto-start/-/auto-start-1.9.7.tgz#4afa53c7c869170cb3a01a0019aa30791b3c5d18"
|
||||
integrity sha512-fKn7Yrl6idw7gxbAC0zvcQLSTsUE9WGs71+Y9WVj+ICQMkTO19ci9Y1lCBdo1AP/njLaQp8yPbHoUe5pI7eW6w==
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/clone@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/clone/-/clone-1.9.7.tgz#fdde8307835cecadd9e29f597ecff890d03167fc"
|
||||
integrity sha512-GNlGh5sKVFYcpOn7Z3HNOLItBdzG3f6t38soUowCmNv4Rd19nmnXkvKKVhfodjfBk26fsdXFI6EZ3iduzYsmAg==
|
||||
|
||||
"@interactjs/components@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/components/-/components-1.9.7.tgz#40ec9889fd1e94d07c67001b36dd39d113b3e762"
|
||||
integrity sha512-TdNlJVbKKLy2ZmNtpjhxQkQls1SqXXFSyY4JfAGRG23UOOMrjoG4+56RAe4tlOpHSIIfEER5skvgBSv6UFajHw==
|
||||
|
||||
"@interactjs/core@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/core/-/core-1.9.7.tgz#1fdf924c369df23ffe1300af9c945f2651538043"
|
||||
integrity sha512-fN7OfPNU9jgS+hEqe0+OJvJjp/XgNE9lkuCnH57/xtT4nfDca/43BkE57bNoEXhM9Ym5js2Ium+MbUTUVyZ+3A==
|
||||
|
||||
"@interactjs/dev-tools@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/dev-tools/-/dev-tools-1.9.7.tgz#91eab3f10806b84b95c313ef5f06408c2d3251cf"
|
||||
integrity sha512-LhLeLZw2joG13j3hUAuhmC9HTsVCnUEggcScgCcpY/SQRA51JCCM9lEcXnwTxTxd02v6A/tueoyUdONm2lniCA==
|
||||
dependencies:
|
||||
"@interactjs/utils" "1.9.7"
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/feedback@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/feedback/-/feedback-1.9.7.tgz#0e3ea3c8e863fdf89d8afee0a1ae5838e9f13d09"
|
||||
integrity sha512-CcgTv2mhCWpH0w6Fq12K6kiV1BSozt8Rdy02yXg927ruKChr7pIQvvZP7TpxfZoBFCN9JJxN3KvQpcfsUQsafQ==
|
||||
|
||||
"@interactjs/inertia@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/inertia/-/inertia-1.9.7.tgz#e8c8ed702bd23d0182a1a0ddbca4be7419826511"
|
||||
integrity sha512-WeVKgztqODjE+fbYuIayJv4cdqwBz4wJ45RC2qYhYWhzsHL0LUbJhEs6sCnV3q+2wZEVMdB8oURh8tnqECBIGg==
|
||||
dependencies:
|
||||
"@interactjs/offset" "1.9.7"
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/interact@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/interact/-/interact-1.9.7.tgz#be988cfb15b13f2cfc0aa68ce826761d49f46e8a"
|
||||
integrity sha512-BocTUB8TfZ3USuN1s7xP+3Uhvb7dnZFNTfr3Ux6Nv2BxKLMz/bIU2fZhYAHw7xApIMKfYyRuUNxSyGM5iyCaEA==
|
||||
dependencies:
|
||||
"@interactjs/core" "1.9.7"
|
||||
"@interactjs/types" "1.9.7"
|
||||
"@interactjs/utils" "1.9.7"
|
||||
|
||||
"@interactjs/interactjs@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/interactjs/-/interactjs-1.9.7.tgz#995b6d9b4abd03a84b02c887315768ab2421b35c"
|
||||
integrity sha512-D3wdlwUQRS8t8r7TopYlkjKsONxazrZu8R4DBL+czUrm26Il/0427+uoV92iMgDUZpw5fYLt1dzqzozUL/y6Dw==
|
||||
dependencies:
|
||||
"@interactjs/actions" "1.9.7"
|
||||
"@interactjs/arrange" "1.9.7"
|
||||
"@interactjs/auto-scroll" "1.9.7"
|
||||
"@interactjs/auto-start" "1.9.7"
|
||||
"@interactjs/clone" "1.9.7"
|
||||
"@interactjs/components" "1.9.7"
|
||||
"@interactjs/core" "1.9.7"
|
||||
"@interactjs/dev-tools" "1.9.7"
|
||||
"@interactjs/feedback" "1.9.7"
|
||||
"@interactjs/inertia" "1.9.7"
|
||||
"@interactjs/interact" "1.9.7"
|
||||
"@interactjs/modifiers" "1.9.7"
|
||||
"@interactjs/multi-target" "1.9.7"
|
||||
"@interactjs/offset" "1.9.7"
|
||||
"@interactjs/pointer-events" "1.9.7"
|
||||
"@interactjs/reflow" "1.9.7"
|
||||
"@interactjs/types" "1.9.7"
|
||||
"@interactjs/utils" "1.9.7"
|
||||
"@interactjs/vue" "1.9.7"
|
||||
|
||||
"@interactjs/modifiers@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/modifiers/-/modifiers-1.9.7.tgz#dcb37e3782c91d7f8b28008d68ec5ebc26101e7a"
|
||||
integrity sha512-1trdJ6E85DiUn2u0zvqLYt77aoug0VYDg8c1GyzcLm64t8CYw+PggTQKqhy+kJiKb30QsgUuhsR5aQdlotguew==
|
||||
dependencies:
|
||||
"@interactjs/snappers" "1.9.7"
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/multi-target@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/multi-target/-/multi-target-1.9.7.tgz#bb4de8612f6a649e18d40b93ed5461cde72f79ee"
|
||||
integrity sha512-hqw4sCKYxUZV00u0ikEM66t6zrCP8t3TDgDPrph274LmEUIdfGrCsv7xWLIEdke63h0pt3lO1V5H8N/rMoGs0A==
|
||||
|
||||
"@interactjs/offset@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/offset/-/offset-1.9.7.tgz#5a2aec0f25781bd1728c71fe8c16a55edc3f5b8e"
|
||||
integrity sha512-IMCizwVDk2hj8yNNTfLnqdK9GuSlFSS8GxK2ZGUGNSQSPh3b6vrkkIrxwA/qHjDGUUuDP+ZWvlAF4D0/OAc74g==
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/pointer-events@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/pointer-events/-/pointer-events-1.9.7.tgz#5a0e0daff1c322c6cbff8cbb8052c531d66d1aad"
|
||||
integrity sha512-Vl/+GTVnZlw8DQ7YN7D1oIIZLiqPL/KgdfRrGHSidsLmo/WJNM2TsJJsJcRMY/IiEQrtTvp/fSKG6rNWyzIr5w==
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/reflow@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/reflow/-/reflow-1.9.7.tgz#77494d83e1a13236ca841adba997faaaf6eb633c"
|
||||
integrity sha512-npuIadX3YBoFFqJbM+LQZgPyw/IYq3HwYM2WNi8Bc/feCy1Ia12uF4Lwi5Rj+8jcA5FyInHzZXBUJCcHO1zaFQ==
|
||||
optionalDependencies:
|
||||
"@interactjs/interact" "1.9.7"
|
||||
|
||||
"@interactjs/snappers@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/snappers/-/snappers-1.9.7.tgz#b2f3752ab25c886cd5ae1f4c0478964b9b8b652e"
|
||||
integrity sha512-EfKsgTi8yCtNWRHSU2INfMob5eMUBY8Wrh53tszgh94JstyKwlmzG2mH6eGwdN7pU3//h0AM4ThuqOmbIYUPCw==
|
||||
|
||||
"@interactjs/symbol-tree@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/symbol-tree/-/symbol-tree-1.9.7.tgz#2aec371ded47be71cfa359305da959b382de66ff"
|
||||
integrity sha512-zLRpXVtzq/TxG6MwT1FhkBNoFGZlYxNd52RZ6Wy5XyPAsxaZoXqNzDUT6See/xe2X80gzvT78dkT5uKSUE3I2w==
|
||||
|
||||
"@interactjs/types@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/types/-/types-1.9.7.tgz#6e7a8bc26d99bd5f324312950b948b936f6d42e0"
|
||||
integrity sha512-Z6fPHp2JjCYg4SJ/DhaIqelY1WA6Oppw87PscOM+28jPc2q5pTUMlFzAY0QQlF43t4PFiCAZVhmBGZzgMfyF0A==
|
||||
dependencies:
|
||||
"@interactjs/actions" "1.9.7"
|
||||
"@interactjs/arrange" "1.9.7"
|
||||
"@interactjs/auto-scroll" "1.9.7"
|
||||
"@interactjs/auto-start" "1.9.7"
|
||||
"@interactjs/core" "1.9.7"
|
||||
"@interactjs/dev-tools" "1.9.7"
|
||||
"@interactjs/inertia" "1.9.7"
|
||||
"@interactjs/modifiers" "1.9.7"
|
||||
"@interactjs/pointer-events" "1.9.7"
|
||||
"@interactjs/reflow" "1.9.7"
|
||||
"@interactjs/snappers" "1.9.7"
|
||||
"@interactjs/symbol-tree" "1.9.7"
|
||||
"@interactjs/utils" "1.9.7"
|
||||
|
||||
"@interactjs/utils@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/utils/-/utils-1.9.7.tgz#390f574c5b8adbf9cc527affb686d9233d241eec"
|
||||
integrity sha512-7/j0UmeuBHi20FHlqKN9KbndulLEuTiPIPID5nEw+1F/jMKucn3uPIXfruSkbcGswltqTCR0QHhICMLXhFRVhw==
|
||||
|
||||
"@interactjs/vue@1.9.7":
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@interactjs/vue/-/vue-1.9.7.tgz#9942407a144b4cd9d1f264ccaaf43d75f5a00a60"
|
||||
integrity sha512-Y1mjCB5tGxsaUkfYP/i1dIoBRnxkDpvZtmfKp38u1SRt3QCfNznKf4252QC7RBTSgIL/Cohi8c/oAq++ZpkTSQ==
|
||||
|
||||
"@jest/console@^24.7.1", "@jest/console@^24.9.0":
|
||||
version "24.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0"
|
||||
@ -2984,11 +3156,6 @@ class-utils@^0.3.5:
|
||||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
classnames@^2.2.5:
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||
|
||||
clean-css@^4.2.1:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
|
||||
@ -5480,6 +5647,14 @@ inquirer@7.0.4, inquirer@^7.0.0:
|
||||
strip-ansi "^5.1.0"
|
||||
through "^2.3.6"
|
||||
|
||||
interactjs@^1.9.7:
|
||||
version "1.9.7"
|
||||
resolved "https://registry.yarnpkg.com/interactjs/-/interactjs-1.9.7.tgz#ebcbc3cab9c63f4cd66aa650a5918bcc2aaeeead"
|
||||
integrity sha512-X8Y4iSeFdy8bnFkbrDJ5C/HwGKCgLUHhOdfvxLsx/f1YlYZ23qBA4aYoB74Qw0CG/mMenYiOFLxbDIaly8hhzQ==
|
||||
dependencies:
|
||||
"@interactjs/interactjs" "1.9.7"
|
||||
"@interactjs/types" "1.9.7"
|
||||
|
||||
internal-ip@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907"
|
||||
@ -7035,6 +7210,11 @@ nan@^2.12.1:
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
||||
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
|
||||
|
||||
nanoid@^2.1.0:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
|
||||
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||
@ -8586,7 +8766,7 @@ prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.3"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
@ -8792,14 +8972,6 @@ react-dom@^16.13.0:
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.0"
|
||||
|
||||
react-draggable@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.2.0.tgz#40cc5209082ca7d613104bf6daf31372cc0e1114"
|
||||
integrity sha512-5wFq//gEoeTYprnd4ze8GrFc+Rbnx+9RkOMR3vk4EbWxj02U6L6T3yrlKeiw4X5CtjD2ma2+b3WujghcXNRzkw==
|
||||
dependencies:
|
||||
classnames "^2.2.5"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-error-overlay@^6.0.6:
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.6.tgz#ac4d9dc4c1b5c536c2c312bf66aa2b09bfa384e2"
|
||||
@ -9604,6 +9776,13 @@ shellwords@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
|
||||
|
||||
shortid@^2.2.15:
|
||||
version "2.2.15"
|
||||
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
|
||||
integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
|
||||
dependencies:
|
||||
nanoid "^2.1.0"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
Loading…
Reference in New Issue
Block a user