From 86f7b09e4c431e3185b26e6fc60935f548c515dd Mon Sep 17 00:00:00 2001 From: saki Date: Fri, 24 May 2024 10:29:15 +0900 Subject: [PATCH 1/2] npm install @atlaskit/pragmatic-drag-and-drop --- package-lock.json | 25 ++++++++++++++++++++++--- package.json | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e08f94b..317fc6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "trellith", "version": "0.12.7", "dependencies": { + "@atlaskit/pragmatic-drag-and-drop": "^1.1.9", "@preact/signals": "^1.2.3", "colorjs.io": "^0.5.0", "preact": "^10.22.0", @@ -41,6 +42,16 @@ "node": ">=6.0.0" } }, + "node_modules/@atlaskit/pragmatic-drag-and-drop": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop/-/pragmatic-drag-and-drop-1.1.9.tgz", + "integrity": "sha512-HZkT0mStizzneobq7vINEnEsm7DTu70gaEu0HHSNKv6lkX4tI0h1HoAyDUZqH3xFc5nuhvjdFxygZRzMhs5w+g==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "bind-event-listener": "^3.0.0", + "raf-schd": "^4.0.3" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", @@ -1704,7 +1715,6 @@ "version": "7.24.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -3391,6 +3401,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bind-event-listener": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-3.0.0.tgz", + "integrity": "sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==" + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -6214,6 +6229,11 @@ } ] }, + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6262,8 +6282,7 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regenerator-transform": { "version": "0.15.2", diff --git a/package.json b/package.json index 0316f0b..06f93f1 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "lint:fix": "eslint --fix ." }, "dependencies": { + "@atlaskit/pragmatic-drag-and-drop": "^1.1.9", "@preact/signals": "^1.2.3", "colorjs.io": "^0.5.0", "preact": "^10.22.0", From f4492221e5e70b4c1d05c1a2d46a8b76bdb1d572 Mon Sep 17 00:00:00 2001 From: saki Date: Fri, 24 May 2024 10:30:04 +0900 Subject: [PATCH 2/2] introduce pragmatic-drag-and-drop to BoardList --- src/components/BoardItem.tsx | 53 +++++++++++++++++++++++++------ src/components/BoardList.tsx | 8 +---- src/components/PageComponents.tsx | 4 --- src/components/PageIndex.tsx | 28 +++++----------- 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/components/BoardItem.tsx b/src/components/BoardItem.tsx index 2dc7918..c7d77a2 100644 --- a/src/components/BoardItem.tsx +++ b/src/components/BoardItem.tsx @@ -2,36 +2,69 @@ import { Link } from "wouter-preact" import { JSX } from "preact/jsx-runtime" import { Pos } from "../types/pos" import { Board } from "../types/board" +import { useEffect, useRef } from "preact/hooks" +import { draggable, dropTargetForElements, monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter" +import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine" export default function BoardItem( { board, pos, cardsNum, - handleDragEnd, handleDragOver, - handleDragStart, - handleDrop + handleDrop, }: { board: Omit pos: Pos cardsNum: number - handleDragEnd: (e: JSX.TargetedDragEvent) => void handleDragOver: (e: JSX.TargetedDragEvent) => void - handleDragStart: (e: JSX.TargetedDragEvent) => void - handleDrop: (e: JSX.TargetedDragEvent) => void + handleDrop: (elemTarget: HTMLDivElement, elemSource: HTMLDivElement) => void } ) { + const ref = useRef(null) + + useEffect(() => { + const el = ref.current + if (el) { + return combine( + draggable({ + element: el, + onDragStart: () => { + console.log('draggable: drag start') + }, + onDrop: () => { + console.log('draggable: drop') + }, + }), + dropTargetForElements({ + element: el, + onDragEnter: () => { + console.log('target: drag enter') + }, + onDragLeave: () => { + console.log('target: drag leave') + }, + onDrop: () => { + console.log('target: drop') + } + }), + monitorForElements({ + onDrop({ location, source }) { + const target = location.current.dropTargets[0] + handleDrop(target.element as HTMLDivElement, source.element as HTMLDivElement) + }, + }), + ) + } + }, []) + return (
void handleDragOver: (e: JSX.TargetedDragEvent) => void - handleDragStart: (e: JSX.TargetedDragEvent) => void - handleDrop: (e: JSX.TargetedDragEvent) => void + handleDrop: (elemTarget: HTMLDivElement, elemSource: HTMLDivElement) => void handleToggleDialog: (e: JSX.TargetedMouseEvent) => void } ) { @@ -81,9 +77,7 @@ export default function BoardList( board={board} pos={idx === 0 ? "first" : (idx === (boards.length - 1) ? "last" : "middle")} cardsNum={board.lists.map(l => l.cards.length).reduce((accumulator, value) => { return accumulator + value }, 0)} - handleDragEnd={handleDragEnd} handleDragOver={handleDragOver} - handleDragStart={handleDragStart} handleDrop={handleDrop} /> ) diff --git a/src/components/PageComponents.tsx b/src/components/PageComponents.tsx index d873295..ef6142b 100644 --- a/src/components/PageComponents.tsx +++ b/src/components/PageComponents.tsx @@ -113,9 +113,7 @@ export default function PageComponents() { board={board1} pos="first" cardsNum={8} - handleDragEnd={() => { }} handleDragOver={() => { }} - handleDragStart={() => { }} handleDrop={() => { }} />
@@ -125,9 +123,7 @@ export default function PageComponents() {
{ }} handleDragOver={() => { }} - handleDragStart={() => { }} handleDrop={() => { }} handleToggleDialog={() => { }} /> diff --git a/src/components/PageIndex.tsx b/src/components/PageIndex.tsx index d52248a..6ec235e 100644 --- a/src/components/PageIndex.tsx +++ b/src/components/PageIndex.tsx @@ -1,4 +1,4 @@ -import { useRef, useState } from 'preact/hooks' +import { useRef } from 'preact/hooks' import { JSX } from 'preact/jsx-runtime' import { Signal } from '@preact/signals' import { ApplicationService } from '../applications/applicationService' @@ -14,7 +14,6 @@ import IconMoreHoriz from './IconMoreHoriz' import { showBoardDialog } from '../main' export default function PageIndex({ appState }: { appState: Signal }) { - const [draggingBoardId, setDraggingBoardId] = useState(undefined) const detailsElement = useRef(null) const repository = new RepositoryLocalStorage() const service = new ApplicationService(repository) @@ -56,24 +55,15 @@ export default function PageIndex({ appState }: { appState: Signal }) { } } - const handleDragEnd = () => setDraggingBoardId(undefined) - const handleDragOver = (e: JSX.TargetedDragEvent) => e.preventDefault() - const handleDragStart = (e: JSX.TargetedDragEvent) => { - if (e.dataTransfer) { - e.dataTransfer.effectAllowed = 'move' - } - const { boardId } = e.currentTarget.dataset - if (boardId) { - setTimeout(() => { setDraggingBoardId(boardId) }, 100) - } - } - - const handleDrop = (e: JSX.TargetedDragEvent) => { - const { boardId, pos } = e.currentTarget.dataset - if (boardId && pos && draggingBoardId) { - appState.value = service.moveBoard(appState.value, draggingBoardId, pos as Pos, boardId) + const handleDrop = (elemTarget: HTMLDivElement, elemSource: HTMLDivElement) => { + const { boardId, pos } = elemTarget.dataset + if (boardId && pos) { + const sourceBoardId = elemSource.dataset.boardId + if (sourceBoardId) { + appState.value = service.moveBoard(appState.value, sourceBoardId, pos as Pos, boardId) + } } } @@ -160,9 +150,7 @@ export default function PageIndex({ appState }: { appState: Signal }) {