Skip to content

Empty State

What to show when a list, table or page has nothing in it yet: a short explanation and the next step.

Feedbackv0.1.0experimentalWCAG 2.2 AAView spec

No projects yet

Projects keep your files, tasks and people in one place. Create your first to get started.

import { Button, EmptyState } from "@rdloom/react";

const FolderIcon = () => (
  <svg viewBox="0 0 20 20" fill="none" aria-hidden="true">
    <path d="M2.75 5.5A1.5 1.5 0 0 1 4.25 4h3.4l1.6 1.75h6.5a1.5 1.5 0 0 1 1.5 1.5v6.75a1.5 1.5 0 0 1-1.5 1.5H4.25a1.5 1.5 0 0 1-1.5-1.5V5.5z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round" />
  </svg>
);

export default function EmptyStateBasicExample() {
  return (
    <div className="w-[28rem] max-w-full">
      <EmptyState icon={<FolderIcon />} title="No projects yet" description="Projects keep your files, tasks and people in one place. Create your first to get started.">
        <Button>Create project</Button>
        <Button variant="ghost">Import</Button>
      </EmptyState>
    </div>
  );
}

Installation

npx rdloom add empty-state

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/empty-state.json

Works, but without upgrade tracking.

Usage

import { Button, EmptyState } from "@rdloom/react";

<div className="w-[28rem] max-w-full">
  <EmptyState icon={<FolderIcon />} title="No projects yet" description="Projects keep your files, tasks and people in one place. Create your first to get started.">
    <Button>Create project</Button>
    <Button variant="ghost">Import</Button>
  </EmptyState>
</div>

No results

No results for “invoice”

Check the spelling or try a broader search.

import { Button, EmptyState } from "@rdloom/react";

const SearchIcon = () => (
  <svg viewBox="0 0 20 20" fill="none" aria-hidden="true">
    <circle cx="9" cy="9" r="5.75" stroke="currentColor" strokeWidth="1.5" />
    <path d="M13.5 13.5L17 17" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
  </svg>
);

export default function EmptyStateNoResultsExample() {
  return (
    <div className="w-[28rem] max-w-full">
      <EmptyState icon={<SearchIcon />} title="No results for “invoice”" description="Check the spelling or try a broader search.">
        <Button variant="secondary">Clear search</Button>
      </EmptyState>
    </div>
  );
}

Compact

No comments

Be the first to reply.

import { EmptyState } from "@rdloom/react";

export default function EmptyStateCompactExample() {
  return (
    <div className="w-72">
      <EmptyState size="sm" headingLevel={4} title="No comments" description="Be the first to reply." />
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
titlerequired

Short headline, e.g. "No projects yet".

stringnone
description

One or two sentences on why it is empty and what to do.

stringnone
icon

Optional illustration or icon, shown above the title. Decorative: it is hidden from screen readers.

nodenone
children

Actions, usually one or two Buttons.

nodenone
headingLevel

Heading level of the title, 2 to 6.

number3
size

sm for inside a card or table, md for a whole page or panel.

"sm" | "md""md"

Accessibility

Role none, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

Not interactive.

Screen readers announce

  • Read in order: title, description, then the actions

What your code must do

  • The title is a real heading at the level you choose
  • The icon is decorative (aria-hidden): the title and description carry the meaning
  • Actions are ordinary buttons or links in the normal tab order
  • It is not announced as an alert: it is the page's content, not an interruption

Guidelines

Use it when

  • A first-run screen, an empty list or a search with no results
  • Telling people the next step when there is no data

Avoid it when

  • An error: use Alert
  • Data that is loading: use Skeleton

Don't

  • Only a picture with no words
  • No next step
  • Using it for errors

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-surface-subtle
  • --rd-color-border-default
  • --rd-color-text-default
  • --rd-color-text-muted
  • --rd-radius-overlay