From 9c9cf3a978b53e675fd9a018c0ecdf985877736e Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sun, 31 Jul 2022 02:14:54 -0700 Subject: [PATCH] Add dnd-kit package --- package-lock.json | 85 +++++++++++++++++++ package.json | 2 + src/renderer/app.tsx | 35 +++++++- .../components/drag-drop/Draggable.tsx | 14 +++ .../components/virtual-grid/GridCard.tsx | 84 +++++++++++------- 5 files changed, 186 insertions(+), 34 deletions(-) create mode 100644 src/renderer/components/drag-drop/Draggable.tsx diff --git a/package-lock.json b/package-lock.json index 75d2d3437..f1550b8c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,8 @@ "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { + "@dnd-kit/core": "^6.0.5", + "@dnd-kit/modifiers": "^6.0.0", "@emotion/react": "^11.9.3", "@jellyfin/client-axios": "^10.7.8", "@mantine/core": "^5.0.0", @@ -790,6 +792,54 @@ "node": ">=10.0.0" } }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz", + "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.5.tgz", + "integrity": "sha512-3nL+Zy5cT+1XwsWdlXIvGIFvbuocMyB4NBxTN74DeBaBqeWdH9JsnKwQv7buZQgAHmAH+eIENfS1ginkvW6bCw==", + "dependencies": { + "@dnd-kit/accessibility": "^3.0.0", + "@dnd-kit/utilities": "^3.2.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/modifiers": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.0.tgz", + "integrity": "sha512-V3+JSo6/BTcgPRHiNUTSKgqVv/doKXg+T4Z0QvKiiXp+uIyJTUtPkQOBRQApUWi3ApBhnoWljyt/3xxY4fTd0Q==", + "dependencies": { + "@dnd-kit/utilities": "^3.2.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.0.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.0.tgz", + "integrity": "sha512-h65/pn2IPCCIWwdlR2BMLqRkDxpTEONA+HQW3n765HBijLYGyrnTCLa2YQt8VVjjSQD6EfFlTE6aS2Q/b6nb2g==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@electron/get": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", @@ -23630,6 +23680,41 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@dnd-kit/accessibility": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz", + "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@dnd-kit/core": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.5.tgz", + "integrity": "sha512-3nL+Zy5cT+1XwsWdlXIvGIFvbuocMyB4NBxTN74DeBaBqeWdH9JsnKwQv7buZQgAHmAH+eIENfS1ginkvW6bCw==", + "requires": { + "@dnd-kit/accessibility": "^3.0.0", + "@dnd-kit/utilities": "^3.2.0", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/modifiers": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.0.tgz", + "integrity": "sha512-V3+JSo6/BTcgPRHiNUTSKgqVv/doKXg+T4Z0QvKiiXp+uIyJTUtPkQOBRQApUWi3ApBhnoWljyt/3xxY4fTd0Q==", + "requires": { + "@dnd-kit/utilities": "^3.2.0", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/utilities": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.0.tgz", + "integrity": "sha512-h65/pn2IPCCIWwdlR2BMLqRkDxpTEONA+HQW3n765HBijLYGyrnTCLa2YQt8VVjjSQD6EfFlTE6aS2Q/b6nb2g==", + "requires": { + "tslib": "^2.0.0" + } + }, "@electron/get": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", diff --git a/package.json b/package.json index 23c040455..b91d38dfc 100644 --- a/package.json +++ b/package.json @@ -245,6 +245,8 @@ "webpack-merge": "^5.8.0" }, "dependencies": { + "@dnd-kit/core": "^6.0.5", + "@dnd-kit/modifiers": "^6.0.0", "@emotion/react": "^11.9.3", "@jellyfin/client-axios": "^10.7.8", "@mantine/core": "^5.0.0", diff --git a/src/renderer/app.tsx b/src/renderer/app.tsx index 8c8d92cb3..65f0e9086 100644 --- a/src/renderer/app.tsx +++ b/src/renderer/app.tsx @@ -1,4 +1,11 @@ import { ReactNode, useEffect } from 'react'; +import { + DndContext, + MouseSensor, + TouchSensor, + useSensor, + useSensors, +} from '@dnd-kit/core'; import { MantineProvider } from '@mantine/core'; import { useLocalStorage } from '@mantine/hooks'; import isElectron from 'is-electron'; @@ -27,6 +34,21 @@ export const App = () => { document.body.setAttribute('data-theme', theme); }, [theme]); + const sensors = useSensors( + useSensor(MouseSensor, { + activationConstraint: { + delay: 200, + tolerance: 100, + }, + }), + useSensor(TouchSensor, { + activationConstraint: { + delay: 500, + tolerance: 10, + }, + }) + ); + return ( { xl: 18, xs: 10, }, + other: {}, spacing: { xs: 2, }, }} > - - - + console.log('drag end')} + onDragStart={() => console.log('drag start')} + > + + + + ); }; diff --git a/src/renderer/components/drag-drop/Draggable.tsx b/src/renderer/components/drag-drop/Draggable.tsx new file mode 100644 index 000000000..b5a754f9f --- /dev/null +++ b/src/renderer/components/drag-drop/Draggable.tsx @@ -0,0 +1,14 @@ +import { useDraggable } from '@dnd-kit/core'; + +export const Draggable = ({ element, id, children, key }: any) => { + const Element = element || 'div'; + const { attributes, listeners, setNodeRef } = useDraggable({ + id, + }); + + return ( + + {children} + + ); +}; diff --git a/src/renderer/components/virtual-grid/GridCard.tsx b/src/renderer/components/virtual-grid/GridCard.tsx index fa36732d1..3a304b7ad 100644 --- a/src/renderer/components/virtual-grid/GridCard.tsx +++ b/src/renderer/components/virtual-grid/GridCard.tsx @@ -1,7 +1,12 @@ +import React, { useState } from 'react'; +import { DragOverlay, useDndMonitor } from '@dnd-kit/core'; +import { snapCenterToCursor } from '@dnd-kit/modifiers'; import { Card, Skeleton } from '@mantine/core'; import { motion } from 'framer-motion'; +import { createPortal } from 'react-dom'; import styled from 'styled-components'; import { CardRow } from '../../types'; +import { Draggable } from '../drag-drop/Draggable'; import { Text } from '../text/Text'; import { GridCardControls } from './GridCardControls'; @@ -98,39 +103,56 @@ export const GridCard = ({ data, index, style }: any) => { const stopIndex = Math.min(itemCount - 1, startIndex + columnCount - 1); const cards = []; + const [isDragging, setIsDragging] = useState(false); + + useDndMonitor({ + onDragCancel: () => setIsDragging(false), + onDragEnd: () => setIsDragging(false), + onDragStart: () => setIsDragging(true), + }); + for (let i = startIndex; i <= stopIndex; i += 1) { cards.push( - - - - - - - - - - - - {cardRows.map((row: CardRow) => ( - - - {itemData[i] && itemData[i][row.prop]} - - - ))} - - - - + + + + + + + + + + + + + + {cardRows.map((row: CardRow) => ( + + + {itemData[i] && itemData[i][row.prop]} + + + ))} + + + + + + {createPortal( + + {isDragging ?
OVERLAY
: null} +
, + document.body + )} +
); }