1
2
3
4
5
Installation
npx @park-ui/cli add carouselAdd Component
Copy the code snippet below into you components folder.
'use client'
import { Carousel, useCarouselContext } from '@ark-ui/react/carousel'
import { type ComponentProps, forwardRef } from 'react'
import { createStyleContext } from 'styled-system/jsx'
import { carousel } from 'styled-system/recipes'
const { withProvider, withContext } = createStyleContext(carousel)
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider(Carousel.Root, 'root', {
forwardProps: ['page'],
defaultProps: { spacing: '16px' },
})
export const RootProvider = withProvider(Carousel.RootProvider, 'root')
export const AutoplayTrigger = withContext(Carousel.AutoplayTrigger, 'autoplayTrigger')
export const Control = withContext(Carousel.Control, 'control')
export const Indicator = withContext(Carousel.Indicator, 'indicator')
export const Item = withContext(Carousel.Item, 'item')
export const ItemGroup = withContext(Carousel.ItemGroup, 'itemGroup')
export const NextTrigger = withContext(Carousel.NextTrigger, 'nextTrigger')
export const PrevTrigger = withContext(Carousel.PrevTrigger, 'prevTrigger')
const StyledIndicatorGroup = withContext(Carousel.IndicatorGroup, 'indicatorGroup')
export const IndicatorGroup = forwardRef<
HTMLDivElement,
ComponentProps<typeof StyledIndicatorGroup>
>((props, ref) => {
const carousel = useCarouselContext()
return (
<StyledIndicatorGroup {...props} ref={ref}>
{carousel.pageSnapPoints.map((_, index) => (
<Indicator key={index} index={index} />
))}
</StyledIndicatorGroup>
)
})
export { CarouselContext as Context } from '@ark-ui/react/carousel'
Integrate Recipe
Integrate this recipe in to your Panda config.
import { carouselAnatomy } from '@ark-ui/react/carousel'
import { defineSlotRecipe } from '@pandacss/dev'
export const carousel = defineSlotRecipe({
className: 'carousel',
slots: carouselAnatomy.keys(),
base: {
root: {
position: 'relative',
display: 'flex',
flexDirection: 'column',
gap: '2',
_vertical: {
flexDirection: 'row',
},
},
control: {
alignItems: 'center',
justifyContent: 'space-between',
borderRadius: 'l2',
display: 'flex',
_vertical: {
flexDirection: 'column',
},
},
itemGroup: {
flex: '1',
},
indicatorGroup: {
display: 'flex',
_vertical: {
flexDirection: 'column',
},
},
indicator: {
borderRadius: 'full',
background: 'gray.subtle.bg',
cursor: 'pointer',
_current: {
background: 'colorPalette.solid.bg',
},
focusVisibleRing: 'outside',
},
},
defaultVariants: {
size: 'md',
},
variants: {
inline: {
true: {
control: {
background: { _light: 'white.a11', _dark: 'black.a11' },
bottom: '3',
left: '50%',
p: '1',
position: 'absolute',
transform: 'translateX(-50%)',
},
},
},
size: {
md: {
control: {
gap: '3',
},
indicatorGroup: {
gap: '3',
},
indicator: {
boxSize: '2.5',
},
},
},
},
})
Usage
import { Carousel } from '@/components/ui'
<Carousel.Root>
<Carousel.ItemGroup>
<Carousel.Item />
</Carousel.ItemGroup>
<Carousel.Control>
<Carousel.PrevTrigger/>
<Carousel.IndicatorGroup>
<Carousel.Indicator />
</Carousel.IndicatorGroup>
<Carousel.NextTrigger />
</Carousel.Control>
</Carousel.Root>
Shortcuts
IndicatorGroup
The Carousel.IndicatorGroup automatically renders indicators for each page. Instead of:
<Carousel.IndicatorGroup>
<Carousel.Indicator index={0} />
<Carousel.Indicator index={1} />
{/* ... */}
</Carousel.IndicatorGroup>
If you don't need to customize the indicators, you can use the shortcut:
<Carousel.IndicatorGroup />
Examples
Multiple
Set the slidesPerPage prop to show multiple items per page.
1
2
3
4
5
6
7
8
9
10
Auto Play
Set the autoPlay prop to enable automatic sliding.
1
2
3
4
5
Images
Here is an example of a carousel displaying images.
Vertical
Set the orientation prop to vertical to create a vertical carousel.
1
2
3
4
5
Scroll To
Use the scrollTo method to programmatically navigate to a specific slide.
1
2
3
4
5
Props
Root
| Prop | Default | Type |
|---|---|---|
slideCount* | numberThe total number of slides. Useful for SSR to render the initial ating the snap points. | |
size | 'md' | 'md' |
allowMouseDrag | false | booleanWhether to allow scrolling via dragging with mouse |
autoplay | false | boolean | { delay: number }Whether to scroll automatically. The default delay is 4000ms. |
defaultPage | 0 | numberThe initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. |
inViewThreshold | 0.6 | number | number[]The threshold for determining if an item is in view. |
loop | false | booleanWhether the carousel should loop around. |
orientation | \horizontal\ | 'horizontal' | 'vertical'The orientation of the element. |
slidesPerMove | \auto\ | number | 'auto'The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. |
slidesPerPage | 1 | numberThe number of slides to show at a time. |
snapType | \mandatory\ | 'proximity' | 'mandatory'The snap type of the item. |
spacing | \0px\ | stringThe amount of space between items. |
inline | boolean | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. | |
ids | Partial<{
root: string
item: (index: number) => string
itemGroup: string
nextTrigger: string
prevTrigger: string
indicatorGroup: string
indicator: (index: number) => string
}>The ids of the elements in the carousel. Useful for composition. | |
onAutoplayStatusChange | (details: AutoplayStatusDetails) => voidFunction called when the autoplay status changes. | |
onDragStatusChange | (details: DragStatusDetails) => voidFunction called when the drag status changes. | |
onPageChange | (details: PageChangeDetails) => voidFunction called when the page changes. | |
padding | stringDefines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | |
page | numberThe controlled page of the carousel. | |
translations | IntlTranslationsThe localized messages to use. |
Indicator
| Prop | Default | Type |
|---|---|---|
index* | numberThe index of the indicator. | |
readOnly | false | booleanWhether the indicator is read only. |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. |
Item
| Prop | Default | Type |
|---|---|---|
index* | numberThe index of the item. | |
snapAlign | \start\ | 'center' | 'start' | 'end'The snap alignment of the item. |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. |