Skip to content

EmptyState

What to show when there is nothing to show (first use, no results, an error), always with the next step.

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Static content

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

No members yet

Invite people to work on projects with you.

Show the code

Default, code

<EmptyState
  title="No members yet"
  icon={UserPlus}
  description="Invite people to work on projects with you."
  actions={<Button iconStart={UserPlus}>Invite people</Button>}
/>

No results

No matches for "invoice 2024"

Check the spelling or search for something shorter.

Show the code

No results, code

<EmptyState
  kind="no-results"
  icon={Search}
  title="No matches for "invoice 2024""
  description="Check the spelling or search for something shorter."
  actions={<Button variant="outline">Clear search</Button>}
/>

Error

We could not load your projects

Your connection may have dropped. Your work is safe.

Show the code

Error, code

<EmptyState
  kind="error"
  icon={CircleAlert}
  title="We could not load your projects"
  description="Your connection may have dropped. Your work is safe."
  actions={<Button>Try again</Button>}
/>

Success

All invoices are paid

Nothing is overdue. New invoices will show here.

Show the code

Success, code

<EmptyState
  kind="success"
  icon={CircleCheck}
  title="All invoices are paid"
  description="Nothing is overdue. New invoices will show here."
  actions={<Button variant="outline">View paid invoices</Button>}
/>

Offline

You are offline

Reconnect to see your latest messages. Drafts are saved on this device.

Show the code

Offline, code

<EmptyState
  kind="offline"
  icon={WifiOff}
  title="You are offline"
  description="Reconnect to see your latest messages. Drafts are saved on this device."
  actions={<Button>Try again</Button>}
/>

No data

No sales in this period

Choose a longer period or a different shop.

Show the code

No data, code

<EmptyState
  kind="no-data"
  icon={ChartNoAxesColumn}
  title="No sales in this period"
  description="Choose a longer period or a different shop."
  actions={<Button variant="outline">Change period</Button>}
/>

Compact

No data for this week

Sales will show here once you have some.

Show the code

Compact, code

<EmptyState
  kind="no-data"
  size="compact"
  icon={ChartNoAxesColumn}
  headingLevel={3}
  title="No data for this week"
  description="Sales will show here once you have some."
/>

Stacked actions

You are offline

Reconnect to send your message.

Show the code

Stacked actions, code

<EmptyState
  kind="offline"
  icon={WifiOff}
  title="You are offline"
  description="Reconnect to send your message."
  actionsLayout="stack"
  actions={<><Button>Try again</Button><Button variant="outline">Open saved drafts</Button></>}
/>

With illustration

Your inbox is empty

New messages will show here.

Show the code

With illustration, code

<EmptyState
  title="Your inbox is empty"
  description="New messages will show here."
  illustration={<div aria-hidden="true" className="rounded-control bg-surface-muted" style={{ width: 160, height: 120 }} />}
  actions={<Button>Write a message</Button>}
/>

Tokens

The 13 design tokens EmptyState reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 13 tokens
Tokens EmptyState reads
TokenValue nowCSS variable
color.bg.muted…--sd-color-bg-muted
color.icon.danger…--sd-color-icon-danger
color.icon.default…--sd-color-icon-default
color.icon.success…--sd-color-icon-success
color.text.default…--sd-color-text-default
color.text.secondary…--sd-color-text-secondary
radius.full…--sd-radius-full
spacing.gap.sm…--sd-spacing-gap-sm
spacing.inset.lg…--sd-spacing-inset-lg
spacing.inset.md…--sd-spacing-inset-md
spacing.inset.xl…--sd-spacing-inset-xl
spacing.stack.sm…--sd-spacing-stack-sm
spacing.stack.xs…--sd-spacing-stack-xs

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { EmptyState } from "@superduperui/react"

Props

EmptyState also takes the props of the React Aria component it’s built on.

EmptyState props
PropTypeWhat it does
titlerequiredstringShort heading: what is empty, or what went wrong ("No invoices yet").
descriptionReactNodeOne or two sentences: why, and what to do next (3.3.5).
iconLucideIconDecorative Lucide icon above the title.
illustrationReactNodeA larger picture above the title, in place of the icon disc. Decorative: give an image alt="".
actionsReactNodeThe next step: usually one Button (and at most one secondary action). For errors, a retry.
actionsLayout'row' | 'stack'Default 'row'row (default): actions side by side, centred. stack: a column of full-width buttons, for phones.
size'default' | 'compact'Default 'default'default, or compact: the small state inside a chart, card or table.
headingLevel2 | 3 | 4 | 5 | 6Default 2Heading level so it fits the page outline (2.4.10). Default 2.
kind'first-use' | 'no-results' | 'error' | 'success' | 'offline' | 'no-data'Default 'first-use'What the state is about: first-use, no-results, error, success, offline or no-data (nothing for this period). It colours the icon (error danger, success success; the rest neutral) and documents intent. Say the kind in the title too: colour is never the only cue.
classNamestring

When to use it

Use it for

  • Empty lists and tables
  • Search with no results
  • Load errors with a retry

Use something else for

  • Loading: use Skeleton
  • Inline field errors

Accessibility

Screen readers announce "No members yet, heading level 2", then the description and the button.

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.3.2.

Compact density meets AA (2.5.8, 24px targets), not AAA.

What your product still has to do

  • Always offer a next step

Shared patterns it ships with: 2.4.10 (headingLevel); 3.3.5 (says what to do next).

This release’s test results

Test results for EmptyState in this release
axe-core (WCAG A, AA, AAA and best practice)200 runs across every story, theme, density and width: 0 violations
Rendered text contrast235 text runs: 0 below 7:1, lowest 11.42:1
Target size28 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)18 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 1 of 1, Firefox 1 of 1, WebKit 1 of 1

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

EmptyState keyboard steps
KeyWhat happens
TabTab reaches the next step (retry)

In Figma

The Figma component is EmptyState, with Kind (First use, No results, Error, Success, Offline, No data); Actions layout (Row, Stack); Size (Default, Compact). The Figma library isn’t published yet.

Figma to code: Kind → kind (First use = "first-use", No results = "no-results", Error = "error", Success = "success", Offline = "offline", No data = "no-data"); Title → title; Description → description when Show description; Icon → icon when Show icon; Actions → actions; Actions layout → actionsLayout (Row = "row", Stack = "stack"); Size → size (Default = "default", Compact = "compact"); Media → illustration when Show illustration.