- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Menubar
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- Typography
About#
The carousel component is built using the Embla Carousel library.
Installation#
pnpm dlx shadcn@latest add @force-ui-svelte/carousel
Usage#
<script lang="ts">
import * as Carousel from "$lib/components/ui/carousel/index.js";
</script><Carousel.Root>
<Carousel.Content>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
</Carousel.Content>
<Carousel.Previous />
<Carousel.Next />
</Carousel.Root>Composition#
Use the following composition to build a Carousel:
Carousel.Root
├── Carousel.Content
│ ├── Carousel.Item
│ └── Carousel.Item
├── Carousel.Previous
└── Carousel.NextExamples#
Sizes#
To set the size of the items, you can use the basis utility class on the <Carousel.Item />.
<Carousel.Root>
<Carousel.Content>
<Carousel.Item class="basis-1/3">...</Carousel.Item>
<Carousel.Item class="basis-1/3">...</Carousel.Item>
<Carousel.Item class="basis-1/3">...</Carousel.Item>
</Carousel.Content>
</Carousel.Root><Carousel.Root>
<Carousel.Content>
<Carousel.Item class="md:basis-1/2 lg:basis-1/3">...</Carousel.Item>
<Carousel.Item class="md:basis-1/2 lg:basis-1/3">...</Carousel.Item>
<Carousel.Item class="md:basis-1/2 lg:basis-1/3">...</Carousel.Item>
</Carousel.Content>
</Carousel.Root>Spacing#
To set the spacing between the items, we use a pl-[VALUE] utility on the <Carousel.Item /> and a negative -ml-[VALUE] on the <Carousel.Content />.
<Carousel.Root>
<Carousel.Content class="-ml-4">
<Carousel.Item class="pl-4">...</Carousel.Item>
<Carousel.Item class="pl-4">...</Carousel.Item>
<Carousel.Item class="pl-4">...</Carousel.Item>
</Carousel.Content>
</Carousel.Root><Carousel.Root>
<Carousel.Content class="-ml-2 md:-ml-4">
<Carousel.Item class="pl-2 md:pl-4">...</Carousel.Item>
<Carousel.Item class="pl-2 md:pl-4">...</Carousel.Item>
<Carousel.Item class="pl-2 md:pl-4">...</Carousel.Item>
</Carousel.Content>
</Carousel.Root>Orientation#
Use the orientation prop to set the orientation of the carousel.
<Carousel.Root orientation="vertical | horizontal">
<Carousel.Content>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
</Carousel.Content>
</Carousel.Root>Options#
You can pass options to the carousel using the opts prop. See the Embla Carousel docs for more information.
<Carousel.Root
opts={{
align: "start",
loop: true,
}}
>
<Carousel.Content>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
</Carousel.Content>
</Carousel.Root>API#
Use reactive state and the setApi callback to get an instance of the carousel API.
<script lang="ts">
import { type CarouselAPI } from "$lib/components/ui/carousel/context.js";
import * as Carousel from "$lib/components/ui/carousel/index.js";
let api = $state<CarouselAPI>();
let current = $state(0);
const count = $derived(api ? api.scrollSnapList().length : 0);
$effect(() => {
if (api) {
current = api.selectedScrollSnap() + 1;
api.on("select", () => {
current = api!.selectedScrollSnap() + 1;
});
}
});
</script>
<Carousel.Root setApi={(emblaApi) => (api = emblaApi)}>
<Carousel.Content>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
</Carousel.Content>
</Carousel.Root>Events#
You can listen to events using the api instance from setApi.
<script lang="ts">
import { type CarouselAPI } from "$lib/components/ui/carousel/context.js";
import * as Carousel from "$lib/components/ui/carousel/index.js";
let api = $state<CarouselAPI>();
$effect(() => {
if (api) {
api.on("select", () => {
// do something
});
}
});
</script>
<Carousel.Root setApi={(emblaApi) => (api = emblaApi)}>
<Carousel.Content>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
</Carousel.Content>
</Carousel.Root>See the Embla Carousel docs for more information on using events.
Plugins#
You can use the plugins prop to add plugins to the carousel.
<script lang="ts">
import Autoplay from "embla-carousel-autoplay";
import * as Carousel from "$lib/components/ui/carousel/index.js";
</script>
<Carousel.Root
plugins={[
Autoplay({
delay: 2000,
}),
]}
>
</Carousel.Root>See the Embla Carousel docs for more information on using plugins.
RTL#
To enable RTL support in Force UI, see the RTL configuration guide.
When localizing the carousel for RTL languages, you need to set the direction option in the opts prop to match the text direction. This ensures the carousel scrolls in the correct direction.
<Carousel.Root
dir={dir}
opts={{
direction: dir,
}}
>
<Carousel.Content>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
<Carousel.Item>...</Carousel.Item>
</Carousel.Content>
<Carousel.Previous class="rtl:rotate-180" />
<Carousel.Next class="rtl:rotate-180" />
</Carousel.Root>The direction option accepts "ltr" or "rtl" and should match the dir prop value. You may also want to rotate the navigation buttons using the rtl:rotate-180 class to ensure they point in the correct direction.
API Reference#
See the Embla Carousel docs for more information on props and plugins.