# Tabs

Tabs strukturieren verwandte Inhalte und ermöglichen einen schnellen Zugriff auf unterschiedliche Ansichten.

## Overview

# Playground

Verwende `<Tabs />`, um Tabs darzustellen. Jeder einzelne Tab wird mit `<Tab />`
definiert und erhält seine Bezeichnung über `<TabTitle />`.

  Tabs vs. TabNavigation

    Verwende Tabs um Inhalte innerhalb derselben Seite umzuschalten, ohne zu
    navigieren. Um zu navigieren verwende die
    [TabNavigation](/04-components/navigation/tab-navigation/overview).

```tsx
import {
  Tab,
  Tabs,
  TabTitle,
} from "@mittwald/flow-react-components";

<Tabs>
  <Tab>
    <TabTitle>Mit App verbinden</TabTitle>
    App Content
  </Tab>
  <Tab>
    <TabTitle>Mit Container verbinden</TabTitle>
    Container Content
  </Tab>
</Tabs>
```

---

# Eingeklappte Ansicht

Wenn die verfügbare Breite nicht ausreicht, wechseln die Tabs automatisch in
eine eingeklappte Ansicht.

```tsx
import {
  Heading,
  LayoutCard,
  Section,
  Tab,
  Tabs,
  TabTitle,
} from "@mittwald/flow-react-components";

<LayoutCard style={{ maxWidth: "320px" }}>
  <Section>
    <Heading>SSH-Benutzer</Heading>
    <Tabs>
      <Tab>
        <TabTitle>Mit App verbinden</TabTitle>
        App Content
      </Tab>
      <Tab>
        <TabTitle>Mit Container verbinden</TabTitle>
        Container Content
      </Tab>
    </Tabs>
  </Section>
</LayoutCard>
```

---

# Mit Status-Icon

Wenn der Inhalt eines Tabs eine wichtige Information oder Warnung enthält (z. B.
in Form eines [Alerts](/04-components/status/alert/overview)), muss der
entsprechende Tab ein Status-Icon erhalten.

```tsx
import {
  AlertIcon,
  Tab,
  Tabs,
  TabTitle,
} from "@mittwald/flow-react-components";

<Tabs>
  <Tab>
    <TabTitle>Mit App verbinden</TabTitle>
    App Content
  </Tab>
  <Tab>
    <TabTitle>
      Mit Container verbinden
      <AlertIcon status="warning" />
    </TabTitle>
    Container Content
  </Tab>
</Tabs>
```

---

# Mit vorausgewähltem Tab

Standardmäßig sollte der erste Tab vorausgewählt sein. Falls ein anderer Tab
initial aktiv sein soll, kann dies über `defaultSelectedKey` festgelegt werden.

```tsx
import {
  Tab,
  Tabs,
  TabTitle,
} from "@mittwald/flow-react-components";

<Tabs defaultSelectedKey="container">
  <Tab>
    <TabTitle>Mit App verbinden</TabTitle>
    App Content
  </Tab>
  <Tab id="container">
    <TabTitle>Mit Container verbinden</TabTitle>
    Container Content
  </Tab>
</Tabs>
```


## Develop

# Reihenfolge der Tabs

Es kann vorkommen, dass sich durch Rerendering die Reihenfolge der Tabs ändert,
wenn innerhalb des Tabs Inhalte nachgeladen werden. Um das zu verhindern, sollte
der Tab-Inhalt in eine eigene Component ausgelagert werden und um diese ein
Suspense gelegt werden.

```
<Tabs>
  <Tab>
    <TabTitle>Tab 1</TabTitle>
    <Suspense>
      <Tab1Content/>
    </Suspense>
  </Tab>
  <Tab>
    <TabTitle>Tab 2</TabTitle>
    <Suspense>
      <Tab2Content/>
    </Suspense>
  </Tab>
</Tabs>
```

---

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `tabNotFoundView` | `ReactNode` | - | - |
| `id` | `string` | - | The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id). |
| `isDisabled` | `boolean` | - | Whether the TabList is disabled. Shows that a selection exists, but is not available in that circumstance. |
| `className` | `ClassNameOrFunction<TabsRenderProps>` | `'react-aria-Tabs'` | The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state. |
| `style` | `StyleOrFunction<DateFieldRenderProps>` | - | The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state. |
| `render` | `DOMRenderFunction<"div", DateFieldRenderProps>` | - | Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate. |
| `slot` | `string` | - | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| `dir` | `string` | - | - |
| `lang` | `string` | - | - |
| `hidden` | `boolean` | - | - |
| `inert` | `boolean` | - | - |
| `translate` | `"yes" \| "no"` | - | - |
| `selectedKey` | `Key` | - | The currently selected key in the collection (controlled). |
| `defaultSelectedKey` | `Key` | - | The initial selected keys in the collection (uncontrolled). |
| `keyboardActivation` | `"manual" \| "automatic"` | `'automatic'` | Whether tabs are activated automatically on focus or manually. |
| `orientation` | `Orientation` | `'horizontal'` | The orientation of the tabs. |
| `disabledKeys` | `Iterable<Key>` | - | The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with. |
| `children` | `ReactNode` | - | - |
| `wrapWith` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | - | - |
| `ref` | `Ref<HTMLSpanElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see [React Docs](https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom) |
| `key` | `Key` | - | - |

### Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `onClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenu` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenuCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDown` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDownCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseEnter` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseLeave` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMove` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMoveCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOut` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOutCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOver` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOverCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUp` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUpCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancel` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancelCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEnd` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEndCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMove` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMoveCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStart` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStartCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onPointerDown` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerDownCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMove` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMoveCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUp` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUpCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancel` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancelCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerEnter` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerLeave` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOver` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOverCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOut` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOutCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onScroll` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onScrollCapture` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onWheel` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onWheelCapture` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStart` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStartCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEnd` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEndCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIteration` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIterationCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancel` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancelCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEnd` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEndCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRun` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRunCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStart` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStartCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onSelectionChange` | `((key: Key) => void)` | - | Handler that is called when the selection changes. |

### Accessibility

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `aria-label` | `string` | - | Defines a string value that labels the current element. |
| `aria-labelledby` | `string` | - | Identifies the element (or elements) that labels the current element. |
| `aria-describedby` | `string` | - | Identifies the element (or elements) that describes the object. |
| `aria-details` | `string` | - | Identifies the element (or elements) that provide a detailed, extended description for the object. |


## Guidelines

# Grundlagen

## Best Practices

Achte bei der Verwendung von Tabs darauf, dass ...

- innerhalb eines Tabs thematisch verwandter Content gruppiert wird.
- die Reihenfolge nach Wichtigkeit oder Häufigkeit der Nutzung erfolgt.
- jeder Tab eigenständig verständlich ist und eine kurze und deutliche
  Beschriftung hat.
- sie nicht zur Navigation eingesetzt werden – Tabs schalten ausschließlich
  Inhalte innerhalb derselben Seite um, ohne zu einer anderen Seite bzw. URL zu
  navigieren, und ersetzen keine Navigation.
- bei Statusanzeigen innerhalb eines Tabs – z. B. durch einen
  Danger-[Alert](/04-components/status/alert/overview) – der Tab selbst ein
  entsprechendes Status-Icon erhält, um die Aufmerksamkeit darauf zu lenken.

## Verwendung

Verwende Tabs, um komplexe Inhalte in kleinere, übersichtlichere Ansichten zu
gliedern.

## Tabs vs. TabNavigation

Flow bietet mit Tabs und der
[TabNavigation](/04-components/navigation/tab-navigation/overview) zwei ähnlich
aussehende Components, die sich aber in der Verwendung klar unterscheiden:

  

**ℹ️ Info**

Inhalte innerhalb derselben Seite umzuschalten, ohne zu navigieren.

  

**ℹ️ Info**

zwischen gleichrangigen Unterseiten zu navigieren.

