Single file upload
Single file upload
Go to top
Also see /react/fileinputarea
React component
Also see /react/examples/multipleFileUpload
Multiple file upload example
Handling events
You can use the onInput event on <FileInputArea> to handle selected file.
The file available in the event are reset every time you select a new file.
The example below shows how we can utilize this event to extract the file name, and set a loading state.
TSX
<FileInputArea
onInput={(e) => {
const files = e.currentTarget.files;
if (!files || !files.length) return;
setFileName(files[0].name);
setUploadState("loading");
//Handle post...
}}
disabled={uploadState === "loading"}
/>Before Uploading
This is the default state of <FileInputArea>, with some recommended content.
TSX
<FileInputArea aria-label="Upload file">
<Icon
icon={faArrowUpFromBracket}
className="bfc-base-2"
style={{ marginBottom: 8 }}
/>
<div>
Drag & drop file or{" "}
<span className="bf-neutral-link-text">click to upload</span>
</div>
<div className="bfc-base-2">.csv file, less than 10 MB</div>
</FileInputArea>Loading
While your file is uploading, you can render content appropriate for the
loading state. While uploading it can make sense to keep the <FileInputArea>
disabled.
TSX
<FileInputArea disabled>
<Icon.Spinner style={{ marginBottom: 8 }} />
<div>Uploading...</div>
<div className="bfc-base-2">filename.jpg</div>
</FileInputArea>Upload failed
If the upload failed, you can use the state="alert" prop to
give the <FileInputArea> a red border.
TSX
<FileInputArea state="alert">
<Icon
icon={faExclamationCircle}
className="bfc-alert"
style={{ marginBottom: 8 }}
/>
<div className="bfc-alert">Could not upload</div>
<div className="bf-neutral-link-text">Try again</div>
</FileInputArea>Upload successful
TSX
<FileInputArea>
<Icon icon={faCheck} className="bfc-success" style={{ marginBottom: 8 }} />
<div>
<strong>test.pdf</strong> sucessfully uploaded
</div>
<div className="bfc-base-2">
Drag and drop or <span className="bf-neutral-link-text">click</span> to
remove and upload new file
</div>
</FileInputArea>Interactive demo
This simulation lets you select a file, fakes uploading for 1s with a 50% chance to fake fail.
Sandbox
import { useState } from "react"; import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons/faExclamationCircle"; import { faCheck } from "@fortawesome/free-solid-svg-icons/faCheck"; import { faArrowUpFromBracket } from "@fortawesome/free-solid-svg-icons/faArrowUpFromBracket"; import FileInputArea from "@intility/bifrost-react/FileInputArea"; import Icon from "@intility/bifrost-react/Icon"; type InputState = "default" | "loading" | "failed" | "success"; const defaultContent = ( <> <Icon icon={faArrowUpFromBracket} className="bfc-base-2" style={{ marginBottom: 8 }} /> <div> Drag & drop file or{" "} <span className="bf-neutral-link-text">click to upload</span> </div> <div className="bfc-base-2">.csv file, less than 10 MB</div> </> ); const LoadingContent = ({ fileName = "" }) => ( <> <Icon.Spinner style={{ marginBottom: 8 }} /> <div>Uploading...</div> <div className="bfc-base-2">{fileName}</div> </> ); const failedContent = ( <> <Icon icon={faExclamationCircle} className="bfc-alert" style={{ marginBottom: 8 }} /> <div className="bfc-alert">Could not upload</div> <div className="bf-neutral-link-text">Try again</div> </> ); const SucessContent = ({ fileName = "" }) => ( <> <Icon icon={faCheck} className="bfc-success" style={{ marginBottom: 8 }} /> <div> <strong>{fileName}</strong> sucessfully uploaded </div> <div className="bfc-base-2"> Drag and drop or <span className="bf-neutral-link-text">click</span> to remove and upload new file </div> </> ); export default function SingleFileUpload() { const [uploadState, setUploadState] = useState<InputState>("default"); const [fileName, setFileName] = useState<string>(""); const handleFileUpload = (e: React.FormEvent<HTMLInputElement>) => { const files = e.currentTarget.files; if (!files || !files.length) return; setFileName(files[0].name); setUploadState("loading"); // Simulate a file upload setTimeout(() => { setUploadState(Math.random() > 0.5 ? "success" : "failed"); }, 1000); }; return ( <FileInputArea disabled={uploadState === "loading"} onInput={handleFileUpload} state={uploadState === "failed" ? "alert" : "default"} > {uploadState === "default" && defaultContent} {uploadState === "loading" && <LoadingContent fileName={fileName} />} {uploadState === "failed" && failedContent} {uploadState === "success" && <SucessContent fileName={fileName} />} </FileInputArea> ); }