useFocus
Reactive utility that tracks whether a DOM element has focus, with two-way binding — read the current focus state and programmatically focus or blur the element.
Click the input or use the buttons to control focus programmatically.
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";import { const useFocus: (target: MaybeEventTarget, options?: DeepMaybeObservable<UseFocusOptions>) => UseFocusReturn
useFocus } from "@usels/web";
function function Component(): JSX.Element
Component() { const const input$: Ref$<HTMLInputElement | null>
input$ = useRef$<HTMLInputElement>(): Ref$<HTMLInputElement | 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 HTMLInputElement
HTMLInputElement>(); const { const focused$: any
Current focus state (read/write) — set(true)→focus(), set(false)→blur()
focused$ } = function useFocus(target: MaybeEventTarget, options?: DeepMaybeObservable<UseFocusOptions>): UseFocusReturn
Framework-agnostic reactive focus tracking for a target element with
optional two-way binding.
Exposes focused$ as a read/write Observable:
- Setting
focused$.set(true) calls el.focus()
- Setting
focused$.set(false) calls el.blur()
- DOM focus/blur events update
focused$ automatically.
useFocus(const input$: Ref$<HTMLInputElement | null>
input$);
return ( <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.input: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
input RefAttributes<HTMLInputElement>.ref?: Ref<HTMLInputElement> | 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 input$: Ref$<HTMLInputElement | null>
input$} InputHTMLAttributes<HTMLInputElement>.placeholder?: string | undefined
placeholder="Click to focus" /> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Focused: {const focused$: any
Current focus state (read/write) — set(true)→focus(), set(false)→blur()
focused$.any
get() ? "Yes" : "No"}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={() => const focused$: any
Current focus state (read/write) — set(true)→focus(), set(false)→blur()
focused$.any
set(true)}>Focus</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={() => const focused$: any
Current focus state (read/write) — set(true)→focus(), set(false)→blur()
focused$.any
set(false)}>Blur</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> </JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}import { createRef$ } from "@usels/core";import { createFocus } from "@usels/web";
function Component() { "use scope" const input$ = createRef$<HTMLInputElement>(); const { focused$ } = createFocus(input$);
return ( <div> <input ref={input$} placeholder="Click to focus" /> <p>Focused: {focused$.get() ? "Yes" : "No"}</p> <button onClick={() => focused$.set(true)}>Focus</button> <button onClick={() => focused$.set(false)}>Blur</button> </div> );}Auto Focus on Mount
Section titled “Auto Focus on Mount”Set initialValue: true to automatically focus the element when the component mounts.
// @noErrorsimport { useRef$ } from "@usels/core";import { useFocus } from "@usels/web";
function AutoFocusInput() { const input$ = useRef$<HTMLInputElement>(); const { focused$ } = useFocus(input$, { initialValue: true }); return <input ref={input$} />;}Focus Visible
Section titled “Focus Visible”When focusVisible: true, only tracks focus that would show a visible focus indicator
(matching the CSS :focus-visible pseudo-class). Mouse clicks won’t trigger focused$,
but keyboard navigation (Tab) will.
// @noErrorsimport { useRef$ } from "@usels/core";import { useFocus } from "@usels/web";
function FocusVisibleButton() { const btn$ = useRef$<HTMLButtonElement>(); const { focused$ } = useFocus(btn$, { focusVisible: true }); return <button ref={btn$}>Tab to me</button>;}Prevent Scroll
Section titled “Prevent Scroll”Pass preventScroll: true to prevent the browser from scrolling to the element when programmatically focused.
const { focused$ } = useFocus(el$, { preventScroll: true });focused$.set(true); // focuses without scrollingParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
target | MaybeEventTarget | - |
options | UseFocusOptions (optional) | - |
UseFocusOptions
Section titled “UseFocusOptions”Returns
Section titled “Returns”UseFocusReturn
| Name | Type | Description |
|---|---|---|
focused$ | ObservableBoolean<boolean> | Current focus state (read/write) — set(true)→focus(), set(false)→blur() |