Empty state
What stands where content would be when there is none: what this is, why it is empty, and what to do next.
First use
No locations yet
Add the places where you see clients, in person or by video.
No results
No clients found
| Client | Next appointment |
|---|---|
No clients match “zzz”Check the spelling, or look in archived clients. | |
It is not a different look: it is the same block with different words. The title repeats what was searched, the action undoes it, and the action is not primary, because clearing a filter is nobody’s goal.
A section, and good news
Relevant notes
Messages
A frame that says something goes here
No documents yet
An ID card, an insurance policy, a referral letter.
variant="dashed" is the language of the drawn “+” tiles in a record’s documents: a dashed line is a place for something. So it is for first use only. On a search with no results a frame that invites making something says the wrong thing.
What did not load
Can’t load map
As drawn: the small size on a surface of its own, over the placeholder of what should have been there.
A field that has not been filled
Contacts
Location instructions
In the product this system was drawn for, a record just made is empty in place: “+ Add address” stands exactly where the address will be. That is not this component. It is a ghost Button with an icon, and needs no title and no sentence, because the heading over it has already said what is missing.
Which one
| Where | Use |
|---|---|
| A field of a record that has not been filled | a ghost Button with “+”, in the field’s place |
| A section or a card with nothing in it | EmptyState, sm |
| A table, a list or a page with nothing in it | EmptyState, lg |
| A picture, a map or a chart that did not load | EmptyState, sm, on a surface of its own over the placeholder |
| A Select or a Combobox with no options | their own line: emptyText |
What it says
| Rule | Why |
|---|---|
| The title says what is not here | “No locations yet”, never “Oops” or “Nothing here”. |
| The sentence says why, or what happens next | It is the one place the feature is explained to someone who has not used it. |
| The action is the verb and the thing | “Add location”, the same words as the button that makes one everywhere else. |
| Two actions at most, one primary | The other way — an import, something to read — comes first and is quieter. |
| No results: repeat what was searched, and undo | The action clears the search and is not primary: clearing a filter is nobody’s goal. |
| Good news has no action | “No unread messages” is where the reader wanted to be. |
| Loading is never empty | A Skeleton first, and this only once the answer is none. |
Accessibility
The title is a heading, so the block is in the page’s outline; headingLevel is one below the heading it stands under. The icon is hidden; media is not, since an illustration may have words of its own, and takes its own alt. The block announces nothing by itself: when results change under a filter, how many were found is the caller’s live region to say. The circle is the pressed wash and not a surface, so one block is right on the page, on a card and in a panel, in both modes.
Using it
import { EmptyState, Button, Table } from 'alpenglow';
// First use: a table with nothing in it.
<Table
…
rows={locations}
empty={
<EmptyState
icon={<Location size={24} />}
title="No locations yet"
description="Add the places where you see clients, in person or by video."
action={<Button onClick={add}>Add location</Button>}
/>
}
/>
// A section of a record.
<EmptyState size="sm" title="No notes yet" description="…" action={<Button variant="ghost" …>Add note</Button>} />| Prop | Type | Default |
|---|---|---|
title | string | required |
description | React | — |
icon | React | — |
media | React | — |
action | React | — |
secondaryAction | React | — |
size | 'sm' | 'lg' | 'lg' |
variant | 'plain' | 'dashed' | 'plain' |
headingLevel | 2 | 3 | 4 | 5 | 6 | 3 |
className | string | — |