shadcn.io is not affiliated with official shadcn/ui
Cookie Settings Dialog Block for React
A newspaper's cookie preference centre shown open over its front page: four categories with switches and counts, Essential locked on, and for the chosen one a sentence and a table of its actual cookies, then Reject non-essential, Accept all and Save choices.
Installation
Overview
Let readers see what each cookie is before they decide, with this preference centre for React with Base UI. It opens from the front page of the Quillbrook Gazette, an independent newspaper: the header holds an outline Cookie settings Button, and the page itself is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, a masthead over three columns and a foot that says what was saved. The Dialog is two panes. At the start four categories each have a Switch and the number of cookies in them, with Essential locked on and marked with a lock. At the end the chosen category shows what it is for in a sentence and a table of its actual cookies: the name, who sets it, how long it lasts and what it does. Reject non-essential and Accept all answer in one press and Save choices, the only Shine Button, keeps the switches as they are; each writes what was saved on the page's foot and closes. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog, with the same switches and the same detail. For news sites, shops and any page whose law or policy asks for consent by category.
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 front page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Cookie settings button in the header 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 CookieFields component and share the block's state, so a switch flipped in the copy is flipped in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
Where do the cookies in the table come from?
CATEGORIES holds each category's switchable state, its sentence and its cookies, each with a name, who sets it, how long it lasts and what it does. Fill it from the cookies your site really sets, found by scanning it, so the table is true; a table that hides a cookie is worse than none. The counts under the category names come from the same lists, so they never disagree with the table.
Why is Essential locked, and how is it read out?
Cookies that keep the site working, such as the session and the saved choice itself, need no consent and can't be refused without breaking it, so their switch is on and disabled, with a lock beside it, and named "Essential cookies, always on". Everything else starts off: nothing optional is on until a reader switches it on or chooses Accept all.
What do the buttons do, and how do I wire them up?
Here each one saves in local state, writes "Saved: Analytics on, Marketing off" on the drawn page's foot, closes the dialog and says so in a polite status message that nothing was stored. Closing without saving drops the switches back to what was last saved. In your app write the choice to your consent store in commit, set or clear the cookies and scripts of each category from it, and keep the table in step with what you set.
Is it accessible from the keyboard?
Yes. The real dialog is named by its title and described by its sentence, focus stays inside until it closes, and Escape, the close button and the three buttons all return focus to Cookie settings. A category is a button that marks itself as current and shows its detail, and its switch is a separate control with its own name, so selecting and switching never get mixed up. The table has a caption, column headers and the cookie name as its row header, and it takes focus as a region when it scrolls sideways. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on Cookie settings.
How does it look on a phone?
The copy shown on load docks to the foot of the page as a bottom sheet, its actions pinned at the bottom with Save choices on top, and the two panes stack: the categories first, then the detail of the chosen one, scrolling above the actions. The detail panels share one place, so the sheet doesn't change height when another category is chosen. The real dialog keeps the Dialog's own phone layout, a sheet stuck to the bottom of the screen.
Related
- Pro
Cookie Consent Dialog
Drawers and popoversA recipe blog's first-visit cookie card shown open over its page: two sentences, then Reject all and Accept all as two equal outline buttons side by side, with no primary. It isn't modal, so the page stays readable, and the choice is written on the page's foot.
- Pro
Cookie Consent Footer
PreferencesA footer for a writing app whose legal row opens a cookie settings dialog with a switch per category and shows what was saved.
- Pro
The cookies on a person's own browser as a table of eleven typed cookies with name, provider, purpose and dates, four category switches that clear what they cover, a search and a delete that asks first.
- Pro
Cookie Consent Settings
Privacy and consentA cookie preferences page with four purpose cells on shared hairlines: necessary locked on in words, three switches, and under each the exact cookies it covers, kept for how long, set or blocked.
- Pro
A time tracker's Today page with a preferences sheet shown open where each setting shows its effect: a theme choice over a preview card, a text size and a reduce-motion switch acting on a sample, a default view and two behaviour switches.
- Pro
Confirm Action Dialog
Confirm and consentA newsletter editor with its publish confirmation shown open: an alert dialog that lists what happens to the issue, a box that remembers the answer, and a foot that gives the question back.