nori-ui

Carousel

Paged horizontal (or vertical) image/card slider with CSS scroll-snap on web and FlatList paging on native.

1.8 kBgzipped

At a glance

  • Compound API: Carousel, Carousel.Content, Carousel.Item, Carousel.Previous, Carousel.Next, Carousel.Dots.
  • Web: CSS scroll-snap-type: x mandatory — no extra dependency.
  • Native: RN FlatList with pagingEnabled — no carousel peer dep.
  • Controlled or uncontrolled via index / defaultIndex.
  • loop prop wraps navigation from last slide back to first and vice versa.

Preview

Usage

import { Carousel } from '@nori-ui/core';
 
export function MyCarousel() {
    return (
        <Carousel>
            <Carousel.Content>
                <Carousel.Item>
                    <img src="/slide1.jpg" alt="Slide 1" />
                </Carousel.Item>
                <Carousel.Item>
                    <img src="/slide2.jpg" alt="Slide 2" />
                </Carousel.Item>
                <Carousel.Item>
                    <img src="/slide3.jpg" alt="Slide 3" />
                </Carousel.Item>
            </Carousel.Content>
            <Carousel.Previous />
            <Carousel.Next />
            <Carousel.Dots />
        </Carousel>
    );
}

Controlled

import { useState } from 'react';
import { Carousel } from '@nori-ui/core';
 
export function ControlledCarousel() {
    const [index, setIndex] = useState(0);
    return (
        <Carousel index={index} onIndexChange={setIndex}>
            <Carousel.Content>
                <Carousel.Item><SlideA /></Carousel.Item>
                <Carousel.Item><SlideB /></Carousel.Item>
            </Carousel.Content>
            <Carousel.Dots />
        </Carousel>
    );
}

Looping

Set loop to wrap from the last slide back to the first when pressing Next, and vice versa:

<Carousel loop>
  <Carousel.Content>
    <Carousel.Item>...</Carousel.Item>
    <Carousel.Item>...</Carousel.Item>
  </Carousel.Content>
  <Carousel.Previous />
  <Carousel.Next />
</Carousel>

Platform notes

Web: Each Carousel.Item has scroll-snap-align: start and min-width: 100%. The scrollbar is hidden via scrollbar-width: none. Previous/Next buttons call scrollIntoView with behavior: smooth.

Native: Carousel.Content renders an RN FlatList with pagingEnabled and horizontal. Each item gets width: windowWidth. The item list passed as children to Carousel.Content is unwrapped by the FlatList renderer — Carousel.Item on native is just a thin View wrapper.

Props

PropTypeDefaultDescription
classNamestring
defaultIndexnumber0Initial index (uncontrolled). @defaultValue 0
indexnumberControlled current index.
loopbooleanfalseWhether navigation wraps from last to first and vice-versa. @defaultValue false
onIndexChange(index: number) => voidFires with the new index.
orientationenumhorizontalScroll axis. @defaultValue 'horizontal'
testIDstring

Carousel.Content

Scrollable or FlatList container that holds the Carousel.Item children. Passes the orientation prop down to determine scroll axis (horizontal by default, vertical for a vertical stack). On web it renders a scroll-snap container; on native it wraps an RN FlatList with pagingEnabled.

Carousel.Item

Single slide wrapper. Accepts children and an optional className. Each item fills the full width (or height, in vertical mode) of the viewport.

Carousel.Previous / Carousel.Next

Navigation button that steps the index backward (Previous) or forward (Next). Accepts children for custom icon content and an aria-label for screen-reader text. Automatically disabled at the boundary unless loop is set on the root.

Carousel.Dots

Indicator track that renders one dot per slide. Accepts className for custom styles. The active dot is highlighted; each dot has an accessible aria-label="Slide N" attribute. Clicking a dot jumps directly to that slide.

On this page

Preview theme