aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/lib/drag-and-drop.ts
diff options
context:
space:
mode:
authorkamtschatka <simon.schatka@gmx.at>2024-07-01 13:59:10 +0200
committerGitHub <noreply@github.com>2024-07-01 12:59:10 +0100
commit9cd617055b7878048120eebd58dc2e05a9cbdfca (patch)
tree4c80908640bb6b92e355d027ed64fce26fac2454 /apps/web/lib/drag-and-drop.ts
parent9883c6bcd18c2ca1fda7d83e465a0bf9cf45510d (diff)
downloadkarakeep-9cd617055b7878048120eebd58dc2e05a9cbdfca.tar.zst
refactor: drag and drop improvements (#264)
* [Feature request] Drag and Drop Items to Lists #123 reworked the drag and drop mechanism to still have change detection, but not so much that it has a huge overhead Changed the layout a bit to allow proper drag/drop of elements from the main section to the sidebar Added the possibility to drag/drop bookmarks onto lists * [Feature request] Drag and Drop Items to Lists #123 Removed the changes to allow dragging&dropping bookmarks
Diffstat (limited to 'apps/web/lib/drag-and-drop.ts')
-rw-r--r--apps/web/lib/drag-and-drop.ts55
1 files changed, 38 insertions, 17 deletions
diff --git a/apps/web/lib/drag-and-drop.ts b/apps/web/lib/drag-and-drop.ts
index e005a6d0..ec37e810 100644
--- a/apps/web/lib/drag-and-drop.ts
+++ b/apps/web/lib/drag-and-drop.ts
@@ -1,31 +1,48 @@
import React from "react";
-import { DraggableData, DraggableEvent } from "react-draggable";
+import { DraggableEvent } from "react-draggable";
+
+export interface DraggingState {
+ isDragging: boolean;
+ initialX: number;
+ initialY: number;
+}
export function useDragAndDrop(
- dragSourceIdAttribute: string,
dragTargetIdAttribute: string,
- onDragOver: (dragSourceId: string, dragTargetId: string) => void,
+ onDragOver: (dragTargetId: string) => void,
+ setDraggingState?: React.Dispatch<React.SetStateAction<DraggingState>>,
) {
- const [dragSourceId, setDragSourceId] = React.useState<string | null>(null);
+ function findTargetId(element: HTMLElement): string | null {
+ let currentElement: HTMLElement | null = element;
+ while (currentElement) {
+ const listId = currentElement.getAttribute(dragTargetIdAttribute);
+ if (listId) {
+ return listId;
+ }
+ currentElement = currentElement.parentElement;
+ }
+ return null;
+ }
const handleDragStart = React.useCallback(
- (_e: DraggableEvent, { node }: DraggableData) => {
- const id = node.getAttribute(dragSourceIdAttribute);
- setDragSourceId(id);
+ (e: DraggableEvent) => {
+ const rect = (e.target as HTMLElement).getBoundingClientRect();
+ setDraggingState?.({
+ isDragging: true,
+ initialX: rect.x,
+ initialY: rect.y,
+ });
},
- [],
+ [setDraggingState],
);
const handleDragEnd = React.useCallback(
(e: DraggableEvent) => {
const { target } = e;
- const dragTargetId = (target as HTMLElement).getAttribute(
- dragTargetIdAttribute,
- );
+ const dragTargetId = findTargetId(target as HTMLElement);
- if (dragSourceId && dragTargetId && dragSourceId !== dragTargetId) {
- /*
- As Draggable tries to setState when the
+ if (dragTargetId) {
+ /* As Draggable tries to setState when the
component is unmounted, it is needed to
push onCombine to the event loop queue.
onCombine would be run after setState on
@@ -33,12 +50,16 @@ export function useDragAndDrop(
they fix it on their end.
*/
setTimeout(() => {
- onDragOver(dragSourceId, dragTargetId);
+ onDragOver(dragTargetId);
}, 0);
}
- setDragSourceId(null);
+ setDraggingState?.({
+ isDragging: false,
+ initialX: 0,
+ initialY: 0,
+ });
},
- [dragSourceId, onDragOver],
+ [onDragOver],
);
return {