Offline state
Connectivity chrome from resolveStatus({ kind: "offline" }) in @sometic/dom/status, plus bindOfflineRecovery for the moment the browser reports it is back. Polite live region, role="status", data-status="offline", and the default title You are offline. Same resolver as Empty state, Error state, and Conflict state, with a different kind.
PreviewStatus
Nothing here yet
Demo empty surface
Something went wrong
Demo error surface
You are offline
Demo offline surface
Conflicting changes
Your version vs Server version
Usage
js
import { bindOfflineRecovery, resolveStatus, resolveStatusAction } from "@sometic/dom/status";
const panel = document.querySelector("#offline");
const view = resolveStatus({ kind: "offline", hasAction: true });
panel.className = view.className;
for (const [key, value] of Object.entries(view.attributes)) {
panel.setAttribute(key, value);
}
const action = document.createElement("button");
for (const [key, value] of Object.entries(resolveStatusAction().attributes)) {
action.setAttribute(key, value);
}
action.textContent = "Retry when online";
panel.append(action);
const stopRecovery = bindOfflineRecovery({
onOnline: () => {
panel.replaceChildren(document.createTextNode("Back online"));
},
});ts
import { bindOfflineRecovery, resolveStatus, type StatusViewModel } from "@sometic/dom/status";
export function mountOffline(panel: HTMLElement, refetch: () => void): () => void {
const view: StatusViewModel = resolveStatus({ kind: "offline", hasAction: true });
panel.className = view.className;
for (const [key, value] of Object.entries(view.attributes)) {
panel.setAttribute(key, value);
}
return bindOfflineRecovery({ onOnline: refetch });
}html
<section id="offline"></section>
<script type="module">
import { bindOfflineRecovery, resolveStatus } from "@sometic/dom/status";
const panel = document.querySelector("#offline");
const view = resolveStatus({ kind: "offline", hasAction: true });
panel.className = view.className;
for (const [key, value] of Object.entries(view.attributes)) {
panel.setAttribute(key, value);
}
const title = document.createElement("h3");
title.dataset.slot = "title";
title.textContent = view.title;
const description = document.createElement("p");
description.dataset.slot = "description";
description.textContent = "Changes will be sent when the connection returns.";
panel.replaceChildren(title, description);
const stopRecovery = bindOfflineRecovery({
onOnline: () => {
description.textContent = "Back online, retrying";
},
});
window.addEventListener("pagehide", stopRecovery, { once: true });
</script>Notes
- Offline is polite, because it is a condition rather than a failed action.
bindOfflineRecoveryreturns a dispose function and never toucheswindowat import time. Call it on unmount, or pass asignaltied to your component lifecycle.- The
onlineevent means the interface came back, not that your API is reachable. Treat recovery as "retry now", then handle a real failure as Error state. - Recovery is a callback on purpose: only your app knows whether to revalidate a query, resend a mutation, or just re-enable a button.
- In tests, pass
addEventListenertobindOfflineRecoveryinstead of faking globals.
Full API, accessibility, styling, edge cases, and FAQ: Status surfaces.