// // Typography.swift // VDS // // Created by Matt Bruce on 8/16/22. // import Foundation import VDSTypographyTokens public enum TextPosition: String, Codable, CaseIterable { case left, right, center var textAlignment: NSTextAlignment { switch self { case .left: return NSTextAlignment.left case .right: return NSTextAlignment.right case .center: return NSTextAlignment.center } } } public enum TypographicalStyle: String, Codable, CaseIterable { case FeatureXLarge case BoldFeatureXLarge case FeatureLarge case BoldFeatureLarge case FeatureMedium case BoldFeatureMedium case FeatureSmall case BoldFeatureSmall case FeatureXSmall case BoldFeatureXSmall case Title2XLarge case BoldTitle2XLarge case TitleXLarge case BoldTitleXLarge case TitleLarge case BoldTitleLarge case TitleMedium case BoldTitleMedium case TitleSmall case BoldTitleSmall case BodyLarge case BoldBodyLarge case BodyMedium case BoldBodyMedium case BodySmall case BoldBodySmall case Micro case BoldMicro public static var defaultStyle: TypographicalStyle { return .BodyLarge } } //MARK: FontCategory extension TypographicalStyle { public enum FontCategory: String, Codable, CaseIterable { case feature = "Feature" case title = "Title" case body = "Body" case micro = "Micro" public var sizes: [FontSize] { switch self { case .feature: return [.xlarge, .large, .medium, .small, .xsmall] case .title: return [.xxlarge, .xlarge, .large, .medium, .small] case .body: return [.large, .medium, .small] case .micro: return [] } } public func style(for fontSize: FontSize?, isBold: Bool = false) -> TypographicalStyle? { let styleName = "\(isBold ? "Bold" : "")\(self.rawValue)\(fontSize?.rawValue ?? "")" guard let style = TypographicalStyle(rawValue: styleName) else { return nil } return style } } } //MARK: FontSize extension TypographicalStyle { public enum FontSize: String, Codable, CaseIterable { case xxlarge = "2XLarge" case xlarge = "XLarge" case large = "Large" case medium = "Medium" case small = "Small" case xsmall = "XSmall" } } //MARK: PointSize extension TypographicalStyle { public var pointSize: CGFloat { switch self { case .FeatureXLarge, .BoldFeatureXLarge: return UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96 case .FeatureLarge, .BoldFeatureLarge: return UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80 case .FeatureMedium, .BoldFeatureMedium: return UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64 case .FeatureSmall, .BoldFeatureSmall: return UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48 case .FeatureXSmall, .BoldFeatureXSmall: return UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40 case .Title2XLarge, .BoldTitle2XLarge: return UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40 case .TitleXLarge, .BoldTitleXLarge: return UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32 case .TitleLarge, .BoldTitleLarge: return UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24 case .TitleMedium, .BoldTitleMedium: return UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20 case .TitleSmall, .BoldTitleSmall: return UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16 case .BodyLarge, .BoldBodyLarge: return VDSTypography.fontSizeBody16 case .BodyMedium, .BoldBodyMedium: return VDSTypography.fontSizeBody14 case .BodySmall, .BoldBodySmall: return VDSTypography.fontSizeBody12 case .Micro, .BoldMicro: return VDSTypography.fontSizeMicro11 } } } //MARK: LineHeight extension TypographicalStyle { public var lineHeight: CGFloat { switch self { case .FeatureXLarge, .BoldFeatureXLarge: return UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88 case .FeatureLarge, .BoldFeatureLarge: return UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76 case .FeatureMedium, .BoldFeatureMedium: return UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64 case .FeatureSmall, .BoldFeatureSmall: return UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48 case .FeatureXSmall, .BoldFeatureXSmall: return UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40 case .Title2XLarge, .BoldTitle2XLarge: return UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40 case .TitleXLarge, .BoldTitleXLarge: return UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36 case .TitleLarge, .BoldTitleLarge: return UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28 case .TitleMedium, .BoldTitleMedium: return UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24 case .TitleSmall, .BoldTitleSmall: return UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20 case .BodyLarge, .BoldBodyLarge: return VDSTypography.lineHeightBody20 case .BodyMedium, .BoldBodyMedium: return VDSTypography.lineHeightBody18 case .BodySmall, .BoldBodySmall: return VDSTypography.lineHeightBody16 case .Micro, .BoldMicro: return VDSTypography.lineHeightMicro16 } } } //MARK: LetterSpacing extension TypographicalStyle { public var letterSpacing: CGFloat { switch self { case .FeatureXLarge, .FeatureLarge, .FeatureMedium, .FeatureSmall, .FeatureXSmall, .Title2XLarge, .TitleXLarge, .TitleLarge: return 0.25 case .BoldBodyLarge, .BodyLarge, .BoldBodyMedium, .BodyMedium: return 0.5 default: return 0.0 } } } //MARK: Alignments extension TypographicalStyle { public var aligments: [TextPosition] { return [.left, .center] } } //MARK: Fonts extension TypographicalStyle { public var fontFace: Fonts { switch self { case .BoldFeatureXLarge, .BoldFeatureLarge, .BoldFeatureMedium, .BoldFeatureSmall, .BoldFeatureXSmall, .BoldTitle2XLarge, .BoldTitleXLarge, .BoldTitleLarge, .BoldTitleMedium, .BoldTitleSmall, .BoldBodyLarge, .BoldBodyMedium: return .dsBold case .FeatureXLarge, .FeatureLarge, .FeatureMedium, .FeatureSmall, .FeatureXSmall, .Title2XLarge, .TitleXLarge: return .dsLight case .TitleLarge, .TitleMedium, .TitleSmall, .BodyLarge, .BodyMedium: return .dsRegular case .BoldBodySmall, .BoldMicro: return .txBold case .BodySmall, .Micro: return .txRegular } } public var font: UIFont { return fontFace.font(ofSize: pointSize) } public var superScriptFont: UIFont { return fontFace.font(ofSize: pointSize / 2) } }