# ContextMenu

Das ContextMenu öffnet ein Popover mit einer Liste von Aktionen oder Links, welches in der Regel über einen Button geöffnet wird.

## Overview

# Playground

Verwende `<ContextMenu />`, um ein ContextMenu darzustellen. Innerhalb von
`<ContextMenuTrigger />` muss ein `<Button />` und ein `<ContextMenu />`
kombiniert werden, um ein ContextMenu per
[Button](/04-components/actions/button/overview)-Klick zu öffnen. Die einzelnen
Aktionen werden über `<MenuItem />` definiert.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu
    onAction={(id) => {
      alert(id);
    }}
  >
    <MenuItem id="1">Item 1</MenuItem>
    <MenuItem id="2">Item 2</MenuItem>
    <MenuItem id="3">Item 3</MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Einfach-Auswahl

Durch `selectionMode="single"` verhalten sich die Menüeinträge des ContextMenu
wie eine [RadioGroup](/04-components/form-controls/radio-group/overview), sodass
nur ein Element ausgewählt werden kann.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu
    selectionMode="single"
    defaultSelectedKeys={["item2"]}
  >
    <MenuItem id="item1">Item 1</MenuItem>
    <MenuItem id="item2">Item 2</MenuItem>
    <MenuItem id="item3">Item 3</MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mehrfach-Auswahl

Durch `selectionMode="multiple"` verhalten sich die Menüeinträge des ContextMenu
wie [Checkboxen](/04-components/form-controls/checkbox/overview), sodass mehrere
Optionen ausgewählt werden können.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu
    selectionMode="multiple"
    defaultSelectedKeys={["item2", "item3"]}
  >
    <MenuItem id="item1">Item 1</MenuItem>
    <MenuItem id="item2">Item 2</MenuItem>
    <MenuItem id="item3">Item 3</MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit Switch

Ein [Switch](/04-components/form-controls/switch/overview) im ContextMenu
ermöglicht es, Aktionen direkt zu aktivieren oder deaktivieren.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu selectionMode="switch">
    <MenuItem id="item1">Item 1</MenuItem>
    <MenuItem id="item2">Item 2</MenuItem>
    <MenuItem id="item3">Item 3</MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit Icon

Verwende [Icons](/04-components/content/icon/overview) innerhalb vom
`<MenuItem />`, um Aktionen schneller verständlich zu machen oder bekannte
Funktionen klarer zu vermitteln.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  IconInfo,
  MenuItem,
  Text,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu
    onAction={(id) => {
      alert(id);
    }}
  >
    <MenuItem id="1">
      <IconInfo />
      <Text>Item 1</Text>
    </MenuItem>
    <MenuItem id="2">
      <IconInfo />
      <Text>Item 2</Text>
    </MenuItem>
    <MenuItem id="3">
      <IconInfo />
      <Text>Item 3</Text>
    </MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit Separator

Ein [Separator](/04-components/structure/separator/overview) gruppiert logisch
zusammengehörige Aktionen.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
  Separator,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu>
    <MenuItem id="1">Item 1</MenuItem>
    <Separator />
    <MenuItem id="2">Item 2</MenuItem>
    <MenuItem id="3">Item 3</MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit ContextMenuSections

Eine `ContextMenuSectionSection` sorgt im ContextMenu für klare Struktur, indem
sie eine [Heading](/04-components/content/heading/overview) und definierte
Abstände verwendet.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuSection,
  ContextMenuTrigger,
  Heading,
  MenuItem,
  Separator,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu>
    <ContextMenuSection>
      <Heading>Section 1</Heading>
      <MenuItem id="1">Item 1</MenuItem>
      <MenuItem id="2">Item 2</MenuItem>
      <MenuItem id="3">Item 3</MenuItem>
    </ContextMenuSection>
    <Separator />
    <ContextMenuSection>
      <Heading>Section 2</Heading>
      <MenuItem id="4">Item 4</MenuItem>
      <MenuItem id="5">Item 5</MenuItem>
    </ContextMenuSection>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit fester Breite

Lege eine Breite für dein ContextMenu fest, um beispielsweise zu verhindern,
dass das ContextMenu zu breit wird oder die Breite des ContextMenus beim
Nachladen von Daten springt.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu
    width={300}
    onAction={(id) => {
      alert(id);
    }}
  >
    <MenuItem id="1">Mein Projekt</MenuItem>
    <MenuItem id="2">Mein zweites Projekt</MenuItem>
    <MenuItem id="3">
      Mein drittes Projekt mit einem sehr langen Namen
    </MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit Selection Mode

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuSection,
  ContextMenuTrigger,
  MenuItem,
  Separator,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu>
    <ContextMenuSection selectionMode="multiple">
      <MenuItem id="item1">Item 1</MenuItem>
      <MenuItem id="item2">Item 2</MenuItem>
      <MenuItem id="item3">Item 3</MenuItem>
    </ContextMenuSection>
    <Separator />
    <ContextMenuSection selectionMode="single">
      <MenuItem id="item1">Item 4</MenuItem>
      <MenuItem id="item2">Item 5</MenuItem>
      <MenuItem id="item3">Item 6</MenuItem>
    </ContextMenuSection>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# Mit Avatar

Verwende das ContextMenu als Profilmenü, indem innerhalb ein
[Avatar](/04-components/content/avatar/overview) und eine
[Heading](/flow/04-components/content/heading/overview) platziert werden.

```tsx
import {
  Avatar,
  Button,
  ContextMenu,
  ContextMenuTrigger,
  Heading,
  IconCamera,
  Initials,
  MenuItem,
  Section,
  Separator,
  Text,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu selectionMode="navigation">
    <Section>
      <MenuItem>
        <Avatar>
          <Initials>Max Mustermann</Initials>
        </Avatar>
        <IconCamera />
      </MenuItem>
      <Heading>Max Mustermann</Heading>
    </Section>
    <Separator />
    <Section>
      <MenuItem>
        <Text>Settings</Text>
      </MenuItem>
      <MenuItem>
        <Text>Logout</Text>
      </MenuItem>
    </Section>
  </ContextMenu>
</ContextMenuTrigger>
```

---

# States

Ein MenuItem kann unterschiedliche States annehmen, die anzeigen, dass aktuell
keine Interaktion möglich ist.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuTrigger,
  MenuItem,
} from "@mittwald/flow-react-components";

<ContextMenuTrigger>
  <Button>Trigger</Button>
  <ContextMenu>
    <MenuItem isDisabled>Disabled</MenuItem>
    <MenuItem isPending>Pending</MenuItem>
    <MenuItem isSucceeded>Succeeded</MenuItem>
    <MenuItem isFailed>Failed</MenuItem>
  </ContextMenu>
</ContextMenuTrigger>
```

**Disabled:** Verwende den Disabled-State, wenn das MenuItem keine Aktion oder
kein Ereignis auslösen soll.

**Pending, Succeeded und Failed:** Pending, Succeeded und Failed sollen dem
Nutzer signalisieren, dass im Hintergrund etwas passiert, wenn er auf ein
MenuItem geklickt hat. Verwende das MenuItem zusammen mit der Komponente
[Action](/04-components/actions/action/overview), um die States zu steuern.

---

# Kombiniere mit

## Modal

Aktionen im ContextMenu können [Modals](/04-components/overlays/modal/overview)
als Overlay öffnen, wenn zusätzliche Informationen erfasst, bestätigt oder
bearbeitet werden müssen.

```tsx
import {
  ActionGroup,
  Button,
  Content,
  ContextMenu,
  ContextMenuTrigger,
  Heading,
  IconContextMenu,
  IconEdit,
  Label,
  MenuItem,
  Modal,
  TextField,
  Text,
  Action,
  useModalController,
} from "@mittwald/flow-react-components";

export default () => {
  const modalController = useModalController();

  return (
    <>
      <ContextMenuTrigger>
        <Button variant="plain" color="secondary">
          <IconContextMenu />
        </Button>
        <ContextMenu>
          <MenuItem
            onAction={() => {
              modalController.open();
            }}
          >
            <IconEdit />
            <Text>Bearbeiten</Text>
          </MenuItem>
        </ContextMenu>
      </ContextMenuTrigger>
      <Modal controller={modalController}>
        <Heading>Bearbeiten</Heading>
        <Content>
          <TextField>
            <Label>Name</Label>
          </TextField>
        </Content>
        <ActionGroup>
          <Action closeModal>
            <Button color="accent">Speichern</Button>
            <Button color="secondary" variant="soft">
              Abbrechen
            </Button>
          </Action>
        </ActionGroup>
      </Modal>
    </>
  );
}
```

