// // Tilet.swift // VDS // // Created by Matt Bruce on 12/19/22. // import Foundation import Foundation import VDSColorTokens import UIKit public enum TiletTitleTypographicalStyle: String, Codable, EnumSubset { case TitleXLarge case BoldTitleXLarge case TitleLarge case BoldTitleLarge case TitleMedium case BoldTitleMedium case TitleSmall case BoldTitleSmall public var defaultValue: TitleLockupTitleTypographicalStyle { .BoldTitleSmall } } public enum TiletOtherTypographicalStyle: String, Codable, EnumSubset { case BodyLarge case BoldBodyLarge case BodyMedium case BoldBodyMedium case BodySmall case BoldBodySmall public var defaultValue: TitleLockupOtherTypographicalStyle { .BodySmall } } @objc(VDSTilet) open class Tilet: TileContainer { //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- required public init() { super.init(frame: .zero) initialSetup() } public override init(frame: CGRect) { super.init(frame: .zero) initialSetup() } public required init?(coder: NSCoder) { super.init(coder: coder) initialSetup() } //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private var titleLockup = TitleLockup().with { let configs = [ TypographicalStyleDeviceSpacingConfig([.TitleSmall, .BoldTitleSmall], neighboring: [ .BodySmall, .BoldBodySmall, .BodyMedium, .BoldBodyMedium ], spacing: 8.0, deviceType: .iPhone), TypographicalStyleDeviceSpacingConfig([.TitleMedium, .BoldTitleMedium, .TitleLarge, .BoldTitleLarge], neighboring: [ .BodySmall, .BoldBodySmall, .BodyMedium, .BoldBodyMedium, .BodyLarge, .BoldBodyLarge], spacing: 8.0, deviceType: .iPhone), TypographicalStyleDeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge], neighboring: [ .BodySmall, .BoldBodySmall, .BodyMedium, .BoldBodyMedium, .BodyLarge, .BoldBodyLarge, .TitleMedium, .BoldTitleMedium ], spacing: 12.0, deviceType: .iPhone), TypographicalStyleDeviceSpacingConfig([.TitleSmall, .BoldTitleSmall, .TitleMedium, .BoldTitleMedium], neighboring: [ .BodySmall, .BoldBodySmall, .BodyMedium, .BoldBodyMedium, .BodyLarge, .BoldBodyLarge ], spacing: 8.0, deviceType: .iPad), TypographicalStyleDeviceSpacingConfig([.TitleLarge, .BoldTitleLarge], neighboring: [ .BodySmall, .BoldBodySmall, .BodyMedium, .BoldBodyMedium, .BodyLarge, .BoldBodyLarge, .TitleSmall, .BoldTitleSmall ], spacing: 12.0, deviceType: .iPad), TypographicalStyleDeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge], neighboring: [ .BodyLarge, .BoldBodyLarge, .TitleMedium, .BoldTitleMedium ], spacing: 16.0, deviceType: .iPad) ] $0.bottomTypographicalStyleSpacingConfig = TypographicalStyleSpacingConfig(configs: configs) } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- //style open var titleTypograpicalStyle: TiletTitleTypographicalStyle = .BoldTitleSmall { didSet { didChange() }} open var otherTypograpicalStyle: TiletOtherTypographicalStyle = .BodySmall { didSet { didChange() }} private var _textWidth: CGFloat? open var textWidth: CGFloat? { get { _textWidth } set { if let newValue, newValue > 44.0 && newValue <= width { _textWidth = newValue if _textPercentage != nil { _textPercentage = nil } } else { _textWidth = nil } didChange() } } private var _textPercentage: CGFloat? open var textPercentage: CGFloat? { get { _textPercentage } set { if let newValue, newValue >= 5 && newValue <= 100.0 { _textPercentage = newValue if textWidth != nil { _textWidth = nil } } else { _textPercentage = nil } didChange() } } //badge open var showBadge: Bool = false { didSet { didChange() }} open var badgeText: String = "" { didSet { didChange() }} open var badgeColor: BadgeFillColor = .red { didSet { didChange() }} //text open var titleText: String = "" { didSet { didChange() }} open var titleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} open var subTitleText: String = "" { didSet { didChange() }} open var subTitleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} open var subTitleColor: Use = .primary { didSet { didChange() }} //icons //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- internal var titleLockupWidthConstraint: NSLayoutConstraint? internal var titleLockupTrailingConstraint: NSLayoutConstraint? //functions //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- open override func setup() { super.setup() width = 100 aspectRatio = .none containerBackgroundColor = .black addContentView(titleLockup, shouldPin: false) titleLockup.pinTop() titleLockup.pinLeading() titleLockup.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor).isActive = true //either you are 100% width of the tileContainer.contentView titleLockupTrailingConstraint = titleLockup.trailingAnchor.constraint(equalTo: containerView.trailingAnchor) titleLockupTrailingConstraint?.isActive = true } public override func reset() { super.reset() aspectRatio = .none surface = .light containerBackgroundColor = .black titleLockup.reset() titleText = "" titleTextAttributes = nil subTitleText = "" subTitleTextAttributes = nil subTitleColor = .primary } //-------------------------------------------------- // MARK: - State //-------------------------------------------------- open override func updateView() { super.updateView() //flip the surface for the titleLockup let flippedSurface: Surface = containerBackgroundColor == .black ? .dark : .light titleLockup.surface = flippedSurface //either use textWidth if let textWidth { titleLockupTrailingConstraint?.isActive = false titleLockupWidthConstraint?.isActive = false titleLockupWidthConstraint = titleLockup.widthAnchor.constraint(equalToConstant: textWidth) titleLockupWidthConstraint?.isActive = true } else if let textPercentage { titleLockupTrailingConstraint?.isActive = false titleLockupWidthConstraint?.isActive = false titleLockupWidthConstraint = NSLayoutConstraint(item: titleLockup, attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: textPercentage / 100, constant: 0.0) titleLockupWidthConstraint?.isActive = true } else { titleLockupWidthConstraint?.isActive = false titleLockupTrailingConstraint?.isActive = true } titleLockup.titleText = titleText titleLockup.titleTypograpicalStyle = titleTypograpicalStyle.value titleLockup.titleTextAttributes = titleTextAttributes titleLockup.subTitleText = subTitleText titleLockup.otherTypograpicalStyle = otherTypograpicalStyle.value titleLockup.subTitleTextAttributes = titleTextAttributes titleLockup.subTitleColor = subTitleColor } }