FileUpload
파일을 선택하거나 Drag & Drop으로 업로드할 수 있는 컴포넌트
개요
FileUpload 컴포넌트는 사용자가 파일을 선택하거나 드래그 앤 드롭하여 업로드할 수 있는 영역을 제공합니다.
주요 특징
- ✅ Drag & Drop: 파일을 드래그하여 업로드 영역에 드롭
- ✅ 파일 유효성 검증: 확장자, 용량, 개수 제한
- ✅ 파일 목록 관리: 업로드된 파일 목록 표시 및 삭제
- ✅ 기존 파일 표시: 서버에 이미 저장된 파일을 메타데이터만으로 목록에 표시 (다운로드 링크 지원)
- ✅ 파일 유형 아이콘: 확장자에 따른 자동 아이콘 표시
- ✅ Tooltip: 긴 파일명 Hover 시 전체 이름 표시
- ✅ 오류 처리: 유효하지 않은 파일 업로드 시 시각적 피드백
- ✅ 디자인 토큰: 테마 커스터마이징 지원
사용 예시
기본 사용
Preview
Drop file or Click to upload
파일을 선택하거나 드래그하여 업로드하세요.
파일 형식 제한
accept prop으로 허용할 파일 확장자 또는 MIME 타입을 지정합니다.
Preview
Drop file or Click to upload
허용: PDF, Excel, Word 파일만
파일 용량 제한
maxSize prop으로 파일 단위 최대 용량을 바이트 단위로 설정합니다.
Preview
Drop file or Click to upload
최대 파일 크기: 1MB
파일 개수 제한
maxFiles로 최대 파일 수를, multiple={false}로 단일 파일 모드를 설정합니다.
Preview
Drop file or Click to upload
최대 3개 파일만 업로드 가능
Drop file or Click to upload
단일 파일만 업로드 가능
비활성화 상태
disabled prop으로 파일 추가 및 삭제를 제한합니다.
Preview
Drop file or Click to upload
비활성화 상태 - 파일 추가/삭제 불가
Drag & Drop 업로드
파일을 드래그하여 업로드 영역에 드롭할 수 있습니다. 드래그 시 영역이 시각적으로 변경됩니다.
Preview
Drop file or Click to upload
파일을 드래그하여 업로드하세요.
파일 업로드 처리 및 상태 갱신
선택 또는 Drop된 파일이 유효성 검사를 통과하면 자동으로 업로드되며, 파일 목록 및 용량 정보가 실시간으로 갱신됩니다.
Preview
Drop file or Click to upload
파일 업로드/삭제 시 목록과 용량이 자동 갱신됩니다.
설명 텍스트
description prop으로 업로드 조건(확장자, 용량 등)을 안내합니다.
Preview
Drop file or Click to upload
허용 확장자: .pdf, .xlsx, .docx / 최대 용량: 5MB / 최대 10개
기존 업로드된 파일 표시 (ReadOnly)
서버에 이미 저장된 파일을 File 데이터 없이 메타데이터만으로 목록에 표시하려면 existingFiles prop에 ExistingFile[] 을 전달합니다.
onRemoveExisting 콜백을 넘기지 않으면 삭제 버튼이 렌더되지 않아 readonly 목록으로 동작합니다.
url 을 지정하면 파일명이 다운로드 링크로 표시됩니다.
Preview
Drop file or Click to upload
이미 업로드된 파일입니다.
기존 파일 + 삭제 이벤트
onRemoveExisting 콜백을 제공하면 각 기존 파일 항목에 X 버튼이 표시됩니다.
클릭 시 해당 파일 메타데이터가 콜백으로 전달되며, 소비자가 서버 DELETE API 호출 후 existingFiles 배열을 갱신합니다 (controlled).
Preview
Drop file or Click to upload
X 버튼으로 기존 파일을 삭제할 수 있습니다.
💡 신규 파일 vs 기존 파일
- 신규 선택 파일(
value/onChange): 브라우저File인스턴스. 내부 상태로 관리되며onChange로 최신 배열이 방출됨. 삭제는 내부에서 처리되어 별도 이벤트가 필요 없음.- 기존 업로드 파일(
existingFiles/onRemoveExisting): 서버에 저장된 파일의 메타데이터. controlled 로 관리하며 삭제 시onRemoveExisting이벤트로 서버 DELETE API 트리거.
maxFiles는 두 목록의 합산 기준으로 검증됩니다.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
accept | string | - | 허용할 파일 확장자 또는 MIME 타입 (쉼표 구분) |
maxSize | number | 5242880 (5MB) | 파일 단위 최대 용량 (바이트) |
maxFiles | number | 10 | 업로드 가능한 최대 파일 개수 (existingFiles 포함 합산 기준) |
multiple | boolean | true | 다중 파일 업로드 허용 여부 |
disabled | boolean | false | 비활성화 상태 |
description | string | - | 업로드 조건 안내 텍스트 |
value | File[] | - | 제어 모드에서 신규 파일 목록 |
existingFiles | ExistingFile[] | - | 서버에 이미 저장된 파일 메타데이터 목록 (controlled) |
className | string | - | 추가 CSS 클래스 |
Events
| Event | Type | Description |
|---|---|---|
onChange | (files: File[]) => void | 신규 파일 목록 변경 시 호출 |
onError | (error: string) => void | 유효성 검증 실패 시 에러 메시지와 함께 호출 |
onRemoveExisting | (file: ExistingFile) => void | 기존 파일의 X 버튼 클릭 시 호출. 미제공 시 X 버튼이 렌더되지 않아 readonly 목록으로 동작. |
Types
interface ExistingFile {
id: string // 서버 측 고유 식별자
name: string // 파일명 (확장자 포함)
size: number // 파일 크기 (바이트)
url?: string // 다운로드 링크 (지정 시 파일명이 링크로 렌더됨)
}기본 사용법
import { FileUpload } from "@vortex/ui-foundation"
// iCignal에서도 동일하게 사용 가능
import { FileUpload } from "@vortex/ui-icignal"
<FileUpload
accept=".pdf,.xlsx"
maxSize={5 * 1024 * 1024}
maxFiles={5}
description="PDF, Excel 파일만 허용 (최대 5MB)"
onChange={(files) => console.log(files)}
onError={(error) => console.error(error)}
/>기존 파일 + 신규 업로드 조합 (편집 폼 패턴)
import { useState } from "react"
import { FileUpload, type ExistingFile } from "@vortex/ui-foundation"
function EditAttachmentsForm({ initialFiles }: { initialFiles: ExistingFile[] }) {
const [existingFiles, setExistingFiles] = useState<ExistingFile[]>(initialFiles)
const [newFiles, setNewFiles] = useState<File[]>([])
const handleSubmit = async () => {
// 신규 업로드만 서버에 전송 (기존 파일은 이미 저장되어 있음)
await api.uploadFiles(newFiles)
}
return (
<FileUpload
maxFiles={10}
existingFiles={existingFiles}
onRemoveExisting={async (file) => {
await api.deleteFile(file.id)
setExistingFiles((prev) => prev.filter((f) => f.id !== file.id))
}}
value={newFiles}
onChange={setNewFiles}
/>
)
}접근성
권장 사항
- ✅
description으로 허용 파일 형식과 용량 제한을 명확히 안내 - ✅
onError콜백을 통해 오류 메시지를 사용자에게 전달 - ✅ 키보드로 업로드 영역에 접근 가능 (클릭 동작)
- ❌ 파일 유형 제한 시
accept만 사용하고 안내 텍스트 없이 사용 지양