Przejdź do treści

Carousel

Stabilny

Przewijany poziomo lub pionowo zestaw slajdów z nawigacją gestem przesunięcia, klawiaturą i przyciskami, zbudowany na Embla.

TokenyJedno źródło prawdy
KomponentyDomyślnie dostępne
WzorceSprawdzone kompozycje
MotywyDopasowane do twojej marki

Instalacja

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/carousel.json

Użycie

import {
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselNext,
  CarouselPrevious,
} from "@/components/ui/carousel"
<Carousel aria-label="Product screenshots">
  <CarouselContent>
    <CarouselItem></CarouselItem>
    <CarouselItem></CarouselItem>
    <CarouselItem></CarouselItem>
  </CarouselContent>
  <CarouselPrevious />
  <CarouselNext />
</Carousel>

Przyciski „poprzedni” i „następny” znajdują się poza slajdami, 48 px na lewo i na prawo od nich. Zostaw na nie miejsce — albo ustaw je samodzielnie przez className.

Przykłady

Kilka slajdów naraz

Szerokość slajdu ustawisz klasą basis-* na CarouselItem. Połącz ją z responsywnymi prefiksami, żeby na szerszych ekranach pokazać więcej slajdów, oraz z opts={{ align: "start" }}, żeby slajdy przyciągały się do krawędzi początkowej.

FakturaPozycje, podatek i sumy
Dziennik zmianDatowane wpisy z tagami
CennikTrzy plany i FAQ
E-mail powitalnyPięcioetapowa seria powitalna
Strona statusuDostępność i historia incydentów
Informacje o wydaniuNowości, poprawki, aktualizacje
Wiki zespołuZagnieżdżone strony z wyszukiwarką
<Carousel opts={{ align: "start" }}>
  <CarouselContent>
    <CarouselItem className="basis-1/2 sm:basis-1/3"></CarouselItem>
  </CarouselContent>
</Carousel>

Odstępy

Slajdy rozdziela padding na CarouselItem i dopasowany do niego ujemny margines na CarouselContent (domyślnie 16 px). Żeby zmienić odstęp, zmień oba: -ml-2 na treści i pl-2 na każdym elemencie.

Pionowa

orientation="vertical" przewija w osi Y. Nadaj CarouselContent stałą wysokość; przyciski przeniosą się nad i pod slajdy.

09:00
Przegląd makietStudio A
10:30
Synchronizacja tokenówZdalnie
12:00
Lunch & learn: animacjeAtrium
14:00
Audyt dostępnościStudio B
16:30
Planowanie wydaniaZdalnie

Z API

setApi przekazuje ci instancję Embla. Użyj jej, żeby zbudować licznik slajdów, kropki paginacji albo miniatury i reagować na zdarzenia select.

Pulpit
Ustawienia
Rozliczenia
Aktywność
Zespół
1 / 5
const [api, setApi] = React.useState<CarouselApi>()

React.useEffect(() => {
  if (!api) return
  const onSelect = () => setCurrent(api.selectedScrollSnap())
  api.on("select", onSelect)
  return () => {
    api.off("select", onSelect)
  }
}, [api])

<Carousel setApi={setApi}></Carousel>

Wytyczne

Kiedy używać

  • Do przeglądania zestawu równorzędnych elementów, gdy wystarczy widzieć kilka naraz: zrzutów ekranu, szablonów, zdjęć produktów, opinii klientów.
  • Na urządzeniach dotykowych, na których przesuwanie palcem po zestawie jest naturalne.

Kiedy nie używać

  • Do treści, którą każdy musi zobaczyć. Slajdy po pierwszym rzadko są oglądane — ważne informacje umieść bezpośrednio na stronie.
  • Do nawigacji lub porównywania — użyj komponentu Tabs, siatki albo komponentu Table.
  • Do pojedynczego obrazu w sekcji hero — po prostu pokaż ten obraz.

Pokaż, że jest więcej

Pozwól następnemu slajdowi wyglądać zza krawędzi, pokaż licznik albo kropki i zostaw przycisk „poprzedni” wyłączony na pierwszym slajdzie. Nikt nie powinien się zastanawiać, czy jest coś więcej.

1 / 4

Dobrze.Kontrolki i wskaźnik pozycji od razu pokazują, jak duży jest zestaw.
Następny slajd za 3 s…
Źle.Slajdy, które przewijają się same i nie mają kontrolek, zabierają treść, zanim ktoś skończy czytać.

Automatyczne przewijanie

prfct nie przewija slajdów automatycznie. Jeśli dodasz do Embla wtyczkę autoplay, wstrzymuj przewijanie po najechaniu kursorem i przy fokusie, dodaj widoczny przycisk pauzy i w ogóle nie włączaj automatycznego przewijania, gdy ustawione jest prefers-reduced-motion. Treść, która porusza się sama dłużej niż pięć sekund, musi dać się zatrzymać (WCAG 2.2.2).

Dostępność

Karuzela to regionaria-roledescription="carousel", a każdy slajd to grouparia-roledescription="slide".

KlawiszDziałanie
Tab
Przenosi fokus do slajdów oraz na przyciski „poprzedni” i „następny”.
Przewija do poprzedniego slajdu, gdy fokus jest wewnątrz karuzeli.
Przewija do następnego slajdu, gdy fokus jest wewnątrz karuzeli.
EnterSpacja
Aktywuje przycisk „poprzedni” lub „następny”, na którym jest fokus.
  • Nazwij karuzelę. Nadaj Carousel atrybut aria-label, który mówi, co pokazują slajdy: „Zrzuty ekranu produktu”.
  • Oznacz slajdy pozycją. Nadaj każdemu CarouselItem atrybut aria-label, np. „2 z 5”, żeby użytkownik wiedział, w którym miejscu jest.
  • Przyciski mają etykiety. CarouselPreviousCarouselNext zawierają dla czytników ekranu etykiety „Poprzedni slajd” i „Następny slajd” — tłumaczone przez LocaleProvider — a na krańcach są wyłączone, chyba że karuzela jest zapętlona.
  • Tekst na obrazach. Utrzymuj kontrast 4,5:1 dla tekstu na zdjęciach — użyj przyciemniającej nakładki (scrim), jak w przykładach.

Dokumentacja API

Element główny. Przyjmuje wszystkie propsy div.

PropTypDomyślnie
opts

Opcje Embla: align, loop, dragFree, slidesToScroll, breakpoints i inne.

EmblaOptionsTypeBrak wartości domyślnej
plugins

Wtyczki Embla, np. autoplay albo gesty kółka myszy.

EmblaPluginType[]Brak wartości domyślnej
orientation

Oś przewijania. Karuzele pionowe potrzebują stałej wysokości treści.

"horizontal" | "vertical""horizontal"
setApi

Otrzymuje instancję Embla, gdy tylko jest gotowa.

(api: CarouselApi) => voidBrak wartości domyślnej

CarouselContent

Przewijana ścieżka. Przyjmuje wszystkie propsy div; jej ujemny margines razem z paddingiem elementów tworzy odstęp.

CarouselItem

Pojedynczy slajd, domyślnie na pełną szerokość. Ustaw basis-*, żeby pokazać kilka naraz.

CarouselPrevious, CarouselNext

Przyciski ikonowe w wariancie outline, podłączone do karuzeli. Przyjmują wszystkie propsy Button; domyślny variant to "outline", a size — "icon-sm".

useCarousel

Zwraca { api, scrollPrev, scrollNext, canScrollPrev, canScrollNext, orientation } do budowania własnych kontrolek wewnątrz Carousel.