shadcn.io is not affiliated with official shadcn/ui
Notification Permission Dialog Block for React
An uptime monitor's status page with a dialog shown open that asks before the browser does: three switches with an example each, a live preview of drawn notification cards, a not-now path and a Don't ask again box, and no browser prompt.
Installation
Overview
Ask what to send before the browser asks whether it may, with this dialog for React with Base UI. It opens from the Status page of Beaconfold, an uptime monitor: the page's header holds an outline Notifications Button, and the page itself, a header with a bell and five service rows with a state word, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog has a bell tile, the title Turn on notifications? and three Switches, Mentions, Deploy failures and Weekly summary, each with a line of what it would send. Under them a live preview draws a small notification card for every switch that is on and a dashed empty place for every one that is off, in three columns, with the count, 2 of 3 on. The only Shine Button turns notifications on, a ghost Not now leaves it for later, and a Checkbox beside it, Don't ask again, says not to ask again. On a phone the button's words shorten to Turn on, and its name stays whole. Pressing the button does not ask your browser for anything: the dialog says it is on in this demo and your browser would ask next, and the drawn bell gets a dot. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog.
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, and the page around the preview keeps working. The Notifications 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 AskFields component and share the block's state, so what you switched on in the copy is there 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.
Does it ask my browser for permission?
No, and it never does. Nothing here calls Notification.requestPermission, the Permissions API or any other way of asking. The one thing the block reads, once after the page has loaded and only to show it, is what Notification.permission already holds, and it says so under the result: "Your browser's own setting is still: default." In your app call Notification.requestPermission() from the Turn on button's handler, after this explanation, and only then.
What is the preview of cards?
A way to show what saying yes means. Each switch has a drawn card with a title bar and a body line, no real brand and no text, and the card appears when its switch is on and fades to a dashed empty place when it is off. The cards keep their places, so the dialog never changes height, and the count above them says how many are on. They are a drawing, not real notifications.
What do Not now and Don't ask again do?
Not now closes the dialog and the drawn bell shows a quiet Off chip; with the box ticked a polite message adds that the bell is how to turn it on later. Nothing is stored: in your app save the answer, and the time of the last ask, where the next visit can read them, and show this dialog again only when the user opens it or after a good while.
What stays local in the demo, and how do I wire it up?
All of it. The three kinds, their examples and the preview are typed here, and Turn on notifications changes only the block's state. In your app save the chosen kinds with the user's other settings, then request the browser permission and register for push; with no switch on the button is quiet and says to pick a kind first rather than asking for nothing.
Is it accessible from the keyboard?
Yes. The real dialog is named Turn on notifications?, focus starts inside and stays there until it closes, and Escape and the close button return focus to the header button. Each switch is named for its kind and moves with Space, and pressing the quiet button with nothing on names what is missing and moves focus to the first switch. 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 the button.
Related
- Pro
Permission Request Notification
Asks and consentA travel journal's permission list: camera, location and microphone, each with what it is for, a state badge, a segmented Allow, Allow once or Deny, a line on what the choice means, Allow all requested and Reset.
- Pro
Push Permission Prompt Notification
Asks and consentA news app's push permission ask drawn in a browser window: a soft card on the page, a drawn browser prompt with Allow and Block, and the three outcomes, with a line that says nothing is asked of your real browser.
- 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
Do Not Disturb Notification
Quiet and digestsA focus app's do-not-disturb panel: a status card that says in a sentence what the settings amount to, a 24-hour strip of the muted hours, one hour, until tomorrow or a nightly schedule, and the calls that still get through.
- Pro
Mobile Push Settings
NotificationsA push settings panel that leads with a 24-hour strip of quiet hours, a critical-alerts switch, and per-device Push, Sound and Badge toggles with a save bar that counts unsaved changes.
- Pro
A team chat inbox with a settings dialog shown open: a real table of notification kinds by channel with a switch in every cell, mixed-state column masters, reset and save, and a chip on the inbox that reports the saved count.