Skip to Content

FileUpload

파일을 선택하거나 Drag & Drop으로 업로드할 수 있는 컴포넌트


개요

FileUpload 컴포넌트는 사용자가 파일을 선택하거나 드래그 앤 드롭하여 업로드할 수 있는 영역을 제공합니다.

주요 특징

  • Drag & Drop: 파일을 드래그하여 업로드 영역에 드롭
  • 파일 유효성 검증: 확장자, 용량, 개수 제한
  • 파일 목록 관리: 업로드된 파일 목록 표시 및 삭제
  • 기존 파일 표시: 서버에 이미 저장된 파일을 메타데이터만으로 목록에 표시 (다운로드 링크 지원)
  • 파일 유형 아이콘: 확장자에 따른 자동 아이콘 표시
  • Tooltip: 긴 파일명 Hover 시 전체 이름 표시
  • 오류 처리: 유효하지 않은 파일 업로드 시 시각적 피드백
  • 디자인 토큰: 테마 커스터마이징 지원

사용 예시

기본 사용

0 file / -

Drop file or Click to upload

파일을 선택하거나 드래그하여 업로드하세요.

파일 형식 제한

accept prop으로 허용할 파일 확장자 또는 MIME 타입을 지정합니다.

0 file / -

Drop file or Click to upload

허용: PDF, Excel, Word 파일만

파일 용량 제한

maxSize prop으로 파일 단위 최대 용량을 바이트 단위로 설정합니다.

0 file / -

Drop file or Click to upload

최대 파일 크기: 1MB

파일 개수 제한

maxFiles로 최대 파일 수를, multiple={false}로 단일 파일 모드를 설정합니다.

0 file / -

Drop file or Click to upload

최대 3개 파일만 업로드 가능

0 file / -

Drop file or Click to upload

단일 파일만 업로드 가능

비활성화 상태

disabled prop으로 파일 추가 및 삭제를 제한합니다.

0 file / -

Drop file or Click to upload

비활성화 상태 - 파일 추가/삭제 불가

Drag & Drop 업로드

파일을 드래그하여 업로드 영역에 드롭할 수 있습니다. 드래그 시 영역이 시각적으로 변경됩니다.

0 file / -

Drop file or Click to upload

파일을 드래그하여 업로드하세요.

파일 업로드 처리 및 상태 갱신

선택 또는 Drop된 파일이 유효성 검사를 통과하면 자동으로 업로드되며, 파일 목록 및 용량 정보가 실시간으로 갱신됩니다.

0 file / -

Drop file or Click to upload

파일 업로드/삭제 시 목록과 용량이 자동 갱신됩니다.

설명 텍스트

description prop으로 업로드 조건(확장자, 용량 등)을 안내합니다.

0 file / -

Drop file or Click to upload

허용 확장자: .pdf, .xlsx, .docx / 최대 용량: 5MB / 최대 10개

기존 업로드된 파일 표시 (ReadOnly)

서버에 이미 저장된 파일을 File 데이터 없이 메타데이터만으로 목록에 표시하려면 existingFiles prop에 ExistingFile[] 을 전달합니다. onRemoveExisting 콜백을 넘기지 않으면 삭제 버튼이 렌더되지 않아 readonly 목록으로 동작합니다. url 을 지정하면 파일명이 다운로드 링크로 표시됩니다.

2 file / 1.61 MB

Drop file or Click to upload

이미 업로드된 파일입니다.

budget.xlsx
446.08 KB

기존 파일 + 삭제 이벤트

onRemoveExisting 콜백을 제공하면 각 기존 파일 항목에 X 버튼이 표시됩니다. 클릭 시 해당 파일 메타데이터가 콜백으로 전달되며, 소비자가 서버 DELETE API 호출 후 existingFiles 배열을 갱신합니다 (controlled).

2 file / 12.24 MB

Drop file or Click to upload

X 버튼으로 기존 파일을 삭제할 수 있습니다.

design-spec.pdf
2.24 MB
assets.zip
10 MB

💡 신규 파일 vs 기존 파일

  • 신규 선택 파일(value/onChange): 브라우저 File 인스턴스. 내부 상태로 관리되며 onChange 로 최신 배열이 방출됨. 삭제는 내부에서 처리되어 별도 이벤트가 필요 없음.
  • 기존 업로드 파일(existingFiles/onRemoveExisting): 서버에 저장된 파일의 메타데이터. controlled 로 관리하며 삭제 시 onRemoveExisting 이벤트로 서버 DELETE API 트리거.

maxFiles 는 두 목록의 합산 기준으로 검증됩니다.


API Reference

Props

PropTypeDefaultDescription
acceptstring-허용할 파일 확장자 또는 MIME 타입 (쉼표 구분)
maxSizenumber5242880 (5MB)파일 단위 최대 용량 (바이트)
maxFilesnumber10업로드 가능한 최대 파일 개수 (existingFiles 포함 합산 기준)
multiplebooleantrue다중 파일 업로드 허용 여부
disabledbooleanfalse비활성화 상태
descriptionstring-업로드 조건 안내 텍스트
valueFile[]-제어 모드에서 신규 파일 목록
existingFilesExistingFile[]-서버에 이미 저장된 파일 메타데이터 목록 (controlled)
classNamestring-추가 CSS 클래스

Events

EventTypeDescription
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만 사용하고 안내 텍스트 없이 사용 지양

관련 컴포넌트

Last updated on