NotificationPreferences
The notification settings screen. A matrix of kinds by channel (email, push, WhatsApp, desktop), quiet hours, a daily cap with batching, a digest schedule and extra email or webhook destinations with a test send. Every change saves at once and rolls back if it fails.
Code
<NotificationPreferences kinds={[ { id: "mention", label: "Mentions", group: "Activity" }, { id: "security", label: "Security alerts", group: "Account", locked: ["email"] }, ]} value={prefs} onChange={(next) => api.savePrefs(next)} pushPermission={permission} onRequestPush={requestPermission} unavailable={{ whatsapp: "Add a WhatsApp number first" }} destinations={destinations} onAddDestination={({ kind, target }) => api.addDestination(kind, target)} onTestDestination={(d) => api.testDestination(d.id)}/>Account · beta
Live examples and controls: NotificationPreferences in the lab.
Install
npx shadcn@latest add https://docs.nasaqui.com/r/notification-preferences.jsonWhere a person decides what reaches them and how. Each row is a kind of notification, each column a channel; below are quiet hours, a daily limit, a digest and extra destinations. There is no Save button: each change is applied on screen at once and sent to you, and if your save fails the screen goes back to the last saved state.
When to use
- The "Notifications" page of account settings (it fills the section body of
AccountSettings).
When not to use
- Showing the notifications themselves: use
NotificationCenter.
Import
import { NotificationPreferences } from "@fadymondy/nasaq/web";Quick start
<NotificationPreferences
kinds={[
{ id: "mention", label: "Mentions", group: "Activity" },
{ id: "security", label: "Security alerts", group: "Account", locked: ["email"] },
]}
value={prefs}
onChange={(next) => api.savePrefs(next)}
pushPermission={permission}
onRequestPush={requestPermission}
unavailable={{ whatsapp: "Add a WhatsApp number first" }}
destinations={destinations}
onAddDestination={({ kind, target }) => api.addDestination(kind, target)}
onTestDestination={(d) => api.testDestination(d.id)}
/>Anatomy
NotificationPreferences data-slot="notification-preferences"
├─ status "Saving" / "Saved", polite live region
├─ Alert rollback, push blocked
├─ matrix data-slot="notification-matrix": a table, header checkbox per channel
├─ quiet hours switch, from and until (TimePicker), summary
├─ volume daily cap switch and number, delivery (instant, hourly, daily)
├─ digest switch, frequency, day, time, next send
└─ destinations data-slot="notification-destinations": list, test, remove, add formAPI
| Prop | Type | Description |
|---|---|---|
kinds | NotificationKind[] | { id, label, description?, group?, locked? }. locked channels are fixed on. |
channels | NotificationChannel[] | Columns to show. Default all four. |
unavailable | { [channel]: reason } | Locks a column and shows why. |
value | NotificationPrefs | { matrix, quietHours, dailyCap, batching, digest }. |
onChange | (next) => Promise<void | { error? }> | Saves. Saves run one after another; a failure rolls the screen back. |
pushPermission, onRequestPush | Turning push on asks the browser first; a refusal changes nothing. | |
destinations, onAddDestination, onRemoveDestination, onTestDestination | Extra email or webhook destinations. | |
sections | array | Show only some sections. |
labels | NotificationPreferencesLabels | English and Arabic built in. |
Pure helpers: setCell, setChannel, channelState, isQuietNow (windows can cross midnight), nextDigest.
Accessibility
The matrix is a real table with row and column headers; every checkbox is named "kind: channel". Saving state is a polite status. Locked cells say why in a tooltip and are disabled.
RTL & i18n
Built-in English and Arabic. Webhook URLs and emails are left-to-right; the digest date follows the locale.
Styling & tokens
Built on SettingsSection, Checkbox, Switch, Select and TimePicker.
Do / Don't
- Do apply the same rules on the server (locked channels, quiet hours).
- Do not offer a channel you cannot deliver on; pass it in
unavailablewith the reason.
Related
Lab
https://docs.nasaqui.com/?path=/docs/components-account-notification-preferences--docs
ChangePasswordForm
Change-password form with current, new (strength meter) and confirm fields, an option to sign out other sessions, client checks, server field errors and a success message, driven by one async onSubmit.
ProfileCard
A person's account card (avatar, name, role, presence, local time, team, quick actions) that opens from any avatar, name or mention on hover, focus or tap, plus the mention chip and presence dot it is built from.