shadcn.io is not affiliated with official shadcn/ui
Date Range Form Block for React
Two date inputs and a month that stay one range: booked nights drawn struck through and named when a block runs over one, an end before the start refused on the end field, and a two-night minimum.
Installation
Overview
Block a run of nights with this date range form for React with Base UI. A compact header sits over a hairline frame with a plus mark on each corner, in two cells. The first holds two Date Inputs, Start and End, and a summary ("5 nights, Fri 6 Nov to Wed 11 Nov"); the second is a month to pick from, drawn as a grid of buttons with a plus mark where it meets the first cell. The inputs and the month are one range: typing a date moves the highlight, and picking two days fills the inputs. Four nights are booked and drawn struck through; a range can't start on one, and one that runs over one says "Includes 14 Nov, which is booked" under the End field. The End is the morning the place opens again, so an End before the Start is refused on the End, and a block is at least two nights. It's built from Date Input, Button, Shine Button and Guides, with a CSS entrance only. For holiday lets, room blocks, leave and any form that takes a start and an end with rules between them.
FAQ
How do I change the booked nights, the minimum and the months?
Edit the constants at the top: BOOKED (ISO days), MIN_NIGHTS, MONTH_IDS (the months the grid can show) and AS_OF (the day the block treats as now, which closes the nights before it). startProblem and endProblem are the rules and return one sentence each; the fields, the summary and the Block dates check all read them, so a new rule is one more line there.
Why is the End a morning and not a night?
A booking is nights, and the last night is the one before the day you leave. So Fri 6 Nov to Wed 11 Nov is five nights (6, 7, 8, 9 and 10), and a booked night on the 11th does not block it. The month names this in words for a screen reader ("first night" on the Start, "the morning it opens again" on the End), and the check that finds a booked night looks at the nights only.
How do the inputs and the month stay in step?
There is one range, kept as two ISO days. The inputs report a date once all three segments are filled; a day picked on the month is written back into them through a small child component inside each input (DateBridge). The first pick starts a range, the second ends it, and picking a day on or before the Start starts again. The month is a grid of buttons and takes the arrow keys, one tab stop, and Enter or Space to pick.
When does it check, and where do the messages go?
When focus leaves the two fields, when you pick on the month and when you press Block dates, which also moves focus to the first field with a problem. A Start problem is under the Start, and everything about the End (before the Start, too short, over a booked night) is under the End, so each message sits next to the field you fix.
What stays local, and how do I connect it for real?
Nothing is blocked: Block dates says "5 nights blocked here only. Nothing was sent." To make it real, send the two ISO days from the submit handler, check the booked nights on your server too, and show its answer in the same status line. Feed BOOKED from your calendar rather than a constant.
How do I connect it to react-hook-form or TanStack Form?
Store the two ISO days as one value. With react-hook-form, use Controller, call field.onChange with the range from the inputs' value handlers and the month's pick handler, and put startProblem and endProblem in a resolver. With TanStack Form, validate the two fields together in a form-level onBlur.
Related
- Pro
Leave Date Input Form
Dates and timesA date field you type or pick: month, day and year segments plus a calendar button, an impossible day named as it is typed, a soft year-end freeze notice, the date read back in words and two quick chips.
- Pro
An analytics page with a date-range dialog shown open: six presets worked out from a fixed day, a calendar for a custom range, start and end fields that check each other, a compare switch and a foot that counts the days.
- Pro
Date Range Calendar Rental Contact
Events and datesAn equipment-hire request in four ruled bands: a tool select with its rates, an inline range calendar with a delivery switch, a band of hairline cells that prices the hire, then name and email.
- Pro
Loose Time Input Form
Dates and timesA pickup time field that accepts what people type, such as 9, 930, 9:30 pm or 21.30, reads it back in a 12 or 24 hour format and names the part of the rule a time breaks.
- Pro
Time Zone Select Form
Dates and timesA grouped select of sixteen time zones with the offset in each label, a real read of the device's own zone after the page loads, and one sentence saying how far the chosen zone is from it.
- Pro
Address Form with ZIP Help
Checkout and addressA six-column address grid that never changes size: street, an apartment line behind a quiet button, city, a state select and a ZIP code that fills the city and state from a typed table of six.