Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Developer Sprints Kanban Block for React

A sprint board with a lane for each of five developers, four statuses ending in a locked Merged column, and pull request numbers stamped as tickets enter PR open.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Track a sprint developer by developer with this sprint board for React with Base UI. A hairline frame with a plus mark on each corner holds a lane for each of five developers and four statuses (Assigned, Coding, PR open and Merged) over nineteen tickets, each with a mono reference. A ticket that enters PR open is stamped with the next pull request number, worked out from the highest one on the board, and keeps it if it goes back. Merged is final: a merged ticket is locked, with a lock where the grip was, no menu, and a reason that a screen reader reads out ("Merged cards stay put"). Each lane head shows the developer's initials in an Avatar, "Merged 3 this sprint", the open tickets and the coding load. Two rules refuse with the reason in words: a ticket is merged only from PR open, and nobody codes more than two tickets at once. A card moves three ways: drag its grip, focus the grip and use Space, the arrow keys and Escape, or open its Dropdown Menu and choose "Move to" a status or "Hand to" a developer. A polite status line in the foot reports each move, and Reset puts the board back. The frame is ruled by Guides. For engineering teams, sprint reviews and any flow with a point of no return.

FAQ

How do I use my own developers and tickets?

Edit LANES, STATUSES and START. A ticket has an id, a ref, a title, a pull number (0 until it first reaches PR open) and the column it starts in, written as the lane and the status joined by a dot (corvin.coding). The merged counts, the open counts and the header sentence are worked out from the tickets.

Where does the pull request number come from?

settleCards runs after every move. When a ticket has just entered PR open and has no number, it gets the highest pull on the board plus one, so the numbers keep counting up whoever opens them. A ticket that goes back to Coding keeps its number and gets the same one when it returns. A cancelled keyboard lift restores the board as it was, so a number is never used up by a move you took back. In a real app the number comes from your host's API.

How does a merged ticket stay put?

lockOf returns a reason for a ticket in Merged and an empty string for the rest. A locked card gets a lock icon with the reason in text for screen readers, in the place of the grip, and no menu, so there is nothing to drag or choose. Nothing in the board moves it, and only Reset (or reloading) brings it back.

How do I move a ticket without a mouse?

Tab to the grip at the start of a card, named "Move" with the ticket's title. Press Space or Enter to pick it up, then ArrowUp and ArrowDown to change its place in the cell (at the top or bottom of a cell the card crosses into the neighbouring developer's cell in the same status), ArrowLeft and ArrowRight to go to the neighbouring status in the same developer (the arrows swap in right-to-left languages), Home and End for the first and last place, Space or Enter to drop it and Escape to put it back. Every step is announced in the status line, for example "STB-227, Rhosyn Tegg, PR open, position 2 of 2."

How do the two rules work, and how do I change them?

refusalOf refuses a move into Merged unless the ticket comes from PR open, and a move into a Coding cell that already holds CODING_CAP tickets. The drop, the keyboard steps and the menu all ask it, a refused move leaves the ticket where it was, and the status line gives the reason.

What stays in the demo, and how do I save the moves?

Everything: the moves and the numbers live in the component's state, nothing is sent anywhere, and a reload or Reset brings back the starting board. To save for real, call your API from put, the one function every finished move goes through. The developers and tickets are made up.