Feat: Working on pressure estimations feature
This commit is contained in:
175
Sources/Styleguide/Styles/TextLabelStyle.swift
Normal file
175
Sources/Styleguide/Styles/TextLabelStyle.swift
Normal file
@@ -0,0 +1,175 @@
|
||||
import SwiftUI
|
||||
|
||||
public protocol TextLabelStyle {
|
||||
|
||||
associatedtype Body: View
|
||||
typealias Configuration = TextLabelConfiguration
|
||||
|
||||
func makeBody(configuration: Self.Configuration) -> Self.Body
|
||||
}
|
||||
|
||||
extension TextLabelStyle {
|
||||
public func combining<Other: TextLabelStyle>(_ style: Other) -> AnyTextLabelStyle {
|
||||
AnyTextLabelStyle(style: self).combining(style)
|
||||
}
|
||||
}
|
||||
|
||||
public struct TextLabelConfiguration {
|
||||
|
||||
/// A type erased label for a text label.
|
||||
public struct Label: View {
|
||||
public var body: AnyView
|
||||
|
||||
public init<Content: View>(content: Content) {
|
||||
body = AnyView(content)
|
||||
}
|
||||
}
|
||||
|
||||
public let label: TextLabelConfiguration.Label
|
||||
}
|
||||
|
||||
public struct AnyTextLabelStyle: TextLabelStyle {
|
||||
private var _makeBody: (Configuration) -> AnyView
|
||||
|
||||
internal init(makeBody: @escaping (Configuration) -> AnyView) {
|
||||
self._makeBody = makeBody
|
||||
}
|
||||
|
||||
public init<S: TextLabelStyle>(style: S) {
|
||||
self._makeBody = { configuration in
|
||||
AnyView(style.makeBody(configuration: configuration))
|
||||
}
|
||||
}
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
_makeBody(configuration)
|
||||
}
|
||||
|
||||
public func combining<S: TextLabelStyle>(_ style: S) -> Self {
|
||||
Self.init { configuration in
|
||||
AnyView(
|
||||
self.makeBody(
|
||||
configuration: TextLabelConfiguration(
|
||||
label: .init(content: style.makeBody(configuration: configuration))
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct AutomaticTextLabelStyle: TextLabelStyle {
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
}
|
||||
}
|
||||
|
||||
private struct TextLabelStyleKey: EnvironmentKey {
|
||||
static let defaultValue = AnyTextLabelStyle(style: AutomaticTextLabelStyle())
|
||||
}
|
||||
|
||||
private struct SectionHeaderLabelStyleKey: EnvironmentKey {
|
||||
static let defaultValue = AnyTextLabelStyle(style: AutomaticTextLabelStyle())
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
public var textLabelStyle: AnyTextLabelStyle {
|
||||
get { self[TextLabelStyleKey.self] }
|
||||
set { self[TextLabelStyleKey.self] = newValue }
|
||||
}
|
||||
|
||||
public var sectionHeaderLabelStyle: AnyTextLabelStyle {
|
||||
get { self[SectionHeaderLabelStyleKey.self] }
|
||||
set { self[SectionHeaderLabelStyleKey.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
public struct FontTextLabelStyle: TextLabelStyle {
|
||||
let font: Font?
|
||||
let fontWeight: Font.Weight?
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
.font(font)
|
||||
.fontWeight(fontWeight)
|
||||
}
|
||||
}
|
||||
|
||||
public struct ColoredTextLabelStyle: TextLabelStyle {
|
||||
|
||||
let primary: Color
|
||||
let secondary: Color?
|
||||
let tertiary: Color?
|
||||
|
||||
@ViewBuilder
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
switch (secondary, tertiary) {
|
||||
case let (.some(secondary), .some(tertiary)):
|
||||
configuration.label.foregroundStyle(primary, secondary, tertiary)
|
||||
case let (.some(secondary), .none):
|
||||
configuration.label.foregroundStyle(primary, secondary)
|
||||
case let (.none, .some(tertiary)):
|
||||
configuration.label.foregroundStyle(primary, tertiary)
|
||||
case (.none, .none):
|
||||
configuration.label.foregroundStyle(primary)
|
||||
}
|
||||
}
|
||||
|
||||
public func font(_ font: Font? = nil, fontWeight: Font.Weight? = nil) -> AnyTextLabelStyle {
|
||||
self.combining(.font(font, fontWeight: fontWeight))
|
||||
}
|
||||
}
|
||||
|
||||
extension TextLabelStyle where Self == AutomaticTextLabelStyle {
|
||||
public static var automatic: Self {
|
||||
.init()
|
||||
}
|
||||
}
|
||||
|
||||
extension TextLabelStyle where Self == FontTextLabelStyle {
|
||||
public static func font(_ font: Font? = nil, fontWeight: Font.Weight? = nil) -> Self {
|
||||
.init(font: font, fontWeight: fontWeight)
|
||||
}
|
||||
|
||||
public static var heavyTitle2: Self {
|
||||
.font(.title2, fontWeight: .heavy)
|
||||
}
|
||||
}
|
||||
|
||||
extension TextLabelStyle where Self == ColoredTextLabelStyle {
|
||||
|
||||
public static func colored(_ color: Color) -> Self {
|
||||
.init(primary: color, secondary: nil, tertiary: nil)
|
||||
}
|
||||
|
||||
public static func colored(_ primary: Color, _ secondary: Color, _ tertiary: Color? = nil) -> Self {
|
||||
.init(primary: primary, secondary: secondary, tertiary: tertiary)
|
||||
}
|
||||
|
||||
public static var secondary: Self {
|
||||
self.colored(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
extension AnyTextLabelStyle {
|
||||
|
||||
public static var boldSecondary: AnyTextLabelStyle {
|
||||
ColoredTextLabelStyle(primary: .secondary, secondary: nil, tertiary: nil)
|
||||
.combining(.font(fontWeight: .bold))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension View {
|
||||
|
||||
public func textLabelStyle(_ style: AnyTextLabelStyle) -> some View {
|
||||
environment(\.textLabelStyle, style)
|
||||
}
|
||||
|
||||
public func textLabelStyle<S: TextLabelStyle>(_ style: S) -> some View {
|
||||
environment(\.textLabelStyle, AnyTextLabelStyle(style: style))
|
||||
}
|
||||
|
||||
public func sectionHeaderLabelStyle<S: TextLabelStyle>(_ style: S) -> some View {
|
||||
environment(\.sectionHeaderLabelStyle, AnyTextLabelStyle(style: style))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user