# Text selection

Capture selected text and page-relative rectangles with a selection action.

Source: https://anara.com/lector/docs/code/select

These docs describe the source deployed with this site, tracking main rather than a versioned npm release. Check your installed @anaralabs/lector and pdfjs-dist versions before applying examples.

Add `TextLayer` to make a text-based PDF selectable. `useSelectionDimensions().getDimension()` reads the current browser selection and returns the selected text and its highlight rectangles. It can return `undefined`, so check the result before using it.

## Turn a selection into a highlight

This example uses `pdf-setup.ts` from [installation](https://anara.com/lector/docs/installation). Select text, then activate the Highlight button in the tooltip.

```tsx title="selection-viewer.tsx"
"use client";

import {
  CanvasLayer, HighlightLayer, Page, Pages, Root, SelectionTooltip,
  TextLayer, usePdf, useSelectionDimensions,
} from "@anaralabs/lector";
import "./pdf-setup";

function SelectionAction() {
  const { getDimension } = useSelectionDimensions();
  const setHighlight = usePdf((state) => state.setHighlight);

  return (
    <SelectionTooltip>
      <button
        type="button"
        style={{ background: "white", color: "black", padding: "6px 12px", border: "1px solid" }}
        onMouseDown={(event) => event.preventDefault()}
        onClick={() => {
          const selection = getDimension();
          if (!selection || selection.isCollapsed || !selection.highlights.length) return;
          setHighlight(selection.highlights);
          window.getSelection()?.removeAllRanges();
        }}
      >
        Highlight selection
      </button>
    </SelectionTooltip>
  );
}

export default function SelectionViewer() {
  return (
    <Root source="/sample.pdf" style={{ height: 600 }}>
      <Pages>
        <Page>
          <CanvasLayer />
          <TextLayer />
          <HighlightLayer style={{ background: "#ffdf6080" }} />
        </Page>
      </Pages>
      <SelectionAction />
    </Root>
  );
}
```

Mount one selection tooltip per viewer, outside the repeated `Page` template. Preventing the button's mouse-down default keeps the browser from discarding the selection before the click handler reads it. The result contains `text`, `highlights`, and `isCollapsed`. Rectangles use [scale-1 page pixels](https://anara.com/lector/docs/code/highlight#coordinate-contract); a multi-page selection can contain multiple page numbers.

`setHighlight` replaces the active highlight. The example does not accumulate selections or persist them.

## Saving highlights

For a built-in color picker, add `ColoredHighlightLayer` under `Page`. Its `onHighlight` callback receives a `ColoredHighlight` with `uuid`, `text`, `color`, `pageNumber`, and `rectangles`. Its tools use Tailwind utility classes; see [styles](https://anara.com/lector/docs/installation#styles-and-pdf-assets).

Your application owns storage. Save each highlight under a document ID and revision, report save failures, and restore saved records using the store's `addColoredHighlight`. Restore once per document session to avoid duplicate records. `deleteColoredHighlight(uuid)` removes one from the current store; delete it from your persistence layer separately.

These are viewer overlays. They do not become embedded PDF annotations when downloading the original file.

## Selection limits

A scanned page without embedded text cannot provide text selection; Lector does not run OCR. Selection geometry also depends on the PDF's text layout and which virtualized text layers are mounted. Test multi-column text, rotated pages, zoom, and touch selection with the PDFs your users work with.

If text is selectable but displaced, check the PDF.js stylesheet and avoid adding your own transforms to `Page` or `TextLayer`.

## Live example

Open the documentation page linked above to use this interactive example.
