Add ability to drag and drop a tile onto the map and added better drag cursors
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -24,7 +24,6 @@ function Tile({
|
||||
borderRadius: "4px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
overflow: "hidden",
|
||||
userSelect: "none",
|
||||
}}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user