# useTextSelection

The text the user has selected inside an element, or `null`. Returns a callback ref for the element.

Follows mouse, touch, and keyboard selection (Shift+arrows, select all). While the mouse or finger is still down it waits, so a toolbar doesn't flicker during a drag, and updates on release. `null` when the selection is empty, only whitespace, or not entirely inside the element.

## Import

```ts
import { useTextSelection } from '@vincent.ri/react-tils'
// or only this hook
import { useTextSelection } from '@vincent.ri/react-tils/useTextSelection'
```

## Usage

```ts
const [ref, selection] = useTextSelection<HTMLElement>()
return (
  <>
    <article ref={ref}>{children}</article>
    {selection && (
      <div style={{ position: 'fixed', top: selection.rect.top - 40, left: selection.rect.left }}>
        <button onClick={() => quote(selection.text)}>Quote</button>
      </div>
    )}
  </>
)
```

## When to use it

A floating toolbar for highlight, comment, share quote, or "Ask AI about this", or a "copy quote" button.

## When not to

The text is in an `<input>` or `<textarea>`; read its `selectionStart` and `selectionEnd`. For a rich text editor, use the editor's own selection API. `rect` doesn't follow scrolling; read `range.getBoundingClientRect()` again if the page scrolls.

## API

```ts
function useTextSelection<T extends Element = HTMLElement>(): [(element: T | null) => void, TextSelection | null]
```

**Returns** `[ref, selection]`. Pass `ref` to the element containing the text.

### Types

```ts
export type TextSelection = {
  /** The selected text. */
  text: string;
  /** Where the selection is on screen, in viewport coordinates, for placing a toolbar. */
  rect: DOMRect;
  /** A copy of the selected range, e.g. to wrap it in a highlight. */
  range: Range;
};
```

## Browser support

Works in all modern browsers.

---

351 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useTextSelection.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useTextSelection/
Previous: [usePasteFiles](https://vincentri.github.io/react-tils/hooks/usePasteFiles.md)
Next: [useRovingFocus](https://vincentri.github.io/react-tils/hooks/useRovingFocus.md)
