Skip to content
v2.5.0
English
Русский
Documentation

SnapScroller

SnapScroller is a compound component for CSS scroll-snap-based horizontal paging.

Patterns

When to use:

  • a snapped surface should also support explicit previous/next controls

Composition notes:

  • keep apiRef stable
  • let external controls call prev() and next()

Trade-offs:

  • explicit and easy to control
  • adds more integration logic than passive snapping
button-controlled-carousel.tsx · 72 lines
import {
  Icon,
  IconButton,
  SnapScroller,
  SnapScrollerContent,
  Text,
  type SnapScrollerApiRef,
} from '@vega-ui/react';
import { ChevronLeft, ChevronRight } from '@vega-ui/icons';
import { useRef, useState, type CSSProperties } from 'react';

const products = [

Highlight Current Page

When to use:

  • the snapped page should visibly stand out

Composition notes:

  • derive highlighted state from onScrollSnapChange or onScrollSnapChanging
  • keep the same keyed ordering in the content list

Trade-offs:

  • clearer current-page feedback
  • one more state synchronization path to maintain
synced-page-control.tsx · 62 lines
import {
  Heading,
  PageControl,
  PageControlItem,
  SnapScroller,
  SnapScrollerContent,
  Text,
  type SnapScrollerApiRef,
} from '@vega-ui/react';
import { useRef, useState, type CSSProperties } from 'react';

const plans = [

Stable Wizard Pages

When to use:

  • a short step flow benefits from physical paging

Composition notes:

  • keep each page width stable
  • use stable indexes that match the intended order

Trade-offs:

  • tactile, clear progression
  • mixed widths or unstable ordering degrade the experience
checkout-wizard-form.tsx · 158 lines
import {
  Button,
  Fieldset,
  FieldsetLegend,
  Label,
  SnapScroller,
  SnapScrollerContent,
  Text,
  TextField,
  TextFieldInput,
  type SnapScrollerApiRef,
} from '@vega-ui/react';

Comparison

Quick Decision Rule

Use SnapScroller when pages already have stable indexes and only direct snap-based paging is needed. Use IndexedSnapScroller when the scroller should manage a sliding logical index window.

SnapScroller vs IndexedSnapScroller

  • Use SnapScroller for direct keyed pages that already exist.
  • Use IndexedSnapScroller for index-windowed infinite-like paging.

SnapScroller vs PageControl

  • Use SnapScroller for the actual paged surface.
  • Use PageControl as a compact indicator or controller for a short sequence.

Choose This Component When

  • pages have stable indexes
  • snap callbacks and imperative prev/next are enough

Do Not Choose This Component When

  • the page list should expand or shift virtually
  • a simple indicator is enough without a snapped surface

Troubleshooting

The Scroller Snaps To Unexpected Pages

Symptom

The scroll settles, but not on the page users expected.

Likely Cause

Indexes or item widths are not as stable as the integration assumes.

How To Verify

  • inspect the registered index values
  • compare item widths and ordering across renders

Fix

Keep indexes stable and use more predictable page sizing.

defaultIndex Does Nothing

Symptom

The scroller mounts, but it does not start on the intended page.

Likely Cause

The keyed item for that index is not present when the initial scroll is attempted.

How To Verify

  • inspect the actual SnapScrollerContent index={...} values at mount

Fix

Ensure the target keyed page exists during the initial render.

External Controls Drift From The Visible Page

Symptom

Previous/next buttons or highlighted state stop matching the current snap position.

Likely Cause

The imperative API and the highlighted state are not reading from the same source of truth.

How To Verify

  • compare the committed snap index with the state used by external controls

Fix

Drive both visible highlighting and imperative controls from the same snap callbacks or committed index.