Notifications
Let a signed-in user control which notifications they receive and through which channels.
Channel Matrix
Notification channels
| Notification | Push | SMS | |
|---|---|---|---|
Security alertsNew sign-ins and password changes | |||
Mentions and repliesWhen someone tags you | |||
Billing and receiptsInvoices and payment issues | |||
Product updatesNew features and announcements |
Example result โ your output may vary with your context and the prompt you pass.
# Notifications: Channel Matrix
## Context
Flexnative UI intent โ a reference solution from the shadcn/ui registry (@flx). The intent frames the problem; the decision is one approach to it.
## Problem
Let a signed-in user control which notifications they receive and through which channels.
## Decision
- Best for: The default when each notification type can arrive on more than one channel, like email, push, and SMS. A grid puts type against channel so a user sees and sets every combination on one screen.
- Trade-off: The matrix grows wide fast and reads as dense, so it strains on small screens and overwhelms when there is really only one channel to toggle.
## Registry Item
@flx/notifications-1
## Stack
- UI: shadcn/ui
- Styling: Tailwind CSS
- shadcn components: Card, Switch, Table
## Registry Source
https://ui.flexnative.com/r/notifications-1.json
## Preview
https://ui.flexnative.com/intents/notifications#1
## Reference Implementation
```tsx
'use client'
import { useState } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Switch } from '@/components/ui/switch'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table'
type Channel = 'email' | 'push' | 'sms'
type Row = {
id: string
label: string
hint: string
channels: Record<Channel, boolean>
}
const INITIAL: Row[] = [
{
id: 'security',
label: 'Security alerts',
hint: 'New sign-ins and password changes',
channels: { email: true, push: true, sms: true },
},
{
id: 'mentions',
label: 'Mentions and replies',
hint: 'When someone tags you',
channels: { email: true, push: true, sms: false },
},
{
id: 'billing',
label: 'Billing and receipts',
hint: 'Invoices and payment issues',
channels: { email: true, push: false, sms: false },
},
{
id: 'product',
label: 'Product updates',
hint: 'New features and announcements',
channels: { email: false, push: false, sms: false },
},
]
const CHANNELS: { key: Channel; label: string }[] = [
{ key: 'email', label: 'Email' },
{ key: 'push', label: 'Push' },
{ key: 'sms', label: 'SMS' },
]
export function Notifications1() {
const [rows, setRows] = useState<Row[]>(INITIAL)
const toggle = (id: string, channel: Channel) =>
setRows((prev) =>
prev.map((row) =>
row.id === id
? {
...row,
channels: {
...row.channels,
[channel]: !row.channels[channel],
},
}
: row,
),
)
return (
<Card>
<CardHeader>
<CardTitle>Notification channels</CardTitle>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Notification</TableHead>
{CHANNELS.map((channel) => (
<TableHead key={channel.key} className="text-center">
{channel.label}
</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{rows.map((row) => (
<TableRow key={row.id}>
<TableCell>
<div className="flex flex-col">
<span className="font-medium">{row.label}</span>
<span className="text-muted-foreground text-xs">
{row.hint}
</span>
</div>
</TableCell>
{CHANNELS.map((channel) => (
<TableCell key={channel.key} className="text-center">
<Switch
checked={row.channels[channel.key]}
onCheckedChange={() => toggle(row.id, channel.key)}
aria-label={`${row.label} via ${channel.label}`}
/>
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
)
}
```Paste into your AI tool and adapt it to your context.
Other ways
Reach for these when the context shifts. Each is copyable too.
Notifications
Security
Social
Billing
Grouped Toggles
Email frequency
Activity summaryComments, mentions, and reactions
Team updatesMembers joining and role changes
Product newsFeatures and announcements
Tips and onboardingSuggestions to get more done
Digest Frequency