Add ability to drag and drop a tile onto the map and added better drag cursors

This commit is contained in:
Mitchell McCaffrey
2021-05-28 17:06:20 +10:00
parent f84baab6fb
commit bac3101886
12 changed files with 400 additions and 186 deletions
+6 -1
View File
@@ -13,6 +13,7 @@ function SortableTile({
hidden,
children,
isDragging,
cursor,
}) {
const {
attributes,
@@ -29,7 +30,7 @@ function SortableTile({
});
const dragStyle = {
cursor: "pointer",
cursor,
opacity: isDragging ? 0.25 : undefined,
};
@@ -92,4 +93,8 @@ function SortableTile({
);
}
SortableTile.defaultProps = {
cursor: "pointer",
};
export default SortableTile;
+3 -1
View File
@@ -20,7 +20,7 @@ import {
import { useGroup } from "../../contexts/GroupContext";
function SortableTiles({ renderTile, subgroup }) {
const { dragId, overId } = useTileDrag();
const { dragId, overId, dragCursor } = useTileDrag();
const {
groups: allGroups,
selectedGroupIds: allSelectedIds,
@@ -88,6 +88,7 @@ function SortableTiles({ renderTile, subgroup }) {
<div
style={{
transform: `translate(${coords[index].x}%, ${coords[index].y}%)`,
cursor: dragCursor,
}}
>
<animated.div style={dragBounce}>
@@ -137,6 +138,7 @@ function SortableTiles({ renderTile, subgroup }) {
disableSorting={disableSorting}
hidden={group.id === openGroupId}
isDragging={isDragging}
cursor={dragCursor}
>
{renderSortableGroup(group, selectedGroups)}
</SortableTile>
-1
View File
@@ -24,7 +24,6 @@ function Tile({
borderRadius: "4px",
justifyContent: "center",
alignItems: "center",
cursor: "pointer",
overflow: "hidden",
userSelect: "none",
}}
+54
View File
@@ -0,0 +1,54 @@
import React from "react";
import { createPortal } from "react-dom";
import Droppable from "../drag/Droppable";
import { ADD_TO_MAP_ID_PREFIX } from "../../contexts/TileDragContext";
function TilesAddDroppable({ containerSize }) {
return createPortal(
<div>
<Droppable
id={`${ADD_TO_MAP_ID_PREFIX}-1`}
style={{
width: "100vw",
height: `calc(50vh - ${containerSize.height / 2}px)`,
position: "absolute",
top: 0,
}}
/>
<Droppable
id={`${ADD_TO_MAP_ID_PREFIX}-2`}
style={{
width: "100vw",
height: `calc(50vh - ${containerSize.height / 2}px)`,
position: "absolute",
bottom: 0,
}}
/>
<Droppable
id={`${ADD_TO_MAP_ID_PREFIX}-3`}
style={{
width: `calc(50vw - ${containerSize.width / 2}px)`,
height: "100vh",
position: "absolute",
top: 0,
left: 0,
}}
/>
<Droppable
id={`${ADD_TO_MAP_ID_PREFIX}-4`}
style={{
width: `calc(50vw - ${containerSize.width / 2}px)`,
height: "100vh",
position: "absolute",
top: 0,
right: 0,
}}
/>
</div>,
document.body
);
}
export default TilesAddDroppable;
+36 -64
View File
@@ -1,14 +1,12 @@
import React, { useState } from "react";
import { createPortal } from "react-dom";
import { Box, Close, Grid, useThemeUI } from "theme-ui";
import { useSpring, animated, config } from "react-spring";
import ReactResizeDetector from "react-resize-detector";
import SimpleBar from "simplebar-react";
import { useGroup } from "../../contexts/GroupContext";
import { UNGROUP_ID_PREFIX } from "../../contexts/TileDragContext";
import Droppable from "../drag/Droppable";
import TilesUngroupDroppable from "./TilesUngroupDroppable";
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
@@ -25,73 +23,47 @@ function TilesOverlay({ children }) {
config: config.gentle,
});
const [containerSize, setContinerSize] = useState(0);
function handleResize(width, height) {
const [containerSize, setContinerSize] = useState({ width: 0, height: 0 });
function handleContainerResize(width, height) {
const size = Math.min(width, height) - 16;
setContinerSize(size);
setContinerSize({ width: size, height: size });
}
function renderUngroupBoxes() {
return createPortal(
<div>
<Droppable
id={`${UNGROUP_ID_PREFIX}-1`}
style={{
width: "100vw",
height: `calc(50vh - ${containerSize / 2}px)`,
position: "absolute",
top: 0,
}}
/>
<Droppable
id={`${UNGROUP_ID_PREFIX}-2`}
style={{
width: "100vw",
height: `calc(50vh - ${containerSize / 2}px)`,
position: "absolute",
bottom: 0,
}}
/>
<Droppable
id={`${UNGROUP_ID_PREFIX}-3`}
style={{
width: `calc(50vw - ${containerSize / 2}px)`,
height: "100vh",
position: "absolute",
top: 0,
left: 0,
}}
/>
<Droppable
id={`${UNGROUP_ID_PREFIX}-4`}
style={{
width: `calc(50vw - ${containerSize / 2}px)`,
height: "100vh",
position: "absolute",
top: 0,
right: 0,
}}
/>
</div>,
document.body
);
const [overlaySize, setOverlaySize] = useState({ width: 0, height: 0 });
function handleOverlayResize(width, height) {
setOverlaySize({ width, height });
}
return (
<>
{openGroupId && renderUngroupBoxes()}
{openGroupId && (
<Box
sx={{
position: "absolute",
width: "100%",
height: "100%",
top: 0,
}}
bg="overlay"
<TilesUngroupDroppable
innerContainerSize={containerSize}
outerContainerSize={overlaySize}
/>
)}
<ReactResizeDetector handleWidth handleHeight onResize={handleResize}>
{openGroupId && (
<ReactResizeDetector
handleWidth
handleHeight
onResize={handleOverlayResize}
>
<Box
sx={{
position: "absolute",
width: "100%",
height: "100%",
top: 0,
}}
bg="overlay"
/>
</ReactResizeDetector>
)}
<ReactResizeDetector
handleWidth
handleHeight
onResize={handleContainerResize}
>
<animated.div
style={{
...openAnimation,
@@ -109,8 +81,8 @@ function TilesOverlay({ children }) {
>
<Box
sx={{
width: containerSize,
height: containerSize,
width: containerSize.width,
height: containerSize.height,
borderRadius: "8px",
border: "1px solid",
borderColor: "border",
@@ -125,8 +97,8 @@ function TilesOverlay({ children }) {
>
<SimpleBar
style={{
width: containerSize - 16,
height: containerSize - 48,
width: containerSize.width - 16,
height: containerSize.height - 48,
marginBottom: "8px",
backgroundColor: theme.colors.muted,
}}
@@ -0,0 +1,59 @@
import React from "react";
import { createPortal } from "react-dom";
import Droppable from "../drag/Droppable";
import { UNGROUP_ID_PREFIX } from "../../contexts/TileDragContext";
function TilesUngroupDroppable({ outerContainerSize, innerContainerSize }) {
const width = (outerContainerSize.width - innerContainerSize.width) / 2;
const height = (outerContainerSize.height - innerContainerSize.height) / 2;
return createPortal(
<div>
<Droppable
id={`${UNGROUP_ID_PREFIX}-1`}
style={{
width: outerContainerSize.width,
height,
position: "absolute",
top: `calc(50% - ${innerContainerSize.height / 2 + height}px)`,
left: `calc(50% - ${outerContainerSize.width / 2}px)`,
}}
/>
<Droppable
id={`${UNGROUP_ID_PREFIX}-2`}
style={{
width: outerContainerSize.width,
height,
position: "absolute",
top: `calc(50% + ${innerContainerSize.height / 2}px)`,
left: `calc(50% - ${outerContainerSize.width / 2}px)`,
}}
/>
<Droppable
id={`${UNGROUP_ID_PREFIX}-3`}
style={{
width,
height: outerContainerSize.height,
position: "absolute",
top: `calc(50% - ${outerContainerSize.height / 2}px)`,
left: `calc(50% - ${innerContainerSize.width / 2 + width}px)`,
}}
/>
<Droppable
id={`${UNGROUP_ID_PREFIX}-4`}
style={{
width,
height: outerContainerSize.height,
position: "absolute",
top: `calc(50% - ${outerContainerSize.height / 2}px)`,
left: `calc(50% + ${innerContainerSize.width / 2}px)`,
}}
/>
</div>,
document.body
);
}
export default TilesUngroupDroppable;