Skip to content
Nana UI

Data Display & Media

File

One file — an attachment, an upload, a document on a record — with what it is, how big it is, and what can be done with it. A photograph shows itself; anything else shows a page marked with its kind and extension.

View .md Download

It follows an upload through: a bar while it goes, the reason and a retry when it fails, the size and a download once it lands. A long name is cut in the middle, so the extension stays in view.

Selecting the name fires nana-file-open; pair it with nana-file-viewer to preview the file in place.

StatusShowsOffers
uploadingA bar at progress, or a moving one while it is unknownCancel, as nana-file-remove
errorerror in redRetry, as nana-file-retry
readyThe size and metaDownload when there is a src, and remove with removable

A photograph shows itself — from thumbnail if you have a small one, or src. Anything else is a page marked with its extension and coloured by kind: PDF red, spreadsheets green, documents blue, presentations orange, audio and video purple, archives amber.

variant="card" suits a grid of photographs and documents; the default row suits a list of attachments.

The name is a button that fires nana-file-open with the file’s name, src and type. Hand those to a File Viewer to preview it without leaving the page:

const viewer = document.querySelector("nana-file-viewer[modal]");
const files = [...document.querySelectorAll("nana-file")];
document.addEventListener("nana-file-open", (e) => {
viewer.files = files.map(({ name, src, type, size }) => ({ name, src, type, size }));
viewer.show(files.indexOf(e.target));
});
npm install @nana-tec/ui-components

Or copy the source in and own it:

npx @nana-tec/ui add file
import "@nana-tec/ui-components/file";
<nana-file name="Tenancy agreement - Unit 4B.pdf" size="482133" meta="Signed 1 Mar 2026" src="/files/lease-4b.pdf" removable></nana-file>
<nana-file name="meter-reading-october.jpg" size="2400000" status="uploading" progress="42"></nana-file>
<nana-file name="rent-roll.xlsx" size="88210" status="error" error="The connection dropped. Try again."></nana-file>
const el = document.querySelector("nana-file");
el.addEventListener("nana-file-open", (e) => console.log(e.detail));
el.addEventListener("nana-file-remove", (e) => console.log(e.detail));
el.addEventListener("nana-file-retry", (e) => console.log(e.detail));

Properties

PropertyAttributeTypeDefaultDescription
errorerrorstring''Why the upload failed
metametastring''Details after the size, such as who uploaded it and when
namenamestring''The file's name, with its extension
noDownloadno-downloadbooleanfalseLeave out the download link
progressprogressnumber | undefined—Upload progress, 0 to 100; leave unset while the size of the upload is unknown
removableremovablebooleanfalseOffer to remove the file
sizesizenumber | undefined—Size in bytes
srcsrcstring''Where the file can be opened or downloaded from
statusstatusFileStatus'ready'Where the file has got to
thumbnailthumbnailstring''A smaller image to show instead of loading src for a photograph
typetypestring''MIME type, when the name alone does not say what the file is
variantvariantFileVariant'row'row for a list, card for a grid

Events

EventDescription
nana-file-openThe file was chosen to open (detail.name, detail.src, detail.type)
nana-file-removeThe reader asked to remove the file, or cancel its upload
nana-file-retryThe reader asked to try a failed upload again

Slots

SlotDescription
actionsFurther controls beside the built-in ones

CSS parts

PartDescription
::part(base)The container
::part(preview)The thumbnail or file glyph
::part(name)The file name, a button that opens it
::part(meta)The size and details line, or the upload state
::part(progress)The upload bar
::part(actions)The controls
::part(download)The download link
::part(remove)The remove or cancel button
::part(retry)The retry button

CSS custom properties

PropertyDescription
--nana-file-bgBackground
--nana-file-borderBorder colour
--nana-press-scaleHow far the buttons depress on press, shared with the other pressable controls
Explore File interactively Every state, prop, and edge case — with live controls — in Storybook.
View in Storybook