cv/src/app/FocusedElement.tsx

43 lines
1.5 KiB
TypeScript
Raw Normal View History

2023-05-25 04:42:30 +00:00
import { useState, useRef, useEffect } from "react";
const focusUrlParamName = 'focus'
const focusChangedEventName = "focus-changed"
const focusedElementClassName = 'focused-element'
function triggerElementFocused(elementKey: string) {
const url = new URL(window.location.href);
url.searchParams.set(focusUrlParamName, elementKey);
const focusChangeEvent = new Event(focusChangedEventName);
history.pushState({}, "", url);
window.dispatchEvent(focusChangeEvent)
}
export function useFocusedElement(elementKey: string) {
const [isFocusedElement, setFocusedElement] = useState(false);
const focusedClass = isFocusedElement ? focusedElementClassName : ''
const elementRef = useRef<HTMLSpanElement>(null)
function focusElement() {
triggerElementFocused(elementKey)
}
useEffect(() => {
function getFocusedState() {
const params = new URLSearchParams(window.location.search)
const focusedElement = params.get(focusUrlParamName)
const focused: boolean = focusedElement && focusedElement == elementKey || false
setFocusedElement(focused)
}
getFocusedState()
addEventListener(focusChangedEventName, getFocusedState)
return () => {
removeEventListener(focusChangedEventName, getFocusedState)
}
}, [elementKey, setFocusedElement])
isFocusedElement && elementRef.current?.scrollIntoView()
return {isFocusedElement, focusedClass, elementRef, focusElement}
}