Browse all of Kata

Empty state

Source docs/design/components/empty-state.mdMarkdown

On this page

What a screen or section shows when there is genuinely nothing in it: what goes here, why, and one way to start.

Light

align="left" · the Kata anatomy

Grading

Nothing graded yet

Add what you’re teaching to start grading.

Add a techniqueSee last month’s list

Dark

align="left" · the Kata anatomy

Grading

Nothing graded yet

Add what you’re teaching to start grading.

Add a techniqueSee last month’s list

Source: EmptyState.tsx. When a screen should be empty at all, and the loading and error states beside it: states.

When to use it

  • After asking whether the screen should be empty. Real data elsewhere that belongs here? Show it. Something you can suggest from a real source? Suggest it.
  • Only then: an empty collection. An empty search is different — keep the field and filters and say what matched nothing.

Use align="left" for anything new. The centred shape is frozen for its existing call sites.

Anatomy

align="left" — the Kata anatomy, in flow on the page's own gutter:

Part Token
Block spacing.section 24 above and below, no horizontal padding, spacing.s8 between parts
Eyebrow typography.eyebrow, text.secondary
Title typography.title 22/700, text.primary
Body typography.body, text.secondary — what goes here and why
Primary the red pill: brand.red, 48 floor, typography.rowTitle, brand.onRed, spacing.s8 extra above
Link typography.label 13/700 in accent.red, 32 drawn plus hitSlop to 44

align="center" — the legacy shape:

Light

align="center" · frozen legacy shape

No events yet

Camps, tests and seminars show up here.

Create an event

Dark

align="center" · frozen legacy shape

No events yet

Camps, tests and seminars show up here.

Create an event
Part Token
Block centred, spacing.s64 vertical, spacing.detailHorizontal 24 horizontal
Glyph 36pt in text.quaternary — off the icon ramp and frozen; do not copy it
Title typography.rowTitle, centred
Action red pill, typography.buttonMedium, spacing.s16 above, hitSlop to 44

States

  • An empty state is itself a state. Its actions press at opacity.pressed 0.85.
  • While it shows, demote the screen's other primary: one filled primary per screen.
  • Loading is never an empty state. Show nothing under a second, then a spinner or skeleton.
  • An error uses the same left anatomy with "Couldn't load …" and a retry.

Content

  • Title says what is missing, plainly: "Nothing graded yet".
  • Body says what goes here and how it gets there: "Add what you're teaching to start grading."
  • No exclamation marks, no "let's", no apology. The ninja may appear in an empty state; a cheerful line about nothing may not.

Accessibility

  • The primary and the link are role button, labelled with their visible text, each 44pt or more.
  • Left-aligned and in flow, so it is read in the order it is seen, right after the screen title.

Do and don't

Students

No students yet

Invite your first student to start taking attendance.

Invite a student

Do

Left-aligned and in flow: what goes here, why, and one way to start.

Nothing here yet — let’s fix that!

Get started

Don’t

A centred line in a void, cheerful about nothing.

Code

import { EmptyState } from '../../components/ui';

<EmptyState
  align="left"
  eyebrow="Grading"
  title="Nothing graded yet"
  subtitle="Add what you're teaching to start grading."
  action={{ label: 'Add a technique', onPress: addTechnique, testID: 'grading-empty-add' }}
  link={{ label: "See last month's list", onPress: openLastMonth, testID: 'grading-empty-last-month' }}
  testID="grading-empty"
/>