A centred status block — how an operation ended or what state a screen is in.
Payment completed
The receipt is in your email
A centred status block — how an operation ended or what state a screen is in.
The receipt is in your email
StatusItem reports a result or a state in one centred block — the picture of the state, a title, a subtitle and, when the user can act on it, one button. Five types share one layout: success, error, no connection, empty state and warning. Two sizes: Standard for a screen or a tall sheet, Compact for a smaller area.
Subtitle
Subtitle
Two states — Standard and Skeleton. The block itself is not interactive: no pressed, hover, focused or disabled look; the button carries its own states. The type is content, not a state — the host replaces the block.
Check the details and try again
Standard: the type's illustration — a square vector at 240, fixed in every SP mode. The no-connection type stages the subtitle off.
illu/status/indrive-success-state-color.svg
illu/status/indrive-error-state-color.svg
illu/status/indrive-no-internet-color.svg
illu/status/indrive-empty-state-color.svg
illu/status/indrive-warning-state-color.svg
The receipt is in your email
Check the details and try again
Try another address
Some of them expire soon
Compact: a Squircle M (var(--sp-s48)) tinted per type; empty state is the Squircle's Standard state with its border on.
check — the icon.--pastel-green1 — the Squircle fill.--text-and-icon-success — the icon colour.
close — the icon.--pastel-red1 — the Squircle fill.--text-and-icon-error — the icon colour.
internet-off — the icon.--pastel-red1 — the Squircle fill.--text-and-icon-error — the icon colour.
search — the icon.--surface-on-white — the Squircle fill, with its border on.--text-and-icon-primary — the icon colour.
warning-tr-outline — the icon.--pastel-orange1 — the Squircle fill.--text-and-icon-warning — the icon colour.
The receipt is in your email
Check the details and try again
Try another address
Some of them expire soon
A vertical stack of two slots, centred, with no surface of its own — no fill, border or radius; the host's background shows through.
Subtitle
Check the details and try again
L (Standard) or S (Compact); hugs its label.Optional — on by default. A second action belongs to the host.
StatusItem fills its host's width — Figma stages it at 360, the phone width. The slots own the spacing; the block has no padding or gap of its own.
Subtitle
Subtitle
pushButton, the button's own motion; StatusItem adds none.
StatusItem stays on screen until the state changes — the content of a screen, a section or a bottom sheet. Short-lived feedback is a Notification or a Snackbar; a page-level banner is a HeaderAlert. The Empty State pattern places the empty-state type on a screen.
The receipt is in your email
Try another address
Check the details and try again
The words carry the whole message. Two stops — the text, read as one heading, and the button; a third only for a Custom top slot whose content carries information. What is shown is what is read.
Check the details and try again
<img alt=""> and aria-hidden on the web, contentDescription = null / clearAndSetSemantics {} on TalkBack, accessibilityHidden(true) on VoiceOver.Colour is not the only signal — error and no connection share a red Squircle; the text tells them apart.Accepted gap: with both text lines off the picture is the only sign of the state; the host gives it a text equivalent elsewhere.
semantics(mergeDescendants = true) { heading() }, VoiceOver children: .combine + .isHeader.Web: a heading (level from the host's outline) and a <p> — the browser reads two lines, the heading first. With the title off the subtitle stays a <p>, so no heading remains on the web; the platforms keep the trait.What is shown is what is read: a line that is off is not read; with both off there is no text element and the button is the only stop.
::after; on the shipped mobile builds unverified.
ACTION_ACCESSIBILITY_FOCUS on the merged text; Compose has no public focus API — paneTitle carries the whole text (title and subtitle), a recorded gap. VoiceOver @AccessibilityFocusState / .screenChanged. Web .focus() on .status-item__text, which carries tabindex="-1".Replacing a section — one polite announcement, focus stays: TalkBack a polite live region on a node that exists before and after the swap (not verified on the shipped builds); VoiceOver a queued announcement — UIKit UIAccessibility.post(.announcement, NSAttributedString) with .accessibilitySpeechQueueAnnouncement, SwiftUI (iOS 17+) AccessibilityNotification.Announcement(…).post(); web a dedicated, empty role="status" the host writes the text into — role="status" is atomic, so a region around the block would re-read the button too.No alert semantics — an error StatusItem is content.
role="status" node without aria-busy; aria-busy goes on the region being loaded.iOS: the hasDsSkeleton path hides the shapes; the unconditional dsSkeleton(...) does not. Android: the DS skeleton sets no semantics — the host hides the shapes (gaps flagged on Skeleton).
<div> — no landmark; a full-screen host names its own <main> or <section>. Centred, so it reads the same in RTL; the button follows its own RTL contract.