// // TrailingTooltipLabel.swift // VDS // // Created by Matt Bruce on 4/14/23. // import Foundation import UIKit import Combine @objc(VDSTrailingTooltipLabel) open class TrailingTooltipLabel: View, TooltipLaunchable { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private let tooltipAction = PassthroughSubject() //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- open var label = Label() open var labelText: String? { didSet { didChange() }} open var labelAttributes: [any LabelAttributeModel]? { didSet { didChange() } } open var labelTextStyle: TextStyle = .defaultStyle { didSet { didChange() } } open var labelTextPosition: TextPosition = .left { didSet { didChange() } } public lazy var textColorConfiguration: AnyColorable = { label.textColorConfiguration }() { didSet { didChange() }} open var tooltipCloseButtonText: String = "Close" { didSet { didChange() } } open var tooltipSize: Tooltip.Size = .medium { didSet { didChange() } } open var tooltipTitle: String = "" { didSet { didChange() } } open var tooltipContent: String = "" { didSet { didChange() } } open var tooltipYOffset: CGFloat = 0 { didSet { didChange() } } //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- open override func setup() { super.setup() addSubview(label) label.pinToSuperView() //create the tooltip click event tooltipAction.sink { [weak self] in guard let self else { return } self.presentTooltip(surface: self.surface, title: self.tooltipTitle, content: self.tooltipContent, closeButtonText: self.tooltipCloseButtonText) }.store(in: &subscribers) } open override func updateView() { super.updateView() label.text = labelText label.textStyle = labelTextStyle label.textPosition = labelTextPosition label.surface = surface label.disabled = disabled //add tooltip if let labelText, !labelText.isEmpty, !tooltipTitle.isEmpty, !tooltipContent.isEmpty { //create the model let model = Label.TooltipModel(surface: surface, closeButtonText: tooltipCloseButtonText, size: tooltipSize, title: tooltipTitle, content: tooltipContent) //add the model label.addTooltip(model: model) } } } extension Label { public struct TooltipModel { public var surface: Surface public var closeButtonText: String public var size: Tooltip.Size public var title: String public var content: String public init(surface: Surface = .light, closeButtonText: String = "Close", size: Tooltip.Size = .medium, title: String, content: String) { self.surface = surface self.closeButtonText = closeButtonText self.size = size self.title = title self.content = content } } public func addTooltip(model: TooltipModel) { var newAttributes: [any LabelAttributeModel] = [] if let attributes { attributes.forEach { attribute in if type(of: attribute) != TooltipLabelAttribute.self { newAttributes.append(attribute) } } } if let text = text, !text.isEmpty { let tooltip = TooltipLabelAttribute(surface: surface, closeButtonText: model.closeButtonText, size: model.size, title: model.title, content: model.content) newAttributes.append(tooltip) } if !newAttributes.isEmpty { attributes = newAttributes } } }