diff --git a/src/app/components/TagCloud.tsx b/src/app/components/TagCloud.tsx index 9b05ca1..7dd455d 100644 --- a/src/app/components/TagCloud.tsx +++ b/src/app/components/TagCloud.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import Container from 'react-bootstrap/Container'; export type Props = { @@ -8,9 +8,48 @@ export type Props = { style?: 'primary' | 'light' } +const focusChangedEventName = "focus-changed" + +function useFocusedElement(elementKey: string) { + const [isFocusedElement, setFocusedElement] = useState(false); + const focusedClass = isFocusedElement ? 'focused-element' : '' + const elementRef = useRef(null) + + useEffect(() => { + function getFocusedState() { + const params = new URLSearchParams(window.location.search) + const focusedElement = params.get('focus') + 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} +} + +function setFocusedElement(elementKey: string) { + const url = new URL(window.location.href); + url.searchParams.set('focus', elementKey); + const focusChangeEvent = new Event(focusChangedEventName); + history.pushState({}, "", url); + window.dispatchEvent(focusChangeEvent) +} + function Tag(props: {text: string}) { + const tagKey = 'tag_' + props.text; + const {focusedClass, elementRef} = useFocusedElement(tagKey) return ( - {props.text} + setFocusedElement(tagKey)} + className={`badge text-bg-light ${focusedClass}`}>{props.text} ) } diff --git a/src/app/globals.css b/src/app/globals.css index a5e9c46..4070cef 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -28,4 +28,7 @@ } .tag-badges > span:hover { filter: brightness(95%); +} +.focused-element { + border: 2px solid red; } \ No newline at end of file