허용 형식
accept 기본값은 .csv,text/csv이며 확장자, MIME, image/* 패턴을 지원합니다.
선택 요약
선택한 파일 이름을 표시하고 여러 개면 첫 파일 외 개수로 요약합니다.
접근성 기준
label 역할 표면이 file input과 연결되고 키보드 Enter/Space로 파일 선택을 엽니다.

허용 형식

accept와 안내 문구
코드 보기tsx
import { FileUploadZone } from "@olundot/ui";

export function CsvUploadZone() {
  return (
    <FileUploadZone surface="canvas"
      id="student-csv"
      accept=".csv,text/csv"
      label="CSV 파일 업로드"
      hint="학생 명단 CSV만 업로드할 수 있습니다."
    />
  );
}

드래그 앤 드롭 표면

클릭과 drop을 같은 영역에서 처리
코드 보기tsx
import { FileUploadZone } from "@olundot/ui";

export function DragDropUploadZone() {
  return (
    <FileUploadZone surface="canvas"
      id="evidence-upload"
      accept=".pdf,image/*"
      multiple
      label="증빙 파일을 끌어다 놓거나 선택"
      hint="PDF 또는 이미지 파일을 여러 개 선택할 수 있습니다."
    />
  );
}

선택된 파일 이름

onFiles와 파일명 요약

선택된 파일 없음

코드 보기tsx
import { useState } from "react";
import { FileUploadZone } from "@olundot/ui";

function summarizeFiles(files: FileList) {
  const names = Array.from(files).map((file) => file.name);

  if (names.length === 0) return "선택된 파일 없음";
  if (names.length === 1) return names[0];
  return `${names[0]} 외 ${names.length - 1}개`;
}

export function SelectedFileNames() {
  const [summary, setSummary] = useState("선택된 파일 없음");

  return (
    <div className="grid gap-2">
      <FileUploadZone surface="canvas"
        id="answer-upload"
        accept=".csv,text/csv"
        multiple
        label="채점 파일 선택"
        hint="선택한 파일 이름은 업로드 영역과 상태 문구에 표시됩니다."
        onFiles={(files) => setSummary(summarizeFiles(files))}
      />
      <p role="status" className="text-sm text-text-secondary">{summary}</p>
    </div>
  );
}

비활성 및 오류

disabled와 error 메시지
코드 보기tsx
import { FileUploadZone } from "@olundot/ui";

export function DisabledAndErrorUploadZone() {
  return (
    <div className="grid gap-4">
      <FileUploadZone surface="canvas"
        id="invalid-upload"
        accept=".csv,text/csv"
        label="CSV 다시 선택"
        hint="헤더는 학번, 이름, 이메일 순서입니다."
        error="CSV 형식이 아니어서 업로드할 수 없습니다."
      />
      <FileUploadZone surface="canvas"
        id="locked-upload"
        label="업로드 잠김"
        hint="제출 기간이 끝난 뒤에는 파일을 바꿀 수 없습니다."
        disabled
      />
    </div>
  );
}