Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Convert use-focus-on-blur to TS
Browse files Browse the repository at this point in the history
  • Loading branch information
obulat committed Sep 2, 2022
1 parent 56d8f87 commit a3d3b3c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 63 deletions.
5 changes: 4 additions & 1 deletion src/composables/use-dialog-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import { useFocusOnBlur } from '~/composables/use-focus-on-blur'
* @param {Props} params
*/
export function useDialogContent({ emit, ...props }) {
const focusOnBlur = useFocusOnBlur(props)
const focusOnBlur = useFocusOnBlur({
dialogRef: props.dialogRef,
visibleRef: props.visibleRef,
})
useFocusOnShow(props)
useFocusOnHide(props)
useHideOnClickOutside(props)
Expand Down
62 changes: 0 additions & 62 deletions src/composables/use-focus-on-blur.js

This file was deleted.

48 changes: 48 additions & 0 deletions src/composables/use-focus-on-blur.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Ref, ref, watch } from '@nuxtjs/composition-api'

import { getActiveElement, getDocument } from '~/utils/reakit-utils/dom'

type Props = {
dialogRef: Ref<HTMLElement | null>
visibleRef: Ref<boolean>
}

function isActualElement(
element: EventTarget | Element | null
): element is Element {
if (!element) return false
const elementAsElement = element as Element
return !!(
elementAsElement.tagName &&
elementAsElement.tagName !== 'HTML' &&
elementAsElement !== getDocument(elementAsElement).body
)
}

function useBlurTracker(): [Ref<number>, () => void] {
const blurredRef = ref(0)

const scheduleFocus = () => (blurredRef.value += 1)

return [blurredRef, scheduleFocus]
}

export function useFocusOnBlur({ dialogRef, visibleRef }: Props) {
const [blurredRef, scheduleFocus] = useBlurTracker()

watch([blurredRef], ([blurred]) => {
if (!visibleRef.value) return
if (!blurred) return
if (!isActualElement(getActiveElement(dialogRef.value))) {
dialogRef.value?.focus()
}
})

return (event: FocusEvent) => {
if (visibleRef.value) return
const nextActiveElement = event.relatedTarget
if (!isActualElement(nextActiveElement as Element)) {
scheduleFocus()
}
}
}

0 comments on commit a3d3b3c

Please sign in to comment.