fetaUI
GitHub

Stay Picker

Pick a stay night by night, with prices in the grid. A range cannot cross a booked night.

FreeWeb and MobileMotion

Preview

npx shadcn add @fetaui/stay-picker
Playground
November 2026Nightly price in USD
Pick a check-in night
TotalPick dates
Booked nights
November 2026Nightly price in USD
Pick a check-in night
TotalPick dates
Minimum stay
Maximum stay
Icons animation
Fail next action
Motion

Installation

Terminal· bash
 npx shadcn add @fetaui/stay-picker

Accessibility

  • Each night reads its date, its price or full, and whether it is the check-in or check-out.
  • Booked nights are aria-disabled but stay focusable, and a click on one explains why it is refused.
  • Refusals and totals are announced.

Motion

  • Hover or focus previews a valid range at 4%.
  • A refused pick rings that night in danger and slides a message in.
  • Reserved turns the button secondary with a check and the total green.
  • With reduced motion, these changes are instant.

Responsive behavior

  • 380 px on Web and full width on Mobile.

Performance

  • Prices are computed once per month in a memo, so keep priceFor stable.
  • The grid has one tab stop, and hover only changes one preview value.

Note for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Import StayPicker from @/components/fetaui/stay-picker. It composes Button and IconButton.
  • priceFor returns a number, or null for a booked night. The total is the sum of those prices.
  • Selection is { from, to } with Date or null. Pass value and onChange to control it, or defaultValue to seed it. Clicking the check-in clears the stay, clicking the check-out keeps only the check-in, and Esc clears.
  • minNights and maxNights refuse a check-out outside the range with a message, and Reserve stays disabled for a stay that breaks them.
  • onReserve gets { from, to } and the total. Return a promise to hold Reserve in a loading state: it shows Reserved once it resolves, and failedMessage with the nights kept if it rejects.
  • The demo's prices are generated and nothing is booked. Check availability and the total on your server.

Related