The Meter component displays a visual representation of a scalar measurement or fractional value within a known range, such as disk space usage, battery level, or rating scores.
Installation
npx shadcn@latest add @eo-n/meter
Install dependencies
npm install @base-ui/react
Copy component code
Copy and paste the following code into your project at components/ui/meter.tsx:"use client";
import * as React from "react";
import { Meter as MeterPrimitive } from "@base-ui/react";
import { cn } from "@/lib/utils";
function Meter({
className,
children,
...props
}: React.ComponentProps<typeof MeterPrimitive.Root>) {
return (
<MeterPrimitive.Root
data-slot="meter"
className={cn(
"relative grid w-full grid-cols-1 gap-1 overflow-hidden select-none has-[[data-slot=meter-label]]:grid-cols-2",
className
)}
{...props}
>
{children}
<MeterPrimitive.Track
data-slot="meter-track"
className="bg-secondary col-span-full block h-2 w-full overflow-hidden rounded-full"
>
<MeterPrimitive.Indicator
data-slot="meter-indicator"
className="bg-primary block transition-all duration-500"
/>
</MeterPrimitive.Track>
</MeterPrimitive.Root>
);
}
function MeterValue({
className,
...props
}: React.ComponentProps<typeof MeterPrimitive.Value>) {
return (
<MeterPrimitive.Value
data-slot="meter-value"
className={cn(
"text-foreground text-right text-sm font-medium",
className
)}
{...props}
/>
);
}
function MeterLabel({
className,
...props
}: React.ComponentProps<typeof MeterPrimitive.Label>) {
return (
<MeterPrimitive.Label
data-slot="meter-label"
className={cn("text-foreground text-sm font-medium", className)}
{...props}
/>
);
}
export { Meter, MeterValue, MeterLabel };
Update imports
Update the import paths to match your project setup.
import { Meter, MeterLabel, MeterValue } from "@/components/ui/meter";
<Meter value={34}>
<MeterLabel>Battery Level</MeterLabel>
<MeterValue />
</Meter>
Examples
Basic Meter
<Meter value={75} className="w-80" />
With Label
<Meter value={45}>
<MeterLabel>Storage Used</MeterLabel>
</Meter>
With Value Display
<Meter value={67}>
<MeterLabel>CPU Usage</MeterLabel>
<MeterValue />
</Meter>
Battery Indicator
import { Meter, MeterLabel, MeterValue } from "@/components/ui/meter";
export default function BatteryMeter() {
const batteryLevel = 34;
return (
<Meter value={batteryLevel}>
<MeterLabel>Battery Level</MeterLabel>
<MeterValue />
</Meter>
);
}
Disk Space Usage
import { Meter, MeterLabel, MeterValue } from "@/components/ui/meter";
export default function DiskSpace() {
const usedSpace = 68.5;
return (
<div className="space-y-2">
<Meter value={usedSpace}>
<MeterLabel>Disk Space</MeterLabel>
<MeterValue />
</Meter>
<p className="text-sm text-muted-foreground">
68.5 GB of 100 GB used
</p>
</div>
);
}
Multiple Meters
import { Meter, MeterLabel, MeterValue } from "@/components/ui/meter";
export default function SystemMetrics() {
return (
<div className="space-y-4">
<Meter value={72}>
<MeterLabel>CPU</MeterLabel>
<MeterValue />
</Meter>
<Meter value={45}>
<MeterLabel>Memory</MeterLabel>
<MeterValue />
</Meter>
<Meter value={88}>
<MeterLabel>Disk</MeterLabel>
<MeterValue />
</Meter>
</div>
);
}
Component API
The root container component.
The current meter value (0-100).
The minimum value. Defaults to 0.
The maximum value. Defaults to 100.
The optimal value. Used to determine if the current value is in a good, suboptimal, or bad range.
The lower boundary of the low range.
The lower boundary of the high range.
Additional CSS classes to apply to the root element.
Optional label and value components.
MeterLabel
Displays a label for the meter.
MeterValue
Displays the current meter value as text.
format
(value: number, max: number) => string
Custom formatter for the value display.
Meter vs Progress
While both components display a horizontal bar, they serve different purposes:
Meter: Represents a scalar measurement within a known range (e.g., disk space, battery level, ratings). The value is meaningful on its own and doesn’t necessarily represent completion.
Progress: Represents the completion status of a task (e.g., file upload, processing). The value represents progress toward completion.
Accessibility
The Meter component is built on Base UI and includes:
- Proper semantic HTML using the
<meter> element
- ARIA attributes for value, min, max, optimum, low, and high
- Screen reader support for value announcements
Reference
Built on top of Base UI Meter.