in src/upload/upload.tsx [43:117]
function UploadInner({
children,
className,
onFilesSelected,
onFilesRejected,
validate = () => true,
variant = 'empty',
multiple,
renderIcon = defaultRenderIcon,
accept,
disabled,
forwardedRef,
}: InnerProps) {
const fileInputRef = useRef<HTMLInputElement>(null);
const [dragOver, setDragOver] = useState(false);
useImperativeHandle(forwardedRef, () => ({openFilePicker: () => fileInputRef.current?.click()}), []);
const handleSelectedFiles = (files: File[]) => {
if (!files.length) {
return;
}
const rejected = files.filter(file => !validate(file));
if (rejected.length > 0) {
onFilesRejected?.(files);
return;
}
onFilesSelected(files);
};
const onDragEnter: DragEventHandler = () => setDragOver(true);
const onDragOver: DragEventHandler = e => e.preventDefault();
const onDragLeave: DragEventHandler = () => setDragOver(false);
const onInputChange = () => {
setDragOver(false);
if (fileInputRef.current?.files) {
handleSelectedFiles(Array.from(fileInputRef.current.files));
}
};
return (
<div
className={classNames(className, styles.upload, {
[styles.disabled]: disabled,
[styles.dragOver]: dragOver,
[styles.success]: variant === 'success',
[styles.error]: variant === 'error',
})}
data-test='ring-upload'
>
<input
onDragEnter={onDragEnter}
onDragOver={onDragOver}
onDragLeave={onDragLeave}
disabled={disabled}
ref={fileInputRef}
data-test='ring-file-input'
multiple={multiple}
accept={accept}
onChange={onInputChange}
type='file'
autoComplete='off'
aria-label='file-picker'
className={styles.invisibleFileInput}
/>
{renderIcon()}
{children}
</div>
);
}