// // VDSFontStyles.swift // VDS // // Created by Matt Bruce on 7/27/22. // import Foundation import UIKit import VDSTypographyTokens public enum FontWeight: String, Codable { case regular case bold var titleCase: String { switch self { case .regular: return "Regular" case .bold: return "Bold" } } } 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 FontCategory: String, Codable, CaseIterable { case feature case title case body case micro var fontSizes: [FontSize] { switch self { case .feature: return [.xlarge, .medium, .small, .xsmall] case .title: return [.xxlarge, .xlarge, .large, .medium, .small] case .body: return [.large, .medium, .small, .xsmall] case .micro: return [] } } var titleCase: String { switch self { case .feature: return "Feature" case .title: return "Title" case .body: return "Body" case .micro: return "Micro" } } } public enum FontSize: String, Codable, CaseIterable { case xxlarge case xlarge case large case medium case small case xsmall var titleCase: String { switch self { case .xxlarge: return "2XLarge" case .xlarge: return "XLarge" case .large: return "Large" case .medium: return "Medium" case .small: return "Small" case .xsmall: return "XSmall" } } } public enum FontStyle: String, Codable, CaseIterable { public enum Error: Swift.Error { case styleNotFound(fontCatergory: FontCategory, fontSize: FontSize, availableFontSizes: [FontSize]) } case RegularFeatureXLarge case BoldFeatureXLarge case RegularFeatureLarge case BoldFeatureLarge case RegularFeatureMedium case BoldFeatureMedium case RegularFeatureSmall case BoldFeatureSmall case RegularFeatureXSmall case BoldFeatureXSmall case RegularTitle2XLarge case BoldTitle2XLarge case RegularTitleXLarge case BoldTitleXLarge case RegularTitleLarge case BoldTitleLarge case RegularTitleMedium case BoldTitleMedium case RegularTitleSmall case BoldTitleSmall case RegularBodyLarge case BoldBodyLarge case RegularBodyMedium case BoldBodyMedium case RegularBodySmall case BoldBodySmall case RegularMicro case BoldMicro public var pointSize: CGFloat { switch self { case .RegularFeatureXLarge, .BoldFeatureXLarge: return UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96 case .RegularFeatureLarge, .BoldFeatureLarge: return UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80 case .RegularFeatureMedium, .BoldFeatureMedium: return UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64 case .RegularFeatureSmall, .BoldFeatureSmall: return UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48 case .RegularFeatureXSmall, .BoldFeatureXSmall: return UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40 case .RegularTitle2XLarge, .BoldTitle2XLarge: return UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40 case .RegularTitleXLarge, .BoldTitleXLarge: return UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32 case .RegularTitleLarge, .BoldTitleLarge: return UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24 case .RegularTitleMedium, .BoldTitleMedium: return UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20 case .RegularTitleSmall, .BoldTitleSmall: return UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16 case .RegularBodyLarge, .BoldBodyLarge: return VDSTypography.fontSizeBody16 case .RegularBodyMedium, .BoldBodyMedium: return VDSTypography.fontSizeBody14 case .RegularBodySmall, .BoldBodySmall: return VDSTypography.fontSizeBody12 case .RegularMicro, .BoldMicro: return VDSTypography.fontSizeMicro11 } } public var fontFace: Fonts { switch self { case .BoldFeatureXLarge, .BoldFeatureLarge, .BoldFeatureMedium, .BoldFeatureSmall, .BoldFeatureXSmall, .BoldTitle2XLarge, .BoldTitleXLarge, .BoldTitleLarge, .BoldTitleMedium, .BoldTitleSmall, .BoldBodyLarge, .BoldBodyMedium, .BoldBodySmall: return .dsBold case .RegularFeatureXLarge, .RegularFeatureLarge, .RegularFeatureMedium, .RegularFeatureSmall, .RegularFeatureXSmall, .RegularTitle2XLarge, .RegularTitleXLarge, .RegularTitleLarge, .RegularTitleMedium, .RegularTitleSmall, .RegularBodyLarge, .RegularBodyMedium, .RegularBodySmall: return .dsRegular case .BoldMicro: return .txBold case .RegularMicro: return .txRegular } } public static var defaultStyle: FontStyle { return FontStyle.RegularBodyLarge } public var font: UIFont { return fontFace.font(ofSize: pointSize) } public var superScriptFont: UIFont { return fontFace.font(ofSize: pointSize / 2) } public static func style(for category: FontCategory, fontWeight: FontWeight, fontSize: FontSize) throws -> FontStyle { let fontName = "\(fontWeight.titleCase)\(category.titleCase)\(fontSize.titleCase)" guard let fontStyle = FontStyle(rawValue: fontName) else { throw FontStyle.Error.styleNotFound(fontCatergory: category, fontSize: fontSize, availableFontSizes: category.fontSizes) } return fontStyle } public static func font(for category: FontCategory, fontWeight: FontWeight, fontSize: FontSize) throws -> UIFont { return try style(for: category, fontWeight: fontWeight, fontSize: fontSize).font } }