Rooks
Event Handling

useTextSelection

Tracks the currently selected text on the page.

About

Tracks the currently selected text on the page or within a scoped element. Listens to the native selectionchange event and clears the selection state when the user clicks outside a scoped target. Returns empty state during SSR.

Examples

Track selection anywhere on the page

import { useTextSelection } from "rooks";

export default function App() {
  const [{ text, rect }] = useTextSelection();

  return (
    <div>
      <p>Select any text on this page.</p>
      {text && (
        <p>
          You selected: <strong>{text}</strong>
        </p>
      )}
    </div>
  );
}

Scope tracking to a specific element

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

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

  return (
    <>
      <div ref={articleRef}>
        <p>
          Only selections within this article are tracked. Try selecting
          some of this text, or the paragraph below.
        </p>
        <p>Another paragraph inside the article.</p>
      </div>
      <p>Selection outside is ignored.</p>
      {text && (
        <pre>
          {JSON.stringify({ text, startOffset, endOffset }, null, 2)}
        </pre>
      )}
    </>
  );
}

Show a floating tooltip at the selection position

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

export default function FloatingTooltip() {
  const [{ text, rect }] = useTextSelection();

  return (
    <div style={{ position: "relative" }}>
      <p>Select any text to see a tooltip appear.</p>
      {text && rect && (
        <div
          style={{
            position: "fixed",
            top: rect.top - 40,
            left: rect.left + rect.width / 2,
            transform: "translateX(-50%)",
            background: "#333",
            color: "#fff",
            padding: "4px 8px",
            borderRadius: 4,
            pointerEvents: "none",
            whiteSpace: "nowrap",
          }}
        >
          {text.length} character{text.length !== 1 ? "s" : ""} selected
        </div>
      )}
    </div>
  );
}

Arguments

ArgumentTypeDescriptionDefault
targetRefObject<HTMLElement>Optional ref to scope selection tracking to a specific element.undefined

Return value

Returns a tuple [selectionState].

AttributeTypeDescription
textstringThe selected text. Empty string when nothing is selected.
rectDOMRect | nullBounding rect of the selection range, or null.
startOffsetnumberCharacter offset within anchorNode where the selection starts.
endOffsetnumberCharacter offset within focusNode where the selection ends.
anchorNodeNode | nullThe node at which the selection begins.
focusNodeNode | nullThe node at which the selection ends (the drag point).

On this page