mana-swift-ui/Sources/ManaOnboardingUI/ManaOnboardingPage.swift
Till JS efe424aa37 ManaOnboardingUI: Apple-„Neue Funktionen"-Sheet-Optik, keine Permission-Abfrage
Redesign nach Feedback. Statt Schritt-Karussell jetzt Apples
What's-New-Sheet-Stil: pro Seite Titel + Zeilen-Liste (Icon+Titel+Text)
+ EIN Button unten, Indikator oben (nicht beim Button).

- ManaOnboardingStep → ManaOnboardingPage (Titel/Vorspann/Row-Liste/
  Fußnote). Voll Sendable, keine Action-Closures mehr.
- Doktrin: fragt NIE Berechtigungen ab — die bleiben just-in-time.
  Onboarding informiert nur (kein Extrahieren auf Vorrat).
- Präsentation als .sheet (.presentationDetents([.large]) + Griff) statt
  fullScreenCover → nicht mehr eingezwängt; per Wischen = gesehen.
- Cross-Fade statt Swipe, reduced-motion-aware. 7 Tests (Seiten-Modell).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 19:19:07 +02:00

65 lines
2.4 KiB
Swift

import SwiftUI
/// Eine Seite im Einstiegs-Flow — im Stil von Apples „Neue Funktionen“-
/// Sheet: ein großer Titel, optional ein kurzer Vorspann, darunter eine
/// **vertikale Liste von Zeilen** (Icon links, Titel + Text rechts), und
/// pro Seite genau **ein** Weiter-Button (der Container rendert ihn).
///
/// Inhalt ist **app-geliefert** — das Paket weiß nichts über Vorsätze,
/// Decks oder Memos. Eine App baut `[ManaOnboardingPage]` und übergibt
/// sie an ``SwiftUICore/View/manaOnboarding(storageKey:pages:onFinish:)``.
/// Die Optik (Farben) kommt aus `@Environment(\.manaTheme)`, das die App
/// sowieso setzt — dadurch sieht der Flow flottenweit einheitlich aus,
/// aber im Signatur-Theme der jeweiligen App.
///
/// **Bewusst ohne Berechtigungs-Schritte.** `ManaOnboardingUI` fragt
/// **nie** System-Rechte ab — Berechtigungen hängen an konkreten Features
/// und werden *just-in-time* erfragt, wenn das Feature zum ersten Mal
/// genutzt wird. Das Onboarding **informiert** nur. (Werte-Entscheidung
/// 2026-06-05: kein Extrahieren auf Vorrat.)
public struct ManaOnboardingPage: Identifiable, Sendable {
public let id: String
/// Große Überschrift oben auf der Seite.
public let title: String
/// Optionaler kurzer Vorspann unter dem Titel (ein Satz). `nil` =
/// kein Vorspann.
public let intro: String?
/// Die Inhalts-Zeilen (Apple-„Neue Funktionen“-Liste).
public let rows: [Row]
/// Optionaler, dezenter Fußnoten-Text über dem Button (z.B. ein
/// Hinweis aufs optionale Konto). `nil` = keine Fußnote.
public let footnote: String?
public init(
id: String? = nil,
title: String,
intro: String? = nil,
rows: [Row],
footnote: String? = nil
) {
self.id = id ?? title
self.title = title
self.intro = intro
self.rows = rows
self.footnote = footnote
}
/// Eine Zeile: SF-Symbol (links, brand-getönt) + Titel + Beschreibung.
public struct Row: Identifiable, Sendable {
public let id: String
public let symbol: String
public let title: String
public let text: String
public init(id: String? = nil, symbol: String, title: String, text: String) {
self.id = id ?? title
self.symbol = symbol
self.title = title
self.text = text
}
}
}