jengacore.shadcn registry · Tailwind v4 · Radix and Base UI
Components
jengacore components · @jengacore/meter

Meter

Share of a limit with the alert threshold marked and the percentage as text.

42%
86%
99%

Install

terminal
npx shadcn@latest add @jengacore/meter

Without the namespace configured: npx shadcn@latest add https://ui.jengacore.com/r/<new-york-v4|base-nova>/meter.json

Registry dependencies

Source

components/jc/meter.tsx
import * as React from "react"

import { cn } from "@/lib/utils"

/**
 * Share of a limit (net debit cap used), with the alert threshold marked.
 * Green below the threshold, amber from it, red from `danger`. Always show the percentage as text too
 * (`showValue`), so the state never depends on colour.
 */
export function Meter({
  percent,
  threshold = 80,
  danger = 95,
  label,
  showValue = false,
  className,
}: {
  percent: number
  threshold?: number
  danger?: number
  label: string
  showValue?: boolean
  className?: string
}) {
  const clamped = Math.max(0, Math.min(percent, 100))
  const tone = percent >= danger ? "bg-destructive" : percent >= threshold ? "bg-warning" : "bg-primary"
  const bar = (
    <div
      role="meter"
      aria-label={label}
      aria-valuenow={Math.round(percent)}
      aria-valuemin={0}
      aria-valuemax={100}
      className={cn("relative h-1.5 flex-1 overflow-hidden rounded-full bg-muted contrast:outline contrast:outline-input", !showValue && className)}
    >
      <i className={cn("absolute inset-y-0 left-0 origin-left animate-fill rounded-full", tone)} style={{ width: `${clamped}%` }} />
      <span className="absolute inset-y-0 w-0.5 bg-foreground/40" style={{ left: `${threshold}%` }} aria-hidden />
    </div>
  )
  if (!showValue) return bar
  return (
    <div data-slot="meter" className={cn("flex items-center gap-2.5", className)}>
      {bar}
      <span className="w-10 text-right font-mono text-xs tabular-nums text-muted-foreground">{Math.round(percent)}%</span>
    </div>
  )
}