// // ListUnordered.swift // VDS // // Created by Vasavi Kanamarlapudi on 16/10/24. // import Foundation import UIKit import VDSCoreTokens /// List unordered breaks up related content into distinct phrases or sentences, which improves scannability. /// This component should be used when the text items don’t need to be in numeric order. @objcMembers @objc(VDSListUnordered) open class ListUnordered: 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 that represents the size availble for the component. public enum Size: String, DefaultValuing, CaseIterable { case large case medium case small case micro public static var defaultValue: Self { .large } /// TextStyle relative to Size. public var textStyle: TextStyle.StandardStyle { switch self { case .large: return .bodyLarge case .medium: return .bodyMedium case .small: return .bodySmall case .micro: return .micro } } } /// Enum that represents the type of spacing available for the component. public enum Spacing: String, CaseIterable { case standard, compact } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- /// Size of the component. The default size is Large. open var size: Size = .defaultValue { didSet { setNeedsUpdate() } } /// Spacing type of the component. open var spacing: Spacing = .standard { didSet { setNeedsUpdate() } } /// Lead-in text that shows as the top text for the component. This is optional. open var leadInText: String? /// Array of unordered list items to show for the component. open var unorderedList: [ListUnorderedItemModel] = [] { didSet { setNeedsUpdate() }} //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- // It can be used for Glyph level 1. private var disc = "•" // It can be used for Glyph Level 2. private var endash = "–" // Spacing between unordered list items. private var spaceBetweenItems: CGFloat { switch (size, spacing) { case (.large, .standard): return VDSLayout.space4X case (.medium, .standard), (.small, .standard), (.micro, .standard): return VDSLayout.space3X case (.large, .compact): return VDSLayout.space2X case (.medium, .compact), (.small, .compact), (.micro, .compact): return VDSLayout.space1X } } // Padding that can be used in an item between the glyph and the item text. private var padding: CGFloat { switch (size, spacing) { case (.large, .standard), (.large, .compact): return VDSLayout.space3X case (.medium, .standard), (.small, .standard), (.micro, .standard), (.medium, .compact), (.small, .compact), (.micro, .compact): return VDSLayout.space2X } } private let textColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark) //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- private lazy var listStackView = UIStackView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.axis = .vertical $0.distribution = .fill $0.spacing = VDSLayout.space3X $0.backgroundColor = .clear } private lazy var itemStackView = UIStackView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.axis = .horizontal $0.alignment = .leading $0.distribution = .fill $0.spacing = padding $0.backgroundColor = .clear } internal var symbolLabel = Label().with { $0.isAccessibilityElement = true $0.numberOfLines = 1 $0.sizeToFit() } internal var textLabel = Label().with { $0.isAccessibilityElement = true $0.lineBreakMode = .byWordWrapping } //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and config.texturations. open override func setup() { super.setup() // add stackview addSubview(listStackView) listStackView.pinToSuperView() } open override func setDefaults() { super.setDefaults() leadInText = nil unorderedList = [] } /// Resets to default settings. open override func reset() { symbolLabel.reset() textLabel.reset() super.reset() } /// Used to make changes to the View based off a change events or from local properties. open override func updateView() { super.updateView() if leadInText != nil { textLabel.text = leadInText textLabel.textStyle = size.textStyle.regular textLabel.textColor = textColorConfiguration.getColor(surface) textLabel.surface = surface listStackView.addArrangedSubview(textLabel) } } //-------------------------------------------------- // MARK: - Private Methods //-------------------------------------------------- }