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.
Installation
npx shadcn@latest add https://craftbits.dev/r/dp-value-row.jsonUsage
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
- One cell per entry.
values.lengthcells render, in order. Each cell showsvalues[i]— a number, a string (such as a "infinity" placeholder), or theplaceholderglyph (?by default) when the entry isnull. - 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 ridesSPRINGS.smooth. - Single-cell highlight. Unlike the core variant (which accepts a set of indices), this variant takes a single
highlightindex — the canonical "this is the cell the algorithm is filling right now". Passnullfor a static row. - Curved transition arcs. Each
transitionsentry draws a quadratic-Bezier arc from cellfromto celltowith an arrowhead atto. Arc depth scales with edge length but caps at the arc-area height so long-range recurrences don't run off the bottom. - Highlight-aware arcs. When
highlightis set, arcs whosetomatches it pulse brighter and slightly thicker — the eye follows the brightness to the cell currently being filled. - Optional arc labels. A transition label renders centered above the arc midpoint at
font-size: 10, incb-fg-mutedink. It brightens to full opacity when its arc is active. - Reduced motion. When
prefers-reduced-motion: reduceis set, both the cell-state transition and the highlight pulse collapse toduration: 0— values and arcs land instantly.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
values | (number | string | null)[] | required | Current DP entries. null renders the placeholder. |
highlight | number | null | null | Index 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. |
placeholder | string | "?" | Glyph for empty cells. |
transition | Transition | SPRINGS.smooth | Cell-state transition. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The outer element is
role="group"with a hidden summary likeDP 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 anaria-labeloflabel: valueorlabel: empty, so a screen-reader user can read the array entry-by-entry. - Each cell exposes
data-state(filled/empty) anddata-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 invalues; 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-classtransitionsarray to make the recurrence visible directly on the row.