← All packages

@searsuite/sear-render-scroll

Logical scrolling, axis locking, boundary feedback, and host scroller adapters.

Scroll state and control

classHeadlessScroller
class HeadlessScroller extends Scroller

Scroller adapter for hosts that have no native scroll surface.

constructorHeadlessScroller(): HeadlessScroller

Constructs a scroller adapter.

propertyreadonly symbol: symbolstatic

DI token for resolving HeadlessScroller.

methodgetPublisher(): ScrollPublisher

Returns the publisher.

Inherited members 2

Inherited from Scroller.

classScrollAxisLock

Locks a continuous input gesture to its first dominant axis.

constructorScrollAxisLock(): ScrollAxisLock
methodconfigure(config: Partial<ScrollAxisLockConfig>): void

Applies validated host overrides and resets an in-progress gesture.

methodconsume(x: number, y: number): { x: number; y: number }

Filters one two-dimensional input sample through the active direction lock.

methodgetAxis(): ScrollAxis | null

Returns the currently selected axis, or null before activation.

methodgetWheelEndDelay(): number

Returns the configured wheel gesture-end delay.

methodreset(): void

Ends the current gesture and clears uncommitted sub-threshold input.

classScrollAxisLockConfigError
class ScrollAxisLockConfigError extends SearError

Stable public error raised for invalid scroll-axis lock configuration.

Inherited members 9

Inherited from SearError.

classScroller

Base class for host scroll adapters.

Concrete scrollers own platform scroll surfaces while ScrollManager owns the platform-neutral viewport state.

constructorScroller(): Scroller

Constructs a scroller adapter.

propertyreadonly configEngine: ConfigEngine

Configuration engine available to concrete scroller adapters.

propertyreadonly ContainerSymbol: symbolstatic

DI token used by hosts that provide a scroller container.

propertyreadonly symbol: symbolstatic

DI token for resolving the active scroller adapter.

classScrollerFactory

Factory registry for host scroller adapters.

constructorScrollerFactory(): ScrollerFactory
methodcreateScroller(type: string | symbol, args: unknown): Scrollerstatic

Creates a scroller for a registered type.

ReturnsNew scroller adapter.

type

Scroller type key.

args

Adapter-specific construction input.

methodregisterScroller(type: string | symbol, scrollerCreator: (args: unknown): Scroller): voidstatic

Registers a scroller creator.

type

Scroller type key.

scrollerCreator

Factory invoked by createScroller().

classScrollManager

Owns viewport scroll state and fans updates out to render subscribers.

constructorScrollManager(width: number, height: number): ScrollManager

Creates a scroll manager for a viewport of the given dimensions.

propertyreadonly symbol: symbolstatic

DI token for resolving the scroll manager.

methodaddPublisher(publisher: ScrollPublisher): (): void

Connects a scroll-event source and returns an idempotent disposer.

methodapplyInputScroll(state: ScrollManagerState): void

Applies platform scroll data within the owning editor's command.

methoddestroy(ownerToken?: object): void

Disconnects publishers and subscribers owned by this manager.

methodenforceCommandBoundary(isExecuting: (): boolean): void

Closes direct viewport writes after the owning editor finishes restoration.

methodenforceTeardownBoundary(ownerToken: object): void

Reserves publisher cleanup for the owning editor.

methodgetContentBoundary(): [number, number]

Returns the maximum logical scroll positions for platform adapters.

methodgetPositionRect(): PositionRect<templateLiteral>

Returns the viewport rectangle as (0, 0, width, height).

The scroll position is NOT included in the returned rect. Consumers that need the world-coordinate viewport should construct their own rect using scrollState.x/y (available via getState()).

Historically this method returned (state.x, state.y, width, height), but since ScrollManager.update() now clamps state.x/y in-place, including them caused double-offset bugs in render strategies that already add scrollState.x/y to compute world-coordinate query rects.

methodgetPreviousState(): ScrollManagerState | null

Returns the previous committed scroll state.

methodgetRenderScrollState(): ScrollManagerState

Returns the scroll state that render strategies should use for viewport copy planning.

deltaX and deltaY are computed from the last position marked as rendered to the current committed position. This keeps wheel scrolling and programmatic scrollTo() jumps on the same delta convention expected by RasterCopyPlan: previous minus current.

methodgetShape(): [number, number]

Returns the viewport dimensions as [width, height].

methodgetState(): ScrollManagerState

Returns the current committed scroll state.

methodhasUnrenderedScroll(): boolean

Returns whether the current scroll position has not yet been rendered.

methodmarkScrollStateRendered(): void

Marks the current committed scroll position as consumed by a render frame.

methodrequestScrollTo(x: number, y: number): void

Requests an absolute scroll position through the owning editor.

methodresize(width: number, height: number): void

Updates viewport dimensions and clamps the current position without emitting a scroll render.

methodscrollTo(x: number, y: number): void

Programmatically scroll to an absolute position, clamped to the content boundary, and notify all subscribers so the render pipeline re-draws.

methodsetContentBoundary(maxWidth: number, maxHeight: number): void

Set the content boundary for scroll clamping.

maxWidth

Maximum scrollable x position (contentWidth - viewportWidth)

maxHeight

Maximum scrollable y position (contentHeight - viewportHeight)

This should be called after initialization once the total sheet dimensions are known (e.g. by expandTreeBoundaryToSheetSize).

methodsetInputUpdateExecutor(executor: (state: ScrollManagerState): void): void

Routes platform-originated viewport input through the host's action boundary.

methodsetPosition(x: number, y: number): void

Directly set the scroll position (x, y) in the manager's state.

Useful for programmatic scroll jumps (e.g. "scroll to cell A1"). For normal scroll events, use addPublisher + update() instead, which clamps the position to the content boundary.

methodsetScrollToExecutor(executor: (x: number, y: number): void): void

Binds programmatic scroll requests to the owning editor's command bus.

methodsubscribeScroll(callback: ScrollSubscriber, prepend?: boolean): (): void

Subscribes to scroll-state changes and returns an idempotent disposer. prepend is reserved for updates that must run before render strategies.

classWebScroller
class WebScroller extends Scroller

Adapts a Web scroll surface to logical editor viewport coordinates.

constructorWebScroller(target: unknown, platform: Platform): WebScroller
propertyreadonly symbol: symbolstatic

DI token for resolving WebScroller.

memberroot
root: unknown
methodconfigureAxisLock(config: Partial<ScrollAxisLockConfig>): void

Enables or tunes Safari-style dominant-axis locking for wheel and touch gestures.

methodconfigureRubberBand(config: Partial<RubberBandConfig>): void

Enables or tunes the Safari-style overscroll effect. Logical editor coordinates remain clamped; only the visible surface moves.

methodgetPublisher(): (scrollStateInstance: ScrollManager, updateState: (newState: ScrollManagerState): void): (): void

Returns the publisher.

Inherited members 2

Inherited from Scroller.

interfaceScrollAxisLockConfig

Host-tunable direction-lock parameters for DOM scrolling gestures.

propertyactivationThreshold: number

Accumulated pixels required before selecting the dominant axis.

propertyenabled: boolean
propertywheelEndDelay: number

Wheel silence in milliseconds that separates two gestures.

interfaceScrollManagerState

Scroll offset snapshot published to render and coordinate subscribers.

propertydeltaX: number

Horizontal input delta that produced the update.

propertydeltaY: number

Vertical input delta that produced the update.

propertyx: number

Current horizontal scroll offset in world coordinates.

propertyy: number

Current vertical scroll offset in world coordinates.

typeScrollAxis
type ScrollAxis = "x" | "y"

Axis selected for one continuous wheel or touch gesture.

typeScrollPublisher
type ScrollPublisher = (manager: ScrollManager, updateState: (newState: ScrollManagerState): void): (): void

Platform adapter that connects a scroll event source to ScrollManager.

functioncreateDefaultScrollManagerState
createDefaultScrollManagerState(): ScrollManagerState

Creates the default zero-offset scroll state.

Rubber band

classRubberBandConfigError
class RubberBandConfigError extends SearError

Stable public error raised for invalid rubber-band physics configuration.

Inherited members 9

Inherited from SearError.

classRubberBandController

Platform-neutral Safari-style overscroll physics.

Logical positions never leave their boundaries. Raw excess input is mapped to a visual displacement with WebKit's viewport-relative resistance curve, then returned by a damped harmonic spring once boundary input settles.

constructorRubberBandController(platform: Platform, publishOffset: (offset: RubberBandOffset): void): RubberBandController

Creates one controller and publishes every visual displacement change.

methodconfigure(config: Partial<RubberBandConfig>): void

Applies validated host overrides and resets immediately when disabled.

methodconsume(input: RubberBandInput): RubberBandOffset

Consumes one wheel or touch sample and returns a clamped logical position. Reversing direction first consumes existing excess before logical scrolling resumes.

methodgetOffset(): RubberBandOffset

Returns a copy of the current transient visual displacement.

methodrelease(delay?: number, preserveVelocity?: boolean): void

Starts the boundary return after the configured input-settle delay.

methodreset(): void

Cancels pending work and restores the exact zero-displacement state.

interfaceRubberBandConfig

Host-tunable parameters for Safari-style boundary resistance and return motion.

propertyenabled: boolean
propertymaxOffset: number

Smooth asymptotic maximum visual displacement in viewport pixels.

propertyresistance: number

Initial slope of the rubber-band curve. Lower values reduce sensitivity.

propertyreturnDelay: number

Default delay used when release is called without an explicit delay.

propertyspringDamping: number

Viscous damping used by the damped harmonic return motion.

propertyspringMass: number

Spring mass used by the damped harmonic return motion.

propertyspringStiffness: number

Spring stiffness used by the damped harmonic return motion.

interfaceRubberBandInput

One logical input sample consumed by RubberBandController.

propertyreadonly boundary: RubberBandOffset
propertyreadonly continueReturnOnOutwardInput?: boolean

Keeps an already scheduled return alive for same-direction wheel inertia.

propertyreadonly displacement: RubberBandOffset

Content displacement: positive values move the visible surface right/down.

propertyreadonly position: RubberBandOffset
propertyreadonly viewport: RubberBandOffset
interfaceRubberBandOffset

Transient visual displacement in viewport pixels.

functionrubberBandDistance
rubberBandDistance(excess: number, viewport: number, resistance?: number, maxOffset?: number): number

Safari-like rubber-band mapping with a smooth maximum visual displacement.