Skip to content
Protocore Design Systemv1.6.9

/// Feedback

EmptyState

A centered, dashed-frame placeholder for a surface that legitimately has nothing to show.

import { EmptyState } from "@protocore/pds";
View as Markdown

Basics

A title and a description inside a dashed frame. The eyebrow defaults to NO DATA; override it to name the specific thing that's missing.

NO DATA
No deployments yet

Nodes you provision will show up here with their health and region.

With icon and action

Add an icon for recognition and an action (usually a Button) that resolves the emptiness — the single most useful next step.

NO NODES
Provision your first node

Spin up a validator to start earning protocol rewards on the ledger.

Empty vs. no results

"Nothing exists yet" and "nothing matches your filter" are different states. The first invites creation; the second offers a way back out of the filter.

NO MATCHES
No entries match “slashing”

Try a broader query or clear the active filters.

The five-state doctrine

EmptyState is state 2 of the five every data surface must render — *loading, empty, error, pending, data*. It means the request succeeded and the answer is genuinely nothing.

  • Still fetching? That's loading — a LoadingSkeleton, not an empty state.
  • Request failed? That's error — an ErrorState. Never show "No data" when you actually failed to fetch it; it hides the problem and blocks retry.
  • Mutation over existing rows? That's pending — keep the data, layer a Spinner.

Getting this distinction right is the whole point of the doctrine: an empty state is an answer, not an absence of one.

Usage

Do

  • Reserve EmptyState for a successful fetch that returned nothing.
  • Offer one clear next action ("Provision node", "Clear filters").
  • Distinguish "nothing yet" (invite creation) from "no matches" (offer escape).
  • Rewrite the eyebrow and title to name the specific missing thing.

Don't

  • Use EmptyState to mask a failed request — that's an ErrorState.
  • Show it while data is still loading.
  • Leave the generic "NO DATA" eyebrow on a user-facing screen.
  • Stack multiple competing actions inside one empty state.

Accessibility

  • EmptyState renders as a plain region — it is informational, not an alert, so it is not announced assertively.
  • The `icon` slot is decorative and marked `aria-hidden`; meaning must live in the title and description text.
  • Any `action` you pass (e.g. a Button) keeps its own semantics and keyboard behavior.
  • Ensure the title conveys the state in words, never through the dashed frame or icon alone.

Mobile (React Native)

Preview. @protocore/pds-mobile ships the React Native sibling of EmptyState. It mirrors the web API where React Native allows; the package is a preview with no device-level QA yet, so pin it and expect small changes.

Import it from the mobile package (not @protocore/pds), inside a <PdsProvider> — there is no stylesheet, so style (a ViewStyle) replaces className and every value comes from the theme:

import { EmptyState } from "@protocore/pds-mobile";

Parity with web. A centered "no data" panel inside a dashed hairline frame.

  • Slots: icon, a mono uppercase eyebrow (default NO DATA), title, description, and an action (e.g. a Button).
<EmptyState
  eyebrow="NO DEPLOYS"
  title="Nothing shipped yet"
  description="Your deployments will show up here."
  action={<Button>Deploy service</Button>}
/>

EmptyState props

PropTypeDefaultDescription
actionReactNodeAction slot (e.g. a Button) shown below the body.
classNamestring
descriptionReactNodeSecondary explanatory copy.
eyebrowReactNodeNO DATAMono uppercase eyebrow above the title.
iconReactNodeOptional decorative icon slot, rendered above the eyebrow.
styleCSSProperties
titleReactNodeSentence-case headline.

Related

  • ErrorStateA centered failure panel with a danger accent rule, optional debugId tag and a retry affordance.
  • LoadingSkeletonShimmering placeholder blocks that hold a layout while its real content loads.
  • ButtonThe system action control — mono uppercase label, sharp corners, and a primary fill that inverts on hover.