Skip to content
WANCRAFT

G.118Data & Feedback

Storage Meter

A stacked usage bar with animated segments, a legend with percentages, tooltips and threshold status.

NewReactCSSTailwindintermediate

Overview

Storage Meter shows usage by category as one stacked bar against a capacity. When the data changes, each segment transitions from its previous width; hovering or tapping a segment, or focusing its legend entry, highlights it, dims the rest and shows a tooltip with the amount and its share. The total is exposed as role="meter" with a full text value, warning and critical thresholds are marked on the track and reported as a text status (not only colour), and the legend doubles as the accessible breakdown list. Amounts are formatted as decimal bytes through Intl by default, or with your own formatter.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/storage-meter.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/storage-meter.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/storage-meter.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { StorageMeter, type StorageSegment } from "@/components/ui/storage-meter";

export function StorageMeterExample() {
  const GB = 1e9;
  const segments: StorageSegment[] = [
    { key: "photos", label: "Photos", value: 38.4 * GB },
    { key: "video", label: "Video", value: 52.1 * GB },
    { key: "docs", label: "Documents", value: 9.6 * GB },
  ];

  return (
    <div className="w-full max-w-md">
      <StorageMeter
        label="Cloud storage"
        segments={segments}
        capacity={200 * GB}
      />
    </div>
  );
}

03Props

PropTypeDefaultDescription
segmentsStorageSegment[]—{ key, label, value, color? } per category; key keeps the width transition stable.
capacitynumber—Total capacity, in the same unit as the values.
labelstring"Storage"Visible label and the meter's accessible name.
format(value: number) => string—Custom formatter; defaults to decimal bytes via Intl (formatBytes is exported).
localestring"en-US"Locale for the default formatter and percentages.
warningAt / criticalAtnumber0.75 / 0.9Fractions of capacity where the status changes; both are marked on the track.
showLegendbooleantrueShow the legend / breakdown list.
thicknessnumber12Bar height in px.
gapnumber2Gap between segments in px.
durationnumber600Width transition in ms.

04Features

  • 01Segments transition from their previous widths when data changes
  • 02Hover or tap a segment, or focus its legend entry, to highlight it with a tooltip
  • 03Legend with formatted values and share of capacity
  • 04Warning and critical thresholds marked on the track and reported as text
  • 05Over-capacity data scales to fit while labels keep the real numbers
  • 06Intl byte formatting by default, or any formatter
motion · tweeninput · hoverinput · focusinput · click

05Accessibility

  • The bar is role="meter" with aria-valuemin/max/now and an aria-valuetext such as "91.6 GB of 200 GB used (45.8%). Plenty of space."
  • The status is written as text next to its colour dot and linked to the meter with aria-describedby.
  • The breakdown is a labelled list of buttons; focusing one highlights its segment (aria-pressed reflects the highlight).
  • Bar segments are aria-hidden visuals; every number they show is also in the legend and meter text.
  • prefers-reduced-motion removes the width and highlight transitions.