# network-status

Live connectivity readout — `navigator.onLine` plus connection type and
speed where the browser exposes them.


```html
<div>
  <network-status></network-status>
  <small role="note">Live — reflects real connectivity. Toggle your
    devtools network throttling (or your device's wifi/data) to see it change.</small>
</div>
```


## Features

- **CSS-driven UI** Style from `[is-online]` / `[connection-type]`
- **Live events** `online` / `offline` / `change` fire as connectivity
  shifts — on transitions, never at mount
- **Bindable state** `.provision` is the full snapshot; read it from Quark
  with `prop("provision")`
- **Network Information API** Connection type + effective speed where
  supported
- **Graceful degradation** Unsupported fields stay `null`; core
  online/offline still works everywhere

## Installation


`@excom/network-status` v0.1.4

```bash
pnpm add @excom/network-status
```

```bash
npm install @excom/network-status
```

```bash
yarn add @excom/network-status
```

### Import

```ts
import "@excom/network-status";
```



## Usage

Drop it anywhere and hook `[is-online]` / `[is-mounted]` with CSS, or
listen for its events from a parent.

```html
<network-status></network-status>
```

```css
network-status:not([is-mounted])::before {
  content: "Loading…";
}
network-status[is-online]::before {
  content: "📶 Online";
}
network-status[is-mounted]:not([is-online])::before {
  content: "📵 Offline";
}
```

Nothing fires at mount: the first read sets `is-online` and `.provision`
only. React to the attribute (or `prop("provision")`) for the initial
state; `network-status-online` / `-offline` report transitions.

The Network Information API (`connection-type`, `effective-type`,
`downlink`, `rtt`) is Chromium-only — Safari and Firefox leave those
fields `null`. Build critical UX on `is-online` alone; treat the rest as
a progressive enhancement. Safari/iOS also have known `navigator.onLine`
reliability quirks — see `INTERNAL.md`.

### API Reference


#### Attributes

| Name | Surface | Type | Default | Values | Description |
| --- | --- | --- | --- | --- | --- |
| `is-online` | state | `boolean` |  |  | Current `navigator.onLine` value. |
| `connection-type` | state | `string` |  |  | Connection type (`wifi`, `cellular`, `ethernet`, …) from the Network Information API. `null` where unsupported (Safari, Firefox). |
| `effective-type` | state | `string` |  |  | Effective connection type (`4g`, `3g`, `2g`, `slow-2g`) from the Network Information API. `null` where unsupported (Safari, Firefox). |

#### Provision

| Name | Type | Description |
| --- | --- | --- |
| `provision` | `NetworkStatusProvision` (`{ isOnline: boolean; connectionType?: string \| null; effectiveType?: string \| null; downlink?: number \| null; rtt?: number \| null; lastOnline?: number \| null; lastOffline?: number \| null; }`) | Full connectivity snapshot: `{ isOnline, connectionType, effectiveType, downlink, rtt, lastOnline, lastOffline }`. Set at mount and on every change; the same object dispatched as `event.detail` on every fired event. `lastOnline` / `lastOffline` are stamped on transitions only. Not reflected as an attribute. |

#### Fires

| Name | Type | Description |
| --- | --- | --- |
| `network-status-online` | `NetworkStatusOnlineEvent` (`CustomEvent & { type: "network-status-online"; detail: { isOnline: boolean; connectionType?: string \| null; effectiveType?: string \| null; downlink?: number \| null; rtt?: number \| null; lastOnline?: number \| null; lastOffline?: number \| null; }; bubbles: true; cancelable: true; composed: true }`) | Dispatched on a transition from offline to online, never at mount. `event.detail` is the full `.provision` payload. |
| `network-status-offline` | `NetworkStatusOfflineEvent` (`CustomEvent & { type: "network-status-offline"; detail: { isOnline: boolean; connectionType?: string \| null; effectiveType?: string \| null; downlink?: number \| null; rtt?: number \| null; lastOnline?: number \| null; lastOffline?: number \| null; }; bubbles: true; cancelable: true; composed: true }`) | Dispatched on a transition from online to offline, never at mount. `event.detail` is the full `.provision` payload. |
| `network-status-change` | `NetworkStatusChangeEvent` (`CustomEvent & { type: "network-status-change"; detail: { isOnline: boolean; connectionType?: string \| null; effectiveType?: string \| null; downlink?: number \| null; rtt?: number \| null; lastOnline?: number \| null; lastOffline?: number \| null; }; bubbles: true; cancelable: true; composed: true }`) | Dispatched when connection details change without an online/offline transition (Network Information API only), never at mount. `event.detail` is the full `.provision` payload. |



### Examples

#### Offline banner

A banner shown purely by CSS attribute selector — no listeners needed.


```html
<div>
  <network-status></network-status>
  <p role="alert">You're offline — some features may be unavailable.</p>
  <small role="note">Banner is CSS-only, driven by
    <code>[is-online]</code>. Go offline to see it appear.</small>
</div>
```

## Release notes

### 0.1.1 (2026-09-23)

- Ship only dist (and declared extras) in the npm tarball; drop build logs, tests and sources
