Usage meter
Show what fills an allowance and how close it is to the limit.
meterusagestorage
Preview
Usage meter preview
Live · keyboard ready
Workspace storage36.0 GB free
64.0 GB of 100 GB used
When to use
- Quota against a fixed allowance, such as storage, seats, or API calls.
- Billing pages that should show what takes the space and how close the plan is to full.
- Plans that can go over the limit, where the overage should be clear without relying on color.
When not to use
- Use progress for task completion.
- Use bar-chart to compare categories without a limit.
- Use gauge or stat-card for a single headline metric.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "usage-meter",
"type": "registry:ui",
"title": "Usage meter",
"description": "Show what fills an allowance and how close it is to the limit.",
"categories": [
"feedback"
],
"dependencies": [
"lucide-react",
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/usage-meter/usage-meter.tsx",
"type": "registry:component",
"target": "@components/manicat/usage-meter/usage-meter.tsx"
},
{
"path": "registry/components/usage-meter/usage-meter.module.css",
"type": "registry:component",
"target": "@components/manicat/usage-meter/usage-meter.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/usage-meter",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/usage-meter",
"markdown": "https://uiarc.dev/components/usage-meter/markdown",
"tags": [
"meter",
"usage",
"storage"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { useState } from "react";
import { UsageMeter } from "@/components/manicat/usage-meter/usage-meter";
import { Button } from "@/components/manicat/button/button";
export function UsageMeterExample() {
const [used, setUsed] = useState(64);
return (
<div className="grid w-full max-w-sm gap-3">
<UsageMeter
label="Workspace storage"
limit={100}
unit="GB"
segments={[
{ id: "db", label: "Database", value: used * 0.5 },
{ id: "media", label: "Media", value: used * 0.4 },
{ id: "logs", label: "Logs", value: used * 0.1 },
]}
/>
<Button size="sm" variant="secondary" onClick={() => setUsed((value) => (value > 90 ? 20 : value + 20))}>
Add 20 GB
</Button>
</div>
);
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Storage quota A segmented meter that shows what fills the quota, with a button to simulate growth.
Storage quota
A segmented meter that shows what fills the quota, with a button to simulate growth. preview
Live · keyboard ready
Workspace storage36.0 GB free
64.0 GB of 100 GB used
storage-quota-a-segmented-meter-that-shows-what-fills-the-quota-with-a-button-to-simulate-growth-.tsxtsx
Keyboard interactions
| Keys | Action |
|---|---|
| ArrowLeft / ArrowRight / ArrowUp / ArrowDown | Moves between legend items (roving tab stop). |
| Home / End | Jumps to the first or last legend item. |
| Enter / Space | Pins or unpins the focused category. |
| Escape | Clears the pinned category. |
Accessibility
- The meter is a role="group" labelled by its title; the bar is role="img" with a full text summary of every segment and the status.
- Rolling numbers are aria-hidden with screen-reader-only text alongside.
- Status changes (near limit, over limit, growing overage) are announced in a polite live region.
- Legend items are buttons with aria-pressed and labels like "Media, 14.2 GB".
Motion
- Segments grow in left to right once scrolled into view, then re-flow on one spring each when values change; crossing the limit fades in a hatched overage and limit marker.
- Digits roll like an odometer in the direction the number moved; the status badge springs to its new width.
- Reduced motion jumps values and swaps text with short fades.
Responsive behavior
- The legend is an auto-fit grid of 108px minimum columns, so it wraps to fewer columns on narrow cards.
- Hovering the bar highlights a category on mouse; on touch a tap pins it instead.
- The caption ellipsizes on one line, so long labels do not push the layout.
Performance
- Segments animate in once via useInView at 40% visibility, then re-flow on springs when values change.
- A ResizeObserver tracks the bar width; up to four segments read clearly.
Notes for AI
- Use for quota against a fixed allowance: storage, seats, API calls. Use progress for task completion and bar-chart for comparing categories without a limit.
- Keep segment ids stable across renders so updates animate instead of remounting.