<!-- GENERATED by scripts/build-llms.mjs from llms/data.md — do not edit this file. -->

# `lr-gauge`

- **Import** `import '@aceshooting/lyra-ui/components/lr-gauge.js';` (stable tag alias; registers the tag)
- **Class** `LyraGauge`, also available unregistered from `@aceshooting/lyra-ui/components/data/gauge/gauge.class.js`
- **Family** `components/data/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 5 parts, 1 custom property — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-gauge`

Dependency-free SVG radial, full-circle ring, or linear meter (no charting library).

Removing `label` omits the visible SVG label in radial, linear, and ring shapes and restores the
localized gauge name unless `aria-label` is authored. The property retains removal `null`;
explicitly empty labels remain empty and later labels render normally.

**Properties:**

- `value: number = 0`
- `min: number = 0`
- `max: number = 100`
- `shape: GaugeShape = 'radial'`, where `GaugeShape = 'radial'|'ring'|'linear'` (reflected —
  `radial` is a 270° sweep; `ring` is a
  full circle that begins at 12 o'clock)
- `size?: LyraSize` (reflected, unset by default) — density tier on the library's one size ladder:
  `'2xs'|'xs'|'s'|'m'|'l'|'xl'`, or the Web Awesome / Shoelace spellings `'small'|'medium'|'large'`,
  which are accepted as authored rather than rewritten to the short form. A tier pins the host font
  size, and because the whole gauge box is expressed in `em` the frame, the stroke geometry and both
  SVG captions scale together — `8em` square for `radial`/`ring`, `12em` by `1.5em` for `linear`,
  each multiplied by that tier's font size. Leaving it unset keeps the inherited ambient text size
  and the exact geometry the gauge rendered before the ladder reached it, so existing markup is
  untouched. An unsupported value normalizes to the omitted state and removes the attribute.
- `label: string = ''`
- `valueText?: string` (attribute `value-text` — overrides both the visible text and the host's
  `aria-valuetext`; an empty string is treated the same as unset and falls back to the numeric
  `value` while removing `aria-valuetext`)
- `showValue: boolean = true` (attribute `show-value`, not reflected) — whether the decorative
  `part="value"` caption renders at all; `show-value="false"` omits it the same way an empty
  `label` already omits `part="label"`. `aria-valuenow`/`aria-valuetext` and the host's accessible
  name are unaffected either way, since the caption itself is always `aria-hidden`. Mirrors
  `<lr-progress-bar>`'s/`<lr-progress-ring>`'s own `showValue` name and meaning; the default here
  is `true` (a gauge's whole purpose is showing the reading it announces) where theirs is `false`.
- `variant: LyraProgressVariant = 'brand'` (reflected) — the same shared semantic-tone vocabulary
  `<lr-progress-bar>` uses (`'neutral'|'brand'|'success'|'warning'|'danger'`). The fallback color
  whenever `thresholds` is empty or matches nothing.
- `thresholds: readonly LyraGaugeThreshold[] = []` (attribute: false) — `LyraGaugeThreshold {
  readonly at: number; readonly variant: LyraProgressVariant }`. Value-to-variant color mapping:
  the LAST entry, after sorting by `at` regardless of authored order, whose `at` is `<=` the
  current `value` wins; an entry whose `at` is not a finite number never matches. The same rule
  serves a higher-is-worse domain like CPU load (`[{at: 0, variant: 'success'}, {at: 70, variant:
  'warning'}, {at: 90, variant: 'danger'}]`) and a higher-is-better one like battery charge
  (`[{at: 0, variant: 'danger'}, {at: 20, variant: 'warning'}, {at: 50, variant: 'success'}]`) —
  only the authored pairs differ.

**Events:** none.

**Slots:** none.

**CSS parts:** `base` (the `<svg>`), `track`, `fill`, `value` (rendered only while `showValue` is
true), `label` (rendered only while `label` is non-empty)

**Themeable custom properties:** `--lr-gauge-fill` (fill stroke; overrides `variant`/`thresholds`
entirely and falls back to the effective variant's shared semantic token —
`--lr-color-brand` by default).

**Optional peer deps:** none.

```html
<lr-gauge value="72" min="0" max="100" label="CPU"></lr-gauge>
<lr-gauge
  shape="ring"
  value="84"
  label="Coverage"
  style="--lr-gauge-fill: var(--lr-color-success)"
></lr-gauge>
<lr-gauge shape="linear" value="0.4" max="1" value-text="72°F"></lr-gauge>
<!-- compact dashboard meter: a slim, captionless, thresholded row -->
<lr-gauge
  shape="linear"
  size="xs"
  show-value="false"
  aria-label="Spend"
  value="84"
  max="100"
></lr-gauge>
<!-- automatic threshold coloring: same rule, opposite direction -->
<lr-gauge id="cpu" value="82" label="CPU"></lr-gauge>
<script>
  cpu.thresholds = [
    { at: 0, variant: 'success' },
    { at: 70, variant: 'warning' },
    { at: 90, variant: 'danger' },
  ];
</script>
<lr-gauge id="battery" value="15" label="Battery"></lr-gauge>
<script>
  battery.thresholds = [
    { at: 0, variant: 'danger' },
    { at: 20, variant: 'warning' },
    { at: 50, variant: 'success' },
  ];
</script>
```

**9.0 migration:** rename geometry `type`/`GaugeType` to `shape`/`GaugeShape`, and formatted-value
`valueLabel` to the declarative `valueText`/`value-text`. There are no legacy aliases.

**Known gotchas:**

- SVG text cannot wrap. Long caller-supplied `label`/`valueText` strings are visibly abbreviated
  with an ellipsis instead of being compressed into unreadable hairline glyphs; a nested SVG
  `<title>` supplies the full hover tooltip, while the host accessible label and `aria-valuetext`
  retain the complete text.
- The host defaults to `role="meter"` for a finite, non-degenerate range and `role="img"`
  otherwise. An authored host role remains authoritative across value updates; removing it restores
  the generated default.
- setting `valueText` (e.g. `"72°F"`) also sets `aria-valuetext` on the host (in addition to
  changing the visible SVG text), so a screen reader announces your formatted string instead of the
  raw `aria-valuenow` number; the SVG `<text part="value">`/`<text part="label">` elements are
  `aria-hidden="true"` so they're no longer separately exposed inside the same `role="meter"` host.
- `thresholds` recolors the fill from `value` alone — no reactive application-state wiring needed
  for the common success/warning/danger case. It never rewrites the `variant` property or its
  reflected attribute; the resolved color is tracked separately so a component reading back
  `variant` always sees the value it set. `--lr-gauge-fill` still overrides both `variant` and
  `thresholds` unconditionally, for a color outside the shared semantic-tone vocabulary.
- no documented component-specific sizing custom property. The host box is fixed em values
  (`8em` radial/ring, `12em`/`1.5em` linear) against the host font size, so `size` is the supported
  way to step it; for a dimension off the ladder, set plain CSS `width`/`height` (or `font-size`)
  on the element instead. The value/label captions are `em`-sized against that same host font-size,
  so they shrink right along with the frame at a smaller tier or a smaller host `font-size` —
  combine a small tier (or a small host `font-size`) with `show-value="false"` for a slim,
  thresholded dashboard meter, matching `<lr-progress-bar size="xs">`'s footprint but with
  `role="meter"` and one `thresholds` array instead of a hand-written ratio-to-variant mapping.
- Divide-by-zero guarded, and radial/linear share one component via the `shape`
  attribute.
- non-finite `value` text remains blank unless `valueText` supplies a truthful fallback; that
  fallback is included in the generated `role="img"` accessible name. Non-finite `min`/`max` use finite default domain
  bounds; no `NaN`/`Infinity` value leaks into the SVG geometry or ARIA attributes, and a finite
  value is clamped into the resolved domain before being announced.

---
