Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Lead Pipeline Kanban Block for React

A four-lane lead board of twelve small businesses, each scored Hot, Warm or Cold with a glyph and a word, where Cold leads can't be qualified until their score is raised.

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

Work a lead list with this pipeline board for React with Base UI. A hairline frame with a plus mark on each corner holds four lanes that share their lines: New, Contacted, Qualified and Won. Each of the twelve leads is a card with the business, the value it could be worth and a lead score drawn as a glyph and a word in an outline Badge: Hot with a flame, Warm with a sun, Cold with a snowflake. Every lane head counts its leads and totals their value, and two rules guard the board and refuse in words: a Cold lead can't be qualified, and a lead is only won from Qualified. The "Raise score" button on a card moves Cold to Warm to Hot, which is how a lead earns its way past the first rule. A lead moves by dragging its grip, by Space, the arrow keys and Space again (Escape cancels), or from its Dropdown Menu with "Move to". The frame is ruled by Guides. On a phone the lanes scroll sideways in one named region with the next lane showing. For lead triage and any pipeline with a qualifying step.

FAQ

How do I fill it with my own leads?

Edit COLUMNS and START. A lead has an id, the column it starts in, a title, a score of "Cold", "Warm" or "Hot" and its value in cents (the usd() helper turns dollars into cents). The lane totals, the count of Hot leads and the header sentence are calculated from the cards.

What are the two rules and how do I change them?

refusalOf holds both: moving a Cold lead to Qualified, and moving any lead to Won from a lane other than Qualified, return a sentence instead of an empty string. The card stays where it is, focus returns to it and the sentence is read out in the status line, so a drag, a keyboard drop and the menu all say the same thing. Change the conditions there, or delete them to allow every move.

Why is the score a word as well as a glyph?

A symbol alone fails people who can't tell the shapes apart or use a screen reader, and colour alone fails more. The badge pairs the glyph with the word and an unseen "Score" prefix, so the meaning is the same in every theme and for every reader. "Raise score" is a real button with the lead's name in its label, disabled once a lead is Hot or Won.

How do I move a card without a mouse?

Tab to the grip at the start of a card, named "Move" with the card's title. Space or Enter picks it up, ArrowUp and ArrowDown change its place in the lane, ArrowLeft and ArrowRight go to the neighbouring lane (they swap in right-to-left languages), Home and End jump to the top and bottom, Space drops it and Escape puts it back. Each step is announced in the status line.

Is there a way to move without dragging?

Yes: the menu at the end of each card lists the lanes with the current one ticked, so one click moves the card, focus lands on it in its new place and the status line says so. This is the route for a single pointer and for touch.

What stays in the demo?

Everything. The moves live in the component's state, nothing is saved or sent, and a reload or Reset brings back the starting board. The product, the deals and the figures are made up. A raised score lasts until you reload or press Reset. To keep a board, call your API from put, the one function every finished move goes through, and update the cards from the response.

How does it look on a phone?

The lanes scroll sideways inside the board with the next lane showing, and each lane scrolls up and down within the board's fixed height, so the page does not jump when a card moves. Touch drags from the grip only, so the rest of a card still scrolls; the menu is the other way to move it.