Linear scale
Picks one number from a row, like 0 to 10, with words under the two ends. For stars or hearts, use Rating.
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
- People answer a survey question with one number on a scale, like a Net Promoter Score from 0 to 10 or a satisfaction score from 1 to 5.
- Every number should stay in view, with words under the two ends that say what they mean, like "Not at all likely" and "Extremely likely".
- Ranges of the scale mean something, like detractors, passives and promoters. Color them with
bands.
Don't use it
- People rate something with stars, hearts or thumbs. Use Rating.
- The options are words, not numbers. Use Radio group, or Toggle group for a segmented control in a toolbar.
- The value is any number in a wide range, like a discount. Use Slider or a number input.
- The score is shown, not entered. Use Gauge.
Usage
import {
LinearScale,
LinearScaleLabel,
LinearScaleLabels,
} from "@/components/wisty/linear-scale"LinearScale
└── LinearScaleLabels
└── LinearScaleLabelLinearScale draws one number for every whole number from min to max (0 to 10 by default). Put the end labels inside it: the first LinearScaleLabel sits under the first number and the last under the last number. Leave LinearScaleLabels out for a scale without words.
<LinearScale min={1} max={5} aria-labelledby="csat-legend">
<LinearScaleLabels>
<LinearScaleLabel>Very dissatisfied</LinearScaleLabel>
<LinearScaleLabel>Very satisfied</LinearScaleLabel>
</LinearScaleLabels>
</LinearScale>The value is the chosen number as a string, like "9", and the same string submits with a form under name. Choosing the chosen number again keeps it. To clear the answer, control value and set it to null, as Rating's Clear example does.
Each band is { from, to, tone }, both ends included, with tone one of "error", "warning" or "success":
<LinearScale
bands={[
{ from: 0, to: 6, tone: "error" },
{ from: 7, to: 8, tone: "warning" },
{ from: 9, to: 10, tone: "success" },
]}
/>Examples
Score bands
The same question with `bands`: 0 to 6 in the error color, 7 and 8 in the warning color, 9 and 10 in the success color.
One to five
A satisfaction question from 1 to 5, set with `min` and `max`.
States
A required question showing its error until a number is chosen, and a `disabled` scale with its answer and bands.
API reference
| Part | Built on | Description |
|---|---|---|
LinearScale | <div> (opens in a new tab) | A row of whole numbers to choose one from, like a 0 to 10 likelihood score. |
LinearScaleLabels | <div> (opens in a new tab) | |
LinearScaleLabel | <span> (opens in a new tab) |
LinearScale
A row of whole numbers to choose one from, like a 0 to 10 likelihood score.
| Prop | Type | Default | Description |
|---|---|---|---|
min | number | 0 | The first number on the scale, a whole number. |
max | number | 10 | The last number on the scale, a whole number, no lower than min. |
bands | readonly LinearScaleBand[] | [] | Colored ranges of numbers. Numbers outside every band keep the plain look. |
value | string | null | The chosen number as a string, controlled. null for none. | |
defaultValue | string | The number chosen at first, uncontrolled. | |
onValueChange | (value: string) => void | Called with the chosen number as a string. | |
name | string | The radios' name, to submit the choice with a form. Generated when not given. | |
disabled | boolean | false | Disables every number. |
required | boolean | false | A number must be chosen before the form submits. |
form | string | The id of a form the radios belong to, outside it. |
LinearScaleBandtype
| Member | Type | Default | Description |
|---|---|---|---|
from* | number | The band's first number, included. | |
to* | number | The band's last number, included. | |
tone* | LinearScaleTone | The band's color, as a strip over each of its numbers. |
SLDS mapping
LinearScale is slds-radio_button-group, and each number is an slds-radio_button: a native radio, visually hidden, and its slds-radio_button__label. The end labels and the band strips have no SLDS class.
Known gaps:
- The numbers have narrower padding than SLDS's radio buttons, so 0 to 10 fits a form column.
- SLDS has no rating scale or band. The strip over a banded number is drawn with the error, warning and success colors.
| Prop | Value | SLDS | Notes |
|---|---|---|---|
bands | error, warning, success (added) | None | A colored strip over the top of each number in a band. |
disabled | true (added) | slds-radio_button [type=radio][disabled] | Every number turns gray, and a band's strip with it. |
Accessibility
- Name the scale with
aria-labelledbypointing at aFieldLegend, or witharia-label. Each radio is named by its number. - The numbers are one Tab stop. Tab enters at the chosen number, or the first one when none is chosen, and the arrow keys move the choice.
- The end labels become the scale's description, after any
aria-describedbyyou pass, so a screen reader reads what the ends mean when focus enters the scale. - For an error, set
aria-invalidonLinearScale, which marks the group, and pointaria-describedbyat theFieldError. Withrequired, the radios are also invalid to the browser until a number is chosen. - A band's color is a hint, not the answer. The number carries the meaning, so the bands need no text of their own.
Responsive behavior
- The numbers keep their width and never wrap. When the row is wider than its container, the scale scrolls sideways, and focusing a number scrolls it into view.
- The scale takes the width of its container. Inside a container that sizes to its content, give that container a width, like
w-full max-w-mdon theFieldSet.
Rules
min,maxand every band's ends are whole numbers, and bands stay inside the range without overlapping. Anything else throws.- Keep the end labels short. Each one wraps within half the scale's width.
- Never pass
asChildorrender.
Related
- RatingPicks a score from a row of stars or other icons that fill up to the choice.
- Radio groupPicks exactly one option from a short list that stays visible.
- Toggle groupJoins toggles in a row, one or several pressed, like Day, Week and Month.
- SliderPicks a number or a range by dragging a thumb along a track.
- GaugeShows one value against a maximum, as a dial, a ring, a bar or a row of dots.