{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "useDrop", "title": "useDrop", "description": "useDrop hook", "registryDependencies": [ "https://shadcn-ahooks.vercel.app/r/useLatest.json", "https://shadcn-ahooks.vercel.app/r/utils.json" ], "files": [ { "path": "packages/hooks/src/useDrop/index.ts", "content": "import useLatest from '../useLatest';\nimport type { BasicTarget } from '../utils/domTarget';\nimport { getTargetElement } from '../utils/domTarget';\nimport useEffectWithTarget from '../utils/useEffectWithTarget';\nimport { useRef } from 'react';\n\nexport interface Options {\n onFiles?: (files: File[], event?: React.DragEvent) => void;\n onUri?: (url: string, event?: React.DragEvent) => void;\n onDom?: (content: any, event?: React.DragEvent) => void;\n onText?: (text: string, event?: React.ClipboardEvent) => void;\n onDragEnter?: (event?: React.DragEvent) => void;\n onDragOver?: (event?: React.DragEvent) => void;\n onDragLeave?: (event?: React.DragEvent) => void;\n onDrop?: (event?: React.DragEvent) => void;\n onPaste?: (event?: React.ClipboardEvent) => void;\n}\n\nconst useDrop = (target: BasicTarget, options: Options = {}) => {\n const optionsRef = useLatest(options);\n\n // https://stackoverflow.com/a/26459269\n const dragEnterTarget = useRef(undefined);\n\n useEffectWithTarget(\n () => {\n const targetElement = getTargetElement(target);\n if (!targetElement?.addEventListener) {\n return;\n }\n\n const onData = (\n dataTransfer: DataTransfer,\n event: React.DragEvent | React.ClipboardEvent,\n ) => {\n const uri = dataTransfer.getData('text/uri-list');\n const dom = dataTransfer.getData('custom');\n\n if (dom && optionsRef.current.onDom) {\n let data = dom;\n try {\n data = JSON.parse(dom);\n } catch {\n data = dom;\n }\n optionsRef.current.onDom(data, event as React.DragEvent);\n return;\n }\n\n if (uri && optionsRef.current.onUri) {\n optionsRef.current.onUri(uri, event as React.DragEvent);\n return;\n }\n\n if (dataTransfer.files && dataTransfer.files.length && optionsRef.current.onFiles) {\n optionsRef.current.onFiles(Array.from(dataTransfer.files), event as React.DragEvent);\n return;\n }\n\n if (dataTransfer.items && dataTransfer.items.length && optionsRef.current.onText) {\n dataTransfer.items[0].getAsString((text) => {\n optionsRef.current.onText!(text, event as React.ClipboardEvent);\n });\n }\n };\n\n const onDragEnter = (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n dragEnterTarget.current = event.target;\n optionsRef.current.onDragEnter?.(event);\n };\n\n const onDragOver = (event: React.DragEvent) => {\n event.preventDefault();\n optionsRef.current.onDragOver?.(event);\n };\n\n const onDragLeave = (event: React.DragEvent) => {\n if (event.target === dragEnterTarget.current) {\n optionsRef.current.onDragLeave?.(event);\n }\n };\n\n const onDrop = (event: React.DragEvent) => {\n event.preventDefault();\n onData(event.dataTransfer, event);\n optionsRef.current.onDrop?.(event);\n };\n\n const onPaste = (event: React.ClipboardEvent) => {\n onData(event.clipboardData, event);\n optionsRef.current.onPaste?.(event);\n };\n\n targetElement.addEventListener('dragenter', onDragEnter as any);\n targetElement.addEventListener('dragover', onDragOver as any);\n targetElement.addEventListener('dragleave', onDragLeave as any);\n targetElement.addEventListener('drop', onDrop as any);\n targetElement.addEventListener('paste', onPaste as any);\n\n return () => {\n targetElement.removeEventListener('dragenter', onDragEnter as any);\n targetElement.removeEventListener('dragover', onDragOver as any);\n targetElement.removeEventListener('dragleave', onDragLeave as any);\n targetElement.removeEventListener('drop', onDrop as any);\n targetElement.removeEventListener('paste', onPaste as any);\n };\n },\n [],\n target,\n );\n};\n\nexport default useDrop;\n", "type": "registry:file", "target": "src/hooks/ahooks/useDrop/index.ts" } ], "type": "registry:hook" }