A flexible and accessible carousel component for displaying content in a scrollable container.
npm install @pallas-ui/carousel'use client'
import * as CarouselPrimitive from '@pallas-ui/carousel'
import { type Assign, type WithFixedClassName, createStyleContext } from '@pallas-ui/style-context'
import { cx } from '@styled-system/css'
import { type CarouselVariantProps, button, carousel } from '@styled-system/recipes'
import type { ComponentProps, JsxStyleProps } from '@styled-system/types'
import * as React from 'react'
import type { ButtonProps } from '../button'
const { withProvider, withContext } = createStyleContext(carousel)
export type RootProps = Assign<
WithFixedClassName<CarouselPrimitive.CarouselRootProps>,
JsxStyleProps & CarouselVariantProps
>
export type PreviousProps = Assign<
ComponentProps<typeof CarouselPrimitive.Previous>,
JsxStyleProps & ButtonProps
>
export type NextProps = Assign<
ComponentProps<typeof CarouselPrimitive.Next>,
JsxStyleProps & ButtonProps
>
export const Root = withProvider<React.ComponentRef<typeof CarouselPrimitive.Root>, RootProps>(
CarouselPrimitive.Root,
'root',
)
export const List = withContext<
React.ComponentRef<typeof CarouselPrimitive.List>,
Assign<ComponentProps<typeof CarouselPrimitive.List>, JsxStyleProps>
>(CarouselPrimitive.List, 'list')
export const Item = withContext<
React.ComponentRef<typeof CarouselPrimitive.Item>,
Assign<ComponentProps<typeof CarouselPrimitive.Item>, JsxStyleProps>
>(CarouselPrimitive.Item, 'item')
const PreviousButton = React.forwardRef<
React.ComponentRef<typeof CarouselPrimitive.Previous>,
PreviousProps
>((props, ref) => {
const [buttonProps, { className, children, ...restProps }] = button.splitVariantProps(props)
return (
<CarouselPrimitive.Previous
ref={ref}
className={cx(button({ variant: 'text', ...buttonProps }), className)}
{...restProps}
>
{children}
</CarouselPrimitive.Previous>
)
})
export const Previous = withContext<
React.ComponentRef<typeof CarouselPrimitive.Previous>,
PreviousProps
>(PreviousButton, 'previous')
const NextButton = React.forwardRef<
React.ComponentRef<typeof CarouselPrimitive.Next>,
PreviousProps
>((props, ref) => {
const [buttonProps, { className, children, ...restProps }] = button.splitVariantProps(props)
return (
<CarouselPrimitive.Next
ref={ref}
className={cx(button({ variant: 'text', ...buttonProps }), className)}
{...restProps}
>
{children}
</CarouselPrimitive.Next>
)
})
export const Next = withContext<React.ComponentRef<typeof CarouselPrimitive.Next>, NextProps>(
NextButton,
'next',
)
export const Dots = withContext<
React.ComponentRef<typeof CarouselPrimitive.Dots>,
Assign<ComponentProps<typeof CarouselPrimitive.Dots>, JsxStyleProps>
>(CarouselPrimitive.Dots, 'dots')
export const Dot = withContext<
React.ComponentRef<typeof CarouselPrimitive.Dot>,
Assign<CarouselPrimitive.CarouselDotProps, JsxStyleProps>
>(CarouselPrimitive.Dot, 'dot')
const Carousel = {
Root,
List,
Item,
Previous,
Next,
Dots,
Dot,
useCarousel: CarouselPrimitive.useCarousel,
}
export default Carouselimport Carousel from '@/components/ui/carousel'<Carousel.Root opts={{ axis: 'x' }}>
<Carousel.List>
<Carousel.Item>
<div>Slide 1</div>
</Carousel.Item>
<Carousel.Item>
<div>Slide 2</div>
</Carousel.Item>
</Carousel.List>
<Carousel.Previous>
<ChevronLeft />
</Carousel.Previous>
<Carousel.Next>
<ChevronRight />
</Carousel.Next>
<Carousel.Dots>
<Carousel.Dot index={0} />
<Carousel.Dot index={1} />
</Carousel.Dots>
</Carousel.Root>The root carousel element that wraps the entire component.
Props:
opts - CarouselOptions - Configuration options for the carouselplugins - CarouselPlugin[] - Array of plugins to usesetApi - function - Callback to receive the carousel APIorientation - 'horizontal' | 'vertical' - Orientation of the carousel (default: 'horizontal')The container that holds all carousel items.
Individual carousel slide/item.
Button to navigate to the previous slide.
Props:
asChild - boolean - Whether to render as a child element (default: false)Button to navigate to the next slide.
Props:
asChild - boolean - Whether to render as a child element (default: false)Container for dot indicators.
Individual dot indicator.
Props:
index - number - The index of the slide this dot representsasChild - boolean - Whether to render as a child element (default: false)Hook to access carousel context and methods.
Returns:
carouselRef - Ref for the carousel containerapi - Carousel API instancescrollPrev - Function to scroll to previous slidescrollNext - Function to scroll to next slidecanScrollPrev - boolean - Whether previous slide is availablecanScrollNext - boolean - Whether next slide is availableonDotButtonClick - Function to handle dot clicksselectedIndex - number - Currently selected slide indexscrollSnaps - number[] - Array of snap points