FileInput | CoUI

FileInput

파일 입력 컴포넌트

FileInput#

파일 선택/업로드를 위한 점선 테두리 드롭존 컴포넌트입니다. Flutter/Web 양쪽에서 동일한 API(CoFileInput)를 제공합니다.

Live Preview#

Web
Drop files here or PNG, JPG, PDF up to 10MB
Flutter
Loading Flutter...
class FileInputDefaultExample extends StatefulComponent {
  const FileInputDefaultExample({super.key});

  @override
  State<FileInputDefaultExample> createState() =>
      _FileInputDefaultExampleState();
}

class _FileInputDefaultExampleState extends State<FileInputDefaultExample> {
  List<String> _selectedFiles = const [];

  @override
  Component build(BuildContext context) {
    return CoFileInput(
      onFilesSelected: (files) {
        setState(() {
          _selectedFiles = [
            for (var i = 0; i < files.length; i++) files.item(i)!.name,
          ];
        });
      },
      multiple: true,
      hint: 'PNG, JPG, PDF up to 10MB',
      selectedFiles: _selectedFiles,
    );
  }
}
class FileInputDefaultExample extends StatefulWidget {
  const FileInputDefaultExample({super.key});

  @override
  State<FileInputDefaultExample> createState() =>
      _FileInputDefaultExampleState();
}

class _FileInputDefaultExampleState extends State<FileInputDefaultExample> {
  List<String> _selectedFiles = const [];

  void handleFilesSelected(List<XFile> files) {
    setState(() {
      _selectedFiles = files.map((f) => f.name).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return CoFileInput(
      onFilesSelected: handleFilesSelected,
      multiple: true,
      hint: 'PNG, JPG, PDF up to 10MB',
      selectedFiles: _selectedFiles,
    );
  }
}

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 사용자가 파일을 업로드해야 할 때 (이미지, 문서 등)
  • 프로필 사진, 첨부파일 등 파일 선택이 필요할 때
  • 폼에서 파일 필드를 포함해야 할 때

대신 다른 컴포넌트를 사용하세요:

  • Input: 텍스트 입력일 때
  • Button: 파일 업로드 트리거만 필요하고 커스텀 UI를 구성할 때

기본 사용법 (Basic Usage)#

// 기본 파일 입력
CoFileInput(
  onFilesSelected: (files) => print('Selected: ${files.length}'),
)

// 이미지만 허용
CoFileInput(
  accept: ['image/*'],
  onFilesSelected: handleImageSelected,
)

// 다중 파일 + 선택 목록 표시
CoFileInput(
  multiple: true,
  accept: ['.pdf', '.doc', '.docx'],
  hint: 'PDF, DOC up to 10MB',
  selectedFiles: selectedFileNames,
  onFilesSelected: handleFilesSelected,
)
// 기본 파일 입력
CoFileInput(
  onFilesSelected: (fileList) => print('Files: ${fileList.length}'),
)

// 이미지만 허용
CoFileInput(
  accept: ['image/*'],
  onFilesSelected: handleImageSelected,
)

// 다중 파일 + 힌트 + 선택 목록
CoFileInput(
  multiple: true,
  accept: ['.pdf', '.doc', '.docx'],
  hint: 'PDF, DOC up to 10MB',
  selectedFiles: selectedFileNames,
  onFilesSelected: handleFilesSelected,
)

Props / Parameters#

CoFileInput은 Flutter/Web에서 동일한 파라미터 이름을 사용합니다. 타입만 플랫폼에 맞게 다릅니다.

속성Flutter 타입Web 타입기본값설명
onFilesSelected ValueChanged<List<XFile>>? void Function(FileList)? null 파일 선택 콜백
accept List<String>? List<String>? null 허용 파일 타입 (예: ['image/*', '.pdf'])
multiple bool bool false 다중 파일 선택 허용
enabled bool bool true 상호작용 활성화 여부
label String? String? 'Drop files here or' 드롭존 안내 문구
hint String? String? null 보조 힌트 텍스트
icon Widget? Component? 업로드 아이콘 커스텀 아이콘
browseButtonText String? String? 'Browse' 파일 선택 버튼 레이블
selectedFiles List<String>? List<String>? null 선택된 파일 목록 표시
name String? String? null 폼 필드 이름

테마 커스터마이징 (Theme)#

프로젝트 수준에서 CoreFileInputTheme으로 기본 스타일을 오버라이드할 수 있습니다.

CoreComponentTheme(
  fileInput: CoreFileInputTheme(
    borderRadius: 12.0,   // 기본: CoreRadius.selector (8px)
    padding: 32.0,        // 기본: CoreSpace.space24 (24px)
    iconSize: 40.0,       // 기본: CoreSize.size32 (32px)
    borderWidth: 1.5,     // 기본: CoreBorderWidth.thin (1px)
    gap: 16.0,            // 기본: CoreSpace.space12 (12px)
  ),
)

Resolve 우선순위: 위젯 파라미터 > CoreFileInputTheme > 디자인 시스템 기본값.

동작 스펙 (Behavior)#

파일 선택#

  • 드롭존 전체 영역을 클릭하면 브라우저 파일 선택 다이얼로그가 열립니다
  • accept로 허용 파일 타입 필터링
  • multiple: true 시 여러 파일 동시 선택 가능
  • 선택된 파일은 onFilesSelected 콜백으로 전달

시각 피드백#

  • 호버 시: 테두리 색상이 primary로 강조되고, 배경에 primary/5 틴트가 적용됩니다
  • 비활성 시: 반투명 + pointer-events 차단
  • 점선 테두리: CoreDashedBorder 토큰으로 Flutter/Web 동일한 시각 렌더링

사용 가이드라인 (Usage Guidelines)#

✅ Do#

accept 속성으로 허용 파일 타입을 명시하세요.

// 이미지만
CoFileInput(accept: ['image/*'], onFilesSelected: handleImage)

// 특정 문서 형식
CoFileInput(accept: ['.pdf', '.doc', '.docx'], onFilesSelected: handleDoc)

사용자가 잘못된 파일을 선택하는 실수를 줄입니다.


❌ Don't#

파일 크기 검증 없이 업로드를 허용하지 마세요.

onFilesSelected 콜백에서 파일 크기를 확인하고, 초과 시 사용자에게 안내하세요.

✅ Do#

선택된 파일 목록을 selectedFiles로 표시하세요.

CoFileInput(
  multiple: true,
  selectedFiles: selectedFileNames,
  onFilesSelected: (files) {
    setState(() {
      selectedFileNames = files.map((f) => f.name).toList();
    });
  },
)

사용자가 어떤 파일을 선택했는지 즉시 확인할 수 있습니다.

접근성 (Accessibility)#

키보드 인터랙션#

동작
Tab파일 선택 버튼으로 포커스 이동
Enter / Space파일 선택 다이얼로그 열기

스크린 리더#

  • Web: 내부에 숨겨진 <input type="file">로 네이티브 시맨틱 제공
  • accept 속성이 허용 파일 타입 정보를 전달
  • enabled: false 시 비활성 상태 전달

라벨#

  • name 속성으로 폼 내 필드 식별 (Web)
  • Input: 텍스트 입력. FileInput은 파일 선택 전용
  • Form: 폼 컨테이너. FileInput을 Form 내에서 사용
  • Button: 내부 Browse 버튼으로 CoButton(variant: outline) 사용