# EmptyState A collection with nothing in it — yet. - Group: Feedback - Import: `import { EmptyState } from '@misoto22/folio'` - Page: https://ui.misoto22.com/components/empty-state/ - Related: error-state, skeleton ## When to reach for it Nothing went wrong. The copy says what to do, not what failed. ## Anatomy - **Frame** (required) — A centred column with 80px of padding above and below and --page-pad either side. View-scale, and carrying no role and no live region of its own. - **Medallion** — The optional Remix Icon glyph at 24px inside a 56px --stone circle, aria-hidden. Decoration that gives the column something to start from, never the message. - **Title** (required) — title in the heading face at --fs-sub, rendered through Heading. level picks the element and defaults to 2; the size does not follow it, so the title is --fs-sub at every level. - **Description** — description in --ink-3-aa, capped at 24rem so it stays a readable measure while the column stays centred. - **Action** — The one thing to do next, 32px below the description and the only interactive element the frame offers. ## Best practices ### Do - Announce the swap yourself. This component has no role and no live region, so replacing a SkeletonPage with it removes the region that said “Loading projects” and puts nothing in its place — a screen reader is left at the last thing it heard. - Say which kind of empty this is. The same component serves a collection that is new and one that a filter has emptied, and “No projects yet” shown over an active filter tells the reader their projects are gone. - Set level from the heading above it. The default of 2 is right directly under a page’s h1; inside a section that already has its own h2, pass 3. Get it wrong and the outline gains a hole a screen reader navigates by. ### Don’t - Do not show it for a failed request. A reader told the collection is empty acts on it — creating the record they already have, or reporting a data loss that never happened — and the recovery from that costs more than the error page would have. - Do not put it inside a card or a panel. 160px of vertical padding is sized to stand in for a view, and in a bordered box it reads as a box with a hole in it. - Do not write a paragraph into description. It is capped at 24rem and centred, so long copy becomes a narrow ragged column that the eye returns from before the sentence that mattered. ## EmptyState A collection with nothing in it — yet. Distinct from `ErrorState`: nothing went wrong here, so the copy says what to do rather than what failed. The two are different components because the shared temptation — one component with a `variant` — produces error pages that read like empty folders. ### Props - `icon` — `RemixiconComponentType`. Optional Remix Icon glyph, shown muted inside a quiet circle. - `title` (required) — `ReactNode`. - `description` — `ReactNode`. - `action` — `ReactNode`. The one thing to do next. An empty state without an action is a dead end. - `level` — `HeadingLevel` default `2`. The heading level `title` opens, in the document the empty state lands in. Defaults to `2`, which is the placement this component is sized for: it stands in for a whole view inside a page that already has an `h1`, so the level below that one is the level that does not leave a hole in heading navigation. Under a section that already has its own `h2`, pass `3`. The default was `3` and fixed, which was wrong in the ordinary case and impossible to correct — the documentation could name the rule but a caller had no prop to follow it with. `2` is the common case rather than a compromise, and it is optional rather than required because the correct placement has one answer often enough that making every existing call site restate it would buy nothing. The size does not follow the level. `title` renders at `--fs-sub` at every level, because moving a state down the outline is a fact about the document and not a request for smaller type. Also accepts: `Omit, 'title'>`. ## Example — default ```tsx import { Button, EmptyState } from '@misoto22/folio' New project} /> ``` ## Example — emptied by a filter ```tsx import { Button, EmptyState, Tag } from '@misoto22/folio'
Archived 2019
Clear filters} />
``` ## Example — empty or failed ```tsx import { Button, EmptyState, ERROR_ACTION_CLASS, ErrorState } from '@misoto22/folio'
New invoice} /> Check service status} />
```