shadcn.io is not affiliated with official shadcn/ui
Table Reservation Contact Block for React
A restaurant reservation in a card in card: a party size stepper, a date picker that closes Mondays and past days, five sittings as choices and a form that checks itself and confirms in place.
Installation
Overview
A table reservation section for React with Base UI, drawn on a card in card that follows your theme: a tinted shell with + marks on its corners and a raised panel inside it. The panel holds a party size in a number input (1 to 12, with steppers and the arrow keys), a date picker whose calendar closes Mondays and every day that has passed, the evening's five sittings as a row of choices (two carry a "Few tables" badge), a name, a phone number and an optional occasion in a select. Submitting checks every field, shows each problem under its field, marks the control invalid and moves focus to the first one; a valid request turns into a confirmation in the same space, which takes focus and repeats the table, the day, the sitting and the phone number. The rails and top rule come from the Guides spine, so the block lines up with its neighbours in a stack. It's built from Number Input, Date Picker, Segment Group, Select, Field, Input, Badge, Guides, Shine Button and Button, with CSS transitions for the entrances and your theme's tokens for every colour. For restaurants, cafes, bars and any venue that takes bookings by request.
FAQ
Where does the form send its data?
Nowhere yet. The submit handler waits 800 milliseconds, as a stand-in for a request, then shows the confirmation. Replace that timer in submit with a call to your booking system or inbox: details holds the party size, sitting, name, phone and occasion, and day holds the chosen date as a year, month and day. Show the confirmation when the request succeeds, and an error line in the form when it doesn't.
How does the date picker know which days to close?
unavailable closes every Monday (the restaurant's closed day) and, once the page is in the browser, every day before today. Today is read after the block mounts, so the server's render never goes stale and no month or year is written into the file. Change MONDAY to close another day, or add rules such as bank holidays to unavailable. The calendar opens on the current month because the date picker does by default.
Where do the sittings and the Few tables badges come from?
They are fixed example data in SITTINGS: a label, a value and a busy flag that draws the badge. In production, build the list from your table plan for the chosen date and mark a sitting as busy when it is nearly full. The sittings are one group of radio choices, so arrow keys move between them and the chosen one fills with the foreground colour, never the primary colour.
What happens with a party over twelve?
The stepper stops at 12, and typing a larger number is reduced to 12 when the field loses focus. If it's cleared or invalid, submitting shows "Enter how many are coming, from 1 to 12." under it and moves focus there. Larger parties are sent to the phone number beside the button, which is a tel: link with a reserved fictional number.
How is the occasion select labelled?
The label above it names the select's button for screen readers.
The select's trigger takes the id, and the label points to it with htmlFor.
How does it fit on a phone?
The header and the card stack in one column. Party size and date go one per row below sm, the five sittings wrap to two rows (three and two), the name and phone go one per row, and the submit button goes full width, so nothing scrolls sideways at 320 pixels. The calendar opens as a popover over the page and never moves the block's height. The header and the card fade up once on load; with reduced motion they simply appear.
Related
- Pro
Stylist Booking Contact
Visits and servicesA salon booking that starts with the person: three stylists in hairline cells, each with their next three openings as chips, a live appointment line, and a form that checks itself and confirms in place.
- Pro
Month Calendar Scheduler Contact
Calls and meetingsA scheduling split: a host panel at the start; a month calendar that closes weekends and past days, the open times of the chosen day and a name and email at the end, with Confirm unavailable until a day and time are chosen.
- Pro
Request a Callback Contact
Calls and meetingsA callback request with a status band and a form that asks when to ring: as soon as possible, later today from a select of 15-minute times, or on a chosen day, with a time zone.
- Pro
Centered Email Capture CTA
Forms and captureA call to action between solid rails that follows the page theme, in a card in card with a two-step email capture: an email field and a Shine Button, then a six-digit code that verifies on the sixth digit and turns into a confirmation in the same space.
- Pro
Talk to Sales Contact
Contact formsA talk-to-sales split for a scheduling platform: what happens next as three numbered steps and a band of contact details beside a form that checks itself, shows each problem under its field and confirms in place.
- Pro
Guest Count Ruler Contact
Events and datesAn event-catering request for a caterer: a guest-count slider drawn as a ruler beside the cost per head and the total, then a three-course menu, dietary needs and a short form on ruled bands.