A stroke glyph rendered in a recessed icon well above the title (muted by default).
description
string
n/a
Supporting line under the title (body.medium role). Keep it to one or two short sentences.
tone
'neutral' | 'brand' | 'error'
'neutral'
Icon-well treatment: neutral muted, brand cyan (first-run), error warm status (failed-to-load). Never color alone, always paired with icon + text.
actions
ReactNode
n/a
Optional call-to-action(s), typically one primary Button plus an optional ghost. Centered under the description.
compact
boolean
false
Denser rhythm + smaller well for a short inline list rather than a full region.
Parameter
Type
Default
Description
title *
String
n/a
The headline. Rendered with typography.titleMedium.
icon
ImageVector
n/a
Leading illustration. Drawn at 48.dp, tinted onCardAltMuted @ alpha 0.5.
description
String?
null
Supporting line (typography.bodyMedium, onCardAltMuted). Context-aware per filter tab in lists (e.g. "No unread notifications").
modifier
Modifier
Modifier.fillMaxSize()
The centered Column fills the region (Arrangement.Center, CenterHorizontally).
action
(@Composable -> Unit)?
null
Optional trailing action, typically a NockerlButton. The error arm uses TERTIARY.
SwiftUI uses the systemContentUnavailableView; there is no custom Nockerl
type. State (empty vs. no-results) is decided by the caller and reflected in the
title/description; the actions/label come from view-builder closures.
Parameter
Type
Default
Description
title *
LocalizedStringKey
n/a
The headline (first positional argument). No-results gets its own title ("No matches").
systemImage *
String
n/a
An SF Symbol name (e.g. "waveform") drawn above the title.
description
Text?
nil
Supporting line under the title.
actions
() -> View
n/a
Closure-form only: a trailing actions builder (e.g. a Retry Button with a Nockerl ButtonStyle). Not available on the short initializer.
Cross-platform drift (tracked for reconciliation)
The web spec is in review; the shipped platforms diverge on the empty-state primitive:
No shared component. Android hand-rolls a centered Column per screen (no
NockerlEmptyState yet); Voice uses the systemContentUnavailableView;
web is unshipped. The Compose pattern above should be promoted to a real
core/ui composable so all empties match.
Icon language(resolved): empty-state illustrations are
our stroke-SVG brand set on all platforms (the web’s token-colored inline strokes); utility
glyphs stay platform-native (Material / SF). Android’s ImageVector tint and Voice’s SF Symbols
give way to the shared brand set for the illustration slot.
CTA support. Android + web allow an action (Retry / Create); Voice’s empties
ship text-only (no action on the short ContentUnavailableView). Use the
closure form when an action is needed.
Title role. Web/Android settle on title.medium/large; the chat/no-session
arm on Android still uses displayMedium + a wordmark, which is out of scope for
the generic empty state.