---
title: "SignalMeter"
description: "A segmented strength bar that reads confidence, relevance, or signal as a count of lit segments."
category: Visualization
status: beta
since: 0.3.9
tags: [ai, confidence, meter]
syncStatus: reviewed
verified: true
---

## Usage

### Four Levels

`value` decides how many segments light up. Unlit segments keep the hairline tone and ignore `tone` entirely.

:::TuffDemoWrapper{demo="SignalMeterLevelsDemo" code-lang="vue"}
---
code: |
  <template>
    <TxSignalMeter :value="3" tone="var(--tx-bui-green)" label="High confidence" />
    <TxSignalMeter :value="2" tone="var(--tx-bui-orange)" label="Needs review" />
    <TxSignalMeter :value="1" tone="var(--tx-bui-red)" label="Weak evidence" />
    <TxSignalMeter :value="0" tone="var(--tx-bui-ink-3)" label="No signal" />
  </template>
---
:::

### Best Practices

- Colour is never the only carrier of state: put a text label beside the meter (`High confidence` / `Needs review`) and pass that same text as `label`.
- Keep `max` consistent within a screen, or "two of three" and "two of five" read as the same strength.
- When the parent already shows a visible label, leave `label` off so a screen reader announces it once.
- Map a semantic value such as `confidence` to `value` + `tone` in the host rather than scattering magic numbers through templates.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `number` | — | Lit segment count. Required; clamped into `[0, max]` and truncated toward zero. |
| `max` | `number` | `3` | Total segment count. |
| `tone` | `string` | `'currentColor'` | Colour of the lit segments, any CSS colour. Inherits the parent's text colour by default. |
| `label` | `string` | — | Accessible name. Without it the whole meter is marked `aria-hidden`. |
| `barHeight` | `number` | `10` | Segment height in px. |
| `barWidth` | `number` | `4` | Segment width in px. |

### Events

The component has no interaction and emits nothing.

### Slots

The component has no slots.

## Where It Fits

- The confidence footer and alternatives list of a suggestion card — `TxRecommendationCard` uses it internally.
- Relevance on retrieval results: three segments scan across a column faster than a percentage.
- Any discrete strong / medium / weak / none quantity. Use `TxProgressBar` for continuous ones.

## Overview

- A presentation-only primitive: no events, no internal state, repaints when `value` changes.
- **`label` decides the accessibility semantics.** Supply it and the meter renders `role="img"` with `aria-label`; omit it and the whole meter is `aria-hidden="true"`. The latter is deliberate — three empty `span`s announced one at a time are noise, and in real layouts the meter always sits beside its own visible text.
- An out-of-range `value` neither throws nor overflows; it is clamped into `[0, max]`.
- `tone` takes a raw CSS colour string and **does not follow the theme**. Pass a variable such as `var(--tx-color-success)` rather than a hex literal if you want it to.
- The fill transition runs 300ms; `prefers-reduced-motion: reduce` drops the transition and keeps the final colour.

## Technologies

- Component source: `packages/tuffex/packages/components/src/signal-meter/src/TxSignalMeter.vue`.
- Types: `packages/tuffex/packages/components/src/signal-meter/src/types.ts`.
- **Verified coverage:** `packages/tuffex/packages/components/src/signal-meter/__tests__/signal-meter.test.ts` (6 cases) covers segment and lit counts, the controlled `value` loop, out-of-range clamping, a custom `max`, the `role` / `aria-hidden` branch around `label`, and tone plus geometry reaching the custom properties.
- Adapted from Beautiful UI (https://www.beautifului.dev), © 2026 Shane Levine, MIT.

<TuffDocSourceLink />

- **How it divides from the existing badges:** `TxStatusBadge` is a bordered badge over five semantic tones and `TxProgressBar` is continuous progress. This component is bare discrete segments that accept any colour, with no border and no icon — the three are not interchangeable.
- **Upstream deviation:** upstream keeps the meter inside the recommendation card, fixed at three segments with hardcoded colours. It is extracted here and the count exposed as `max`, because the same shape is useful for retrieval relevance.
