shadcn.io is an independent project built on shadcn/ui
Installation
Overview
Sell a set that can be trimmed with this bundle product card for React with React Aria. A hairline grid holds five drawn greyscale desk pieces, each a whole-tile tick box showing its bundle price and its usual price struck through, and a sixth cell that sums them up. The summary draws a bar: each ticked piece's bundle price is a segment, the saving is a hatched tail, and all five pieces' usual prices set the scale, so unticking a piece makes the bar and the price shrink in proportion with no step. A badge and one line say what you save, and the single Shine Button "Add the bundle" turns into "Added" with an Undo. Guides mark each tile's corners. For bundles where every piece has its own price.
FAQ
How is the bundle price worked out?
Each piece's bundle price is its usual price less OFF percent, in integer cents (bundleOf). The bundle is the sum of the ticked pieces, so the saving is exactly the difference between the two sums and the bar's segments add up to the price shown. Change OFF or a piece's listCents and everything follows.
Why can't I untick below two pieces?
A bundle of one piece is not a bundle. The third untick is refused in the status line ("A bundle needs at least 2 pieces") and the tile stays ticked. Change LEAST to allow other sizes.
How does the bar work?
Every segment is a flex child whose width is a share of all five pieces' usual prices, set through one CSS variable from a small helper. Unticked pieces collapse; the hatched tail is the saving. The bar is decorative, so the same numbers are given in text beside it.
What stays local, and how do I wire it for real?
The ticked pieces and the bag are page state. Nothing is stored, charged or sent. Replace the body of add and undo with calls to your cart, send the ticked ids, and have your server price the bundle again.





