143 lines
4.6 KiB
Swift
143 lines
4.6 KiB
Swift
//
|
|
// Modal.swift
|
|
// VDS
|
|
//
|
|
// Created by Kanamarlapudi, Vasavi on 05/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() } }
|
|
|
|
///// Array of Buttonable Views that are shown as Modal Footer. Primary and Close button data for modal button group.
|
|
open var buttonData: [ButtonBase]? { didSet { setNeedsUpdate() } }
|
|
|
|
///// If provided, the Modal Dialog will render at full screen.
|
|
open var fullScreenDialog: Bool = false { 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() }
|
|
|
|
bridge_accessibilityLabelBlock = { [weak self] in
|
|
guard let self else { return "" }
|
|
var label = title
|
|
if label == nil {
|
|
label = content
|
|
}
|
|
if let label, !label.isEmpty {
|
|
return label
|
|
} else {
|
|
return "Modal"
|
|
}
|
|
}
|
|
|
|
bridge_accessibilityHintBlock = { [weak self] in
|
|
guard let self else { return "" }
|
|
return isEnabled ? "Double tap to open." : ""
|
|
}
|
|
}
|
|
|
|
internal func showModalButtonClick() {
|
|
self.presentModal(surface: self.surface,
|
|
modalModel: .init(closeButtonText: showModalButton.text ?? "",
|
|
title: title,
|
|
content: content,
|
|
contentView: contentView,
|
|
buttonData: buttonData),
|
|
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)
|
|
}
|
|
|
|
}
|