File

A file component lets users drag and drop files or click to open a file picker for uploading.

Component preview

01_album_cover.jpg01_album_cover.jpg02_single_cover.jpg03_album_cover.jpg04_next_cover.jpg
import * as UI from "@iyk/ui"

export default () => (
  <form method="POST" className="w-full max-w-[330px] grid gap-8">
    <UI.Field name="single-photo">
      <UI.Label>Single Photo</UI.Label>

      <UI.File
        defaultValue={JSON.stringify({
          url: "https://placehold.co/64x64?text=01",
          name: "01_album_cover.jpg",
          mimeType: "image/jpeg",
        })}
        handleFile={async (handler) => {
          handler.progress = 5

          await new Promise((resolve) => setTimeout(resolve, 700))

          handler.progress = 50

          await new Promise((resolve) => setTimeout(resolve, 600))

          handler.progress = 98

          await new Promise((resolve) => setTimeout(resolve, 400))

          handler.progress = 100
        }}
      />
    </UI.Field>

    <UI.Field name="photos">
      <UI.Label>Multiple Photos</UI.Label>

      <UI.File
        multiple
        sortable
        defaultValue={[
          JSON.stringify({
            url: "https://placehold.co/64x64?text=01",
            name: "01_album_cover.jpg",
            mimeType: "image/jpeg",
          }),
          JSON.stringify({
            url: "https://placehold.co/64x64?text=02",
            name: "02_single_cover.jpg",
            mimeType: "image/jpeg",
          }),
          JSON.stringify({
            url: "https://placehold.co/64x64?text=03",
            name: "03_album_cover.jpg",
            mimeType: "image/jpeg",
          }),
          JSON.stringify({
            url: "https://placehold.co/64x64?text=04",
            name: "04_next_cover.jpg",
            mimeType: "image/jpeg",
          }),
        ]}
        types={[
          {
            description: "Images",
            accept: {
              "image/avif": [".avif", ".avifs"],
              "image/jpeg": [".jpeg", ".jpg"],
              "image/png": [".png"],
              "image/gif": [".gif"],
              "image/webp": [".webp"],
            },
          },
        ]}
        handleFile={async (handler) => {
          handler.progress = 5

          await new Promise((resolve) => setTimeout(resolve, 700))

          handler.progress = 50

          await new Promise((resolve) => setTimeout(resolve, 600))

          handler.progress = 98

          await new Promise((resolve) => setTimeout(resolve, 400))

          handler.progress = 100
        }}
      />
    </UI.Field>

    <UI.Button type="submit" kind="outline" size="md">
      Update
    </UI.Button>
  </form>
)

Props

kind

"default" | "avatarCircle" | "avatarSquare"

Used to show which kind of file should render

defaultValue

string | string[] | null | undefined

The default value of the file

multiple

boolean

Allow multiple files

sortable

boolean

Allow the files to be sorted

types

FilePickerAcceptType[]

The types of files that can be uploaded

handleFile

(handler: File.Handler) => void

The function to handle the file

Kinds

import * as UI from "@iyk/ui"

export default () => (
  <form method="POST" className="w-full max-w-[330px] grid gap-8">
    <UI.Field name="avatar-circle">
      <UI.Label>Avatar (circle)</UI.Label>

      <UI.File
        kind="avatarCircle"
        handleFile={async (handler) => {
          handler.progress = 100
        }}
      />
    </UI.Field>

    <UI.Field name="avatar-rounded">
      <UI.Label>Avatar (square)</UI.Label>

      <UI.File
        kind="avatarSquare"
        handleFile={async (handler) => {
          handler.progress = 100
        }}
      />
    </UI.Field>

    <UI.Button type="submit" kind="outline" size="md">
      Update
    </UI.Button>
  </form>
)