Primitives
Meter
Static range meter for quota, storage, score, or usage values.
Composition
Anatomy
- <Meter>
- <MeterLabel />
- <MeterValue />
- <MeterTrack>
- <MeterIndicator />
Installation
First install and activate one skin. Core deliberately contains no visual token defaults.
The Control UI source installs this primitive from src/registry/sources/control-ui/ui/meter.tsx.
npx shadcn@latest add https://control-ui.dev/r/meter.jsonRaw code
Primary installed source
"use client";import { Meter as MeterPrimitive } from "@base-ui/react/meter";import type { ComponentProps, CSSProperties, ReactNode } from "react";import type { RangeKnobStyle } from "@/components/control-ui/knob-contracts/range-knobs";import { cn } from "@/components/control-ui/lib/cn";export type MeterProps = Omit< ComponentProps<"div"> & { value: number; min?: number; max?: number; format?: Intl.NumberFormatOptions; getAriaValueText?: (formattedValue: string, value: number) => string; locale?: Intl.LocalesArgument; }, "style"> & { style?: CSSProperties & RangeKnobStyle };export type MeterTrackProps = Omit<ComponentProps<"div">, "style"> & { style?: CSSProperties & RangeKnobStyle };export type MeterIndicatorProps = Omit<ComponentProps<"div">, "style"> & { style?: CSSProperties & RangeKnobStyle };export type MeterLabelProps = Omit<ComponentProps<"span">, "style"> & { style?: CSSProperties & RangeKnobStyle };export type MeterValueProps = Omit< Omit<ComponentProps<"span">, "children"> & { children?: ((formattedValue: string, value: number) => ReactNode) | null; }, "style"> & { style?: CSSProperties & RangeKnobStyle };// value is required — role="meter" is static gauge, never indeterminate way Progress can be.export function Meter({ className, ...props }: MeterProps) { return ( <MeterPrimitive.Root data-control-ui="meter" data-range-kind="meter" data-slot="root" data-control-family="range" className={cn("flex w-full flex-col", className)} {...props} /> );}export function MeterLabel({ className, ...props }: MeterLabelProps) { return ( <MeterPrimitive.Label data-control-ui="meter" data-control-family="range" data-range-kind="meter" data-slot="label" className={className} {...props} /> );}export function MeterValue({ className, ...props }: MeterValueProps) { return ( <MeterPrimitive.Value data-control-ui="meter" data-control-family="range" data-range-kind="meter" data-slot="value" className={className} {...props} /> );}export function MeterTrack({ className, ...props }: MeterTrackProps) { return ( <MeterPrimitive.Track data-control-ui="meter" data-control-family="range" data-range-kind="meter" data-slot="track" className={cn("relative w-full overflow-hidden", className)} {...props} /> );}export function MeterIndicator({ className, ...props }: MeterIndicatorProps) { return ( <MeterPrimitive.Indicator data-control-ui="meter" data-control-family="range" data-range-kind="meter" data-slot="indicator" className={className} {...props} /> );}Knobs
Typed custom properties the recipe paints with. Set one on the root — style, a utility class, or a skin — and every slot inherits it.
--cui-range-* · 13 knobsHow the cascade resolves--cui-range-level-warning-background<color>var(--warning)--cui-range-level-clip-background<color>var(--destructive)--cui-range-level-size<length-percentage>calc(var(--spacing) * 2)--cui-range-level-scale-foreground<color>var(--muted-foreground)--cui-range-indeterminate-size<length-percentage>40%--cui-range-track-radius<length-percentage>9999px--cui-range-track-background<color>var(--muted)--cui-range-indicator-radius<length-percentage>9999px--cui-range-indicator-background<color>var(--primary)--cui-range-thumb-radius<length-percentage>9999px--cui-range-thumb-background<color>var(--background)--cui-range-thumb-border-color<color>var(--control-rim)--cui-range-thumb-shadow*var(--shadow-sm)