- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
"use client"
import { UsageMeter } from "@/components/ui/usage-meter"The UsageMeter component shows how much of a limit is used: card spending, withdrawals, free transfers or data. It shows a label and used-of-total, with an optional line under it. From 90% it turns to warning, and over the limit it stays full. Use it for a quantity that has a ceiling. For a task in progress with no limit, use a progress bar; for levels the user moves through, use TierLadder.
Installation#
pnpm dlx shadcn@latest add @dots/usage-meter
Usage#
import { UsageMeter } from "@/components/ui/usage-meter"<UsageMeter
label="Monthly spending"
value={1840}
max={2500}
formatOptions={{ style: "currency", currency: "USD" }}
description="Resets Dec 1"
/>Features#
- Three variants:
barfor a list of limits,ringfor a row of several,gaugefor one limit on its own - Three states from the numbers:
default,nearfromwarnAt, andoverabove the limit - Any unit through
formatOptions, or your ownvalueText - Two sizes
- Announced as a meter with the used-of-total as its value, plus how much is over the limit
States#
The state comes from value and max. From warnAt (90% by default) the fill and the description turn to warning. Above the limit the value text turns to warning too, and the fill stays full.
"use client"
import { UsageMeter } from "@/components/ui/usage-meter"Units#
Pass formatOptions for any number format, or valueText for your own wording. Set warnAt={false} for an allowance that is fine to use up, such as free withdrawals.
"use client"
import { UsageMeter } from "@/components/ui/usage-meter"Sizes#
Use size to switch between default and sm.
"use client"
import { UsageMeter } from "@/components/ui/usage-meter"Gauge#
Set variant="gauge" for one limit that leads a screen. The percentage and used-of-total sit inside the arc, with zero and the limit at its ends.
"use client"
import { UsageMeter } from "@/components/ui/usage-meter"Ring#
Set variant="ring" to show several limits side by side. The percentage sits inside the ring, and the label and used-of-total under it.
"use client"
import { UsageMeter } from "@/components/ui/usage-meter"Accessibility#
UsageMeter is built on React Aria Meter, so it is announced as a meter (role="meter progressbar", with progressbar as the fallback) with its value range. The label names the meter, and the description is linked with aria-describedby. The bar, ring and gauge graphics and the visible numbers are hidden from assistive tech; the value is read once.
Spoken value#
Screen readers hear value and max formatted with formatOptions, such as "$1,840 of $2,500", plus how much is over the limit. valueText is only shown, never read. When valueText adds words or a unit the numbers lack, such as a custom unit without formatOptions, pass a valueLabel with the same meaning.
<UsageMeter
label="Data abroad"
value={1.2}
max={2}
valueText="1.2 GB of 2 GB"
valueLabel="1.2 GB of 2 GB used"
/>Meaning beyond color#
The warning and over states use color. Say what happens in description, such as "$60 over the limit".
API Reference#
UsageMeter#
Accepts all React Aria Meter props except children, className, style, value, minValue, maxValue, valueLabel and formatOptions, which are replaced below.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | - | What is measured. Also names the meter. Required. |
value | number | - | How much is used, in the same unit as max. May exceed it. Required. |
max | number | - | The limit or allowance. Required. |
valueText | ReactNode | both numbers formatted | Used-of-total text: next to the label on a bar, under the ring, inside the gauge. Not read by screen readers. |
formatOptions | Intl.NumberFormatOptions | - | Number format for the value text, the gauge ends and screen readers. |
locale | string | "en-US" | Locale for the numbers. |
description | ReactNode | - | Quiet line at the bottom. |
valueLabel | string | used-of-total | What screen readers hear as the value. |
warnAt | number | false | 0.9 | Share of max from which the meter turns to warning. |
variant | "bar" | "ring" | "gauge" | "bar" | How the usage is drawn. |
size | "default" | "sm" | "default" | The meter size. |
className | string | - | Additional classes to apply to the root element. |
The root element exposes data-state ("default", "near" or "over"), data-variant and data-size for styling.