579 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Swift
		
	
	
	
			
		
		
	
	
			579 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Swift
		
	
	
	
| //
 | ||
| //  CLSystemTokens.swift
 | ||
| //  Crush
 | ||
| //
 | ||
| //  Created by Leon on 2025/7/11.
 | ||
| //
 | ||
| 
 | ||
| import UIKit
 | ||
| 
 | ||
| // MARK: - Convenience functions
 | ||
| extension UIColor {
 | ||
|     static var c: SystemColor {
 | ||
|         SystemColor()
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| extension UIFont {
 | ||
|     static var t: SystemFont {
 | ||
|         SystemFont()
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| @dynamicMemberLookup
 | ||
| struct SystemColor {
 | ||
|     subscript(dynamicMember key: String) -> UIColor {
 | ||
|         guard let token = CLEnumSystemToken.allCases.first(where: { "\($0)" == key }) else {
 | ||
|             return .black
 | ||
|         }
 | ||
|         return CLSystemToken.color(token: token) ?? .red
 | ||
|     }
 | ||
| 
 | ||
|     func systemTokenValue(for key: String) -> String? {
 | ||
|         CLEnumSystemToken.allCases.first(where: { "\($0)" == key })?.rawValue
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| @dynamicMemberLookup
 | ||
| struct SystemFont {
 | ||
|     subscript(dynamicMember key: String) -> UIFont {
 | ||
|         guard let token = CLEnumSystemToken.allCases.first(where: { "\($0)" == key }) else {
 | ||
|             return .systemFont(ofSize: 14)
 | ||
|         }
 | ||
|         return CLSystemToken.font(token: token)
 | ||
|     }
 | ||
| 
 | ||
|     func systemTokenValue(for key: String) -> String? {
 | ||
|         CLEnumSystemToken.allCases.first(where: { "\($0)" == key })?.rawValue
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // MARK: - CLEnumSystemToken: Enums and Constants
 | ||
| 
 | ||
| enum CLEnumSystemToken: String, CaseIterable {
 | ||
|     init?(caseName: String) {
 | ||
|         self = CLEnumSystemToken.allCases.first(where: { "\($0)" == caseName }) ?? .cpn
 | ||
|     }
 | ||
| 
 | ||
|     case cpn = "color.primary.normal"
 | ||
|     case cph = "color.primary.hover"
 | ||
|     case cpp = "color.primary.press"
 | ||
|     case cpd = "color.primary.disabled"
 | ||
|     case cpvn = "color.primary.variant.normal"
 | ||
|     case cpvh = "color.primary.variant.hover"
 | ||
|     case cpvp = "color.primary.variant.press"
 | ||
|     case cpvd = "color.primary.variant.disabled"
 | ||
|     case cpgn = "color.primary.gradient.normal"
 | ||
|     case cpgh = "color.primary.gradient.hover"
 | ||
|     case cpgp = "color.primary.gradient.press"
 | ||
|     case cpgd = "color.primary.gradient.disabled"
 | ||
|     case cin = "color.important.normal"
 | ||
|     case cih = "color.important.hover"
 | ||
|     case cip = "color.important.press"
 | ||
|     case cid = "color.important.disabled"
 | ||
|     case civn = "color.important.variant.normal"
 | ||
|     case civh = "color.important.variant.hover"
 | ||
|     case civp = "color.important.variant.press"
 | ||
|     case civd = "color.important.variant.disabled"
 | ||
|     case cign = "color.important.gradient.normal"
 | ||
|     case cigh = "color.important.gradient.hover"
 | ||
|     case cigp = "color.important.gradient.press"
 | ||
|     case ciopn = "color.important.onpic.normal"
 | ||
|     case cposn = "color.positive.normal"
 | ||
|     case cposh = "color.positive.hover"
 | ||
|     case cposp = "color.positive.press"
 | ||
|     case cposd = "color.positive.disabled"
 | ||
|     case cposvn = "color.positive.variant.normal"
 | ||
|     case cposvh = "color.positive.variant.hover"
 | ||
|     case cposvp = "color.positive.variant.press"
 | ||
|     case cposvd = "color.positive.variant.disabled"
 | ||
|     case cposgn = "color.positive.gradient.normal"
 | ||
|     case cposopn = "color.positive.onpic.normal"
 | ||
|     case cwn = "color.warning.normal"
 | ||
|     case cwh = "color.warning.hover"
 | ||
|     case cwp = "color.warning.press"
 | ||
|     case cwd = "color.warning.disabled"
 | ||
|     case cwvn = "color.warning.variant.normal"
 | ||
|     case cwvh = "color.warning.variant.hover"
 | ||
|     case cwvp = "color.warning.variant.press"
 | ||
|     case cwvd = "color.warning.variant.disabled"
 | ||
|     case cwgn = "color.warning.gradient.normal"
 | ||
|     case cwopn = "color.warning.onpic.normal"
 | ||
|     case cen = "color.emphasis.normal"
 | ||
|     case ceh = "color.emphasis.hover"
 | ||
|     case cep = "color.emphasis.press"
 | ||
|     case ced = "color.emphasis.disabled"
 | ||
|     case cevn = "color.emphasis.variant.normal"
 | ||
|     case cevh = "color.emphasis.variant.hover"
 | ||
|     case cevp = "color.emphasis.variant.press"
 | ||
|     case cevd = "color.emphasis.variant.disabled"
 | ||
|     case cegn = "color.emphasis.grandient.normal"
 | ||
|     case cegh = "color.emphasis.grandient.hover"
 | ||
|     case cegp = "color.emphasis.grandient.press"
 | ||
|     case cegd = "color.emphasis.grandient.disabled"
 | ||
|     case ceopn = "color.emphasis.onpic.normal"
 | ||
|     case cbd = "color.background.default"
 | ||
|     case cbs = "color.background.specialmap"
 | ||
|     case cbdi = "color.background.district"
 | ||
|     case csbn = "color.surface.base.normal"
 | ||
|     case csbh = "color.surface.base.hover"
 | ||
|     case csbp = "color.surface.base.press"
 | ||
|     case csbsn = "color.surface.base.specialmap.normal"
 | ||
|     case csbsh = "color.surface.base.specialmap.hover"
 | ||
|     case csbsp = "color.surface.base.specialmap.press"
 | ||
|     case csbsd = "color.surface.base.specialmap.disabled"
 | ||
|     case csfn = "color.surface.float.normal"
 | ||
|     case csfh = "color.surface.float.hover"
 | ||
|     case csfp = "color.surface.float.press"
 | ||
|     case cstn = "color.surface.top.normal"
 | ||
|     case csth = "color.surface.top.hover"
 | ||
|     case cstp = "color.surface.top.press"
 | ||
|     case cstd = "color.surface.top.disabled"
 | ||
|     case csdn = "color.surface.district.normal"
 | ||
|     case csdh = "color.surface.district.hover"
 | ||
|     case csdp = "color.surface.district.press"
 | ||
|     case csdd = "color.surface.district.disabled"
 | ||
|     case csnn = "color.surface.nest.normal"
 | ||
|     case csnh = "color.surface.nest.hover"
 | ||
|     case csnp = "color.surface.nest.press"
 | ||
|     case csnd = "color.surface.nest.disabled"
 | ||
|     case csen = "color.surface.element.normal"
 | ||
|     case cseh = "color.surface.element.hover"
 | ||
|     case csep = "color.surface.element.press"
 | ||
|     case csed = "color.surface.element.disabled"
 | ||
|     case csedn = "color.surface.element.dark.normal"
 | ||
|     case csedh = "color.surface.element.dark.hover"
 | ||
|     case csedp = "color.surface.element.dark.press"
 | ||
|     case csedd = "color.surface.element.dark.disabled"
 | ||
|     case cseln = "color.surface.element.light.normal"
 | ||
|     case cselh = "color.surface.element.light.hover"
 | ||
|     case cselp = "color.surface.element.light.press"
 | ||
|     case cseld = "color.surface.element.light.disabled"
 | ||
|     case cswn = "color.surface.white.normal"
 | ||
|     case cswh = "color.surface.white.hover"
 | ||
|     case cswp = "color.surface.white.press"
 | ||
|     case cswd = "color.surface.white.disabled"
 | ||
|     case csbn2 = "color.surface.black.normal"
 | ||
|     case con = "color.outline.normal"
 | ||
|     case coh = "color.outline.hover"
 | ||
|     case cop = "color.outline.press"
 | ||
|     case cod = "color.outline.disabled"
 | ||
|     case copr = "color.overlay.primary"
 | ||
|     case cogr = "color.overlay.gradient"
 | ||
|     case codr = "color.overlay.dark"
 | ||
|     /// graident
 | ||
|     case cob = "color.overlay.background"
 | ||
|     case cobase = "color.overlay.base"
 | ||
|     /// vip gradient
 | ||
|     case ccvn = "color.context.vip.normal"
 | ||
|     case ctpn = "color.txt.primary.normal"
 | ||
|     case ctph = "color.txt.primary.hover"
 | ||
|     case ctpp = "color.txt.primary.press"
 | ||
|     case ctpd = "color.txt.primary.disabled"
 | ||
|     case ctpsn = "color.txt.primary.specialmap.normal"
 | ||
|     case ctpsh = "color.txt.primary.specialmap.hover"
 | ||
|     case ctpsp = "color.txt.primary.specialmap.press"
 | ||
|     case ctpsd = "color.txt.primary.specialmap.disabled"
 | ||
|     case ctsn = "color.txt.secondary.normal"
 | ||
|     case ctsh = "color.txt.secondary.hover"
 | ||
|     case ctsp = "color.txt.secondary.press"
 | ||
|     case ctsd = "color.txt.secondary.disabled"
 | ||
|     case cttn = "color.txt.tertiary.normal"
 | ||
|     case ctg = "color.txt.grass"
 | ||
|     case ctd = "color.txt.disabled"
 | ||
|     case td = "txt.display"
 | ||
|     case tdxl = "txt.display.xl"
 | ||
|     case tdl = "txt.display.l"
 | ||
|     case tdm = "txt.display.m"
 | ||
|     case tds = "txt.display.s"
 | ||
|     case thl = "txt.headline.l"
 | ||
|     case thm = "txt.headline.m"
 | ||
|     case ths = "txt.headline.s"
 | ||
|     case ttl = "txt.title.l"
 | ||
|     case ttm = "txt.title.m"
 | ||
|     case tts = "txt.title.s"
 | ||
|     case tbsl = "txt.bodySemibold.l"
 | ||
|     case tbsm = "txt.bodySemibold.m"
 | ||
|     case tbss = "txt.bodySemibold.s"
 | ||
|     case tbl = "txt.body.l"
 | ||
|     case tbm = "txt.body.m"
 | ||
|     case tbim = "txt.body.italic.m"
 | ||
|     case tbs = "txt.body.s"
 | ||
|     case tll = "txt.label.l"
 | ||
|     case tlm = "txt.label.m"
 | ||
|     case tls = "txt.label.s"
 | ||
|     case tndxl = "txt.numDisplay.xl"
 | ||
|     case tndl = "txt.numDisplay.l"
 | ||
|     case tndm = "txt.numDisplay.m"
 | ||
|     case tnds = "txt.numDisplay.s"
 | ||
|     case tnmxl = "txt.numMonotype.xl"
 | ||
|     case tnml = "txt.numMonotype.l"
 | ||
|     case tnmm = "txt.numMonotype.m"
 | ||
|     case tnms = "txt.numMonotype.s"
 | ||
|     case tnmxs = "txt.numMonotype.xs"
 | ||
|     case shs = "shadow.s"
 | ||
|     case shm = "shadow.m"
 | ||
|     case shl = "shadow.l"
 | ||
|     case rxs = "radius.xs"
 | ||
|     case rs = "radius.s"
 | ||
|     case rm = "radius.m"
 | ||
|     case rl = "radius.l"
 | ||
|     case rxl = "radius.xl"
 | ||
|     case rxxl = "radius.xxl"
 | ||
|     case rr = "radius.round"
 | ||
|     case rp = "radius.pill"
 | ||
|     case bd = "border.divider"
 | ||
|     case bs = "border.s"
 | ||
|     case bm = "border.m"
 | ||
|     case bl = "border.l"
 | ||
| }
 | ||
| 
 | ||
| func KeyForSystemTokenFrom(_ token: CLEnumSystemToken) -> String {
 | ||
|     return token.rawValue
 | ||
| }
 | ||
| 
 | ||
| // MARK: - EPShadow
 | ||
| 
 | ||
| struct EPShadow {
 | ||
|     var color: UIColor?
 | ||
|     var opacity: Float = 0
 | ||
|     var offset: CGSize = .zero
 | ||
|     var radius: CGFloat = 0
 | ||
| }
 | ||
| 
 | ||
| // MARK: - EPGradient
 | ||
| 
 | ||
| struct EPGradient {
 | ||
|     var direction: CGPoint = .zero
 | ||
|     var firstColor: UIColor?
 | ||
|     var secondColor: UIColor?
 | ||
|     var thirdColor : UIColor?
 | ||
| 
 | ||
|     public func toImage(size: CGSize) -> UIImage? {
 | ||
|         guard let firstColor = firstColor?.cgColor, let secondColor = secondColor?.cgColor else {
 | ||
|             return nil
 | ||
|         }
 | ||
| 
 | ||
|         // 根据 direction 计算 startPoint 和 endPoint
 | ||
|         let startPoint: CGPoint
 | ||
|         let endPoint: CGPoint
 | ||
| 
 | ||
|         switch direction {
 | ||
|         case CGPoint(x: 0, y: -1): // 从上到下
 | ||
|             startPoint = CGPoint(x: 0.5, y: 0)
 | ||
|             endPoint = CGPoint(x: 0.5, y: 1)
 | ||
|         case CGPoint(x: 1, y: -1): // 从左上到右下
 | ||
|             startPoint = CGPoint(x: 0, y: 0)
 | ||
|             endPoint = CGPoint(x: 1, y: 1)
 | ||
|         default:
 | ||
|             // 如果 direction 不匹配已知方向,返回 nil 或使用默认方向
 | ||
|             startPoint = CGPoint(x: 0, y: 0.5)
 | ||
|             endPoint = CGPoint(x: 1, y: 0.5) // 默认水平渐变
 | ||
|         }
 | ||
|         
 | ||
|         var colors = [firstColor, secondColor]
 | ||
|         if(colors.count == 3){
 | ||
|             if let third = thirdColor?.cgColor{
 | ||
|                 colors = [firstColor, secondColor, third]
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 调用 gradientImageWithSize 生成图像
 | ||
|         return UIImage.gradientImageWithSize(
 | ||
|             size: size,
 | ||
|             colors: colors,
 | ||
|             startPoint: startPoint,
 | ||
|             endPoint: endPoint
 | ||
|         )
 | ||
|     }
 | ||
|     
 | ||
|     public func colors() -> [UIColor]{
 | ||
|         var colors = [UIColor]()
 | ||
|         if let first = firstColor{
 | ||
|             colors.append(first)
 | ||
|         }
 | ||
|         if let second = secondColor{
 | ||
|             colors.append(second)
 | ||
|         }
 | ||
|         if let third = thirdColor{
 | ||
|             colors.append(third)
 | ||
|         }
 | ||
|         return colors
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| // MARK: - EPTypography
 | ||
| 
 | ||
| struct EPTypography {
 | ||
|     var font: UIFont?
 | ||
|     var lineHeight: CGFloat = 0
 | ||
| }
 | ||
| 
 | ||
| // MARK: - EPBaseObject
 | ||
| 
 | ||
| class EPBaseObject {
 | ||
|     static func subGetColorByTokenValues(_ values: [String]) -> UIColor? {
 | ||
|         guard !values.isEmpty else {
 | ||
|             preconditionFailure("Invalid color values: empty array")
 | ||
|             return nil
 | ||
|         }
 | ||
| 
 | ||
|         guard let hex = values.first, hex.hasPrefix("#") else {
 | ||
|             print("❌ Invalid color format for values: \(values)")
 | ||
|             return nil
 | ||
|         }
 | ||
| 
 | ||
|         let hexString = hex.replacingOccurrences(of: "#", with: "")
 | ||
|         var rgb: UInt64 = 0
 | ||
|         Scanner(string: hexString).scanHexInt64(&rgb)
 | ||
| 
 | ||
|         let red = CGFloat((rgb >> 16) & 0xFF) / 255.0
 | ||
|         let green = CGFloat((rgb >> 8) & 0xFF) / 255.0
 | ||
|         let blue = CGFloat(rgb & 0xFF) / 255.0
 | ||
|         let alpha: CGFloat = values.count > 1 ? CGFloat(Float(values.last!) ?? 1.0) : 1.0
 | ||
| 
 | ||
|         return UIColor(red: red, green: green, blue: blue, alpha: alpha)
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| // MARK: - CLSystemToken
 | ||
| 
 | ||
| class CLSystemToken {
 | ||
|     static let baseTokens = CLBaseTokens.shared
 | ||
| 
 | ||
|     // MARK: - Color Methods
 | ||
| 
 | ||
|     static func color(token: CLEnumSystemToken) -> UIColor? {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let values = baseTokens.getTokensByKey(key)
 | ||
|         return EPBaseObject.subGetColorByTokenValues(values)
 | ||
|     }
 | ||
| 
 | ||
|     static func darkColor(token: CLEnumSystemToken) -> UIColor? {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let values = baseTokens.getDarkTokens(key)
 | ||
|         return EPBaseObject.subGetColorByTokenValues(values)
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - String Method
 | ||
| 
 | ||
|     static func string(token: CLEnumSystemToken) -> String? {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         return baseTokens.getTokenByKey(key)
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Float Method
 | ||
| 
 | ||
|     static func float(token: CLEnumSystemToken) -> CGFloat {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let value = baseTokens.getTokenByKey(key)
 | ||
|         guard let floatValue = Float(value) else {
 | ||
|             print("❌ Invalid float format for key: \(key)")
 | ||
|             return 0
 | ||
|         }
 | ||
|         return CGFloat(floatValue)
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Radius Method
 | ||
| 
 | ||
|     static func radius(token: CLEnumSystemToken) -> CGFloat {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let value = baseTokens.getTokenByKey(key)
 | ||
|         guard let radius = Float(value) else {
 | ||
|             print("❌ Invalid radius format for key: \(key)")
 | ||
|             return 0
 | ||
|         }
 | ||
|         // print("🎨 radius: \(key) \(radius)") // DLog 替换为 print
 | ||
|         return CGFloat(radius)
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Border Method
 | ||
| 
 | ||
|     static func border(token: CLEnumSystemToken) -> CGFloat {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let value = baseTokens.getTokenByKey(key)
 | ||
|         guard let border = Float(value) else {
 | ||
|             print("❌ Invalid border format for key: \(key)")
 | ||
|             return 0
 | ||
|         }
 | ||
|         // print("🎨 border: \(key) \(border)") // DLog 替换为 print
 | ||
|         return CGFloat(border)
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Shadow Method
 | ||
| 
 | ||
|     static func shadow(token: CLEnumSystemToken) -> EPShadow {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let values = baseTokens.getTokensByKey(key)
 | ||
| 
 | ||
|         guard values.count == 4, values.first?.contains(EPConfigShadowPrefix) == true else {
 | ||
|             assertionFailure("Wrong format for shadow token: \(key)")
 | ||
|             return EPShadow()
 | ||
|         }
 | ||
| 
 | ||
|         var shadow = EPShadow()
 | ||
| 
 | ||
|         if let colorStr = values.first?.replacingOccurrences(of: EPConfigShadowPrefix, with: "") {
 | ||
|             let color = EPBaseObject.subGetColorByTokenValues([colorStr])
 | ||
|             shadow.color = color
 | ||
|         }
 | ||
| 
 | ||
|         if let opacity = Float(values[1]) {
 | ||
|             shadow.opacity = opacity
 | ||
|         }
 | ||
|         let offXy = values[2].components(separatedBy: "&")
 | ||
|         if offXy.count == 2,
 | ||
|            let x = Float(offXy[0]), let y = Float(offXy[1]) {
 | ||
|             shadow.offset = CGSize(width: CGFloat(x), height: CGFloat(y))
 | ||
|         }
 | ||
| 
 | ||
|         if let radius = Float(values[3]) {
 | ||
|             shadow.radius = CGFloat(radius)
 | ||
|         }
 | ||
| 
 | ||
|         return shadow
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Gradient Method
 | ||
| 
 | ||
|     static func gradient(token: CLEnumSystemToken) -> EPGradient {
 | ||
| //        if token == .colorContextVipNormal {
 | ||
| //            assertionFailure("Special style rule, not used in this unified rule, please use another method")
 | ||
| //            return gradient(token: .colorPrimaryGradientNormal)
 | ||
| //        }
 | ||
| 
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let values = baseTokens.getTokensByKey(key)
 | ||
| 
 | ||
|         if values.count <= 2  { // || values.first?.contains(EPConfigGradientPrefix) != true
 | ||
|             var gradient = EPGradient()
 | ||
|             gradient.direction = CGPoint(x: 1, y: 0)
 | ||
|             gradient.firstColor = EPBaseObject.subGetColorByTokenValues(values)
 | ||
|             gradient.secondColor = gradient.firstColor
 | ||
|             return gradient
 | ||
|         }
 | ||
| 
 | ||
|         // 方向+ 2个颜色,或者3个颜色
 | ||
|         guard values.count == 3 || values.count == 4 else {
 | ||
|             assertionFailure("Wrong format for gradient token: \(key)")
 | ||
|             return EPGradient()
 | ||
|         }
 | ||
| 
 | ||
|         var gradient = EPGradient()
 | ||
| 
 | ||
|         if let directionStr = values.first {
 | ||
|             switch directionStr {
 | ||
|             case "LTR":
 | ||
|                 gradient.direction = CGPoint(x: 1, y: 0)
 | ||
|             case "TTB":
 | ||
|                 gradient.direction = CGPoint(x: 0, y: 1)
 | ||
|             case "LTTRB":
 | ||
|                 gradient.direction = CGPoint(x: 1, y: 1)
 | ||
|             default:
 | ||
|                 assertionFailure("Not handled direction: \(directionStr)")
 | ||
|                 gradient.direction = .zero
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         let color1Str = values[1].replacingOccurrences(of: EPConfigGradientPrefix, with: "")
 | ||
|         let color1Array = color1Str.components(separatedBy: "&")
 | ||
|         gradient.firstColor = EPBaseObject.subGetColorByTokenValues(color1Array)
 | ||
| 
 | ||
|         let color2Str = values[2].replacingOccurrences(of: EPConfigGradientPrefix, with: "")
 | ||
|         let color2Array = color2Str.components(separatedBy: "&")
 | ||
|         gradient.secondColor = EPBaseObject.subGetColorByTokenValues(color2Array)
 | ||
|         
 | ||
|         if(values.count == 4){
 | ||
|             let color3Str = values[3].replacingOccurrences(of: EPConfigGradientPrefix, with: "")
 | ||
|             let color3Array = color3Str.components(separatedBy: "&")
 | ||
|             gradient.thirdColor = EPBaseObject.subGetColorByTokenValues(color3Array)
 | ||
|         }
 | ||
| 
 | ||
|         return gradient
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Typography Method
 | ||
| 
 | ||
|     static func typography(token: CLEnumSystemToken) -> EPTypography {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let values = baseTokens.getTokensByKey(key)
 | ||
| 
 | ||
|         guard values.count == 4 else {
 | ||
|             assertionFailure("Wrong format for typography token: \(key)")
 | ||
|             return EPTypography()
 | ||
|         }
 | ||
| 
 | ||
|         var typography = EPTypography()
 | ||
| 
 | ||
|         var fontName = values[0]
 | ||
|         guard let fontSize = Int(values[1]),
 | ||
|               let weight = Int(values[2]),
 | ||
|               let lineHeight = Int(values[3]) else {
 | ||
|             assertionFailure("Invalid typography values for token: \(key)")
 | ||
|             return EPTypography()
 | ||
|         }
 | ||
| 
 | ||
|         if !fontName.contains("-Italic") {
 | ||
|             switch weight {
 | ||
|             case 400:
 | ||
|                 fontName += "-Regular"
 | ||
|             case 500:
 | ||
|                 fontName += "-Medium"
 | ||
|             case 600:
 | ||
|                 fontName += "-SemiBold"
 | ||
|             case 700:
 | ||
|                 fontName += "-Bold"
 | ||
|             default:
 | ||
|                 assertionFailure("Not handled font weight: \(weight)")
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         typography.font = UIFont(name: fontName, size: CGFloat(fontSize))
 | ||
|         typography.lineHeight = CGFloat(lineHeight)
 | ||
| 
 | ||
|         return typography
 | ||
|     }
 | ||
| 
 | ||
|     // MARK: - Font Method
 | ||
| 
 | ||
|     static func font(token: CLEnumSystemToken) -> UIFont {
 | ||
|         let key = KeyForSystemTokenFrom(token)
 | ||
|         let values = baseTokens.getTokensByKey(key)
 | ||
| 
 | ||
|         guard values.count == 4 else {
 | ||
|             assertionFailure("Wrong format for font token: \(key)")
 | ||
|             return UIFont.systemFont(ofSize: 14)
 | ||
|         }
 | ||
| 
 | ||
|         var fontName = values[0]
 | ||
|         guard let fontSize = Int(values[1]),
 | ||
|               let weight = Int(values[2]) else {
 | ||
|             assertionFailure("Invalid font values for token: \(key)")
 | ||
|             return UIFont.systemFont(ofSize: 14)
 | ||
|         }
 | ||
|         
 | ||
|         if(fontName .isNotBlank){
 | ||
|             fontName = fontName.removingAllWhitespace
 | ||
|         }
 | ||
| 
 | ||
|         if !fontName.contains("-Italic") {
 | ||
|             switch weight {
 | ||
|             case 400:
 | ||
|                 fontName += "-Regular"
 | ||
|             case 500:
 | ||
|                 fontName += "-Medium"
 | ||
|             case 600:
 | ||
|                 fontName += "-SemiBold"
 | ||
|             case 700:
 | ||
|                 fontName += "-Bold"
 | ||
|             default:
 | ||
|                 assertionFailure("Not handled font weight: \(weight)")
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return UIFont(name: fontName, size: CGFloat(fontSize)) ?? UIFont.systemFont(ofSize: 14)
 | ||
|     }
 | ||
| }
 |