diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index ef0b9018..f05784ea 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -63,6 +63,8 @@ EA0D1C412A6AD61C00E5C127 /* Typography+Additional.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */; }; EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */; }; EA0FC2C62914222900DF80B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */; }; + EA225FC72CA4845100B6B3B3 /* LanguageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA225FC62CA4845100B6B3B3 /* LanguageManager.swift */; }; + EA225FC92CA4932900B6B3B3 /* Typography+StyleProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA225FC82CA4932900B6B3B3 /* Typography+StyleProvider.swift */; }; EA297A5529FB07760031ED56 /* TooltipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA297A5429FB07760031ED56 /* TooltipLabelAttribute.swift */; }; EA297A5729FB0A360031ED56 /* AppleGuidelinesTouchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA297A5629FB0A360031ED56 /* AppleGuidelinesTouchable.swift */; }; EA2DC9B02BE175BA004F58C5 /* RequiredRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2DC9AF2BE175BA004F58C5 /* RequiredRule.swift */; }; @@ -286,6 +288,8 @@ EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawRepresentable.swift; sourceTree = ""; }; EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = ""; }; EA21C5DA2B600EDD00CFC139 /* VDSTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTokens.xcframework; path = ../SharedFrameworks/VDSTokens.xcframework; sourceTree = ""; }; + EA225FC62CA4845100B6B3B3 /* LanguageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageManager.swift; sourceTree = ""; }; + EA225FC82CA4932900B6B3B3 /* Typography+StyleProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+StyleProvider.swift"; sourceTree = ""; }; EA297A5429FB07760031ED56 /* TooltipLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TooltipLabelAttribute.swift; sourceTree = ""; }; EA297A5629FB0A360031ED56 /* AppleGuidelinesTouchable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesTouchable.swift; sourceTree = ""; }; EA2DC9AF2BE175BA004F58C5 /* RequiredRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequiredRule.swift; sourceTree = ""; }; @@ -814,12 +818,13 @@ EA3361B4288B2A360071C351 /* Classes */ = { isa = PBXGroup; children = ( + EAF2F4752C231EAA007BFEDC /* AccessibilityActionElement.swift */, + EAF2F4882C2A1075007BFEDC /* AlertViewController.swift */, EA985C1C296CD13600F2FF2E /* BundleManager.swift */, EAC58C282BF4118C00BA39FA /* ClearPopoverViewController.swift */, EAF7F0B8289C139800B287F5 /* ColorConfiguration.swift */, + EA225FC62CA4845100B6B3B3 /* LanguageManager.swift */, EAB5FEF02927F4AA00998C17 /* SelfSizingCollectionView.swift */, - EAF2F4752C231EAA007BFEDC /* AccessibilityActionElement.swift */, - EAF2F4882C2A1075007BFEDC /* AlertViewController.swift */, ); path = Classes; sourceTree = ""; @@ -987,6 +992,7 @@ EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */, EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */, EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */, + EA225FC82CA4932900B6B3B3 /* Typography+StyleProvider.swift */, ); path = Typography; sourceTree = ""; @@ -1370,6 +1376,7 @@ 44BD43B62C04866600644F87 /* TableRowModel.swift in Sources */, 71FC86DA2B96F44C00700965 /* PaginationButton.swift in Sources */, EABFEB642A26473700C4C106 /* NSAttributedString.swift in Sources */, + EA225FC72CA4845100B6B3B3 /* LanguageManager.swift in Sources */, EAF7F13328A2A16500B287F5 /* AttachmentLabelAttributeModel.swift in Sources */, EA0FC2C62914222900DF80B4 /* ButtonGroup.swift in Sources */, EA89200628B526D6006B9984 /* CheckboxGroup.swift in Sources */, @@ -1406,6 +1413,7 @@ 44604AD729CE196600E62B51 /* Line.swift in Sources */, 1808BEBC2BA41C3200129230 /* CarouselScrollbar.swift in Sources */, EAF978212A99035B00C2FEA9 /* Enabling.swift in Sources */, + EA225FC92CA4932900B6B3B3 /* Typography+StyleProvider.swift in Sources */, EAC58C062BED000200BA39FA /* CreditCard.swift in Sources */, EA5E3058295105A40082B959 /* Tilelet.swift in Sources */, 186D13CB2BBA8B1500986B53 /* DropdownSelect.swift in Sources */, diff --git a/VDS/Classes/LanguageManager.swift b/VDS/Classes/LanguageManager.swift new file mode 100644 index 00000000..4d7842b0 --- /dev/null +++ b/VDS/Classes/LanguageManager.swift @@ -0,0 +1,63 @@ +// +// LanguageManager.swift +// VDS +// +// Created by Matt Bruce on 9/25/24. +// + +import Foundation + +// Language Manager to control the current language setting +public class LanguageManager { + + // Enum to define supported languages + public enum SupportedLanguage: String, CustomStringConvertible { + case english = "en" + case spanish = "es" + + public var description: String { self == .english ? "English" : "Spanish"} + } + + // Private static variable to hold the in-memory current language + private static var _currentLanguage: SupportedLanguage? { + didSet { + TextStyle.Provider.updateCurrentStyles() + } + } + + // Static property to manage the current language setting + public static var currentLanguage: SupportedLanguage { + get { + // Check if there is an in-memory language setting + guard let _currentLanguage else { + + // set default + var deviceCurrentLanguage: SupportedLanguage = .english + + // Check device's preferred language + let deviceLanguage = Locale.preferredLanguages.first ?? "en" + if deviceLanguage.starts(with: "es") { + deviceCurrentLanguage = .spanish + } + + _currentLanguage = deviceCurrentLanguage + return deviceCurrentLanguage + } + + return _currentLanguage + } + set { + // Set the in-memory language + _currentLanguage = newValue + } + } + + // Method to set language using a language code string + public static func setLanguage(with code: String) { + if code.starts(with: "es") { + _currentLanguage = .spanish + } else { + _currentLanguage = .english + } + } +} diff --git a/VDS/Typography/Typogprahy+Styles.swift b/VDS/Typography/Typogprahy+Styles.swift index f2f572a8..256094c5 100644 --- a/VDS/Typography/Typogprahy+Styles.swift +++ b/VDS/Typography/Typogprahy+Styles.swift @@ -11,206 +11,69 @@ import VDSCoreTokens //MARK: Definitions extension TextStyle { - - // Static properties for different text styles - - public static let boldFeatureXLarge = TextStyle(rawValue: "boldFeatureXLarge", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, - edgeInsets: .bottom(UIDevice.isIPad ? -6: -4)) - - public static let featureXLarge = TextStyle(rawValue: "featureXLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, - letterSpacing: VDSTypography.letterSpacingSemiwide, - edgeInsets: .bottom(UIDevice.isIPad ? -6: -4)) - - public static let boldFeatureLarge = TextStyle(rawValue: "boldFeatureLarge", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, - edgeInsets: .bottom(UIDevice.isIPad ? -6: -2)) - - public static let featureLarge = TextStyle(rawValue: "featureLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, - letterSpacing: VDSTypography.letterSpacingSemiwide, - edgeInsets: .bottom(UIDevice.isIPad ? -6: -2)) - - public static let boldFeatureMedium = TextStyle(rawValue: "boldFeatureMedium", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, - edgeInsets: .bottom(UIDevice.isIPad ? -4: -2)) - - public static let featureMedium = TextStyle(rawValue: "featureMedium", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, - letterSpacing: VDSTypography.letterSpacingSemiwide, - edgeInsets: .bottom(UIDevice.isIPad ? -4: -2)) - - public static let boldFeatureSmall = TextStyle(rawValue: "boldFeatureSmall", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, - edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)) - - public static let featureSmall = TextStyle(rawValue: "featureSmall", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, - letterSpacing: VDSTypography.letterSpacingSemiwide, - edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)) - - public static let boldFeatureXSmall = TextStyle(rawValue: "boldFeatureXSmall", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, - edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)) - - public static let featureXSmall = TextStyle(rawValue: "featureXSmall", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, - letterSpacing: VDSTypography.letterSpacingSemiwide, - edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)) - - public static let boldTitle2XLarge = TextStyle(rawValue: "boldTitle2XLarge", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, - edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)) - - public static let title2XLarge = TextStyle(rawValue: "title2XLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, - letterSpacing: VDSTypography.letterSpacingSemiwide, - edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)) - - public static let boldTitleXLarge = TextStyle(rawValue: "boldTitleXLarge", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36) - - public static let titleXLarge = TextStyle(rawValue: "titleXLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36, - letterSpacing: VDSTypography.letterSpacingSemiwide) - - public static let boldTitleLarge = TextStyle(rawValue: "boldTitleLarge", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28) - - public static let titleLarge = TextStyle(rawValue: "titleLarge", - fontFace: UIDevice.isIPad ? .dsLight : .edsRegular, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28, - letterSpacing: UIDevice.isIPad ? VDSTypography.letterSpacingSemiwide : 0) - - public static let boldTitleMedium = TextStyle(rawValue: "boldTitleMedium", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24) - - public static let titleMedium = TextStyle(rawValue: "titleMedium", - fontFace: .edsRegular, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24) - - public static let boldTitleSmall = TextStyle(rawValue: "boldTitleSmall", - fontFace: .edsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20) - - public static let titleSmall = TextStyle(rawValue: "titleSmall", - fontFace: .edsRegular, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20) - - public static let boldBodyLarge = TextStyle(rawValue: "boldBodyLarge", - fontFace: .edsBold, - pointSize: VDSTypography.fontSizeBody16, - lineHeight: VDSTypography.lineHeightBody20, - letterSpacing: VDSTypography.letterSpacingWide) - - public static let bodyLarge = TextStyle(rawValue: "bodyLarge", - fontFace: .edsRegular, - pointSize: VDSTypography.fontSizeBody16, - lineHeight: VDSTypography.lineHeightBody20, - letterSpacing:VDSTypography.letterSpacingWide) - - public static let boldBodyMedium = TextStyle(rawValue: "boldBodyMedium", - fontFace: .edsBold, - pointSize: VDSTypography.fontSizeBody14, - lineHeight: VDSTypography.lineHeightBody18, - letterSpacing: VDSTypography.letterSpacingWide) - - public static let bodyMedium = TextStyle(rawValue: "bodyMedium", - fontFace: .edsRegular, - pointSize: VDSTypography.fontSizeBody14, - lineHeight: VDSTypography.lineHeightBody18, - letterSpacing: VDSTypography.letterSpacingWide) - - public static let boldBodySmall = TextStyle(rawValue: "boldBodySmall", - fontFace: .etxBold, - pointSize: VDSTypography.fontSizeBody12, - lineHeight: VDSTypography.lineHeightBody16) - - public static let bodySmall = TextStyle(rawValue: "bodySmall", - fontFace: .etxRegular, - pointSize: VDSTypography.fontSizeBody12, - lineHeight: VDSTypography.lineHeightBody16) - - public static let boldMicro = TextStyle(rawValue: "boldMicro", - fontFace: .etxBold, - pointSize: VDSTypography.fontSizeMicro11, - lineHeight: VDSTypography.lineHeightMicro16) - - public static let micro = TextStyle(rawValue: "micro", - fontFace: .etxRegular, - pointSize: VDSTypography.fontSizeMicro11, - lineHeight: VDSTypography.lineHeightMicro16) - - public static var allCases: [TextStyle] { - return [ - featureXLarge, - boldFeatureXLarge, - featureLarge, - boldFeatureLarge, - featureMedium, - boldFeatureMedium, - featureSmall, - boldFeatureSmall, - featureXSmall, - boldFeatureXSmall, - title2XLarge, - boldTitle2XLarge, - titleXLarge, - boldTitleXLarge, - titleLarge, - boldTitleLarge, - titleMedium, - boldTitleMedium, - titleSmall, - boldTitleSmall, - bodyLarge, - boldBodyLarge, - bodyMedium, - boldBodyMedium, - bodySmall, - boldBodySmall, - micro, - boldMicro - ] + internal enum Style: String, CaseIterable { + case boldFeatureXLarge + case featureXLarge + case boldFeatureLarge + case featureLarge + case boldFeatureMedium + case featureMedium + case boldFeatureSmall + case featureSmall + case boldFeatureXSmall + case featureXSmall + case boldTitle2XLarge + case title2XLarge + case boldTitleXLarge + case titleXLarge + case boldTitleLarge + case titleLarge + case boldTitleMedium + case titleMedium + case boldTitleSmall + case titleSmall + case boldBodyLarge + case bodyLarge + case boldBodyMedium + case bodyMedium + case boldBodySmall + case bodySmall + case boldMicro + case micro } + // Static properties for different text styles + public static var boldFeatureXLarge: TextStyle { Provider.style(for: .boldFeatureXLarge) } + public static var featureXLarge: TextStyle { Provider.style(for: .featureXLarge) } + public static var boldFeatureLarge: TextStyle { Provider.style(for: .boldFeatureLarge) } + public static var featureLarge: TextStyle { Provider.style(for: .featureLarge) } + public static var boldFeatureMedium: TextStyle { Provider.style(for: .boldFeatureMedium) } + public static var featureMedium: TextStyle { Provider.style(for: .featureMedium) } + public static var boldFeatureSmall: TextStyle { Provider.style(for: .boldFeatureSmall) } + public static var featureSmall: TextStyle { Provider.style(for: .featureSmall) } + public static var boldFeatureXSmall: TextStyle { Provider.style(for: .boldFeatureXSmall) } + public static var featureXSmall: TextStyle { Provider.style(for: .featureXSmall) } + public static var boldTitle2XLarge: TextStyle { Provider.style(for: .boldTitle2XLarge) } + public static var title2XLarge: TextStyle { Provider.style(for: .title2XLarge) } + public static var boldTitleXLarge: TextStyle { Provider.style(for: .boldTitleXLarge) } + public static var titleXLarge: TextStyle { Provider.style(for: .titleXLarge) } + public static var boldTitleLarge: TextStyle { Provider.style(for: .boldTitleLarge) } + public static var titleLarge: TextStyle { Provider.style(for: .titleLarge) } + public static var boldTitleMedium: TextStyle { Provider.style(for: .boldTitleMedium) } + public static var titleMedium: TextStyle { Provider.style(for: .titleMedium) } + public static var boldTitleSmall: TextStyle { Provider.style(for: .boldTitleSmall) } + public static var titleSmall: TextStyle { Provider.style(for: .titleSmall) } + public static var boldBodyLarge: TextStyle { Provider.style(for: .boldBodyLarge) } + public static var bodyLarge: TextStyle { Provider.style(for: .bodyLarge) } + public static var boldBodyMedium: TextStyle { Provider.style(for: .boldBodyMedium) } + public static var bodyMedium: TextStyle { Provider.style(for: .bodyMedium) } + public static var boldBodySmall: TextStyle { Provider.style(for: .boldBodySmall) } + public static var bodySmall: TextStyle { Provider.style(for: .bodySmall) } + public static var boldMicro: TextStyle { Provider.style(for: .boldMicro) } + public static var micro: TextStyle { Provider.style(for: .micro) } + + public static var allCases: [TextStyle] { Style.allCases.compactMap { Provider.style(for: $0) } } + public static func convert(font: UIFont) -> TextStyle { guard let found = allCases.first(where: { font.fontName == $0.fontFace.fontName && font.pointSize == $0.pointSize} ) else { return TextStyle(rawValue: "Custom\(font.fontName)", fontFace: .custom(font), pointSize: font.pointSize) diff --git a/VDS/Typography/Typography+StyleProvider.swift b/VDS/Typography/Typography+StyleProvider.swift new file mode 100644 index 00000000..ef690253 --- /dev/null +++ b/VDS/Typography/Typography+StyleProvider.swift @@ -0,0 +1,246 @@ +// +// Typography+StyleProvider.swift +// VDS +// +// Created by Matt Bruce on 9/25/24. +// + +import Foundation +import UIKit +import VDSCoreTokens + +extension TextStyle { + // Class responsible for providing the correct TextStyles based on language + public class Provider { + + // Base styles for English (default) + private static let baseStyles: [Style: TextStyle] = [ + .boldFeatureXLarge: TextStyle(rawValue: Style.boldFeatureXLarge.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, + edgeInsets: .bottom(UIDevice.isIPad ? -6: -4)), + + .featureXLarge: TextStyle(rawValue: Style.featureXLarge.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, + letterSpacing: VDSTypography.letterSpacingSemiwide, + edgeInsets: .bottom(UIDevice.isIPad ? -6: -4)), + + .boldFeatureLarge: TextStyle(rawValue: Style.boldFeatureLarge.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, + edgeInsets: .bottom(UIDevice.isIPad ? -6: -2)), + + .featureLarge: TextStyle(rawValue: Style.featureLarge.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, + letterSpacing: VDSTypography.letterSpacingSemiwide, + edgeInsets: .bottom(UIDevice.isIPad ? -6: -2)), + + .boldFeatureMedium: TextStyle(rawValue: Style.boldFeatureMedium.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, + edgeInsets: .bottom(UIDevice.isIPad ? -4: -2)), + + .featureMedium: TextStyle(rawValue: Style.featureMedium.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, + letterSpacing: VDSTypography.letterSpacingSemiwide, + edgeInsets: .bottom(UIDevice.isIPad ? -4: -2)), + + .boldFeatureSmall: TextStyle(rawValue: Style.boldFeatureSmall.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, + edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)), + + .featureSmall: TextStyle(rawValue: Style.featureSmall.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, + letterSpacing: VDSTypography.letterSpacingSemiwide, + edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)), + + .boldFeatureXSmall: TextStyle(rawValue: Style.boldFeatureXSmall.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, + edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)), + + .featureXSmall: TextStyle(rawValue: Style.featureXSmall.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, + letterSpacing: VDSTypography.letterSpacingSemiwide, + edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)), + + .boldTitle2XLarge: TextStyle(rawValue: Style.boldTitle2XLarge.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, + edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)), + + .title2XLarge: TextStyle(rawValue: Style.title2XLarge.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, + letterSpacing: VDSTypography.letterSpacingSemiwide, + edgeInsets: .bottom(UIDevice.isIPad ? -2: 0)), + + .boldTitleXLarge: TextStyle(rawValue: Style.boldTitleXLarge.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36), + + .titleXLarge: TextStyle(rawValue: Style.titleXLarge.rawValue, + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36, + letterSpacing: VDSTypography.letterSpacingSemiwide), + + .boldTitleLarge: TextStyle(rawValue: Style.boldTitleLarge.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28), + + .titleLarge: TextStyle(rawValue: Style.titleLarge.rawValue, + fontFace: UIDevice.isIPad ? .dsLight : .edsRegular, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28, + letterSpacing: UIDevice.isIPad ? VDSTypography.letterSpacingSemiwide : 0), + + .boldTitleMedium: TextStyle(rawValue: Style.boldTitleMedium.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24), + + .titleMedium: TextStyle(rawValue: Style.titleMedium.rawValue, + fontFace: .edsRegular, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24), + + .boldTitleSmall: TextStyle(rawValue: Style.boldTitleSmall.rawValue, + fontFace: .edsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20), + + .titleSmall: TextStyle(rawValue: Style.titleSmall.rawValue, + fontFace: .edsRegular, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20), + + .boldBodyLarge: TextStyle(rawValue: Style.boldBodyLarge.rawValue, + fontFace: .edsBold, + pointSize: VDSTypography.fontSizeBody16, + lineHeight: VDSTypography.lineHeightBody20, + letterSpacing: VDSTypography.letterSpacingWide), + + .bodyLarge: TextStyle(rawValue: Style.bodyLarge.rawValue, + fontFace: .edsRegular, + pointSize: VDSTypography.fontSizeBody16, + lineHeight: VDSTypography.lineHeightBody20, + letterSpacing:VDSTypography.letterSpacingWide), + + .boldBodyMedium: TextStyle(rawValue: Style.boldBodyMedium.rawValue, + fontFace: .edsBold, + pointSize: VDSTypography.fontSizeBody14, + lineHeight: VDSTypography.lineHeightBody18, + letterSpacing: VDSTypography.letterSpacingWide), + + .bodyMedium: TextStyle(rawValue: Style.bodyMedium.rawValue, + fontFace: .edsRegular, + pointSize: VDSTypography.fontSizeBody14, + lineHeight: VDSTypography.lineHeightBody18, + letterSpacing: VDSTypography.letterSpacingWide), + + .boldBodySmall: TextStyle(rawValue: Style.boldBodySmall.rawValue, + fontFace: .etxBold, + pointSize: VDSTypography.fontSizeBody12, + lineHeight: VDSTypography.lineHeightBody16), + + .bodySmall: TextStyle(rawValue: Style.bodySmall.rawValue, + fontFace: .etxRegular, + pointSize: VDSTypography.fontSizeBody12, + lineHeight: VDSTypography.lineHeightBody16), + + .boldMicro: TextStyle(rawValue: Style.boldMicro.rawValue, + fontFace: .etxBold, + pointSize: VDSTypography.fontSizeMicro11, + lineHeight: VDSTypography.lineHeightMicro16), + + .micro: TextStyle(rawValue: Style.micro.rawValue, + fontFace: .etxRegular, + pointSize: VDSTypography.fontSizeMicro11, + lineHeight: VDSTypography.lineHeightMicro16) + + ] + + // Spanish lineHeight overrides + private static let spanishLineHeightOverrides: [Style: CGFloat] = [ + .boldFeatureXLarge: UIDevice.isIPad ? 156 : 104, + .featureXLarge: UIDevice.isIPad ? 156 : 104, + .boldFeatureLarge: UIDevice.isIPad ? 140 : 88, + .featureLarge: UIDevice.isIPad ? 140 : 88, + .boldFeatureMedium: UIDevice.isIPad ? 104 : 72, + .featureMedium: UIDevice.isIPad ? 104 : 72, + .boldFeatureSmall: UIDevice.isIPad ? 88 : 56, + .featureSmall: UIDevice.isIPad ? 88 : 56, + .boldFeatureXSmall: UIDevice.isIPad ? 72 : 48, + .featureXSmall: UIDevice.isIPad ? 72 : 48, + .boldTitle2XLarge: UIDevice.isIPad ? 72 : 48, + .title2XLarge: UIDevice.isIPad ? 72 : 48, + .boldTitleXLarge: UIDevice.isIPad ? 56 : 36, + .titleXLarge: UIDevice.isIPad ? 56 : 36 + ] + + // Cache for the current styles based on the current language + private static var currentStyles: [Style: TextStyle] = [:] + + // Function to get the style with conditional lineHeight adjustment + static func style(for key: Style) -> TextStyle { + DispatchQueue.once(block: { TextStyle.Provider.initialize() }) + guard let style = currentStyles[key] else { + fatalError("TextStyle for \(key.rawValue) is not defined.") + } + return style + } + + // Update current styles only once when language changes + static func updateCurrentStyles() { + // Start with the base styles + currentStyles = baseStyles + + // If the language is Spanish, apply the lineHeight overrides + if LanguageManager.currentLanguage == .spanish { + for (styleKey, spanishLineHeight) in spanishLineHeightOverrides { + if var style = currentStyles[styleKey] { + style = TextStyle( + rawValue: style.rawValue, + fontFace: style.fontFace, + pointSize: style.pointSize, + lineHeight: spanishLineHeight, // Apply the Spanish lineHeight + letterSpacing: style.letterSpacing, + edgeInsets: style.edgeInsets + ) + currentStyles[styleKey] = style + } + } + } + } + + // Initial setup to populate the current styles based on the initial language + static func initialize() { + updateCurrentStyles() + Style.allCases.forEach { style in + let found = Provider.currentStyles[style] + assert(found != nil, "\(style.rawValue) has not been set in the TextStyleProvider.baseStyles") + } + } + } +}