NotificationList
NotificationList shows the in-app notifications of one part of the app as a snackbar, one notification at a time. It reads them from client.notifications, keeps those tagged for its notification target, and renders each with the Notification key of ComponentsContext. Displaying notifications explains targets, routing and translation, and Publishing notifications the store.
Best practices
- Render a list inside a notification target: an SDK surface, or a
NotificationTargetProviderof your own. Without a target and withoutpanelandhostId, the list shows nothing. - Render one list per target. Two lists for the same target pick the same notification and show it twice.
- Replace the SDK's lists through the
NotificationListkey, and spread the props you receive:MessageListpassesbottomOffsetandfilter. - Keep
filtercheap. It runs for every notification of the target each time the store changes. - Give the list's parent the size of the area it covers. The list is positioned absolutely inside it.
Where the SDK renders it
| Surface | Renders | Target |
|---|---|---|
MessageList and MessageFlashList |
the NotificationList key |
the Channel or Thread around them |
ChannelList |
the NotificationList key |
channel-list, with the list's notificationHostId |
ThreadList |
the NotificationList key |
thread-list, with the list's notificationHostId |
ChannelDetails, its forms and its lists |
NotificationList itself, not the key |
channel-details, one host for the screen and one for each modal |
MessageList passes bottomOffset while the composer floats over the list, so the snackbar stays above it. With pending uploads on, it passes filter={excludeCanceledUploadNotifications}, which hides the upload failures a user causes by removing an attachment while it uploads.
Behavior
The list asks useNotificationListController() for the notification to show:
- A notification without a
duration, such as aloadingone, shows first. Otherwise the newest one shows. - Every other notification for the target is removed from the store. There's no queue.
- The countdown of the shown notification starts when it shows, so one that waits for its list doesn't expire unseen. A notification with actions stays at least 5 seconds.
- The list registers its target as the latest one mounted. A notification published with no target, outside a composer and outside
runWithNotificationTarget, goes to the latest mounted list. See Routing notifications. - When the list unmounts, every notification for its target is removed.
System notifications, the ones with the system tag, never show in a list.
The list renders the Notification key with the notification, onDismiss that removes it, and showClose for a notification without a duration. The notification animates in from enterFrom, or from the direction in its metadata.entryDirection or origin.context.entryDirection, and animates out the same way. A notification of a new type animates in again; one that replaces another of the same type doesn't.
The list is absolutely positioned and centered, 16 points from the edge it's anchored to and from both sides, above the other content of its parent. It has the accessibility label "Notifications", the notifications.list.accessibilityLabel key.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
panel |
NotificationTargetPanel |
The kind of surface the list serves. With hostId, the exact target. Alone, the nearest provider's target if its panel matches, and no target otherwise. |
|
hostId |
string |
The host the list serves. Only used together with panel. |
|
filter |
NotificationListFilter |
(notification) => boolean, applied after the target. A notification it rejects isn't shown, and isn't removed while the list is mounted. |
|
enterFrom |
NotificationListEnterFrom |
'bottom' |
The side notifications animate in from: 'bottom', 'top', 'left' or 'right'. |
verticalAlignment |
NotificationListVerticalAlignment |
'bottom' |
The edge the list is anchored to: 'bottom' or 'top'. |
bottomOffset |
number |
Added to the distance from the bottom edge. Only applies with verticalAlignment="bottom". |
|
topOffset |
number |
Added to the distance from the top edge. Only applies with verticalAlignment="top". |
Without panel and hostId, the list serves the target of the nearest NotificationTargetProvider.
Theming
The theme's notificationList.container styles the list. The offsets apply after it, so a bottom or top in the theme is replaced while an offset is passed. Each notification is styled by the notification key: see Notification components.
Examples
A list for a screen of your own
import { Text, View } from "react-native";
import {
NotificationList,
NotificationTargetProvider,
} from "stream-chat-react-native";
export const SettingsScreen = () => (
<NotificationTargetProvider hostId="settings" panel="settings">
<View style={{ flex: 1 }}>
<Text>Settings</Text>
<NotificationList enterFrom="top" topOffset={8} verticalAlignment="top" />
</View>
</NotificationTargetProvider>
);Notifications published with useNotificationApi() inside the provider, or with target: { panel: "settings", hostId: "settings" } from anywhere, show in this list.
Only errors in the channel list
import type { Notification } from "stream-chat";
import { NotificationList } from "stream-chat-react-native";
import type {
ComponentOverrides,
NotificationListProps,
} from "stream-chat-react-native";
const isError = (notification: Notification) =>
notification.severity === "error";
const ErrorsOnlyList = (props: NotificationListProps) => (
<NotificationList {...props} filter={isError} />
);
// Pass these to a WithComponents around ChannelList only.
export const channelListNotificationOverrides: ComponentOverrides = {
NotificationList: ErrorsOnlyList,
};A WithComponents around ChannelList alone keeps the message lists on the default key, so their filter isn't replaced.
Related
- Notification components:
Notification,NotificationIconandNotificationTargetProvider. - Notification hooks:
useNotificationListController, to render notifications your own way. - Notifications: the feature end to end.