|
| 1 | +import BlueprintUI |
| 2 | +import UIKit |
| 3 | + |
| 4 | +/// An element that allows overriding the user interface style (light/dark mode) for its wrapped content. |
| 5 | +/// |
| 6 | +/// Use this element to force a specific appearance for a portion of your UI, regardless of the system-wide |
| 7 | +/// settings. This can be useful when you need to ensure certain UI elements maintain a consistent appearance |
| 8 | +/// across different user interface styles. |
| 9 | +/// |
| 10 | +/// Example: |
| 11 | +/// ```swift |
| 12 | +/// let content = Label(text: "Hello, World!") |
| 13 | +/// let forcedLightMode = UserInterfaceStyleOverridingElement( |
| 14 | +/// userInterfaceStyle: .light, |
| 15 | +/// wrapping: content |
| 16 | +/// ) |
| 17 | +/// ``` |
| 18 | +public struct UserInterfaceStyleOverridingElement: Element { |
| 19 | + |
| 20 | + /// The element being wrapped with the overridden interface style. |
| 21 | + public var wrappedElement: Element |
| 22 | + |
| 23 | + /// The user interface style to apply to the wrapped content. |
| 24 | + /// This can be `.light`, `.dark`, or `.unspecified`. |
| 25 | + public var userInterfaceStyle: UIUserInterfaceStyle |
| 26 | + |
| 27 | + /// Creates a new element that overrides the user interface style for its wrapped content. |
| 28 | + /// |
| 29 | + /// - Parameters: |
| 30 | + /// - userInterfaceStyle: The desired interface style to apply (`.light`, `.dark`, or `.unspecified`). |
| 31 | + /// - wrapping: The content whose interface style should be overridden. |
| 32 | + public init( |
| 33 | + userInterfaceStyle: UIUserInterfaceStyle, |
| 34 | + wrapping content: () -> (Element) |
| 35 | + ) { |
| 36 | + self.userInterfaceStyle = userInterfaceStyle |
| 37 | + wrappedElement = content() |
| 38 | + } |
| 39 | + |
| 40 | + public var content: ElementContent { |
| 41 | + ElementContent(child: wrappedElement) |
| 42 | + } |
| 43 | + |
| 44 | + public func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription? { |
| 45 | + UIView.describe { config in |
| 46 | + config[\.overrideUserInterfaceStyle] = userInterfaceStyle |
| 47 | + } |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +extension Element { |
| 52 | + /// Wraps this element in a `UserInterfaceStyleOverridingElement` to override its interface style. |
| 53 | + /// |
| 54 | + /// This method provides a convenient way to override the user interface style (light/dark mode) |
| 55 | + /// for any element. |
| 56 | + /// |
| 57 | + /// Example: |
| 58 | + /// ```swift |
| 59 | + /// Label(text: "Always Light Mode") |
| 60 | + /// .overrideUserInterfaceStyle(.light) |
| 61 | + /// ``` |
| 62 | + /// |
| 63 | + /// - Parameter override: The desired interface style to apply. Defaults to `.unspecified`. |
| 64 | + /// - Returns: A new element wrapped with the specified interface style override. |
| 65 | + public func overrideUserInterfaceStyle( |
| 66 | + _ override: UIUserInterfaceStyle = .unspecified |
| 67 | + ) -> UserInterfaceStyleOverridingElement { |
| 68 | + UserInterfaceStyleOverridingElement(userInterfaceStyle: override) { |
| 69 | + self |
| 70 | + } |
| 71 | + } |
| 72 | +} |
0 commit comments