// // Modal.swift // VDS // // Created by Kanamarlapudi, Vasavi on 5/09/24. // import Foundation import UIKit import VDSCoreTokens import Combine /// A Modal is an overlay that interrupts the user flow /// to force the customer to provide information or a response. /// After the customer interacts with the modal, they can return to the parent content. @objcMembers @objc(VDSModal) open class Modal: Control, ModalLaunchable { //-------------------------------------------------- // 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: - Private Properties //-------------------------------------------------- internal var showModalButton = Button().with { $0.use = .primary $0.text = "Show Modal" } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- /// Text rendered for the title of the modal open var title: String? { didSet { setNeedsUpdate() } } /// Text rendered for the content of the modal open var content: String? { didSet { setNeedsUpdate() } } /// UIView rendered for the content area of the modal open var contentView: UIView? { didSet { setNeedsUpdate() } } //-------------------------------------------------- // 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(showModalButton) showModalButton.pinToSuperView() backgroundColor = .clear isAccessibilityElement = true accessibilityTraits = .button } open override func setDefaults() { super.setDefaults() title = nil content = nil contentView = nil showModalButton.onClick = { _ in self.showModalButtonClick() } } internal func showModalButtonClick() { print("Clicked showModalButton") self.presentModal(surface: self.surface, modalModel: .init(closeButtonText: showModalButton.text ?? "", title: title, content: content, contentView: contentView), presenter: self) } /// Used to make changes to the View based off a change events or from local properties. open override func updateView() { super.updateView() showModalButton.surface = surface } public static func accessibleText(for title: String?, content: String?, closeButtonText: String) -> String { var label = "" if let title { label = title } if let content { if !label.isEmpty { label += "," } label += content } return label } } // MARK: AppleGuidelinesTouchable extension Modal: AppleGuidelinesTouchable { /// Overrides to ensure that the touch point meets a minimum of the minimumTappableArea. override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { Self.acceptablyOutsideBounds(point: point, bounds: bounds) } }