diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index 19c40bbc..fe0c36d4 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -38,8 +38,16 @@ open class Badge: View, ParentViewProtocol { // MARK: - Enums //-------------------------------------------------- /// Enum used to describe the primary color for the view. - public enum FillColor: String, CaseIterable { + public enum FillColor: Equatable { case red, yellow, green, orange, blue, black, white + case token(UIColor.VDSColor) + case custom(UIColor) + + private var reflectedValue: String { String(reflecting: self) } + + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.reflectedValue == rhs.reflectedValue + } } //-------------------------------------------------- @@ -61,10 +69,12 @@ open class Badge: View, ParentViewProtocol { /// This will render the badges fill color based on the available options. /// When used in conjunction with the surface prop, this fill color will change its tint automatically based on a light or dark surface. open var fillColor: FillColor = .red { didSet { setNeedsUpdate() }} - + /// The text that will be shown in the label. open var text: String = "" { didSet { setNeedsUpdate() }} + open var textColor: TextColor? { didSet { setNeedsUpdate() }} + /// When applied, this property takes a px value that will restrict the width at that point. open var maxWidth: CGFloat? { didSet { setNeedsUpdate() }} @@ -93,38 +103,91 @@ open class Badge: View, ParentViewProtocol { right: VDSLayout.space1X) /// ColorConfiguration that is mapped to the 'fillColor' for the surface. - private var backgroundColorConfiguration: AnyColorable = { - let config = KeyedColorConfiguration(keyPath: \.fillColor) - config.setSurfaceColors(VDSColor.badgesBackgroundRedOnlight, VDSColor.badgesBackgroundRedOndark, forKey: .red) - config.setSurfaceColors(VDSColor.badgesBackgroundYellowOnlight, VDSColor.badgesBackgroundYellowOndark, forKey: .yellow) - config.setSurfaceColors(VDSColor.badgesBackgroundGreenOnlight, VDSColor.badgesBackgroundGreenOndark, forKey: .green) - config.setSurfaceColors(VDSColor.badgesBackgroundOrangeOnlight, VDSColor.badgesBackgroundOrangeOndark, forKey: .orange) - config.setSurfaceColors(VDSColor.badgesBackgroundBlueOnlight, VDSColor.badgesBackgroundBlueOndark, forKey: .blue) - config.setSurfaceColors(VDSColor.badgesBackgroundBlackOnlight, VDSColor.badgesBackgroundBlackOndark, forKey: .black) - config.setSurfaceColors(VDSColor.badgesBackgroundWhiteOnlight, VDSColor.badgesBackgroundWhiteOndark, forKey: .white) - return config.eraseToAnyColorable() - }() + private var backgroundColorConfiguration = SurfaceColorConfiguration() /// ColorConfiguration for the Text. private var textColorConfiguration = ViewColorConfiguration() /// Updates the textColorConfiguration based on the fillColor. - public func updateTextColorConfig() { + public func updateColorConfig() { + var config = backgroundColorConfiguration + switch fillColor { + case .red: + config.lightColor = VDSColor.badgesBackgroundRedOnlight + config.darkColor = VDSColor.badgesBackgroundRedOndark + case .yellow: + config.lightColor = VDSColor.badgesBackgroundYellowOnlight + config.darkColor = VDSColor.badgesBackgroundYellowOndark + case .green: + config.lightColor = VDSColor.badgesBackgroundGreenOnlight + config.darkColor = VDSColor.badgesBackgroundGreenOndark + case .orange: + config.lightColor = VDSColor.badgesBackgroundOrangeOnlight + config.darkColor = VDSColor.badgesBackgroundOrangeOndark + case .blue: + config.lightColor = VDSColor.badgesBackgroundBlueOnlight + config.darkColor = VDSColor.badgesBackgroundBlueOndark + case .black: + config.lightColor = VDSColor.badgesBackgroundBlackOnlight + config.darkColor = VDSColor.badgesBackgroundBlackOndark + case .white: + config.lightColor = VDSColor.badgesBackgroundWhiteOnlight + config.darkColor = VDSColor.badgesBackgroundWhiteOndark + case .token(let color): + config.lightColor = color.uiColor + config.darkColor = color.uiColor + case .custom(let color): + config.lightColor = color + config.darkColor = color + } + textColorConfiguration.reset() - switch fillColor { - - case .red, .black: - textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: false) - textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: true) - - case .yellow, .white: - textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: false) - textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: true) - - case .orange, .green, .blue: - textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forDisabled: false) - textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forDisabled: true) + func update(for color: UIColor) { + if let configuration = textColor?.configuration { + textColorConfiguration = configuration + } else { + if color.isDark() { + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: false) + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: true) + } else { + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: false) + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: true) + + } + } + } + + if let textColor { + switch textColor { + case .token(let color): + textColorConfiguration.setSurfaceColors(color.uiColor, color.uiColor, forDisabled: false) + textColorConfiguration.setSurfaceColors(color.uiColor, color.uiColor, forDisabled: true) + case .custom(let color): + textColorConfiguration.setSurfaceColors(color, color, forDisabled: false) + textColorConfiguration.setSurfaceColors(color, color, forDisabled: true) + } + } else { + switch fillColor { + + case .red, .black: + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: false) + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: true) + + case .yellow, .white: + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: false) + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: true) + + case .orange, .green, .blue: + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forDisabled: false) + textColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forDisabled: true) + + case .token(let color): + update(for: color.uiColor) + + case .custom(let color): + update(for: color) + } } } @@ -179,7 +242,7 @@ open class Badge: View, ParentViewProtocol { open override func updateView() { super.updateView() - updateTextColorConfig() + updateColorConfig() updateMaxWidth() backgroundColor = backgroundColorConfiguration.getColor(self) @@ -191,3 +254,29 @@ open class Badge: View, ParentViewProtocol { label.isEnabled = isEnabled } } + +extension Badge{ + public enum TextColor: Equatable { + case token(UIColor.VDSColor) + case custom(UIColor) + + private var reflectedValue: String { String(reflecting: self) } + + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.reflectedValue == rhs.reflectedValue + } + + public var configuration: ViewColorConfiguration { + let config = ViewColorConfiguration() + switch self { + case .token(let color): + config.setSurfaceColors(color.uiColor, color.uiColor, forDisabled: true) + config.setSurfaceColors(color.uiColor, color.uiColor, forDisabled: false) + case .custom(let color): + config.setSurfaceColors(color, color, forDisabled: true) + config.setSurfaceColors(color, color, forDisabled: false) + } + return config + } + } +} diff --git a/VDS/Extensions/UIColor.swift b/VDS/Extensions/UIColor.swift index aad6e180..805da614 100644 --- a/VDS/Extensions/UIColor.swift +++ b/VDS/Extensions/UIColor.swift @@ -192,4 +192,14 @@ extension UIColor { } self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) } + + public func isDark() -> Bool { + var white: CGFloat = 0 + var alpha: CGFloat = 0 + if getWhite(&white, alpha: &alpha) { + return white < 0.5 + } + + return false + } }