File Input

Installation

Run the following command

npx vibes@latest add file-input

Usage

import { FileInput } from '@/vibes/soul/form/file-input';function Usage() {  return (    <FileInput />  );}

API Reference

FileInputProps

PropTypeDefault
id
string
className
string
initialFiles
Map<File, FileState>
onFilesChange
(files: Map<File, FileState>) => void
onUpload
(files: File[], options: UploadOptions) => Promise<void> | void
onFileAccept
(file: File) => void
onFileReject
(file: File, message: string) => void
onFileValidate
(file: File) => string | null | undefined
hideLabel
boolean
false
message
string
cta
string
'Upload file'
hint
string
'or drag and drop files here'
invalid
boolean
label
string
'File upload'
maxFiles
number
maxSize
number
uploadingLabel
string
'Uploading'
successLabel
string
'Upload complete'
errorLabel
string
'Error'

UploadOptions

PropTypeDefault
onProgress
(file: File, progress: number) => void
onSuccess
(file: File) => void
onError
(file: File, error: Error) => void

FileState

PropTypeDefault
progress
number
status
'idle' | 'uploading' | 'success' | 'error'
error
string

FileDropzoneProps

PropTypeDefault
children
ReactNode
inputRef
RefObject<HTMLInputElement | null>
disabled
boolean
invalid
boolean

FileItemProps

PropTypeDefault
file
File
fileState
FileState
onRemoveFile
(file: File) => void
uploadingLabel
string
'Uploading'
successLabel
string
'Upload complete'
errorLabel
string
'Error'

CSS Variables

This component supports various CSS variables for theming. Here's a comprehensive list.

:root {  --file-input-focus: var(--primary);  --file-input-message: var(--contrast-500);  --file-input-message-font-family: var(--font-family-body);  --file-input-dropzone-background: var(--background);  --file-input-dropzone-border: var(--contrast-200);  --file-input-dropzone-background-hover: var(--contrast-100);  --file-input-dropzone-border-hover: var(--foreground);  --file-input-dropzone-border-disabled: color-mix(in oklab, var(--contrast-200) 70%, transparent);  --file-input-dropzone-background-disabled: var(--background);  --file-input-dropzone-border-error: var(--error);  --file-input-dropzone-border-dragging: var(--foreground);  --file-input-dropzone-background-dragging: var(--success-highlight);  --file-input-trigger-icon: var(--foreground);  --file-input-dropzone-message-font-family: var(--font-family-body);  --file-input-dropzone-message: var(--contrast-500);  --file-input-dropzone-message-disabled: color-mix(in oklab, var(--contrast-500) 70%, transparent);  --file-input-item-border: var(--contrast-200);  --file-input-item-border-error: var(--error);  --file-input-item-name-font-family: var(--font-family-body);  --file-input-item-name: var(--foreground);  --file-input-item-status: var(--contrast-500);  --file-input-item-status-error: var(--error);  --file-input-item-delete-icon: var(--foreground);  --file-input-item-progress: var(--primary);  --file-input-mime-icon: var(--contrast-400);}