cloudscape-design / components

React components for Cloudscape Design System
https://cloudscape.design/
Apache License 2.0
2.3k stars 140 forks source link

[Feature Request]: Paste to upload file #2432

Closed rinkaaan closed 5 days ago

rinkaaan commented 5 days ago

Description

Support pasting from clipboard to upload a file in: https://cloudscape.design/components/file-upload/?tabId=playground&example=multiple-files-upload

Code of Conduct

rinkaaan commented 5 days ago

Nvm, got it working with this react hook:

import { useEffect, useCallback, useState } from "react"

interface UsePasteUploadOptions {
  callback: (file: File) => void
  isActive?: boolean
}

export default function usePasteUpload({ callback, isActive = true }: UsePasteUploadOptions) {
  const [lastPastedFile, setLastPastedFile] = useState<File | null>(null)

  const handlePaste = useCallback((event: ClipboardEvent) => {
    const items = event.clipboardData?.items
    if (!items) return

    for (let i = 0; i < items.length; i++) {
      if (["image", "video"].some(type => items[i].type.includes(type))) {
        const file = items[i].getAsFile()
        if (file) {
          setLastPastedFile(file)
          callback(file)
        }
        break
      }
    }
  }, [callback])

  useEffect(() => {
    if (isActive) {
      document.addEventListener("paste", handlePaste)
      return () => document.removeEventListener("paste", handlePaste)
    }
  }, [isActive, handlePaste])

  return lastPastedFile
}
rinkaaan commented 5 days ago

It's working but for some reason files added to the state via my paste hook don't have gap with other files. I'm guessing there's some internal file tracking being done by the file upload component?

It's only happening on macOS Safari.

image
rinkaaan commented 5 days ago

Seems like this is unrelated to paste to upload, will open separate issue.