From 21986231fa7720859a8d1845005e0f0ba545f4eb Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Wed, 9 Jun 2021 23:25:28 +1000 Subject: [PATCH] Add prevent select helper to stop highlighting UI elements on drag with touch devices --- src/components/token/TokenBar.js | 17 ++++++++++++++--- src/contexts/TileDragContext.js | 20 +++++++++++++++++--- src/hooks/usePreventSelect.js | 13 +++++++++++++ src/index.css | 4 ++++ 4 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 src/hooks/usePreventSelect.js diff --git a/src/components/token/TokenBar.js b/src/components/token/TokenBar.js index 2a9b93e..7f42544 100644 --- a/src/components/token/TokenBar.js +++ b/src/components/token/TokenBar.js @@ -5,7 +5,8 @@ import SimpleBar from "simplebar-react"; import { DragOverlay, DndContext, - PointerSensor, + MouseSensor, + TouchSensor, KeyboardSensor, useSensor, useSensors, @@ -18,6 +19,7 @@ import SelectTokensButton from "./SelectTokensButton"; import Draggable from "../drag/Draggable"; import useSetting from "../../hooks/useSetting"; +import usePreventSelect from "../../hooks/usePreventSelect"; import { useTokenData } from "../../contexts/TokenDataContext"; import { useAuth } from "../../contexts/AuthContext"; @@ -43,14 +45,20 @@ function TokenBar({ onMapTokensStateCreate }) { // https://github.com/clauderic/dnd-kit/issues/238 const dragOverlayRef = useRef(); - const pointerSensor = useSensor(PointerSensor, { + const mouseSensor = useSensor(MouseSensor, { + activationConstraint: { distance: 5 }, + }); + const touchSensor = useSensor(TouchSensor, { activationConstraint: { distance: 5 }, }); const keyboardSensor = useSensor(KeyboardSensor); - const sensors = useSensors(pointerSensor, keyboardSensor); + const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor); + + const [preventSelect, resumeSelect] = usePreventSelect(); function handleDragStart({ active }) { setDragId(active.id); + preventSelect(); } function handleDragEnd({ active }) { @@ -93,10 +101,13 @@ function TokenBar({ onMapTokensStateCreate }) { } } } + + resumeSelect(); } function handleDragCancel() { setDragId(null); + resumeSelect(); } function renderToken(group, draggable = true) { diff --git a/src/contexts/TileDragContext.js b/src/contexts/TileDragContext.js index 6990d4d..2e8c229 100644 --- a/src/contexts/TileDragContext.js +++ b/src/contexts/TileDragContext.js @@ -1,7 +1,8 @@ import React, { useState, useContext } from "react"; import { DndContext, - PointerSensor, + MouseSensor, + TouchSensor, KeyboardSensor, useSensor, useSensors, @@ -12,6 +13,8 @@ import { useGroup } from "./GroupContext"; import { moveGroupsInto, moveGroups, ungroup } from "../helpers/group"; +import usePreventSelect from "../hooks/usePreventSelect"; + const TileDragContext = React.createContext(); export const BASE_SORTABLE_ID = "__base__"; @@ -56,17 +59,22 @@ export function TileDragProvider({ filter, } = useGroup(); - const pointerSensor = useSensor(PointerSensor, { + const mouseSensor = useSensor(MouseSensor, { + activationConstraint: { delay: 250, tolerance: 5 }, + }); + const touchSensor = useSensor(TouchSensor, { activationConstraint: { delay: 250, tolerance: 5 }, }); const keyboardSensor = useSensor(KeyboardSensor); - const sensors = useSensors(pointerSensor, keyboardSensor); + const sensors = useSensors(mouseSensor, touchSensor, keyboardSensor); const [dragId, setDragId] = useState(); const [overId, setOverId] = useState(); const [dragCursor, setDragCursor] = useState("pointer"); + const [preventSelect, resumeSelect] = usePreventSelect(); + function handleDragStart(event) { const { active, over } = event; setDragId(active.id); @@ -77,6 +85,8 @@ export function TileDragProvider({ setDragCursor("grabbing"); onDragStart && onDragStart(event); + + preventSelect(); } function handleDragOver(event) { @@ -146,6 +156,8 @@ export function TileDragProvider({ } } + resumeSelect(); + onDragEnd && onDragEnd(event); } @@ -154,6 +166,8 @@ export function TileDragProvider({ setOverId(); setDragCursor("pointer"); + resumeSelect(); + onDragCancel && onDragCancel(event); } diff --git a/src/hooks/usePreventSelect.js b/src/hooks/usePreventSelect.js new file mode 100644 index 0000000..d20bb40 --- /dev/null +++ b/src/hooks/usePreventSelect.js @@ -0,0 +1,13 @@ +function usePreventSelect() { + function preventSelect() { + document.body.classList.add("no-select"); + } + + function resumeSelect() { + document.body.classList.remove("no-select"); + } + + return [preventSelect, resumeSelect]; +} + +export default usePreventSelect; diff --git a/src/index.css b/src/index.css index fb96b26..38bf6b3 100644 --- a/src/index.css +++ b/src/index.css @@ -13,3 +13,7 @@ html { input[type="checkbox"]:disabled ~ svg { opacity: 0.1; } + +.no-select div { + user-select: none; +}