Gauge
Shows one value against a maximum, as a dial, a ring, a bar or a row of dots. Optional ranges color the scale.
Installation
The CLI installs the Radix or Base UI file to match your project.
If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.
When to use
Use it
- One value is measured against a scale or a goal, like quota attainment, win rate or customer satisfaction.
- A value falls into ranges that mean something, like behind, at risk and on track. The default dial draws them on its scale, as a Lightning dashboard's Gauge does.
- Progress toward a goal, where max is the goal. Use a ring (
variant="polar"), or a bar (variant="flat") where space is tight. - A score out of a few points, like a 1 to 10 survey. Use
variant="rating". - A usage meter against its limit, like data storage. Use a bar with the limit as
max, as the Against a limit example shows.
Don't use it
- For a number with no maximum or scale. Use Metric.
- For a task's progress, like an upload or an import. Use Progress.
- For several values to compare. Use Chart, with a bar or column chart.
- For a record's stage in a process. Use Path.
- For a rating someone enters. The rating variant only shows a score. Use Rating.
Usage
import { Gauge } from "@/components/wisty/gauge"<Gauge
variant="flat"
label="First contact resolution"
value={64}
unit="%"
reference={70}
/>Pick the variant by what the reader compares the value with. A dial shows where the value sits on ranges from bad to good. A ring and a bar show progress toward max, the goal. A rating shows a score on max dots, five by default.
Add a reference when there's a point to compare with, like a target or the team's average, and name it with referenceLabel ("Target" by default, "Avg" for an average). It's optional on every variant.
A band runs up to its to, not including it, so a value of exactly 80 falls in the band after to: 80. A value at or past the last band's to counts as the last band. Leave out a band's tone for a calm range below a warning. Format the value with valueFormatter for the org's locale; the examples use en-US.
Examples
Ring
Metric. 75% of the goal on a ring from `variant="polar"`, with the value in the middle.
Flat
Metric. Two bars from `variant="flat"`, each with the team average as a `reference` named Avg.
Rating
Metric. Customer satisfaction of 7 on ten dots from `variant="rating"`, against a target `reference` of 8.
Without bands
Metric. A dial with no `bands`: a win rate of 34% fills the track up to the needle, with the 40% average as a `reference`.
Against a limit
Metric. Data storage at 4.6 of a 5 GB `max` on a bar, in a Near limit band after a band with no tone.
Bands
Lightning's segment ranges from `bands` on a ring for the team and a bar per rep: behind below 50%, at risk below 80%, on track from it.
Over target
Metric. A `value` of 124 past a `max` of 100, as a dial and a bar: the needle and the bar stop at max and the text shows the real value.
No data
Metric. A `value` of `null` for attainment that didn't load: the dial has no needle, the bar is empty, and both say No data.
API reference
Gauge
| Prop | Type | Default | Description |
|---|---|---|---|
label* | React.ReactNode | Names the gauge. Shown under a dial or a ring, or above a bar or a rating. | |
value* | number | null | The value. It may pass max; the drawing stops at max, the text doesn't. null shows noDataLabel. | |
max | number | The end of the scale, which starts at 0: the goal on a ring or a bar, the number of dots on a rating. Default 100, or 5 on a rating. | |
variant | "dial" | "polar" | "flat" | "rating" | "dial" | A half dial with a needle (dial), a ring (polar), a bar (flat) or a row of dots (rating). |
reference | number | A point to compare the value with, like a target or an average. Keep it within max, or it has no mark. | |
referenceLabel | string | "Target" | The reference's name, shown with it, like "Target" or "Avg". |
bands | GaugeBand[] | Value ranges, lowest first. A dial draws them on its scale; the other variants take the color of the one the value is in. | |
noDataLabel | string | "No data" | Shown and read when value is null, or max isn't above 0. |
valueFormatter | (value: number) => string | (value: number) => oneDecimal.format(value) | Formats the value, the reference and a dial's scale. Default rounded to one decimal. |
unit | string | A unit after the value and the reference, like "%" or "days". |
Also takes every <div> (opens in a new tab) prop.
GaugeBandtype
type GaugeBand =
| {
to: number
tone: "success" | "warning" | "error"
label: string
}
| {
to: number
tone?: undefined
label?: string
}SLDS mapping
SLDS has no gauge component. The dial is Lightning's dashboard Gauge: a half ring with its segment ranges on the scale, the scale's values inside it, and a needle at the value. The ring, the bar and the rating are the polar gauge, flat gauge and ratings chart of the SLDS Charts guidelines' Metric intent: the ring and the bar fill toward max, the goal, and the guidelines ask for a reference point, a target or an average, where there is one. bands take the colors the charts and Metric's trend use; on a ring, a bar or a rating they color the value instead of the scale.
Known gaps:
- Lightning's dial shows no value by default and has no reference. This one writes the value and the band's name under the hub, and marks a
referencewhen you pass one. - Lightning draws its gauge in SLDS 1's colors. This one uses SLDS 2's success, warning and error colors, so it changes with the theme.
- The guidelines say a ring can drain as well as fill. Pass what's left as the value to drain one.
| Prop | Value | SLDS | Notes |
|---|---|---|---|
variant | dial (added) | none (Lightning's dashboard Gauge) | A half dial with its ranges on the scale and a needle at the value, with the value under it. The default. |
variant | polar (added) | none (the Charts guidelines' polar gauge) | A ring that fills clockwise from 12 o'clock toward max, the goal, with the value in the middle. |
variant | flat (added) | none (the Charts guidelines' flat gauge) | A thick bar toward max, the goal, with the label above and the value at its end. Use it where space is tight. |
variant | rating (added) | none (the Charts guidelines' ratings chart) | A row of max dots, filled up to the value, with the label above and the value at its end. |
reference | number (added) | none | Optional: a target or an average to compare with, named by referenceLabel. A tick across the dial or the ring, or a dashed line across the bar or the dots with its name in a tag below. |
bands | success, warning, error (added) | slds-progress-ring_complete, _warning, _expired | Lightning's segment ranges. A dial draws them on its scale; the other variants take the color of the band the value is in. Either way the band's name shows in its color. A band without a tone is the track's color on a dial and keeps the default color elsewhere. |
Accessibility
- The gauge is a
meternamed by itslabel. It sets its own role andaria-value*attributes after your props, so you can't replace them. aria-valuenowstops atmax, as a meter's value must.aria-valuetextcarries the real value, the band and the reference, like "68%, At risk, Avg 80%".- The drawing is hidden from screen readers, and so are the dial's scale values. Everything it shows is also in the text.
Motion
- The dial's needle sweeps from 0 to the value over 800ms when it first draws, with the charts' easing, and to a new value when the value changes. A dial without bands fills its track along with it.
- With reduced motion, the needle points straight at the value.
- The ring, the bar and the rating don't animate. A new value jumps into place.
Responsive behavior
- A dial is as wide as its parent, up to 18rem, and a little over half as tall. Below 12rem its scale shows only 0 and max, with no minor ticks.
- A ring is as wide as its parent, up to 14rem, and as tall as it is wide. Narrow either with
className, likemax-w-48. - The ring scales but its text doesn't. Below about 160px the value no longer fits inside, so use a bar there and in lists of people or records.
- A bar fills its parent, with the value at its end. A rating's dots keep their size and shrink only when the row is too narrow.
- In a list of bars whose values differ in width, give the value a fixed width so the bars line up, like
[&_[data-slot=gauge-value]]:min-w-32.
Rules
- Pass the real value, even past
max. The drawing stops full and the text shows the real value, like "124%". Never clamp or round it yourself. - Pass
nullfor a value that didn't load, never 0, so the gauge says "No data" (the No data example). - Keep
referencewithinmax: a reference past it gets no mark, only its text. - On a rating, keep
maxto ten dots or fewer, and pass a whole-numberreferenceso its line falls between dots. - On a dial, a band without a tone draws in the track's color. Use it for a calm range, never for one that needs attention.
- Pass
valueFormattera formatter with a fixed locale, like(value) => compact.format(value), so server and client print the same text. - Change the default value color through
className, like[--gauge-color:var(--chart-3)]. It colors a dial's fill when it has no bands, and the value on the other variants. Bands override it. - Never pass
asChildorrender.
Related
- MetricShows one number with its name, a unit and a trend colored good or bad.
- ProgressShows how far a task has come, from 0 to 100%.
- Progress ringShows how much of a task is done as a small ring that fills from 0 to 100.
- ChartDraws bar, line, area, donut, scatter and funnel charts.
- PathShows a record's stages as chevrons, with the current one and an action.
- RatingPicks a score from a row of stars or other icons that fill up to the choice.