Added reactive bridge for swift UI in Colour Themes

This commit is contained in:
Christophe Deschamps 2025-10-04 07:27:14 +02:00
parent 9beadaadd9
commit b75db70d19
2 changed files with 42 additions and 16 deletions

View file

@ -22,15 +22,17 @@ import SwiftUI
extension Color { extension Color {
private static var theme: Theme { ColorProvider.shared.theme }
static let transparentColor = Color(hex: "#00000000") static let transparentColor = Color(hex: "#00000000")
static let black = Color(hex: "#000000") static let black = Color(hex: "#000000")
static let white = Color(hex: "#FFFFFF") static let white = Color(hex: "#FFFFFF")
static let orangeMain700 = ThemeManager.shared.currentTheme.main700 static var orangeMain700: Color { theme.main700 }
static let orangeMain500 = ThemeManager.shared.currentTheme.main500 static var orangeMain500: Color { theme.main500 }
static let orangeMain300 = ThemeManager.shared.currentTheme.main300 static var orangeMain300: Color { theme.main300 }
static let orangeMain100 = ThemeManager.shared.currentTheme.main100 static var orangeMain100: Color { theme.main100 }
static let orangeMain100Alpha50 = ThemeManager.shared.currentTheme.main100Alpha50 static var orangeMain100Alpha50: Color { theme.main100Alpha50 }
static let grayMain2c800 = Color(hex: "#22334D") static let grayMain2c800 = Color(hex: "#22334D")
static let grayMain2c800Alpha65 = Color(hex: "#A622334D") static let grayMain2c800Alpha65 = Color(hex: "#A622334D")

View file

@ -18,9 +18,11 @@
*/ */
import SwiftUI import SwiftUI
import Combine
// MARK: - Theme definition
struct Theme { struct Theme: Equatable {
let name: String let name: String
let main100: Color let main100: Color
let main100Alpha50: Color let main100Alpha50: Color
@ -29,26 +31,28 @@ struct Theme {
let main700: Color let main700: Color
} }
class ThemeManager { // MARK: - Theme Manager
final class ThemeManager: ObservableObject {
static let shared = ThemeManager() static let shared = ThemeManager()
private let themeKey = "selectedTheme" private let themeKey = "selectedTheme"
var currentTheme: Theme
init () { @Published var currentTheme: Theme = ThemeManager.orange
private init() {
let storedName = UserDefaults.standard.string(forKey: themeKey) let storedName = UserDefaults.standard.string(forKey: themeKey)
currentTheme = themes[storedName ?? ""] ?? ThemeManager.orange currentTheme = themes[storedName ?? ""] ?? ThemeManager.orange
} }
func applyTheme(named name: String) { func applyTheme(named name: String) {
guard let theme = themes[name] else { guard let theme = themes[name] else { return }
return withAnimation(.easeInOut(duration: 0.3)) {
self.currentTheme = theme
} }
self.currentTheme = theme UserDefaults.standard.setValue(name, forKey: themeKey)
UserDefaults.standard.setValue(name, forKey: self.themeKey)
} }
// MARK: - Theme Instances // MARK: - Theme Presets
let themes: [String: Theme] = [ let themes: [String: Theme] = [
orange.name: orange, orange.name: orange,
@ -122,5 +126,25 @@ class ThemeManager {
main500: Color(hex: "#800080"), main500: Color(hex: "#800080"),
main700: Color(hex: "#520052") main700: Color(hex: "#520052")
) )
}
// MARK: - Color Provider (reactive bridge for SwiftUI)
final class ColorProvider: ObservableObject {
static let shared = ColorProvider()
@Published private(set) var theme: Theme
private var cancellable: AnyCancellable?
private init() {
let manager = ThemeManager.shared
self.theme = manager.currentTheme
cancellable = manager.$currentTheme
.sink { [weak self] theme in
withAnimation(.easeInOut(duration: 0.3)) {
self?.theme = theme
}
}
}
} }