@olundot/ui · Inputs
FileUploadZone
파일 선택과 드래그 앤 드롭을 하나의 접근 가능한 업로드 표면으로 제공하는 입력 컴포넌트입니다.
- 허용 형식
- 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>
);
}