useCsvFileDrop.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { type ImportDataFileAddedEvent } from 'common/telemetry-constants'
  2. import { useCallback, useState, type DragEvent } from 'react'
  3. import { flagInvalidFileImport } from '@/components/interfaces/TableGridEditor/SidePanelEditor/SpreadsheetImport/SpreadsheetImport.utils'
  4. interface UseCsvFileDropOptions {
  5. enabled: boolean
  6. onFileDropped: (file: File) => void
  7. onTelemetryEvent?: (eventName: ImportDataFileAddedEvent['action']) => void
  8. }
  9. interface UseCsvFileDropReturn {
  10. isDraggedOver: boolean
  11. onDragOver: (event: DragEvent<HTMLDivElement>) => void
  12. onFileDrop: (event: DragEvent<HTMLDivElement>) => void
  13. }
  14. export function useCsvFileDrop({
  15. enabled,
  16. onFileDropped,
  17. onTelemetryEvent,
  18. }: UseCsvFileDropOptions): UseCsvFileDropReturn {
  19. const [isDraggedOver, setIsDraggedOver] = useState(false)
  20. const onDragOver = useCallback(
  21. (event: DragEvent<HTMLDivElement>) => {
  22. if (!enabled) return
  23. const [item] = event.dataTransfer.items
  24. // ignore non files drop, like column headers
  25. if (item && item.kind !== 'file') return
  26. if (event.type === 'dragover' && !isDraggedOver) {
  27. setIsDraggedOver(true)
  28. } else if (event.type === 'dragleave' || event.type === 'drop') {
  29. setIsDraggedOver(false)
  30. }
  31. event.stopPropagation()
  32. event.preventDefault()
  33. },
  34. [enabled, isDraggedOver]
  35. )
  36. const onFileDrop = useCallback(
  37. (event: DragEvent<HTMLDivElement>) => {
  38. if (!enabled) return
  39. onDragOver(event)
  40. const [file] = event.dataTransfer.files
  41. const [item] = event.dataTransfer.items
  42. // ignore non files drop, like column headers
  43. if (item && item.kind !== 'file') return
  44. if (flagInvalidFileImport(file)) return
  45. onFileDropped(file)
  46. onTelemetryEvent?.('import_data_dropzone_file_added')
  47. },
  48. [enabled, onDragOver, onFileDropped, onTelemetryEvent]
  49. )
  50. return {
  51. isDraggedOver,
  52. onDragOver,
  53. onFileDrop,
  54. }
  55. }