Sticky Metric

Pinned metric pill that sticks to a canvas object's corner.

Report a bug

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Installation

pnpm dlx shadcn@latest add https://ui.vllnt.ai/r/sticky-metric.json

Storybook

Explore all variants, controls, and accessibility checks in the interactive Storybook playground.

View in Storybook

4 stories available:

Code

"use client"; import { type ComponentPropsWithoutRef, forwardRef, type ReactNode, } from "react"; import { cn } from "../../lib/utils"; /** * Tone of the metric — drives the dot color. * * @public */ export type StickyMetricTone = "danger" | "neutral" | "success" | "warn"; /** * Anchor corner relative to the canvas object the metric sticks to. * * @public */ export type StickyMetricAnchor = | "bottom-left" | "bottom-right" | "top-left" | "top-right"; const TONE_DOT: Record<StickyMetricTone, string> = { danger: "bg-red-500", neutral: "bg-muted-foreground", success: "bg-emerald-500", warn: "bg-amber-500", }; const ANCHOR_OFFSET: Record<StickyMetricAnchor, { transform: string }> = { "bottom-left": { transform: "translate(-100%, 100%)" }, "bottom-right": { transform: "translate(0%, 100%)" }, "top-left": { transform: "translate(-100%, -100%)" }, "top-right": { transform: "translate(0%, -100%)" }, }; /** * Localizable strings. * * @public */ export type StickyMetricLabels = { /** Aria-label override. Defaults to `"Sticky metric"`. */ region?: string; }; const DEFAULT_LABELS = { region: "Sticky metric", } as const satisfies Required<StickyMetricLabels>; /** * Props for {@link StickyMetric}. * * @public */ export type StickyMetricProps = { /** Anchor corner. Defaults to `"top-right"`. */ anchor?: StickyMetricAnchor; /** Optional secondary slot rendered after the value (delta, unit). */ detail?: ReactNode; /** Short metric label (e.g. `"errs/min"`). */ label: ReactNode; /** Localizable strings. */ labels?: StickyMetricLabels; /** Tone for the leading dot. Defaults to `"neutral"`. */ tone?: StickyMetricTone; /** Display value (already formatted by host). */ value: ReactNode; /** Anchor X in canvas pixels. */ x: number; /** Anchor Y in canvas pixels. */ y: number; } & ComponentPropsWithoutRef<"div">; /** * Pinned metric pill that sticks to a canvas object's corner. Use to * overlay a single live value (errors / min, p95 latency, queue depth) * on a runtime object without consuming card real-estate. Pure * presentation; the host computes the anchor coords from the object's * bounding box and the value from the runtime stream. * * The wrapper is `pointer-events: none` — host gestures pass through. * * @example * ```tsx * <div className="relative h-screen w-screen"> * <Canvas /> * <StickyMetric * x={420} y={180} * anchor="top-right" * label="errs / min" * value="14" * tone="danger" * /> * </div> * ``` * * @public */ export const StickyMetric = forwardRef<HTMLDivElement, StickyMetricProps>( (props, ref) => { const { anchor = "top-right", className, detail, label, labels, tone = "neutral", value, x, y, ...rest } = props; const resolvedLabels = { ...DEFAULT_LABELS, ...labels }; return ( <div aria-label={resolvedLabels.region} className={cn( "pointer-events-none absolute z-20 inline-flex items-center gap-1.5 rounded-full border border-border bg-background/90 px-2 py-1 text-[11px] shadow-sm backdrop-blur", className, )} data-sticky-anchor={anchor} data-sticky-metric data-sticky-tone={tone} ref={ref} role="status" style={{ left: x, top: y, transform: ANCHOR_OFFSET[anchor].transform, }} {...rest} > <span aria-hidden="true" className={cn("size-1.5 rounded-full", TONE_DOT[tone])} data-sticky-metric-dot /> <span className="font-medium text-muted-foreground">{label}</span> <span className="font-semibold text-foreground">{value}</span> {detail ? ( <span className="text-[10px] text-muted-foreground" data-sticky-metric-detail > {detail} </span> ) : null} </div> ); }, ); StickyMetric.displayName = "StickyMetric";

Dependencies

  • @vllnt/ui@^0.2.1