File Drop

A drop zone around a real file input — rejections are reported, never silent.

Installation

bun add elia
@import "tailwindcss";
@import "@aile.sh/elia/styles/elia.css";
@source "../node_modules/@aile.sh/elia";

Usage

import { useState } from "react";
import { FileDrop, formatBytes } from "@aile.sh/elia";

export function Example() {
  const [files, setFiles] = useState<File[]>([]);
  const [rejected, setRejected] = useState<string[]>([]);

  return (
    <div className="w-full max-w-md">
      <FileDrop
        multiple
        accept=".jsonl,.csv"
        maxSize={5 * 1024 * 1024}
        onFiles={(next) => setFiles(next)}
        onReject={(next) => setRejected(next.map((r) => `${r.file.name} (${r.reason})`))}
        label="Drop a training set"
      />
      {files.length > 0 && (
        <ul className="mt-2 flex flex-col gap-1">
          {files.map((file) => (
            <li key={file.name} className="flex justify-between text-[11.5px] text-ink-2">
              <span className="truncate">{file.name}</span>
              <span className="font-mono tabular-nums text-ink-3">{formatBytes(file.size)}</span>
            </li>
          ))}
        </ul>
      )}
      {rejected.length > 0 && (
        <p className="mt-2 text-[11.5px] text-red">Rejected: {rejected.join(", ")}</p>
      )}
    </div>
  );
}

— elia design system · MIT · base · https://github.com/aile-sh/elia