···
const usePriority = makePriorityHook();
8
-
export function useDialogDismiss<T extends HTMLElement>(
8
+
export interface DismissableOptions {
12
+
export function useDismissable<T extends HTMLElement>(
10
-
onDismiss: () => void
14
+
onDismiss: () => void,
15
+
options?: DismissableOptions
17
+
const focusLoss = !!(options && options.focusLoss);
const hasPriority = usePriority(ref);
if (!ref.current || !hasPriority) return;
23
+
function onFocusOut(event: FocusEvent) {
24
+
if (event.defaultPrevented) return;
26
+
const { target, relatedTarget } = event;
28
+
contains(ref.current, target) &&
29
+
!contains(ref.current, relatedTarget)
function onKey(event: KeyboardEvent) {
if (!event.isComposing && event.code === 'Escape') {
// The current dialog can be dismissed by pressing escape if it either has focus
···
62
+
if (focusLoss) document.body.addEventListener('focusout', onFocusOut);
document.addEventListener('mousedown', onClick);
document.addEventListener('touchstart', onClick);
document.addEventListener('keydown', onKey);
69
+
if (focusLoss) document.body.removeEventListener('focusout', onFocusOut);
document.removeEventListener('mousedown', onClick);
document.removeEventListener('touchstart', onClick);
document.removeEventListener('keydown', onKey);
53
-
}, [ref, hasPriority, onDismiss]);
75
+
}, [ref, hasPriority, focusLoss, onDismiss]);