Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Delivery Schedule Checkout Block for React Aria

A delivery step planned backwards from a needed-by date: three typed methods each show the day they arrive, the last day and hour an order can go in and the days to spare, and a method that cannot make the date offers the earliest one.

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 out when to order, not just when it arrives, with this delivery schedule checkout for React with React Aria. A compact header from Rowanleigh, a houseplant shop, sits over a hairline frame with a plus mark on each corner. The first band holds a "Needed by" Native Select of the next fifteen days (Saturday 24 October to begin with) and the fixed "now" the sums start from: Friday 16 October, 09:00 UTC. The second band lists three methods, each with typed rules: which weekdays it arrives on, how many working days it takes, the hour its order must be in by and a fee. For the date you picked, the block counts back from the arrival to the last day an order can be placed and says it plainly ("Order by Tue 20 Oct, 14:00 UTC, 4 days to spare"). A method that cannot make the date says so, names the earliest it can ("The earliest is Wed 21 Oct") and has a button that moves the date there. The selected method follows the date, and the only Shine Button books it. It's built from Field, Native Select, Button, Shine Button and Guides, with a CSS entrance only. For plants, flowers, cakes and anything that has to arrive on a day.

FAQ

How is the last order day worked out?

From the arrival day it steps back one day at a time and counts only working days (Monday to Friday) until it has counted the method's transit days; the day it lands on is the last order day, and the method's cut-off hour (UTC) applies on that day. If the wanted date is not a day the method arrives on, it uses the nearest earlier one that is, and the row says when it actually arrives. The earliest possible date is found by scanning forward from tomorrow with the same function, so the two always agree.

Why is 'now' fixed?

Dates in a block are typed so that it renders the same on the server and in the browser and in every screenshot: AS_OF is 16 October 2026 and the hour is 9. In your shop compute the day from the server's clock in the shop's time zone, keep the cut-off hours in that zone, and pass the day numbers in; the arithmetic helpers take plain day numbers and do not read the clock.

What happens when no method can make the date?

Every row explains itself and offers a button for the earliest date it can do (when that date is in the select), the Shine Button changes to "Choose another date" and is marked unavailable, and pressing it says to pick a later date. Choosing a date that works again selects the cheapest method that works, or keeps your own choice if it still does.

How do I handle holidays and weekends?

Replace isWorking with a check against your calendar: a list of closed dates as ISO strings and the weekday rule. Everything that counts working days goes through that one function. Saturday and Sunday arrivals are already a property of the method (arrive), so a Sunday method is one more entry with arrive: [0].

How do I use it with a keyboard?

The date is a native select, so type a day or use the arrow keys. The methods that work are native radio inputs in one group: Tab to the group and use the arrow keys, and the row for the selected one is shaded. A method that cannot make the date is not in the group, so the arrow keys skip it, and its move button is an ordinary button in the tab order.

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

Everything: the date, the method and the result live in the block's state, and Book only says that nothing was sent or charged. In your app replace METHODS with your carrier's rules, create the delivery with the date and method chosen, and keep the promise you showed (arrival date and order-by time) with the order so support can see what the customer was told.