<arc-notification-panel> Overview
Guidelines
When to use
- Place the trigger button (bell icon, badge) in the trigger slot for consistent click handling
- Use the header slot for a title like "Notifications" and an optional unread count
- Use the footer slot for a "View all notifications" link or "Mark all as read" action
- Set max-height to prevent the panel from exceeding viewport bounds on mobile
- Listen for arc-open to lazy-load or refresh notification data
When not to use
- Use NotificationPanel for generic dropdown menus -- use DropdownMenu or Select instead
- Place complex interactive forms inside the panel -- keep it to a list of actionable items
- Forget to handle the arc-close event if you need to clean up or reset scroll position
- Set position to top-left when the trigger is on the left edge of the screen -- the panel may overflow
- Nest NotificationPanel inside another popover or modal -- stacking contexts will conflict
Features
- Click-triggered popover with automatic outside-click dismissal
- Dedicated header, body (default slot), and footer regions for structured content
- Scrollable body with configurable max-height to prevent viewport overflow
- Position prop (top-right, top-left) for trigger-relative alignment
- Smooth opacity and translateY transition on open and close
- arc-open and arc-close custom events for state synchronization
- Shadow DOM parts (trigger, panel, header, body, footer) for targeted styling
- z-index: 1000 overlay stacking for reliable layering above page content
Preview
Notifications
Deploy succeeded
Production build completed in 42s
Production build completed in 42s
New comment
Alice commented on PR #128
Alice commented on PR #128
Usage
This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.
<arc-notification-panel position="top-right">
<!-- Trigger: bell icon-button with unread badge -->
<div slot="trigger" style="position:relative;display:inline-block;">
<arc-icon-button name="bell" variant="ghost" size="sm" label="Notifications"></arc-icon-button>
<span id="badge" style="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--color-error);pointer-events:none;"></span>
</div>
<div slot="header">
<span>Notifications</span>
<arc-badge variant="primary">3 new</arc-badge>
</div>
<!-- Notification items -->
<div style="display:flex;flex-direction:column;">
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;align-items:flex-start;">
<arc-icon name="check-circle" size="16" style="color:var(--color-success);margin-top:2px;flex-shrink:0;"></arc-icon>
<div>
<div style="font-weight:600;font-size:13px;color:var(--text-primary);">Deploy succeeded</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Production build completed in 42s</div>
<div style="font-size:11px;color:var(--text-tertiary);margin-top:4px;">2 min ago</div>
</div>
</div>
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;align-items:flex-start;">
<arc-icon name="message-circle" size="16" style="color:var(--accent-primary);margin-top:2px;flex-shrink:0;"></arc-icon>
<div>
<div style="font-weight:600;font-size:13px;color:var(--text-primary);">Alice commented on PR #128</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">"Looks good, just one nit on the error handling"</div>
<div style="font-size:11px;color:var(--text-tertiary);margin-top:4px;">18 min ago</div>
</div>
</div>
<div style="padding:12px 16px;display:flex;gap:10px;align-items:flex-start;">
<arc-icon name="alert-triangle" size="16" style="color:var(--color-warning);margin-top:2px;flex-shrink:0;"></arc-icon>
<div>
<div style="font-weight:600;font-size:13px;color:var(--text-primary);">Build warning</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Bundle size increased by 12% in staging</div>
<div style="font-size:11px;color:var(--text-tertiary);margin-top:4px;">1 hour ago</div>
</div>
</div>
</div>
<div slot="footer">
<arc-link href="/notifications">View all notifications</arc-link>
</div>
</arc-notification-panel>
<script>
const panel = document.querySelector('arc-notification-panel');
panel.addEventListener('arc-open', () => console.log('opened'));
panel.addEventListener('arc-close', () => console.log('closed'));
</script> import { NotificationPanel, IconButton, Icon, Badge, Link } from '@arclux/arc-ui-react';
function AppHeader() {
return (
<NotificationPanel position="top-right">
<div slot="trigger" style={{ position: 'relative', display: 'inline-block' }}>
<IconButton name="bell" variant="ghost" size="sm" label="Notifications" />
<span style={{
position: 'absolute', top: 2, right: 2,
width: 8, height: 8, borderRadius: '50%',
background: 'var(--color-error)', pointerEvents: 'none'
}} />
</div>
<div slot="header">
<span>Notifications</span>
<Badge variant="primary">3 new</Badge>
</div>
<div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border-subtle)', display: 'flex', gap: 10 }}>
<Icon name="check-circle" size="16" style={{ color: 'var(--color-success)', flexShrink: 0 }} />
<div>
<div style={{ fontWeight: 600, fontSize: 13 }}>Deploy succeeded</div>
<div style={{ fontSize: 12, color: 'var(--text-tertiary)', marginTop: 2 }}>Production build completed in 42s</div>
</div>
</div>
<div slot="footer">
<Link href="/notifications">View all notifications</Link>
</div>
</NotificationPanel>
);
} <script setup>
import { NotificationPanel, IconButton, Icon, Badge, Link } from '@arclux/arc-ui-vue';
</script>
<template>
<NotificationPanel position="top-right">
<div slot="trigger" style="position:relative;display:inline-block;">
<IconButton name="bell" variant="ghost" size="sm" label="Notifications" />
<span style="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--color-error);pointer-events:none;" />
</div>
<template #header>
<span>Notifications</span>
<Badge variant="primary">3 new</Badge>
</template>
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;">
<Icon name="check-circle" size="16" style="color:var(--color-success)" />
<div>
<div style="font-weight:600;font-size:13px;">Deploy succeeded</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Production build completed in 42s</div>
</div>
</div>
<template #footer>
<Link href="/notifications">View all notifications</Link>
</template>
</NotificationPanel>
</template> <script>
import { NotificationPanel, IconButton, Icon, Badge, Link } from '@arclux/arc-ui-svelte';
</script>
<NotificationPanel position="top-right">
<div slot="trigger" style="position:relative;display:inline-block;">
<IconButton name="bell" variant="ghost" size="sm" label="Notifications" />
<span style="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--color-error);pointer-events:none;" />
</div>
<div slot="header">
<span>Notifications</span>
<Badge variant="primary">3 new</Badge>
</div>
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;">
<Icon name="check-circle" size="16" style="color:var(--color-success)" />
<div>
<div style="font-weight:600;font-size:13px;">Deploy succeeded</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Production build completed in 42s</div>
</div>
</div>
<div slot="footer">
<Link href="/notifications">View all notifications</Link>
</div>
</NotificationPanel> import { Component } from '@angular/core';
import { NotificationPanel, IconButton, Icon, Badge, Link } from '@arclux/arc-ui-angular';
@Component({
imports: [NotificationPanel, IconButton, Icon, Badge, Link],
template: `
<NotificationPanel position="top-right">
<div slot="trigger" style="position:relative;display:inline-block;">
<IconButton name="bell" variant="ghost" size="sm" label="Notifications" />
<span style="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--color-error);pointer-events:none;"></span>
</div>
<div slot="header">
<span>Notifications</span>
<Badge variant="primary">3 new</Badge>
</div>
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;">
<Icon name="check-circle" size="16" style="color:var(--color-success)" />
<div>
<div style="font-weight:600;font-size:13px;">Deploy succeeded</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Production build completed in 42s</div>
</div>
</div>
<div slot="footer">
<Link href="/notifications">View all notifications</Link>
</div>
</NotificationPanel>
`,
})
export class AppHeaderComponent {} import { NotificationPanel, IconButton, Icon, Badge, Link } from '@arclux/arc-ui-solid';
function AppHeader() {
return (
<NotificationPanel position="top-right">
<div slot="trigger" style="position:relative;display:inline-block;">
<IconButton name="bell" variant="ghost" size="sm" label="Notifications" />
<span style="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--color-error);pointer-events:none;" />
</div>
<div slot="header">
<span>Notifications</span>
<Badge variant="primary">3 new</Badge>
</div>
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;">
<Icon name="check-circle" size="16" style="color:var(--color-success)" />
<div>
<div style="font-weight:600;font-size:13px;">Deploy succeeded</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Production build completed in 42s</div>
</div>
</div>
<div slot="footer">
<Link href="/notifications">View all notifications</Link>
</div>
</NotificationPanel>
);
} import { NotificationPanel, IconButton, Icon, Badge, Link } from '@arclux/arc-ui-preact';
function AppHeader() {
return (
<NotificationPanel position="top-right">
<div slot="trigger" style="position:relative;display:inline-block;">
<IconButton name="bell" variant="ghost" size="sm" label="Notifications" />
<span style="position:absolute;top:2px;right:2px;width:8px;height:8px;border-radius:50%;background:var(--color-error);pointer-events:none;" />
</div>
<div slot="header">
<span>Notifications</span>
<Badge variant="primary">3 new</Badge>
</div>
<div style="padding:12px 16px;border-bottom:1px solid var(--border-subtle);display:flex;gap:10px;">
<Icon name="check-circle" size="16" style="color:var(--color-success)" />
<div>
<div style="font-weight:600;font-size:13px;">Deploy succeeded</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:2px;">Production build completed in 42s</div>
</div>
</div>
<div slot="footer">
<Link href="/notifications">View all notifications</Link>
</div>
</NotificationPanel>
);
} API
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Controls whether the notification panel is visible. Toggle this programmatically or let the built-in trigger click handler manage it. |
position | 'top-right' | 'top-left' | 'top-right' | Horizontal alignment of the panel relative to the trigger element. Use top-right when the trigger is near the right edge of the viewport. |
max-height | string | '400px' | Maximum height of the scrollable body area. Prevents long notification lists from overflowing the viewport. |
Events
| Event | Description |
|---|---|
arc-open | Fired when the notification panel opens |
arc-close | Fired when the notification panel closes |
See Also
- Toast Stack-managed notification toasts with auto-dismiss, variant-colored indicators, configurable position, and smooth enter/exit animations.
- Alert Contextual alert banner with four semantic variants and optional dismiss button for delivering timely, prominent feedback to users.
- Badge Compact pill-shaped label for status indicators, category tags, and notification counts. Three color variants let you encode meaning at a glance across dashboards, tables, and card layouts.