vds_ios/VDS/Components/BadgeIndicator/BadgeIndicator.swift
Matt Bruce 00edeac169 initial component just copied badge for ease
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-06-15 13:21:09 -05:00

145 lines
5.7 KiB
Swift

//
// Badge.swift
// VDS
//
// Created by Matt Bruce on 9/22/22.
//
import Foundation
import UIKit
import VDSColorTokens
import VDSFormControlsTokens
import Combine
/// Badges are visual labels used to convey status or highlight supplemental information.
@objc(VDSBadgeIndicator)
open class BadgeIndicator: View {
//--------------------------------------------------
// MARK: - Enums
//--------------------------------------------------
public enum FillColor: String, CaseIterable {
case red, yellow, green, orange, blue, gray, grayLowContrast, black, white
}
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
open var label = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical)
$0.adjustsFontSizeToFitWidth = false
$0.lineBreakMode = .byTruncatingTail
$0.textPosition = .left
$0.textStyle = .boldBodySmall
}
open var fillColor: FillColor = .red { didSet { setNeedsUpdate() }}
open var text: String = "" { didSet { setNeedsUpdate() }}
open var maxWidth: CGFloat? { didSet { setNeedsUpdate() }}
open var numberOfLines: Int = 1 { didSet { setNeedsUpdate() }}
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
private var maxWidthConstraint: NSLayoutConstraint?
private var minWidthConstraint: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
open override func setup() {
super.setup()
accessibilityElements = [label]
layer.cornerRadius = 2
addSubview(label)
label.pinToSuperView(.init(top: 2,
left: VDSLayout.Spacing.space1X.value,
bottom: 2,
right: VDSLayout.Spacing.space1X.value))
maxWidthConstraint = label.widthAnchor.constraint(lessThanOrEqualToConstant: 100)
minWidthConstraint = label.widthAnchor.constraint(greaterThanOrEqualToConstant: 23)
minWidthConstraint?.isActive = true
}
open override func reset() {
super.reset()
shouldUpdateView = false
label.reset()
label.lineBreakMode = .byTruncatingTail
label.textPosition = .left
label.textStyle = .boldBodySmall
fillColor = .red
text = ""
maxWidth = nil
numberOfLines = 1
shouldUpdateView = true
setNeedsUpdate()
}
//--------------------------------------------------
// MARK: - Configuration
//--------------------------------------------------
private var backgroundColorConfiguration: AnyColorable = {
let config = KeyedColorConfiguration<BadgeIndicator, FillColor>(keyPath: \.fillColor)
config.setSurfaceColors(VDSColor.backgroundBrandhighlight, VDSColor.backgroundBrandhighlight, forKey: .red)
config.setSurfaceColors(VDSColor.paletteYellow53, VDSColor.paletteYellow53, forKey: .yellow)
config.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen36, forKey: .green)
config.setSurfaceColors(VDSColor.paletteOrange41, VDSColor.paletteOrange58, forKey: .orange)
config.setSurfaceColors(VDSColor.paletteBlue38, VDSColor.paletteBlue46, forKey: .blue)
config.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryDark, forKey: .black)
config.setSurfaceColors(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryLight, forKey: .white)
return config.eraseToAnyColorable()
}()
private var textColorConfiguration = ViewColorConfiguration()
public func updateTextColorConfig() {
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)
}
}
//--------------------------------------------------
// MARK: - State
//--------------------------------------------------
open override func updateView() {
updateTextColorConfig()
backgroundColor = backgroundColorConfiguration.getColor(self)
label.textColorConfiguration = textColorConfiguration.eraseToAnyColorable()
label.numberOfLines = numberOfLines
label.text = text
label.surface = surface
label.disabled = disabled
if let maxWidth = maxWidth, let minWidth = minWidthConstraint?.constant, maxWidth > minWidth {
maxWidthConstraint?.constant = maxWidth
maxWidthConstraint?.isActive = true
} else {
maxWidthConstraint?.isActive = false
}
}
}