Files
element-x-ios/ElementX/Sources/AppHooks/HealthChat/HealthChatCompoundHook.swift
T

100 lines
3.9 KiB
Swift

//
// Copyright 2026 Novaloop AG
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
import UIKit
/// Recolours Compound's accent token family to the HealthChat brand.
/// Applied once at startup from `AppCoordinator` via `AppHooks.compoundHook`. Because the override
/// runs at app startup (not in previews), preview snapshots keep the default Compound colours.
struct HealthChatCompoundHook: CompoundHookProtocol {
func override(colors: CompoundColors, uiColors: CompoundUIColors) {
let brand = HealthChatBrandColors.brand
let tint = HealthChatBrandColors.tint
// Solid accent → brand blue (primary + send buttons, links, accent icons, badges, borders).
// NB: bgAccentRest is a SOLID fill (behind a white icon on the send button), not a subtle tint.
let solidColorTokens: [KeyPath<CompoundColorTokens, Color>] = [
\.bgActionPrimaryRest,
\.bgAccentRest,
\.iconAccentPrimary,
\.iconAccentTertiary,
\.textActionPrimary,
\.textActionAccent,
\.textLinkExternal,
\.borderInteractivePrimary,
\.borderAccentPrimary,
\.textBadgeAccent
]
let solidUIColorTokens: [KeyPath<CompoundUIColorTokens, UIColor> & Sendable] = [
\.bgActionPrimaryRest,
\.bgAccentRest,
\.iconAccentPrimary,
\.iconAccentTertiary,
\.textActionPrimary,
\.textActionAccent,
\.textLinkExternal,
\.borderInteractivePrimary,
\.borderAccentPrimary,
\.textBadgeAccent
]
for keyPath in solidColorTokens {
colors.override(keyPath, with: Color(brand))
}
for keyPath in solidUIColorTokens {
uiColors.override(keyPath, with: brand)
}
// Primary button pressed state. The disabled state stays Compound's neutral grey.
colors.override(\.bgActionPrimaryPressed, with: Color(HealthChatBrandColors.brandPressed))
uiColors.override(\.bgActionPrimaryPressed, with: HealthChatBrandColors.brandPressed)
// Gradient "super"/action buttons → brand blue (SwiftUI-only concept).
let gradientTokens: [KeyPath<CompoundColorTokens, Color>] = [
\.gradientActionStop1,
\.gradientActionStop2,
\.gradientActionStop3,
\.gradientActionStop4
]
for keyPath in gradientTokens {
colors.override(keyPath, with: Color(brand))
}
// Subtle gradient (home screen bloom, highlighted timeline item) → brand blue fading out,
// at the opacities Compound uses for its green stops. Stop 6 stays transparent.
let subtleGradientTokens: [KeyPath<CompoundColorTokens, Color>] = [
\.gradientSubtleStop1,
\.gradientSubtleStop2,
\.gradientSubtleStop3,
\.gradientSubtleStop4,
\.gradientSubtleStop5
]
for (keyPath, opacity) in zip(subtleGradientTokens, [0.41, 0.23, 0.11, 0.06, 0.03]) {
colors.override(keyPath, with: Color(brand).opacity(opacity))
}
// Subtle accent backgrounds (paired with accent-coloured foregrounds) → brand tint.
let tintColorTokens: [KeyPath<CompoundColorTokens, Color>] = [
\.bgAccentSelected,
\.bgBadgeAccent,
\.borderAccentSubtle
]
let tintUIColorTokens: [KeyPath<CompoundUIColorTokens, UIColor> & Sendable] = [
\.bgAccentSelected,
\.bgBadgeAccent,
\.borderAccentSubtle
]
for keyPath in tintColorTokens {
colors.override(keyPath, with: Color(tint))
}
for keyPath in tintUIColorTokens {
uiColors.override(keyPath, with: tint)
}
}
}