Shipping Methods
Delivery options for checkout and delivery dates for product pages. Handles order cutoffs, store pickup and rates that change with the address.
ShippingMethods is the delivery step of a checkout. Each option is a radio card that leads with the date it arrives, “Mon, Oct 26 – Wed, Oct 28” or “Tomorrow”, then the method and carrier, with the price on the right. Shoppers compare dates more easily than “3–5 business days”, so the block works out real dates from business days, skipping weekends and any holidays you pass.
A rate can have an order cutoff. Before it, the card says “Order within 3 h 12 min for delivery tomorrow”, updated once a minute and never ticking seconds. When the cutoff passes, the estimate moves to the next business day on its own. The fastest paid option gets a small badge, and the cheapest one does too when it isn’t already free.
Pickup options sit behind a Ship / Pick up switch that only appears when both exist. A pickup card shows when the order is ready, “Ready today after 2 PM”, with the store name, distance and address. Switching back remembers the shipping option you had.
The block owns the hard states: skeleton cards the same shape as the real ones while rates load, an empty state with Change address when nothing ships there, an inline error with Retry, and rates that change after an address change. If the chosen option is still offered it stays selected; if not, the cheapest one is picked and the block says “Express isn’t available for this address”. DeliveryEstimate brings the same dates to a product page, with a ZIP code popover and a returns line.
HextaUI Pro holen
Eine einmalige Zahlung schaltet jeden Block frei, auch künftige. Preise ansehen.
Die Pro-Registry zu components.json hinzufügen
components.json Token hinzufügen
Erstelle auf deiner Kontoseite einen Token und trage ihn in
.env.localalsHEXTAUI_PRO_TOKENein.Den Block hinzufügen
pnpm dlx shadcn@latest add @hextaui-pro/shipping-methods
Shopify delivery groups
Map a cart’s deliveryGroups to rates and save the choice with cartSelectedDeliveryOptionsUpdate. Pickup and local options keep their own kind, so the Ship / Pick up switch appears on its own.
Shippo and EasyPost rates
Carrier APIs return transit days or a delivery date. Pass them through and the block turns them into real dates, skipping weekends and the holidays you list.
Stripe shipping rates
Stripe shipping rates carry a price in minor units and a delivery estimate in business days, hours or weeks. Convert them once and let the block show dates instead of speeds.
Aufbau
Die Teile, die du zusammensetzt, von außen nach innen.
| Part | Beschreibung |
|---|---|
ShippingMethods | The delivery options as radio cards, with the Ship / Pick up switch and every loading, empty and error state. |
DeliveryEstimate | A product page line, “Free delivery Mon, Oct 26 – Wed, Oct 28 to 94110”, with a Change popover and a returns line. |
businessDaysFrom, formatDeliveryRange | Pure date helpers: add business days skipping weekends and holidays, and format a date range with Today and Tomorrow. |
resolveDelivery, rateBadges | Turn a rate into dates for a given time, including cutoffs, and work out the fastest and cheapest badges. |
ShippingMethods
Also takes div props.
| Prop | Typ | Standard |
|---|---|---|
ratesThe options for the current address. | ShippingRate[] | – |
valueThe selected rate id. Leave undefined for uncontrolled. | string | null | – |
defaultValueThe first selection when uncontrolled. Without one, the cheapest option is picked. | string | null | – |
onValueChangeCalled when the shopper picks an option, and when the block replaces one that’s no longer offered. | (id: string, rate: ShippingRate) => void | – |
statusLoading shows skeleton cards; error shows the error message with Retry. | "idle" | "loading" | "error" | "idle" |
errorA specific error message instead of the default. | string | – |
onRetryShows Retry in the error state. A returned promise shows a spinner on the button. | () => unknown | – |
onChangeAddressShows Change address when there are no options. | () => void | – |
nowPins the current time, for tests and previews. Without it the block reads the clock after mount and once a minute. | Date | number | – |
calendarDays nothing ships or arrives on. | { closedWeekdays?: number[]; holidays?: string[] } | Saturday and Sunday |
cutoffWindowShow the cutoff line only when it’s this many minutes away or fewer. | number | 1440 |
localeLocale for dates and prices. | Intl.LocalesArgument | "en-US" |
trailingZerosShow $18.00 instead of $18. | boolean | false |
labelsEvery visible and announced string, including the cutoff and ready sentences. | Partial<ShippingMethodsLabels> | – |
| Prop | Typ | Standard |
|---|---|---|
idA stable id, such as the carrier rate id or Shopify handle. | string | – |
titleThe method, like Standard or Express. | string | – |
carrierThe carrier and service, like UPS 2nd Day Air. | string | – |
priceThe price. Zero shows Free. | Money | – |
compareAtPriceThe usual price, struck through, when shipping is discounted. | Money | null | – |
deliveryDelivery dates as YYYY-MM-DD, or business days counted from the ship day. | { from: string; to?: string } | { businessDays: [min, max] } | – |
cutoffISO time of the order cutoff for this estimate. After it, the estimate moves one business day. | string | – |
kindPickup rates go behind the Pick up switch. | "ship" | "pickup" | "local" | – |
pickupStore details for pickup. readyBy is an ISO time. | { name; address; distance?; readyBy? } | – |
noteA short extra line, like how long pickups are held. | string | – |
DeliveryEstimate
Also takes div props.
| Prop | Typ | Standard |
|---|---|---|
defaultPostalCodeThe ZIP code the estimate is for. | string | null | – |
defaultEstimateThe estimate for that ZIP code. | { delivery; price?; cutoff? } | – |
onEstimateLooks up a new ZIP code. Return null when you don’t deliver there; throw to show your message. | (postalCode: string) => Promise<DeliveryEstimateValue | null> | – |
onPostalCodeChangeCalled after a successful lookup, to remember the ZIP code. | (postalCode, estimate) => void | – |
validatePostalCodeReturns an error message or null. Defaults to US ZIP codes. | (value: string) => string | null | – |
returnsThe returns line. null hides it. | ReactNode | null | "Free 30-day returns" |
now, calendar, locale, labelsSame as ShippingMethods. | See ShippingMethods | – |
| Taste | Aktion |
|---|---|
| Tab | Moves to the Ship / Pick up switch, then to the selected option. |
| ArrowDownArrowUp | Moves between options and selects them. |
| ArrowLeftArrowRight | Switches between Ship and Pick up. |
| Enter | Submits the ZIP code in the delivery estimate popover. |
| Escape | Closes the ZIP code popover and returns focus to Change. |
- Options are a real radio group. Each card reads its date first, “Arrives Mon, Oct 26 to Wed, Oct 28”, then the method, carrier and price.
- A polite live region announces new options after an address change, and why an option was replaced. Errors use role="alert". The cutoff line updates once a minute and is not announced, so screen readers aren’t interrupted.
- After Retry, focus moves to the selected option once rates load.
- Selection shows a ring, a filled radio and a tinted card, not color alone. Loading and date changes fade in, and nothing moves with reduced motion.
Gebaut mit
Die kostenlosen HextaUI-Komponenten, aus denen Shipping Methods besteht. Jede lässt sich einzeln installieren.
Code
7 Dateien, hinzugefügt zu components/blocks/shipping-methods.