Skip to content
Sensors

useElementHover

Reactively tracks whether a DOM element is being hovered. Supports optional enter/leave delays for debounced hover behavior.

Element Hover
Not Hovered

Hover over the box below to see the state change.

Hover me
import {
const useElementHover: (target: MaybeEventTarget, options?: DeepMaybeObservable<UseElementHoverOptions>) => UseElementHoverReturn
useElementHover
} from "@usels/web";
import {
const useRef$: {
<T = any>(initialValue: null): Ref$<T | null>;
<T = any>(initialValue: T): Ref$<T>;
<T = any>(): Ref$<T | null>;
}
useRef$
} from "@usels/core";
function
function HoverTracker(): JSX.Element
HoverTracker
() {
const
const el$: Ref$<HTMLDivElement | null>
el$
=
useRef$<HTMLDivElement>(): Ref$<HTMLDivElement | null> (+2 overloads)

Core (framework-agnostic) version of useRef$. Creates an observable element ref with opaque wrapping.

  • non-null value → Ref$<T>: current, get(), peek() return T
  • null / no arg → Ref$<T | null>: current, get(), peek() return T | null

Nullability is expressed via the type parameter, mirroring T | null at the call site.

useRef$
<
interface HTMLDivElement
HTMLDivElement
>();
const
const isHovered$: any
isHovered$
=
function useElementHover(target: MaybeEventTarget, options?: DeepMaybeObservable<UseElementHoverOptions>): UseElementHoverReturn

Framework-agnostic reactive element hover tracker.

Tracks whether a target element is being hovered via mouseenter / mouseleave events. Supports optional enter/leave delays.

useElementHover
(
const el$: Ref$<HTMLDivElement | null>
el$
);
return <
JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
RefAttributes<HTMLDivElement>.ref?: Ref<HTMLDivElement> | undefined

Allows getting a ref to the component instance. Once the component unmounts, React will set ref.current to null (or call the ref with null if you passed a callback ref).

ref
={
const el$: Ref$<HTMLDivElement | null>
el$
}>{
const isHovered$: any
isHovered$
.
any
get
() ? "Hovered!" : "Hover me"}</
JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>;
}
import { useElementHover } from "@usels/web";
import { useRef$ } from "@usels/core";
function DelayedHover() {
const el$ = useRef$<HTMLDivElement>();
const isHovered$ = useElementHover(el$, {
delayEnter: 200,
delayLeave: 300,
});
return <div ref={el$}>{isHovered$.get() ? "Hovered (with delay)" : "Hover me"}</div>;
}
import { observable } from "@usels/core";
const delayEnter$ = observable(200);
const isHovered$ = useElementHover(el$, { delayEnter: delayEnter$ });
// Later: update delay reactively
delayEnter$.set(500);

options is DeepMaybeObservable. Each option field (delayEnter, delayLeave) can be a plain value or an Observable. Changes are picked up reactively at each hover toggle.

ParameterTypeDescription
targetMaybeEventTarget-
optionsUseElementHoverOptions (optional)-
OptionTypeDefaultDescription
delayEnternumber-Delay in ms before entering hover state
delayLeavenumber-Delay in ms before leaving hover state

UseElementHoverReturn

NameTypeDescription
peek{ (): boolean; (): boolean; }-
get(trackingType?: TrackingType | GetOptions) => boolean-
onChange(cb: ListenerFn<boolean>, options?: { trackingType?: TrackingType; initial?: boolean | undefined; immediate?: boolean | undefined; noArgs?: boolean | undefined; } | undefined) => () => void-

View on GitHub