<PaperScroller />
Wraps one or more <Paper> components with a scrollable, zoomable viewport.
Each <Paper> descendant gets its own independent scroller instance, so a
single <PaperScroller> can wrap multiple <Paper> components.
A forwarded ref receives the ui.PaperScroller instance. Since the
scroller is per-Paper, when wrapping multiple <Paper> children prefer
usePaperScroller to access the paperScroller for a specific Paper
context.
Wheel over a scrollable region inside a node body (native <textarea> or an
element marked data-jj-scrollable) is handled by <Paper> itself — see
that component's docs. The scroller adds nothing on top.
See
Example
import { GraphProvider, Paper, HTMLBox, type CellRecord, PaperScroller, usePaperScroller } from '@joint/react-plus';
interface NodeData {
label: string;
}
const cells: ReadonlyArray<CellRecord<NodeData>> = [
{ id: '1', type: 'element', position: { x: 40, y: 40 }, size: { width: 80, height: 40 }, data: { label: 'A' } },
];
const RenderElement = (data: NodeData) => <HTMLBox>{data.label}</HTMLBox>;
function MyDiagram() {
return (
<GraphProvider initialCells={cells}>
<PaperScroller style={{ width: '100%', height: 500 }} mode="infinite">
<Paper renderElement={RenderElement} />
</PaperScroller>
</GraphProvider>
);
}
// Access the scroller instance via usePaperScroller:
function Controls() {
const { paperScroller } = usePaperScroller();
return <button onClick={() => paperScroller?.center()}>Center</button>;
}
Props
children?
readonly optional children?: ReactNode;
The <Paper> (and any other) elements to render inside the scroller.
className?
readonly optional className?: string;
CSS class name for the scroller's wrapper element.
cursor?
readonly optional cursor?: string;
CSS cursor shown over the scroller's viewport (e.g. 'grab').
fixedSheet?
readonly optional fixedSheet?: boolean;
In sheets mode, locks the canvas to a single sheetWidth × sheetHeight
page. When false, the sheet auto-expands in page increments as content
grows past the current bounds (more pages appear). Ignored in infinite
mode, where the borderless canvas always grows.
Default
false
id?
readonly optional id?: string;
Feature id under which the scroller registers on the paper.
inertia?
readonly optional inertia?: boolean | InertiaOptions;
Momentum scrolling after a pan gesture ends. true for defaults,
or an options object to tune friction/decay.
maxZoom?
readonly optional maxZoom?: number;
Largest zoom level the viewport allows. Clamps every zoom interaction:
mouse wheel, pinch, usePaperScroller setZoom, and the
<Navigator> mini-map drag-zoom.
Default
3
minZoom?
readonly optional minZoom?: number;
Smallest zoom level the viewport allows. Clamps every zoom interaction:
mouse wheel, pinch, usePaperScroller setZoom, and the
<Navigator> mini-map drag-zoom.
Default
0.2
mode?
readonly optional mode?: "infinite" | "sheets";
Canvas behaviour preset.
'infinite': a borderless canvas that grows around the content.'sheets': a bordered, paged canvas that grows insheetWidth×sheetHeightincrements.
Default
'infinite'
options?
readonly optional options?: Partial<Omit<Options, "virtualRendering">>;
Escape hatch for native PaperScrollerOptions that have no dedicated
prop (padding, minVisiblePaperSize, contentOptions, borderless,
plus mvc internals like theme, events, attributes, tagName, etc.).
Values here override defaults derived from mode. Avoid overriding the
options this component controls (paper, model, el, baseWidth,
baseHeight).
scrollWhileDragging?
readonly optional scrollWhileDragging?: boolean | ScrollWhileDraggingOptions;
Auto-scroll the viewport when dragging a cell near its edges.
true for defaults, or an options object to tune the behaviour.
sheetHeight?
readonly optional sheetHeight?: number;
Page height in sheets mode, in paper coordinates (maps to the native
baseHeight). Ignored in infinite mode. Defaults to A4 portrait height
at 72 DPI.
Default
842
sheetWidth?
readonly optional sheetWidth?: number;
Page width in sheets mode, in paper coordinates (maps to the native
baseWidth). Ignored in infinite mode. Defaults to A4 portrait width
at 72 DPI.
Default
595
sheetX?
readonly optional sheetX?: number;
X origin of the page grid in paper coordinates. Shifts the grid anchor:
- growth mode: the first page starts at
(sheetX, sheetY), with later pages at(sheetX + n*sheetWidth, sheetY + m*sheetHeight). fixedSheetmode: positions the single locked sheet's top-left at(sheetX, sheetY).
Default
0
sheetY?
readonly optional sheetY?: number;
Y origin of the page grid in paper coordinates. See sheetX.
Default
0
style?
readonly optional style?: CSSProperties;
Inline styles for the scroller's wrapper element.
virtualRendering?
readonly optional virtualRendering?: boolean | Omit<Options, "cellVisibility">;
Renders only the cells inside the viewport — a performance win for large
diagrams. Pass true for defaults or an options object to tune it.
Applied at mount only: changing this prop at runtime has no effect;
remount the <PaperScroller> (e.g. via a key) to switch it.
cellVisibility is intentionally not accepted here: declare it on
the child <Paper cellVisibility> and it is composed with the viewport
check automatically.
Default
false