Lector
Feature recipes

Zoom controls

Set zoom limits, build a toolbar, and keep pages fitted to the container.

Zoom values are multipliers: 1 means 100%, 0.5 means 50%. The CurrentZoom input displays a percentage.

Add a toolbar

Mount this component inside Root. It includes a fit-width action and disables zoom buttons at the configured limits.

zoom-controls.tsx
"use client";
 
import { CurrentZoom, ZoomIn, ZoomOut, usePdf } from "@anaralabs/lector";
 
export default function ZoomControls() {
  const zoom = usePdf((state) => state.zoom);
  const min = usePdf((state) => state.zoomOptions.minZoom);
  const max = usePdf((state) => state.zoomOptions.maxZoom);
  const fitWidth = usePdf((state) => state.zoomFitWidth);
 
  return (
    <div role="group" aria-label="Zoom controls" style={{ display: "flex", gap: 8 }}>
      <ZoomOut type="button" disabled={zoom <= min}>Zoom out</ZoomOut>
      <label>Zoom <CurrentZoom style={{ width: 56 }} /> %</label>
      <ZoomIn type="button" disabled={zoom >= max}>Zoom in</ZoomIn>
      <button type="button" onClick={fitWidth}>Fit width</button>
    </div>
  );
}

Initial zoom and limits

<Root
  source="/sample.pdf"
  zoom={1}
  zoomOptions={{ minZoom: 0.5, maxZoom: 4 }}
>
  {/* Your toolbar and bounded Pages container */}
</Root>

The defaults are zoom: 1, minZoom: 0.5, and maxZoom: 10. Supply a positive minimum and a maximum at least as large as the minimum. Initial zoom and limits initialize the document store; they are not controlled props that update the zoom after mounting.

For runtime changes, select updateZoom from usePdf and call updateZoom(1.5) or updateZoom((previous) => previous + 0.1). Updates are clamped to the configured limits. ZoomIn and ZoomOut change zoom in steps of 0.1.

Fit width

Set isZoomFitWidth on Root to start fitted to the container. zoomFitWidth() enables the same mode from a control. Fit mode responds to container resizing and respects zoom limits. A manual updateZoom call leaves fit mode by default.

For a toolbar layout, keep Pages in a flex: 1; min-height: 0 wrapper. See your first viewer for the complete structure. Avoid CSS transform: scale(...) on the viewer: the library must know the zoom to position selection and overlays correctly.

Live example

Loading...

On this page