File Input
<quiet-file-input>
File inputs let the user select files to upload to the server.
<quiet-file-input name="files" label="Select a file" description="Files must be 20MB or less" multiple ></quiet-file-input>
This component works like a native file input. Files can be posted to your server as multipart form data or you can access them via JavaScript for processing.
Examples Jump to heading
Labels and descriptions Jump to heading
You can use the label
and description
attributes to provide plain text labels and
descriptions for the file input. If you want to provide HTML, use the label
and
description
slots instead.
<quiet-file-input name="file" label="Select a file"> <span slot="description"> For more information, <a href="https://example.com/" target="_blank">visit our website</a>. </span> </quiet-file-input>
Uploading with forms Jump to heading
When uploading a file from a form, you'll probably want to add
method="post"
and
enctype="multipart/form-data"
to the form so the files will be sent to the server correctly.
<form id="file-input__uploading" enctype="multipart/form-data" method="post" action="about:blank" target="_blank" > <quiet-file-input name="files" label="Select a file"></quiet-file-input> <br> <quiet-button type="submit" variant="primary">Upload</quiet-button> </form> <script> const form = document.getElementById('file-input__uploading'); form.addEventListener('submit', event => { event.preventDefault(); const formData = new FormData(form); console.log(...formData.values()); }); </script>
Working with files Jump to heading
Use the files
property to get an array of selected files. Note the use of an array instead of a
FileList
, which allows you to add, modify, and remove files more easily than a native file input.
Try selecting a few files and then clicking each button.
<quiet-file-input id="file-input__accessing" name="files" label="Select some files" description="Files must be 20MB or less" multiple ></quiet-file-input> <br> <quiet-button type="submit">Reverse</quiet-button> <quiet-button type="submit">Clear</quiet-button> <script> const fileInput = document.getElementById('file-input__accessing'); const reverseButton = fileInput.nextElementSibling.nextElementSibling; const clearButton = reverseButton.nextElementSibling; // Reverse reverseButton.addEventListener('click', event => { fileInput.files = fileInput.files.toReversed(); }); // Clear clearButton.addEventListener('click', event => { fileInput.files = []; }); </script>
The files
property must be reassigned, not mutated! Avoid using functions that mutate the
array, such as
reverse()
and
sort()
, because they won't trigger an update.
Accepting multiple files Jump to heading
Add the multiple
attribute to allow the file input to accept more than one file.
<quiet-file-input name="files" label="Select the files you want to upload" multiple > </quiet-file-input>
Accepting file types Jump to heading
To limit the file input to certain file types, set the accept
attribute to a comma-separated
string of
unique file type specifiers.
<quiet-file-input name="file" label="Upload a picture of your cat" accept="image/jpeg, image/png, image/gif, image/webp" > </quiet-file-input>
Changing the size Jump to heading
<quiet-file-input size="xs" name="xs" label="Extra small"></quiet-file-input><br> <quiet-file-input size="sm" name="sm" label="Small"></quiet-file-input><br> <quiet-file-input size="md" name="md" label="Medium"></quiet-file-input><br> <quiet-file-input size="lg" name="lg" label="Large"></quiet-file-input><br> <quiet-file-input size="xl" name="xl" label="Extra large"></quiet-file-input>
Custom dropzone content Jump to heading
Use the dropzone
slot to customize what appears inside the dropzone.
Choose some files to send to the cloud
<quiet-file-input name="files" label="Upload a file" multiple> <div slot="dropzone"> <quiet-icon name="cloud-upload" style="font-size: 2rem;"></quiet-icon> <br> Choose some files to send to the cloud </div> </quiet-file-input>
Button-only file inputs Jump to heading
Button-only file inputs aren't supported, but you can achieve this pattern with a button, a native
<input type="file">
, and a bit of JavaScript. If you're using
Quiet Restyle, you can use the visually-hidden
utility class to
hide the input.
<quiet-button id="file-input__button-only">Select files</quiet-button> <input class="visually-hidden" type="file" name="file"> <script> const button = document.getElementById('file-input__button-only'); const fileInput = button.nextElementSibling; // Open the system file browser when the button is clicked button.addEventListener('click', () => { fileInput.click(); }); // Listen for files to be selected fileInput.addEventListener('change', () => { // Do something with the files console.log(...fileInput.files); // Reset the input fileInput.value = ''; }); </script>
Validation Jump to heading
The required
attribute can be applied to enable validation using the
Constraint Validation API. This will prevent form submission until the user has selected a file.
<form action="about:blank" method="get" target="_blank"> <quiet-file-input name="file" label="Select a file" required></quiet-file-input> <br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form>
Using custom validation Jump to heading
Use the custom-validity
attribute to make the file input invalid and show a custom error
message on submit. This will override all other validation parameters. To clear the error, remove the
attribute or set it to an empty string.
<form action="about:blank" method="get" target="_blank"> <quiet-file-input name="file" label="Select a file" custom-validity="Not so fast, bubba!" required ></quiet-file-input> <br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form>
Styling validation Jump to heading
You can style valid and invalid file inputs using the :valid
and :invalid
pseudo
classes.
<form action="about:blank" method="get" target="_blank" class="file-input__validation-pseudo"> <quiet-file-input name="file" label="Select a file" required></quiet-file-input> <br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form> <style> .file-input__validation-pseudo { quiet-file-input:valid { outline: solid 2px var(--quiet-constructive-stroke-mid); outline-offset: .5rem; } quiet-file-input:invalid { outline: solid 2px var(--quiet-destructive-stroke-mid); outline-offset: .5rem; } } </style>
However, these selectors will match even before the user has had a chance to fill out the form. More often
than not, you'll want to use the user-valid
and user-invalid
custom states instead. This way, validation styles are only shown
after the user interacts with the form control or when the form is submitted.
<form action="about:blank" method="get" target="_blank" class="file-input__validation-custom"> <quiet-file-input name="file" label="Select a file" required></quiet-file-input> <br> <quiet-button type="submit" variant="primary">Submit</quiet-button> <quiet-button type="reset">Reset</quiet-button> </form> <style> .file-input__validation-custom { quiet-file-input:state(user-valid) { outline: solid 2px var(--quiet-constructive-stroke-mid); outline-offset: .5rem; } quiet-file-input:state(user-invalid) { outline: solid 2px var(--quiet-destructive-stroke-mid); outline-offset: .5rem; } } </style>
API Jump to heading
Importing Jump to heading
The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.
To manually import <quiet-file-input>
from the CDN, use the following code.
import 'https://cdn.jsdelivr.net/npm/@quietui/quiet@1.0.0/dist/components/file-input/file-input.js';
To manually import <quiet-file-input>
from npm, use the following code.
import '@quietui/quiet/dist/components/file-input/file-input.js';
Slots Jump to heading
File Input supports the following slots. Learn more about using slots
Name | Description |
---|---|
label
|
The file input's label. For plain-text labels, you can use the label attribute instead.
|
description
|
The file input's description. For plain-text descriptions, you can use the
description attribute instead.
|
dropzone
|
Custom content to show in the dropzone. |
Properties Jump to heading
File Input has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties
Property / Attribute | Description | Reflects | Type | Default |
---|---|---|---|---|
associatedForm
|
A reference to the <form> associated with the form control, or
null if no form is associated.
|
|
HTMLFormElement
|
null
|
files
|
An array of files that are currently selected. (Property only) |
|
File[]
|
[]
|
label
|
The text field's label. If you need to provide HTML in the label, use the label slot
instead.
|
|
string
|
|
description
|
The text field's description. If you need to provide HTML in the description, use the
description slot instead.
|
|
string
|
|
name
|
The name of the file input. This will be submitted with the form as a name/value pair. |
|
string
|
|
disabled
|
Disables the file input. |
|
boolean
|
false
|
accept
|
A list of acceptable file types. Must be a comma-separated list of unique file type specifiers. |
|
boolean
|
false
|
multiple
|
Allows more than one file to be selected. |
|
boolean
|
false
|
size
|
The file input's size. |
|
'xs'
|
'md'
|
form
|
The form to associate this control with. If omitted, the closest containing
<form> will be used. The value of this attribute must be an ID of a form in the
same document or shadow root.
|
|
string
|
|
required
|
Makes the file input required. Form submission will not be allowed when this is set and no files are selected. |
|
boolean
|
false
|
customValidity
custom-validity
|
You can provide a custom error message to force the text field to be invalid. To clear the error, set this to an empty string. |
|
string
|
''
|
Events Jump to heading
File Input dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events
Name | Description |
---|---|
quiet-blur |
Emitted when the file input loses focus. This event does not bubble. |
quiet-change |
Emitted when the user selects or removes a file. |
quiet-focus |
Emitted when the file input receives focus. This event does not bubble. |
quiet-input |
Emitted when the file input receives input. |
CSS parts Jump to heading
File Input exposes internal elements that can be styled with CSS using the selectors shown below. Learn more about CSS parts
Name | Description | CSS selector |
---|---|---|
label |
The element that contains the text field's label, a <label> element.
|
::part(label)
|
description |
The element that contains the text field's description. |
::part(description)
|
dropzone |
The bordered region where files can be dropped. |
::part(dropzone)
|
file-list |
The list of files shown when at least one file is selected. |
::part(file-list)
|
file |
A selected file will be drawn in this container. |
::part(file)
|
file-thumbnail |
The container that hold's the file's image or icon. |
::part(file-thumbnail)
|
file-image |
The file's image preview (if it's an image). |
::part(file-image)
|
file-icon |
The file's icon (if it's not an image). |
::part(file-icon)
|
file-icon__svg |
The <svg> part of the file icon. |
::part(file-icon__svg)
|
file-details |
The container that holds the filename and size. |
::part(file-details)
|
file-name |
The container that holds the file's name, a <span> element.
|
::part(file-name)
|
file-size |
The container that holds the file's size, a <small> element.
|
::part(file-size)
|
file-actions |
The container that holds the file's remove button. |
::part(file-actions)
|
file-remove-button |
The file's remove button. |
::part(file-remove-button)
|
file-remove-button__button |
The button part of the file's remove button. |
::part(file-remove-button__button)
|
Custom States Jump to heading
File Input has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states
Name | Description | CSS selector |
---|---|---|
disabled |
Applied when the file input is disabled. |
:state(disabled)
|
blank |
Applied when the file input has a blank value. |
:state(blank)
|
focused |
Applied when the file input has focus. |
:state(focused)
|
user-valid |
Applied when the file input is valid and the user has sufficiently interacted with it. |
:state(user-valid)
|
user-invalid |
Applied when the file input is invalid and the user has sufficiently interacted with it. |
:state(user-invalid)
|
Dependencies Jump to heading
File Input automatically imports the following elements. Sub-dependencies are also included in this list.