File card
Shows a file as a card with its thumbnail or type icon, its name and actions. To pick files, use File selector.
Installation
The CLI installs the Radix or Base UI file to match your project, with what it builds on: icon, spinner, button, dropdown-menu.
If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.
When to use
Use it
- A record page lists its files as a grid of cards, each with a thumbnail or a type icon and its name.
- One file needs a preview people open, with Download and a menu of file actions beside its name.
- An attachment row needs a small picture of the file, like an email's attachment beside its linked name.
- Files just chosen in a File selector should show as cards before they're uploaded.
- It replaces SLDS's file card, what
lightning-file-cardand the Files related list draw.
Don't use it
- People pick or drop files. Use File selector, then show what they chose with File card.
- The upload itself, with progress and a server. The card only draws a file the page already knows.
- A plain list of files with no pictures, like names and sizes in a table or a list. Use Item or Table.
- A record or a block of content that isn't a file. Use Card.
Usage
Copy the icon package's folder to the app's static files once, unchanged, as Icon does:
mkdir -p public/assets/icons
cp -R node_modules/@salesforce-ux/icons/dist/salesforce-lightning-design-system-icons/. public/assets/icons/import {
FileCard,
FileCardActions,
FileCardCaption,
FileCardPreview,
FileCardSource,
FileCardTitle,
} from "@/components/wisty/file-card"FileCard
├── FileCardPreview
├── FileCardCaption
│ ├── FileCardTitle
│ └── FileCardActions
└── FileCardSource<FileCard name="Site survey.csv">
<FileCardPreview href="/files/site-survey" />
<FileCardCaption>
<FileCardTitle />
</FileCardCaption>
</FileCard>FileCardPreview is a link with href, a button with onClick, and a picture with neither. Its thumbnail is the image, { state: "loading" } while the page fetches one, or { state: "unavailable" } when it can't be shown. Leave it out for a file that has no image, and the preview shows its type icon. { state: "placeholder" } fills the preview with a pattern in the theme's primary colors instead, for a page with no real images yet, like a prototype over sample records. The type icon comes from the name's extension, or from icon when the page knows better:
<FileCard name="Site survey notes" icon="doctype:quip_doc">fileCardIcon(name) gives the same icon for a name, for a list that draws it elsewhere.
Examples
Crops
The placeholder pattern filling each `crop` on `FileCardPreview`, with long names truncated before the download button.
Without a title
An image with no `FileCardTitle`: `variant="scrim"` on `FileCardCaption` puts the download button on a dark gradient.
More files
Two of a record's files and a tile linking to 22 more, with `variant="overlay"` and an `aria-label` that names the link.
Email attachment
A captionless card as an attachment row's picture, beside the linked file name, its size and a download link.
Chosen files
Files just chosen in a file selector, as static cards with a Remove button and the type icon read from each name.
External source
A Quip document with `FileCardSource` naming the service it comes from, beside its own type icon.
Thumbnail states
A thumbnail still loading, one that can't be shown, and a file of an unknown type, each keeping its name and link.
API reference
| Part | Built on | Description |
|---|---|---|
FileCard | <div> (opens in a new tab) | One file as a card: a preview, and a title bar with its name and actions. |
FileCardPreview | <div> (opens in a new tab) | The cropped picture of the file: a link with href, a button with onClick, or a picture with neither. |
FileCardCaption | <div> (opens in a new tab) | The bar over the preview's bottom that holds the title and actions, or a count over the whole preview. |
FileCardTitle | <span> (opens in a new tab) | The file's type icon and its name, truncated. |
FileCardActions | <div> (opens in a new tab) | The file's own actions, like Download and a menu, beside the title or on their own. |
FileCardSource | Icon | The icon of the service the file comes from, over the preview's top start. |
FileCard
One file as a card: a preview, and a title bar with its name and actions.
| Prop | Type | Default | Description |
|---|---|---|---|
name* | string | The file's name, with its extension. | |
icon | `doctype:${FileCardDoctype}` | The type icon; defaults to the one for the name's extension. |
FileCardPreview
The cropped picture of the file: a link with href, a button with onClick, or a picture with neither.
| Prop | Type | Default | Description |
|---|---|---|---|
thumbnail | FileCardThumbnail | The image, a stand-in pattern, a loading image or one that can't be shown; omit it for the type icon. | |
crop | FileCardCrop | "16-by-9" | The crop's ratio. Default "16-by-9". |
loadingLabel | string | "Loading thumbnail" | Read while the image loads. Default "Loading thumbnail". |
unavailableLabel | string | "Thumbnail unavailable" | Shown when the image can't be. Default "Thumbnail unavailable". |
href | string | Makes the preview a link that opens the file. Not with onClick. | |
onClick | React.MouseEventHandler<HTMLButtonElement> | Makes the preview a button that runs the page's own preview. Not with href. | |
disabled | boolean | Turns the button off, with onClick. |
FileCardCaption
The bar over the preview's bottom that holds the title and actions, or a count over the whole preview.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "overlay" | "scrim" | "default" |
FileCardTitle
The file's type icon and its name, truncated.
| Prop | Type | Default | Description |
|---|---|---|---|
children | string | Words shown instead of the file's name. |
FileCardActions
The file's own actions, like Download and a menu, beside the title or on their own.
| Prop | Type | Default | Description |
|---|---|---|---|
aria-label* | string | Names the group after the file it acts on. |
FileCardSource
The icon of the service the file comes from, over the preview's top start.
| Prop | Type | Default | Description |
|---|---|---|---|
label* | string | Names the service, and is its tooltip unless title is given. |
fileCardIconfunction
The type icon for a file name's extension in any case, or "doctype:unknown".
| Parameter | Type | Default |
|---|---|---|
name* | string |
Returns "doctype:audio" | "doctype:html" | "doctype:link" | "doctype:video" | "doctype:image" | "doctype:unknown" | "doctype:overlay" | "doctype:ai" | "doctype:attachment" | "doctype:box_notes" | "doctype:css" | "doctype:csv" | "doctype:eps" | "doctype:excel" | "doctype:exe" | "doctype:flash" | "doctype:folder" | "doctype:gdoc" | "doctype:gdocs" | "doctype:gform" | "doctype:gpres" | "doctype:gsheet" | "doctype:keynote" | "doctype:library_folder" | "doctype:mp4" | "doctype:pack" | "doctype:pages" | "doctype:pdf" | "doctype:ppt" | "doctype:psd" | "doctype:quip_doc" | "doctype:quip_sheet" | "doctype:quip_slide" | "doctype:rtf" | "doctype:shared_folder" | "doctype:slack_canvas" | "doctype:slack_list_item" | "doctype:slack_lists" | "doctype:slide" | "doctype:stypi" | "doctype:txt" | "doctype:vcf" | "doctype:visio" | "doctype:webex" | "doctype:word" | "doctype:xml" | "doctype:zip".
FileCardDoctypetype
A symbol in the doctype sprite of
type FileCardDoctype =
| "ai"
| "attachment"
| "audio"
| "box_notes"
| "css"
| "csv"
| "eps"
| "excel"
| "exe"
| "flash"
| "folder"
| "gdoc"
| "gdocs"
| "gform"
| "gpres"
| "gsheet"
| "html"
| "image"
| "keynote"
| "library_folder"
| "link"
| "mp4"
| "overlay"
| "pack"
| "pages"
| "pdf"
| "ppt"
| "psd"
| "quip_doc"
| "quip_sheet"
| "quip_slide"
| "rtf"
| "shared_folder"
| "slack_canvas"
| "slack_list_item"
| "slack_lists"
| "slide"
| "stypi"
| "txt"
| "unknown"
| "vcf"
| "video"
| "visio"
| "webex"
| "word"
| "xml"
| "zip"FileCardCroptype
type FileCardCrop = "16-by-9" | "4-by-3" | "1-by-1"FileCardThumbnailtype
The preview's image, a stand-in pattern, or why there's none yet.
type FileCardThumbnail =
| { state: "image"; src: string; alt: string }
| { state: "placeholder" }
| { state: "loading" }
| { state: "unavailable" }SLDS mapping
FileCard is slds-file slds-file_card. FileCardPreview is the slds-file__crop link, with the image, the centered slds-file__icon or the medium spinner of slds-file_loading inside. FileCardCaption is slds-file__title_card by default, slds-file__title_overlay over slds-file_overlay as overlay, and slds-file__title_scrim as scrim. FileCardTitle is the small media object with the x-small type icon and slds-file__text slds-truncate. FileCardActions is slds-file__actions-menu with its button group, and FileCardSource is slds-file__external-icon.
Known gaps:
- No uncropped figure (
slds-file__figure) or portrait figure (slds-file__figure_portrait). Every preview has a crop. - No link attachment, the media object with a small file and a source line.
- The preview's eye and the action icons are lucide's, where SLDS draws its own eye and
utility:downloadandutility:down. - "Thumbnail unavailable" under the type icon is an addition. SLDS draws a missing and a broken image the same.
- The placeholder pattern is an addition. SLDS draws a file with no image as its type icon.
| Prop | Value | SLDS | Notes |
|---|---|---|---|
crop | 16-by-9 (added) | slds-file__crop slds-file__crop_16-by-9 | The default: a 16:9 preview with the image centered at its own size. |
crop | 4-by-3 (added) | slds-file__crop slds-file__crop_4-by-3 | A 4:3 preview, as a grid of a record's files uses. |
crop | 1-by-1 (added) | slds-file__crop slds-file__crop_1-by-1 | A square preview. |
variant | default (added) | slds-file__title slds-file__title_card | On FileCardCaption: the title bar over the preview's bottom, with the actions at its end. |
variant | overlay (added) | slds-file_overlay, slds-file__title slds-file__title_overlay slds-text-heading_large | On FileCardCaption: a dark layer over the whole preview with a centered count, like "+22". |
variant | scrim (added) | slds-file__title slds-file__title_scrim, slds-button_icon-inverse | On FileCardCaption: the actions alone on a gradient over the image, with inverse icons. |
(loading) | aria-busy (added) | slds-file_loading | On FileCardPreview while its image loads: a spinner, and no hover layer. |
Accessibility
- A link or button preview is named by the file's name. Give the more-files tile an
aria-labelthat says what it opens, like "Show 22 more files". - Give each action its own name with the file in it, like "Download Renewal proposal.pdf", and give
FileCardActionsanaria-label. - Write an
altthat describes the image, or""when the name beside it says it all, as in an attachment row. - While the image loads the preview is
aria-busyand described by "Loading thumbnail". When it can't be shown, by "Thumbnail unavailable". Change the words withloadingLabelandunavailableLabel.
Motion
- The spinner turns while a thumbnail loads, and stops with reduced motion.
Responsive behavior
- The card fills its container. The page sets its width or the grid's columns.
- A long name truncates before the actions, and the full name shows as the preview's tooltip.
- On a device with no hover, the dark layer and the eye don't show.
Rules
- Put actions in
FileCardActions, never insideFileCardPreview. The preview is the card's one link or button. - Give every action button
type="button"in a form, or it submits the form. - Keep
FileCardTitleandFileCardActionsin a defaultFileCardCaption. Ascrimcaption holds only actions, and anoverlaycaption only aFileCardTitlewith its count. - Pass
icononly as adoctype:symbol the icon package has. The type checks it. - Never pass
asChildorrender.