diff --git a/packages/core/useDropZone/index.ts b/packages/core/useDropZone/index.ts index 7135cccfd44..d8b09d1aba0 100644 --- a/packages/core/useDropZone/index.ts +++ b/packages/core/useDropZone/index.ts @@ -34,12 +34,56 @@ export function useDropZone( let isDataTypeIncluded = true if (isClient) { const _options = typeof options === 'function' ? { onDrop: options } : options - const getFiles = (event: DragEvent) => { - const list = Array.from(event.dataTransfer?.files ?? []) - return (files.value = list.length === 0 ? null : list) + const getFiles = async (event: DragEvent): Promise => { + return new Promise((resolve) => { + const dataTransfer = event.dataTransfer! + const items = dataTransfer.items + let list: File[] = [] + if (items[0].type === 'text/plain' || !window.webkitURL) { + list = Array.from(event.dataTransfer?.files ?? []) + resolve(list) + } + else { + const u = items.length + let k = 0 + const returnResolve = () => { + if (k === u) + resolve(list) + } + for (let i = 0; i < items.length; i++) { + const item = items[i] + const ItemEntry = item.webkitGetAsEntry()! + if (ItemEntry.isFile) { + const fileEntry = ItemEntry as FileSystemFileEntry + fileEntry.file((file) => { + list.push(file) + k = k + 1 + returnResolve() + }) + } + if (ItemEntry.isDirectory) { + const directoryEntry = ItemEntry as FileSystemDirectoryEntry + const reader = directoryEntry.createReader() + reader.readEntries((entries) => { + for (let i = 0; i < entries.length; i++) { + const entry = entries[i] as FileSystemFileEntry + if (entry.isFile) { + entry.file((file) => { + list.push(file) + if (i === entries.length - 1) + k = k + 1 + returnResolve() + }) + } + } + }) + } + } + } + }) } - useEventListener(target, 'dragenter', (event) => { + useEventListener(target, 'dragenter', async (event) => { const types = Array.from(event?.dataTransfer?.items || []) .map(i => i.kind === 'file' ? i.type : null) .filter(notNullish) @@ -57,28 +101,32 @@ export function useDropZone( event.preventDefault() counter += 1 isOverDropZone.value = true - _options.onEnter?.(getFiles(event), event) + const files = await getFiles(event) as File[] + _options.onDrop?.(files, event) }) - useEventListener(target, 'dragover', (event) => { + useEventListener(target, 'dragover', async (event) => { if (!isDataTypeIncluded) return event.preventDefault() - _options.onOver?.(getFiles(event), event) + const files = await getFiles(event) as File[] + _options.onDrop?.(files, event) }) - useEventListener(target, 'dragleave', (event) => { + useEventListener(target, 'dragleave', async (event) => { if (!isDataTypeIncluded) return event.preventDefault() counter -= 1 if (counter === 0) isOverDropZone.value = false - _options.onLeave?.(getFiles(event), event) + const files = await getFiles(event) as File[] + _options.onDrop?.(files, event) }) - useEventListener(target, 'drop', (event) => { + useEventListener(target, 'drop', async (event) => { event.preventDefault() counter = 0 isOverDropZone.value = false - _options.onDrop?.(getFiles(event), event) + const files = await getFiles(event) as File[] + _options.onDrop?.(files, event) }) }