Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Vendor Tracker Kanban Block for React

A four-lane procurement board of eleven supplier contracts with the annual value, a renewal worked out in words from a fixed date, and a clock mark on contracts renewing within 30 days.

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

Keep supplier contracts and their renewals in view with this vendor board for React with Base UI. A hairline frame with a plus mark on each corner holds four lanes that share their lines: Researching, Evaluating, Negotiating and Approved. Each of the eleven contracts is a card with a title, its annual value ("/yr") and a renewal worked out in words from a fixed date ("Renews in 45 days", "Renews today", "Renewal passed 3 days ago"); a renewal within 30 days gets a clock and medium weight, so urgency never depends on colour. Every lane head counts its contracts and totals their annual value, and the header sentence counts the renewals that are near or past. A contract 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 procurement reviews and renewal calendars.

FAQ

How do I fill it with my own contracts?

Edit COLUMNS, START, SOON and AS_OF. A contract has an id, the column it starts in, a title, its annual value in cents (the usd() helper turns dollars into cents) and a renews ISO date. SOON is the number of days that count as near; the lane totals and the header sentence are calculated from the cards.

How is the renewal word worked out?

From the ISO date and the single AS_OF constant, as whole days since the epoch, so it never depends on the visitor's clock or time zone and the server and the browser agree. Future dates read "Renews in N days", the same day reads "Renews today" and past dates read "Renewal passed N days ago". Use the server's date for AS_OF in production.

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. 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.

Is any move refused?

No: a contract can go to any lane, including back to Evaluating when terms change. Add a check to refusalOf, for instance that nothing is Approved without passing Negotiating, and the refusal appears in the status line.