Lynx UI logo
Lynx UI

<Swiper>

A Swiper (carousel) component for ReactLynx. It provides pagination and gesture-handling primitives.
Info

You can check the source code to understand how it works, and you're welcome to submit MRs to enhance its capabilities.

Basic Usage
Advanced Usage

Basic Usage

Start with normal mode for common paged content. Keep the item size and container size explicit, then use onChange to sync the current index with an indicator or other page state.

Loop

Use loop mode when the first and last items should connect. This avoids a hard edge in cyclic carousels such as featured content, campaigns, or repeating recommendations.

Bounces

Use bounce content for boundary feedback or pull-to-load behavior. Keep it hidden during normal browsing, and reveal only a lightweight state while the user drags past the edge.

Custom

Use a custom mode when the slide should react continuously to swipe progress. Map the progress value to transforms such as translate, scale, and rotate to build stacked-card interactions.

You can see Advanced Usage for more.

SwiperProps

autoPlay
iOS
Android
Harmony
Typeboolean·Defaultfalse
Whether to enable autoPlay
autoPlayInterval
iOS
Android
Harmony
Typenumber·Default2000
Auto play interval
blockNativeEvent
iOS
Android
Harmony
Typeboolean·Defaultfalse
Whether to block native event. Can be useful when swiper is in Scrollview, List or other components that will block swiper's touch event.
bounceConfig
iOS
Android
Harmony
TypeBounceConfig
BounceParams
children
iOS
Android
Harmony
Type(prop: {index: number, item: T, realIndex: number}) => ReactElement
Children of Swiper should be a function, returning a SwiperItem
consumeSlideEvent
iOS
Android
Harmony
Typeundefined[]·Default[[-180, -135], [-45, 45], [135, 180]]
Determines how swiper respond to touch in different angle. By default, swiper will only respond to horizontal touches. Refer to https://lynxjs.org/en/api/elements/built-in/view.html#consume-slide-event for more
containerWidth
iOS
Android
Harmony
Typenumber·Defaultlynx.__globalProps.screenWidth
Width of swiper item
customAnimationFirstScreen
iOS
Android
Harmony
Type(value: number, index: number) => CSSProperties
Custom animation effect used in JS, should be a JS function. customAnimationFirstScreen should be a function of the same content of 'main-thread:customAnimation' without 'main thread' annotation This is a workaround for MainThreadScript's disability for supporting firstScreen. We are working on removing the duplicated JS version of customAnimation. For now, this is needed.
data
iOS
Android
Harmony
TypeT[]
Swiper items data set
duration
iOS
Android
Harmony
Typenumber·Default500
Duration of animation for paging or swiping
initialIndex
iOS
Android
Harmony
Typenumber·Default0
Initial index of Swiper, this value will only be used at firstScreen. Later updates will be ignored.
itemHeight
iOS
Android
Harmony
Typenumber | auto
Height of SwiperItem
itemWidth
iOS
Android
Harmony
Typenumber
Width of swiper item
loop
iOS
Android
Harmony
Typeboolean·Defaultfalse
Swiper loop back
loopDuplicateCount
iOS
Android
Harmony
Typenumber·Default2
When loop is true, Swiper will duplicate the first 2 items and last 2 items to create a loop effect. This prop can be used to customize how many items to duplicate the first and last item.
main-thread:customAnimation
iOS
Android
Harmony
Type(value: number, index: number) => CSSProperties
Custom animation effect, should be a MainThread function
main-thread:easing
iOS
Android
Harmony
Type(progress: number) => number
Custom easing function for paging effect
main-thread:onOffsetChange
iOS
Android
Harmony
Type(offset: number) => void
Callback fired when offset of Swiper changed. Should be a MainThread function
offsetLimit
iOS
Android
Harmony
Type[object Object]
Use this to limit or extend the offset of Swiper's range. This can be useful for limiting offset to avoid overscroll. For example, when mode === 'normal', and modeConfig.align === 'start', swipe to the last item technically means the last item's left edge align with container's left edge, leaving a blank area, which usually is not what we want. So we add an offsetLimit of [0, containerWidth - itemWidth], to limit the offset of Swiper. In this case, when swipe to the end, the last item's right edge align with container's right edge, leaving no blank area.
onChange
iOS
Android
Harmony
Type(current: number) => void
Callback fired when currentIndex of Swiper has changed
onSwipeStart
iOS
Android
Harmony
Type(current: number) => void
Callback fired when swiper started to swipe. Can be used with onSwipeStop. This is useful for disabling clicking when swiping.
onSwipeStop
iOS
Android
Harmony
Type(current: number) => void
Callback fired when swiper stopped to swipe. Can be used with onSwipeStart. This is useful for disabling clicking when swiping.
resetOnReuse
iOS
Android
Harmony
Typeboolean·Defaultfalse
Whether to reset Swiper progress and state when reuse Swiper Component. Can be useful when used in list.
RTL
iOS
Android
Harmony
Typeboolean | lynx-rtl·Defaultfalse
Whether to enable RTL mode.
style
iOS
Android
Harmony
TypeCSSProperties
Style for the root element of the Swiper component. This controls the visible viewport/frame that contains the swiper. Use this for: background, borders, padding, dimensions, overflow, etc.
swiperKey
iOS
Android
Harmony
Typeunknown
key of Swiper Component. Change this will reset Swiper progress and state. Can be used when reusing Swiper Component. Upon resting, initialIndex will be used again.
trackStyle
iOS
Android
Harmony
TypeCSSProperties
Style for the inner sliding track that holds all swiper items. This is the element that actually moves/slides.

RenderFunctionProps

index
Typenumber
Logical index of current SwiperItem in Swiper's data.
item
TypeT
Data item of current SwiperItem.
realIndex
Typenumber
Physical index of current SwiperItem. Kept for compatibility with existing manual SwiperItem wiring. SwiperItem receives this automatically when rendered inside Swiper's children function.

BounceConfig

enable
iOS
Android
Harmony
Typeboolean·Defaultfalse
Whether to enable bounces. Ignored when loop is true.
endBounceItem
iOS
Android
Harmony
TypeReactElement
The right bounceItem (when in horizontal)
endBounceItemWidth
iOS
Android
Harmony
Typenumber·Default100
Width of bounceItem. When overscroll the bounces, you will have larger and larger resistance, to make overscroll not exceed bounceItemWidth
onEndBounceItemBounce
iOS
Android
Harmony
Type(bounceParams: {offset: number, type: start | end}) => void
····· ·· When endBounceItem is in bounce state, releasing finger will call this.
onStartBounceItemBounce
iOS
Android
Harmony
Type(bounceParams: {offset: number, type: start | end}) => void
When startBounceItem is in bounce state, releasing finger will call this.
startBounceItem
iOS
Android
Harmony
TypeReactElement
The left bounceItem (when in horizontal)
startBounceItemWidth
iOS
Android
Harmony
Typenumber·Default100
Width of bounceItem. When overscroll the bounces, you will have larger and larger resistance, to make overscroll not exceed bounceItemWidth

onBounceParams

offset
Typenumber
type
Typestart | end

SwipeToOptions

animate
Typeboolean
onFinished
Type() => void

SwiperRef

cancelAnimation
iOS
Android
Harmony
Type() => void
Cancel Current Running Animation. Use with caution, may break internal states.
swipeNext
iOS
Android
Harmony
Type() => void
Swiper to next item
swipePrev
iOS
Android
Harmony
Type() => void
Swiper to previous item
swipeTo
iOS
Android
Harmony
Type(index: number, options: {animate?: boolean, onFinished?: () => void}) => void
SwiperTo item of index

Advanced Usage

Use the advanced APIs when the default slide layout is not enough. customAnimation lets each item respond to swipe progress, while mode decides whether Swiper places items for you or leaves placement to your animation function.

Understanding customAnimation

type customAnimation = (value: number, index: number) => CSSProperties

customAnimation is a main thread function. While Swiper is scrolling, each SwiperItem receives its distance from the active item and returns the style it should use for that frame.

The function parameter value represents the distance of this <SwiperItem> relative to the selected <SwiperItem>.

In this example, when <Swiper>'s progress is 2:

  • <SwiperItem>-2 receives a value of 0
  • <SwiperItem>-1 receives a value of -1
  • <SwiperItem>-3 receives a value of 1

Furthermore, when <Swiper>'s progress is updated to 3:

  • <SwiperItem>-2 receives a value of -1
  • <SwiperItem>-1 receives a value of -2
  • <SwiperItem>-3 receives a value of 0

Use this value as a stable input for interpolation. For example, 0 is the active item, -1 is the previous item, and 1 is the next item.

Practice with customAnimation

This pattern is useful when Swiper should keep its normal layout but the items need visual treatment such as scale, opacity, or rotation.

Understanding mode

<Swiper> supports two mode options: normal and custom. Their differences are as follows:

mode='normal'

  • <SwiperItem>s are arranged sequentially in the direction

  • Provides center alignment, right alignment, and other capabilities through modeConfig mode='custom'

  • The position of <SwiperItem> needs to be specified through customAnimation

  • Offers higher customization capabilities

To summarize:

  • normal mode handles the position of <SwiperItem>s, making it more suitable for horizontal sliding scenarios and easier to use
  • custom mode requires manual position calculation but offers higher extensibility

Practice with customAnimation when mode='custom'

Use custom mode when item placement itself is part of the design. In this mode, the animation function should return both position and visual style.

Except as otherwise noted, this work is licensed under a Creative Commons Attribution 4.0 International License, and code samples are licensed under the Apache License 2.0.