# useCaretPosition

The caret's position on screen in a `<textarea>` or text `<input>`, or `null` while the field isn't focused. Returns a callback ref for the field.

Browsers don't expose caret coordinates, so this measures a hidden copy of the field's text and styles. Updates on typing, clicks, arrow keys, selection changes, and scrolling inside the field or the page, at most once per frame. Coordinates are in viewport pixels, for a `position: fixed` popup. Safe with controlled fields: it never updates state during their events.

## Import

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

## Usage

```ts
const [ref, caret] = useCaretPosition()
const [text, setText] = useState('')
const mentioning = /@\w*$/.test(text)
return (
  <>
    <textarea ref={ref} value={text} onChange={(e) => setText(e.target.value)} />
    {mentioning && caret && (
      <ul style={{ position: 'fixed', top: caret.top + caret.height, left: caret.left }}>…</ul>
    )}
  </>
)
```

## When to use it

Placing an `@mention`, `/command`, emoji, or autocomplete popup next to the caret, like in chat and comment inputs.

## When not to

The popup can sit below the whole field; position it from the field's own box. For rich text editors, use the editor's selection API; for text selected elsewhere on the page, use `useTextSelection`.

## API

```ts
function useCaretPosition<T extends HTMLTextAreaElement | HTMLInputElement = HTMLTextAreaElement>(): [(element: T | null) => void, CaretPosition | null]
```

**Returns** `[ref, position]`. Pass `ref` to the textarea or input.

### Types

```ts
export type CaretPosition = {
  /** Top of the caret line, in viewport pixels. Use with `position: fixed`. */
  top: number;
  /** Left of the caret, in viewport pixels. */
  left: number;
  /** Line height at the caret, in pixels. Place a popup at `top + height`. */
  height: number;
};
```

## Browser support

Works in all modern browsers.

## Coming from another library?

Other libraries call this `useCaretCoordinates`, `textarea-caret`.

---

705 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useCaretPosition.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useCaretPosition/
Previous: [useAutosizeTextarea](https://vincentri.github.io/react-tils/hooks/useAutosizeTextarea.md)
Next: [useInterval](https://vincentri.github.io/react-tils/hooks/useInterval.md)
