Skip to content

API Reference

The main hook. Returns everything you need to build a split-view UI — refs, transforms, clip-paths, handle event bundles, and imperative controls.

import { useSplitView } from "use-split-view"
const sv = useSplitView({
direction: "horizontal",
initialSplit: 50,
})

All options are optional. Pass {} or nothing to get the defaults.


OptionTypeDefaultDescription
direction"horizontal" | "vertical""horizontal"Split orientation. Flips clip-path and handle math
initialSplitnumber50Initial split position as a percentage (0–100)
OptionTypeDefaultDescription
minScalenumber0.1Minimum allowed zoom level
maxScalenumber50Maximum allowed zoom level
panSpeednumber1Multiplier for pan speed (mouse wheel only)
zoomSpeednumber1Multiplier for zoom speed (mouse wheel only)
OptionTypeDefaultDescription
viewStateViewStateControlled view state. When provided, the hook becomes controlled
onViewStateChange(view: ViewState) => voidCallback on every view change. Required when viewState is provided

See Controlled View State for patterns.


useSplitView returns a single object (UseSplitViewReturn).

PropertyTypeDescription
containerRefRefObject<HTMLDivElement | null>Attach to your container element
containerSize{ w: number; h: number }Container dimensions tracked via ResizeObserver
PropertyTypeDescription
splitnumberCurrent split position (0–100)
setSplit(value: number) => voidSet the split position programmatically
directionSplitViewDirectionCurrent direction (echoed from options)
splitCSSValuestringConvenience string like "50%"
PropertyTypeDescription
viewViewStateCurrent { x, y, zoom }
setView(v: ViewState, opts?: AnimationOptions) => voidSet view directly, optionally animated
centerZoom(targetZoom: number) => voidZoom to target keeping container center fixed
resetView() => voidReset to { x: 0, y: 0, zoom: 1 }
isLockedbooleanWhether zoom/pan is currently locked
setIsLocked(locked: boolean) => voidManually lock or unlock gestures
PropertyTypeDescription
naturalSize{ w: number; h: number } | nullContent’s natural dimensions (or null before set)
setNaturalSize(w: number, h: number) => voidReport content dimensions; call once on load
fitScalenumberScale factor to fit content into container
displaySize{ w: number; h: number }Rendered dimensions (naturalSize * fitScale)
displayZoomPctnumberUser-facing zoom percentage (integer)
PropertyTypeDescription
getPaneState(part: "start" | "end") => SplitPaneStateReturns clip-path, transform, and content style for one pane
handlePropsHandlePropsSpread on your drag handle element

Returned by getPaneState("start" | "end"):

interface SplitPaneState {
clipPath: string // CSS clip-path, e.g. "inset(0 calc(100% - 50%) 0 0)"
transform: string // CSS transform, e.g. "translate(12px, 4px) scale(1.5)"
contentStyle: CSSProperties // Width/height for the content layer
}

Before setNaturalSize is called, contentStyle is { opacity: 0 }. After it’s called, it becomes { width: displaySize.w, height: displaySize.h }.


interface HandleProps {
onPointerDown: (e: React.PointerEvent) => void
onPointerMove: (e: React.PointerEvent) => void
onPointerUp: (e: React.PointerEvent) => void
onPointerCancel: (e: React.PointerEvent) => void
onMouseEnter: () => void
onMouseLeave: () => void
}

These are ready to spread:

<div {...handleProps} style={...}>...</div>

They implement pointer capture, split update math, zoom/pan locking on drag, and hover-locking. See The Drag Handle for a deep dive.


Everything from use-zoom-pinch is re-exported for convenience:

import {
useZoomPinch,
easeInOut,
easeOut,
linear,
type ViewState,
type AnimationOptions,
type BoundsOptions,
type GesturesOptions,
type InertiaOptions,
type DoubleTapOptions,
type RotationOptions,
type KeyboardOptions,
type CursorOptions,
type ActivationKeyOptions,
type SnapToGridOptions,
type ZoomSnapLevel,
type EasingFunction,
type UseZoomPinchOptions,
type UseZoomPinchReturn,
} from "use-split-view"

This lets you build custom overlays or secondary hooks (e.g. a minimap) without adding use-zoom-pinch as a separate dependency.