AIFT Design
Components

FileUploader

클릭·드래그 앤 드롭으로 파일을 선택하는 업로드 드롭존(단일·다중 선택)

FileUploader는 파일 아이콘과 안내 문구를 보여 주는 드롭존 UI입니다. 영역을 클릭하면 파일 선택 창이 열리고, 파일을 끌어다 놓으면(drop) 동일하게 선택됩니다. 드래그 중에는 테두리가 강조됩니다.

FileUploaderItem과 함께 쓰면 선택된 파일을 리스트로 보여 주는 패턴을 구성할 수 있습니다.

기본 사용법

파일을 드래그 또는 선택하여 업로드하세요.
확장자(.hwpx)파일로 최대 20mb까지 업로드 가능합니다.

'use client';import FileUploader from '@aift/ui/FileUploader';import FileUploaderItem from '@aift/ui/FileUploaderItem';import { useState } from 'react';import Blank20Icon from '@aift/ui/Icons/Blank20';export default function FileUploaderPreviewExample() {  const [files, setFiles] = useState<{ name: string; id: number }[]>([]);  const handleChangeFile = (file: File | null) => {    if (file) {      setFiles([...files, { name: file.name, id: files.length + 1 }]);    }  };  const handleRemoveFile = (id: number) => {    setFiles(files.filter((f) => f.id !== id));  };  return (    <div className="max-w-md space-y-2">      <div className="flex flex-col rounded-md bg-background-neutral p-4 gap-4">        <FileUploader          accept=".hwpx,.hwp"          onFileChange={handleChangeFile}          message={            <>              파일을 드래그 또는 선택하여 업로드하세요.              <br />              확장자(.hwpx)파일로 최대 20mb까지 업로드 가능합니다.            </>          }        />        <div className="flex flex-col gap-1">          {files.map((file) => (            <FileUploaderItem              key={file.name}              onRemoveClick={() => handleRemoveFile(file.id)}              leftSlot={<Blank20Icon size={16} />}            >              {file.name}            </FileUploaderItem>          ))}        </div>      </div>    </div>  );}

Multiple

여러 파일을 한 번에 드래그하거나 선택할 수 있습니다.
(예시: 동시 선택·다중 드롭)

'use client';import FileUploader from '@aift/ui/FileUploader';import FileUploaderItem from '@aift/ui/FileUploaderItem';import { useState } from 'react';import Blank20Icon from '@aift/ui/Icons/Blank20';export default function FileUploaderMultipleExample() {  const [files, setFiles] = useState<{ name: string; id: number }[]>([]);  const handleFiles = (uploaded: File[]) => {    if (uploaded.length === 0) return;    setFiles((prev) => {      const nextId =        prev.length === 0 ? 1 : Math.max(...prev.map((f) => f.id)) + 1;      return [        ...prev,        ...uploaded.map((file, i) => ({          name: file.name,          id: nextId + i,        })),      ];    });  };  const handleRemoveFile = (id: number) => {    setFiles((prev) => prev.filter((f) => f.id !== id));  };  return (    <div className="max-w-md space-y-2">      <div className="flex flex-col rounded-md bg-background-neutral p-4 gap-4">        <FileUploader          multiple          onFileChange={handleFiles}          message={            <>              여러 파일을 한 번에 드래그하거나 선택할 수 있습니다.              <br />              (예시: 동시 선택·다중 드롭)            </>          }        />        <div className="flex flex-col gap-1">          {files.map((file) => (            <FileUploaderItem              key={file.id}              onRemoveClick={() => handleRemoveFile(file.id)}              leftSlot={<Blank20Icon size={16} />}            >              {file.name}            </FileUploaderItem>          ))}        </div>      </div>    </div>  );}

Disabled

disabled이면 파일 선택 창이 열리지 않고, 드래그·드롭으로도 파일이 바뀌지 않으며 비활성 스타일이 적용됩니다.

업로드가 비활성화된 상태입니다.
클릭·드래그·드롭으로 파일을 바꿀 수 없습니다.

'use client';import FileUploader from '@aift/ui/FileUploader';export default function FileUploaderDisabledExample() {  return (    <div className="max-w-md space-y-2">      <div className="flex flex-col rounded-md bg-background-neutral p-4 gap-4">        <FileUploader          disabled          message={            <>              업로드가 비활성화된 상태입니다.              <br />              클릭·드래그·드롭으로 파일을 바꿀 수 없습니다.            </>          }        />      </div>    </div>  );}

Props

  • 단일 선택(기본): multiple을 생략하거나 false이면 한 번에 하나의 파일만 다루며, onFileChange에는 첫 번째 File 전달됩니다(없으면 null). OS에서 여러 개를 고르더라도 첫 항목만 콜백으로 옵니다.
  • 다중 선택: multipletrue로 두면 <input type="file" multiple />과 같이 여러 파일을 한 번에 선택하거나 드롭할 수 있고, onFileChange에는 **File[]**가 전달됩니다(없으면 빈 배열).
  • 검증·제한: accept로 파일 선택 창에 허용 형식 힌트를 줄 수 있습니다(MIME·.ext 등). 용량·내용 검증은 내장되어 있지 않으며, 드래그 앤 드롭은 브라우저에 따라 accept와 무관하게 들어올 수 있으니 필요하면 onFileChange에서 File을 검사하면 됩니다.
  • 비활성화: disabled이면 클릭·드래그·드롭으로 파일이 바뀌지 않으며 시각적으로 비활성 스타일이 적용됩니다.

FileUploaderProps는 루트 div에 대응하는 DOM 속성을 확장합니다(onChange는 내부 파일 입력과 구분하기 위해 제외). 표준 속성(className, onKeyDown 등)은 그대로 넘길 수 있습니다.

Prop타입기본값설명
multiplebooleanfalsetrue이면 다중 선택·드롭. 이때 onFileChange(files: File[]) => void
acceptstring-숨은 inputaccept. 예: image/png, .pdf, image/*
messageReactNode'파일을 드래그 또는 선택하여 업로드하세요.'안내 문구. falsy면 문구 영역은 렌더되지 않습니다.
onFileChange조건부-multiplefalse(기본): (file: File | null) => void. multipletrue: (files: File[]) => void
disabledboolean-비활성화 시 클릭·드래그·드롭으로 파일 변경 없음
rolestring'group'접근성 역할
tabIndexnumber0키보드 포커스 순서
aria-labelstring'파일 업로드'드롭존에 대한 접근성 레이블

accept·multiple은 각각 숨은 input type="file"의 네이티브 속성과 연결됩니다.

On this page