merge button and text link

This commit is contained in:
Scott Pfeil 2023-09-28 17:01:04 -04:00
commit b42d477b09
4 changed files with 66 additions and 149 deletions

View File

@ -11,29 +11,24 @@ import UIKit
open class ExternalLink: Link {
//--------------------------------------------------
// MARK: - Properties
// MARK: - Public Properties
//--------------------------------------------------
public var exportImageView: UIImageView?
open var exportImageView: UIImageView?
open var exportImageHeight: NSLayoutConstraint?
open var exportImageWidth: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
// MARK: - Overrides
//--------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ExternalLinkModel else { return }
exportImageView?.tintColor = titleColor(for: model.enabled ? .normal : .disabled)
open override func viewModelDidUpdate() {
super.viewModelDidUpdate()
exportImageView?.tintColor = textColor
exportImageWidth?.constant = textStyle.lineHeight
exportImageHeight?.constant = textStyle.lineHeight
}
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open override func setupView() {
super.setupView()
open override func setup() {
super.setup()
let image = MVMCoreUIUtility.imageNamed("externalLink")
exportImageView = UIImageView(image: image?.withRenderingMode(.alwaysTemplate))
@ -46,10 +41,10 @@ open class ExternalLink: Link {
addSubview(exportIcon)
trailingAnchor.constraint(greaterThanOrEqualTo: exportIcon.trailingAnchor).isActive = true
if let titleLabel = titleLabel {
let dimension = titleLabel.font.pointSize
exportIcon.heightAnchor.constraint(equalToConstant: dimension).isActive = true
exportIcon.widthAnchor.constraint(equalToConstant: dimension).isActive = true
exportImageHeight = exportIcon.heightAnchor.constraint(equalToConstant: textStyle.pointSize).activate()
exportImageWidth = exportIcon.widthAnchor.constraint(equalToConstant: textStyle.pointSize).activate()
if let titleLabel {
exportIcon.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 4).isActive = true
exportIcon.bottomAnchor.constraint(equalTo: titleLabel.lastBaselineAnchor, constant: 3).isActive = true
}

View File

@ -8,83 +8,59 @@
import UIKit
import VDSColorTokens
import VDS
open class Link: VDS.TextLink, VDSMoleculeViewProtocol {
@objcMembers open class Link: Button {
//--------------------------------------------------
// MARK: - Draw
// MARK: - Public Properties
//--------------------------------------------------
open var viewModel: LinkModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
open override func draw(_ rect: CGRect) {
//--------------------------------------------------
// MARK: - Public Functions
//--------------------------------------------------
open func viewModelDidUpdate() {
isEnabled = viewModel.enabled
size = viewModel.size
text = viewModel.title
surface = viewModel.surface
guard let textRect = titleLabel?.frame,
let context = UIGraphicsGetCurrentContext()
else { return }
onClick = { [weak self] control in
guard let self else { return }
MVMCoreUIActionHandler.performActionUnstructured(with: self.viewModel.action,
sourceModel: self.viewModel,
additionalData: self.additionalData,
delegateObject: self.delegateObject)
}
}
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
open override func updateAccessibility() {
super.updateAccessibility()
// Set line to the same color as the text
if let color = titleColor(for: state)?.cgColor {
context.setStrokeColor(color)
guard let viewModel = viewModel else { return }
if let accessibilityText = viewModel.accessibilityText {
self.accessibilityLabel = accessibilityText
}
// x should be according to the text, not the button
let x = textRect.origin.x
// Line is 0 point below the text
let y = textRect.origin.y + textRect.size.height
context.move(to: CGPoint(x: x, y: y))
context.addLine(to: CGPoint(x: x + textRect.size.width, y: y))
context.strokePath()
}
open override var intrinsicContentSize: CGSize {
guard let size = titleLabel?.intrinsicContentSize else { return super.intrinsicContentSize }
return CGSize(width: size.width, height: size.height + 1)
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? LinkModel else { return }
setTitle(model.title, for: .normal)
if let accessibilityText = model.accessibilityText {
accessibilityLabel = accessibilityText
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
setTitleColor((model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor, for: .normal)
setTitleColor((model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor, for: .disabled)
setTitleColor((model.inverted ? model.activeColor_inverted : model.activeColor).uiColor, for: .highlighted)
isEnabled = model.enabled
titleLabel?.font = model.getFont(model.size)
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 31 }
}
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 31 }
// MARK: - MVMCoreViewProtocol
extension Link {
open func updateView(_ size: CGFloat) { }
open override func updateView(_ size: CGFloat) {
super.updateView(size)
}
open override func setupView() {
super.setupView()
backgroundColor = .clear
contentMode = .redraw
setTitleColor(VDSColor.elementsPrimaryOnlight, for: .normal)
setTitleColor(VDSColor.interactiveDisabledOnlight, for: .disabled)
setTitleColor(VDSColor.interactiveActiveOnlight, for: .highlighted)
titleLabel?.numberOfLines = 1
titleLabel?.lineBreakMode = .byTruncatingTail
titleLabel?.textAlignment = .left
contentHorizontalAlignment = .left
contentVerticalAlignment = .top
}
open func setupView() {}
}
// MARK: - MVMCoreUIViewConstrainingProtocol

View File

@ -7,7 +7,7 @@
//
import UIKit
import VDSColorTokens
import VDS
open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol {
//--------------------------------------------------
@ -23,15 +23,9 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
public var accessibilityText: String?
public var action: ActionModelProtocol
public var enabled = true
public var enabledColor = Color(uiColor: VDSColor.elementsPrimaryOnlight)
public var enabledColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOndark)
public var disabledColor = Color(uiColor: VDSColor.interactiveDisabledOnlight)
public var disabledColor_inverted = Color(uiColor: VDSColor.interactiveDisabledOndark)
public var activeColor = Color(uiColor: VDSColor.interactiveActiveOnlight)
public var activeColor_inverted = Color(uiColor: VDSColor.interactiveActiveOndark)
public var inverted = false
public var size:linkFontSize = linkFontSize.small
public var size: TextLink.Size = .small
public var shouldMaskRecordedView: Bool? = false
@ -57,34 +51,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
case title
case action
case enabled
case enabledColor
case enabledColor_inverted
case disabledColor
case disabledColor_inverted
case activeColor
case activeColor_inverted
case inverted
case size
case shouldMaskRecordedView
}
public enum linkFontSize: String, Codable {
case small
case large
}
//--------------------------------------------------
// MARK: - Method
//--------------------------------------------------
func getFont(_ type: linkFontSize) -> UIFont {
switch type {
case .small:
return MFStyler.fontRegularBodySmall()
case .large:
return MFStyler.fontRegularBodyLarge()
}
}
//--------------------------------------------------
// MARK: - Codec
@ -108,30 +78,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
self.inverted = inverted
}
if let enabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) {
self.enabledColor = enabledColor
}
if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) {
self.enabledColor_inverted = enabledColor_inverted
}
if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
self.disabledColor = disabledColor
}
if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) {
self.disabledColor_inverted = disabledColor_inverted
}
if let activeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor) {
self.activeColor = activeColor
}
if let activeColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor_inverted) {
self.activeColor_inverted = activeColor_inverted
}
if let size = try typeContainer.decodeIfPresent(linkFontSize.self, forKey: .size) {
if let size = try typeContainer.decodeIfPresent(TextLink.Size.self, forKey: .size) {
self.size = size
}
@ -148,13 +95,11 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
try container.encodeModel(action, forKey: .action)
try container.encode(inverted, forKey: .inverted)
try container.encode(enabled, forKey: .enabled)
try container.encode(enabledColor, forKey: .enabledColor)
try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted)
try container.encode(disabledColor, forKey: .disabledColor)
try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted)
try container.encode(activeColor, forKey: .activeColor)
try container.encode(activeColor_inverted, forKey: .activeColor_inverted)
try container.encodeIfPresent(size, forKey: .size)
try container.encode(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
}
}
extension LinkModel {
public var surface: Surface { inverted ? .dark : .light }
}

View File

@ -21,3 +21,4 @@ extension VDS.Button.Size: RawRepresentableCodable {
public static var mapping: [String : VDS.Button.Size] { ["standard": .large, "tiny": .small] }
public static var defaultValue: VDS.Button.Size? { nil }
}
extension TextLink.Size: Codable {}