DP Value Row

A horizontal strip of equal-width cells, one per index, paired with optional curved arcs drawn underneath that show how each cell's value is derived from prior cells. Where the @craft-bits/core DPValueRow focuses on per-cell tone semantics, this @craft-bits/viz variant focuses on the recurrence — the dependency shape that turns a flat array into a DP table.

Pass values for the current entries, highlight for the cell currently being filled, and transitions for the recurrence arcs. Each arc renders as a downward-bowed quadratic-Bezier curve with an arrowhead at to, and arcs whose to matches the current highlight brighten so the eye lands on the recurrence being applied.

DP value row, 7 cells, 2 filled, 2 transitions.
Customize
Shape
7
Playback
800 ms

Installation

npx shadcn@latest add https://craftbits.dev/r/dp-value-row.json

Usage

import { DPValueRow } from "@craft-bits/viz/dp-value-row";
 
<DPValueRow
  values={[0, 1, 1, 2, 3, null]}
  highlight={5}
  transitions={[
    { from: 3, to: 5, label: "f(i-2)" },
    { from: 4, to: 5, label: "f(i-1)" },
  ]}
/>

Pass labels to rename each column:

<DPValueRow
  values={[0, 1, 1, 2, 3, 5]}
  labels={["f(0)", "f(1)", "f(2)", "f(3)", "f(4)", "f(5)"]}
/>

Drop the transitions array entirely for a plain DP strip with no arcs:

<DPValueRow values={[0, 1, 1, 2, 3, 5]} highlight={5} />

Understanding the component

  1. One cell per entry. values.length cells render, in order. Each cell shows values[i] — a number, a string (such as a "infinity" placeholder), or the placeholder glyph (? by default) when the entry is null.
  2. Filled vs empty. Filled cells get an accent fill, accent border, and accent ink; empty cells get a muted background and the ? placeholder. The transition between states rides SPRINGS.smooth.
  3. Single-cell highlight. Unlike the core variant (which accepts a set of indices), this variant takes a single highlight index — the canonical "this is the cell the algorithm is filling right now". Pass null for a static row.
  4. Curved transition arcs. Each transitions entry draws a quadratic-Bezier arc from cell from to cell to with an arrowhead at to. Arc depth scales with edge length but caps at the arc-area height so long-range recurrences don't run off the bottom.
  5. Highlight-aware arcs. When highlight is set, arcs whose to matches it pulse brighter and slightly thicker — the eye follows the brightness to the cell currently being filled.
  6. Optional arc labels. A transition label renders centered above the arc midpoint at font-size: 10, in cb-fg-muted ink. It brightens to full opacity when its arc is active.
  7. Reduced motion. When prefers-reduced-motion: reduce is set, both the cell-state transition and the highlight pulse collapse to duration: 0 — values and arcs land instantly.

Props

PropTypeDefaultDescription
values(number | string | null)[]requiredCurrent DP entries. null renders the placeholder.
highlightnumber | nullnullIndex of the cell to pulse. null for a static row.
transitions{ from, to, label? }[][]Recurrence arcs to render under the row.
labels(string | undefined)[]Per-cell label above the cell. Defaults to the index.
placeholderstring"?"Glyph for empty cells.
transitionTransitionSPRINGS.smoothCell-state transition.
classNamestringMerged onto the root via cn().

Accessibility

  • The outer element is role="group" with a hidden summary like DP value row, 6 cells, 3 filled, 2 transitions. so screen readers hear the row's state at a glance.
  • Each cell is role="img" with an aria-label of label: value or label: empty, so a screen-reader user can read the array entry-by-entry.
  • Each cell exposes data-state (filled / empty) and data-highlight (true / false) so consumer apps can hook custom styles or assistive tooling.
  • The transition-arc SVG is aria-hidden — arcs are a visual reinforcement of the recurrence already encoded in values; screen readers consume the cell ARIA labels instead.
  • Colour is never the only signal — empty cells render the placeholder glyph alongside the muted background; the highlighted cell gets both a pulsing border and a brighter ink color.
  • Motion respects prefers-reduced-motion: reduce — cell-state transitions and the highlight pulse both collapse to instant swaps when the user opts out.

Credits

  • Extracted from: AlgoFlashcards (src/lessons/primitives/graph/DPValueRow.tsx). The viz extract strips the lesson chrome and the typed-input "predict the value" mode, accepts a flat (number | string | null)[] so the same component covers tabulation, memoization, BFS distances, and parent-pointer rows, and adds a first-class transitions array to make the recurrence visible directly on the row.