Basic
gauge-demo-basic
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
export function GaugeDemoBasic() {
return (
<Gauge value={72}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
)
}
Combined
gauge-demo-combined
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeLabel,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
export function GaugeDemoCombined() {
return (
<div className="flex flex-col items-center gap-4">
<Gauge value={84} size={220} thickness={20} gap={20} segments={60}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText>
<div className="flex flex-col items-center">
<span className="text-4xl font-medium tracking-tight">84%</span>
<span className="text-xs text-muted-foreground">Excellent</span>
</div>
</GaugeValueText>
</Gauge>
<GaugeLabel>Overall Health Score</GaugeLabel>
</div>
)
}
Custom Value
gauge-demo-custom-value
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
export function GaugeDemoCustomValue() {
return (
<div className="flex flex-wrap items-center justify-center gap-10">
<Gauge value={72} getValueText={(value) => `${value} BPM`}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<Gauge value={4} min={0} max={10} getValueText={(value) => `${value}/10`}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<Gauge
value={42}
min={0}
max={60}
getValueText={(value) => `${value} min`}
>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
</div>
)
}
Sizes
gauge-demo-sizes
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const gauges = [
{
label: "Small",
size: 120,
gap: 20,
value: 72,
},
{
label: "Medium",
size: 180,
gap: 15,
value: 72,
},
{
label: "Large",
size: 240,
gap: 10,
value: 72,
},
]
export function GaugeDemoSizes() {
return (
<div className="flex flex-wrap items-end justify-center gap-8">
{gauges.map((gauge) => (
<div key={gauge.label} className="flex flex-col items-center gap-3">
<Gauge value={gauge.value} size={gauge.size} gap={gauge.gap}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">{gauge.label}</span>
</div>
))}
</div>
)
}
Thickness
gauge-demo-thickness
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const gauges = [
{
label: "Thin",
thickness: 1,
gap: 4,
},
{
label: "Default",
thickness: 4,
gap: 10,
},
{
label: "Medium",
thickness: 6,
gap: 15,
},
{
label: "Thick",
thickness: 10,
gap: 20,
},
]
export function GaugeDemoThickness() {
return (
<div className="flex flex-wrap items-center justify-center gap-8">
{gauges.map((gauge) => (
<div key={gauge.label} className="flex flex-col items-center gap-3">
<Gauge
value={gauge.thickness}
min={0}
max={12}
size={160}
thickness={gauge.thickness}
gap={gauge.gap}
>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">{gauge.label}</span>
</div>
))}
</div>
)
}
Gap
gauge-demo-gap
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const gauges = [
{
label: "No Gap",
},
{
label: "20 Gap",
gap: 20,
},
{
label: "40 Gap",
gap: 40,
},
{
label: "80 Gap",
gap: 80,
},
]
export function GaugeDemoGap() {
return (
<div className="flex flex-wrap items-center justify-center gap-8">
{gauges.map((gauge) => (
<div key={gauge.label} className="flex flex-col items-center gap-3">
<Gauge value={75} size={160} gap={gauge.gap}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">{gauge.label}</span>
</div>
))}
</div>
)
}
Segments
gauge-demo-segments
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const gauges = [
{
label: "4 Segments",
segments: 4,
},
{
label: "8 Segments",
segments: 8,
},
{
label: "12 Segments",
segments: 12,
},
{
label: "24 Segments",
segments: 24,
},
]
export function GaugeDemoSegments() {
return (
<div className="flex flex-wrap items-center justify-center gap-8">
{gauges.map((gauge) => (
<div key={gauge.label} className="flex flex-col items-center gap-3">
<Gauge value={65} size={160} segments={gauge.segments}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">{gauge.label}</span>
</div>
))}
</div>
)
}
Angles
gauge-demo-angles
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const gauges = [
{
label: "Full Circle",
startAngle: 0,
endAngle: 360,
},
{
label: "Semicircle",
startAngle: -90,
endAngle: 90,
},
{
label: "Three Quarter",
startAngle: -135,
endAngle: 135,
},
]
export function GaugeDemoAngles() {
return (
<div className="flex flex-wrap items-center justify-center gap-10">
{gauges.map((gauge) => (
<div key={gauge.label} className="flex flex-col items-center gap-3">
<Gauge
value={70}
size={180}
gap={20}
startAngle={gauge.startAngle}
endAngle={gauge.endAngle}
>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">{gauge.label}</span>
</div>
))}
</div>
)
}
Custom Radius
gauge-demo-radius
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
export function GaugeDemoRadius() {
return (
<div className="flex flex-wrap items-center justify-center gap-10">
<div className="flex flex-col items-center gap-3">
<Gauge value={72} size={180} tickInnerRadius={77} tickOuterRadius={88}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">Compact</span>
</div>
<div className="flex flex-col items-center gap-3">
<Gauge value={72} size={180} tickInnerRadius={35} tickOuterRadius={88}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">Wide</span>
</div>
</div>
)
}
States
gauge-demo-states
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const states = [
{
label: "Indeterminate",
value: null,
},
{
label: "Loading",
value: 64,
},
{
label: "Complete",
value: 100,
},
]
export function GaugeDemoStates() {
return (
<div className="flex flex-wrap items-center justify-center gap-10">
{states.map((item) => (
<div key={item.label} className="flex flex-col items-center gap-3">
<Gauge value={item.value} size={170}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText>
{item.value === null ? "—" : `${item.value}%`}
</GaugeValueText>
</Gauge>
<span className="text-sm text-muted-foreground">{item.label}</span>
</div>
))}
</div>
)
}
Custom Range
gauge-demo-range
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const ranges = [
{
label: "0–100",
min: 0,
max: 100,
value: 72,
},
{
label: "0–10",
min: 0,
max: 10,
value: 7,
},
{
label: "50–150",
min: 50,
max: 150,
value: 120,
},
]
export function GaugeDemoRange() {
return (
<div className="flex flex-wrap items-center justify-center gap-10">
{ranges.map((item) => (
<div key={item.label} className="flex flex-col items-center gap-3">
<Gauge
value={item.value}
min={item.min}
max={item.max}
size={170}
getValueText={(value, min, max) => {
const percentage = ((value - min) / (max - min)) * 100
return `${Math.round(percentage)}%`
}}
>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<span className="text-sm text-muted-foreground">{item.label}</span>
</div>
))}
</div>
)
}
Label
gauge-demo-label
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeLabel,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
export function GaugeDemoLabel() {
return (
<div className="flex flex-col items-center gap-4">
<Gauge value={78} size={190}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText />
</Gauge>
<GaugeLabel>Muscle Health</GaugeLabel>
</div>
)
}
Custom Content
gauge-demo-custom-content
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
export function GaugeDemoCustomContent() {
return (
<div className="flex flex-wrap items-center justify-center gap-10">
<Gauge value={82} size={180}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText>
<div className="flex flex-col items-center">
<span className="text-4xl font-medium tracking-tight">82</span>
<span className="text-xs font-normal text-muted-foreground">
Score
</span>
</div>
</GaugeValueText>
</Gauge>
<Gauge value={64} size={180}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText>
<div className="flex flex-col items-center">
<span className="text-4xl font-medium">64%</span>
<span className="text-xs font-normal text-muted-foreground">
Healthy
</span>
</div>
</GaugeValueText>
</Gauge>
</div>
)
}
Biomarker
gauge-demo-biomarker
Loading...
"use client"
import * as React from "react"
import { Card, CardContent } from "@/components/ui/card"
import {
Gauge,
GaugeIndicator,
GaugeLabel,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const biomarkers = [
{
label: "Muscle Health",
value: 82,
},
{
label: "Metabolic Health",
value: 74,
},
{
label: "Recovery",
value: 61,
},
]
export function GaugeDemoBiomarker() {
return (
<div className="grid grid-cols-1 gap-6 sm:grid-cols-3">
{biomarkers.map((item) => (
<Card key={item.label} className="pt-0">
<CardContent className="flex flex-col items-center gap-4 pt-6">
<Gauge value={item.value} size={160}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText>
<div className="flex flex-col items-center">
<span className="text-3xl font-medium">{item.value}</span>
<span className="text-xs text-muted-foreground">/ 100</span>
</div>
</GaugeValueText>
</Gauge>
<GaugeLabel>{item.label}</GaugeLabel>
</CardContent>
</Card>
))}
</div>
)
}
Multiple Gauges
gauge-demo-multiple
Loading...
"use client"
import * as React from "react"
import {
Gauge,
GaugeIndicator,
GaugeRange,
GaugeTrack,
GaugeValueText,
} from "@/components/ui/gauge"
const metrics = [
{
label: "Strength",
value: 86,
},
{
label: "Mobility",
value: 72,
},
{
label: "Balance",
value: 64,
},
{
label: "Recovery",
value: 91,
},
]
export function GaugeDemoMultiple() {
return (
<div className="grid grid-cols-2 gap-6 sm:grid-cols-4">
{metrics.map((metric) => (
<div key={metric.label} className="flex flex-col items-center gap-3">
<Gauge value={metric.value} size={130} segments={40}>
<GaugeIndicator>
<GaugeTrack />
<GaugeRange />
</GaugeIndicator>
<GaugeValueText className="text-2xl" />
</Gauge>
<span className="text-sm font-medium">{metric.label}</span>
</div>
))}
</div>
)
}
Installation
pnpm dlx @designali/cli@latest components add gauge
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | null | Current value of the gauge. |
min | number | 0 | Minimum value. |
max | number | 100 | Maximum value. |
size | number | 200 | Width and height of the gauge. |
thickness | number | 2 | Thickness of each gauge tick. |
gap | number | 4 | Gap between adjacent ticks. |
segments | number | 60 | Maximum/preferred number of gauge segments. |
startAngle | number | 0 | Starting angle of the gauge. |
endAngle | number | 360 | Ending angle of the gauge. |
tickInnerRadius | number | calculated | Inner radius of the ticks. |
tickOuterRadius | number | calculated | Outer radius of the ticks. |
getValueText | (value, min, max) => string | percentage | Function used to generate accessible/display value text. |
asChild | boolean | false | Render the root element using the child element. |