You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

use-dsl-drag-drop.ts 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { useEffect, useState } from 'react'
  2. type DSLDragDropHookProps = {
  3. onDSLFileDropped: (file: File) => void
  4. containerRef: React.RefObject<HTMLDivElement | null>
  5. enabled?: boolean
  6. }
  7. export const useDSLDragDrop = ({ onDSLFileDropped, containerRef, enabled = true }: DSLDragDropHookProps) => {
  8. const [dragging, setDragging] = useState(false)
  9. const handleDragEnter = (e: DragEvent) => {
  10. e.preventDefault()
  11. e.stopPropagation()
  12. if (e.dataTransfer?.types.includes('Files'))
  13. setDragging(true)
  14. }
  15. const handleDragOver = (e: DragEvent) => {
  16. e.preventDefault()
  17. e.stopPropagation()
  18. }
  19. const handleDragLeave = (e: DragEvent) => {
  20. e.preventDefault()
  21. e.stopPropagation()
  22. if (e.relatedTarget === null || !containerRef.current?.contains(e.relatedTarget as Node))
  23. setDragging(false)
  24. }
  25. const handleDrop = (e: DragEvent) => {
  26. e.preventDefault()
  27. e.stopPropagation()
  28. setDragging(false)
  29. if (!e.dataTransfer)
  30. return
  31. const files = [...e.dataTransfer.files]
  32. if (files.length === 0)
  33. return
  34. const file = files[0]
  35. if (file.name.toLowerCase().endsWith('.yaml') || file.name.toLowerCase().endsWith('.yml'))
  36. onDSLFileDropped(file)
  37. }
  38. useEffect(() => {
  39. if (!enabled)
  40. return
  41. const current = containerRef.current
  42. if (current) {
  43. current.addEventListener('dragenter', handleDragEnter)
  44. current.addEventListener('dragover', handleDragOver)
  45. current.addEventListener('dragleave', handleDragLeave)
  46. current.addEventListener('drop', handleDrop)
  47. }
  48. return () => {
  49. if (current) {
  50. current.removeEventListener('dragenter', handleDragEnter)
  51. current.removeEventListener('dragover', handleDragOver)
  52. current.removeEventListener('dragleave', handleDragLeave)
  53. current.removeEventListener('drop', handleDrop)
  54. }
  55. }
  56. }, [containerRef, enabled])
  57. return {
  58. dragging: enabled ? dragging : false,
  59. }
  60. }