Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Select Quantity Dialog Block for React

A hardware shop's quantity dialog shown open: a number field with a button on each side over a four-tier price ladder that follows it, a hint to the next tier and totals worked out in whole cents.

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

Let people see what a bigger order saves while they choose it, with this quantity dialog for React with Base UI. It opens from the Fasteners page of Hexbarrow, a zinc hardware supplier: the page's header holds an outline Choose quantity Button, and the shop, a header with a cart chip and six product tiles, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The dialog holds a drawn bolt and the product's name, a Number Input with a minus and a plus button (1 box up to the 120 in stock), and the price ladder: four tiers from $12.00 a box down to $8.40, the one in force ticked and heavier. As the number crosses a break the ticked row moves, a hint says how many more boxes reach the next tier ("Add 1 more box to pay $9.60 each"), and the totals, the price each, the total and what is saved against the single-box price, are worked out in whole cents. Add 24 to cart, the only Shine Button, names the number and puts the boxes on the cart chip behind the dialog. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog, with the same field and the same ladder. For wholesale, hardware, packaging and anything priced in bands.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the shop: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Choose quantity button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same QuantityFields component and share the block's state, so a number typed in the copy is there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

How is the price worked out?

From the TIERS list: each tier starts at a number of boxes and has a price in cents, and the quantity picks the last tier it has reached. Every figure is whole cents, formatted with Intl.NumberFormat, so $259.20 is 25920 and never a rounded float. The ranges ("10 to 24") are written from where the next tier begins, so they cannot disagree with the prices, and the saving is the quantity at the single-box price minus the total. Change TIERS and STOCK and the table, the hint, the totals and the button all follow.

What happens when I type a number that doesn't fit?

Nothing stops you typing, and the figures beside the field already read the nearest valid number. When you leave the field it is held between 1 and the stock and says why, "Held at 120, the boxes in stock", or "Whole boxes only" for a fraction. The minus and plus buttons and the arrow keys move one box, Page Up and Page Down ten, and at either end the button goes quiet but stays focusable and tells you why when pressed. An empty field says "Enter 1 to 120 boxes" and takes focus back when you press Add.

What stays local in the demo, and how do I wire it up?

All of it. The tiers, the stock and the cart count are typed in this file, and Add to cart only changes the chip on the drawn shop and says so in a polite message: nothing is ordered and no stock is held. In your app post the quantity from add, read the stock and the tiers from your catalogue, and re-check both on the server, which should own the price. The number field is controlled through its value, set from the block's text.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus starts in the number field and stays inside until the dialog closes, and Escape, Cancel and the close button return focus to Choose quantity. The ladder is a real table with a caption, the row in force is marked as current and has a ticked cell and an "(your price)" note for screen readers, and the price is read out once typing has rested for a moment, "24 boxes: $10.80 each, $259.20 in all". The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it, Cancel and its close button close it and put focus on the button.

How does it look on a phone?

The copy shown on load docks to the foot of the page as a bottom sheet, with Add to cart pinned under a scrolling body, and the ladder reads the same in the narrower column. The real dialog keeps the Dialog's own phone layout: a sheet stuck to the bottom of the screen. The side buttons and the field keep a touch-sized height.

  • Pro

    Add to Cart Dialog

    Payments and plans

    A stool shop's product page with its add-to-cart dialog shown open: two heights that redraw the stool and move the price, three finishes with a sentence each, a quantity that stops at the stock left, and a total that follows the choices.

  • Pro

    Seats on a team plan: members with a role each (viewers are free), a stepper for the seats you pay for, and the monthly and prorated cost worked out before you save.

  • Pro

    A quantity field that sells in cases of six: typing a number snaps it up to a whole case on leaving, the keys and buttons move one case or five, and the line total is worked out in whole cents.

  • Pro

    Quick Calculator Dialog

    Media and widgets

    A contractor's quote with a calculator dialog shown open: a display with the sum above its result, a four by five keypad, memory keys, a history of the last five sums, working keyboard keys and a Use result button that writes the figure on the quote.

  • Pro

    A homeware shop's shipping dialog shown open: four delivery methods with arrival dates counted in business days from a fixed order date, prices in whole cents, a free-shipping bar and a button that names the choice.

  • Pro

    A design tool's account page with its subscription sheet shown open: the plan, billing cycle and seats editable in place, a next-invoice foot worked out from the controls, and a plan card behind it that changes when you save.