vds_ios/VDS/Components/Tooltip/Tooltip.swift
Matt Bruce f41e6f9c9c updated color for state changes
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-04-17 16:36:14 -05:00

175 lines
5.9 KiB
Swift

//
// Tooltip.swift
// VDS
//
// Created by Matt Bruce on 4/13/23.
//
import Foundation
import UIKit
import VDSColorTokens
import VDSFormControlsTokens
import Combine
@objc(VDSTooltip)
open class Tooltip: Control, TooltipLaunchable {
//--------------------------------------------------
// MARK: - Enums
//--------------------------------------------------
public enum FillColor: String, CaseIterable {
case primary, secondary, brandHighlight
}
public enum Size: String, CaseIterable {
case small
case medium
public var dimensions: CGSize {
switch self {
case .small:
return .init(width: 13.33, height: 13.33)
case .medium:
return .init(width: 16.67, height: 16.67)
}
}
}
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
private var widthConstraint: NSLayoutConstraint?
private var heightConstraint: NSLayoutConstraint?
private var infoImage = UIImage()
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
open var imageView = UIImageView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.contentMode = .scaleAspectFill
$0.clipsToBounds = true
}
open var closeButtonText: String = "Close" { didSet { didChange() }}
open var fillColor: FillColor = .primary { didSet { didChange() }}
open var size: Size = .medium { didSet { didChange() }}
open var title: String = "" { didSet { didChange() }}
open var content: String = "" { didSet { didChange() }}
//--------------------------------------------------
// MARK: - Configuration
//--------------------------------------------------
private var iconColorConfig: AnyColorable {
switch fillColor {
case .primary:
return primaryColorConfig.eraseToAnyColorable()
case .secondary:
return secondaryColorConfig.eraseToAnyColorable()
case .brandHighlight:
return brandHighlightColorConfig.eraseToAnyColorable()
}
}
private var primaryColorConfig = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
private var secondaryColorConfig = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.paletteGray65, VDSColor.paletteGray65, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
private var brandHighlightColorConfig = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsBrandhighlight, VDSColor.elementsBrandhighlight, forState: .normal)
$0.setSurfaceColors(VDSColor.elementsBrandhighlight, VDSColor.elementsBrandhighlight, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
required public init() {
super.init(frame: .zero)
}
public override init(frame: CGRect) {
super.init(frame: .zero)
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
open override func setup() {
super.setup()
if let image = BundleManager.shared.image(for: "info") {
infoImage = image
}
addSubview(imageView)
imageView.pinToSuperView()
heightConstraint = imageView.heightAnchor.constraint(equalToConstant: size.dimensions.height)
heightConstraint?.isActive = true
widthConstraint = imageView.widthAnchor.constraint(equalToConstant: size.dimensions.width)
widthConstraint?.isActive = true
backgroundColor = .clear
isAccessibilityElement = true
accessibilityTraits = .link
onClickSubscriber = publisher(for: .touchUpInside)
.sink(receiveValue: { [weak self] tooltip in
guard let self else { return}
self.presentTooltip(surface: tooltip.surface,
title: tooltip.title,
content: tooltip.content,
closeButtonText: tooltip.closeButtonText)
})
}
open override func reset() {
super.reset()
size = .medium
title = ""
content = ""
fillColor = .primary
closeButtonText = "Close"
imageView.image = nil
}
open override func updateView() {
super.updateView()
//set the dimensions
let dimensions = size.dimensions
heightConstraint?.constant = dimensions.height
widthConstraint?.constant = dimensions.width
//get the color for the image
let imageColor = iconColorConfig.getColor(self)
imageView.image = infoImage.withTintColor(imageColor)
accessibilityLabel = "Tooltip: \(title)"
}
}