Bedrock/Sources/Bedrock/Theme/Typography.swift

139 lines
3.5 KiB
Swift

//
// Typography.swift
// Bedrock
//
// Semantic typography system with explicit, self-describing font names.
//
import SwiftUI
/// Semantic typography with explicit naming.
///
/// Each case name describes exactly what font you get:
/// - Base name = regular weight (e.g., `.title2` = Font.title2)
/// - `*Bold` = bold weight (e.g., `.title2Bold` = Font.title2.bold())
/// - `*Emphasis` = semibold weight (e.g., `.bodyEmphasis` = Font.body.weight(.semibold))
///
/// ## Example
///
/// ```swift
/// Text("Hello")
/// .font(Typography.heading.font)
///
/// // Or with the View extension:
/// Text("Hello")
/// .typography(.heading)
/// ```
public enum Typography: CaseIterable, Sendable {
// MARK: - Hero / Large Titles
/// Large title (regular weight).
case hero
/// Large title (bold weight).
case heroBold
/// Title (regular weight).
case title
/// Title (bold weight).
case titleBold
/// Title 2 (regular weight).
case title2
/// Title 2 (bold weight).
case title2Bold
/// Title 3 (regular weight).
case title3
/// Title 3 (bold weight).
case title3Bold
// MARK: - Headings
/// Headline (regular weight).
case heading
/// Headline (semibold weight).
case headingEmphasis
/// Headline (bold weight).
case headingBold
/// Subheadline (regular weight).
case subheading
/// Subheadline (semibold weight).
case subheadingEmphasis
// MARK: - Body
/// Body text (regular weight).
case body
/// Body text (semibold weight).
case bodyEmphasis
/// Callout text (regular weight).
case callout
/// Callout text (semibold weight).
case calloutEmphasis
// MARK: - Micro
/// Footnote text (regular weight).
case footnote
/// Footnote text (semibold weight).
case footnoteEmphasis
/// Caption text (regular weight).
case caption
/// Caption text (semibold weight).
case captionEmphasis
/// Caption 2 text (regular weight).
case caption2
/// Caption 2 text (semibold weight).
case caption2Emphasis
// MARK: - Font
/// The SwiftUI Font for this typography style.
public var font: Font {
switch self {
case .hero: .largeTitle
case .heroBold: .largeTitle.bold()
case .title: .title
case .titleBold: .title.bold()
case .title2: .title2
case .title2Bold: .title2.bold()
case .title3: .title3
case .title3Bold: .title3.bold()
case .heading: .headline
case .headingEmphasis: .headline.weight(.semibold)
case .headingBold: .headline.bold()
case .subheading: .subheadline
case .subheadingEmphasis: .subheadline.weight(.semibold)
case .body: .body
case .bodyEmphasis: .body.weight(.semibold)
case .callout: .callout
case .calloutEmphasis: .callout.weight(.semibold)
case .footnote: .footnote
case .footnoteEmphasis: .footnote.weight(.semibold)
case .caption: .caption
case .captionEmphasis: .caption.weight(.semibold)
case .caption2: .caption2
case .caption2Emphasis: .caption2.weight(.semibold)
}
}
}
// MARK: - View Extension
extension View {
/// Applies a typography style to the view.
///
/// ```swift
/// Text("Hello")
/// .typography(.heading)
/// ```
public func typography(_ style: Typography) -> some View {
self.font(style.font)
}
}