vds_ios/VDS/Components/PriceLockup/PriceLockup.swift
2024-08-12 15:45:18 +05:30

213 lines
7.0 KiB
Swift

//
// PriceLockup.swift
// VDS
//
// Created by Kanamarlapudi, Vasavi on 06/08/24.
//
import Foundation
import UIKit
import VDSCoreTokens
@objcMembers
@objc(VDSPriceLockup)
open class PriceLockup: View {
//--------------------------------------------------
// 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: - Enums
//--------------------------------------------------
/// Enum used to describe the kind of PriceLockup.
public enum Kind: String, CaseIterable {
case primary, secondary, savings
}
/// Enum used to describe the term of PriceLockup.
public enum Term: String, CaseIterable {
case month, year, biennial, none
/// The default term is 'month'.
public static var defaultValue : Self { .month }
/// Text for this term of PriceLockup.
public var text: String {
switch self {
case .month:
return "mo"
case .year:
return "yr"
case .biennial:
return "biennial"
case .none:
return ""
}
}
}
/// Enum type describing size of PriceLockup.
public enum Size: String, CaseIterable {
case xxxsmall
case xxsmall
case xsmall
case small
case medium
case large
case xlarge
case xxlarge
}
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
/// If true, the component will render as bold.
open var bold: Bool = false { didSet { setNeedsUpdate() } }
/// Currency - If hideCurrency true, the component will render without currency.
open var hideCurrency: Bool = false { didSet { setNeedsUpdate() } }
/// Leading text for the component.
open var leadingText: String? { didSet { setNeedsUpdate() } }
/// Value rendered for the component.
open var price: CGFloat? { didSet { setNeedsUpdate() } }
/// Color to the component. The default kind is primary.
open var kind: Kind = .primary { didSet { setNeedsUpdate() } }
/// Size of the component. It varies by size and viewport(mobile/Tablet).
/// The default size is medium with viewport mobile.
open var size: Size = .medium { didSet { setNeedsUpdate() } }
/// If true, the component with a strikethrough. It applies only when uniformSize is true.
/// Does not apply a strikethrough format to leading and trailing text.
open var strikethrough: Bool = false { didSet { setNeedsUpdate() } }
/// Term text for the component. The default term is 'month'.
/// Superscript placement can vary when term and delimeter are "none".
open var term: Term = Term.defaultValue { didSet { setNeedsUpdate() } }
/// Trailing text for the component.
open var trailingText: String? { didSet { setNeedsUpdate() } }
/// Superscript text for the component.
open var superscript: String? { didSet { setNeedsUpdate() } }
/// If true, currency and value have the same font text style as delimeter, term label and superscript.
/// This will render the pricing and term sections as a uniform size.
open var uniformSize: Bool = false { didSet { setNeedsUpdate() } }
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
internal var containerView = View().with {
$0.clipsToBounds = true
}
internal var label = Label().with {
$0.isAccessibilityElement = false
$0.lineBreakMode = .byWordWrapping
}
//--------------------------------------------------
// MARK: - Configuration Properties
//--------------------------------------------------
internal var containerSize: CGSize { CGSize(width: 45, height: 44) }
private var kindColorConfiguration: AnyColorable {
switch kind {
case .primary:
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)}.eraseToAnyColorable()
case .secondary:
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forState: .normal)}.eraseToAnyColorable()
case .savings:
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen36, forState: .normal)}.eraseToAnyColorable()
}
}
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() {
super.setup()
addSubview(containerView)
containerView
.pinTop()
.pinBottom()
.pinLeadingGreaterThanOrEqualTo()
.pinTrailingLessThanOrEqualTo()
.height(containerSize.height)
containerView.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
// Price lockup
containerView.addSubview(label)
label.pinToSuperView()
label.centerXAnchor.constraint(equalTo: centerXAnchor).activate()
}
/// Used to make changes to the View based off a change events or from local properties.
open override func updateView() {
super.updateView()
label.text = fetchText()
}
/// Resets to default settings.
open override func reset() {
super.reset()
shouldUpdateView = false
label.reset()
shouldUpdateView = true
setNeedsUpdate()
}
open override var accessibilityElements: [Any]? {
get {
return nil
}
set {}
}
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
open func fetchText() -> String {
var text : String = ""
let currency: String = hideCurrency ? "" : "$"
if let leadingStr = leadingText {
text = text + leadingStr + " "
}
if let value = price {
text = text + currency + "\(value)"
}
if term != .none {
text = text + "/" + term.text
}
if let trailingStr = trailingText {
text = text + " " + trailingStr
}
text = text + (superscript ?? "")
return text
}
}