saas-js/saas-ui

FileUpload component: Clear button doesn't actually clear.

jleuth opened this issue · 2 comments

jleuth commented

Hello, i have found that in the FileUpload component, the clear button doesn't actually clear the file, even though it doesn't show the filename.

Here, you'll see that i have uploaded a file:
image

But when I click clear, and click submit again, you'll see that it doesn't really clear, and still uploads the same file.
image

Once you click clear, my API its fetching should be saying "No file provided", but its not because the clear function only clears the file from the component visually.

Assuming you use the Forms example from the docs, I notice there's a mistake in the example.

onFilesChange={(files) => {
          if (files.acceptedFiles?.length) {
            onChange(files.acceptedFiles[0])
          }
}}

This only updates when there are files, but onChange should also be called with all files are removed.

Also misses a check on data.file and it throws an error when no file is selected.

Full working example:

import { Text, HStack } from '@chakra-ui/react'
import {
  FileUpload,
  FileUploadTrigger,
  FileUploadDropzone,
} from '@saas-ui/file-upload'
import { Form, FormLayout, createField } from '@saas-ui/forms'

const UploadField = createField(
  forwardRef((props, ref) => {
    const { onChange, ...rest } = props
    return (
      <FileUpload
        /* Remove `getRootNode` in your code, only required for this example */
        getRootNode={getRootNode}
        maxFileSize={1024 * 1024}
        accept="image/*"
        {...rest}
        onFilesChange={(files) => {
          onChange(files.acceptedFiles[0])
        }}
        maxFiles={1}
        inputRef={ref}
      >
        {({ files, deleteFile }) => (
          <FileUploadDropzone>
            <Text fontSize="sm">Drag your image here</Text>
            {!files?.length ? (
              <FileUploadTrigger as={Button}>Select files</FileUploadTrigger>
            ) : (
              <HStack>
                <Text fontSize="sm">{files[0].name}</Text>
                <Button
                  onClick={(e) => {
                    e.stopPropagation()
                    deleteFile(files[0])
                  }}
                >
                  Clear
                </Button>
              </HStack>
            )}
          </FileUploadDropzone>
        )}
      </FileUpload>
    )
  }),
  {
    isControlled: true,
  }
)

export default function FormField() {
  return (
    <Form
      onSubmit={async (data) => {
        const formData = new FormData()

        if (data.file) {
          formData.append('profilePicture', data.file)
          formData.append(
            'meta',
            JSON.stringify({
              filename: data.file.name,
              size: data.file.size,
              type: data.file.type,
            })
          )
          formData.append('name', data.name)
        }
        formData.append('name', data.name)

        return fetch('/api/user', {
          method: 'POST',
          body: formData,
        }).then((response) => {
          if (response.ok) {
            // Handle successful upload
          } else {
            // Handle error
          }
        })
      }}
    >
      {({ Field }) => (
        <FormLayout>
          <Field name="name" label="Your name" />
          <UploadField name="file" label="Profile picture" />
          <SubmitButton />
        </FormLayout>
      )}
    </Form>
  )
}