# Storage Meter

Storage Meter [#storage-meter]

The **Storage Meter** shows origin / IndexedDB storage usage against quota as a meter, with a warning state past a configurable threshold. Storage estimates are approximate and blocked in some browsers (e.g. Safari private mode), so the component degrades to a graceful "unavailable" state rather than erroring. Bind it to `useStorageQuota` (the default) or pass an explicit `quota`.

Preview [#preview]

```tsx
'use client';

import { StorageMeter } from '@/components/storage-meter';

/**
 * Demo for StorageMeter. The first reads the device's real
 * navigator.storage.estimate() via useStorageQuota; the second passes an
 * explicit near-full quota to show the warning state.
 */
export default function StorageMeterDemo() {
  return (
    <div className="flex w-full max-w-xs flex-col gap-4">
      <StorageMeter />
      <StorageMeter
        quota={{ usedBytes: 1.9e9, quotaBytes: 2e9 }}
        warnThreshold={0.8}
      />
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/local-first/storage-meter
```

Data source & dependencies [#data-source--dependencies]

**Data source:** reads `navigator.storage.estimate()` via the bundled `useStorageQuota` navigator hook (or pass an explicit `quota`) — self-contained, works in any React app. (It mirrors `useStorageQuota` from `@localmode/react`.)

* `@localmode/ui/lib/use-environment` — the bundled `useStorageQuota` navigator hook (installed automatically as a registry dependency)
* `@localmode/ui/lib/browser-utils` — `formatBytes` for the usage readout (installed automatically as a registry dependency)
* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Files installed [#files-installed]

* `storage-meter.tsx` — the `StorageMeter` component
* `lib/use-environment.ts` — the bundled `useStorageQuota` navigator hook
* `lib/browser-utils.ts` — generic browser helpers (`formatBytes`)
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**StorageMeter**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `warnThreshold` | `number` | `0.8` | Fraction (0–1) at which the meter enters its warning state. |
| `quota` | `object` | — | Override the live quota source (used / total bytes). When omitted the component reads `useStorageQuota()`. |

Examples [#examples]

Default (live quota) [#default-live-quota]

```tsx
<StorageMeter warnThreshold={0.9} />
```

Explicit quota [#explicit-quota]

```tsx
<StorageMeter quota={{ usedBytes: 1.9e9, quotaBytes: 2e9 }} />
```

Customization [#customization]

The warning state turns the bar amber and shows a hint past `warnThreshold` (default `0.8`). When no estimate is available the component renders a muted "Storage estimate unavailable" row — never an error. Styled entirely with shadcn/ui CSS-variable utilities so it inherits your theme — because you own the copied file, every class and threshold is yours to change.