shadcn.io is not affiliated with official shadcn/ui
Age-Aware Sign-Up Dialog Block for React
A recipe community page with its sign-up dialog shown open: a rail of promises, name, email, password and date of birth fields, the terms, and a button that changes with the age worked out from the date.
Installation
Overview
Open the door to your community and check the age on the way in, with this sign-up dialog for React with Base UI. It opens from the community page of Spoonlane, a recipe-sharing community: the page's header holds an outline Join Button, and the page is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The dialog is a split: at the start a plain rail of three promises (save recipes, follow cooks, free for ever), hidden on phones, and at the end the form, with name and email Inputs and a Password Input beside a Date Input in month, day and year segments, each in a Field that names its problem under itself, and a required Checkbox for the terms. The age is worked out against a fixed date: 16 and over join with Create account, the only Shine Button; 13 to 15 are asked for a parent's email, which unfolds in place, and the button reads Ask my parent; under 13 the button stays off and the line under the date says why. For preview the dialog is drawn open in place when the page loads; the Join button opens the real Dialog. For communities, marketplaces and any product with young members.
FAQ
Why is the dialog already open, and what do I keep?
So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused. The Join button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same RegisterFields component and share the block's state, so what you typed in the copy is there in the real one, except the date segments, which keep their own value and start empty. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
How is the age decided?
From the date, against AS_OF, a fixed day written once at the top of the file, so the demo reads the same whenever it is opened. MIN_AGE (13) and ADULT_AGE (16) are constants too, because the ages that matter differ between countries and products. A date in the future asks for a real one. Under 13 the Create account button is off and the line under the date says "You need to be 13 to join". In your app work the age out on the server from its own clock, and treat the browser's answer as a convenience.
What happens for a 13 to 15 year old?
The line under the date says "We'll ask them to say yes before your account opens", a field for a parent or guardian's email unfolds, and the button reads Ask my parent. Here the account then waits and the header says so; nothing is sent. In your app send the parent a link to confirm, keep the account pending until they do, and let the young person know where it stands.
What stays local, and how do I wire it for real?
No account is created and no email goes out. A finished form only sets a local result: the header's Join button becomes the new member's name with their initials, or "Waiting for a parent" for the younger path, with a Start over button to try another date. In your app post the fields in join, show the server's reasons under the matching fields, and keep the dialog open on a refusal.
Why is the date of birth typed, not picked?
Because people know it by heart and a calendar would make them page back decades. The Date Input is segments: type the digits, and Tab moves between month, day and year. It is the same part on every target, with no popup, so nothing floats over the dialog.
Is it accessible from the keyboard?
Yes. The real dialog is named by its title and described by its sentence, focus starts in the name field and stays inside until it closes, and Escape, Cancel and the close button all return focus to the Join button. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. Each problem takes focus in turn, and a polite status message reports the age line and each result. On a phone the rail is gone and the form becomes one column in a bottom sheet.
Related
- Pro
Sign-In Gate Dialog
Account and securityA paid newsletter page with its sign-in dialog shown open: email and password with a show and hide button, a remember box, a reset link, two provider rows, and a page that lifts its blur once you are in.
- @Pro
Create Account Handle Check Login
Sign-up and consentA sign-up page for a community forum in two columns of fields: a handle with an at sign that checks itself against a typed taken list and offers three tries as buttons, then the email, a password with an eight-character hint and Create account.
- Pro
Email Verification Dialog
Account and securityA newsletter tool's profile page with its email verification shown open: a six-slot code that checks itself when full, three tries, a resend held for 30 seconds by a timer, a way to use a different address, and a success state.
- Pro
Terms Accept Dialog
Confirm and consentA marketplace sign-up at its last step with the terms shown open: an alert dialog with six sections in a focusable scroll region, a reading bar, and a checkbox that stays off until the end has been reached.
- Pro
Change Password Dialog
Account and securityA password manager's account page with its change-password dialog shown open: three password fields, a live checklist of five rules with a strength meter, a match line, and an Update button that stays quiet until every rule passes.
- Pro
Add Profile Dialog
Account and securityA newsletter's writers page with its byline composer shown open: a name, what they write, a 120 character bio, a mark from six drawn glyphs or initials and a switch, beside a card that shows the byline as it will print.