Skip to content

Components · Status and feedback

EmptyState

What will appear here, and the action that creates it.

@rookcom/monarch-reactComponent

First run

No tickets yet

New tickets from your inbox and portal appear here.

Press N to create a ticket from anywhere.

Usage examples

Filtered and all clear

One line

Purpose

Shown when there is nothing to display: says what will appear and offers the action that creates it, or a way back when a filter matched nothing.

Use when

  • A list, table or view has no items yet (kind="first-run", the default).
  • A search or filter returns nothing (kind="filtered" with onClearFilters).
  • A queue is empty because the work is done (kind="success").
  • A dashboard section or table body is empty and needs a one-line note (layout="line", size="compact").

Avoid when

  • Loading failed: use ErrorState or InlineErrorRetry.
  • Content is still loading: use LoadingState.
  • A whole route is missing or forbidden: use ErrorPage.

Design principles

  • Say what will appear here, then offer the action that creates it. The product writes every word; the component only lays it out.
  • First-run and filtered states read differently: first-run explains and invites, filtered offers a way back (Clear filters) rather than a create action.
  • The heading level is configurable so the state fits the page outline; p avoids a heading inside a table cell.
  • One accent-tinted icon tile at most; success switches it to the success tint. The rest stays neutral.

API reference

import { EmptyState } from '@rookcom/monarch-react';
ExportKindRenderingRoot class
EmptyStatecomponentserver-safe.mn-empty-state

All native <div> attributes pass through, and the ref is forwarded to the root <div>.

children render after the actions (for example a short list of next steps); tip renders last in small muted text.

Generated from the TypeScript declarations of packages/react/src/components/feedback/empty-state.

Properties

EmptyState

Shown when there is nothing to display yet. Say what will appear here and offer the action that creates it.

PropTypeDescription
title requiredReactNode
actionsReactNodePrimary and secondary actions, usually Buttons.
childrenReactNodeExtra content after the actions, such as a list of next steps.
classNamestring
clearFiltersLabelstringLabel of the clear-filters button. Default "Clear filters".
descriptionReactNode
headingLevelEmptyStateHeadingLevelTitle element. Default `h3`. Match the page outline (no skipped levels); use `p` where a heading would be wrong, such as inside a table cell.
iconReactNodeDecorative icon in a tinted tile. Hidden from assistive technology.
idstring
kindEmptyStateKindWhy the view is empty. Exposed as `data-kind`. Default `first-run`.
layout"stack" | "line"`stack` (default) centres icon, text and actions in a column; `line` is a single left-aligned row (icon, text, actions) for a list or dashboard section that has nothing in it.
onClearFilters(() => void)With `kind="filtered"`, renders a "Clear filters" button before any other actions. The product resets its own filters.
size"inline" | "page" | "compact"`inline` (default) sits inside a card or table; `page` fills an empty view; `compact` is a tighter block for table bodies, side panels and small cards.
tipReactNodeA short hint under the actions, such as a keyboard shortcut (compose it with Kbd). Shown in small muted text.

Variants

PropValuesDescription
size'inline''page''compact'inline (default) sits inside a card or table; page adds vertical padding to fill a view; compact tightens padding, icon and title for table bodies and side panels. Exposed as data-size.
layout'stack''line'stack (default) centres everything in a column; line is one left-aligned row of icon, text and actions. line is exposed as data-layout="line".
kind'first-run''filtered''success'filtered adds a Clear filters button when onClearFilters is set; success uses the success tint and a check icon when no icon is given. Non-default kinds are exposed as data-kind.
headingLevel'h1''h2''h3''h4''h5''h6''p'Title element. Default h3.

States

StateExposed asBehaviour
First run–The default: icon, title, description and actions.
Filtereddata-kind="filtered"Clear filters (secondary button, label clearFiltersLabel) is rendered before the other actions.
Successdata-kind="success"Success-tinted icon tile; a check icon when no icon is passed.

Interaction behaviour

  • Clear filters calls onClearFilters; the product resets its own filters and the list re-renders.
  • Other actions keep their own behaviour.

Keyboard support

KeysAction
Tab / Shift+TabMoves through Clear filters and the actions, in that order.
Enter / SpaceActivates the focused action.

The empty state itself is not focusable.

Accessibility

Role
none; the title is a heading (or a paragraph with headingLevel="p")
Accessible name
–
  • The icon tile is aria-hidden; meaning is carried by the title.
  • The title is a real heading (h3 by default); pick the level that continues the page outline instead of skipping levels.
  • No live region: an empty state is page content, not an announcement. When it replaces results after a filter change, the product announces the result count itself.
  • Verified with axe in jsdom (each kind and layout) and in Chromium, Firefox and WebKit on /components/empty-state.

Responsive behaviour

  • stack is centred with a 28rem maximum width; text wraps at narrow widths and actions wrap onto new lines.
  • line wraps: the text takes the remaining width (12rem minimum) and the actions drop below it at 320px.

Theme support

  • The icon tile uses the accent subtle and strong tokens, so it follows the product accent; success uses the success tokens.
  • Colours are Monarch semantic tokens only, so light, dark and more-contrast themes apply automatically.

Do and don't

Do

  • Describe what will appear, not that nothing is there.
  • Offer at most one primary action.
  • Use kind="filtered" when a filter is active, so the way out is Clear filters, not Create.
  • Keep next-step logic (which action to suggest) in the product and pass the result as actions.

Don't

  • Do not use an empty state to report an error.
  • Do not reuse the first-run copy for a filtered result: "No tickets yet" is wrong when tickets exist but are filtered out.

Dependencies

KindDepends on
npm packagesreact
Monarch componentsButton

Testing coverage

  • Renders the title as an h3 by default; headingLevel changes it, p renders no heading.
  • Default props keep the 0.3 markup (no data-kind or data-layout; decorative icon).
  • Filtered renders Clear filters first and activates it from the keyboard; other kinds never render it.
  • Success shows a check icon unless one is passed; line and compact are exposed as data attributes.
  • Tip and children render after the actions; the ref is forwarded.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines: /__gallery; Cross-browser axe: /components/empty-state

Tests: packages/react/src/components/feedback/empty-state