Detent web components
By Shane Logsdon

Charts & metrics

Metric Sparkline

Implemented

Telemetry tile with a live-scrubbable sparkline

detent-metric-sparkline

Port status
Catalog status
implemented
Origin
upstream
Phase
3
Wave
phase-3-data
Group
Charts & metrics

9.1 KB gzip for the class module · inlines the shared spring

Variants

Three selectable metrics (CPU load, p99 latency, error rate) with delta badges, a status aura and a scrubbable sparkline. Switch the range with the 1h / 24h / 7d / 30d buttons (each is a real button with aria-pressed), select a card, and copy a value with the copy control. Every series is a local simulation: nothing is measured, streamed or sent anywhere.

Ready.

Recorded states

  • active recorded state; no setter
  • hover recorded state; no setter
  • copied recorded state; no setter
  • normal recorded state; no setter
  • warning recorded state; no setter
  • critical recorded state; no setter
  • empty recorded state; no setter
  • reduced motion recorded state; no setter

Usage

Import

import '/components/metric-sparkline/define.js';

// or register it yourself
import { DetentMetricSparkline } from '/components/metric-sparkline/metric-sparkline.js';

Attributes

  • default-time-range

Properties

  • metrics
  • timeRanges

Slots

No slots are recorded for this component.

Events

No events are recorded for this component.

Example

Runnable example: site/examples/metric-sparkline.ts. The snippet below is generated from the catalogued attributes.

<detent-metric-sparkline
  default-time-range="24h"
></detent-metric-sparkline>

Property-only values

const element = document.querySelector('detent-metric-sparkline');
if (element !== null) {
  // metrics: MetricItem[]
  element.metrics = [];
  // timeRanges: string[]
  element.timeRanges = [];
}

Source

The pinned upstream source for this row:

  • src/components/ui/MetricHUD.tsx sha256 efc6993ee923…

Native files

The native module and its artifacts:

  • src/components/metric-sparkline/metric-sparkline.ts
  • src/components/metric-sparkline/styles.css
  • src/components/metric-sparkline/define.ts
  • docs/components/metric-sparkline.md
  • site/examples/metric-sparkline.ts
  • tests/browser/metric-sparkline.spec.ts
  • evidence/components/metric-sparkline.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
default-time-rangedefaultTimeRangestring'24h'Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
metricsMetricItem[][]Property-only: assign from script; not accepted as an attribute.
timeRangesstring[]['1h', '24h', '7d', '30d']Property-only: assign from script; not accepted as an attribute.

Events

No custom events are recorded for this component.

Slots

No slots are recorded for this component.

CSS customisation

  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • Metric cards are a <button part="metric-select"> with a sibling <button part="metric-copy"> instead of a clickable <div> with a nested button: nested buttons are invalid HTML, and the upstream div was not keyboard operable (recorded accessibility correction, PC-12.6).
  • The status indicator adds a visible word next to the colour dot, and the delta badge exposes data-trend/data-tone; upstream relies on colour and a lucide icon.
  • Copy feedback changes the copy button's accessible name and icon; upstream shows a check icon with no announcement.
  • The line draws once per mount of the path on springGentle (pathLength through stroke-dashoffset on the shared spring helper; new series redraw in place, as upstream's unkeyed path), the selected time-range pill glides on springSnappy (box-spring, as its layoutId), the critical indicator pings as Tailwind 4.3.3 animate-ping (1s cubic-bezier(0, 0, 0.2, 1), scale 2 / opacity 0) and the hover dot carries upstream's static r=6 halo. Under reduced motion the draw and ping are removed and the pill moves at once (PC-10.5).
  • description is accepted as plain data and kept in the model, but this port does not render a tooltip for it: the row records no tooltip surface for this component (the description reaches assistive technology through the consumer's own copy).
  • The HUD is themed from --detent-color-* tokens instead of upstream's hard-coded #0E0E0E/#FAFAFA, so light and dark both work (PC-9.5).
  • className is replaced by the documented parts and custom properties; there is no Tailwind in consumers.

What it does

A developer telemetry HUD: a header with a status indicator and a time-range switcher, a grid of selectable metric cards (value, unit, delta badge, copy action), and one interactive SVG sparkline for the selected metric and range with a pointer crosshair, a coordinate readout and min/max labels.

Upstream behaviour
  • Zero-dependency hardware-accelerated SVG sparkline rendering
  • Interactive pointer crosshair scrubbing with dynamic coordinate inspection
  • Spring-animated time-range switching (1h, 24h, 7d, 30d)
  • Real-time delta trend badges (up / down / neutral) with status aura
  • One-click metric value copying with validation feedback
Differences from upstream
  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • Metric cards are a <button part="metric-select"> with a sibling <button part="metric-copy"> instead of a clickable <div> with a nested button: nested buttons are invalid HTML, and the upstream div was not keyboard operable (recorded accessibility correction, PC-12.6).
  • The status indicator adds a visible word next to the colour dot, and the delta badge exposes data-trend/data-tone; upstream relies on colour and a lucide icon.
  • Copy feedback changes the copy button's accessible name and icon; upstream shows a check icon with no announcement.
  • The line draws once per mount of the path on springGentle (pathLength through stroke-dashoffset on the shared spring helper; new series redraw in place, as upstream's unkeyed path), the selected time-range pill glides on springSnappy (box-spring, as its layoutId), the critical indicator pings as Tailwind 4.3.3 animate-ping (1s cubic-bezier(0, 0, 0.2, 1), scale 2 / opacity 0) and the hover dot carries upstream's static r=6 halo. Under reduced motion the draw and ping are removed and the pill moves at once (PC-10.5).
  • description is accepted as plain data and kept in the model, but this port does not render a tooltip for it: the row records no tooltip surface for this component (the description reaches assistive technology through the consumer's own copy).
  • The HUD is themed from --detent-color-* tokens instead of upstream's hard-coded #0E0E0E/#FAFAFA, so light and dark both work (PC-9.5).
  • className is replaced by the documented parts and custom properties; there is no Tailwind in consumers.
Previous: Meteors Next: Money Card

Docs

Components

Project