Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(useDropZone): new function (#1610)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
- Loading branch information
Showing
4 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { useDropZone } from '@vueuse/core' | ||
const filesData = ref<{ name: string; size: number; type: string; lastModified: number }[]>([]) | ||
function onDrop(files: File[] | null) { | ||
filesData.value = [] | ||
if (files) { | ||
filesData.value = files.map(file => ({ | ||
name: file.name, | ||
size: file.size, | ||
type: file.type, | ||
lastModified: file.lastModified, | ||
})) | ||
} | ||
} | ||
const dropZoneRef = ref<HTMLElement | null>(null) | ||
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop) | ||
</script> | ||
|
||
<template> | ||
<div class="flex"> | ||
<div class="w-full h-auto relative"> | ||
<p>Drop files into dropZone</p> | ||
<img src="/favicon.ico" alt="Drop me"> | ||
|
||
<div ref="dropZoneRef" class="flex flex-col w-full min-h-200px h-auto bg-gray-400/10 justify-center items-center mt-6"> | ||
<div> isOverDropZone: <BooleanDisplay :value="isOverDropZone" /></div> | ||
<div class="flex flex-wrap justify-center items-center"> | ||
<div v-for="(file, index) in filesData" :key="index" class="w-200px bg-black-200/10 ma-2 pa-6"> | ||
<p>Name: {{ file.name }}</p> | ||
<p>Size: {{ file.size }}</p> | ||
<p>Type: {{ file.type }}</p> | ||
<p>Last modified: {{ file.lastModified }}</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--- | ||
category: Elements | ||
--- | ||
|
||
# useDropZone | ||
|
||
Create an zone where files can be dropped. | ||
|
||
## Usage | ||
|
||
```html | ||
<script setup lang="ts"> | ||
import { useDropZone } from '@vueuse/core' | ||
const dropZoneRef = ref(null) | ||
function onDrop(dropZoneRef, files: File[] | null) { | ||
// Trigger an event when file(s) is drop on zone | ||
} | ||
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop) | ||
</script> | ||
|
||
<template> | ||
<div ref="dropZoneRef"> | ||
Drop files here | ||
</div> | ||
</template> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { ref } from 'vue-demi' | ||
import type { Ref } from 'vue-demi' | ||
import type { MaybeRef } from '@vueuse/shared' | ||
import { isClient } from '@vueuse/shared' | ||
import { useEventListener } from '../useEventListener' | ||
|
||
export interface UseDropZoneReturn { | ||
isOverDropZone: Ref<boolean> | ||
} | ||
|
||
export function useDropZone(target: MaybeRef<HTMLElement | null>, onDrop: (files: File[] | null) => void): UseDropZoneReturn { | ||
const isOverDropZone = ref(false) | ||
let counter = 0 | ||
|
||
if (isClient) { | ||
useEventListener<DragEvent>(target, 'dragenter', (event) => { | ||
event.preventDefault() | ||
counter += 1 | ||
isOverDropZone.value = true | ||
}) | ||
useEventListener<DragEvent>(target, 'dragover', (event) => { | ||
event.preventDefault() | ||
}) | ||
useEventListener<DragEvent>(target, 'dragleave', (event) => { | ||
event.preventDefault() | ||
counter -= 1 | ||
if (counter === 0) | ||
isOverDropZone.value = false | ||
}) | ||
useEventListener<DragEvent>(target, 'drop', (event) => { | ||
event.preventDefault() | ||
counter = 0 | ||
isOverDropZone.value = false | ||
const files = Array.from(event.dataTransfer?.files ?? []) | ||
if (files.length === 0) { | ||
onDrop(null) | ||
return | ||
} | ||
onDrop(files) | ||
}) | ||
} | ||
|
||
return { | ||
isOverDropZone, | ||
} | ||
} |