KQ-1725 · BURNDOWN/BOARD
Burndown Board
A sprint board under its own burndown chart: the planned scope's ideal line is a faint dashed guide, the actual line runs through the end of each day, and scope added mid-sprint raises a marked step with a flag. Moving a card into Done lifts its points off the card as a token that arcs up into today's point on one spring; as it lands the line steps down on springs.glide, the dot takes the hit on springs.recoil and the points-left figure rolls its digits on springs.snap, while every card that moved FLIPs to its place on glide. Cards move by drag or by keys — one roving tab stop, arrows to move, Space to lift, arrows to carry, Space to drop, Escape to put back — and under 40rem the chart shrinks into a header strip.
Sprint 14 · Tide tables
Oct 12 – 23 · day 5 of 10
| Mon 12 | 36 |
|---|---|
| Tue 13 | 31 |
| Wed 14 | 32 |
| Thu 15 | 29 |
| Fri 16 | 29 |
Arrows move between cards. Space lifts a card, arrows carry it, Space drops it and Escape puts it back. Moving a card to Done takes its points off the burndown.
29 pts left · day 5 of 10 · behind by 11
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/burndown-board
Props
- sprint
- BurndownSprint
- default defaultBurndownSprint
- The sprint the chart spans: { name, goal?, start (ISO date), days (working days, weekends skipped) }.
- columns
- BurndownColumn[]
- default defaultBurndownColumns
- The columns, left to right: { id, title, done? }. Cards that reach a done column come off the line.
- cards / defaultCards
- BurndownCard[]
- default — / defaultBurndownCards
- The cards, controlled or initial, in column order: { id, title, column, points, assignee?, addedOn?, doneOn? }. addedOn marks scope added on that working day; the board sets doneOn when a card reaches Done.
- onCardsChange
- (cards: BurndownCard[]) => void
- default —
- Fires with the whole board after a move.
- onMove
- (move: { cardId, from, to, index }) => void
- default —
- Fires from the drop, pointer or keyboard, that moved a card.
- onSprintChange
- (stats: BurndownStats) => void
- default —
- Fires from a move that changed the burndown, with { scope, planned, added, remaining, done, ideal, day, days, history }.
- onAddCard
- (columnId: string) => void
- default —
- Shows an Add button on the first column; the host appends the card, with addedOn set to today to mark it as added scope.
- now
- string
- default "2026-10-16"
- Today, as an ISO date; a weekend counts as the Friday before it. Never the wall clock.
- chartHeight
- number
- default 136
- The chart's height at tablet width and up, in px. Under 40rem it becomes a 40px header strip.
- cardStyle
- "raised" | "flat" | "outline"
- default "raised"
- Card surface: raised with a shadow, a flat tint, or an outline on the board colour.
- palette
- "cobalt" | "moss" | "ember" | "mono"
- default "cobalt"
- The burndown line, its wash, the dot, the points tokens and the done pills; the scope flag takes a contrasting colour.
- unit
- string
- default "pts"
- The unit printed after the figures.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the sprint has loaded: loading shows skeleton columns, error a message with Try again.
- onReload
- () => void
- default —
- Try again was pressed after the sprint failed to load.
- disabled
- boolean
- default false
- Read-only: nothing moves.
- className
- string
- default —
- Classes for the outer container.
| Prop | Type | Default | Description |
|---|---|---|---|
| sprint | BurndownSprint | defaultBurndownSprint | The sprint the chart spans: { name, goal?, start (ISO date), days (working days, weekends skipped) }. |
| columns | BurndownColumn[] | defaultBurndownColumns | The columns, left to right: { id, title, done? }. Cards that reach a done column come off the line. |
| cards / defaultCards | BurndownCard[] | — / defaultBurndownCards | The cards, controlled or initial, in column order: { id, title, column, points, assignee?, addedOn?, doneOn? }. addedOn marks scope added on that working day; the board sets doneOn when a card reaches Done. |
| onCardsChange | (cards: BurndownCard[]) => void | — | Fires with the whole board after a move. |
| onMove | (move: { cardId, from, to, index }) => void | — | Fires from the drop, pointer or keyboard, that moved a card. |
| onSprintChange | (stats: BurndownStats) => void | — | Fires from a move that changed the burndown, with { scope, planned, added, remaining, done, ideal, day, days, history }. |
| onAddCard | (columnId: string) => void | — | Shows an Add button on the first column; the host appends the card, with addedOn set to today to mark it as added scope. |
| now | string | "2026-10-16" | Today, as an ISO date; a weekend counts as the Friday before it. Never the wall clock. |
| chartHeight | number | 136 | The chart's height at tablet width and up, in px. Under 40rem it becomes a 40px header strip. |
| cardStyle | "raised" | "flat" | "outline" | "raised" | Card surface: raised with a shadow, a flat tint, or an outline on the board colour. |
| palette | "cobalt" | "moss" | "ember" | "mono" | "cobalt" | The burndown line, its wash, the dot, the points tokens and the done pills; the scope flag takes a contrasting colour. |
| unit | string | "pts" | The unit printed after the figures. |
| status | "ready" | "loading" | "error" | "ready" | Whether the sprint has loaded: loading shows skeleton columns, error a message with Try again. |
| onReload | () => void | — | Try again was pressed after the sprint failed to load. |
| disabled | boolean | false | Read-only: nothing moves. |
| className | string | — | Classes for the outer container. |