ReScript Shadcn
Get started
  • Installation
Components
  • Accordion
  • Alert
  • AlertDialog
  • AspectRatio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • ButtonGroup
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • ContextMenu
  • DataTable
  • DatePicker
  • Dialog
  • Direction
  • Drawer
  • DropdownMenu
  • Empty
  • Field
  • HoverCard
  • Input
  • InputGroup
  • InputOtp
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • MessageScroller
  • NativeSelect
  • NavigationMenu
  • Pagination
  • Popover
  • Progress
  • RadioGroup
  • Resizable
  • ScrollArea
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • ToggleGroup
  • Tooltip
  • Typography

Carousel

A carousel with motion and swipe built using Embla.

1
2
3
4
5

About#

The carousel component is built using the Embla Carousel library.

Installation#

npx shadcn@latest add @rescript-shadcn/Carousel

Usage#

<Carousel>
  <Carousel.Content>
    <Carousel.Item> {"..."->React.string} </Carousel.Item>
    <Carousel.Item> {"..."->React.string} </Carousel.Item>
    <Carousel.Item> {"..."->React.string} </Carousel.Item>
  </Carousel.Content>
  <Carousel.Previous />
  <Carousel.Next />
</Carousel>

Examples#

Sizes#

To set the size of the items, you can use the basis utility class on the <CarouselItem />.

1
2
3
4
5
// 33% of the carousel width.
<Carousel>
  <CarouselContent>
    <CarouselItem className="basis-1/3">...</CarouselItem>
    <CarouselItem className="basis-1/3">...</CarouselItem>
    <CarouselItem className="basis-1/3">...</CarouselItem>
  </CarouselContent>
</Carousel>
// 50% on small screens and 33% on larger screens.
<Carousel>
  <CarouselContent>
    <CarouselItem className="md:basis-1/2 lg:basis-1/3">...</CarouselItem>
    <CarouselItem className="md:basis-1/2 lg:basis-1/3">...</CarouselItem>
    <CarouselItem className="md:basis-1/2 lg:basis-1/3">...</CarouselItem>
  </CarouselContent>
</Carousel>

Spacing#

To set the spacing between the items, we use a pl-[VALUE] utility on the <CarouselItem /> and a negative -ml-[VALUE] on the <CarouselContent />.

1
2
3
4
5
<Carousel>
  <CarouselContent className="-ml-4">
    <CarouselItem className="pl-4">...</CarouselItem>
    <CarouselItem className="pl-4">...</CarouselItem>
    <CarouselItem className="pl-4">...</CarouselItem>
  </CarouselContent>
</Carousel>
<Carousel>
  <CarouselContent className="-ml-2 md:-ml-4">
    <CarouselItem className="pl-2 md:pl-4">...</CarouselItem>
    <CarouselItem className="pl-2 md:pl-4">...</CarouselItem>
    <CarouselItem className="pl-2 md:pl-4">...</CarouselItem>
  </CarouselContent>
</Carousel>

Orientation#

Use the orientation prop to set the orientation of the carousel.

1
2
3
4
5
<Carousel orientation=Vertical>
  <CarouselContent>
    <CarouselItem>...</CarouselItem>
    <CarouselItem>...</CarouselItem>
    <CarouselItem>...</CarouselItem>
  </CarouselContent>
</Carousel>

Options#

You can pass options to the carousel using the opts prop. See the Embla Carousel docs for more information.

<Carousel
  opts={{
    align: "start",
    loop: true,
  }}
>
  <CarouselContent>
    <CarouselItem>...</CarouselItem>
    <CarouselItem>...</CarouselItem>
    <CarouselItem>...</CarouselItem>
  </CarouselContent>
</Carousel>

API#

Use a state and the setApi props to get an instance of the carousel API.

1
2
3
4
5
Slide 0 of 0
@react.component
let make = () => {
  const (api, setApi) = React.useState(() => None)
  const (current, setCurrent) = React.useState(() => 0)
  const (count, setCount) = React.useState(() => 0)
 
  React.useEffect(() => {
    api->Option.forEach(api => {
      setCount(_ => api->Carousel.Api.scrollSnapList->Array.length)
      setCurrent(_ => api->Carousel.Api.selectedScrollSnap + 1)
      api->Carousel.Api.on("select", () => {
        setCurrent(_ => api->Carousel.Api.selectedScrollSnap + 1)
      })
    })
    None
  }, [api])
 
  <Carousel setApi={api => setApi(_ => api)}>
    <Carousel.Content>
      <Carousel.Item>...</Carousel.Item>
      <Carousel.Item>...</Carousel.Item>
      <Carousel.Item>...</Carousel.Item>
    </Carousel.Content>
  </Carousel>
}

Events#

You can listen to events using the api instance from setApi.

module Example = {
  @react.component
  let make = () => {
    let (api, setApi) = React.useState(() => None)
 
    React.useEffect(() => {
 
      api->Option.forEach(api => api->Carousel.Api.on("select", api => {
        // Do something on select.
      }))
      None
    }, [api])
 
    <Carousel setApi={setApi}>
      <CarouselContent>
        <CarouselItem>...</CarouselItem>
        <CarouselItem>...</CarouselItem>
        <CarouselItem>...</CarouselItem>
      </CarouselContent>
    </Carousel>
    }
}

See the Embla Carousel docs for more information on using events.

Plugins#

You can use the plugins prop to add plugins to the carousel.

type autoplayOptions = {delay: int}
@module("embla-carousel-autoplay")
external autoplay: autplayOptions => Carousel.emblaPlugin = "default"
 
module Example = {
  @react.component
  let make = () => {
    <Carousel
      plugins={[
        autoplay({
          delay: 2000,
        }),
      ]}
    >
      // ...
    </Carousel>
  }
}
1
2
3
4
5

API Reference#

See the Embla Carousel docs for more information on props and plugins.

@@directive("'use client'")

@react.component
@react.component
let make = () =>
  <Carousel className="w-full max-w-[12rem] sm:max-w-xs">
@react.component
let make = () =>
  <Carousel opts={align: "start"} className="w-full max-w-[12rem] sm:max-w-xs md:max-w-sm">
@react.component
let make = () =>
  <Carousel
@@directive("'use client'")

type autoplayOptions = {delay: int, stopOnInteraction: bool}
@react.component
let make = () =>
  <Carousel className="w-full max-w-[12rem] sm:max-w-xs md:max-w-sm">