Range Meter
A reading on a ruler of ticks that rises where the value is, with the number above it.
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.
components/ui/range-meter/
├── RangeMeter.vue
├── RangeMeterLabel.vue
├── RangeMeterScale.vue
└── index.tsUsage
<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.
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.
API Reference
RangeMeter
RangeMeterScale
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.
- 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.