# React Swipeable Tabs: Seiten, die dem Daumen folgen

> So baust du React Swipeable Tabs mit nativem Scroll Snap: Der Indikator folgt dem Finger, vertikales Scrollen wechselt nie den Tab, mit Tastatur, ohne Altlast.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 16. Okt. 2026
- Kategorie: [Mobile UI mit React](https://wingo-ui.com/de/blog/category/mobile-ui)
- Lesezeit: 11 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/react-swipeable-tabs
- Englische Fassung: https://wingo-ui.com/blog/react-swipeable-tabs

## Kurz gesagt

Für React Swipeable Tabs legst du die Seiten aller Tabs nebeneinander in einen horizontalen Container mit CSS Scroll Snap: Ein Wischen zur Seite bewegt so eine Seite mit dem Schwung des Browsers, und der Indikator liest die Scroll-Position. Jede Seite scrollt vertikal für sich, damit vertikales Scrollen nie den Tab wechselt, und die Tab-Reihe bleibt eine echte WAI-ARIA-Tablist mit Pfeiltasten, Pos1 und Ende. Die Swipeable Tabs (Pro) von Wingo UI packen das in eine einzige React-19-Komponente, ohne die Abhängigkeit react-swipeable-views aus der Zeit von React 17.

Du willst die Tabs aus nativen Apps im Web: Die Seiten liegen nebeneinander, ein Wischen zur Seite zieht die nächste unter deinem Daumen herein, und der Indikator in der Tab-Reihe gleitet mit, während sich die Seiten bewegen. React Swipeable Tabs sehen einfach aus, bis ein vertikales Scrollen den Tab wechselt oder der Indikator einen Frame hinter dem Finger herhinkt. Dieser Guide zeigt, was eine Web-Version richtig machen muss (das Wischen, den Indikator, vertikales Scrollen, Tastatur, reduzierte Bewegung), mit der Komponente [Swipeable Tabs](https://wingo-ui.com/components/swipeable-tabs) von Wingo UI. Wir bauen diese Bibliothek, wir sind also nicht neutral.

## Was sind Swipeable Tabs, und wann passen sie?

Swipeable Tabs sind Tabs, deren Panels zugleich Seiten in einem horizontalen Pager sind. Ein Tipp auf einen Tab gleitet zu seiner Seite; ein Wischen über den Inhalt wechselt zur Nachbarseite und wählt ihren Tab. Sie passen zu Screens, auf denen die Tabs parallele Ansichten derselben Sache sind und man oft zur Nachbarseite wechselt: Ordner in einem Mail-Client, Aktiv / Überfällig / Interessenten in einer CRM-Liste, Tag / Woche / Monat in einem Kalender.

Weniger gut passen sie, wenn eine Seite eigene horizontale Gesten hat (eine Karte, ein Chart, über das du mit dem Finger fährst, ein Foto-Karussell) oder wenn die Tabs nichts miteinander zu tun haben. Für eine Einstellungsseite mit vier Formularen sind normale [Tabs](https://wingo-ui.com/components/tabs) das bessere Bedienelement, und eine Auswahl, die nur die Daten auf dem Screen ändert, etwa ein Zeitraum, ist ein [Segmented Control](https://wingo-ui.com/components/segmented-control). Der [Guide zum React Segmented Control](https://wingo-ui.com/de/blog/react-segmented-control) erklärt diese Trennung im Detail.

## Warum nicht einfach react-swipeable-views nutzen?

Weil das Paket immer noch React 17 als neueste unterstützte Version angibt und der Browser diese Arbeit heute selbst erledigt. Wer in React zwischen Tabs wischen wollte, griff jahrelang zu react-swipeable-views, dem Paket für Swipeable Views hinter dem Full-Width-Beispiel in der [Tabs-Demo von Material UI v4](https://v4.mui.com/components/tabs/). Das neueste Release auf [npm](https://www.npmjs.com/package/react-swipeable-views) ist 0.14.2, veröffentlicht am 22. Juni 2026, und als Peer Dependencies stehen dort weiter React 15, 16 und 17 (geprüft am 16. Oktober 2026). In einem React-19-Projekt bricht npm ab Version 7 die Installation mit einem Peer-Dependency-Konflikt ab, außer du übergibst `--legacy-peer-deps`. Die aktuelle [Doku zu MUI Tabs](https://mui.com/material-ui/react-tabs/) zeigt keine Swipe-Demo mehr (geprüft am 16. Oktober 2026).

Eine Karussell-Bibliothek, die an den Tab-Wert gekoppelt ist, geht auch. Dann kommen das Ziehen, die Entscheidung über die Achse und der Schwung aber aus JavaScript statt aus dem Scroller des Browsers. Die React-Aria-Doku von Adobe geht in ihrem [Beispiel für Swipeable Tabs](https://react-aria.adobe.com/examples/swipeable-tabs) den nativen Weg und baut auf CSS Scroll Snapping, Scroll-driven Animations und Anchor Positioning auf. Nutzt deine App schon React Aria Components, fang dort an. Die Komponente von Wingo UI nutzt denselben Scroll-Snap-Pager und steuert den Indikator stattdessen über einen Motion Value.

## Wie baust du Swipeable Tabs in React ein?

Installier die Komponente, übergib pro Tab eine Option mit ihrer Seite und gib dem Elternelement eine Höhe. Die CLI kopiert auch alles, was die Datei importiert: Badge, die Helfer für Haptics, Motion, Tones und UI-Config sowie zwei kleine Hooks:

```bash
npx wingo-ui@latest add swipeable-tabs
```

Jedes Objekt in `options` nimmt `value`, `label`, optional `icon`, `badge` oder `disabled` und seine Seite in `content`. Mit dem Standardwert `layout="fill"` füllen die Tabs die Höhe ihres Elternelements, deshalb braucht das Elternelement eine feste Höhe:

```tsx
"use client";

import { useState } from "react";
import { SwipeableTabs } from "@/components/ui/swipeable-tabs";

const CLIENTS = [
  { name: "Tech Solutions Inc.", city: "New York", status: "active" },
  { name: "Summit Logistics", city: "Boston", status: "active" },
  { name: "Greenleaf Pharmacy", city: "Portland", status: "overdue" },
  { name: "Bistro 21", city: "Chicago", status: "prospect" },
];

function ClientList({ status }: { status?: string }) {
  const rows = CLIENTS.filter((c) => !status || c.status === status);
  return (
    <ul className="divide-y divide-foreground/10 px-4">
      {rows.map((c) => (
        <li key={c.name} className="flex min-h-14 flex-col justify-center">
          <span className="text-[15px] font-medium">{c.name}</span>
          <span className="text-[13px] text-muted-foreground">{c.city}</span>
        </li>
      ))}
    </ul>
  );
}

export function Clients() {
  const [tab, setTab] = useState("all");

  return (
    <div className="flex h-dvh flex-col">
      <SwipeableTabs
        aria-label="Kunden"
        value={tab}
        onValueChange={setTab}
        options={[
          { value: "all", label: "Alle", badge: 4, content: <ClientList /> },
          { value: "active", label: "Aktiv", badge: 2, content: <ClientList status="active" /> },
          { value: "overdue", label: "Überfällig", badge: 1, content: <ClientList status="overdue" /> },
          { value: "prospects", label: "Interessenten", content: <ClientList status="prospect" /> },
        ]}
      />
    </div>
  );
}
```

`onValueChange` wird aufgerufen, wenn ein Wischen auf einer neuen Seite zur Ruhe kommt, ein Tab gedrückt wird oder die Pfeiltasten einen auswählen. Eine Zahl in `badge` erscheint als Zähler, der bei 0 verschwindet.

> Live-Demo (Swipeable Tabs): Wisch die Kundenliste zur Seite oder wisch mit zwei Fingern auf dem Trackpad: Die Unterstreichung dehnt sich zwischen den Tabs, während sich die Seiten bewegen. Tipp auf den aktiven Tab, um seine Seite wieder nach oben zu scrollen. Probier sie unter [Swipeable Tabs](https://wingo-ui.com/components/swipeable-tabs) aus und installier sie mit `npx wingo-ui@latest add swipeable-tabs`.

## Wie folgt der Indikator dem Wischen?

Der Indikator liest die Position des Scrollers bei jedem Scroll-Event und wartet nie auf React. Die Seiten liegen in einem nativen horizontalen Scroller mit `scroll-snap-type: x mandatory`, und jede Seite hat `scroll-snap-stop: always`. Ein Wischen bewegt also höchstens eine Seite, und der Schwung kommt vom Browser selbst. Ein passiver Scroll-Listener macht aus der Position eine einzige Zahl, `progress`, einen Motion Value, bei dem 0 die erste Seite ist und 1,5 die Mitte zwischen der zweiten und dritten.

Alles, was sich bewegt, leitet sich aus dieser Zahl ab. Die Tab-Reihe misst die Offsets der Trigger nach jedem Render (und noch einmal, wenn Schriften laden oder ein Badge wächst), und Position und Breite des Indikators sind lineare Interpolationen zwischen den beiden Tabs links und rechts von `progress`. Die Unterstreichung ist ein fester Balken von 100px, der auf die Breite des Labels skaliert wird, so bleibt sie ein Transform. Pills und der Segmented Thumb bekommen eine Breite, weil das Skalieren einer Kapsel ihre runden Enden verzerren würde. Nichts davon löst pro Frame einen React-Render aus. Die Farbe des Labels wechselt bei der Hälfte des Wegs, und das kostet nur eine Handvoll Renders pro Wischen.

Dieselbe Zahl bekommen deine eigenen Teile über `useSwipeableTabs()`. Hier ist ein dünner Fortschrittsbalken unter der Tab-Reihe, gebaut mit der Parts-API:

```tsx
"use client";

import { motion, useTransform } from "motion/react";
import {
  SwipeableTabsList,
  SwipeableTabsPanel,
  SwipeableTabsPanels,
  SwipeableTabsRoot,
  SwipeableTabsTrigger,
  useSwipeableTabs,
} from "@/components/ui/swipeable-tabs";

const VIEWS = ["day", "week", "month"];

function PageProgress() {
  const { progress } = useSwipeableTabs();
  const scaleX = useTransform(progress, (p) => (p + 1) / VIEWS.length);
  return <motion.div style={{ scaleX }} className="h-0.5 origin-left bg-foreground/20" />;
}

export function Agenda() {
  return (
    <div className="flex h-dvh flex-col">
      <SwipeableTabsRoot defaultValue="week" variant="segmented">
        <SwipeableTabsList aria-label="Kalender" className="px-4">
          {VIEWS.map((view) => (
            <SwipeableTabsTrigger key={view} value={view} className="capitalize">
              {view}
            </SwipeableTabsTrigger>
          ))}
        </SwipeableTabsList>
        <PageProgress />
        <SwipeableTabsPanels>
          {VIEWS.map((view) => (
            <SwipeableTabsPanel key={view} value={view}>
              <p className="p-4 text-muted-foreground">Termine in dieser Ansicht: {view}</p>
            </SwipeableTabsPanel>
          ))}
        </SwipeableTabsPanels>
      </SwipeableTabsRoot>
    </div>
  );
}
```

Die Panels müssen in derselben Reihenfolge stehen wie die Trigger, denn Seite 2 im Scroller ist Tab 2.

## Wann zählt ein Wischen als Tabwechsel?

Wenn der Scroller auf einer Seite stehen geblieben ist und kein Finger mehr aufliegt. Den Tab schon bei jedem Scroll-Event zu wechseln ist der Bug, der sich in selbst gebauten Scroll Snap Tabs am leichtesten einschleicht. Die Komponente schützt vor drei Varianten davon:

- **Zur Ruhe kommen.** Sie wartet auf `scrollend`; in Browsern ohne dieses Event gilt das Scrollen nach 150ms ohne Scroll-Events als beendet. Solange noch ein Finger aufliegt, zählt das nicht. Ein Finger, der mitten im Wischen innehält, wählt also nie einen Tab aus.
- **Programmatisches Gleiten.** Ein Tipp auf Tab 4, während Tab 1 offen ist, scrollt sanft über die Seiten 2 und 3 hinweg. Die Komponente merkt sich das Ziel und ignoriert das Anhalten auf den Seiten dazwischen. `onValueChange` feuert also einmal, für Tab 4, statt dreimal. Der haptische Tick spielt nur, wenn ein Finger, ein Trackpad oder ein Ziehen mit der Maus die Seite bewegt hat.
- **Krumme Breiten.** `clientWidth` ist gerundet, die Snap Points sind es nicht. In einem 393,5px breiten Container landet `scrollLeft` deshalb einen Bruchteil eines Pixels neben `page * width`, und die Abweichung wächst um bis zu einen halben Pixel pro Seite. Ein exakter Vergleich kann die hinteren Seiten verfehlen; die Komponente rechnet diese Abweichung ein.

Auch ein deaktivierter Tab wird hier übersprungen: Ein Wischen, das auf seiner Seite landet, läuft weiter bis zur nächsten aktivierten Seite.

## Wie verhinderst du, dass vertikales Scrollen den Tab wechselt?

Das ist der klassische Bug bei selbst gebauten Tabs mit Wischgeste: Du scrollst eine lange Liste, dein Daumen driftet zur Seite, und der Screen springt zum nächsten Tab, weil ein Handler in JavaScript zu früh auf „horizontal“ entschieden hat.

Swipeable Tabs überlassen die Entscheidung dem Browser. Mit `layout="fill"` ist jede Seite ein eigener vertikaler Scroller (`overflow-y: auto` mit `overscroll-behavior-y: contain`) im horizontalen Pager, und der Browser gibt jede Geste an den Scroller, der zu ihrer Richtung passt. Eine überwiegend vertikale Bewegung scrollt die Liste, eine überwiegend horizontale blättert die Seite um. Jede Seite behält auch ihre eigene Scroll-Position: Wischst du weg und wieder zurück, landest du dort, wo du aufgehört hast.

Auf echten Screens kommen zwei weitere Fälle vor:

- **Eine horizontale Leiste in einer Seite.** Eine Reihe aus Chips oder Karten, die seitlich überläuft, scrollt zuerst. Hat die Leiste ihr Ende erreicht, blättert das nächste Wischen die Seite um.
- **Eine Fläche, die horizontales Ziehen für sich braucht.** Eine Karte, ein Range-Slider oder ein Unterschriftenfeld sollen nie die Seite umblättern. Markier sie mit `data-no-swipe`, dann bleiben horizontale Wischbewegungen, die dort beginnen, bei ihr:

```tsx
<SwipeableTabsPanel value="route">
  <div data-no-swipe className="h-72">
    {/* deine Karte oder dein Chart: horizontales Ziehen bleibt hier */}
  </div>
</SwipeableTabsPanel>
```

Auf dem Desktop blättert ein Wischen mit zwei Fingern auf dem Trackpad die Seiten um. Ein Ziehen mit der Maus tut das standardmäßig nicht, damit du Text weiter markieren kannst. Mit `swipeWithMouse` bewegt ein Ziehen über ein Viertel der Breite oder ein schnelles Schnippen eine Seite.

> Live-Demo (Swipeable Tabs): Dieselben Tabs mit variant="segmented": Der erhabene Thumb gleitet im Takt der Seiten zwischen den Segmenten, und Scrollen nach oben und unten wechselt nie den Tab. Probier sie unter [Swipeable Tabs](https://wingo-ui.com/components/swipeable-tabs) aus und installier sie mit `npx wingo-ui@latest add swipeable-tabs`.

## Wie funktionieren Tastatur und Screenreader?

Die Tab-Reihe folgt dem [WAI-ARIA-Pattern für Tabs](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/): eine `tablist` aus `tab`-Buttons mit `aria-selected` und `aria-controls` und pro Seite ein `tabpanel`, das von seinem Tab beschriftet wird. Die Tabulatortaste landet auf dem ausgewählten Tab, Links und Rechts wechseln zwischen den Tabs (gespiegelt in Layouts von rechts nach links, deaktivierte Tabs werden übersprungen, an den Enden geht es auf der anderen Seite weiter), Pos1 und Ende springen, und ein weiterer Druck auf die Tabulatortaste führt in die Seite.

Die APG empfiehlt, schon beim Fokussieren auszuwählen (automatische Aktivierung), wenn die Panels ohne spürbare Verzögerung erscheinen. Das ist hier der Standard, weil die Nachbarseiten schon gemountet sind. Lädt eine Seite beim Öffnen Daten, setz `activationMode="manual"`: Dann bewegen die Pfeile nur den Fokus, und Enter oder Leertaste wählen aus.

Das Wischen bringt zwei Details mit. Seiten außerhalb des Bildschirms sind `inert`, also landet die Tabulatortaste nie in einem Feld, das du nicht siehst. Trägt ein Wischen das fokussierte Feld davon, wandert der Fokus zum Tab, der jetzt zu sehen ist. Die Tab-Liste trägt außerdem eine versteckte Beschreibung, standardmäßig das englische „Swipe the content left or right to switch tabs.“, die du über die Prop `labels` übersetzen kannst.

## Wie verhalten sich Swipeable Tabs bei reduzierter Bewegung?

Ein Wischen ist direkte Manipulation: Die Seite liegt unter deinem Finger, also bewegt sie sich mit ihm, egal was eingestellt ist. Was sich unter `prefers-reduced-motion: reduce` ändert, ist alles, was die Komponente selbst animiert. Ein Tipp auf einen Tab springt zur Seite, statt dorthin zu gleiten, der Indikator springt mit, die Tap-Skalierung der Trigger ist aus, und Seiten, die ohne Wischen wechseln, blenden nur über. Die Einstellung kommt aus `usePrefersReducedMotion` in `lib/motion`, das keine Hydration-Fehler auslöst; der [Guide zu prefers-reduced-motion](https://wingo-ui.com/de/blog/prefers-reduced-motion-react) erklärt, warum das wichtig ist.

## Welche Props von Swipeable Tabs sind am wichtigsten?

Die meisten Screens brauchen nur `options`, `value` und `onValueChange`; der Rest sind Standardwerte, die du für einen bestimmten Screen änderst.

| Prop | Standard | Was sie tut |
|---|---|---|
| `variant` | `"underline"` | Unterstreichung, Pill oder Segmented Thumb; jede Variante dehnt sich beim Wischen zwischen den Tabs |
| `layout` | `"fill"` | `fill`: Die Tabs füllen das Elternelement, und jede Seite scrollt für sich. `auto`: Die Seiten nehmen die Höhe ihres Inhalts an |
| `fullWidth` | `true` | Die Tabs teilen sich die Reihe. Aus: Sie richten sich nach ihren Labels, und die Reihe scrollt mit ausgeblendeten Rändern |
| `swipe` | `true` | Aus: normale Tabs, die Seiten wechseln mit einem kurzen Überblenden |
| `swipeWithMouse` | `false` | Auch Ziehen mit der Maus wischt die Seiten |
| `lazy` | `true` | Eine Seite wird gemountet, wenn sie zum ersten Mal aktiv ist oder neben der aktiven liegt |
| `keepMounted` | `true` | Besuchte Seiten bleiben mit Scroll-Position und getippter Eingabe gemountet |
| `activationMode` | `"automatic"` | `manual`: Die Pfeile bewegen den Fokus, Enter oder Leertaste wählen aus |
| `scrollToTopOnReselect` | `true` | Ein Tipp auf den aktiven Tab scrollt seine Seite nach oben |
| `haptics` | `true` | Ein Auswahl-Tick über den Helfer [Haptics](https://wingo-ui.com/components/haptics), wenn ein Wischen auf einem neuen Tab zur Ruhe kommt |

`size`, `tone`, `color`, `radius` und `classNames` folgen derselben Skala wie der Rest der Bibliothek. Touchscreens bekommen in der Standardgröße Trigger mit 44px.

Auf Android nutzt der Tick `navigator.vibrate`, und zwar erst, nachdem die Seite einen Tipp gesehen hat. Auf dem iPhone weicht der Helfer auf den System-Tick eines versteckten nativen Schalters aus, den iOS ab Version 26.5 nur abspielt, wenn die Person selbst darauf tippt. Ein Wischen, das zur Ruhe kommt, bleibt dort also still (Stand Oktober 2026; der [Guide zur Web Vibration API](https://wingo-ui.com/de/blog/web-vibration-api-haptic-feedback) hat die Quellen). Sieh den Tick als Bonus, nie als einziges Feedback.

## Was geht bei Swipeable Tabs auf echten Screens schief?

Vier Fehler passieren leicht, wenn du das in eine App einbaust, und jeder lässt sich mit einer Zeile beheben.

- **Keine Höhe am Elternelement.** Mit `layout="fill"` nehmen die Tabs `h-full`. In einem Elternelement ohne Höhe fallen die Seiten in sich zusammen. Nimm einen Screen mit `flex h-dvh flex-col` oder wechsle für Tabs in einer Karte zu `layout="auto"`.
- **Schwere Seiten, die alle auf einmal mounten.** Lass `lazy` an: Der erste Render mountet nur die aktive Seite und ihre Nachbarn. Stapeln sich besuchte Seiten, setz `keepMounted={false}`. Dann werden Seiten, die mehr als eine Position entfernt liegen, nach einem Wischen wieder ausgehängt und verlieren ihre Scroll-Position.
- **Ein kontrollierter Wert, der sich mitten im Wischen ändert.** Die Komponente übernimmt ihn, wenn das Wischen zur Ruhe gekommen ist, statt gegen den Finger zu kämpfen. Versuch also nicht, das mit einem Timeout zu „reparieren“.
- **Zu viele Tabs.** Laufen die Labels über, scrollt die Reihe seitlich mit ausgeblendeten Rändern und hält den aktiven Tab beim Wischen sichtbar. Mit dem Standardwert `fullWidth` rücken überlaufende Labels der Variante underline zuerst bis auf einen knappen Mindestabstand zusammen. Ab vier oder fünf Labels auf einem 360px breiten Smartphone setzt du deshalb `fullWidth={false}`, damit jedes Label sein normales Padding bekommt.

## Womit solltest du anfangen?

Braucht dein Screen nur Tabs, die auf Tipps reagieren, fang mit den kostenlosen Tabs an (`npx wingo-ui@latest add tabs`). Für Seiten, die dem Daumen folgen, gehören Swipeable Tabs zu [Wingo UI Pro](https://wingo-ui.com/de/pricing), und die Live-Demo auf ihrer Doku-Seite funktioniert auf deinem Smartphone, bevor du irgendetwas installierst. Weitere Patterns wie dieses findest du in der Kategorie [Mobile UI in React](https://wingo-ui.com/de/blog/category/mobile-ui) und im [Guide zu Mobile-first React Components](https://wingo-ui.com/de/blog/mobile-first-react-components).

## Komponenten in diesem Artikel

- [Swipeable Tabs](https://wingo-ui.com/components/swipeable-tabs) (Pro): React swipeable tabs whose pages sit side by side and follow your thumb: swipe and the indicator tracks the finger, tap and the pages slide. Installation: `npx wingo-ui@latest add swipeable-tabs`
- [Tabs](https://wingo-ui.com/components/tabs) (Free): React tabs with a sliding indicator that switch views of one page: underline for sections, pill for filters, segmented for a compact switch. Installation: `npx wingo-ui@latest add tabs`
- [Segmented Control](https://wingo-ui.com/components/segmented-control) (Free): A React iOS-style segmented control with a raised thumb that slides and follows your finger. Installation: `npx wingo-ui@latest add segmented-control`

## Häufige Fragen

### Wie wische ich in React ohne Bibliothek zwischen Tabs?

Leg pro Tab ein Panel in voller Breite in einen Container mit scroll-snap-type: x mandatory, teil beim Scrollen scrollLeft durch clientWidth, um den Indikator zu bewegen, und wähl den neuen Tab aus, sobald das Scrollen zur Ruhe kommt. Die Tab-Semantik, die Tastatur, den Fokus und den kontrollierten Wert musst du trotzdem selbst schreiben.

### Funktioniert react-swipeable-views mit React 19?

Das neueste Release, 0.14.2 vom Juni 2026, nennt React 15, 16 und 17 als Peer Dependencies. In einem React-19-Projekt meldet npm deshalb einen Peer-Dependency-Konflikt (npm-Registry, geprüft am 16. Oktober 2026). Ein nativer Scroll-Snap-Container braucht überhaupt kein zusätzliches Paket.

### Warum wechselt ein vertikales Scrollen meinen Tab?

Meist schnappt sich ein Gesten-Handler in JavaScript die Ziehbewegung, bevor der Browser ihre Richtung entschieden hat. Ist der Pager ein nativer horizontaler Scroller und scrollt jede Seite vertikal für sich, gibt der Browser jede Geste an den Scroller, der zu ihrer Richtung passt. Eine überwiegend vertikale Bewegung scrollt also die Seite.

### Sind Swipeable Tabs barrierefrei?

Ja, wenn die Tab-Reihe eine Tablist aus echten Buttons mit aria-selected und aria-controls ist, die Pfeiltasten zwischen den Tabs wechseln und Seiten außerhalb des Bildschirms inert sind. Das Wischen ist ein Extra: Jeder Tab muss sich auch per Tipp und per Tastatur öffnen lassen.

### Sind die Swipeable Tabs von Wingo UI kostenlos?

Nein, Swipeable Tabs gehören zu Wingo UI Pro. Tabs und das Segmented Control sind kostenlos und lassen sich mit npx wingo-ui@latest add tabs oder add segmented-control installieren.

---

Quelle: https://wingo-ui.com/de/blog/react-swipeable-tabs
