Overview
Reference usage
StaleRegion wraps a page (or a part of one) that keeps showing old data while the server cannot answer. It changes nothing about how that data looks: text, dots and tones stay exactly as they were, at full contrast, never dimmed with opacity. The warning banner above it is the only sign it is old. What the region does is turn off the controls that change something, and only those.
A control opts in with mutating, on Button, Toggle, Checkbox, Select and DropdownTrigger. While the region is stale an opted-in control goes inert: it carries aria-disabled="true", stays focusable so a keyboard or screen-reader user can still land on it and hear why, ignores the press, and lists the region's reason in aria-describedby ("Off until it’s back" unless the page words its own). Everything that does not opt in stays live: links, tabs, filters, search, Retry now and Cancel. A control outside any region is untouched. When stale turns false the controls return by themselves, with no remount.
The region takes no box of its own (display: contents), so wrapping a header, a banner and a list does not move any of them.
What it does not do
- It does not draw the banner. Put a
Bannerwith a connection preset inside the region; the banner names the "as of" time with its zone once, so no row repeats it. - It does not choose between the old data and the full error state. A page that has data shows the data under the banner; a page with nothing to show renders the error state instead. Never both.
- It does not say which controls change something. That is the page's call: mark the pencil, the trash and the "+" with
mutating, and leave Export, which only reads, without it. New chat creates a new chat rather than editing the list, so it stays live.
Usage
When to use
- The server is unreachable or a refresh failed and the page keeps showing what it loaded, with a banner above it.
- Turning off a page's writing controls (Edit, Save, Delete, a switch) while its reading controls (links, filters, tabs, Retry) stay live.
- Disabling one control for its own reason, such as a missing provider — set aria-disabled on that control and describe it.
- Showing the connection state itself — use banner with a connection preset.
Examples
Old data with inert writes
The server is unreachable, so the page keeps its data at full contrast under a warning banner. Only the button that changes something is inert (aria-disabled, still focusable, described by "Off until it’s back"); the link and Retry now stay live.
Every control that changes something
Button, Toggle, Checkbox and Select opt in with mutating. Under a stale region each one keeps focus, ignores the press and is described by the reason. The page words the reason, and the filter beside them, which only reads, stays live.
An offline page with old data at full contrast
The offline banner sits over the page, the old data keeps full text contrast (no opacity), and only the controls marked mutating go inert: the header +, Edit and the approval card’s Approve and Deny. Reading, Export and links stay live.
Props
Name | Type | Default | Description |
|---|---|---|---|
stale | boolean | true | Whether the data under the region is old. While it is, every control inside that opted in with
mutating goes inert; when it turns false they return by themselves. Defaults to true, so a
page mounts the region only while it is stale or binds this to its connection state. |
reason | text | 'Off until it’s back' | The reason an inert control is off, read as its description. Pages word it for what they show: "Off until storage answers", "Approving is off until Interborough is reachable". |
describedBy | text | The id of an element that already says why, such as the page's banner. Inert controls list it
in aria-describedby instead of the region's own reason, which is then not rendered. | |
children required | snippet | The page or section whose data may be old. |