feat(brand): logoAssetName für Custom-Logos (v0.7.0)

ManaBrandConfig.logoAssetName ergänzt — Apps liefern einen Asset-
Catalog-Namen, ManaAuthScaffold rendert das Bundle-Asset 64×64pt
ohne Tint statt eines getinteten SF-Symbols. logoSymbol bleibt
Fallback.

Hintergrund: Pageta hat ein eigenes Apple-Icon-Composer-SVG; SF-
Symbol "book.pages" sah neben dem polierten App-Icon unecht aus.

Additive Änderung, alle bestehenden Apps quellkompatibel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-22 12:29:19 +02:00
parent 8f4d4b0c03
commit d621cb8372
3 changed files with 70 additions and 1 deletions

View file

@ -23,8 +23,18 @@ public struct ManaBrandConfig: Sendable {
/// Optionales SF-Symbol, das zentral über dem App-Namen erscheint.
/// Z.B. `"rectangle.stack.fill"` für Cardecky, `"map.fill"` für
/// Manaspur. Wenn nil, wird kein Icon gerendert.
///
/// Wenn ``logoAssetName`` gesetzt ist, hat das Vorrang das
/// SF-Symbol dient als Fallback.
public let logoSymbol: String?
/// Optionaler Asset-Catalog-Name eines App-spezifischen Logos
/// (z.B. SVG aus dem App Icon Composer). Hat Vorrang vor
/// ``logoSymbol``. Das Asset muss im Bundle der konsumierenden App
/// liegen und Template-fähig sein, wenn es brand.primary annehmen
/// soll sonst wird's in Originalfarben gerendert.
public let logoAssetName: String?
// MARK: - Theme-Farben
/// Seiten-Hintergrund.
@ -58,6 +68,7 @@ public struct ManaBrandConfig: Sendable {
appName: String,
tagline: String? = nil,
logoSymbol: String? = nil,
logoAssetName: String? = nil,
background: Color,
foreground: Color,
surface: Color,
@ -71,6 +82,7 @@ public struct ManaBrandConfig: Sendable {
self.appName = appName
self.tagline = tagline
self.logoSymbol = logoSymbol
self.logoAssetName = logoAssetName
self.background = background
self.foreground = foreground
self.surface = surface
@ -91,6 +103,7 @@ public extension ManaBrandConfig {
appName: "mana",
tagline: nil,
logoSymbol: nil,
logoAssetName: nil,
background: PlatformPalette.background,
foreground: .primary,
surface: PlatformPalette.surface,

View file

@ -47,7 +47,16 @@ public struct ManaAuthScaffold<Content: View>: View {
@ViewBuilder
private var header: some View {
VStack(spacing: 12) {
if let symbol = brand.logoSymbol {
if let assetName = brand.logoAssetName {
// App-spezifisches Logo aus dem Bundle der konsumierenden
// App. Größere 64pt-Variante, damit ein detailliertes
// Custom-Logo seinen Charakter zeigt (statt nur als
// SF-Symbol-Stand-In zu wirken).
Image(assetName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 64, height: 64)
} else if let symbol = brand.logoSymbol {
Image(systemName: symbol)
.font(.system(size: 44, weight: .medium))
.foregroundStyle(brand.primary)