Network Status
stimeo--network-status
Tells you when the connection drops and when it returns, urgently and then quietly.
Watches for the connection dropping and coming back, and swaps between your two notices. Losing it is urgent, so that one interrupts, while coming back is announced quietly. The same state is never announced twice over. The recovery notice can hide itself after a while. The browser only knows whether there is a connection at all, not whether your server can be reached, so word the notice accordingly.
These buttons dispatch the window online / offline events so you can see the behavior without actually disconnecting.
Keyboard
This component has no keyboard interactions of its own.
<%# Markup for the network-status (offline-detection banner) demo.
The library checks navigator.onLine initially and subscribes to the window's
online/offline events, toggling the corresponding banner's hidden. The banners are
the visual half only: a region revealed at the moment of the change is not reliably
read, so the wording goes instead to the shared stimeo--announcer your app seats once,
in its layout — losing the connection interrupts (assertive), regaining it waits its
turn (polite). Since real online/offline is environment-dependent, the demo's demo.js
fakes the window events to reproduce the behavior. %>
<div class="network-demo">
<div class="network-demo__controls">
<button class="demo-trigger" type="button" data-network-demo="offline">
<%= t("components.network_status.demo.go_offline") %>
</button>
<button class="demo-trigger" type="button" data-network-demo="online">
<%= t("components.network_status.demo.go_online") %>
</button>
</div>
<div data-controller="stimeo--network-status"
data-stimeo--network-status-online-auto-hide-value="3000"
data-stimeo--network-status-announce-text-value="<%=
t("components.network_status.demo.offline_message") %>"
data-stimeo--network-status-announce-online-text-value="<%=
t("components.network_status.demo.online_message") %>">
<div
class="network-banner network-banner--offline"
hidden
data-stimeo--network-status-target="offline">
<%= t("components.network_status.demo.offline_message") %>
</div>
<div
class="network-banner network-banner--online"
hidden
data-stimeo--network-status-target="online">
<%= t("components.network_status.demo.online_message") %>
</div>
</div>
<p class="network-demo__note"><%= t("components.network_status.demo.note") %></p>
</div>
/*
* Presentation-only styles for the network-status demo.
* This CSS owns the banner's color and placement; the library only toggles
* hidden and reflects data-state (online / offline).
*/
.network-demo {
display: flex;
flex-direction: column;
gap: 1rem;
max-width: 32rem;
}
.network-demo__controls {
display: flex;
gap: 0.5rem;
}
.network-banner {
padding: 0.6rem 0.9rem;
border: 1px solid var(--border);
border-radius: 0.375rem;
font-size: 0.95rem;
}
.network-banner--offline {
border-color: var(--danger-500);
background: var(--danger-50);
color: var(--color-accent);
}
.network-banner--online {
border-color: var(--leaf-500);
background: var(--leaf-50);
color: var(--leaf-500);
}
.network-demo__note {
margin: 0;
font-size: 0.85rem;
color: var(--color-text-muted);
}
// Consumer-side JS for the network-status demo (demo-only).
// Real online / offline transitions are environment-dependent and hard to reproduce,
// so demo buttons fake the window's online / offline events. The library subscribes to
// those events to switch the banner, so production runs the same code path.
document.querySelectorAll("[data-network-demo='offline']").forEach((button) => {
button.addEventListener("click", () => {
window.dispatchEvent(new Event("offline"));
});
});
document.querySelectorAll("[data-network-demo='online']").forEach((button) => {
button.addEventListener("click", () => {
window.dispatchEvent(new Event("online"));
});
});
// Example of subscribing to the state-change event (usable for analytics, a toast, etc.).
document.addEventListener("stimeo--network-status:change", (event) => {
console.log(`[network-status] online=${event.detail.online}`);
});
These demo styles use shared design tokens (light + dark). Copy the shared styles too, then toggle data-theme on your root element for dark mode.
The data-* attributes you add to your own HTML to wire this component. Put the data-controller below on a root element, then place its targets / values / actions inside that element.
On the root element
data-controller="stimeo--network-status"
Targets
| Name | Description | Attribute |
|---|---|---|
offline
|
The visual banner shown while connectivity is lost. | data-stimeo--network-status-target="offline" |
online
|
The visual recovery banner shown when connectivity returns. | data-stimeo--network-status-target="online" |
Values
| Name | Description | Attribute |
|---|---|---|
announceText
|
Wording read out assertively when the connection drops; empty announces nothing. | data-stimeo--network-status-announce-text-value |
announceOnlineText
|
Wording read out politely when the connection returns; empty announces nothing. | data-stimeo--network-status-announce-online-text-value |
onlineAutoHide
|
Milliseconds after which the recovery banner auto-hides; 0 disables (default 0). | data-stimeo--network-status-online-auto-hide-value |
Events
| Name | Description | Event |
|---|---|---|
change
|
Fires on a connectivity transition with detail.online (boolean). | stimeo--network-status:change |
State hooks
The library only manages these ARIA/data attributes and custom properties. Your CSS reads them to render the look — selectors like [aria-selected], [aria-expanded], or var(--stimeo--…) hook into this state.
| Hook | Target | Meaning |
|---|---|---|
hidden |
Offline / Online banner | Toggled to show the matching banner. |
data-state |
Root element | "online" / "offline". |