mana-swift-ui/Sources/ManaComponentsUI/ManaSectionHeader.swift
Till JS fc8a8d4702 ManaComponentsUI: ManaSectionHeader + ManaPinnedGlyph, ManaScreenHeader fett
Geteilte Listen-Bausteine, drift-sicher als Pendant zur Compose-Lib:
- ManaSectionHeader: großer (.title2/SemiBold) Abschnitts-Header für
  scrollende Listen, optional einklappbar (Chevron).
- ManaPinnedGlyph: gezeichneter Fünfzack-Stern (geteilte Geometrie via
  ManaStarShape), kein SF-Symbol → pixelgleich zum Android-Pendant.
- ManaScreenHeader: Titel jetzt fett (.title.bold).

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

67 lines
2.3 KiB
Swift

import ManaTokens
import SwiftUI
/// Flotten-einheitlicher **Abschnitts-Header** für scrollende Listen (Datums-
/// gruppen, „Angepinnt" …) — natives Pendant zur Android-`ManaSectionHeader`
/// (mana-kotlin-ui). **Der Stil ist hier zentral festgelegt**, damit sticky
/// Section-Header über alle Apps gleich aussehen:
///
/// - Label: `.title2` + SemiBold, gedämpfte Vordergrundfarbe (foreground 80 %).
/// - Links-bündig, Padding 12 oben / 8 unten.
/// - Optional **einklappbar**: ganze Zeile tappbar, Chevron zeigt auf-/zugeklappt.
///
/// Bewusst groß (nicht das winzige `.footnote`/uppercase-Caption-Muster) — wie
/// die memoro-Android-Referenz. Farbe aus der aktiven Theme-Variant via
/// `@Environment(\.manaTheme)`.
///
/// ```swift
/// ManaSectionHeader("Gestern")
/// ManaSectionHeader("Angepinnt", isExpanded: pinnedExpanded) { pinnedExpanded.toggle() }
/// ```
public struct ManaSectionHeader: View {
@Environment(\.manaTheme) private var theme
private let label: String
private let isExpanded: Bool?
private let onToggle: (() -> Void)?
/// Nicht einklappbarer Header (reines Label).
public init(_ label: String) {
self.label = label
isExpanded = nil
onToggle = nil
}
/// Einklappbarer Header: ganze Zeile tappbar, Chevron spiegelt `isExpanded`.
public init(_ label: String, isExpanded: Bool, onToggle: @escaping () -> Void) {
self.label = label
self.isExpanded = isExpanded
self.onToggle = onToggle
}
public var body: some View {
let color = theme.colors.foreground.opacity(0.8)
let content = HStack(spacing: 4) {
Text(label)
.font(.title2.weight(.semibold))
.foregroundStyle(color)
if let isExpanded {
Image(systemName: isExpanded ? "chevron.down" : "chevron.up")
.font(.body.weight(.semibold))
.foregroundStyle(color)
}
Spacer(minLength: 0)
}
.padding(.top, 12)
.padding(.bottom, 8)
.contentShape(Rectangle())
if let onToggle {
Button(action: onToggle) { content }
.buttonStyle(.plain)
.accessibilityAddTraits(.isHeader)
} else {
content.accessibilityAddTraits(.isHeader)
}
}
}