diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift index e051cf32..9e5cd108 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift @@ -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 } diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift index c6a14872..5ca77679 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift @@ -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 diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index 62ba0422..7e9a4640 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -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 } +} diff --git a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift index ee504e2f..092956a3 100644 --- a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift +++ b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift @@ -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 {}