laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
130 lines (103 loc) • 4.47 kB
Markdown
A flexible, accessible carousel built on Embla. Supports horizontal/vertical orientation, previous/next controls, keyboard navigation, and responsive layouts.
---
| Prop | Type | Default | Description |
| -------------- | -------------------------------------- | -------------- | -------------------------------------------------- |
| `orientation` | `"horizontal" | "vertical"` | `"horizontal"` | Scroll axis for the carousel. |
| `opts` | `EmblaOptionsType` | `{}` | Embla options (e.g., loop). |
| `plugins` | `EmblaPluginType[]` | `[]` | Embla plugins. |
| `setApi` | `(api: CarouselApi) => void` | `undefined` | Receives the Embla API instance. |
| `className` | `string` | `""` | Additional classes for the container. |
| `children` | `React.ReactNode` | **required** | Compose with subcomponents below. |
- `CarouselContent`: Scroll container (wraps slides).
- `CarouselItem`: A single slide.
- `CarouselPrevious`: Previous button (disabled when not scrollable).
- `CarouselNext`: Next button (disabled when not scrollable).
---
## Behavior
- **Keyboard**: Left/Right arrows move slides (when horizontal).
- **Controls**: Prev/Next buttons enable/disable based on scroll availability.
- **Orientation**: Vertical orientation rotates controls appropriately.
---
## Examples
### Basic
```tsx
import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext } from "laif-ds";
import { Card, CardContent } from "laif-ds";
export function BasicCarousel() {
return (
<Carousel className="w-full max-w-xs">
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-xl font-semibold">{index + 1}</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
```
```tsx
import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext } from "laif-ds";
import { Card, CardContent } from "laif-ds";
export function MultipleItems() {
return (
<Carousel className="w-full max-w-md">
<CarouselContent className="-ml-1">
{Array.from({ length: 10 }).map((_, index) => (
<CarouselItem key={index} className="pl-1 md:basis-1/2 lg:basis-1/3">
<div className="p-1">
<Card>
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-lg font-semibold">{index + 1}</span>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
```
```tsx
import { useState } from "react";
import type { CarouselApi } from "laif-ds";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "laif-ds";
export function CarouselWithApi() {
const [api, setApi] = useState<CarouselApi | null>(null);
return (
<Carousel className="w-full max-w-xs" setApi={setApi} opts={{ loop: true }}>
<CarouselContent>
{[1, 2, 3, 4, 5].map((n) => (
<CarouselItem key={n}><div className="p-6">Slide {n}</div></CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
);
}
```
---
- **Focus**: The root handles arrow keys via `onKeyDownCapture`.
- **Responsiveness**: Use `basis-*` utilities on `CarouselItem` for multi-column layouts.
- **Plugins**: Pass Embla plugins via `plugins` prop when needed.