A slide-over drawer component that displays unread notifications with infinite scroll, toggle controls for popup/desktop notifications, and a history navigation button. It renders either within an `AppLayout` panel or falls back to a full viewport `Drawer` depending on the host context. ## Key Components - **`NotificationDrawer`** — Primary export. Reads state from `useOptionalNotifications()` context and renders within `AppLayoutDrawer` or fallback `Drawer` based on layout context detection. - **`DrawerScrollList`** — Scrollable notification list with `IntersectionObserver`-based infinite scroll; renders `NotificationTile` items or custom tiles via `renderTile`. - **`DrawerLoadingTiles`** — Animated skeleton placeholders shown during paginated load. - **`EmptyState`** — Displayed when there are no unread notifications. - **`ShowNotificationsToggleRow`** — Switch to toggle in-app popup notifications. - **`DesktopNotificationsToggleRow`** — Switch to enable browser push notifications; requests permission on enable, disables itself if permission is denied, and hides on unsupported platforms (SSR, iOS Safari). - **`NotificationsHistoryButton`** — `SplitButton` that navigates to notification history inline or opens it in a new tab. ## Usage Example ```typescript // Wrap your app with NotificationsProvider, then render the drawer: import { NotificationDrawer } from './notification-drawer' function AppShell() { return ( ( )} /> ) } ``` | Prop | Type | Default | Description | |---|---|---|---| | `liveDurationMs` | `number` | — | Auto-dismiss duration for live tiles | | `loadMoreRootMargin` | `string` | `"200px"` | IntersectionObserver root margin for pagination trigger | | `renderTile` | `RenderNotificationTile` | ctx default | Custom tile renderer; falls back to `NotificationTile` | | `className` | `string` | — | Additional classes on the drawer panel |