---
title: "Benachrichtigungen — zenit Zig UI Doku"
description: "Nutzen Sie den Notifier für Benachrichtigungen im Fenster, die die aktuelle Aufgabe nie blockieren — Erfolg, Fehler, Fortschritt, Rückgängig und Nachrichten…"
url: https://zenit.z.express/de/docs/advanced/notifications
language: de
alternate_en: https://zenit.z.express/docs/advanced/notifications.md
alternate_zh: https://zenit.z.express/zh/docs/advanced/notifications.md
alternate_es: https://zenit.z.express/es/docs/advanced/notifications.md
alternate_ja: https://zenit.z.express/ja/docs/advanced/notifications.md
alternate_ko: https://zenit.z.express/ko/docs/advanced/notifications.md
alternate_fr: https://zenit.z.express/fr/docs/advanced/notifications.md
project: zenit v0.1.0-alpha (Zig 0.15.2, macOS)
source: https://github.com/version-next/zenit
---

# Benachrichtigungen

Nutzen Sie den Notifier für Benachrichtigungen im Fenster, die die aktuelle Aufgabe nie blockieren — Erfolg, Fehler, Fortschritt, Rückgängig und Nachrichten —, wobei Stapeln, Aufklappen bei Hover und acht Andockpositionen für Sie übernommen werden.

## Was der Notifier ist

`ui.widgets.Notifier` ist ein Dienst auf Fensterebene: einmal initialisieren, dann `show` von überall aufrufen. Die Karten liegen auf der Toast-Ebene des Overlay-Portals des Fensters (z 2000 — über Dialogen, unter Tooltips) und nehmen nie am Seitenlayout teil. Jede Karte besitzt einen festen Node, sodass das Entfernen einer Karte die anderen nie neu aufbaut oder ihren Auftritt erneut abspielt. Er ersetzt den früheren ToastManager.

[Video](https://zenit.z.express/media/stories/notification.mp4?v=5f8cadb85b)

Das echte Storybook: Erfolg, Fehler, Warnung, Fortschritt, Aktion, Person, Rückgängig, dezent und Zusammenfassung nacheinander, dann vier auf einmal als Stapel, per Hover aufgeklappt, und die mittlere Karte geschlossen.

Die API Feld für Feld (`Notification`, `NotifierOptions` und jede Methodensignatur) finden Sie auf der [Notification-Seite](https://zenit.z.express/de/components/notification) der Komponenten-Website.

## Einen Notifier erstellen

Erstellen Sie ihn einmal in Ihrer Root-Mount-Funktion und reichen Sie den Zeiger an alles weiter, was benachrichtigen muss (etwa App-State, der per `cx.bindState` gehalten wird). Der Notifier gehört dem übergebenen Scope und verschwindet mit ihm.

`app.zig`

```zig
const notifier = try ui.widgets.Notifier.init(scope, cx, .{
    .position = .bottom_center,
    // Keep the stack clear of a 56px toolbar.
    .content_insets = .{ .top = 56 },
    .max_visible = 4,
});
```

| NotifierOptions-Feld | Zweck |
| --- | --- |
| `position` | Eine von acht Positionen, Standard .bottom\_center; zur Laufzeit mit setPosition umschaltbar |
| `max_visible` | Wie viele Karten aufgeklappt sichtbar sind (2–6, Standard 4) |
| `expand_on_hover` | Bei false pausiert Hover nur die Timer und klappt nicht auf |
| `content_insets` | Abstände zu den Fensterrändern (Titelleiste, Toolbar, Statusleiste); der 22px-Andockabstand beginnt hier |
| `width` | Kartenbreite, Standard 392 |
| `strings` | UI-Texte ("now", "Undo", "Reply…", das eingeklappte Badge …) für die Lokalisierung |
| `listener` | Callback für Benutzeraktionen und Ablauf; auch per setListener setzbar |

## Eine Benachrichtigung anzeigen

`show` nimmt einen `ui.widgets.Notification`\-Wert und gibt dessen id zurück. Der Notifier kopiert jeden String, Ihre Puffer sind also sofort wiederverwendbar. Ab mehr als sechs Karten auf dem Bildschirm verschwindet die älteste mit ihrer normalen Abgangsanimation.

`notify.zig`

```zig
// Success: auto-dismisses after 3.6 s.
_ = try notifier.show(.{
    .tone = .success,
    .title = "Saved to iCloud",
    .body = "3 files synced · 2.1 MB",
});

// Error with two actions: errors stay until the user acts.
const failed = try notifier.show(.{
    .tone = .@"error",
    .title = "Upload failed",
    .body = "network timeout · dist/app.zip",
    .actions = &.{
        .{ .label = "Retry", .primary = true, .tag = "retry" },
        .{ .label = "View log", .tag = "log" },
    },
});

// Undo: a 7 s countdown ring and a default "Undo" button.
_ = try notifier.show(.{
    .kind = .undo,
    .title = "Moved 4 items to the Trash",
    .body = "You can undo this for 7 seconds.",
});

// A person's message with an inline reply box.
_ = try notifier.show(.{
    .tone = .violet,
    .avatar = "L",
    .title = "Lin",
    .body = "I finished the table widths in section three.",
    .reply = true,
});
```

> NOTE
> 
> **Höchstens zwei Buttons.** Buttons sitzen unter einer Trennlinie in gleicher Breite auf neutralem Hintergrund; primary bedeutet nur kräftigere Füllung und Schrift — die Tonfarbe übernimmt er nie.

## Arten, Töne und Anzeigedauer

Das Aussehen einer Karte ergibt sich aus zwei Achsen: `kind` (Layout) und `tone` (semantische Farbe). Das vorangestellte Icon wird aus beiden abgeleitet oder explizit mit `lead` / `glyph` gesetzt.

| kind | Layout |
| --- | --- |
| `.default` | Icon, Titel und Text, optional mit Buttons, Antwortfeld oder Avatar |
| `.progress` | Spinner, determinierter Balken und ein n / N-Zähler; kein Lebensdauerbalken |
| `.undo` | Countdown-Ring mit den verbleibenden Sekunden, dazu ein Standard-Button "Undo" |

| tone | Verwendung | Standarddauer |
| --- | --- | --- |
| `.success` | Etwas ist fertig | 3.6 s |
| `.@"error"` | Ein Fehler, der Aufmerksamkeit braucht | dauerhaft |
| `.warning` | Beachtenswert, nicht blockierend | 5.6 s |
| `.info` | Allgemeine Information (Standard) | 4.2 s |
| `.violet` | Personen, Einladungen und andere soziale Nachrichten | 4.2 s; mit Buttons dauerhaft |
| `.quiet` | Dezenter Status (ein kleiner Punkt statt eines Icons) | 2.8 s |

-   **Standardmäßig dauerhaft:** progress-Karten, Karten mit Antwortfeld, der Ton error und violet-Karten mit Buttons schließen sich nie von selbst.
    
-   **Explizite Überschreibungen:** `sticky = true` erzwingt Dauerhaftigkeit; `duration_ms` ersetzt die Standarddauer; `life_bar` schaltet den Lebensdauerbalken um.
    
-   **Undo** dauert standardmäßig 7 Sekunden, der Ring folgt dem Timer.
    

## Aktualisierung vor Ort und Fortschritt

`update(id, …)` schreibt Art, Ton, Titel und Text derselben Karte neu und startet ihre Lebensdauer neu — kein Zerstören, kein Neuaufbau, kein erneuter Auftritt. Treiben Sie eine Fortschrittskarte mit `setProgress` an, das nur die Fortschrittsebene berührt. Auch `show` mit einer vorhandenen `id` verwandelt die Karte vor Ort.

`upload.zig`

```zig
const id = try notifier.show(.{
    .kind = .progress,
    .title = "Uploading attachment",
    .body = "assets/hero-shot.png",
    .progress = .{ .value = 0, .label = "Uploading · about 5 s", .count = "0 / 5" },
});

// Each tick: only the progress layer is touched, the card isn't rebuilt.
notifier.setProgress(id, 0.6, "Uploading · about 2 s", "3 / 5");

// Done: the same card turns into a success card in place —
// no new entrance, and it now dismisses itself after 3.4 s.
try notifier.update(id, .{
    .tone = .success,
    .title = "Upload complete",
    .body = "assets/hero-shot.png",
    .duration_ms = 3400,
});
```

## Benutzeraktionen verarbeiten

Der Notifier meldet über einen einzigen `ui.widgets.NotificationListener`. Ein `NotificationEvent` enthält die Karten-`id`, die Event-`kind` und das `tag` / den `index` des Buttons oder den Antwort-`text`.

| EventKind | Wann |
| --- | --- |
| `.action` | Ein Button wurde geklickt (per tag unterscheiden) |
| `.undo` | Undo wurde geklickt; der Ring ist bereits zu einem ✓ geworden |
| `.reply` | Das Antwortfeld wurde abgeschickt (Enter oder Send); text enthält den Inhalt |
| `.dismissed` | Der Benutzer hat sie geschlossen (✕ oder Wegwischen) |
| `.expired` | Sie ist abgelaufen |

`uploads.zig`

```zig
const Uploads = struct {
    fn onEvent(ctx: ?*anyopaque, n: *ui.widgets.Notifier, e: ui.widgets.NotificationEvent) void {
        const self: *Uploads = @ptrCast(@alignCast(ctx orelse return));
        switch (e.kind) {
            .action => if (std.mem.eql(u8, e.tag, "retry")) {
                // Turn the sticky error card into a progress card in place.
                n.update(e.id, .{
                    .kind = .progress,
                    .title = "Retrying upload",
                    .progress = .{ .value = 0, .label = "Uploading", .count = "0 / 5" },
                }) catch return;
                self.restart(e.id);
            } else n.dismiss(e.id),
            .reply => self.send(e.text),
            .undo => self.restoreTrash(),
            .dismissed, .expired => {},
        }
    }
    // …restart / send / restoreTrash
};

const uploads = try cx.bindState(Uploads, .{});
notifier.setListener(.{ .context = @ptrCast(uploads), .callback = Uploads.onEvent });
```

> TIP
> 
> **Antwort nicht gesendet?** Rufen Sie `notifier.replyFailed(id, title, body)` auf, um dieselbe Karte vor Ort in einen Fehlerzustand zu versetzen, ohne die Eingabe des Benutzers zu verlieren.

## Stapeln und Hover

Mehrere Benachrichtigungen klappen zu einem Stapel zusammen: Die neueste liegt dem Anker am nächsten mit dem höchsten z; jede Ebene dahinter lugt 9px hervor und schrumpft um 3.8 %, bis zu drei Ebenen, mit einem Badge „N weitere · Hover zum Aufklappen“. Betritt der Zeiger die Stapelgrenzen (um 18px erweitert), klappt er mit 9px Abstand auf und alle Timer pausieren; beim Verlassen klappt er zu und die Timer laufen weiter.

STACK

Die Werte stammen aus Spec in notification/model.zig: 9px Überstand, 3.8 % Skalierung pro Ebene, 9px Abstand im aufgeklappten Zustand.

**Alle löschen**

Neben dem Badge sitzt ein Button zum Löschen aller Karten: Der erste Klick zeigt die Beschriftung, der zweite löscht tatsächlich, und beim Wegbewegen klappt er wieder ein. Im Code rufen Sie dismissAll() auf.

**Wegwischen zum Schließen**

Eine einzelne Karte lässt sich wegwischen, was dismissed meldet.

**Fenstergröße ändern**

Beim Ändern der Fenstergröße folgt der Stapel seinem Anker starr, ohne nachziehende Interpolation.

## Positionen

`setPosition` ändert nur Anker, Wachstumsrichtung und Auftrittsversatz — Karten werden nicht neu aufgebaut, und eine Karte, die gerade abgeht, beendet ihren Abgang in der neuen Richtung.

POSITIONS

[Video](https://zenit.z.express/media/stories/notification-positions.mp4?v=2df7ff87b6)

Dieselben vier Benachrichtigungen nacheinander an allen acht Positionen angedockt; ganzes Fenster im Bild, da die linken Positionen am Fensterrand anliegen.

## Die Mitteilungszentrale gehört Ihnen

Verlauf, Nicht stören und ein Glocken-Einstieg — die Funktionen einer Mitteilungszentrale — sind App-Logik und liegen außerhalb von zenit: Protokollieren Sie den Verlauf dort, wo Sie show aufrufen, entscheiden Sie, ob überhaupt eine Karte erscheint, und erfahren Sie über den Listener von Schließen, Ablauf und Button-Aktionen. Die Zusammenfassungskarte im Storybook zeigt das Muster: Nach dem Ende von Nicht stören fasst eine quiet-Karte zusammen, was eingetroffen ist.

> WARNING
> 
> **Barrierefreiheit ist noch nicht abgenommen.** Wie beim Rest von zenit ist die VoiceOver-Abnahme für Benachrichtigungskarten noch nicht erfolgt; machen Sie sie nicht zum einzigen Kanal für kritische Informationen.
