In good old UIKit times, when I worked on the white label app News, it was very helpful to separate app views/controllers from app stylings like colors and fonts. Nowadays, in the SwiftUI century, I tried to apply the same pattern.

Our first task is to define AppStyleProtocol, this usually looks the same as in UIKit.

protocol AppStyleProtocol {
    var colors: AppColorsProtocol { get }
    var fonts: AppFontsProtocol { get }
}
 
protocol AppColorsProtocol {
    var text: Color { get }
    var background: Color { get }
}
 
protocol AppFontsProtocol {
    var title: Font { get }
}

The second step, the same as in UIKit, is to create some implementation of AppStyleProtocol.

struct LimeAppStyle: AppStyleProtocol {
    let colors: AppColorsProtocol = LimeAppColors()
    let fonts: AppFontsProtocol = AppFonts()
}
 
struct LimeAppColors: AppColorsProtocol {
    let text = Color.red
    let background = Color.green
}
 
struct AppFonts: AppFontsProtocol {
    let title = Font.headline
}

Tip: In SwiftUI world to make things easier we can inject AppStyleProtocol implementation to every SwiftUI View like environment variable. I define a new environment style property for that. This environment property can be set only on the first View and then is injected to every SwiftUI View.

struct AppStyleKey: EnvironmentKey {
    static let defaultValue: AppStyleProtocol = AppStyle()
}
 
extension EnvironmentValues {
    var style: AppStyleProtocol {
        get { self[AppStyleKey.self] }
        set { self[AppStyleKey.self] = newValue }
    }
}

Tip: By using a View and Text extensions we can make our implementation more clear and powerful.

extension View {
    func style(_ style: AppStyleProtocol) -> some View {
        self
            .background(style.colors.background)
    }
}
 
extension Text {
    func title(_ style: AppStyleProtocol) -> some View {
        self
            .foregroundColor(style.colors.text)
            .font(style.fonts.title)
    }
}

And finally can implement some view and easily style without define any specific color, font or what you want in your custome View.

struct SampleView: View {
    @Environment(\.style) var style: AppStyleProtocol
 
    var body: some View {
        VStack {
            Text("Fruits!")
                .title(style)
        }
        .frame(width: 300, height: 300)
        .style(style)
    }
}

Same View with different AppStyle - default lime and orange then can looks like this: AppStyle example

Download code example with LimeAppStyle and OrangeAppStyle.