HextaUI

File input (UI SDK): Invalid

invalid marks the drop zone and the trigger, and the trigger tells screen readers. Point the trigger’s aria-describedby at your message.

Proof of address

A utility bill or bank statement from the last 3 months.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  FileInput,
  FileInputDropzone,
  FileInputDropzoneDescription,
  FileInputDropzoneTitle,
  FileInputItem,
  FileInputList,
  FileInputTrigger,
} from "@/components/ui/ui-sdk-file-input"

function UiSdkFileInputInvalid() {
  const [invalid, setInvalid] = React.useState(false)
  const errorId = React.useId()

  return (
    <form
      noValidate
      className="flex w-full max-w-md flex-col gap-3"
      onSubmit={(event) => {
        event.preventDefault()
        const data = new FormData(event.currentTarget)
        const proof = data.get("proof")
        setInvalid(!(proof instanceof File && proof.name))
      }}
    >
      <FileInput
        name="proof"
        accept={["image/*", ".pdf"]}
        invalid={invalid}
        onValueChange={(value) => {
          if (value.length) setInvalid(false)
        }}
      >
        <FileInputDropzone className="min-h-32">
          <FileInputDropzoneTitle>Proof of address</FileInputDropzoneTitle>
          <FileInputDropzoneDescription>
            A utility bill or bank statement from the last 3 months.
          </FileInputDropzoneDescription>
          <FileInputTrigger
            className="mt-3"
            aria-describedby={invalid ? errorId : undefined}
          >
            Choose a file
          </FileInputTrigger>
        </FileInputDropzone>
        {invalid ? (
          <p id={errorId} className="m-0 text-sm text-destructive">
            Add a scan to continue.
          </p>
        ) : null}
        <FileInputList aria-label="Proof of address">
          <FileInputItem />
        </FileInputList>
      </FileInput>
      <Button type="submit" size="sm" className="self-start">
        Continue
      </Button>
    </form>
  )
}

export { UiSdkFileInputInvalid }

This adds the example as components/examples/ui-sdk-file-input/invalid.tsx, together with the File input component and the HextaUI theme tokens it needs.

pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-file-input-invalid.json

To add only the component, follow the File input installation.

Props in this example

The File input props this example sets, from the API reference.

PropTypeDefault
onValueChangedetails has the reason and the added, removed and rejected files.
(value: File[], details) => void–
accept
string | string[]–
invalid
booleanfalse
name
string–

Every prop is in the File input API reference.

See them all, with keyboard support and accessibility notes, on the File input page.