File size: 1,292 Bytes
fbef5e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import type { Attachment } from "svelte/attachments";

export function clickOutside(callback: () => void): Attachment {
	return node => {
		function handleClick(event: MouseEvent) {
			if (window.getSelection()?.toString()) {
				// Don't close if text is selected
				return;
			}

			// For dialog elements, check if click was on the backdrop
			if (node instanceof HTMLDialogElement) {
				const rect = node.getBoundingClientRect();
				const isInDialog =
					event.clientX >= rect.left &&
					event.clientX <= rect.right &&
					event.clientY >= rect.top &&
					event.clientY <= rect.bottom;

				if (!isInDialog) {
					callback();
					return;
				}
			}

			// For non-dialog elements, use the standard contains check
			if (!node.contains(event.target as Node) && !event.defaultPrevented) {
				callback();
			}
		}

		// For dialogs, listen on the element itself
		if (node instanceof HTMLDialogElement) {
			node.addEventListener("click", handleClick);
		} else {
			// For other elements, listen on the document
			document.addEventListener("click", handleClick, true);
		}

		return () => {
			if (node instanceof HTMLDialogElement) {
				node.removeEventListener("click", handleClick);
			} else {
				document.removeEventListener("click", handleClick, true);
			}
		};
	};
}