Vanilla Breeze

product-roadmap

Interactive themes × quarters product roadmap. Auto-discovers lane sections + initiative articles; editable mode wires drag-to-reschedule, drag-to-resize, and drop-on-lane.

Overview

The <product-roadmap> component renders a horizontal time axis (quarters or months) with one swimlane per <section data-lane>. Each <article data-start data-end> inside a lane becomes a status-coded bar spanning its date range.

Distinct from <gantt-chart>: roadmap is theme-centric (initiatives in lanes, status as enum, no dependency arrows). Gantt is task-scheduling. Use roadmap for quarterly product roadmaps; gantt for project plans.

Authoring shape

The component reads its content from authored HTML — no JSON config required. Lanes are <section data-lane>; initiatives are <article data-start data-end> inside a lane:

Dates accept ISO 8601 (2026-07-01) or quarter shorthand (2026-Q3). For data-end, quarter shorthand resolves to the last day of the quarter.

Attributes

Child attributes

Status colors

Set data-status on each initiative to drive the bar color. Recognized values:

  • planned — info blue
  • in-progress — accent
  • at-risk — warning amber
  • shipped — success green
  • blocked — danger red

Custom statuses fall back to the default accent. Override --color-accent or per-status tokens to retheme.

Editable mode

Add the editable attribute to enable interactive editing:

  • Drag bar body → snaps to the nearest quarter (or month, if view="month"); fires product-roadmap:reschedule; updates data-start/data-end on both the rendered bar AND the source <article>.
  • Drag right edge → resizes the end date; fires product-roadmap:resize.
  • Drag onto another lane → moves the source <article>; fires product-roadmap:move.
  • Click bar → fires product-roadmap:select with full detail.

Today marker

Add today-marker to render a vertical line at the current date if it falls within the visible range. Useful for "where are we now in the year" context.

Progressive Enhancement

  1. HTML. Without JS, the component CSS hides source lanes (otherwise <article> headings would flash before upgrade). Authors who need a visible no-JS fallback should render a sibling table or list.
  2. CSS. The :not(:defined) selector keeps the host visible pre-upgrade.
  3. JS. Auto-discovers lanes + initiatives, builds the time-axis header, positions bars by date fraction, optionally wires drag-to-reschedule and lane drops.

Known limitations (v1)

  • Overlapping initiatives in the same lane render stacked (later DOM order on top). Sequence non-overlapping work in a single lane, or split overlapping work into multiple lanes.
  • Initiatives whose dates fall entirely outside the visible range are skipped. Initiatives crossing the boundary are clipped.
  • No keyboard shortcuts for drag-to-reschedule yet (use the explicit data-start/data-end attributes for screen-reader-driven editing).

Related