Skip to content
Sign in
CommerceFlight optionsMenu

Flight optionsPro

Flights compared on one clock: layovers and problem connections drawn, fares per flight, hold or book.

ProFour ways from Lisbon to San Francisco on one clock: pick a flight, compare its fares, hold or book.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/flight-options

Usage

tsx
import { FlightOptions } from "@/components/ui/chatcn/pro/flight-options"

<FlightOptions
  title="Lisbon to San Francisco"
  description="Thu 12 Nov, 1 adult"
  options={results}
  currency="EUR"
  holdFor={1440}
  onHold={(sel) => airline.hold(sel)}
  onBook={(sel) => airline.book(sel)}
/>

Every flight is drawn on one shared clock, from the earliest departure to the latest landing: solid where it flies, a hairline where it waits, amber where the wait is a problem (shorter than shortConnection, overnight, or a change of airport, each also said in words). Stacked rows line up, so the early start, the long layover and the next day landing are visible before any number is read. Choosing a flight opens its fares side by side with what each includes, and seats left when few. Sort by best, cheapest or fastest; the cheapest and fastest are labeled. Hold places a timed hold that drains as a thin meter and lapses on its own.

Examples

States

ProHeld with three hours left, an overnight connection with a failed booking, one flight, nothing found, loading and error.

Props

PropTypeNotes
options{ id, carrier, logo?, flights?, from, to, departs, arrives, arrivesDays?, duration, connections?, fares }[]Times as HH:MM, durations in minutes
fares{ id, name, cabin?, price, includes?, excludes?, seatsLeft? }[]Per option
connections{ code, city?, at, layover, overnight?, airportChange? }[]at is minutes after departure
title, descriptionReactNodeHeader
currency, localestringPrices format with Intl, tabular figures. Default USD, en-US
travellersnumberMultiplies the total. Default 1
selection, defaultSelection, onSelectionChange{ option, fare }The pick
sort, defaultSort, onSortChange"best" | "cheapest" | "fastest"Order
shortConnectionnumberMinutes under which a layover is flagged. Default 60
holdFor, onHold, hold, onReleasenumber, (sel) => { until } | Promise<...>, { option, fare, until }Timed holds
onBook(sel) => unknown | Promise<unknown>Reject with an Error to show it
now, loading, error, onRetry, disabledStates
labelsPartial<FlightOptionsLabels>Every string, for translation

Keyboard

KeyAction
TabThe sort, the flights (one stop), the fares (one stop), then Hold and Book
Arrow keysMove between flights or fares (native radios)

Accessibility

  • Flights and fares are radio groups; each flight is named with carrier, times, duration, stops and price.
  • Connection problems are linked with aria-describedby; amber is never the only signal.
  • The clock is decorative; every time is also text in the row.
  • Holds and bookings are status messages; errors are alerts that say what to do.

Motion

Fares and the hold line fade up 4 px in 180 ms. The hold meter drains linearly once a second. Reduced motion keeps the fades and steps the meter.