Carousel scrolls a row of items horizontally when they overflow the available width. Use it for card grids, image galleries, product lists, or any set of items that should be browsable without taking up the full page.
Preview loads on approachPreview loads on approach
Exact source · carousel-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.
'use client';
import {Carousel} from '@astryxdesign/core/Carousel';
import {Card} from '@astryxdesign/core/Card';
import {Stack} from '@astryxdesign/core/Layout';
import {Text, Heading} from '@astryxdesign/core/Text';
const ITEMS = [
{title: 'Design', body: 'Create wireframes and prototypes.'},
{title: 'Develop', body: 'Build components and pages.'},
{title: 'Test', body: 'Write tests and fix bugs.'},
{title: 'Deploy', body: 'Ship to production.'},
{title: 'Monitor', body: 'Track performance and errors.'},
];
export default function CarouselShowcase() {
return (
<Carousel
gap={2}
hasSnap
hasButtons={false}
aria-label="Workflow steps"
style={{maxWidth: 500}}>
{ITEMS.map(item => (
<Card key={item.title} padding={3} style={{minWidth: 200}}>
<Stack direction="vertical" gap={1}>
<Heading level={5}>{item.title}</Heading>
<Text type="supporting" color="secondary">
{item.body}
</Text>
</Stack>
</Card>
))}
</Carousel>
);
}
Usage
Carousel scrolls a row of items horizontally when they overflow the available width. Use it for card grids, image galleries, product lists, or any set of items that should be browsable without taking up the full page.
Enable scroll-snap when each item should land precisely at the start edge, like a gallery or product list.
Reach for hasLoop on small, cyclable sets like a photo gallery, where wrapping past the last item back to the first feels natural.
Always provide an aria-label that describes what the carousel contains, like "Featured products" or "Team members".
Carousel implements the WAI-ARIA APG carousel pattern (https://www.w3.org/WAI/ARIA/apg/patterns/carousel/) without auto-rotation: the region is labelled and carries aria-roledescription="carousel", each item is a group named "Slide N of M", and the scroll container is a tab stop so keyboard users can pan it with the arrow keys.
Use a consistent gap and item width so the carousel looks intentional, not like content overflowing by accident.
Trust the built-in navigation: trackpad users can swipe horizontally, and mouse users can hold Shift while scrolling the wheel to move through items.
Use a carousel for content every user must see. Not everyone scrolls horizontally, so put critical content above the fold.
Auto-advance items. Let the user scroll at their own pace.
Nest carousels. A carousel inside a carousel is confusing and breaks keyboard navigation.
Typed props
Prop
Type and behavior
children
ReactNode · required
Carousel items rendered in a horizontal scroll container.
gap
0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 · default 1
Gap between items using the spacing token scale.
hasButtons
boolean · default true
Show prev/next navigation buttons when content is scrollable.
hasEdgeFade
boolean · default true
Show a gradient edge-fade mask when content overflows, signalling that more items exist off-screen.
hasLoop
boolean · default false
Wrap-around scrolling: next at the end scrolls to the start, prev at the start scrolls to the end. Buttons stay visible at both edges. Only engages when content overflows.
hasSnap
boolean · default false
Enable scroll-snap so each child snaps to the start edge.
padding
0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10
Inline padding inside the scroll container, with matching scroll-padding so snap points align to the content edge.
aria-label
string · default 'Carousel'
Accessible label for the carousel region.
ref
React.Ref<HTMLDivElement>
Ref forwarded to the root element.
handleRef
React.Ref<CarouselHandle>
Imperative handle exposing scrollNext(), scrollPrev(), scrollTo(index), canScrollNext(), and canScrollPrev() for programmatic scroll control.
xstyle
StyleXStyles
StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value.
className
string
CSS class name for the root element. Prefer xstyle for styling.
style
CSSProperties
Inline styles for the root element. Prefer xstyle.
data-testid
string
Test selector for automated testing frameworks.
Anatomy
Scroll container · required
The horizontal overflow area that holds all items.
Items · required
The children rendered in a row inside the scroll container. With hasSnap, each item snaps to the start edge.
Fade edges · optional
Gradient fades on the left and right edges that indicate more content is available. Enabled by default, disable with hasEdgeFade={false}.
Navigation buttons · optional
Prev/next buttons that appear when the content can scroll in that direction. Enabled by default, disable with hasButtons={false}.