-
Hi guys. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 9 replies
-
The native web drop event doesn't work. But tauri has some events for file drop that you can register and listen to. Here is an example. |
Beta Was this translation helpful? Give feedback.
-
To continue this topic: I tried implementing the approach of the other answer. The workaround @abisar suggested works fine, I opted to use Registering the listener const {listen} = await import('@tauri-apps/api/event')
listen('tauri://file-drop', async event => {
await new Promise(resolve => setTimeout(resolve, 100))
if(this.shadowRoot.querySelector("form:hover")) {
console.log(event)
}
}) Value of the event {
"event": "tauri://file-drop",
"windowLabel": "main",
"payload": [
"Path\\To\\File"
],
"id": 1234
} |
Beta Was this translation helpful? Give feedback.
-
I've created something like this, to best mimic the native behaviour. It works great for me and you can easily extend it to your needs class DropEvent extends DragEvent {
offsetX: number
offsetY: number
constructor(path: string, offsetX: number, offsetY: number) {
super('drop', {
dataTransfer: new DataTransfer(),
})
this.offsetX = offsetX
this.offsetY = offsetY
this.dataTransfer?.setData('text/plain', path)
}
}
const startListeningForDragAndDropEvents = (animationsStore: AnimationsStore) => {
const appContainer = document.getElementById('app')
let draggedData: string | null = null
let dropTarget: HTMLElement | null = null
let offsetX = 0
let offsetY = 0
appContainer?.addEventListener('dragstart', e => {
draggedData = e.dataTransfer?.getData('text/plain') || null
})
appContainer?.addEventListener('dragover', e => {
offsetX = e.offsetX
offsetY = e.offsetY
})
appContainer?.addEventListener('dragenter', e => {
dropTarget = e.target as HTMLElement
})
appContainer?.addEventListener('dragend', () => {
dropTarget = null
draggedData = null
})
listen('tauri://file-drop', e => {
let filePath = draggedData || ''
if (Array.isArray(e.payload) && typeof e.payload[0] === 'string') {
filePath = e.payload[0]
}
const dropEvent = new DropEvent(filePath, offsetX, offsetY)
dropEvent.dataTransfer?.setData('text/plain', filePath)
dropTarget?.dispatchEvent(dropEvent)
dropTarget = null
draggedData = null
})
} |
Beta Was this translation helpful? Give feedback.
-
For someone who needs to detect the element, I think we can use document.elementFromPoint to identify the element under the drop. React code: import { listen } from "@tauri-apps/api/event";
import { useEffect, useRef, useState } from "react";
type TauriDragDropEvent = {
paths: string[];
position: {
x: number;
y: number;
};
};
const useDropZone = ({ onDrop }: { onDrop: (paths: string[]) => void }) => {
const ref = useRef<HTMLDivElement>(null);
const [dragIn, setDragIn] = useState(false);
useEffect(() => {
const unlisten = listen<TauriDragDropEvent>("tauri://drag-drop", (e) => {
const { x, y } = e.payload.position;
if (document.elementFromPoint(x, y) === ref.current) {
onDrop(e.payload.paths);
setDragIn(false);
}
});
return () => {
unlisten.then((unlisten) => {
unlisten();
});
};
}, [onDrop]);
useEffect(() => {
const unlisten = listen<TauriDragDropEvent>("tauri://drag-over", (e) => {
const { x, y } = e.payload.position;
if (document.elementFromPoint(x, y) === ref.current) {
setDragIn(true);
} else {
setDragIn(false);
}
});
return () => {
unlisten.then((unlisten) => {
unlisten();
});
};
}, []);
return { ref, dragIn };
};
export { useDropZone }; |
Beta Was this translation helpful? Give feedback.
The native web drop event doesn't work. But tauri has some events for file drop that you can register and listen to. Here is an example.