Range Meter

A reading on a ruler of ticks that rises where the value is, with the number above it.

Dark previewReplay previewOpen in new tab

Checkout page

Budget 300 ms

Response time

240ms

60 ms inside budget
240
80 ms600 ms

Use it for one reading on a known scale where the position matters as much as the number: a response time between the fastest and the slowest, a level between empty and full. The scale is a ruler of ticks that rises where the reading is, with the number in a tag above the rise.

With v-model it is a slider that can be dragged. With only :model-value, the same drawing is a meter that only shows a value.

It needs about 12rem of width for the rise to read as one. In a tighter space, or for a reading that needs no number, use Progress.

Installation

Copy the folder into components/ui, where you can edit it. It needs the cn helper and the theme's info, success and warning colours.

text
components/ui/range-meter/
├── RangeMeter.vue
├── RangeMeterLabel.vue
├── RangeMeterScale.vue
└── index.ts

Usage

vue
<script setup lang="ts">
import { ref } from "vue";
import { RangeMeter, RangeMeterLabel, RangeMeterScale } from "@/components/ui/range-meter";

const time = ref(240);
</script>

<template>
  <RangeMeterLabel>Response time</RangeMeterLabel>
  <RangeMeter v-model="time" :min="80" :max="600" :step="10" :marker="300" />
  <RangeMeterScale start="80 ms" end="600 ms" />
</template>

Composition

<RangeMeterLabel />
<RangeMeter v-model="…" />
<RangeMeterScale start="…" end="…" />
  • RangeMeterLabel: the meter's name, written over it. The meter's own label prop is what a screen reader says; this is the visible name.
  • RangeMeterScale: what the two ends of the ruler stand for, at either side under it: start and end.

A reading that cannot be changed

Bind only :model-value and it is announced as a meter, takes no focus and ignores the pointer. format-value writes the number in the tag.

Dark previewReplay previewOpen in new tab

Build cache

71%

Artifact storage

88%

Log retention

34%

Fewer ticks and an icon

ticks sets how many the ruler is drawn with. Here there are 21, one for each step of 5. The default slot is drawn in the tag before the number, which is the place for an icon.

Dark previewReplay previewOpen in new tab
65%
DimBright

API Reference

RangeMeter

PropTypeDefaultDescription
modelValuenumber—The reading: where the ruler rises and the number written above it. Bind it with v-model to make it a slider; without a listener it is a meter.
minnumber0The low end of the ruler.
maxnumber100The high end of the ruler.
stepnumber1How much one arrow key press moves the value, and what a drag snaps to.
markernumber—A value to mark under the ruler, such as a target.
ticksnumber41How many ticks the ruler is drawn with.
color"primary" | "info" | "success" | "warning" | "destructive""primary"Which of the theme's roles the lit ticks and the tag are drawn in.
formatValue(value: number) => string—Writes the number in the tag. Defaults to the value as it is.
labelstring"Reading"What a screen reader calls it.
valueTextstring—What a screen reader says for the value: "240 milliseconds".
EventDescription
update:modelValueThe new value as the ruler is dragged or moved with the keyboard.
SlotDescription
defaultDrawn in the tag before the number: an icon.

RangeMeterScale

PropTypeDefaultDescription
startstring—The word or figure at the low end.
endstring—The word or figure at the high end.
SlotDescription
startMarkup for the low end, in place of the start prop.
endMarkup for the high end, in place of the end prop.

Every part also takes the attributes of the element it renders, and a class.

Notes

Scale

min and max are the ends of the ruler and default to 0 and 100. A value outside them is drawn at the nearest end and still announced as given.

step is what one arrow key press moves the value by, and what a drag snaps to.

Ticks

The ruler has 41 ticks unless ticks says otherwise. They are decoration and not graduations: the reading is placed by its value, between two ticks if that is where it falls. Set ticks so one tick is a round amount if you want them to line up with the steps.

The tag stays inside

The tag sits over the reading and is hung from it in proportion to the reading's place on the ruler: by its left edge at the lowest value, its middle half way and its right edge at the highest. Nothing hangs outside the control, so it can be placed against the edge of a card.

The control is taller than the ruler by the height of the tag, which is drawn inside its box.

Marker

marker draws a small diamond under the ruler at a value, such as a target or a budget. It is hidden from screen readers, so say what it marks in text beside the meter.

Colour

color names one of the theme's roles and colours the lit ticks and the tag. To show that a reading has crossed a threshold, work out the role from the value and pass it, as the first example does. The text in the tag is worked out from the colour, dark on a light one and white on a dark one.

Keyboard

Left and down lower the value by one step, right and up raise it. Page Up and Page Down move a tenth of the range, and Home and End go to the ends.

Screen readers

Pass label to name the reading and value-text to say the value with its unit, such as "240 milliseconds".

Accessibility

Keyboard shortcuts and ARIA behavior.

Shortcut Description
← + ↓Lower the value by one step.
→ + ↑Raise the value by one step.
PageDownLower the value by a tenth of the range.
PageUpRaise the value by a tenth of the range.
HomeGo to the low end.
EndGo to the high end.
  • With v-model it has role="slider" and one Tab stop; with only :model-value it has role="meter" and takes no focus.
  • aria-valuenow, aria-valuemin and aria-valuemax follow the value and the range; value-text becomes aria-valuetext.