Patterns
Button-Controlled Carousel
When to use:
- a snapped surface should also support explicit previous/next controls
Composition notes:
- keep
apiRefstable - let external controls call
prev()andnext()
Trade-offs:
- explicit and easy to control
- adds more integration logic than passive snapping
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
onScrollSnapChangeoronScrollSnapChanging - keep the same keyed ordering in the content list
Trade-offs:
- clearer current-page feedback
- one more state synchronization path to maintain
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
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
SnapScrollerfor direct keyed pages that already exist. - Use
IndexedSnapScrollerfor index-windowed infinite-like paging.
SnapScroller vs PageControl
- Use
SnapScrollerfor the actual paged surface. - Use
PageControlas 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
indexvalues - 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.