Skip to content
RU
Scale
Density
Theme
Accent

Feedback

Empty state

A region with nothing to show yet. An empty state is not the absence of an interface but a screen in its own right: it explains why it is empty and gives a way out.

The component
No runs yet
A launch creates a queue of agents and a log, and they will appear here.
Markup
<div class="inst-panel">
  <div class="inst-empty">
    <div class="inst-empty-title">No runs yet</div>
    <div class="inst-empty-desc">A launch creates a queue of agents and a log, and they will appear here.</div>
    <button class="inst-btn inst-btn--sm" type="button">Start the first one</button>
  </div>
</div>

Contract

What Required Why
A heading naming the reason yes "Nothing found" with no reason reads as a breakage
An aria-live="polite" on the container yes, if the list emptied because of a filter Otherwise for a screen reader simply nothing happened
A real heading of the right level yes, if it takes a whole region inst-empty-title styles but does not declare
An action no An ordinary button; it has no class of its own

Accessibility

Appearing after an action If the list emptied because of a filter, the message has to reach an aria-live="polite" — otherwise for a screen reader simply nothing happened
The heading A real heading of the right level, if the empty state takes a whole region
Not an illustration alone There is no picture in the component: the meaning is carried by the text. An empty state made of one icon says nothing
Contrast The text takes --text-muted (4.5:1) rather than --text-faint: this is data that gets read rather than decoration

Variants

Three different kinds of "empty". They are confused, and each calls for a text of its own.

Why it is empty What to write The action
Not started yet What will appear here and where from A button creating the first object
A filter found nothing Which filter is applied "Reset the filter"
Everything is done That the list is empty for a good reason Usually not needed
Example
No runs yet
A launch creates a queue of agents and a log, and they will appear here.
Nothing matched the "failed" filter
Over the last day every run finished successfully.
The queue is empty
Every task has been taken.
Markup
<div class="inst-empty">
  <div class="inst-empty-title">No runs yet</div>
  <div class="inst-empty-desc">A launch creates a queue of agents and a log, and they will appear here.</div>
  <button class="inst-btn inst-btn--sm" type="button">Start the first one</button>
</div>
<div class="inst-empty">
  <div class="inst-empty-title">Nothing matched the "failed" filter</div>
  <div class="inst-empty-desc">Over the last day every run finished successfully.</div>
  <button class="inst-btn inst-btn--sm" type="button">Reset the filter</button>
</div>
<div class="inst-empty">
  <div class="inst-empty-title">The queue is empty</div>
  <div class="inst-empty-desc">Every task has been taken.</div>
</div>

The text "Nothing found" with no reason given suits the second case only and in the first reads as a breakage.

API

Classes
NameWhat it does
class
inst-emptyThe container; it centres the content
inst-empty-titleThe heading: why it is empty
inst-empty-descThe explanation
Tokens
NameValueWhere from
token
--space-948pxone across every cell
--space-616pxone across every cell
--gap-inlinevar(--space-4)base +14: density · scale
--text-sm0.875rembase +4: scale
--text-mutedlight-dark(var(--n-8), var(--n-6))one across every cell

Why the kit works this way — the constitution · Open source under MIT, github.com/keshon/instrument