From d64070e8a0c8812f8ddea75f2f51c7df601d6f40 Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Tue, 31 May 2022 14:34:09 +0200 Subject: [PATCH] feat(useDropZone): new function (#1610) Co-authored-by: Anthony Fu --- packages/core/index.ts | 1 + packages/core/useDropZone/demo.vue | 42 +++++++++++++++++++++++++++ packages/core/useDropZone/index.md | 29 +++++++++++++++++++ packages/core/useDropZone/index.ts | 46 ++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 packages/core/useDropZone/demo.vue create mode 100644 packages/core/useDropZone/index.md create mode 100644 packages/core/useDropZone/index.ts diff --git a/packages/core/index.ts b/packages/core/index.ts index fb34dc83890..5707de41c3b 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -32,6 +32,7 @@ export * from './useDevicesList' export * from './useDisplayMedia' export * from './useDocumentVisibility' export * from './useDraggable' +export * from './useDropZone' export * from './useElementBounding' export * from './useElementByPoint' export * from './useElementHover' diff --git a/packages/core/useDropZone/demo.vue b/packages/core/useDropZone/demo.vue new file mode 100644 index 00000000000..e694c34638c --- /dev/null +++ b/packages/core/useDropZone/demo.vue @@ -0,0 +1,42 @@ + + + diff --git a/packages/core/useDropZone/index.md b/packages/core/useDropZone/index.md new file mode 100644 index 00000000000..7795a58a1d5 --- /dev/null +++ b/packages/core/useDropZone/index.md @@ -0,0 +1,29 @@ +--- +category: Elements +--- + +# useDropZone + +Create an zone where files can be dropped. + +## Usage + +```html + + + +``` diff --git a/packages/core/useDropZone/index.ts b/packages/core/useDropZone/index.ts new file mode 100644 index 00000000000..219a9f14d99 --- /dev/null +++ b/packages/core/useDropZone/index.ts @@ -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 +} + +export function useDropZone(target: MaybeRef, onDrop: (files: File[] | null) => void): UseDropZoneReturn { + const isOverDropZone = ref(false) + let counter = 0 + + if (isClient) { + useEventListener(target, 'dragenter', (event) => { + event.preventDefault() + counter += 1 + isOverDropZone.value = true + }) + useEventListener(target, 'dragover', (event) => { + event.preventDefault() + }) + useEventListener(target, 'dragleave', (event) => { + event.preventDefault() + counter -= 1 + if (counter === 0) + isOverDropZone.value = false + }) + useEventListener(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, + } +}