Pointer Labels

Labeled arrow markers anchored above (or below) positions on an SVG axis. The "pointer + chip" compound for marking algorithmic positions on a linear visualization — i and j cursors in a two-pointer scan, head and tail markers on an array, lo and hi boundaries in a binary search.

ij
Customize
Visual
idx 2
idx 5
accent

Installation

npx shadcn@latest add https://craftbits.dev/r/pointer-labels.json

Usage

import { PointerLabels } from "@craft-bits/core";
 
<svg viewBox="0 0 360 120">
  <PointerLabels
    y={80}
    pointers={[
      { id: "i", x: 80,  label: "i", tone: "accent"  },
      { id: "j", x: 180, label: "j", tone: "success" },
    ]}
  />
</svg>

Understanding the component

  1. Drop inside an <svg>. PointerLabels renders an SVG <g> containing one subgroup per pointer. Each subgroup is a rect chip plus text plus a triangle arrow. It must live inside an <svg>.
  2. Each pointer has stable identity. Pointers are keyed by id. Passing the same id with a different x glides the pointer to its new position via layoutId and SPRINGS.smooth. Adding or removing a pointer fades it in or out without disturbing the rest.
  3. Direction flips the layout. direction="down" (the default) renders an arrow pointing downward toward the axis with the chip stacked above. direction="up" mirrors it — chip below, arrow above.
  4. Tones derive from theme tokens. default uses --cb-fg and --cb-bg-elevated. accent, success, warning, and error consume the corresponding --cb-* semantic vars, so chip color follows the user's theme.

Props

PropTypeDefaultDescription
pointersReadonlyArray<PointerLabelEntry>requiredEach entry has id, x, label, optional tone.
direction'down' | 'up''down'Arrow direction.
ynumber0Y position of the arrow tip in SVG user coordinates.
fontSizenumber11Label font size in px.
padnumber5Horizontal padding around the label text.
gapnumber2Distance between arrow base and chip.
arrowSizenumber6Arrow triangle height.

Accessibility

  • The outer <g> carries role="group" and aria-label="Pointers"; each pointer subgroup carries role="img" and a derived aria-label.
  • The wrapper sets pointer-events: none and user-select: none since pointers are presentational overlays.
  • Position glides use SPRINGS.smooth. Honor prefers-reduced-motion at the consumer level if needed.

Credits

  • Extracted from: algoflashcards (src/lessons/primitives/viz/PointerLabels.tsx).