export type FileRejectReason = 'type' | 'size' | 'count'; export type FileRejection = { file: File; reason: FileRejectReason; }; /** Reactive inputs are passed as getters so the core tracks live prop changes. */ export type FileUploadConfig = { files: () => File[]; onChange?: (files: File[]) => void; /** Rejected files (wrong type / too big / over the count cap). */ onReject?: (rejections: FileRejection[]) => void; /** Comma list like "image/*,.pdf" (matches MIME or extension). */ accept?: () => string | undefined; multiple?: () => boolean; /** Max size per file in bytes. */ maxSize?: () => number | undefined; /** Max number of files (multiple mode). */ maxFiles?: () => number | undefined; disabled?: () => boolean; readonly?: () => boolean; id?: () => string | undefined; invalid?: () => boolean; required?: () => boolean; error?: () => string | undefined; hint?: () => string | undefined; ariaLabel?: () => string | undefined; }; /** Whether `file` satisfies an `accept` list (MIME globs or extensions). Pure. */ export declare function fileMatchesAccept(file: File, accept?: string): boolean; export declare function createFileUpload(config: FileUploadConfig): { /** Whether files are being dragged over the dropzone. */ readonly dragging: boolean; /** Whether interaction is allowed. */ readonly isInteractive: boolean; /** Selected files (controlled value). */ readonly files: File[]; addFiles: (incoming: File[]) => void; removeAt: (index: number) => void; clear: () => void; setDragging: (v: boolean) => void; /** Spread onto the dropzone element (click opens the picker; Enter/Space too). * Wire drag events yourself (they carry a DataTransfer): call * `setDragging(true/false)` and `addFiles([...e.dataTransfer.files])`. */ dropzoneProps: () => { 'aria-invalid': "true" | undefined; 'aria-required': "true" | undefined; 'aria-describedby': string | undefined; 'aria-label': string | undefined; role: "button"; tabindex: number; 'data-dragging': string | undefined; 'aria-disabled': true | undefined; }; /** Spread onto the visually-hidden . */ inputProps: () => { type: "file"; accept: string | undefined; multiple: boolean; disabled: boolean; tabindex: number; }; /** Spread onto a selected file's remove