Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 45x 45x | import type {MeterHTMLAttributes} from "react";
import {cn} from "@/lib/utils/utils";
/** Semantic fill colors for bounded score meters. */
export type MeterTone = "amber" | "cyan" | "emerald" | "rose";
/** Props for the shared accessible meter primitive. */
export type MeterBarProps = Omit<MeterHTMLAttributes<HTMLMeterElement>, "children" | "max" | "min" | "value"> & {
label: string;
max?: number;
min?: number;
tone?: MeterTone;
value: number;
valueText?: string;
};
/** Accessible native meter styled through CSS instead of inline width values. */
export function MeterBar({
className,
label,
max = 100,
min = 0,
tone = "cyan",
value,
valueText,
...props
}: MeterBarProps) {
const boundedValue = Math.min(Math.max(value, min), max);
return (
<meter
aria-label={label}
aria-valuemax={max}
aria-valuemin={min}
aria-valuenow={boundedValue}
aria-valuetext={valueText ?? `${boundedValue} of ${max}`}
className={cn("meter-bar", className)}
data-tone={tone}
max={max}
min={min}
value={boundedValue}
{...props}
/>
);
}
|