-
Notifications
You must be signed in to change notification settings - Fork 252
/
Copy pathfocus.ts
33 lines (26 loc) · 1016 Bytes
/
focus.ts
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
import {findClosest, getActiveElement, isFocusable} from '../utils'
import {updateSelectionOnFocus} from './selection'
import {wrapEvent} from './wrapEvent'
// Browsers do not dispatch FocusEvent if the document does not have focus.
// TODO: simulate FocusEvent in browsers
/**
* Focus closest focusable element.
*/
export function focusElement(element: Element) {
const target = findClosest(element, isFocusable)
const activeElement = getActiveElement(element.ownerDocument)
if ((target ?? element.ownerDocument.body) === activeElement) {
return
} else if (target) {
wrapEvent(() => target.focus(), element)
} else {
wrapEvent(() => (activeElement as HTMLElement | null)?.blur(), element)
}
updateSelectionOnFocus(target ?? element.ownerDocument.body)
}
export function blurElement(element: Element) {
if (!isFocusable(element)) return
const wasActive = getActiveElement(element.ownerDocument) === element
if (!wasActive) return
wrapEvent(() => element.blur(), element)
}