⬅️ Back to Table of Contents
📄 index.ts
📊 Analysis Summary
Metric |
Count |
🔧 Functions |
6 |
📦 Imports |
7 |
📊 Variables & Constants |
7 |
📐 Interfaces |
2 |
📚 Table of Contents
🛠️ File Location:
📂 packages/core/useDropZone/index.ts
📦 Imports
Name |
Source |
MaybeRef |
vue |
MaybeRefOrGetter |
vue |
ShallowRef |
vue |
isClient |
@vueuse/shared |
shallowRef |
vue |
unref |
vue |
useEventListener |
../useEventListener |
Variables & Constants
Name |
Type |
Kind |
Value |
Exported |
counter |
number |
let/var |
0 |
✗ |
isValid |
boolean |
let/var |
true |
✗ |
_options |
UseDropZoneOptions |
const |
typeof options === 'function' ? { onDrop: options } : options |
✗ |
multiple |
boolean |
const |
_options.multiple ?? true |
✗ |
preventDefaultForUnhandled |
boolean |
const |
_options.preventDefaultForUnhandled ?? false |
✗ |
multipleFilesValid |
boolean |
const |
multiple || items.length <= 1 |
✗ |
dataTransferItemList |
DataTransferItemList |
const |
event.dataTransfer?.items |
✗ |
Functions
useDropZone(target: MaybeRefOrGetter<HTMLElement | Document | null | undefined>, options: UseDropZoneOptions | UseDropZoneOptions['onDrop']): UseDropZoneReturn
Code
export function useDropZone(
target: MaybeRefOrGetter<HTMLElement | Document | null | undefined>,
options: UseDropZoneOptions | UseDropZoneOptions['onDrop'] = {},
): UseDropZoneReturn {
const isOverDropZone = shallowRef(false)
const files = shallowRef<File[] | null>(null)
let counter = 0
let isValid = true
if (isClient) {
const _options = typeof options === 'function' ? { onDrop: options } : options
const multiple = _options.multiple ?? true
const preventDefaultForUnhandled = _options.preventDefaultForUnhandled ?? false
const getFiles = (event: DragEvent) => {
const list = Array.from(event.dataTransfer?.files ?? [])
return list.length === 0 ? null : (multiple ? list : [list[0]])
}
const checkDataTypes = (types: string[]) => {
const dataTypes = unref(_options.dataTypes)
if (typeof dataTypes === 'function')
return dataTypes(types)
if (!dataTypes?.length)
return true
if (types.length === 0)
return false
return types.every(type =>
dataTypes.some(allowedType => type.includes(allowedType)),
)
}
const checkValidity = (items: DataTransferItemList) => {
const types = Array.from(items ?? []).map(item => item.type)
const dataTypesValid = checkDataTypes(types)
const multipleFilesValid = multiple || items.length <= 1
return dataTypesValid && multipleFilesValid
}
const isSafari = () => (
/^(?:(?!chrome|android).)*safari/i.test(navigator.userAgent)
&& !('chrome' in window)
)
const handleDragEvent = (event: DragEvent, eventType: 'enter' | 'over' | 'leave' | 'drop') => {
const dataTransferItemList = event.dataTransfer?.items
isValid = (dataTransferItemList && checkValidity(dataTransferItemList)) ?? false
if (preventDefaultForUnhandled) {
event.preventDefault()
}
if (!isSafari() && !isValid) {
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'none'
}
return
}
event.preventDefault()
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'copy'
}
const currentFiles = getFiles(event)
switch (eventType) {
case 'enter':
counter += 1
isOverDropZone.value = true
_options.onEnter?.(null, event)
break
case 'over':
_options.onOver?.(null, event)
break
case 'leave':
counter -= 1
if (counter === 0)
isOverDropZone.value = false
_options.onLeave?.(null, event)
break
case 'drop':
counter = 0
isOverDropZone.value = false
if (isValid) {
files.value = currentFiles
_options.onDrop?.(currentFiles, event)
}
break
}
}
useEventListener<DragEvent>(target, 'dragenter', event => handleDragEvent(event, 'enter'))
useEventListener<DragEvent>(target, 'dragover', event => handleDragEvent(event, 'over'))
useEventListener<DragEvent>(target, 'dragleave', event => handleDragEvent(event, 'leave'))
useEventListener<DragEvent>(target, 'drop', event => handleDragEvent(event, 'drop'))
}
return {
files,
isOverDropZone,
}
}
- Parameters:
target: MaybeRefOrGetter<HTMLElement | Document | null | undefined>
options: UseDropZoneOptions | UseDropZoneOptions['onDrop']
- Return Type:
UseDropZoneReturn
- Calls:
shallowRef (from vue)
Array.from
unref (from vue)
dataTypes
types.every
dataTypes.some
type.includes
Array.from(items ?? []).map
checkDataTypes
/^(?:(?!chrome|android).)*safari/i.test
checkValidity
event.preventDefault
isSafari
getFiles
_options.onEnter
_options.onOver
_options.onLeave
_options.onDrop
useEventListener (from ../useEventListener)
handleDragEvent
getFiles(event: DragEvent): File[]
Code
(event: DragEvent) => {
const list = Array.from(event.dataTransfer?.files ?? [])
return list.length === 0 ? null : (multiple ? list : [list[0]])
}
- Parameters:
event: DragEvent
- Return Type:
File[]
- Calls:
Array.from
checkDataTypes(types: string[]): any
Code
(types: string[]) => {
const dataTypes = unref(_options.dataTypes)
if (typeof dataTypes === 'function')
return dataTypes(types)
if (!dataTypes?.length)
return true
if (types.length === 0)
return false
return types.every(type =>
dataTypes.some(allowedType => type.includes(allowedType)),
)
}
- Parameters:
types: string[]
- Return Type:
any
- Calls:
unref (from vue)
dataTypes
types.every
dataTypes.some
type.includes
checkValidity(items: DataTransferItemList): boolean
Code
(items: DataTransferItemList) => {
const types = Array.from(items ?? []).map(item => item.type)
const dataTypesValid = checkDataTypes(types)
const multipleFilesValid = multiple || items.length <= 1
return dataTypesValid && multipleFilesValid
}
- Parameters:
items: DataTransferItemList
- Return Type:
boolean
- Calls:
Array.from(items ?? []).map
checkDataTypes
isSafari(): boolean
Code
() => (
/^(?:(?!chrome|android).)*safari/i.test(navigator.userAgent)
&& !('chrome' in window)
)
handleDragEvent(event: DragEvent, eventType: 'enter' | 'over' | 'leave' | 'drop'): void
Code
(event: DragEvent, eventType: 'enter' | 'over' | 'leave' | 'drop') => {
const dataTransferItemList = event.dataTransfer?.items
isValid = (dataTransferItemList && checkValidity(dataTransferItemList)) ?? false
if (preventDefaultForUnhandled) {
event.preventDefault()
}
if (!isSafari() && !isValid) {
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'none'
}
return
}
event.preventDefault()
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'copy'
}
const currentFiles = getFiles(event)
switch (eventType) {
case 'enter':
counter += 1
isOverDropZone.value = true
_options.onEnter?.(null, event)
break
case 'over':
_options.onOver?.(null, event)
break
case 'leave':
counter -= 1
if (counter === 0)
isOverDropZone.value = false
_options.onLeave?.(null, event)
break
case 'drop':
counter = 0
isOverDropZone.value = false
if (isValid) {
files.value = currentFiles
_options.onDrop?.(currentFiles, event)
}
break
}
}
- Parameters:
event: DragEvent
eventType: 'enter' | 'over' | 'leave' | 'drop'
- Return Type:
void
- Calls:
checkValidity
event.preventDefault
isSafari
getFiles
_options.onEnter
_options.onOver
_options.onLeave
_options.onDrop
Interfaces
UseDropZoneReturn
Interface Code
export interface UseDropZoneReturn {
files: ShallowRef<File[] | null>
isOverDropZone: ShallowRef<boolean>
}
Properties
Name |
Type |
Optional |
Description |
files |
ShallowRef<File[] | null> |
✗ |
|
isOverDropZone |
ShallowRef<boolean> |
✗ |
|
UseDropZoneOptions
Interface Code
export interface UseDropZoneOptions {
/**
* Allowed data types, if not set, all data types are allowed.
* Also can be a function to check the data types.
*/
dataTypes?: MaybeRef<readonly string[]> | ((types: readonly string[]) => boolean)
onDrop?: (files: File[] | null, event: DragEvent) => void
onEnter?: (files: File[] | null, event: DragEvent) => void
onLeave?: (files: File[] | null, event: DragEvent) => void
onOver?: (files: File[] | null, event: DragEvent) => void
/**
* Allow multiple files to be dropped. Defaults to true.
*/
multiple?: boolean
/**
* Prevent default behavior for unhandled events. Defaults to false.
*/
preventDefaultForUnhandled?: boolean
}
Properties
Name |
Type |
Optional |
Description |
dataTypes |
MaybeRef<readonly string[]> | ((types: readonly string[]) => boolean) |
✓ |
|
onDrop |
(files: File[] | null, event: DragEvent) => void |
✓ |
|
onEnter |
(files: File[] | null, event: DragEvent) => void |
✓ |
|
onLeave |
(files: File[] | null, event: DragEvent) => void |
✓ |
|
onOver |
(files: File[] | null, event: DragEvent) => void |
✓ |
|
multiple |
boolean |
✓ |
|
preventDefaultForUnhandled |
boolean |
✓ |
|