Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Product Catalog Kanban Block for React

A four-column catalog board (Draft, Review, Live, Retired) of ten products with drawn image plates, SKUs and prices in cents, where a product can't go Live until it has an image.

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

Bring products to the shelf with this catalog board for React with Base UI. A hairline frame with a plus mark on each corner holds four columns that share their lines (Draft, Review, Live and Retired) and ten products. Each card shows a drawn image plate or a dashed "no image" box, the name, the SKU in mono and the price, held in integer cents; every column head counts its products and totals their prices, and the sentence under the heading counts the products still missing an image. An "Add image" Button on a card draws its plate. One rule guards the board: a product can't go Live without an image, and the refusal names the product and says what to do. A card moves by dragging its grip, by Space, the arrow keys and Space again (Escape cancels), or from its Dropdown Menu under "Move to", the route for a single pointer and for touch. A polite status line in the foot reports each change and Reset puts the catalog back. The frame is ruled by Guides. On a phone the columns scroll sideways in one named region. For storefront back offices, merchandising tools and any workflow that publishes records through review.

FAQ

How do I fill it with my own products?

Edit COLUMNS and START. A product has an id, the column it starts in, a name, a sku, a price in integer cents, a shape for its drawn plate (bottle, lamp, mug, stool or tote) and drawn, whether its image exists yet. Every count, total and sentence is calculated from the cards. To show a real image, replace the Plate component with an img of the product's file and set drawn from whether the file exists.

How does the image rule work?

refusalOf gets the cards, the product, the column it comes from and the column it is going to, and returns a reason or an empty string. The grip's drop, the keyboard steps and the menu all ask it, so no route gets around it. A refused move leaves the product where it was and the status line gives the reason. Add more checks there, such as a price above zero before Review.

Why are prices in cents?

Floating point can't hold a price exactly, so the board keeps integer cents and formats them in one helper. Lane totals are sums of integers. The price is always set left to right, so digits and the dollar sign keep their order in a right-to-left page.

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. Press Space or Enter to pick it up, then ArrowUp and ArrowDown to change its place, ArrowLeft and ArrowRight to go to the neighbouring column (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. Each step is announced in the status line. The card's "More actions" menu offers a "Move to" choice for every column too, which is the route for a single pointer and for touch.

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

Everything: products, drawn images and moves live in the component's state, nothing is uploaded or published, and a reload or Reset brings back the starting catalog. To save for real, call your API from put, the one function every finished move goes through, and from the Add image handler, then update the cards from the response. The products are made up.

How does it look on a phone?

The columns scroll sideways in one named region with the next column showing, and each column scrolls up and down inside the board's fixed height, so the page never jumps. The "Add image" button stays on the card. Touch drags from the grip only, so the rest of a card still scrolls the board; the menu moves a card with a single tap.