Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Terms Consent Login Block for React

A full-height agreements screen for a tenant app: a select-all checkbox that turns mixed over the two required agreements, an optional product-updates box that is never pre-ticked, and a Continue button that names what is missing instead of being disabled.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Ask people to accept your terms without a dead button, with this consent login block for React with Base UI. It's the step after sign-in of Leasebird, a tenant app: the page's side rails run its full height, and one band crosses the screen between two rules with a plus mark where each meets a rail. The product's mark sits over the heading and the signed-in address, then one bordered group of hairline cells holds the agreements. The first cell is a select-all Checkbox that is ticked when both required agreements are, mixed when one is, and clear when neither is, with its count beside it ("1 of 2 required accepted"). Under it are the Terms of use and the Privacy notice, each with what it covers, its version and its day, and a link to read it, then product updates, which are optional, never pre-ticked and not part of select-all. The Shine Button continues and is never disabled: pressed with a required box unticked it marks that box, names what is missing under the group and moves focus to the first one. A good press shows a spinner for a moment, then puts what was accepted in the form's own space and moves focus to it, with a way to start over. It's built from Checkbox, Button, Shine Button and Guides, with CSS entrances only. For any app that needs a recorded acceptance at the door.

FAQ

What is recorded when I press Continue, and how do I wire it for real?

Nothing. Continue waits under a spinner for less than a second, then shows which versions were accepted, the fixed day the demo uses and whether product updates were chosen, and a polite status message says nothing was recorded. Start over clears every box. For real, post the ticked agreements from the submit handler where the code says so: the user, each agreement's id and version, the time and where it was accepted, stored where you can show it later, and only then open the app. Keep the busy state until the server answers and show its error under the group if it refuses.

Why is Continue never disabled?

A disabled button can't say why, and keyboard users can't reach it to find out. Here it stays enabled: pressed with the Terms or the Privacy notice unticked, it marks those cells, writes one sentence under the group that names them and moves focus to the first, so a screen reader hears what to do. Ticking a box clears its mark as you go, and the line under the group always has its space, so nothing moves.

How does the select-all box work, and why doesn't it include product updates?

It reads the two required boxes: clear when neither is ticked, mixed when one is, ticked when both are, and pressing it ticks or clears both. Product updates stay outside it because one box should not buy consent to two different things, and an optional agreement should be a choice made on its own: it is never pre-ticked and never required. The mixed state is the indeterminate prop beside checked.

Why do the agreements show a version and a day?

Because what a person accepted is a particular text. The version and its effective day are typed in AGREEMENTS, so when you publish version 8 you change two values and everyone who accepted version 7 is asked again. Keep the number you show in the same record you store, so you can prove which words were accepted.

Is it usable with a keyboard and a screen reader?

Yes. Tab runs through select-all, each agreement's box, the Read links, Continue and the quiet link. A press on any part of a cell ticks its box, and Space does the same from the keyboard. Each box is named by its title and described by what it covers and its version, and a marked one is also described by the group's problem line. After Continue, focus moves to the result's heading and a polite status message says what was accepted, so the outcome is heard.

How does it look on a phone?

The band keeps its rails and the group fills the width of the screen, so every box has a large target. Continue ends on the first screen, the cells' text wraps, and the result replaces the group without the page changing height.

  • Pro

    Privacy Notice Login

    Split with a panel

    A split sign-in page for a patient portal: a Why we ask button under each field opens one sentence on why it is needed, a data list says what the portal keeps, and a required privacy box names itself when it is left unticked.

  • Pro

    Cookie Consent Login

    Sign-up and consent

    A bakery subscription's cookie choices shown open over a drawn sign-in page: Essential locked on, Analytics and Marketing switches that start off, and three equal buttons, Reject all, Accept all and Save choices.

  • Pro

    A 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

    A full-height sign-in page for a team chat app: the product's mark, Google and GitHub rows with lettermark tiles, an or rule, email and password checked on submit, and one Sign in button with a simulated wait and its result.

  • Pro

    OAuth Consent Login

    Sign-up and consent

    A consent screen for a calendar when a scheduling app asks for access: two required permissions shown locked, two optional ones you can untick, a button that counts what it grants and a scope details disclosure.

  • Pro

    Account Locked Login

    Recovery and reset

    A locked-account page for a point-of-sale system that draws the lockout ladder, marks the rung the account is on with a fixed unlock time, and offers an unlock link by email or a password reset.