refactor(bell): migrate attachClickOutside to use:clickOutside action (#195)

Replace the inline attachClickOutside attachment in NotificationBell with
the shared use:clickOutside action from $lib/actions/clickOutside. The
inline implementation was functionally identical to the existing action.

Guard the onclickoutside handler so it only calls closeDropdown() when
the notification panel is already open, preventing the bell button from
stealing focus from other interactive elements (e.g. the user avatar menu).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-15 12:55:29 +02:00
parent 4446e80875
commit c50845bcfc

View File

@@ -2,6 +2,7 @@
import { onMount, onDestroy } from 'svelte';
import { goto } from '$app/navigation';
import { m } from '$lib/paraglide/messages.js';
import { clickOutside } from '$lib/actions/clickOutside';
import {
type NotificationItem,
relativeTime,
@@ -110,21 +111,6 @@ function attachFirstFocusable(node: HTMLButtonElement) {
};
}
// Attachment: closes dropdown when clicking outside the wrapper element
function attachClickOutside(node: HTMLElement) {
const handleClick = (event: MouseEvent) => {
if (!node.contains(event.target as Node) && !event.defaultPrevented) {
if (open) {
open = false;
}
}
};
document.addEventListener('click', handleClick, true);
return () => {
document.removeEventListener('click', handleClick, true);
};
}
onMount(() => {
fetchUnreadCount();
eventSource = new EventSource('/api/notifications/stream');
@@ -143,7 +129,7 @@ onDestroy(() => {
<svelte:window onkeydown={handleKeydown} />
<div class="relative" {@attach attachClickOutside}>
<div class="relative" use:clickOutside onclickoutside={() => { if (open) closeDropdown(); }}>
<!-- Bell button -->
<button
{@attach attachBellButton}