Rooks
HooksEvent Handling

useTextSelection

Returns the current text selection for the document or a target element.

About

useTextSelection tracks the browser selection and exposes its text, endpoints, and first-range rectangle. An optional ref restricts accepted selections to one element.

Example

import { useRef } from "react";
import { useTextSelection } from "rooks";

export default function SelectionReader() {
  const articleRef = useRef<HTMLDivElement>(null!);
  const [{ text, startOffset, endOffset }] = useTextSelection(articleRef);

  return (
    <div>
      <div ref={articleRef}>Select any part of this sentence.</div>
      <p>Selected: {text || "nothing"}</p>
      <p>
        Anchor: {startOffset}; focus: {endOffset}
      </p>
    </div>
  );
}

Parameters

  • target: optional RefObject<HTMLElement>. When provided, both the selection's anchor and focus nodes must be contained by the current element. With React typings that infer RefObject<T | null> from useRef(null), the current hook signature requires a non-null initializer or equivalent type assertion.

Return value

The hook returns a one-item tuple containing TextSelectionState:

  • text: string
  • rect: DOMRect | null, from the first selection range
  • startOffset: number, the selection's anchor offset
  • endOffset: number, the selection's focus offset
  • anchorNode: Node | null
  • focusNode: Node | null

startOffset and endOffset preserve anchor/focus direction; they are not sorted document boundaries. TextSelectionState is a public type export from rooks.

Behavior and lifecycle

The hook subscribes to document selectionchange and mousedown. Collapsed, empty, unavailable, or out-of-scope selections produce the shared empty state. In scoped mode, a mouse down outside the target clears a previously recorded selection. Reading a detached range rectangle is guarded; if it throws, rect remains null. Both listeners are removed on unmount.

Compatibility and accessibility

The server snapshot contains empty text, zero offsets, null nodes, and a null rectangle. Selection APIs and rectangle values are browser-defined. Treat selected text as supplemental state and do not replace the browser's standard selection or copy behavior.

On this page