Data Cost Notice

On mobile data, Data Saver or a slow line, shows a big download's size and rough time and offers a lighter version or waiting for Wi-Fi.

StopsBig download ate the mobile data pack

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/data-cost-notice.json

The files land in your project. They're yours to edit.

Usage

data-cost-notice-usage.tsx
import { DataCostNotice, type ConnectionInfo } from "@/components/ui/data-cost-notice"

<DataCostNotice
  label="1080p"
  bytes={480e6}
  lighter={{ label: "480p · same lecture", bytes: 120e6 }}
  connection={onWifi ? wifi : weakSignal ? weak : mobile}
  onChoose={setChoice}
/>

What it catches

  • Large downloads, uploads or autoplay on mobile data
  • Data Saver / Save-Data preference
  • Slow connections, with a rough time estimate
  • A lighter version and how much it saves

Props

DataCostNotice props
PropTypeDefault
bytes* (required)

Size of the full version in bytes.

number—
label* (required)

Name of the full version, e.g. "1080p".

string—
lighter

A smaller alternative: lower quality, compressed, audio only.

{ label: string; bytes: number }—
direction

Uploads are estimated as "over" the time, since upload speed isn't measured.

TransferDirection"download"
verb

Verb for the detail line; defaults to "Downloading"/"Uploading". Use "Playing" for autoplay.

stringdirection === "upload" ? "Uploading" : "Downloading"
connection

Override the browser's reading, e.g. from a `Save-Data: on` request header or a native shell.

ConnectionInfo—
onChoose* (required)

The user picked a version. A deferred choice arrives once the connection stops being a concern.

(choice: "full" | "lighter") => void—
minBytes

Transfers smaller than this only warn when they'd be slow.

number—
slowSeconds

Transfers slower than this always warn, in seconds.

number—
saveDataTitle

Templates: `{verb}`, `{label}`, `{size}`, `{time}`, `{type}` (e.g. "3G") are filled in; `savesText` takes `{saved}`.

string"Data Saver is on"
cellularTitle

Title when on mobile data.

string"You're on mobile data"
slowTitle

Title when the connection is slow.

string"Slow connection ({type})"
detailText

Line giving the size.

string"{verb} {label} uses {size}"
timeText

Line giving the rough time.

string"{time} at this speed"
savesText

Text for how much the lighter version saves.

string"saves {saved}"
waitLabel

Text for the wait-for-Wi-Fi button.

string"Wait for Wi-Fi"
waitingText

Shown while waiting for Wi-Fi.

string"Waiting for Wi-Fi · {label} starts once you're on it"
fullLabel

Text for choosing the full version.

string"{label} anyway"
cancelLabel

Text for cancelling the wait.

string"Cancel"

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Notice content is a role="status" region
  • Version choices are a labelled role="group" of buttons
  • The waiting pulse only animates when motion is allowed

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • The Network Information API is not available in every browser (notably Safari and Firefox); without it, pass connection details yourself
  • Chrome caps reported bandwidth at 10 Mbps, so times are rough and fast lines aren't called slow
  • "Wait for Wi-Fi" relies on the browser reporting the connection type

What it stops

Big download ate the mobile data pack

Also known as

mobile data · data saver · wifi only · network information api · save-data · download size · jio · slow 3g

Field type

Dependencies

Pairs well with