From 68868a35ed547968777968376fd839573ea50e59 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 3 Oct 2022 15:28:18 -0500 Subject: [PATCH 01/23] first cut of entry fields Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 40 ++++ .../TextFields/EntryField/EntryField.swift | 194 ++++++++++++++++++ .../EntryField/EntryFieldModel.swift | 69 +++++++ .../TextEntryField/TextEntryField.swift | 64 ++++++ .../TextEntryField/TextEntryFieldModel.swift | 49 +++++ 5 files changed, 416 insertions(+) create mode 100644 VDS/Components/TextFields/EntryField/EntryField.swift create mode 100644 VDS/Components/TextFields/EntryField/EntryFieldModel.swift create mode 100644 VDS/Components/TextFields/TextEntryField/TextEntryField.swift create mode 100644 VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index a34f8806..edd1fe38 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -59,6 +59,10 @@ EA89201328B568D8006B9984 /* RadioBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201228B568D8006B9984 /* RadioBox.swift */; }; EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201428B56CF4006B9984 /* RadioBoxGroup.swift */; }; EA89201728B56CFF006B9984 /* RadioBoxGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201628B56CFF006B9984 /* RadioBoxGroupModel.swift */; }; + EAA5EEA928EB3ED0003B3210 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEA828EB3ED0003B3210 /* EntryField.swift */; }; + EAA5EEAB28EB3ED9003B3210 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */; }; + EAA5EEB128EB6A5A003B3210 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */; }; + EAA5EEB328EB6A66003B3210 /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */; }; EAB1D29A28A5611D00DAE764 /* SelectorGroupModelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */; }; EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */; }; EAB1D29E28A5619500DAE764 /* RadioButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */; }; @@ -161,6 +165,10 @@ EA89201228B568D8006B9984 /* RadioBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBox.swift; sourceTree = ""; }; EA89201428B56CF4006B9984 /* RadioBoxGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxGroup.swift; sourceTree = ""; }; EA89201628B56CFF006B9984 /* RadioBoxGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxGroupModel.swift; sourceTree = ""; }; + EAA5EEA828EB3ED0003B3210 /* EntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = ""; }; + EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = ""; }; + EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = ""; }; + EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupModelable.swift; sourceTree = ""; }; EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = ""; }; EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroupModel.swift; sourceTree = ""; }; @@ -309,6 +317,7 @@ EA89200B28B530F0006B9984 /* RadioBox */, EAF7F11428A1470D00B287F5 /* RadioButton */, EA1F265F28B945070033E859 /* RadioSwatch */, + EAA5EEA728EB3EBC003B3210 /* TextFields */, EA3361A0288B1E6F0071C351 /* Toggle */, ); path = Components; @@ -440,6 +449,33 @@ path = RadioBox; sourceTree = ""; }; + EAA5EEA728EB3EBC003B3210 /* TextFields */ = { + isa = PBXGroup; + children = ( + EAA5EEAF28EB6A49003B3210 /* TextEntryField */, + EAA5EEAE28EB6A3D003B3210 /* EntryField */, + ); + path = TextFields; + sourceTree = ""; + }; + EAA5EEAE28EB6A3D003B3210 /* EntryField */ = { + isa = PBXGroup; + children = ( + EAA5EEA828EB3ED0003B3210 /* EntryField.swift */, + EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */, + ); + path = EntryField; + sourceTree = ""; + }; + EAA5EEAF28EB6A49003B3210 /* TextEntryField */ = { + isa = PBXGroup; + children = ( + EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */, + EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */, + ); + path = TextEntryField; + sourceTree = ""; + }; EAB1D29F28A598D000DAE764 /* PropertyWrappers */ = { isa = PBXGroup; children = ( @@ -628,6 +664,7 @@ EAF7F11828A1475A00B287F5 /* RadioButtonModel.swift in Sources */, EA89200D28B530FD006B9984 /* RadioBoxModel.swift in Sources */, EA1F266728B945070033E859 /* RadioSwatchModel.swift in Sources */, + EAA5EEB328EB6A66003B3210 /* TextEntryField.swift in Sources */, EA89201328B568D8006B9984 /* RadioBox.swift in Sources */, EA84F6B128B94A2500D67ABC /* CodableColor.swift in Sources */, EA3362402892EF6C0071C351 /* Label.swift in Sources */, @@ -637,6 +674,8 @@ EAF7F0AF289B144C00B287F5 /* LabelAttributeUnderline.swift in Sources */, EA3361C5289030FC0071C351 /* Accessable.swift in Sources */, EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */, + EAA5EEAB28EB3ED9003B3210 /* EntryFieldModel.swift in Sources */, + EAA5EEA928EB3ED0003B3210 /* EntryField.swift in Sources */, EAF7F11728A1475A00B287F5 /* RadioButton.swift in Sources */, EAB1D2A128A598FE00DAE764 /* UsesAutoLayout.swift in Sources */, EAB1D2CD28ABE76100DAE764 /* Withable.swift in Sources */, @@ -666,6 +705,7 @@ EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */, EAB1D29A28A5611D00DAE764 /* SelectorGroupModelable.swift in Sources */, EAF7F0BB289D80ED00B287F5 /* Modelable.swift in Sources */, + EAA5EEB128EB6A5A003B3210 /* TextEntryFieldModel.swift in Sources */, EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */, EA4DB30028DCBC9900103EE3 /* BadgeModel.swift in Sources */, EAF7F09E289AAEC000B287F5 /* Constants.swift in Sources */, diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift new file mode 100644 index 00000000..21fe9c1c --- /dev/null +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -0,0 +1,194 @@ +// +// EntryField.swift +// VDS +// +// Created by Matt Bruce on 10/3/22. +// + +import Foundation +import UIKit +import VDSColorTokens +import Combine + +open class EntryField: Control { + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var stackView: UIStackView = { + return UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .vertical + $0.distribution = .fill + } + }() + + private var containerStackView: UIStackView = { + return UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .horizontal + $0.distribution = .fill + $0.spacing = 12 + } + }() + + private var titleLabel = Label() + private var errorLabel = Label() + private var helperLabel = Label() + private var successLabel = Label() + + internal var containerView: UIView = { + return UIView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + } + }() + + //-------------------------------------------------- + // MARK: - Configuration Properties + //-------------------------------------------------- + // Sizes are from InVision design specs. + public let containerSize = CGSize(width: 45, height: 45) + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + @Proxy(\.model.labelText) + open var labelText: String? + + @Proxy(\.model.helperText) + open var helperText: String? + + @Proxy(\.model.showError) + open var showError: Bool + + @Proxy(\.model.errorText) + open var errorText: String? + + @Proxy(\.model.showSuccess) + open var showSuccess: Bool + + @Proxy(\.model.successText) + open var successText: String? + + @Proxy(\.model.helperTextPlacement) + open var helperTextPlacement: HelperTextPlacement + + @Proxy(\.model.transparentBackground) + open var transparentBackground: Bool + + @Proxy(\.model.width) + open var width: CGFloat? + + @Proxy(\.model.maxLength) + open var maxLength: Int? + + @Proxy(\.model.inputId) + open var inputId: String? + + @Proxy(\.model.value) + open var value: AnyHashable? + + @Proxy(\.model.defaultVaue) + open var defaultValue: AnyHashable? + + @Proxy(\.model.required) + open var required: Bool + + @Proxy(\.model.readOnly) + open var readOnly: Bool + + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + internal var heightConstraint: NSLayoutConstraint? + internal var widthConstraint: NSLayoutConstraint? + internal var minWidthConstraint: NSLayoutConstraint? + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func setup() { + super.setup() + + //add tapGesture to self + publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in + self?.sendActions(for: .touchUpInside) + }.store(in: &subscribers) + + isAccessibilityElement = true + accessibilityTraits = .button + addSubview(stackView) + + //create the wrapping view + containerView.widthAnchor.constraint(equalToConstant: containerSize.width).isActive = true + containerView.heightAnchor.constraint(equalToConstant: containerSize.height).isActive = true + + heightConstraint = containerView.heightAnchor.constraint(equalToConstant: containerSize.height) + heightConstraint?.isActive = true + + widthConstraint = containerView.widthAnchor.constraint(equalToConstant: containerSize.width) + + minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: containerSize.width) + minWidthConstraint?.isActive = true + + containerStackView.addArrangedSubview(containerView) + stackView.addArrangedSubview(titleLabel) + stackView.addArrangedSubview(containerStackView) + stackView.addArrangedSubview(errorLabel) + stackView.addArrangedSubview(successLabel) + + stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true + stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true + stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true + stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + } + + public override func reset() { + super.reset() + setAccessibilityLabel() + } + + //-------------------------------------------------- + // MARK: - State + //-------------------------------------------------- + open override func updateView(viewModel: ModelType) { + + titleLabel.set(with: viewModel.labelModel) + + //show error or success + if viewModel.showError, let errorLabelModel = viewModel.errorLabelModel { + errorLabel.set(with: errorLabelModel) + errorLabel.isHidden = false + successLabel.isHidden = true + } else if viewModel.showSuccess, let successLabelModel = viewModel.successLabelModel { + successLabel.set(with: successLabelModel) + errorLabel.isHidden = true + successLabel.isHidden = false + } else { + errorLabel.isHidden = true + successLabel.isHidden = true + } + + //set the helper label position + if let helperLabelModel = viewModel.helperLabelModel { + helperLabel.removeFromSuperview() + if viewModel.helperTextPlacement == .right { + containerStackView.spacing = 12 + containerStackView.addArrangedSubview(helperLabel) + } else { + containerStackView.spacing = 0 + stackView.addArrangedSubview(helperLabel) + } + helperLabel.set(with: helperLabelModel) + helperLabel.isHidden = false + } else { + helperLabel.isHidden = true + } + + setAccessibilityHint(!viewModel.disabled) + backgroundColor = viewModel.surface.color + setNeedsLayout() + layoutIfNeeded() + } +} diff --git a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift new file mode 100644 index 00000000..f2fd8a9b --- /dev/null +++ b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift @@ -0,0 +1,69 @@ +// +// EntryFieldModel.swift +// VDS +// +// Created by Matt Bruce on 10/3/22. +// + +import Foundation + +public enum HelperTextPlacement: String, CaseIterable { + case bottom, right +} + +public protocol EntryFieldModel: Modelable, FormFieldable, Errorable { + var defaultVaue: AnyHashable? { get set } + var required: Bool { get set } + var readOnly: Bool { get set } + var labelText: String? { get set } + var helperText: String? { get set } + var helperTextPlacement: HelperTextPlacement { get set } + var showSuccess: Bool { get set } + var successText: String? { get set } + var transparentBackground: Bool { get set } + var width: CGFloat? { get set } + var maxLength: Int? { get set } +} + +extension EntryFieldModel { + + public var labelModel: DefaultLabelModel { + var model = DefaultLabelModel() + model.textPosition = .left + model.typograpicalStyle = .BodySmall + model.text = labelText ?? "" + model.surface = surface + model.disabled = disabled + return model + } + + public var helperLabelModel: DefaultLabelModel? { + var model = DefaultLabelModel() + model.textPosition = .left + model.typograpicalStyle = .BodySmall + model.text = helperText + model.surface = surface + model.disabled = disabled + return model + } + + public var errorLabelModel: DefaultLabelModel? { + var model = DefaultLabelModel() + model.textPosition = .left + model.typograpicalStyle = .BodySmall + model.text = errorText + model.surface = surface + model.disabled = disabled + return model + } + + public var successLabelModel: DefaultLabelModel? { + var model = DefaultLabelModel() + model.textPosition = .left + model.typograpicalStyle = .BodySmall + model.text = successText + model.surface = surface + model.disabled = disabled + return model + } +} diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift new file mode 100644 index 00000000..fb2255cc --- /dev/null +++ b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift @@ -0,0 +1,64 @@ +// +// TextEntryField.swift +// VDS +// +// Created by Matt Bruce on 10/3/22. +// + +import Foundation +import UIKit +import VDSColorTokens +import Combine + +public class TextEntryField: TextEntryFieldBase{} + +open class TextEntryFieldBase: EntryField { + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + + @Proxy(\.model.type) + public var type: TextEntryFieldType + + + //-------------------------------------------------- + // MARK: - State + //-------------------------------------------------- + open override func updateView(viewModel: ModelType) { + super.updateView(viewModel: viewModel) + containerView.backgroundColor = .red + + //set the width constraints + if let width = viewModel.width, width > viewModel.type.width { + widthConstraint?.constant = width + widthConstraint?.isActive = true + minWidthConstraint?.isActive = false + } else { + minWidthConstraint?.constant = viewModel.type.width + widthConstraint?.isActive = false + minWidthConstraint?.isActive = true + } + } +} + +extension TextEntryFieldType { + var width: CGFloat { + switch self { + case .inlineAction: + return 102 + case .password: + return 62.0 + case .creditCard: + return 288.0 + case .tel: + return 176.0 + case .date: + return 114.0 + case .securityCode: + return 88.0 + default: + return 40.0 + } + } +} diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift new file mode 100644 index 00000000..e50947ec --- /dev/null +++ b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift @@ -0,0 +1,49 @@ +// +// TextEntryFieldModel.swift +// VDS +// +// Created by Matt Bruce on 10/3/22. +// + +import Foundation + +public enum TextEntryFieldType: String, CaseIterable { + case text, number, calendar, inlineAction, password, creditCard, tel, date, securityCode +} + +public protocol TextEntryFieldModel: EntryFieldModel { + var type: TextEntryFieldType { get set } +} + + +public struct DefaultTextEntryField: TextEntryFieldModel { + public var id = UUID() + public var inputId: String? + + public var type: TextEntryFieldType = .text + public var value: AnyHashable? + public var defaultVaue: AnyHashable? + public var required: Bool = false + public var readOnly: Bool = false + + public var labelText: String? + + public var helperText: String? + public var helperTextPlacement: HelperTextPlacement = .bottom + + public var showError: Bool = false + public var errorText: String? + + public var showSuccess: Bool = false + public var successText: String? + + public var transparentBackground: Bool = false + public var width: CGFloat? + public var maxLength: Int? + + + public var surface: Surface = .light + public var disabled: Bool = false + + public init() { } +} From 7d007e0391299cc8ec0e316379a6224d00d283a0 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 4 Oct 2022 09:16:59 -0500 Subject: [PATCH 02/23] fixed background color Signed-off-by: Matt Bruce --- VDS/Protocols/Surfaceable.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Protocols/Surfaceable.swift b/VDS/Protocols/Surfaceable.swift index d1eec284..d5283a37 100644 --- a/VDS/Protocols/Surfaceable.swift +++ b/VDS/Protocols/Surfaceable.swift @@ -12,7 +12,7 @@ import VDSColorTokens public enum Surface: String, Codable, Equatable { case light, dark public var color: UIColor { - return self == .dark ? VDSColor.backgroundPrimaryDark : .clear + return self == .dark ? VDSColor.backgroundPrimaryDark : VDSColor.backgroundSecondaryLight } } From be71919ccf956b49005d5613516a4c417c73e2ef Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 4 Oct 2022 11:38:20 -0500 Subject: [PATCH 03/23] added new properties for accessible and for actions that aren't text Signed-off-by: Matt Bruce --- .../Label/Attributes/LabelAttributeAction.swift | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Label/Attributes/LabelAttributeAction.swift b/VDS/Components/Label/Attributes/LabelAttributeAction.swift index f2a5fe49..7e280a42 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeAction.swift +++ b/VDS/Components/Label/Attributes/LabelAttributeAction.swift @@ -10,6 +10,7 @@ import UIKit import Combine public protocol LabelAttributeActionable: LabelAttributeModel { + var accessibleText: String? { get set } var action: PassthroughSubject { get set } } @@ -29,15 +30,19 @@ public struct LabelAttributeActionModel: LabelAttributeActionable { public var id = UUID() public var location: Int public var length: Int + public var shouldUnderline: Bool + public var accessibleText: String? public var action = PassthroughSubject() //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- - public init(location: Int, length: Int) { + public init(location: Int, length: Int, shouldUnderline: Bool = true, accessibleText: String? = nil) { self.location = location self.length = length + self.shouldUnderline = shouldUnderline + self.accessibleText = accessibleText } private enum CodingKeys: String, CodingKey { @@ -45,6 +50,8 @@ public struct LabelAttributeActionModel: LabelAttributeActionable { } public func setAttribute(on attributedString: NSMutableAttributedString) { - attributedString.addAttribute(.underlineStyle, value: UnderlineStyle.single.value(), range: range) + if(shouldUnderline){ + attributedString.addAttribute(.underlineStyle, value: UnderlineStyle.single.value(), range: range) + } } } From 7551519d2db8003b4a8628bbc91ea40c2ec3d8af Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 4 Oct 2022 11:38:44 -0500 Subject: [PATCH 04/23] added accessibleText for actions as an override Signed-off-by: Matt Bruce --- VDS/Components/Label/Label.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 93eb5754..8dae7755 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -161,7 +161,7 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt //see if the attribute is Actionable if let actionable = attribute as? any LabelAttributeActionable{ //create a accessibleAction - let customAccessibilityAction = customAccessibilityAction(range: actionable.range) + let customAccessibilityAction = customAccessibilityAction(range: actionable.range, accessibleText: actionable.accessibleText) //create a wrapper for the attributes range, block and actions.append(LabelAction(range: actionable.range, action: actionable.action, accessibilityID: customAccessibilityAction?.hashValue ?? -1)) @@ -274,7 +274,7 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt //-------------------------------------------------- // MARK: - Accessibility For Actions //-------------------------------------------------- - private func customAccessibilityAction(range: NSRange) -> UIAccessibilityCustomAction? { + private func customAccessibilityAction(range: NSRange, accessibleText: String? = nil) -> UIAccessibilityCustomAction? { guard let text = text else { return nil } //TODO: accessibilityHint for Label @@ -282,7 +282,7 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt // accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "swipe_to_select_with_action_hint") // } - let actionText = NSString(string: text).substring(with: range) + let actionText = accessibleText ?? NSString(string:text).substring(with: range) let accessibleAction = UIAccessibilityCustomAction(name: actionText, target: self, selector: #selector(accessibilityCustomAction(_:))) accessibilityCustomActions?.append(accessibleAction) From 61493d382d138be7beb5513fd0f579ad4673cd1c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 4 Oct 2022 11:39:27 -0500 Subject: [PATCH 05/23] added more structs for helping attribrutes/colors, etc.. Signed-off-by: Matt Bruce --- .../TextFields/EntryField/EntryField.swift | 140 ++++++++++++++++-- .../EntryField/EntryFieldModel.swift | 6 +- .../TextEntryField/TextEntryFieldModel.swift | 4 +- 3 files changed, 137 insertions(+), 13 deletions(-) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index 21fe9c1c..d5fb351b 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -49,6 +49,20 @@ open class EntryField: Control { // Sizes are from InVision design specs. public let containerSize = CGSize(width: 45, height: 45) + internal let primaryColorConfig = DisabledSurfaceColorConfiguration().with { + $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.disabled.darkColor = VDSColor.interactiveDisabledOndark + $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.enabled.darkColor = VDSColor.elementsPrimaryOndark + } + + internal let secondaryColorConfig = DisabledSurfaceColorConfiguration().with { + $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.disabled.darkColor = VDSColor.interactiveDisabledOndark + $0.enabled.lightColor = VDSColor.elementsSecondaryOnlight + $0.enabled.darkColor = VDSColor.elementsSecondaryOndark + } + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -72,6 +86,12 @@ open class EntryField: Control { @Proxy(\.model.helperTextPlacement) open var helperTextPlacement: HelperTextPlacement + + @Proxy(\.model.tooltipTitle) + open var tooltipTitle: String? + + @Proxy(\.model.tooltipContent) + open var tooltipContent: String? @Proxy(\.model.transparentBackground) open var transparentBackground: Bool @@ -104,7 +124,7 @@ open class EntryField: Control { internal var heightConstraint: NSLayoutConstraint? internal var widthConstraint: NSLayoutConstraint? internal var minWidthConstraint: NSLayoutConstraint? - + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- @@ -121,15 +141,12 @@ open class EntryField: Control { addSubview(stackView) //create the wrapping view - containerView.widthAnchor.constraint(equalToConstant: containerSize.width).isActive = true - containerView.heightAnchor.constraint(equalToConstant: containerSize.height).isActive = true - - heightConstraint = containerView.heightAnchor.constraint(equalToConstant: containerSize.height) + heightConstraint = containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: containerSize.height) heightConstraint?.isActive = true - widthConstraint = containerView.widthAnchor.constraint(equalToConstant: containerSize.width) + widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 0) - minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: containerSize.width) + minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: 0) minWidthConstraint?.isActive = true containerStackView.addArrangedSubview(containerView) @@ -138,24 +155,47 @@ open class EntryField: Control { stackView.addArrangedSubview(errorLabel) stackView.addArrangedSubview(successLabel) + stackView.setCustomSpacing(4, after: titleLabel) + stackView.setCustomSpacing(8, after: containerStackView) + stackView.setCustomSpacing(8, after: errorLabel) + stackView.setCustomSpacing(8, after: successLabel) + stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + + titleLabel.textColorConfiguration = primaryColorConfig + successLabel.textColorConfiguration = primaryColorConfig + errorLabel.textColorConfiguration = primaryColorConfig + helperLabel.textColorConfiguration = secondaryColorConfig } public override func reset() { super.reset() setAccessibilityLabel() } - + //-------------------------------------------------- // MARK: - State //-------------------------------------------------- open override func updateView(viewModel: ModelType) { + + //update the title model if the required flag is false + var titleLabelModel = viewModel.labelModel + .addOptional(required: viewModel.required, colorConfiguration: secondaryColorConfig) + + //tooltip action + if let toolTipTitle = viewModel.tooltipTitle, let toolTipContent = viewModel.tooltipContent { + let toolTipAction = PassthroughSubject() + titleLabelModel = titleLabelModel.addToolTip(action: toolTipAction, colorConfiguration: primaryColorConfig) + toolTipAction.sink { + print("clicked Tool Tip: \rtitle:\(toolTipTitle)\rcontent:\(toolTipContent)") + }.store(in: &subscribers) + } - titleLabel.set(with: viewModel.labelModel) - + titleLabel.set(with: titleLabelModel) + //show error or success if viewModel.showError, let errorLabelModel = viewModel.errorLabelModel { errorLabel.set(with: errorLabelModel) @@ -192,3 +232,83 @@ open class EntryField: Control { layoutIfNeeded() } } + +extension DefaultLabelModel { + public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { + guard let text = text, !required else { return self} + let optionColorAttr = LabelAttributeColor(location: text.count + 2, + length: 8, + color: colorConfiguration.getColor(self)) + + let newText = "\(text) Optional" + return copyWith { + $0.text = newText + $0.attributes = [optionColorAttr] + } + } + + public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { + guard let text = text else { return self} + var newAttributes = attributes ?? [] + let newText = "\(text) " + let toolTip = ToolTipLabelAttribute(action: action, + location: newText.count, + length: 1, + tintColor: colorConfiguration.getColor(self)) + newAttributes.append(toolTip) + return copyWith { + $0.text = newText + $0.attributes = newAttributes + } + } +} + +public struct LabelSystemImageAttachement: LabelAttributeAttachment { + public var id = UUID() + public var location: Int + public var length: Int + public var imageName: String + public var frame: CGRect + public var tintColor: UIColor + public static func == (lhs: LabelSystemImageAttachement, rhs: LabelSystemImageAttachement) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: LabelSystemImageAttachement) -> Bool { + return id == equatable.id && range == equatable.range && imageName == equatable.imageName + } + + public func getAttachment() throws -> NSTextAttachment { + let attachment = NSTextAttachment() + attachment.image = UIImage(systemName: imageName)?.withTintColor(tintColor) + attachment.bounds = frame + return attachment + } +} + +public struct ToolTipLabelAttribute: LabelAttributeActionable { + public var id = UUID() + public var accessibleText: String? = "Tool Tip" + public var action = PassthroughSubject() + public var location: Int + public var length: Int + public var tintColor: UIColor + public func setAttribute(on attributedString: NSMutableAttributedString) { + let image = LabelSystemImageAttachement(location: location, + length: length, + imageName: "info.circle", + frame: .init(x: 0, y: -2, width: 13.3, height: 13.3), + tintColor: tintColor) + + image.setAttribute(on: attributedString) + + } + + public static func == (lhs: ToolTipLabelAttribute, rhs: ToolTipLabelAttribute) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: ToolTipLabelAttribute) -> Bool { + return id == equatable.id && range == equatable.range + } +} diff --git a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift index f2fd8a9b..86d80427 100644 --- a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift +++ b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift @@ -23,6 +23,8 @@ public protocol EntryFieldModel: Modelable, FormFieldable, Errorable { var transparentBackground: Bool { get set } var width: CGFloat? { get set } var maxLength: Int? { get set } + var tooltipTitle: String? { get set } + var tooltipContent: String? { get set } } extension EntryFieldModel { @@ -31,12 +33,12 @@ extension EntryFieldModel { var model = DefaultLabelModel() model.textPosition = .left model.typograpicalStyle = .BodySmall - model.text = labelText ?? "" + model.text = labelText model.surface = surface model.disabled = disabled return model } - + public var helperLabelModel: DefaultLabelModel? { var model = DefaultLabelModel() model.textPosition = .left diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift index e50947ec..4b310b4a 100644 --- a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift +++ b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift @@ -41,7 +41,9 @@ public struct DefaultTextEntryField: TextEntryFieldModel { public var width: CGFloat? public var maxLength: Int? - + public var tooltipTitle: String? + public var tooltipContent: String? + public var surface: Surface = .light public var disabled: Bool = false From e2573492fa8b544dad8660006e5878ed8fad7ce3 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 4 Oct 2022 12:44:42 -0500 Subject: [PATCH 06/23] added entry field colors Signed-off-by: Matt Bruce --- .../TextFields/EntryField/EntryField.swift | 111 +++++++++++++----- .../TextEntryField/TextEntryField.swift | 6 +- 2 files changed, 88 insertions(+), 29 deletions(-) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index d5fb351b..e8643ecb 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -8,10 +8,11 @@ import Foundation import UIKit import VDSColorTokens +import VDSFormControlsTokens import Combine open class EntryField: Control { - + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -42,7 +43,7 @@ open class EntryField: Control { $0.translatesAutoresizingMaskIntoConstraints = false } }() - + //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- @@ -62,25 +63,57 @@ open class EntryField: Control { $0.enabled.lightColor = VDSColor.elementsSecondaryOnlight $0.enabled.darkColor = VDSColor.elementsSecondaryOndark } + + internal var backgroundColorConfiguration: EntryFieldColorConfiguration = { + return EntryFieldColorConfiguration().with { + $0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.disabled.darkColor = VDSFormControlsColor.backgroundOndark + + //error/success doesn't care enabled/disable + $0.error.lightColor = VDSColor.feedbackErrorBackgroundOnlight + $0.error.darkColor = VDSColor.feedbackErrorBackgroundOndark + $0.success.lightColor = VDSColor.feedbackSuccessBackgroundOnlight + $0.success.darkColor = VDSColor.feedbackSuccessBackgroundOndark + + } + }() + + internal var borderColorConfiguration: EntryFieldColorConfiguration = { + return EntryFieldColorConfiguration().with { + $0.enabled.lightColor = VDSFormControlsColor.borderOnlight + $0.enabled.darkColor = VDSFormControlsColor.borderOnlight + $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.disabled.darkColor = VDSColor.interactiveDisabledOndark + + //error/success doesn't care enabled/disable + $0.error.lightColor = VDSColor.feedbackErrorOnlight + $0.error.darkColor = VDSColor.feedbackErrorOndark + $0.success.lightColor = VDSColor.feedbackSuccessOnlight + $0.success.darkColor = VDSColor.feedbackSuccessOndark + } + }() + //-------------------------------------------------- // MARK: - Public Properties - //-------------------------------------------------- + //-------------------------------------------------- @Proxy(\.model.labelText) open var labelText: String? - + @Proxy(\.model.helperText) open var helperText: String? - + @Proxy(\.model.showError) open var showError: Bool - + @Proxy(\.model.errorText) open var errorText: String? - + @Proxy(\.model.showSuccess) open var showSuccess: Bool - + @Proxy(\.model.successText) open var successText: String? @@ -92,39 +125,39 @@ open class EntryField: Control { @Proxy(\.model.tooltipContent) open var tooltipContent: String? - + @Proxy(\.model.transparentBackground) open var transparentBackground: Bool - + @Proxy(\.model.width) open var width: CGFloat? - + @Proxy(\.model.maxLength) open var maxLength: Int? - + @Proxy(\.model.inputId) open var inputId: String? - + @Proxy(\.model.value) open var value: AnyHashable? - + @Proxy(\.model.defaultVaue) open var defaultValue: AnyHashable? - + @Proxy(\.model.required) open var required: Bool - + @Proxy(\.model.readOnly) open var readOnly: Bool - - + + //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- internal var heightConstraint: NSLayoutConstraint? internal var widthConstraint: NSLayoutConstraint? internal var minWidthConstraint: NSLayoutConstraint? - + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- @@ -139,7 +172,7 @@ open class EntryField: Control { isAccessibilityElement = true accessibilityTraits = .button addSubview(stackView) - + //create the wrapping view heightConstraint = containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: containerSize.height) heightConstraint?.isActive = true @@ -148,7 +181,7 @@ open class EntryField: Control { minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: 0) minWidthConstraint?.isActive = true - + containerStackView.addArrangedSubview(containerView) stackView.addArrangedSubview(titleLabel) stackView.addArrangedSubview(containerStackView) @@ -164,7 +197,7 @@ open class EntryField: Control { stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true - + titleLabel.textColorConfiguration = primaryColorConfig successLabel.textColorConfiguration = primaryColorConfig errorLabel.textColorConfiguration = primaryColorConfig @@ -180,11 +213,11 @@ open class EntryField: Control { // MARK: - State //-------------------------------------------------- open override func updateView(viewModel: ModelType) { - + //update the title model if the required flag is false var titleLabelModel = viewModel.labelModel - .addOptional(required: viewModel.required, colorConfiguration: secondaryColorConfig) - + .addOptional(required: viewModel.required, colorConfiguration: secondaryColorConfig) + //tooltip action if let toolTipTitle = viewModel.tooltipTitle, let toolTipContent = viewModel.tooltipContent { let toolTipAction = PassthroughSubject() @@ -195,7 +228,7 @@ open class EntryField: Control { } titleLabel.set(with: titleLabelModel) - + //show error or success if viewModel.showError, let errorLabelModel = viewModel.errorLabelModel { errorLabel.set(with: errorLabelModel) @@ -225,12 +258,36 @@ open class EntryField: Control { } else { helperLabel.isHidden = true } - + setAccessibilityHint(!viewModel.disabled) backgroundColor = viewModel.surface.color setNeedsLayout() layoutIfNeeded() } + + //-------------------------------------------------- + // MARK: - Color Class Configurations + //-------------------------------------------------- + internal class EntryFieldColorConfiguration: DisabledSurfaceColorConfiguration { + public let error = SurfaceColorConfiguration() + public let success = SurfaceColorConfiguration() + + override func getColor(_ viewModel: ModelType) -> UIColor { + //only show error is enabled and showError == true + let showErrorColor = !viewModel.disabled && viewModel.showError + let showSuccessColor = !viewModel.disabled && viewModel.showSuccess + + if showErrorColor { + return error.getColor(viewModel) + + } else if showSuccessColor { + return success.getColor(viewModel) + + } else { + return super.getColor(viewModel) + } + } + } } extension DefaultLabelModel { diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift index fb2255cc..f2065977 100644 --- a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift +++ b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift @@ -27,8 +27,10 @@ open class TextEntryFieldBase: EntryField viewModel.type.width { widthConstraint?.constant = width From 02a3bd9e78baf556d5c2c2991679d21ce61fb5ac Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 4 Oct 2022 15:08:03 -0500 Subject: [PATCH 07/23] refactored names of XXXLabelAttribute Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 60 ++++++++++--------- ...ction.swift => ActionLabelAttribute.swift} | 8 +-- ...ft => AttachmentLabelAttributeModel.swift} | 4 +- ...eColor.swift => ColorLabelAttribute.swift} | 4 +- ...uteFont.swift => FontLabelAttribute.swift} | 4 +- ...wift => StrikeThroughLabelAttribute.swift} | 4 +- .../SystemImageLabelAttribute.swift | 32 ++++++++++ .../Attributes/ToolTipLabelAttribute.swift | 39 ++++++++++++ ...ne.swift => UnderlineLabelAttribute.swift} | 4 +- VDS/Components/Label/Label.swift | 2 +- .../TextFields/EntryField/EntryField.swift | 52 +--------------- 11 files changed, 119 insertions(+), 94 deletions(-) rename VDS/Components/Label/Attributes/{LabelAttributeAction.swift => ActionLabelAttribute.swift} (82%) rename VDS/Components/Label/Attributes/{LabelAttributeAttachment.swift => AttachmentLabelAttributeModel.swift} (84%) rename VDS/Components/Label/Attributes/{LabelAttributeColor.swift => ColorLabelAttribute.swift} (89%) rename VDS/Components/Label/Attributes/{LabelAttributeFont.swift => FontLabelAttribute.swift} (91%) rename VDS/Components/Label/Attributes/{LabelAttributeStrikeThrough.swift => StrikeThroughLabelAttribute.swift} (84%) create mode 100644 VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift create mode 100644 VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift rename VDS/Components/Label/Attributes/{LabelAttributeUnderline.swift => UnderlineLabelAttribute.swift} (95%) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index edd1fe38..d97e55ac 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -63,6 +63,8 @@ EAA5EEAB28EB3ED9003B3210 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */; }; EAA5EEB128EB6A5A003B3210 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */; }; EAA5EEB328EB6A66003B3210 /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */; }; + EAA5EEB528ECBFB4003B3210 /* SystemImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* SystemImageLabelAttribute.swift */; }; + EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */; }; EAB1D29A28A5611D00DAE764 /* SelectorGroupModelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */; }; EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */; }; EAB1D29E28A5619500DAE764 /* RadioButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */; }; @@ -81,11 +83,11 @@ EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0A1289AFB3900B287F5 /* Errorable.swift */; }; EAF7F0A4289B017C00B287F5 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0A3289B017C00B287F5 /* LabelAttributeModel.swift */; }; EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0A5289B0CE000B287F5 /* Resetable.swift */; }; - EAF7F0AB289B13FD00B287F5 /* LabelAttributeFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AA289B13FD00B287F5 /* LabelAttributeFont.swift */; }; - EAF7F0AD289B142900B287F5 /* LabelAttributeStrikeThrough.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AC289B142900B287F5 /* LabelAttributeStrikeThrough.swift */; }; - EAF7F0AF289B144C00B287F5 /* LabelAttributeUnderline.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AE289B144C00B287F5 /* LabelAttributeUnderline.swift */; }; - EAF7F0B1289B177F00B287F5 /* LabelAttributeColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B0289B177F00B287F5 /* LabelAttributeColor.swift */; }; - EAF7F0B3289B1ADC00B287F5 /* LabelAttributeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */; }; + EAF7F0AB289B13FD00B287F5 /* FontLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AA289B13FD00B287F5 /* FontLabelAttribute.swift */; }; + EAF7F0AD289B142900B287F5 /* StrikeThroughLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */; }; + EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AE289B144C00B287F5 /* UnderlineLabelAttribute.swift */; }; + EAF7F0B1289B177F00B287F5 /* ColorLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */; }; + EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B2289B1ADC00B287F5 /* ActionLabelAttribute.swift */; }; EAF7F0B5289C126F00B287F5 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B4289C126F00B287F5 /* UILabel.swift */; }; EAF7F0B7289C12A600B287F5 /* UITapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */; }; EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B8289C139800B287F5 /* ColorConfiguration.swift */; }; @@ -95,7 +97,7 @@ EAF7F0FB289DB1AC00B287F5 /* VDSColorTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAF7F0E9289DB0DA00B287F5 /* VDSColorTokens.xcframework */; }; EAF7F11728A1475A00B287F5 /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F11528A1475A00B287F5 /* RadioButton.swift */; }; EAF7F11828A1475A00B287F5 /* RadioButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F11628A1475A00B287F5 /* RadioButtonModel.swift */; }; - EAF7F13328A2A16500B287F5 /* LabelAttributeAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */; }; + EAF7F13328A2A16500B287F5 /* AttachmentLabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F13228A2A16500B287F5 /* AttachmentLabelAttributeModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -169,6 +171,8 @@ EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = ""; }; EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = ""; }; EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; + EAA5EEB428ECBFB4003B3210 /* SystemImageLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemImageLabelAttribute.swift; sourceTree = ""; }; + EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolTipLabelAttribute.swift; sourceTree = ""; }; EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupModelable.swift; sourceTree = ""; }; EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = ""; }; EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroupModel.swift; sourceTree = ""; }; @@ -187,11 +191,11 @@ EAF7F0A1289AFB3900B287F5 /* Errorable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errorable.swift; sourceTree = ""; }; EAF7F0A3289B017C00B287F5 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = ""; }; EAF7F0A5289B0CE000B287F5 /* Resetable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Resetable.swift; sourceTree = ""; }; - EAF7F0AA289B13FD00B287F5 /* LabelAttributeFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeFont.swift; sourceTree = ""; }; - EAF7F0AC289B142900B287F5 /* LabelAttributeStrikeThrough.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeStrikeThrough.swift; sourceTree = ""; }; - EAF7F0AE289B144C00B287F5 /* LabelAttributeUnderline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeUnderline.swift; sourceTree = ""; }; - EAF7F0B0289B177F00B287F5 /* LabelAttributeColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeColor.swift; sourceTree = ""; }; - EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeAction.swift; sourceTree = ""; }; + EAF7F0AA289B13FD00B287F5 /* FontLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontLabelAttribute.swift; sourceTree = ""; }; + EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrikeThroughLabelAttribute.swift; sourceTree = ""; }; + EAF7F0AE289B144C00B287F5 /* UnderlineLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderlineLabelAttribute.swift; sourceTree = ""; }; + EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorLabelAttribute.swift; sourceTree = ""; }; + EAF7F0B2289B1ADC00B287F5 /* ActionLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionLabelAttribute.swift; sourceTree = ""; }; EAF7F0B4289C126F00B287F5 /* UILabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = ""; }; EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITapGestureRecognizer.swift; sourceTree = ""; }; EAF7F0B8289C139800B287F5 /* ColorConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorConfiguration.swift; sourceTree = ""; }; @@ -202,7 +206,7 @@ EAF7F0EB289DB0DA00B287F5 /* VDSLayoutTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSLayoutTokens.xcframework; path = ../SharedFrameworks/VDSLayoutTokens.xcframework; sourceTree = ""; }; EAF7F11528A1475A00B287F5 /* RadioButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = ""; }; EAF7F11628A1475A00B287F5 /* RadioButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = ""; }; - EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeAttachment.swift; sourceTree = ""; }; + EAF7F13228A2A16500B287F5 /* AttachmentLabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentLabelAttributeModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -522,12 +526,14 @@ isa = PBXGroup; children = ( EAF7F0A3289B017C00B287F5 /* LabelAttributeModel.swift */, - EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */, - EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */, - EAF7F0B0289B177F00B287F5 /* LabelAttributeColor.swift */, - EAF7F0AA289B13FD00B287F5 /* LabelAttributeFont.swift */, - EAF7F0AC289B142900B287F5 /* LabelAttributeStrikeThrough.swift */, - EAF7F0AE289B144C00B287F5 /* LabelAttributeUnderline.swift */, + EAF7F0B2289B1ADC00B287F5 /* ActionLabelAttribute.swift */, + EAF7F13228A2A16500B287F5 /* AttachmentLabelAttributeModel.swift */, + EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */, + EAF7F0AA289B13FD00B287F5 /* FontLabelAttribute.swift */, + EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */, + EAA5EEB428ECBFB4003B3210 /* SystemImageLabelAttribute.swift */, + EAF7F0AE289B144C00B287F5 /* UnderlineLabelAttribute.swift */, + EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */, ); path = Attributes; sourceTree = ""; @@ -668,10 +674,11 @@ EA89201328B568D8006B9984 /* RadioBox.swift in Sources */, EA84F6B128B94A2500D67ABC /* CodableColor.swift in Sources */, EA3362402892EF6C0071C351 /* Label.swift in Sources */, - EAF7F0B3289B1ADC00B287F5 /* LabelAttributeAction.swift in Sources */, + EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */, EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */, EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */, - EAF7F0AF289B144C00B287F5 /* LabelAttributeUnderline.swift in Sources */, + EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */, + EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */, EA3361C5289030FC0071C351 /* Accessable.swift in Sources */, EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */, EAA5EEAB28EB3ED9003B3210 /* EntryFieldModel.swift in Sources */, @@ -688,9 +695,9 @@ EA3362432892EFF20071C351 /* LabelModel.swift in Sources */, EA33624728931B050071C351 /* Initable.swift in Sources */, EAF7F0A4289B017C00B287F5 /* LabelAttributeModel.swift in Sources */, - EAF7F0B1289B177F00B287F5 /* LabelAttributeColor.swift in Sources */, + EAF7F0B1289B177F00B287F5 /* ColorLabelAttribute.swift in Sources */, EAB1D2EA28AE84AA00DAE764 /* UIControlPublisher.swift in Sources */, - EAF7F13328A2A16500B287F5 /* LabelAttributeAttachment.swift in Sources */, + EAF7F13328A2A16500B287F5 /* AttachmentLabelAttributeModel.swift in Sources */, EA89200628B526D6006B9984 /* CheckboxGroup.swift in Sources */, EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */, EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */, @@ -712,9 +719,10 @@ EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */, EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */, EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */, - EAF7F0AB289B13FD00B287F5 /* LabelAttributeFont.swift in Sources */, + EAF7F0AB289B13FD00B287F5 /* FontLabelAttribute.swift in Sources */, EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */, EA336171288B19200071C351 /* VDS.docc in Sources */, + EAA5EEB528ECBFB4003B3210 /* SystemImageLabelAttribute.swift in Sources */, EAF7F0962899861000B287F5 /* CheckboxModel.swift in Sources */, EAB1D2E628AE842000DAE764 /* Publisher+Bind.swift in Sources */, EA3361AA288B25E40071C351 /* Disabling.swift in Sources */, @@ -728,7 +736,7 @@ EA33623E2892EE950071C351 /* UIDevice.swift in Sources */, EA3362302891EB4A0071C351 /* Fonts.swift in Sources */, EA1F265E28B944F00033E859 /* CollectionViewCell.swift in Sources */, - EAF7F0AD289B142900B287F5 /* LabelAttributeStrikeThrough.swift in Sources */, + EAF7F0AD289B142900B287F5 /* StrikeThroughLabelAttribute.swift in Sources */, EA3361B8288B2AAA0071C351 /* ViewProtocol.swift in Sources */, EA3361BF288B2EA60071C351 /* ModelHandlerable.swift in Sources */, EA3361A8288B23300071C351 /* UIColor.swift in Sources */, @@ -880,7 +888,6 @@ EA336181288B19210071C351 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BITCODE_GENERATION_MODE = bitcode; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -888,7 +895,6 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_BITCODE = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -913,7 +919,6 @@ EA336182288B19210071C351 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BITCODE_GENERATION_MODE = bitcode; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -921,7 +926,6 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_BITCODE = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/VDS/Components/Label/Attributes/LabelAttributeAction.swift b/VDS/Components/Label/Attributes/ActionLabelAttribute.swift similarity index 82% rename from VDS/Components/Label/Attributes/LabelAttributeAction.swift rename to VDS/Components/Label/Attributes/ActionLabelAttribute.swift index 7e280a42..fe3b2012 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeAction.swift +++ b/VDS/Components/Label/Attributes/ActionLabelAttribute.swift @@ -9,18 +9,18 @@ import Foundation import UIKit import Combine -public protocol LabelAttributeActionable: LabelAttributeModel { +public protocol ActionLabelAttributeModel: LabelAttributeModel { var accessibleText: String? { get set } var action: PassthroughSubject { get set } } -public struct LabelAttributeActionModel: LabelAttributeActionable { +public struct ActionLabelAttribute: ActionLabelAttributeModel { - public static func == (lhs: LabelAttributeActionModel, rhs: LabelAttributeActionModel) -> Bool { + public static func == (lhs: ActionLabelAttribute, rhs: ActionLabelAttribute) -> Bool { lhs.isEqual(rhs) } - public func isEqual(_ equatable: LabelAttributeActionModel) -> Bool { + public func isEqual(_ equatable: ActionLabelAttribute) -> Bool { return id == equatable.id && range == equatable.range } diff --git a/VDS/Components/Label/Attributes/LabelAttributeAttachment.swift b/VDS/Components/Label/Attributes/AttachmentLabelAttributeModel.swift similarity index 84% rename from VDS/Components/Label/Attributes/LabelAttributeAttachment.swift rename to VDS/Components/Label/Attributes/AttachmentLabelAttributeModel.swift index 35008d14..5de6f4b2 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeAttachment.swift +++ b/VDS/Components/Label/Attributes/AttachmentLabelAttributeModel.swift @@ -8,11 +8,11 @@ import Foundation import UIKit -public protocol LabelAttributeAttachment: LabelAttributeModel { +public protocol AttachmentLabelAttributeModel: LabelAttributeModel { func getAttachment() throws -> NSTextAttachment } -extension LabelAttributeAttachment { +extension AttachmentLabelAttributeModel { public func setAttribute(on attributedString: NSMutableAttributedString) { do { let mutableString = NSMutableAttributedString() diff --git a/VDS/Components/Label/Attributes/LabelAttributeColor.swift b/VDS/Components/Label/Attributes/ColorLabelAttribute.swift similarity index 89% rename from VDS/Components/Label/Attributes/LabelAttributeColor.swift rename to VDS/Components/Label/Attributes/ColorLabelAttribute.swift index 6d3f35aa..8d70296d 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeColor.swift +++ b/VDS/Components/Label/Attributes/ColorLabelAttribute.swift @@ -8,8 +8,8 @@ import Foundation import UIKit -public struct LabelAttributeColor: LabelAttributeModel { - public func isEqual(_ equatable: LabelAttributeColor) -> Bool { +public struct ColorLabelAttribute: LabelAttributeModel { + public func isEqual(_ equatable: ColorLabelAttribute) -> Bool { return id == equatable.id && range == equatable.range && color == equatable.color } //-------------------------------------------------- diff --git a/VDS/Components/Label/Attributes/LabelAttributeFont.swift b/VDS/Components/Label/Attributes/FontLabelAttribute.swift similarity index 91% rename from VDS/Components/Label/Attributes/LabelAttributeFont.swift rename to VDS/Components/Label/Attributes/FontLabelAttribute.swift index af559184..6456b76c 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeFont.swift +++ b/VDS/Components/Label/Attributes/FontLabelAttribute.swift @@ -8,8 +8,8 @@ import Foundation import UIKit -public struct LabelAttributeFont: LabelAttributeModel { - public func isEqual(_ equatable: LabelAttributeFont) -> Bool { +public struct FontLabelAttribute: LabelAttributeModel { + public func isEqual(_ equatable: FontLabelAttribute) -> Bool { return id == equatable.id && range == equatable.range && color == equatable.color diff --git a/VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift b/VDS/Components/Label/Attributes/StrikeThroughLabelAttribute.swift similarity index 84% rename from VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift rename to VDS/Components/Label/Attributes/StrikeThroughLabelAttribute.swift index 6b62691c..93650f2b 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeStrikeThrough.swift +++ b/VDS/Components/Label/Attributes/StrikeThroughLabelAttribute.swift @@ -8,8 +8,8 @@ import Foundation import UIKit -public struct LabelAttributeStrikeThrough: LabelAttributeModel { - public func isEqual(_ equatable: LabelAttributeStrikeThrough) -> Bool { +public struct StrikeThroughLabelAttribute: LabelAttributeModel { + public func isEqual(_ equatable: StrikeThroughLabelAttribute) -> Bool { return id == equatable.id && range == equatable.range } diff --git a/VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift b/VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift new file mode 100644 index 00000000..6f3bf3a2 --- /dev/null +++ b/VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift @@ -0,0 +1,32 @@ +// +// LabelSystemImageLabelAttribute.swift +// VDS +// +// Created by Matt Bruce on 10/4/22. +// + +import Foundation +import UIKit + +public struct SystemImageLabelAttribute: AttachmentLabelAttributeModel { + public var id = UUID() + public var location: Int + public var length: Int + public var imageName: String + public var frame: CGRect + public var tintColor: UIColor + public static func == (lhs: SystemImageLabelAttribute, rhs: SystemImageLabelAttribute) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: SystemImageLabelAttribute) -> Bool { + return id == equatable.id && range == equatable.range && imageName == equatable.imageName + } + + public func getAttachment() throws -> NSTextAttachment { + let attachment = NSTextAttachment() + attachment.image = UIImage(systemName: imageName)?.withTintColor(tintColor) + attachment.bounds = frame + return attachment + } +} diff --git a/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift b/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift new file mode 100644 index 00000000..8bb16199 --- /dev/null +++ b/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift @@ -0,0 +1,39 @@ +// +// ToolTipLabelAttribute.swift +// VDS +// +// Created by Matt Bruce on 10/4/22. +// + +import Foundation +import UIKit +import Combine + +public struct ToolTipLabelAttribute: ActionLabelAttributeModel { + public var id = UUID() + public var accessibleText: String? = "Tool Tip" + public var action = PassthroughSubject() + public var location: Int + public var length: Int + public var tintColor: UIColor + + public func setAttribute(on attributedString: NSMutableAttributedString) { + let image = SystemImageLabelAttribute(location: location, + length: length, + imageName: "info.circle", + frame: .init(x: 0, y: -2, width: 13.3, height: 13.3), + tintColor: tintColor) + + image.setAttribute(on: attributedString) + + } + + public static func == (lhs: ToolTipLabelAttribute, rhs: ToolTipLabelAttribute) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: ToolTipLabelAttribute) -> Bool { + return id == equatable.id && range == equatable.range + } +} + diff --git a/VDS/Components/Label/Attributes/LabelAttributeUnderline.swift b/VDS/Components/Label/Attributes/UnderlineLabelAttribute.swift similarity index 95% rename from VDS/Components/Label/Attributes/LabelAttributeUnderline.swift rename to VDS/Components/Label/Attributes/UnderlineLabelAttribute.swift index d7c302cc..98ed45a2 100644 --- a/VDS/Components/Label/Attributes/LabelAttributeUnderline.swift +++ b/VDS/Components/Label/Attributes/UnderlineLabelAttribute.swift @@ -8,9 +8,9 @@ import Foundation import UIKit -public struct LabelAttributeUnderline: LabelAttributeModel { +public struct UnderlineLabelAttribute: LabelAttributeModel { - public func isEqual(_ equatable: LabelAttributeUnderline) -> Bool { + public func isEqual(_ equatable: UnderlineLabelAttribute) -> Bool { return id == equatable.id && range == equatable.range && color == equatable.color diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 8dae7755..9ebfc020 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -159,7 +159,7 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt attribute.setAttribute(on: mutableText) //see if the attribute is Actionable - if let actionable = attribute as? any LabelAttributeActionable{ + if let actionable = attribute as? any ActionLabelAttributeModel{ //create a accessibleAction let customAccessibilityAction = customAccessibilityAction(range: actionable.range, accessibleText: actionable.accessibleText) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index e8643ecb..bae1fc76 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -293,7 +293,7 @@ open class EntryField: Control { extension DefaultLabelModel { public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { guard let text = text, !required else { return self} - let optionColorAttr = LabelAttributeColor(location: text.count + 2, + let optionColorAttr = ColorLabelAttribute(location: text.count + 2, length: 8, color: colorConfiguration.getColor(self)) @@ -319,53 +319,3 @@ extension DefaultLabelModel { } } } - -public struct LabelSystemImageAttachement: LabelAttributeAttachment { - public var id = UUID() - public var location: Int - public var length: Int - public var imageName: String - public var frame: CGRect - public var tintColor: UIColor - public static func == (lhs: LabelSystemImageAttachement, rhs: LabelSystemImageAttachement) -> Bool { - lhs.isEqual(rhs) - } - - public func isEqual(_ equatable: LabelSystemImageAttachement) -> Bool { - return id == equatable.id && range == equatable.range && imageName == equatable.imageName - } - - public func getAttachment() throws -> NSTextAttachment { - let attachment = NSTextAttachment() - attachment.image = UIImage(systemName: imageName)?.withTintColor(tintColor) - attachment.bounds = frame - return attachment - } -} - -public struct ToolTipLabelAttribute: LabelAttributeActionable { - public var id = UUID() - public var accessibleText: String? = "Tool Tip" - public var action = PassthroughSubject() - public var location: Int - public var length: Int - public var tintColor: UIColor - public func setAttribute(on attributedString: NSMutableAttributedString) { - let image = LabelSystemImageAttachement(location: location, - length: length, - imageName: "info.circle", - frame: .init(x: 0, y: -2, width: 13.3, height: 13.3), - tintColor: tintColor) - - image.setAttribute(on: attributedString) - - } - - public static func == (lhs: ToolTipLabelAttribute, rhs: ToolTipLabelAttribute) -> Bool { - lhs.isEqual(rhs) - } - - public func isEqual(_ equatable: ToolTipLabelAttribute) -> Bool { - return id == equatable.id && range == equatable.range - } -} From 26da08ba48bf7df17cd0ded6ce2747e29ec85703 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 7 Oct 2022 09:13:20 -0500 Subject: [PATCH 08/23] images Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 12 +- .../Attributes/ImageLabelAttribute.swift | 44 ++++ .../SystemImageLabelAttribute.swift | 32 --- .../Icons.xcassets/Contents.json | 6 + .../Icons.xcassets/CreditCard/Contents.json | 6 + .../CreditCard/amex.imageset/Contents.json | 12 ++ .../CreditCard/amex.imageset/amex.svg | 8 + .../credit-card.imageset/Contents.json | 12 ++ .../credit-card.imageset/credit-card.svg | 1 + .../Contents.json | 12 ++ .../dinersClub-inverted.svg | 196 ++++++++++++++++++ .../dinersClub.imageset/Contents.json | 12 ++ .../dinersClub.imageset/dinersClub.svg | 196 ++++++++++++++++++ .../discover.imageset/Contents.json | 12 ++ .../CreditCard/discover.imageset/discover.svg | 49 +++++ .../generic-inverted.imageset/Contents.json | 12 ++ .../generic-inverted.svg | 10 + .../CreditCard/generic.imageset/Contents.json | 12 ++ .../CreditCard/generic.imageset/generic.svg | 17 ++ .../CreditCard/jcb.imageset/Contents.json | 12 ++ .../CreditCard/jcb.imageset/jcb.svg | 51 +++++ .../mastercard.imageset/Contents.json | 12 ++ .../mastercard.imageset/mastercard.svg | 12 ++ .../Contents.json | 12 ++ .../placeholder-inverted.svg | 7 + .../placeholder.imageset/Contents.json | 12 ++ .../placeholder.imageset/placeholder.svg | 18 ++ .../Contents.json | 12 ++ .../securityCode-inverted.svg | 29 +++ .../securityCode.imageset/Contents.json | 12 ++ .../securityCode.imageset/securityCode.svg | 37 ++++ .../Contents.json | 12 ++ .../securityCodeAmex-inverted.svg | 34 +++ .../securityCodeAmex.imageset/Contents.json | 12 ++ .../securityCodeAmex.svg | 38 ++++ .../visa-inverted.imageset/Contents.json | 12 ++ .../visa-inverted.imageset/visa-inverted.svg | 10 + .../CreditCard/visa.imageset/Contents.json | 12 ++ .../CreditCard/visa.imageset/visa.svg | 7 + .../checkmark-alt.imageset/Contents.json | 12 ++ .../checkmark-alt.imageset/checkmark-alt.svg | 1 + .../error.imageset/Contents.json | 12 ++ .../Icons.xcassets/error.imageset/error.svg | 1 + .../info.imageset/Contents.json | 12 ++ .../Icons.xcassets/info.imageset/info.svg | 1 + 45 files changed, 1027 insertions(+), 36 deletions(-) create mode 100644 VDS/Components/Label/Attributes/ImageLabelAttribute.swift delete mode 100644 VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift create mode 100644 VDS/SupportingFiles/Icons.xcassets/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/amex.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/credit-card.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/dinersClub-inverted.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/dinersClub.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/generic-inverted.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/generic.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/mastercard.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/placeholder-inverted.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/placeholder.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/securityCode-inverted.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/securityCode.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/securityCodeAmex-inverted.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/securityCodeAmex.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/visa-inverted.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/visa.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/checkmark-alt.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/error.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/error.imageset/error.svg create mode 100644 VDS/SupportingFiles/Icons.xcassets/info.imageset/Contents.json create mode 100644 VDS/SupportingFiles/Icons.xcassets/info.imageset/info.svg diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index d97e55ac..59d6d763 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -63,8 +63,9 @@ EAA5EEAB28EB3ED9003B3210 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */; }; EAA5EEB128EB6A5A003B3210 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */; }; EAA5EEB328EB6A66003B3210 /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */; }; - EAA5EEB528ECBFB4003B3210 /* SystemImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* SystemImageLabelAttribute.swift */; }; + EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */; }; EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */; }; + EAA5EEB928ECD24B003B3210 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EAA5EEB828ECD24B003B3210 /* Icons.xcassets */; }; EAB1D29A28A5611D00DAE764 /* SelectorGroupModelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */; }; EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */; }; EAB1D29E28A5619500DAE764 /* RadioButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */; }; @@ -171,8 +172,9 @@ EAA5EEAA28EB3ED9003B3210 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = ""; }; EAA5EEB028EB6A5A003B3210 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = ""; }; EAA5EEB228EB6A66003B3210 /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; - EAA5EEB428ECBFB4003B3210 /* SystemImageLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemImageLabelAttribute.swift; sourceTree = ""; }; + EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLabelAttribute.swift; sourceTree = ""; }; EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolTipLabelAttribute.swift; sourceTree = ""; }; + EAA5EEB828ECD24B003B3210 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = ""; }; EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupModelable.swift; sourceTree = ""; }; EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = ""; }; EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroupModel.swift; sourceTree = ""; }; @@ -408,6 +410,7 @@ isa = PBXGroup; children = ( EA3361FF2891E14C0071C351 /* Fonts */, + EAA5EEB828ECD24B003B3210 /* Icons.xcassets */, ); path = SupportingFiles; sourceTree = ""; @@ -531,7 +534,7 @@ EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */, EAF7F0AA289B13FD00B287F5 /* FontLabelAttribute.swift */, EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */, - EAA5EEB428ECBFB4003B3210 /* SystemImageLabelAttribute.swift */, + EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */, EAF7F0AE289B144C00B287F5 /* UnderlineLabelAttribute.swift */, EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */, ); @@ -645,6 +648,7 @@ EA3362072891E14D0071C351 /* VerizonNHGeDS-Regular.otf in Resources */, EA3362062891E14D0071C351 /* VerizonNHGeTX-Regular.otf in Resources */, EA3362052891E14D0071C351 /* VerizonNHGeDS-Bold.otf in Resources */, + EAA5EEB928ECD24B003B3210 /* Icons.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -722,7 +726,7 @@ EAF7F0AB289B13FD00B287F5 /* FontLabelAttribute.swift in Sources */, EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */, EA336171288B19200071C351 /* VDS.docc in Sources */, - EAA5EEB528ECBFB4003B3210 /* SystemImageLabelAttribute.swift in Sources */, + EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */, EAF7F0962899861000B287F5 /* CheckboxModel.swift in Sources */, EAB1D2E628AE842000DAE764 /* Publisher+Bind.swift in Sources */, EA3361AA288B25E40071C351 /* Disabling.swift in Sources */, diff --git a/VDS/Components/Label/Attributes/ImageLabelAttribute.swift b/VDS/Components/Label/Attributes/ImageLabelAttribute.swift new file mode 100644 index 00000000..9bba6287 --- /dev/null +++ b/VDS/Components/Label/Attributes/ImageLabelAttribute.swift @@ -0,0 +1,44 @@ +// +// LabelSystemImageLabelAttribute.swift +// VDS +// +// Created by Matt Bruce on 10/4/22. +// + +import Foundation +import UIKit + +public struct ImageLabelAttribute: AttachmentLabelAttributeModel { + public enum Error: Swift.Error { + case bundleNotFound + case imageNotFound(String) + } + public var id = UUID() + public var location: Int + public var length: Int + public var imageName: String + public var frame: CGRect + public var tintColor: UIColor + public static func == (lhs: ImageLabelAttribute, rhs: ImageLabelAttribute) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: ImageLabelAttribute) -> Bool { + return id == equatable.id && range == equatable.range && imageName == equatable.imageName + } + + public func getAttachment() throws -> NSTextAttachment { + guard let bundle = Bundle(identifier: "com.vzw.vds") else { + throw Error.bundleNotFound + } + + guard let image = UIImage(named: imageName, in: bundle, with: nil) else { + throw Error.imageNotFound(imageName) + } + + let attachment = NSTextAttachment() + attachment.image = image.withTintColor(tintColor) + attachment.bounds = frame + return attachment + } +} diff --git a/VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift b/VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift deleted file mode 100644 index 6f3bf3a2..00000000 --- a/VDS/Components/Label/Attributes/SystemImageLabelAttribute.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// LabelSystemImageLabelAttribute.swift -// VDS -// -// Created by Matt Bruce on 10/4/22. -// - -import Foundation -import UIKit - -public struct SystemImageLabelAttribute: AttachmentLabelAttributeModel { - public var id = UUID() - public var location: Int - public var length: Int - public var imageName: String - public var frame: CGRect - public var tintColor: UIColor - public static func == (lhs: SystemImageLabelAttribute, rhs: SystemImageLabelAttribute) -> Bool { - lhs.isEqual(rhs) - } - - public func isEqual(_ equatable: SystemImageLabelAttribute) -> Bool { - return id == equatable.id && range == equatable.range && imageName == equatable.imageName - } - - public func getAttachment() throws -> NSTextAttachment { - let attachment = NSTextAttachment() - attachment.image = UIImage(systemName: imageName)?.withTintColor(tintColor) - attachment.bounds = frame - return attachment - } -} diff --git a/VDS/SupportingFiles/Icons.xcassets/Contents.json b/VDS/SupportingFiles/Icons.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/Contents.json new file mode 100644 index 00000000..610ffbd7 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "amex.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/amex.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/amex.svg new file mode 100644 index 00000000..de85ed53 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/amex.imageset/amex.svg @@ -0,0 +1,8 @@ + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/Contents.json new file mode 100644 index 00000000..df2d7bca --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "credit-card.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/credit-card.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/credit-card.svg new file mode 100644 index 00000000..a5975ebf --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/credit-card.imageset/credit-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/Contents.json new file mode 100644 index 00000000..b4949ace --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "dinersClub-inverted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/dinersClub-inverted.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/dinersClub-inverted.svg new file mode 100644 index 00000000..1c8b4ccc --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub-inverted.imageset/dinersClub-inverted.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/Contents.json new file mode 100644 index 00000000..6a22c2dd --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "dinersClub.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/dinersClub.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/dinersClub.svg new file mode 100644 index 00000000..083ed5af --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/dinersClub.imageset/dinersClub.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json new file mode 100644 index 00000000..ae99049b --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "discover.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg new file mode 100644 index 00000000..a056ab58 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/Contents.json new file mode 100644 index 00000000..49581273 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "generic-inverted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/generic-inverted.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/generic-inverted.svg new file mode 100644 index 00000000..42904015 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic-inverted.imageset/generic-inverted.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/Contents.json new file mode 100644 index 00000000..b0026068 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "generic.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/generic.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/generic.svg new file mode 100644 index 00000000..38b925ee --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/generic.imageset/generic.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json new file mode 100644 index 00000000..5798433a --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "jcb.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg new file mode 100644 index 00000000..ab197f4b --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/Contents.json new file mode 100644 index 00000000..3ee10a5c --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "mastercard.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/mastercard.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/mastercard.svg new file mode 100644 index 00000000..dc3082aa --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/mastercard.imageset/mastercard.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/Contents.json new file mode 100644 index 00000000..caf02da3 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "placeholder-inverted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/placeholder-inverted.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/placeholder-inverted.svg new file mode 100644 index 00000000..06f4891e --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder-inverted.imageset/placeholder-inverted.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/Contents.json new file mode 100644 index 00000000..d039c34d --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "placeholder.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/placeholder.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/placeholder.svg new file mode 100644 index 00000000..842da557 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/placeholder.imageset/placeholder.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/Contents.json new file mode 100644 index 00000000..2c8a3508 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "securityCode-inverted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/securityCode-inverted.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/securityCode-inverted.svg new file mode 100644 index 00000000..75f8a3f9 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode-inverted.imageset/securityCode-inverted.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/Contents.json new file mode 100644 index 00000000..21980ced --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "securityCode.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/securityCode.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/securityCode.svg new file mode 100644 index 00000000..f1c6353e --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCode.imageset/securityCode.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/Contents.json new file mode 100644 index 00000000..4bc9d730 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "securityCodeAmex-inverted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/securityCodeAmex-inverted.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/securityCodeAmex-inverted.svg new file mode 100644 index 00000000..7d8b5a6a --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex-inverted.imageset/securityCodeAmex-inverted.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/Contents.json new file mode 100644 index 00000000..c4dc8123 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "securityCodeAmex.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/securityCodeAmex.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/securityCodeAmex.svg new file mode 100644 index 00000000..226b265d --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/securityCodeAmex.imageset/securityCodeAmex.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/Contents.json new file mode 100644 index 00000000..f1e909a2 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "visa-inverted.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/visa-inverted.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/visa-inverted.svg new file mode 100644 index 00000000..7277b618 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa-inverted.imageset/visa-inverted.svg @@ -0,0 +1,10 @@ + + + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/Contents.json new file mode 100644 index 00000000..680fa238 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "visa.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/visa.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/visa.svg new file mode 100644 index 00000000..26ee8433 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/visa.imageset/visa.svg @@ -0,0 +1,7 @@ + + + diff --git a/VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/Contents.json new file mode 100644 index 00000000..50ccb6e9 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "checkmark-alt.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/checkmark-alt.svg b/VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/checkmark-alt.svg new file mode 100644 index 00000000..0fc5f61c --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/checkmark-alt.imageset/checkmark-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/VDS/SupportingFiles/Icons.xcassets/error.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/error.imageset/Contents.json new file mode 100644 index 00000000..a2f87247 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/error.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "error.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/error.imageset/error.svg b/VDS/SupportingFiles/Icons.xcassets/error.imageset/error.svg new file mode 100644 index 00000000..eb392746 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/error.imageset/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/VDS/SupportingFiles/Icons.xcassets/info.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/info.imageset/Contents.json new file mode 100644 index 00000000..adcd08a2 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/info.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "info.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/info.imageset/info.svg b/VDS/SupportingFiles/Icons.xcassets/info.imageset/info.svg new file mode 100644 index 00000000..5fe83ac9 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/info.imageset/info.svg @@ -0,0 +1 @@ + \ No newline at end of file From 3ae6167f18fc0d0d9dbffcdbcb94612bae473c51 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 7 Oct 2022 09:14:02 -0500 Subject: [PATCH 09/23] tooltipo update Signed-off-by: Matt Bruce --- VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift b/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift index 8bb16199..39e6277c 100644 --- a/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift +++ b/VDS/Components/Label/Attributes/ToolTipLabelAttribute.swift @@ -18,9 +18,9 @@ public struct ToolTipLabelAttribute: ActionLabelAttributeModel { public var tintColor: UIColor public func setAttribute(on attributedString: NSMutableAttributedString) { - let image = SystemImageLabelAttribute(location: location, + let image = ImageLabelAttribute(location: location, length: length, - imageName: "info.circle", + imageName: "info", frame: .init(x: 0, y: -2, width: 13.3, height: 13.3), tintColor: tintColor) From c29cd4a7a5afcb83b9bdbd4006386de3c3e8b14f Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 7 Oct 2022 09:15:05 -0500 Subject: [PATCH 10/23] accessable update Signed-off-by: Matt Bruce --- VDS/Components/Badge/Badge.swift | 2 +- VDS/Components/Checkbox/Checkbox.swift | 2 +- VDS/Components/RadioBox/RadioBox.swift | 2 +- VDS/Components/RadioButton/RadioButton.swift | 2 +- VDS/Components/RadioSwatch/RadioSwatch.swift | 2 +- VDS/Components/Toggle/Toggle.swift | 2 +- VDS/Protocols/Accessable.swift | 21 +++++++++++--------- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index 1f3fe2b2..69d41b6a 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -178,7 +178,7 @@ open class BadgeBase: View { maxWidthConstraint?.isActive = false } label.set(with: viewModel.label) - setAccessibilityLabel(!viewModel.disabled) + setAccessibilityLabel() } } diff --git a/VDS/Components/Checkbox/Checkbox.swift b/VDS/Components/Checkbox/Checkbox.swift index 46e6d034..caf2dd8a 100644 --- a/VDS/Components/Checkbox/Checkbox.swift +++ b/VDS/Components/Checkbox/Checkbox.swift @@ -234,7 +234,7 @@ open class CheckboxBase: Control { updateLabels(viewModel) updateSelector(viewModel) - setAccessibilityHint(enabled) + setAccessibilityHint() setAccessibilityValue(viewModel.selected) setAccessibilityLabel(viewModel.selected) setNeedsLayout() diff --git a/VDS/Components/RadioBox/RadioBox.swift b/VDS/Components/RadioBox/RadioBox.swift index 6b860403..4d71159d 100644 --- a/VDS/Components/RadioBox/RadioBox.swift +++ b/VDS/Components/RadioBox/RadioBox.swift @@ -211,7 +211,7 @@ open class RadioBoxBase: Control { updateLabels(viewModel) updateSelector(viewModel) - setAccessibilityHint(enabled) + setAccessibilityHint() setAccessibilityValue(viewModel.selected) setAccessibilityLabel(viewModel.selected) setNeedsLayout() diff --git a/VDS/Components/RadioButton/RadioButton.swift b/VDS/Components/RadioButton/RadioButton.swift index be4a6967..cb2081c9 100644 --- a/VDS/Components/RadioButton/RadioButton.swift +++ b/VDS/Components/RadioButton/RadioButton.swift @@ -244,7 +244,7 @@ open class RadioButtonBase: Control { updateLabels(viewModel) updateSelector(viewModel) - setAccessibilityHint(enabled) + setAccessibilityHint() setAccessibilityValue(viewModel.selected) setAccessibilityLabel(viewModel.selected) setNeedsLayout() diff --git a/VDS/Components/RadioSwatch/RadioSwatch.swift b/VDS/Components/RadioSwatch/RadioSwatch.swift index 235b28bd..1d0e4164 100644 --- a/VDS/Components/RadioSwatch/RadioSwatch.swift +++ b/VDS/Components/RadioSwatch/RadioSwatch.swift @@ -144,7 +144,7 @@ open class RadioSwatchBase: Control { let enabled = !viewModel.disabled updateSelector(viewModel) - setAccessibilityHint(enabled) + setAccessibilityHint() setAccessibilityValue(viewModel.selected) setAccessibilityLabel(viewModel.selected) setNeedsLayout() diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index b66d4eef..27d19634 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -333,7 +333,7 @@ open class ToggleBase: Control { label.set(with: viewModel.label) updateLabel(viewModel) updateToggle(viewModel) - setAccessibilityHint(!viewModel.disabled) + setAccessibilityHint() setAccessibilityValue(viewModel.on) setAccessibilityLabel(viewModel.on) backgroundColor = viewModel.surface.color diff --git a/VDS/Protocols/Accessable.swift b/VDS/Protocols/Accessable.swift index 35afd6e6..fd9ad370 100644 --- a/VDS/Protocols/Accessable.swift +++ b/VDS/Protocols/Accessable.swift @@ -26,26 +26,29 @@ extension ModelHandlerable where Self: UIView { return model } - public func setAccessibilityHint(_ enabled: Bool = true) { - if let value = accessableModel?.accessibilityHintEnabled, enabled { + public func setAccessibilityHint(_ override: Bool? = nil) { + let check = override ?? !model.disabled + if let value = accessableModel?.accessibilityHintEnabled, check { accessibilityHint = value - } else if let value = accessableModel?.accessibilityHintDisabled, !enabled { + } else if let value = accessableModel?.accessibilityHintDisabled, !check { accessibilityHint = value } } - public func setAccessibilityValue(_ enabled: Bool = true) { - if let value = accessableModel?.accessibilityValueEnabled, enabled { + public func setAccessibilityValue(_ override: Bool? = nil) { + let check = override ?? !model.disabled + if let value = accessableModel?.accessibilityValueEnabled, check { accessibilityValue = value - } else if let value = accessableModel?.accessibilityValueDisabled, !enabled { + } else if let value = accessableModel?.accessibilityValueDisabled, !check { accessibilityValue = value } } - public func setAccessibilityLabel(_ enabled: Bool = true) { - if let value = accessableModel?.accessibilityLabelEnabled, enabled { + public func setAccessibilityLabel(_ override: Bool? = nil) { + let check = override ?? !model.disabled + if let value = accessableModel?.accessibilityLabelEnabled, check { accessibilityLabel = value - } else if let value = accessableModel?.accessibilityLabelDisabled, !enabled { + } else if let value = accessableModel?.accessibilityLabelDisabled, !check { accessibilityLabel = value } } From d7f243a09e5f001edb01b6a216385b26844f2e56 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 10:22:37 -0500 Subject: [PATCH 11/23] added AnyColorConfiguration Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index 8633185e..831d9704 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -public protocol Colorable: AnyObject, ObjectWithable, Initable { +public protocol Colorable: AnyObject, ObjectWithable { associatedtype ModelType func getColor(_ viewModel: ModelType) -> UIColor } @@ -33,7 +33,7 @@ extension BinaryColorable where Self: Selectable { /// config.darkColor = .white /// /// let textColor = config.getColor(model) //returns .black -open class SurfaceColorConfiguration: Colorable { +open class SurfaceColorConfiguration: Colorable, Initable { public var lightColor: UIColor = .clear public var darkColor: UIColor = .clear @@ -64,7 +64,7 @@ open class SurfaceColorConfiguration: Colorable { /// let textColor = config.getColor(model) //returns .white /// /// -open class DisabledSurfaceColorConfiguration: Colorable { +open class DisabledSurfaceColorConfiguration: Colorable, Initable { public var disabled = SurfaceColorConfiguration() public var enabled = SurfaceColorConfiguration() @@ -95,7 +95,7 @@ open class DisabledSurfaceColorConfiguration: /// let textColor = config.getColor(model) //returns .white /// /// -open class BinarySurfaceColorConfiguration: Colorable{ +open class BinarySurfaceColorConfiguration: Colorable, Initable{ public var forTrue = SurfaceColorConfiguration() public var forFalse = SurfaceColorConfiguration() @@ -132,7 +132,7 @@ open class BinarySurfaceColorConfiguration: Colorable { +open class BinaryDisabledSurfaceColorConfiguration: Colorable, Initable { public var forTrue = DisabledSurfaceColorConfiguration() public var forFalse = DisabledSurfaceColorConfiguration() @@ -142,3 +142,15 @@ open class BinaryDisabledSurfaceColorConfiguration: Colorable { + + private var colorHelper: (ModelType) -> UIColor + + public init(colorable: C) where C.ModelType == ModelType { + colorHelper = colorable.getColor(_:) + } + public func getColor(_ viewModel: ModelType) -> UIColor { + colorHelper(viewModel) + } +} From 94ad6cd9f851f52ce735cd1c921d3ae2434b5dfd Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 10:44:04 -0500 Subject: [PATCH 12/23] updated label/badge to AnyColorable Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 24 ++++++++++++------------ VDS/Components/Badge/Badge.swift | 14 +++++++------- VDS/Components/Label/Label.swift | 4 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index 831d9704..cad4fd18 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -13,6 +13,18 @@ public protocol Colorable: AnyObject, ObjectWithable { func getColor(_ viewModel: ModelType) -> UIColor } +public class AnyColorable: Colorable { + + private var wrapper: (ModelType) -> UIColor + + public init(colorable: C) where C.ModelType == ModelType { + wrapper = colorable.getColor(_:) + } + public func getColor(_ viewModel: ModelType) -> UIColor { + wrapper(viewModel) + } +} + public protocol BinaryColorable{ var userTrueColor: Bool { get } } @@ -142,15 +154,3 @@ open class BinaryDisabledSurfaceColorConfiguration: Colorable { - - private var colorHelper: (ModelType) -> UIColor - - public init(colorable: C) where C.ModelType == ModelType { - colorHelper = colorable.getColor(_:) - } - public func getColor(_ viewModel: ModelType) -> UIColor { - colorHelper(viewModel) - } -} diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index 69d41b6a..ed724abe 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -133,31 +133,31 @@ open class BadgeBase: View { return config.getColor(model) } - public func textColorConfiguration(for fillColor: BadgeFillColor) -> DisabledSurfaceColorConfiguration { + public func textColorConfiguration(for fillColor: BadgeFillColor) -> AnyColorable { switch fillColor { case .red, .black: - return DisabledSurfaceColorConfiguration().with { + return .init(colorable: DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOndark $0.disabled.darkColor = VDSColor.elementsPrimaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOndark $0.enabled.darkColor = VDSColor.elementsPrimaryOndark - } + }) case .yellow, .white: - return DisabledSurfaceColorConfiguration().with { + return .init(colorable: DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOnlight $0.disabled.darkColor = VDSColor.elementsPrimaryOnlight $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.enabled.darkColor = VDSColor.elementsPrimaryOnlight - } + }) case .orange, .green, .blue: - return DisabledSurfaceColorConfiguration().with { + return .init(colorable: DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOndark $0.disabled.darkColor = VDSColor.elementsPrimaryOnlight $0.enabled.lightColor = VDSColor.elementsPrimaryOndark $0.enabled.darkColor = VDSColor.elementsPrimaryOnlight - } + }) } } diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 9ebfc020..7d143dd8 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -67,12 +67,12 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- - public var textColorConfiguration = DisabledSurfaceColorConfiguration().with { + public var textColorConfiguration: AnyColorable = .init(colorable: DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsSecondaryOnlight $0.disabled.darkColor = VDSColor.elementsSecondaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.enabled.darkColor = VDSColor.elementsPrimaryOndark - } + }) //-------------------------------------------------- // MARK: - Initializers From b81dac7039f51e3aaa6f0ab890e1abda8c07cc12 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 10:52:49 -0500 Subject: [PATCH 13/23] added type erasure Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 6 ++++++ VDS/Components/Badge/Badge.swift | 12 ++++++------ VDS/Components/Label/Label.swift | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index cad4fd18..373ab90c 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -13,6 +13,12 @@ public protocol Colorable: AnyObject, ObjectWithable { func getColor(_ viewModel: ModelType) -> UIColor } +extension Colorable { + public func eraseToAnyColorable() -> AnyColorable { + AnyColorable(colorable: self) + } +} + public class AnyColorable: Colorable { private var wrapper: (ModelType) -> UIColor diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index ed724abe..285b228d 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -138,26 +138,26 @@ open class BadgeBase: View { switch fillColor { case .red, .black: - return .init(colorable: DisabledSurfaceColorConfiguration().with { + return DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOndark $0.disabled.darkColor = VDSColor.elementsPrimaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOndark $0.enabled.darkColor = VDSColor.elementsPrimaryOndark - }) + }.eraseToAnyColorable() case .yellow, .white: - return .init(colorable: DisabledSurfaceColorConfiguration().with { + return DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOnlight $0.disabled.darkColor = VDSColor.elementsPrimaryOnlight $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.enabled.darkColor = VDSColor.elementsPrimaryOnlight - }) + }.eraseToAnyColorable() case .orange, .green, .blue: - return .init(colorable: DisabledSurfaceColorConfiguration().with { + return DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOndark $0.disabled.darkColor = VDSColor.elementsPrimaryOnlight $0.enabled.lightColor = VDSColor.elementsPrimaryOndark $0.enabled.darkColor = VDSColor.elementsPrimaryOnlight - }) + }.eraseToAnyColorable() } } diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 7d143dd8..4951ecdb 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -67,12 +67,12 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- - public var textColorConfiguration: AnyColorable = .init(colorable: DisabledSurfaceColorConfiguration().with { + public var textColorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsSecondaryOnlight $0.disabled.darkColor = VDSColor.elementsSecondaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.enabled.darkColor = VDSColor.elementsPrimaryOndark - }) + }.eraseToAnyColorable() //-------------------------------------------------- // MARK: - Initializers From 27a5d665cf490e1c7975881c18720e1be0dcd690 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 12:47:18 -0500 Subject: [PATCH 14/23] refactored more colorable for AnyColorable Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 22 ++++++++++++---------- VDS/Components/Button/Button.swift | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index 373ab90c..fa4b30d8 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -public protocol Colorable: AnyObject, ObjectWithable { +public protocol Colorable { associatedtype ModelType func getColor(_ viewModel: ModelType) -> UIColor } @@ -19,15 +19,15 @@ extension Colorable { } } -public class AnyColorable: Colorable { - - private var wrapper: (ModelType) -> UIColor +public struct AnyColorable: Colorable, Withable { + private var wrapped: any Colorable public init(colorable: C) where C.ModelType == ModelType { - wrapper = colorable.getColor(_:) + wrapped = colorable } + public func getColor(_ viewModel: ModelType) -> UIColor { - wrapper(viewModel) + wrapped.getColor(viewModel) } } @@ -39,6 +39,8 @@ extension BinaryColorable where Self: Selectable { public var userTrueColor: Bool { return selected } } +public typealias ClassColorable = Colorable & Initable & ObjectWithable + /// Meant to be used in a Object that implements the following interfaces for 2 possible color combinations /// - Surfaceable (var surface: Surface) /// @@ -51,7 +53,7 @@ extension BinaryColorable where Self: Selectable { /// config.darkColor = .white /// /// let textColor = config.getColor(model) //returns .black -open class SurfaceColorConfiguration: Colorable, Initable { +open class SurfaceColorConfiguration: ClassColorable { public var lightColor: UIColor = .clear public var darkColor: UIColor = .clear @@ -82,7 +84,7 @@ open class SurfaceColorConfiguration: Colorable, Initable /// let textColor = config.getColor(model) //returns .white /// /// -open class DisabledSurfaceColorConfiguration: Colorable, Initable { +open class DisabledSurfaceColorConfiguration: ClassColorable { public var disabled = SurfaceColorConfiguration() public var enabled = SurfaceColorConfiguration() @@ -113,7 +115,7 @@ open class DisabledSurfaceColorConfiguration: /// let textColor = config.getColor(model) //returns .white /// /// -open class BinarySurfaceColorConfiguration: Colorable, Initable{ +open class BinarySurfaceColorConfiguration: ClassColorable { public var forTrue = SurfaceColorConfiguration() public var forFalse = SurfaceColorConfiguration() @@ -150,7 +152,7 @@ open class BinarySurfaceColorConfiguration: Colorable, Initable { +open class BinaryDisabledSurfaceColorConfiguration: ClassColorable { public var forTrue = DisabledSurfaceColorConfiguration() public var forFalse = DisabledSurfaceColorConfiguration() diff --git a/VDS/Components/Button/Button.swift b/VDS/Components/Button/Button.swift index bdddb0a9..46f916ab 100644 --- a/VDS/Components/Button/Button.swift +++ b/VDS/Components/Button/Button.swift @@ -213,7 +213,7 @@ open class ButtonBase: UIButton, ModelHandlerable, ViewP // MARK: - PRIVATE //-------------------------------------------------- - private class UseableColorConfiguration : Colorable { + private class UseableColorConfiguration : ClassColorable { public var primary = DisabledSurfaceColorConfiguration() public var secondary = DisabledSurfaceColorConfiguration() From 0abcbde5ec94574c11af17c52b6629c2da97370b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 13:51:18 -0500 Subject: [PATCH 15/23] refactored colorable again Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 23 ------------- VDS/Components/Badge/Badge.swift | 2 +- VDS/Components/Label/Label.swift | 2 +- VDS/Protocols/Colorable.swift | 50 ++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 VDS/Protocols/Colorable.swift diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index fa4b30d8..dc66efc8 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -8,29 +8,6 @@ import Foundation import UIKit -public protocol Colorable { - associatedtype ModelType - func getColor(_ viewModel: ModelType) -> UIColor -} - -extension Colorable { - public func eraseToAnyColorable() -> AnyColorable { - AnyColorable(colorable: self) - } -} - -public struct AnyColorable: Colorable, Withable { - private var wrapped: any Colorable - - public init(colorable: C) where C.ModelType == ModelType { - wrapped = colorable - } - - public func getColor(_ viewModel: ModelType) -> UIColor { - wrapped.getColor(viewModel) - } -} - public protocol BinaryColorable{ var userTrueColor: Bool { get } } diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index 285b228d..caf908b0 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -133,7 +133,7 @@ open class BadgeBase: View { return config.getColor(model) } - public func textColorConfiguration(for fillColor: BadgeFillColor) -> AnyColorable { + public func textColorConfiguration(for fillColor: BadgeFillColor) -> AnyColorable { switch fillColor { diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 4951ecdb..12216af7 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -67,7 +67,7 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- - public var textColorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with { + public var textColorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsSecondaryOnlight $0.disabled.darkColor = VDSColor.elementsSecondaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight diff --git a/VDS/Protocols/Colorable.swift b/VDS/Protocols/Colorable.swift new file mode 100644 index 00000000..92a7f461 --- /dev/null +++ b/VDS/Protocols/Colorable.swift @@ -0,0 +1,50 @@ +// +// Colorable.swift +// VDS +// +// Created by Matt Bruce on 10/10/22. +// + +import Foundation +import UIKit + +public protocol Colorable { + associatedtype ModelType + func getColor(_ viewModel: ModelType) -> UIColor +} + +extension Colorable { + fileprivate func getColor(_ viewModel: Any) -> UIColor { + guard let model = viewModel as? ModelType else { + assertionFailure("Invalid ModelType, Expecting type \(ModelType.self), received \(viewModel) ") + return .black + } + return getColor(model) + } + + public func eraseToAnyColorable() -> AnyColorable { AnyColorable(self) } +} + +public struct GenericColorable: Colorable, Withable { + private var wrapped: any Colorable + + public init(colorable: C) where C.ModelType == ModelType { + wrapped = colorable + } + + public func getColor(_ viewModel: ModelType) -> UIColor { + wrapped.getColor(viewModel) + } +} + +public struct AnyColorable: Colorable, Withable { + private let wrapped: any Colorable + + public init(_ colorable: any Colorable) { + wrapped = colorable + } + + public func getColor(_ viewModel: Any) -> UIColor { + wrapped.getColor(viewModel) + } +} From 02325d0d305511a1cab803c6af03b7950266fabc Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 14:17:17 -0500 Subject: [PATCH 16/23] updated entry fields Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 + .../TextFields/EntryField/EntryField.swift | 227 ++++++++++-------- .../EntryField/EntryFieldModel.swift | 21 +- .../TextEntryField/TextEntryField.swift | 138 ++++++++++- .../TextEntryField/TextEntryFieldModel.swift | 16 ++ 5 files changed, 295 insertions(+), 111 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 59d6d763..d4fdd413 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -66,6 +66,7 @@ EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */; }; EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */; }; EAA5EEB928ECD24B003B3210 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EAA5EEB828ECD24B003B3210 /* Icons.xcassets */; }; + EAA5EEE028F49DB3003B3210 /* Colorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEDF28F49DB3003B3210 /* Colorable.swift */; }; EAB1D29A28A5611D00DAE764 /* SelectorGroupModelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */; }; EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */; }; EAB1D29E28A5619500DAE764 /* RadioButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */; }; @@ -175,6 +176,7 @@ EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLabelAttribute.swift; sourceTree = ""; }; EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolTipLabelAttribute.swift; sourceTree = ""; }; EAA5EEB828ECD24B003B3210 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = ""; }; + EAA5EEDF28F49DB3003B3210 /* Colorable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colorable.swift; sourceTree = ""; }; EAB1D29928A5611D00DAE764 /* SelectorGroupModelable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupModelable.swift; sourceTree = ""; }; EAB1D29B28A5618900DAE764 /* RadioButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = ""; }; EAB1D29D28A5619500DAE764 /* RadioButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroupModel.swift; sourceTree = ""; }; @@ -356,6 +358,7 @@ children = ( EA3361C4289030FC0071C351 /* Accessable.swift */, EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */, + EAA5EEDF28F49DB3003B3210 /* Colorable.swift */, EA3361AC288B26190071C351 /* DataTrackable.swift */, EA3361A9288B25E40071C351 /* Disabling.swift */, EAF7F0A1289AFB3900B287F5 /* Errorable.swift */, @@ -677,6 +680,7 @@ EAA5EEB328EB6A66003B3210 /* TextEntryField.swift in Sources */, EA89201328B568D8006B9984 /* RadioBox.swift in Sources */, EA84F6B128B94A2500D67ABC /* CodableColor.swift in Sources */, + EAA5EEE028F49DB3003B3210 /* Colorable.swift in Sources */, EA3362402892EF6C0071C351 /* Label.swift in Sources */, EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */, EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */, diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index bae1fc76..bb2f6108 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -16,27 +16,25 @@ open class EntryField: Control { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - private var stackView: UIStackView = { + internal var stackView: UIStackView = { return UIStackView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.axis = .vertical $0.distribution = .fill } }() + + internal var titleLabel = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } - private var containerStackView: UIStackView = { - return UIStackView().with { - $0.translatesAutoresizingMaskIntoConstraints = false - $0.axis = .horizontal - $0.distribution = .fill - $0.spacing = 12 - } - }() + internal var errorLabel = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } - private var titleLabel = Label() - private var errorLabel = Label() - private var helperLabel = Label() - private var successLabel = Label() + internal var helperLabel = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } internal var containerView: UIView = { return UIView().with { @@ -44,11 +42,13 @@ open class EntryField: Control { } }() + internal var tooltipView: UIView? + //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- // Sizes are from InVision design specs. - public let containerSize = CGSize(width: 45, height: 45) + internal let containerSize = CGSize(width: 45, height: 45) internal let primaryColorConfig = DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight @@ -64,38 +64,14 @@ open class EntryField: Control { $0.enabled.darkColor = VDSColor.elementsSecondaryOndark } - internal var backgroundColorConfiguration: EntryFieldColorConfiguration = { - return EntryFieldColorConfiguration().with { - $0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.enabled.darkColor = VDSFormControlsColor.backgroundOndark - $0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.disabled.darkColor = VDSFormControlsColor.backgroundOndark - - //error/success doesn't care enabled/disable - $0.error.lightColor = VDSColor.feedbackErrorBackgroundOnlight - $0.error.darkColor = VDSColor.feedbackErrorBackgroundOndark - $0.success.lightColor = VDSColor.feedbackSuccessBackgroundOnlight - $0.success.darkColor = VDSColor.feedbackSuccessBackgroundOndark - - } - }() - - internal var borderColorConfiguration: EntryFieldColorConfiguration = { - return EntryFieldColorConfiguration().with { - $0.enabled.lightColor = VDSFormControlsColor.borderOnlight - $0.enabled.darkColor = VDSFormControlsColor.borderOnlight - $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.disabled.darkColor = VDSColor.interactiveDisabledOndark - - //error/success doesn't care enabled/disable - $0.error.lightColor = VDSColor.feedbackErrorOnlight - $0.error.darkColor = VDSColor.feedbackErrorOndark - $0.success.lightColor = VDSColor.feedbackSuccessOnlight - $0.success.darkColor = VDSColor.feedbackSuccessOndark - } + internal lazy var backgroundColorConfiguration: AnyColorable = { + return getBackgroundConfig() + }() + + internal lazy var borderColorConfiguration: AnyColorable = { + return getBorderConfig() }() - //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -110,16 +86,7 @@ open class EntryField: Control { @Proxy(\.model.errorText) open var errorText: String? - - @Proxy(\.model.showSuccess) - open var showSuccess: Bool - - @Proxy(\.model.successText) - open var successText: String? - - @Proxy(\.model.helperTextPlacement) - open var helperTextPlacement: HelperTextPlacement - + @Proxy(\.model.tooltipTitle) open var tooltipTitle: String? @@ -156,8 +123,7 @@ open class EntryField: Control { //-------------------------------------------------- internal var heightConstraint: NSLayoutConstraint? internal var widthConstraint: NSLayoutConstraint? - internal var minWidthConstraint: NSLayoutConstraint? - + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- @@ -178,30 +144,88 @@ open class EntryField: Control { heightConstraint?.isActive = true widthConstraint = containerView.widthAnchor.constraint(equalToConstant: 0) - - minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: 0) - minWidthConstraint?.isActive = true - - containerStackView.addArrangedSubview(containerView) + + let container = getContainer() stackView.addArrangedSubview(titleLabel) - stackView.addArrangedSubview(containerStackView) + stackView.addArrangedSubview(container) stackView.addArrangedSubview(errorLabel) - stackView.addArrangedSubview(successLabel) - + stackView.addArrangedSubview(helperLabel) + stackView.setCustomSpacing(4, after: titleLabel) - stackView.setCustomSpacing(8, after: containerStackView) + stackView.setCustomSpacing(8, after: container) stackView.setCustomSpacing(8, after: errorLabel) - stackView.setCustomSpacing(8, after: successLabel) - + stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + + titleLabel.textColorConfiguration = primaryColorConfig.eraseToAnyColorable() + errorLabel.textColorConfiguration = primaryColorConfig.eraseToAnyColorable() + helperLabel.textColorConfiguration = secondaryColorConfig.eraseToAnyColorable() + } + + open func getContainer() -> UIView { + return containerView + } + + open func getBackgroundConfig() -> AnyColorable { + return EntryFieldColorConfiguration().with { + $0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.disabled.darkColor = VDSFormControlsColor.backgroundOndark + + //error doesn't care enabled/disable + $0.error.lightColor = VDSColor.feedbackErrorBackgroundOnlight + $0.error.darkColor = VDSColor.feedbackErrorBackgroundOndark + }.eraseToAnyColorable() + } + + open func getBorderConfig() -> AnyColorable { + return EntryFieldColorConfiguration().with { + $0.enabled.lightColor = VDSFormControlsColor.borderOnlight + $0.enabled.darkColor = VDSFormControlsColor.borderOnlight + $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.disabled.darkColor = VDSColor.interactiveDisabledOndark + + //error doesn't care enabled/disable + $0.error.lightColor = VDSColor.feedbackErrorOnlight + $0.error.darkColor = VDSColor.feedbackErrorOndark + }.eraseToAnyColorable() + } + + open func getToolTipView(viewModel: ModelType) -> UIView? { + guard let toolTipTitleModel = viewModel.tooltipTitleModel, let toolTipContentModel = viewModel.tooltipContentModel else { + return nil + } + let stack = UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .vertical + $0.distribution = .fill + $0.spacing = 4 + } + + let title = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } + title.set(with: toolTipTitleModel) + + let content = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } + content.set(with: toolTipContentModel) + + stack.addArrangedSubview(title) + stack.addArrangedSubview(content) + + stack.backgroundColor = backgroundColorConfiguration.getColor(viewModel) + + return stack + } + + open func showToolTipView(){ - titleLabel.textColorConfiguration = primaryColorConfig - successLabel.textColorConfiguration = primaryColorConfig - errorLabel.textColorConfiguration = primaryColorConfig - helperLabel.textColorConfiguration = secondaryColorConfig } public override func reset() { @@ -214,55 +238,58 @@ open class EntryField: Control { //-------------------------------------------------- open override func updateView(viewModel: ModelType) { + containerView.backgroundColor = backgroundColorConfiguration.getColor(viewModel) + containerView.layer.borderColor = borderColorConfiguration.getColor(viewModel).cgColor + containerView.layer.borderWidth = 1 + containerView.layer.cornerRadius = 4 + + updateTitleLabel(viewModel: viewModel) + updateErrorLabel(viewModel: viewModel) + updateHelperLabel(viewModel: viewModel) + + setAccessibilityHint() + backgroundColor = viewModel.surface.color + setNeedsLayout() + layoutIfNeeded() + } + + open func updateTitleLabel(viewModel: ModelType) { //update the title model if the required flag is false var titleLabelModel = viewModel.labelModel .addOptional(required: viewModel.required, colorConfiguration: secondaryColorConfig) //tooltip action - if let toolTipTitle = viewModel.tooltipTitle, let toolTipContent = viewModel.tooltipContent { + if let view = getToolTipView(viewModel: viewModel) { + tooltipView = view let toolTipAction = PassthroughSubject() titleLabelModel = titleLabelModel.addToolTip(action: toolTipAction, colorConfiguration: primaryColorConfig) - toolTipAction.sink { - print("clicked Tool Tip: \rtitle:\(toolTipTitle)\rcontent:\(toolTipContent)") + toolTipAction.sink { [weak self] in + self?.showToolTipView() }.store(in: &subscribers) + } else { + tooltipView = nil } titleLabel.set(with: titleLabelModel) - - //show error or success + } + + open func updateErrorLabel(viewModel: ModelType){ if viewModel.showError, let errorLabelModel = viewModel.errorLabelModel { errorLabel.set(with: errorLabelModel) errorLabel.isHidden = false - successLabel.isHidden = true - } else if viewModel.showSuccess, let successLabelModel = viewModel.successLabelModel { - successLabel.set(with: successLabelModel) - errorLabel.isHidden = true - successLabel.isHidden = false } else { errorLabel.isHidden = true - successLabel.isHidden = true } - + } + + open func updateHelperLabel(viewModel: ModelType){ //set the helper label position if let helperLabelModel = viewModel.helperLabelModel { - helperLabel.removeFromSuperview() - if viewModel.helperTextPlacement == .right { - containerStackView.spacing = 12 - containerStackView.addArrangedSubview(helperLabel) - } else { - containerStackView.spacing = 0 - stackView.addArrangedSubview(helperLabel) - } helperLabel.set(with: helperLabelModel) helperLabel.isHidden = false } else { helperLabel.isHidden = true } - - setAccessibilityHint(!viewModel.disabled) - backgroundColor = viewModel.surface.color - setNeedsLayout() - layoutIfNeeded() } //-------------------------------------------------- @@ -270,19 +297,13 @@ open class EntryField: Control { //-------------------------------------------------- internal class EntryFieldColorConfiguration: DisabledSurfaceColorConfiguration { public let error = SurfaceColorConfiguration() - public let success = SurfaceColorConfiguration() override func getColor(_ viewModel: ModelType) -> UIColor { //only show error is enabled and showError == true let showErrorColor = !viewModel.disabled && viewModel.showError - let showSuccessColor = !viewModel.disabled && viewModel.showSuccess if showErrorColor { return error.getColor(viewModel) - - } else if showSuccessColor { - return success.getColor(viewModel) - } else { return super.getColor(viewModel) } @@ -307,7 +328,7 @@ extension DefaultLabelModel { public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { guard let text = text else { return self} var newAttributes = attributes ?? [] - let newText = "\(text) " + let newText = "\(text) " //create a little space between the final character and tooltip image let toolTip = ToolTipLabelAttribute(action: action, location: newText.count, length: 1, diff --git a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift index 86d80427..746ffda4 100644 --- a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift +++ b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift @@ -18,8 +18,6 @@ public protocol EntryFieldModel: Modelable, FormFieldable, Errorable { var labelText: String? { get set } var helperText: String? { get set } var helperTextPlacement: HelperTextPlacement { get set } - var showSuccess: Bool { get set } - var successText: String? { get set } var transparentBackground: Bool { get set } var width: CGFloat? { get set } var maxLength: Int? { get set } @@ -40,6 +38,7 @@ extension EntryFieldModel { } public var helperLabelModel: DefaultLabelModel? { + guard let helperText else { return nil } var model = DefaultLabelModel() model.textPosition = .left model.typograpicalStyle = .BodySmall @@ -50,6 +49,7 @@ extension EntryFieldModel { } public var errorLabelModel: DefaultLabelModel? { + guard let errorText else { return nil } var model = DefaultLabelModel() model.textPosition = .left model.typograpicalStyle = .BodySmall @@ -59,13 +59,26 @@ extension EntryFieldModel { return model } - public var successLabelModel: DefaultLabelModel? { + public var tooltipTitleModel: DefaultLabelModel? { + guard let tooltipTitle else { return nil } var model = DefaultLabelModel() model.textPosition = .left model.typograpicalStyle = .BodySmall - model.text = successText + model.text = tooltipTitle model.surface = surface model.disabled = disabled return model } + + public var tooltipContentModel: DefaultLabelModel? { + guard let tooltipContent else { return nil } + var model = DefaultLabelModel() + model.textPosition = .left + model.typograpicalStyle = .BodySmall + model.text = tooltipContent + model.surface = surface + model.disabled = disabled + return model + } + } diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift index f2065977..5e337a1d 100644 --- a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift +++ b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift @@ -8,12 +8,25 @@ import Foundation import UIKit import VDSColorTokens +import VDSFormControlsTokens import Combine public class TextEntryField: TextEntryFieldBase{} open class TextEntryFieldBase: EntryField { + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + internal var containerStackView: UIStackView = { + return UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .horizontal + $0.distribution = .fill + $0.spacing = 12 + } + }() + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -21,16 +34,92 @@ open class TextEntryFieldBase: EntryField UIView { + containerStackView.addArrangedSubview(containerView) + return containerStackView + } + + open override func getBackgroundConfig() -> AnyColorable { + return TextEntryFieldColorConfiguration().with { + $0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.disabled.darkColor = VDSFormControlsColor.backgroundOndark + + //error/success doesn't care enabled/disable + $0.error.lightColor = VDSColor.feedbackErrorBackgroundOnlight + $0.error.darkColor = VDSColor.feedbackErrorBackgroundOndark + $0.success.lightColor = VDSColor.feedbackSuccessBackgroundOnlight + $0.success.darkColor = VDSColor.feedbackSuccessBackgroundOndark + }.eraseToAnyColorable() + } + + open override func getBorderConfig() -> AnyColorable { + return TextEntryFieldColorConfiguration().with { + $0.enabled.lightColor = VDSFormControlsColor.borderOnlight + $0.enabled.darkColor = VDSFormControlsColor.borderOnlight + $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.disabled.darkColor = VDSColor.interactiveDisabledOndark + + //error/success doesn't care enabled/disable + $0.error.lightColor = VDSColor.feedbackErrorOnlight + $0.error.darkColor = VDSColor.feedbackErrorOndark + $0.success.lightColor = VDSColor.feedbackSuccessOnlight + $0.success.darkColor = VDSColor.feedbackSuccessOndark + }.eraseToAnyColorable() + } //-------------------------------------------------- // MARK: - State //-------------------------------------------------- open override func updateView(viewModel: ModelType) { super.updateView(viewModel: viewModel) - containerView.backgroundColor = backgroundColorConfiguration.getColor(viewModel) - containerView.layer.borderColor = borderColorConfiguration.getColor(viewModel).cgColor - containerView.layer.borderWidth = 1 - containerView.layer.cornerRadius = 4 + + //show error or success + if viewModel.showError, let _ = viewModel.errorLabelModel { + successLabel.isHidden = true + + } else if viewModel.showSuccess, let successLabelModel = viewModel.successLabelModel { + successLabel.set(with: successLabelModel) + successLabel.isHidden = false + errorLabel.isHidden = true + + } else { + successLabel.isHidden = true + + } + //set the width constraints if let width = viewModel.width, width > viewModel.type.width { widthConstraint?.constant = width @@ -42,6 +131,47 @@ open class TextEntryFieldBase: EntryField() + + override func getColor(_ viewModel: ModelType) -> UIColor { + //only show error is enabled and showError == true + let showErrorColor = !viewModel.disabled && viewModel.showError + let showSuccessColor = !viewModel.disabled && viewModel.showSuccess + + if showErrorColor { + return error.getColor(viewModel) + + } else if showSuccessColor { + return success.getColor(viewModel) + + } else { + return super.getColor(viewModel) + } + } + } } extension TextEntryFieldType { diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift index 4b310b4a..faa05579 100644 --- a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift +++ b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift @@ -13,6 +13,22 @@ public enum TextEntryFieldType: String, CaseIterable { public protocol TextEntryFieldModel: EntryFieldModel { var type: TextEntryFieldType { get set } + var showSuccess: Bool { get set } + var successText: String? { get set } +} + +extension TextEntryFieldModel { + + public var successLabelModel: DefaultLabelModel? { + var model = DefaultLabelModel() + model.textPosition = .left + model.typograpicalStyle = .BodySmall + model.text = successText + model.surface = surface + model.disabled = disabled + return model + } + } From 163c292796ead5f74fe831585a72d4f36caa3e78 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 16:22:28 -0500 Subject: [PATCH 17/23] updated color config Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 108 ++++++++++++++----- VDS/Components/Badge/Badge.swift | 22 ++-- VDS/Components/Button/Button.swift | 81 +++++++------- VDS/Components/Checkbox/Checkbox.swift | 55 +++++----- VDS/Components/Label/Label.swift | 2 +- VDS/Components/RadioBox/RadioBox.swift | 52 ++++----- VDS/Components/RadioButton/RadioButton.swift | 86 ++++++--------- VDS/Components/RadioSwatch/RadioSwatch.swift | 61 +++++------ VDS/Components/Toggle/Toggle.swift | 44 ++++---- VDS/Protocols/Withable.swift | 1 + 10 files changed, 260 insertions(+), 252 deletions(-) diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index dc66efc8..da63fc3a 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -8,15 +8,7 @@ import Foundation import UIKit -public protocol BinaryColorable{ - var userTrueColor: Bool { get } -} - -extension BinaryColorable where Self: Selectable { - public var userTrueColor: Bool { return selected } -} - -public typealias ClassColorable = Colorable & Initable & ObjectWithable +public typealias ObjectColorable = Colorable & Initable & ObjectWithable /// Meant to be used in a Object that implements the following interfaces for 2 possible color combinations /// - Surfaceable (var surface: Surface) @@ -30,16 +22,31 @@ public typealias ClassColorable = Colorable & Initable & ObjectWithable /// config.darkColor = .white /// /// let textColor = config.getColor(model) //returns .black -open class SurfaceColorConfiguration: ClassColorable { +final public class SurfaceColorConfiguration: ObjectColorable { + public typealias ModelType = Surfaceable public var lightColor: UIColor = .clear public var darkColor: UIColor = .clear required public init(){} - public func getColor(_ viewModel: ModelType) -> UIColor { + public func getColor(_ viewModel: any ModelType) -> UIColor { return viewModel.surface == .light ? lightColor : darkColor } } +///------------------------------------------------------------------- +///MARK -- DisabledSurfaceColorable +///------------------------------------------------------------------- +public protocol DisabledSurfaceColorable: ObjectColorable { + var disabled: SurfaceColorConfiguration { get set } + var enabled: SurfaceColorConfiguration { get set } +} + +extension DisabledSurfaceColorable { + public func getDisabledColor (_ viewModel: M) -> UIColor { + viewModel.disabled ? disabled.getColor(viewModel) : enabled.getColor(viewModel) + } +} + /// Meant to be used in a Object that implements the following interfaces for 4 possible color combinations /// - Disabling (var disabled: Bool) /// - Surfaceable (var surface: Surface) @@ -48,7 +55,7 @@ open class SurfaceColorConfiguration: ClassColorable { /// model.surface = .dark /// model.disabled = false /// -/// let config = DisabledSurfaceColorConfiguration() +/// let config = DisabledSurfaceColorConfiguration() /// /// //disabled == false /// config.enabled.lightColor = .black @@ -61,14 +68,40 @@ open class SurfaceColorConfiguration: ClassColorable { /// let textColor = config.getColor(model) //returns .white /// /// -open class DisabledSurfaceColorConfiguration: ClassColorable { - public var disabled = SurfaceColorConfiguration() - public var enabled = SurfaceColorConfiguration() +final public class DisabledSurfaceColorConfiguration: DisabledSurfaceColorable { + public typealias ModelType = Surfaceable & Disabling + public var disabled = SurfaceColorConfiguration() + public var enabled = SurfaceColorConfiguration() required public init(){} - public func getColor(_ viewModel: ModelType) -> UIColor { - return viewModel.disabled ? disabled.getColor(viewModel) : enabled.getColor(viewModel) + public func getColor(_ viewModel: any ModelType) -> UIColor { + getDisabledColor(viewModel) + } +} + +///------------------------------------------------------------------- +///MARK -- BinaryColorable +///------------------------------------------------------------------- +public protocol BinaryColorable{ + var userTrueColor: Bool { get } +} + +extension BinaryColorable where Self: Selectable { + public var userTrueColor: Bool { return selected } +} + +///------------------------------------------------------------------- +///MARK -- BinarySurfaceColorable +///------------------------------------------------------------------- +public protocol BinarySurfaceColorable: ObjectColorable { + var forTrue: SurfaceColorConfiguration { get set } + var forFalse: SurfaceColorConfiguration { get set } +} + +extension BinarySurfaceColorable { + public func getBinaryColor(_ viewModel: M) -> UIColor { + viewModel.userTrueColor ? forTrue.getColor(viewModel) : forFalse.getColor(viewModel) } } @@ -79,7 +112,7 @@ open class DisabledSurfaceColorConfiguration: /// let model = TestModel() /// model.surface = .dark /// model.on = true //this is read in the extension var userTrueColor -/// let config = BinarySurfaceColorConfiguration() +/// let config = BinarySurfaceColorConfiguration() /// /// //True from BinaryColorable.userTrueColor /// config.forTrue.lightColor = .black @@ -92,14 +125,30 @@ open class DisabledSurfaceColorConfiguration: /// let textColor = config.getColor(model) //returns .white /// /// -open class BinarySurfaceColorConfiguration: ClassColorable { - public var forTrue = SurfaceColorConfiguration() - public var forFalse = SurfaceColorConfiguration() +final public class BinarySurfaceColorConfiguration: BinarySurfaceColorable { + public typealias ModelType = Surfaceable & BinaryColorable + public var forTrue = SurfaceColorConfiguration() + public var forFalse = SurfaceColorConfiguration() required public init(){} - public func getColor(_ viewModel: ModelType) -> UIColor { - return viewModel.userTrueColor ? forTrue.getColor(viewModel) : forFalse.getColor(viewModel) + public func getColor(_ viewModel: any ModelType) -> UIColor { + getBinaryColor(viewModel) + } +} + +///------------------------------------------------------------------- +///MARK -- BinaryDisabledSurfaceColorable +///------------------------------------------------------------------- + +public protocol BinaryDisabledSurfaceColorable: ObjectColorable { + var forTrue: DisabledSurfaceColorConfiguration { get set } + var forFalse: DisabledSurfaceColorConfiguration { get set } +} + +extension BinaryDisabledSurfaceColorable { + public func getBinaryColor(_ viewModel: M) -> UIColor { + viewModel.userTrueColor ? forTrue.getColor(viewModel) : forFalse.getColor(viewModel) } } @@ -112,7 +161,7 @@ open class BinarySurfaceColorConfiguration() +/// let config = BinaryDisabledSurfaceColorConfiguration() /// /// //True /// config.forTrue.enabled.lightColor = .black @@ -129,13 +178,14 @@ open class BinarySurfaceColorConfiguration: ClassColorable { - public var forTrue = DisabledSurfaceColorConfiguration() - public var forFalse = DisabledSurfaceColorConfiguration() +final public class BinaryDisabledSurfaceColorConfiguration: BinaryDisabledSurfaceColorable { + public typealias ModelType = Disabling & Surfaceable & BinaryColorable + public var forTrue = DisabledSurfaceColorConfiguration() + public var forFalse = DisabledSurfaceColorConfiguration() required public init(){} - public func getColor(_ viewModel: ModelType) -> UIColor { - return viewModel.userTrueColor ? forTrue.getColor(viewModel) : forFalse.getColor(viewModel) + public func getColor(_ viewModel: any ModelType) -> UIColor { + getBinaryColor(viewModel) } } diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index caf908b0..746a445b 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -91,40 +91,40 @@ open class BadgeBase: View { // MARK: - Configuration //-------------------------------------------------- public func backgroundColor(for fillColor: BadgeFillColor) -> UIColor { - var config: SurfaceColorConfiguration + var config: SurfaceColorConfiguration switch model.fillColor { case .red: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.backgroundBrandhighlight $0.darkColor = VDSColor.backgroundBrandhighlight } case .yellow: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.paletteYellow62 $0.darkColor = VDSColor.paletteYellow62 } case .green: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.paletteGreen26 $0.darkColor = VDSColor.paletteGreen34 } case .orange: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.paletteOrange39 $0.darkColor = VDSColor.paletteOrange46 } case .blue: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.paletteBlue35 $0.darkColor = VDSColor.paletteBlue45 } case .black: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.paletteBlack $0.darkColor = VDSColor.paletteBlack } case .white: - config = SurfaceColorConfiguration().with { + config = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.paletteWhite $0.darkColor = VDSColor.paletteWhite } @@ -138,21 +138,21 @@ open class BadgeBase: View { switch fillColor { case .red, .black: - return DisabledSurfaceColorConfiguration().with { + return DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOndark $0.disabled.darkColor = VDSColor.elementsPrimaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOndark $0.enabled.darkColor = VDSColor.elementsPrimaryOndark }.eraseToAnyColorable() case .yellow, .white: - return DisabledSurfaceColorConfiguration().with { + return DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOnlight $0.disabled.darkColor = VDSColor.elementsPrimaryOnlight $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.enabled.darkColor = VDSColor.elementsPrimaryOnlight }.eraseToAnyColorable() case .orange, .green, .blue: - return DisabledSurfaceColorConfiguration().with { + return DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsPrimaryOndark $0.disabled.darkColor = VDSColor.elementsPrimaryOnlight $0.enabled.lightColor = VDSColor.elementsPrimaryOndark diff --git a/VDS/Components/Button/Button.swift b/VDS/Components/Button/Button.swift index 46f916ab..d31d4807 100644 --- a/VDS/Components/Button/Button.swift +++ b/VDS/Components/Button/Button.swift @@ -65,51 +65,45 @@ open class ButtonBase: UIButton, ModelHandlerable, ViewP isUserInteractionEnabled = isEnabled } } - + //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- - private var buttonBackgroundColorConfiguration: UseableColorConfiguration = { - return UseableColorConfiguration().with { - $0.primary.enabled.lightColor = VDSColor.backgroundPrimaryDark - $0.primary.enabled.darkColor = VDSColor.backgroundPrimaryLight - $0.primary.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.primary.disabled.darkColor = VDSColor.interactiveDisabledOndark - - $0.secondary.enabled.lightColor = UIColor.clear - $0.secondary.enabled.darkColor = UIColor.clear - $0.secondary.disabled.lightColor = UIColor.clear - $0.secondary.disabled.darkColor = UIColor.clear - } - }() + private var buttonBackgroundColorConfiguration = UseableColorConfiguration().with { + $0.primary.enabled.lightColor = VDSColor.backgroundPrimaryDark + $0.primary.enabled.darkColor = VDSColor.backgroundPrimaryLight + $0.primary.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.primary.disabled.darkColor = VDSColor.interactiveDisabledOndark + + $0.secondary.enabled.lightColor = UIColor.clear + $0.secondary.enabled.darkColor = UIColor.clear + $0.secondary.disabled.lightColor = UIColor.clear + $0.secondary.disabled.darkColor = UIColor.clear + } - private var buttonBorderColorConfiguration: UseableColorConfiguration = { - return UseableColorConfiguration().with { - $0.primary.enabled.lightColor = VDSColor.elementsPrimaryOndark - $0.primary.enabled.darkColor = VDSColor.elementsPrimaryOnlight - $0.primary.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.primary.disabled.darkColor = VDSColor.interactiveDisabledOndark - - $0.secondary.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.secondary.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.secondary.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.secondary.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - }() + private var buttonBorderColorConfiguration = UseableColorConfiguration().with { + $0.primary.enabled.lightColor = VDSColor.elementsPrimaryOndark + $0.primary.enabled.darkColor = VDSColor.elementsPrimaryOnlight + $0.primary.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.primary.disabled.darkColor = VDSColor.interactiveDisabledOndark + + $0.secondary.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.secondary.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.secondary.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.secondary.disabled.darkColor = VDSColor.interactiveDisabledOndark + } - private var buttonTitleColorConfiguration: UseableColorConfiguration = { - return UseableColorConfiguration().with { - $0.primary.enabled.lightColor = VDSColor.elementsPrimaryOndark - $0.primary.enabled.darkColor = VDSColor.elementsPrimaryOnlight - $0.primary.disabled.lightColor = VDSColor.elementsPrimaryOndark - $0.primary.disabled.darkColor = VDSColor.elementsPrimaryOnlight - - $0.secondary.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.secondary.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.secondary.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.secondary.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - }() + private var buttonTitleColorConfiguration = UseableColorConfiguration().with { + $0.primary.enabled.lightColor = VDSColor.elementsPrimaryOndark + $0.primary.enabled.darkColor = VDSColor.elementsPrimaryOnlight + $0.primary.disabled.lightColor = VDSColor.elementsPrimaryOndark + $0.primary.disabled.darkColor = VDSColor.elementsPrimaryOnlight + + $0.secondary.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.secondary.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.secondary.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.secondary.disabled.darkColor = VDSColor.interactiveDisabledOndark + } //-------------------------------------------------- // MARK: - Initializers @@ -213,9 +207,10 @@ open class ButtonBase: UIButton, ModelHandlerable, ViewP // MARK: - PRIVATE //-------------------------------------------------- - private class UseableColorConfiguration : ClassColorable { - public var primary = DisabledSurfaceColorConfiguration() - public var secondary = DisabledSurfaceColorConfiguration() + private class UseableColorConfiguration: ObjectColorable { + typealias ModelType = Disabling & Surfaceable & Useable + public var primary = DisabledSurfaceColorConfiguration() + public var secondary = DisabledSurfaceColorConfiguration() required public init(){} diff --git a/VDS/Components/Checkbox/Checkbox.swift b/VDS/Components/Checkbox/Checkbox.swift index caf2dd8a..e14e5b2b 100644 --- a/VDS/Components/Checkbox/Checkbox.swift +++ b/VDS/Components/Checkbox/Checkbox.swift @@ -230,8 +230,6 @@ open class CheckboxBase: Control { // MARK: - State //-------------------------------------------------- open override func updateView(viewModel: ModelType) { - let enabled = !viewModel.disabled - updateLabels(viewModel) updateSelector(viewModel) setAccessibilityHint() @@ -247,8 +245,8 @@ open class CheckboxBase: Control { //-------------------------------------------------- public let checkboxSize = CGSize(width: 20, height: 20) - private var checkboxBackgroundColorConfiguration: CheckboxErrorColorConfiguration = { - return CheckboxErrorColorConfiguration().with { + private var checkboxBackgroundColorConfiguration: ErrorBinaryDisabledSurfaceColorConfiguration = { + return ErrorBinaryDisabledSurfaceColorConfiguration().with { $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight @@ -261,8 +259,8 @@ open class CheckboxBase: Control { } }() - private var checkboxBorderColorConfiguration: CheckboxErrorColorConfiguration = { - return CheckboxErrorColorConfiguration().with { + private var checkboxBorderColorConfiguration: ErrorBinaryDisabledSurfaceColorConfiguration = { + return ErrorBinaryDisabledSurfaceColorConfiguration().with { $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight @@ -279,8 +277,8 @@ open class CheckboxBase: Control { } }() - private var checkboxCheckColorConfiguration: BinarySurfaceColorConfiguration = { - return BinarySurfaceColorConfiguration().with { + private var checkboxCheckColorConfiguration: BinarySurfaceColorConfiguration = { + return BinarySurfaceColorConfiguration().with { $0.forTrue.lightColor = VDSColor.elementsPrimaryOndark $0.forTrue.darkColor = VDSColor.elementsPrimaryOnlight } @@ -346,23 +344,28 @@ open class CheckboxBase: Control { } } } - - //-------------------------------------------------- - // MARK: - Color Class Configurations - //-------------------------------------------------- - private class CheckboxErrorColorConfiguration: BinaryDisabledSurfaceColorConfiguration { - public let error = BinarySurfaceColorConfiguration() - override func getColor(_ viewModel: ModelType) -> UIColor { - //only show error is enabled and showError == true - let showErrorColor = !viewModel.disabled && viewModel.showError - - if showErrorColor { - return error.getColor(viewModel) - } else { - return super.getColor(viewModel) - } - } - } - +} + +//-------------------------------------------------- +// MARK: - Color Class Configurations +//-------------------------------------------------- +internal class ErrorBinaryDisabledSurfaceColorConfiguration: BinaryDisabledSurfaceColorable { + typealias ModelType = Errorable & Disabling & Surfaceable & BinaryColorable + var error = BinarySurfaceColorConfiguration() + var forTrue = DisabledSurfaceColorConfiguration() + var forFalse = DisabledSurfaceColorConfiguration() + + required init() {} + + func getColor(_ viewModel: ModelType) -> UIColor { + //only show error is enabled and showError == true + let showErrorColor = !viewModel.disabled && viewModel.showError + + if showErrorColor { + return error.getColor(viewModel) + } else { + return getBinaryColor(viewModel) + } + } } diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 12216af7..5934458e 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -67,7 +67,7 @@ open class LabelBase: UILabel, ModelHandlerable, ViewProt //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- - public var textColorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with { + public var textColorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.elementsSecondaryOnlight $0.disabled.darkColor = VDSColor.elementsSecondaryOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight diff --git a/VDS/Components/RadioBox/RadioBox.swift b/VDS/Components/RadioBox/RadioBox.swift index 4d71159d..a4e47b40 100644 --- a/VDS/Components/RadioBox/RadioBox.swift +++ b/VDS/Components/RadioBox/RadioBox.swift @@ -207,8 +207,6 @@ open class RadioBoxBase: Control { // MARK: - State //-------------------------------------------------- open override func updateView(viewModel: ModelType) { - let enabled = !viewModel.disabled - updateLabels(viewModel) updateSelector(viewModel) setAccessibilityHint() @@ -227,34 +225,30 @@ open class RadioBoxBase: Control { private var selectorBorderWidthSelected: CGFloat = 2.0 private var selectorBorderWidth: CGFloat = 1.0 - private var radioBoxBackgroundColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark - $0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forFalse.disabled.darkColor = VDSFormControlsColor.backgroundOndark - - $0.forTrue.enabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark - $0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark - } - }() + private var radioBoxBackgroundColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forFalse.disabled.darkColor = VDSFormControlsColor.backgroundOndark + + $0.forTrue.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark + } + + private var radioBoxBorderColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight + $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark + + $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark + $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark + } - private var radioBoxBorderColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight - $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark - - $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark - $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - }() - //-------------------------------------------------- // MARK: - RadioBox View Updates //-------------------------------------------------- diff --git a/VDS/Components/RadioButton/RadioButton.swift b/VDS/Components/RadioButton/RadioButton.swift index cb2081c9..4a77cb48 100644 --- a/VDS/Components/RadioButton/RadioButton.swift +++ b/VDS/Components/RadioButton/RadioButton.swift @@ -240,8 +240,6 @@ open class RadioButtonBase: Control { // MARK: - State //-------------------------------------------------- open override func updateView(viewModel: ModelType) { - let enabled = !viewModel.disabled - updateLabels(viewModel) updateSelector(viewModel) setAccessibilityHint() @@ -256,43 +254,37 @@ open class RadioButtonBase: Control { //-------------------------------------------------- public let radioButtonSize = CGSize(width: 20, height: 20) public let radioButtonSelectedSize = CGSize(width: 10, height: 10) - - private var radioButtonBackgroundColorConfiguration: RadioButtonErrorColorConfiguration = { - return RadioButtonErrorColorConfiguration().with { - //error doesn't care enabled/disable - $0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight - $0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark - $0.error.forFalse.lightColor = VDSColor.feedbackErrorBackgroundOnlight - $0.error.forFalse.darkColor = VDSColor.feedbackErrorBackgroundOndark - } - }() - private var radioButtonBorderColorConfiguration: RadioButtonErrorColorConfiguration = { - return RadioButtonErrorColorConfiguration().with { - $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight - $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark - $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark - $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark - //error doesn't care enabled/disable - $0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight - $0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark - $0.error.forFalse.lightColor = VDSColor.feedbackErrorOnlight - $0.error.forFalse.darkColor = VDSColor.feedbackErrorOndark - } - }() - - private var radioButtonCheckColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - }() + private var radioButtonBackgroundColorConfiguration = ErrorBinaryDisabledSurfaceColorConfiguration().with { + //error doesn't care enabled/disable + $0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight + $0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark + $0.error.forFalse.lightColor = VDSColor.feedbackErrorBackgroundOnlight + $0.error.forFalse.darkColor = VDSColor.feedbackErrorBackgroundOndark + } + + private var radioButtonBorderColorConfiguration = ErrorBinaryDisabledSurfaceColorConfiguration().with { + $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight + $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark + $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark + $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark + //error doesn't care enabled/disable + $0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight + $0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark + $0.error.forFalse.lightColor = VDSColor.feedbackErrorOnlight + $0.error.forFalse.darkColor = VDSColor.feedbackErrorOndark + } + + private var radioButtonCheckColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark + } //-------------------------------------------------- // MARK: - RadioButton View @@ -338,23 +330,5 @@ open class RadioButtonBase: Control { shapeLayer.path = bezierPath.cgPath } } - - //-------------------------------------------------- - // MARK: - Color Class Configurations - //-------------------------------------------------- - private class RadioButtonErrorColorConfiguration: BinaryDisabledSurfaceColorConfiguration { - public let error = BinarySurfaceColorConfiguration() - override func getColor(_ viewModel: ModelType) -> UIColor { - //only show error is enabled and showError == true - let showErrorColor = !viewModel.disabled && viewModel.showError - - if showErrorColor { - return error.getColor(viewModel) - } else { - return super.getColor(viewModel) - } - } - } - } diff --git a/VDS/Components/RadioSwatch/RadioSwatch.swift b/VDS/Components/RadioSwatch/RadioSwatch.swift index 1d0e4164..c53e7079 100644 --- a/VDS/Components/RadioSwatch/RadioSwatch.swift +++ b/VDS/Components/RadioSwatch/RadioSwatch.swift @@ -159,41 +159,36 @@ open class RadioSwatchBase: Control { public let swatchSize = CGSize(width: 48, height: 48) public let fillSize = CGSize(width: 36, height: 36) public let disabledAlpha = 0.5 - private var radioSwatchBackgroundColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark - $0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forFalse.disabled.darkColor = VDSFormControlsColor.backgroundOndark - - $0.forTrue.enabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark - $0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight - $0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark - } - }() - private var radioSwatchBorderColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight - $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark - $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark - $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - }() + private var radioSwatchBackgroundColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forFalse.disabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.forTrue.enabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark + $0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight + $0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark + } + + private var radioSwatchBorderColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight + $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark + $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark + $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark + } + + private var radioSwatchFillBorderColorConfiguration = DisabledSurfaceColorConfiguration().with { + $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight + $0.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.disabled.darkColor = VDSColor.interactiveDisabledOndark + } - private var radioSwatchFillBorderColorConfiguration: DisabledSurfaceColorConfiguration = { - return DisabledSurfaceColorConfiguration().with { - $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight - $0.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - }() //-------------------------------------------------- // MARK: - RadioBox View Updates //-------------------------------------------------- diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 27d19634..8babbace 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -64,31 +64,27 @@ open class ToggleBase: Control { public let toggleContainerSize = CGSize(width: 52, height: 44) public let knobSize = CGSize(width: 20, height: 20) - private var toggleColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forTrue.enabled.lightColor = VDSColor.paletteGreen26 - $0.forTrue.enabled.darkColor = VDSColor.paletteGreen34 - $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark - $0.forFalse.enabled.lightColor = VDSColor.elementsSecondaryOnlight - $0.forFalse.enabled.darkColor = VDSColor.paletteGray44 - $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight - $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark - } - } () + private var toggleColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forTrue.enabled.lightColor = VDSColor.paletteGreen26 + $0.forTrue.enabled.darkColor = VDSColor.paletteGreen34 + $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark + $0.forFalse.enabled.lightColor = VDSColor.elementsSecondaryOnlight + $0.forFalse.enabled.darkColor = VDSColor.paletteGray44 + $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight + $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark + } - private var knobColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { - return BinaryDisabledSurfaceColorConfiguration().with { - $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOndark - $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.forTrue.disabled.lightColor = VDSColor.paletteGray95 - $0.forTrue.disabled.darkColor = VDSColor.paletteGray44 - $0.forFalse.enabled.lightColor = VDSColor.elementsPrimaryOndark - $0.forFalse.enabled.darkColor = VDSColor.elementsPrimaryOndark - $0.forFalse.disabled.lightColor = VDSColor.paletteGray95 - $0.forFalse.disabled.darkColor = VDSColor.paletteGray44 - } - } () + private var knobColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with { + $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOndark + $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.forTrue.disabled.lightColor = VDSColor.paletteGray95 + $0.forTrue.disabled.darkColor = VDSColor.paletteGray44 + $0.forFalse.enabled.lightColor = VDSColor.elementsPrimaryOndark + $0.forFalse.enabled.darkColor = VDSColor.elementsPrimaryOndark + $0.forFalse.disabled.lightColor = VDSColor.paletteGray95 + $0.forFalse.disabled.darkColor = VDSColor.paletteGray44 + } //-------------------------------------------------- // MARK: - Public Properties diff --git a/VDS/Protocols/Withable.swift b/VDS/Protocols/Withable.swift index 62af68ab..0ab9eebd 100644 --- a/VDS/Protocols/Withable.swift +++ b/VDS/Protocols/Withable.swift @@ -48,3 +48,4 @@ public extension Withable { return copy } } + From 0a8b0c2f7cd44dc5212e192c6fc202e1d48e20cb Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 10 Oct 2022 16:24:49 -0500 Subject: [PATCH 18/23] updated code Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 2 +- .../TextFields/EntryField/EntryField.swift | 45 ++++++++++--------- .../TextEntryField/TextEntryField.swift | 17 ++++--- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index d4fdd413..7f7742b8 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -442,8 +442,8 @@ EA4DB2FE28DCBC1900103EE3 /* Badge */ = { isa = PBXGroup; children = ( - EA4DB2FF28DCBC9900103EE3 /* BadgeModel.swift */, EA4DB30128DCBCA500103EE3 /* Badge.swift */, + EA4DB2FF28DCBC9900103EE3 /* BadgeModel.swift */, ); path = Badge; sourceTree = ""; diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index bb2f6108..936138ef 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -50,14 +50,14 @@ open class EntryField: Control { // Sizes are from InVision design specs. internal let containerSize = CGSize(width: 45, height: 45) - internal let primaryColorConfig = DisabledSurfaceColorConfiguration().with { + internal let primaryColorConfig = DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight $0.disabled.darkColor = VDSColor.interactiveDisabledOndark $0.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.enabled.darkColor = VDSColor.elementsPrimaryOndark } - internal let secondaryColorConfig = DisabledSurfaceColorConfiguration().with { + internal let secondaryColorConfig = DisabledSurfaceColorConfiguration().with { $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight $0.disabled.darkColor = VDSColor.interactiveDisabledOndark $0.enabled.lightColor = VDSColor.elementsSecondaryOnlight @@ -170,7 +170,7 @@ open class EntryField: Control { } open func getBackgroundConfig() -> AnyColorable { - return EntryFieldColorConfiguration().with { + return ErrorDisabledSurfaceColorConfiguration().with { $0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight $0.enabled.darkColor = VDSFormControlsColor.backgroundOndark $0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight @@ -183,7 +183,7 @@ open class EntryField: Control { } open func getBorderConfig() -> AnyColorable { - return EntryFieldColorConfiguration().with { + return ErrorDisabledSurfaceColorConfiguration().with { $0.enabled.lightColor = VDSFormControlsColor.borderOnlight $0.enabled.darkColor = VDSFormControlsColor.borderOnlight $0.disabled.lightColor = VDSColor.interactiveDisabledOnlight @@ -291,28 +291,33 @@ open class EntryField: Control { helperLabel.isHidden = true } } +} - //-------------------------------------------------- - // MARK: - Color Class Configurations - //-------------------------------------------------- - internal class EntryFieldColorConfiguration: DisabledSurfaceColorConfiguration { - public let error = SurfaceColorConfiguration() - - override func getColor(_ viewModel: ModelType) -> UIColor { - //only show error is enabled and showError == true - let showErrorColor = !viewModel.disabled && viewModel.showError +//-------------------------------------------------- +// MARK: - Color Class Configurations +//-------------------------------------------------- +internal class ErrorDisabledSurfaceColorConfiguration: DisabledSurfaceColorable { + typealias ModelType = Errorable & Surfaceable & Disabling + var error = SurfaceColorConfiguration() + var disabled = SurfaceColorConfiguration() + var enabled = SurfaceColorConfiguration() + + required public init(){} - if showErrorColor { - return error.getColor(viewModel) - } else { - return super.getColor(viewModel) - } + func getColor(_ viewModel: any ModelType) -> UIColor { + //only show error is enabled and showError == true + let showErrorColor = !viewModel.disabled && viewModel.showError + + if showErrorColor { + return error.getColor(viewModel) + } else { + return getDisabledColor(viewModel) } } } extension DefaultLabelModel { - public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { + public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { guard let text = text, !required else { return self} let optionColorAttr = ColorLabelAttribute(location: text.count + 2, length: 8, @@ -325,7 +330,7 @@ extension DefaultLabelModel { } } - public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { + public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { guard let text = text else { return self} var newAttributes = attributes ?? [] let newText = "\(text) " //create a little space between the final character and tooltip image diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift index 5e337a1d..d2f49038 100644 --- a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift +++ b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift @@ -153,10 +153,15 @@ open class TextEntryFieldBase: EntryField() - - override func getColor(_ viewModel: ModelType) -> UIColor { + internal class TextEntryFieldColorConfiguration: DisabledSurfaceColorable { + var success = SurfaceColorConfiguration() + var error = SurfaceColorConfiguration() + var disabled = SurfaceColorConfiguration() + var enabled = SurfaceColorConfiguration() + + required init(){} + + func getColor(_ viewModel: ModelType) -> UIColor { //only show error is enabled and showError == true let showErrorColor = !viewModel.disabled && viewModel.showError let showSuccessColor = !viewModel.disabled && viewModel.showSuccess @@ -168,10 +173,12 @@ open class TextEntryFieldBase: EntryField Date: Wed, 2 Nov 2022 10:07:42 -0500 Subject: [PATCH 19/23] refatored entry field/textField, still not done but now these don't have models Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 8 - .../TextFields/EntryField/EntryField.swift | 142 +++++++++++------- .../EntryField/EntryFieldModel.swift | 84 ----------- .../TextEntryField/TextEntryField.swift | 52 ++++--- .../TextEntryField/TextEntryFieldModel.swift | 64 -------- 5 files changed, 114 insertions(+), 236 deletions(-) delete mode 100644 VDS/Components/TextFields/EntryField/EntryFieldModel.swift delete mode 100644 VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index ba4fe7f6..55652d7c 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -58,8 +58,6 @@ EAB1D2EA28AE84AA00DAE764 /* UIControlPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB1D2E928AE84AA00DAE764 /* UIControlPublisher.swift */; }; EAC925842911C63100091998 /* Colorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEDF28F49DB3003B3210 /* Colorable.swift */; }; EAC9258C2911C9DE00091998 /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC925872911C9DE00091998 /* TextEntryField.swift */; }; - EAC9258D2911C9DE00091998 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC925882911C9DE00091998 /* TextEntryFieldModel.swift */; }; - EAC9258E2911C9DE00091998 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9258A2911C9DE00091998 /* EntryFieldModel.swift */; }; EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9258B2911C9DE00091998 /* EntryField.swift */; }; EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; }; EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0932899861000B287F5 /* Checkbox.swift */; }; @@ -144,8 +142,6 @@ EAB1D2E328AE842000DAE764 /* Publisher+Bind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Publisher+Bind.swift"; sourceTree = ""; }; EAB1D2E928AE84AA00DAE764 /* UIControlPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControlPublisher.swift; sourceTree = ""; }; EAC925872911C9DE00091998 /* TextEntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; - EAC925882911C9DE00091998 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = ""; }; - EAC9258A2911C9DE00091998 /* EntryFieldModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = ""; }; EAC9258B2911C9DE00091998 /* EntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = ""; }; EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = ""; }; EAF7F0932899861000B287F5 /* Checkbox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = ""; }; @@ -428,7 +424,6 @@ isa = PBXGroup; children = ( EAC925872911C9DE00091998 /* TextEntryField.swift */, - EAC925882911C9DE00091998 /* TextEntryFieldModel.swift */, ); path = TextEntryField; sourceTree = ""; @@ -436,7 +431,6 @@ EAC925892911C9DE00091998 /* EntryField */ = { isa = PBXGroup; children = ( - EAC9258A2911C9DE00091998 /* EntryFieldModel.swift */, EAC9258B2911C9DE00091998 /* EntryField.swift */, ); path = EntryField; @@ -599,7 +593,6 @@ EA89201328B568D8006B9984 /* RadioBox.swift in Sources */, EAC9258C2911C9DE00091998 /* TextEntryField.swift in Sources */, EA3362402892EF6C0071C351 /* Label.swift in Sources */, - EAC9258D2911C9DE00091998 /* TextEntryFieldModel.swift in Sources */, EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */, EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */, EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */, @@ -631,7 +624,6 @@ EAF7F09E289AAEC000B287F5 /* Constants.swift in Sources */, EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */, EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */, - EAC9258E2911C9DE00091998 /* EntryFieldModel.swift in Sources */, EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */, EAF7F0AB289B13FD00B287F5 /* FontLabelAttribute.swift in Sources */, EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */, diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index e9945c13..f0be2f88 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -15,7 +15,7 @@ public enum HelperTextPlacement: String, CaseIterable { case bottom, right } -open class EntryField: Control { +open class EntryField: Control, Accessable { //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -93,34 +93,45 @@ open class EntryField: Control { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- - open var labelText: String? + open var labelText: String? { didSet { didChange() }} - open var helperText: String? + open var helperText: String? { didSet { didChange() }} - open var showError: Bool + open var showError: Bool = false { didSet { didChange() }} - open var errorText: String? + open var errorText: String? { didSet { didChange() }} - open var tooltipTitle: String? + open var tooltipTitle: String? { didSet { didChange() }} - open var tooltipContent: String? + open var tooltipContent: String? { didSet { didChange() }} - open var transparentBackground: Bool + open var transparentBackground: Bool = false { didSet { didChange() }} - open var width: CGFloat? + open var width: CGFloat? { didSet { didChange() }} - open var maxLength: Int? + open var maxLength: Int? { didSet { didChange() }} - open var inputId: String? + open var inputId: String? { didSet { didChange() }} - open var value: AnyHashable? + open var value: AnyHashable? { didSet { didChange() }} - open var defaultValue: AnyHashable? + open var defaultValue: AnyHashable? { didSet { didChange() }} - open var required: Bool + open var required: Bool = false { didSet { didChange() }} - open var readOnly: Bool + open var readOnly: Bool = false { didSet { didChange() }} + open var accessibilityHintEnabled: String? { didSet { didChange() }} + + open var accessibilityHintDisabled: String? { didSet { didChange() }} + + open var accessibilityValueEnabled: String? { didSet { didChange() }} + + open var accessibilityValueDisabled: String? { didSet { didChange() }} + + open var accessibilityLabelEnabled: String? { didSet { didChange() }} + + open var accessibilityLabelDisabled: String? { didSet { didChange() }} //-------------------------------------------------- // MARK: - Constraints @@ -199,10 +210,11 @@ open class EntryField: Control { }.eraseToAnyColorable() } - open func getToolTipView(viewModel: ModelType) -> UIView? { - guard let toolTipTitleModel = viewModel.tooltipTitleModel, let toolTipContentModel = viewModel.tooltipContentModel else { + open func getToolTipView() -> UIView? { + guard let tooltipTitle, let tooltipContent else { return nil } + let stack = UIStackView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.axis = .vertical @@ -212,18 +224,26 @@ open class EntryField: Control { let title = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) + $0.textPosition = .left + $0.typograpicalStyle = .BoldBodySmall + $0.text = tooltipTitle + $0.surface = surface + $0.disabled = disabled } - title.set(with: toolTipTitleModel) let content = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) + $0.textPosition = .left + $0.typograpicalStyle = .BoldBodySmall + $0.text = tooltipContent + $0.surface = surface + $0.disabled = disabled } - content.set(with: toolTipContentModel) stack.addArrangedSubview(title) stack.addArrangedSubview(content) - stack.backgroundColor = backgroundColorConfiguration.getColor(viewModel) + stack.backgroundColor = backgroundColorConfiguration.getColor(self) return stack } @@ -240,33 +260,36 @@ open class EntryField: Control { //-------------------------------------------------- // MARK: - State //-------------------------------------------------- - open override func updateView(viewModel: ModelType) { + open override func updateView() { - containerView.backgroundColor = backgroundColorConfiguration.getColor(viewModel) - containerView.layer.borderColor = borderColorConfiguration.getColor(viewModel).cgColor + containerView.backgroundColor = backgroundColorConfiguration.getColor(self) + containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor containerView.layer.borderWidth = 1 containerView.layer.cornerRadius = 4 - updateTitleLabel(viewModel: viewModel) - updateErrorLabel(viewModel: viewModel) - updateHelperLabel(viewModel: viewModel) + updateTitleLabel() + updateErrorLabel() + updateHelperLabel() setAccessibilityHint() - backgroundColor = viewModel.surface.color + backgroundColor = surface.color setNeedsLayout() layoutIfNeeded() } - open func updateTitleLabel(viewModel: ModelType) { + open func updateTitleLabel() { + + //remove all attributes + titleLabel.attributes?.removeAll() + //update the title model if the required flag is false - var titleLabelModel = viewModel.labelModel - .addOptional(required: viewModel.required, colorConfiguration: secondaryColorConfig) + titleLabel.addOptional(required: required, colorConfiguration: secondaryColorConfig) //tooltip action - if let view = getToolTipView(viewModel: viewModel) { + if let view = getToolTipView() { tooltipView = view let toolTipAction = PassthroughSubject() - titleLabelModel = titleLabelModel.addToolTip(action: toolTipAction, colorConfiguration: primaryColorConfig) + titleLabel.addToolTip(action: toolTipAction, colorConfiguration: primaryColorConfig) toolTipAction.sink { [weak self] in self?.showToolTipView() }.store(in: &subscribers) @@ -274,22 +297,35 @@ open class EntryField: Control { tooltipView = nil } - titleLabel.set(with: titleLabelModel) + titleLabel.textPosition = .left + titleLabel.typograpicalStyle = .BodySmall + titleLabel.text = labelText + titleLabel.surface = surface + titleLabel.disabled = disabled + } - open func updateErrorLabel(viewModel: ModelType){ - if viewModel.showError, let errorLabelModel = viewModel.errorLabelModel { - errorLabel.set(with: errorLabelModel) + open func updateErrorLabel(){ + if showError, let errorText { + errorLabel.textPosition = .left + errorLabel.typograpicalStyle = .BodySmall + errorLabel.text = errorText + errorLabel.surface = surface + errorLabel.disabled = disabled errorLabel.isHidden = false } else { errorLabel.isHidden = true } } - open func updateHelperLabel(viewModel: ModelType){ + open func updateHelperLabel(){ //set the helper label position - if let helperLabelModel = viewModel.helperLabelModel { - helperLabel.set(with: helperLabelModel) + if let helperText { + helperLabel.textPosition = .left + helperLabel.typograpicalStyle = .BodySmall + helperLabel.text = helperText + helperLabel.surface = surface + helperLabel.disabled = disabled helperLabel.isHidden = false } else { helperLabel.isHidden = true @@ -320,32 +356,28 @@ internal class ErrorDisabledSurfaceColorConfiguration: DisabledSurfaceColorable } } -extension DefaultLabelModel { - public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { - guard let text = text, !required else { return self} - let optionColorAttr = ColorLabelAttribute(location: text.count + 2, +extension Label { + public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) { + guard let oldText = text, !required, !oldText.hasSuffix("Optional") else { return } + let optionColorAttr = ColorLabelAttribute(location: oldText.count + 2, length: 8, color: colorConfiguration.getColor(self)) - let newText = "\(text) Optional" - return copyWith { - $0.text = newText - $0.attributes = [optionColorAttr] - } + let newText = "\(oldText) Optional" + text = newText + attributes = [optionColorAttr] } - public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) -> DefaultLabelModel { - guard let text = text else { return self} + public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) { + guard let oldText = text else { return} var newAttributes = attributes ?? [] - let newText = "\(text) " //create a little space between the final character and tooltip image + let newText = "\(oldText) " //create a little space between the final character and tooltip image let toolTip = ToolTipLabelAttribute(action: action, location: newText.count, length: 1, tintColor: colorConfiguration.getColor(self)) newAttributes.append(toolTip) - return copyWith { - $0.text = newText - $0.attributes = newAttributes - } + text = newText + attributes = newAttributes } } diff --git a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift b/VDS/Components/TextFields/EntryField/EntryFieldModel.swift deleted file mode 100644 index f1ce6e22..00000000 --- a/VDS/Components/TextFields/EntryField/EntryFieldModel.swift +++ /dev/null @@ -1,84 +0,0 @@ -//// -//// EntryFieldModel.swift -//// VDS -//// -//// Created by Matt Bruce on 10/3/22. -//// -// -//import Foundation -// -//public enum HelperTextPlacement: String, CaseIterable { -// case bottom, right -//} -// -//public protocol EntryFieldModel: Modelable, FormFieldable, Errorable { -// var defaultVaue: AnyHashable? { get set } -// var required: Bool { get set } -// var readOnly: Bool { get set } -// var labelText: String? { get set } -// var helperText: String? { get set } -// var helperTextPlacement: HelperTextPlacement { get set } -// var transparentBackground: Bool { get set } -// var width: CGFloat? { get set } -// var maxLength: Int? { get set } -// var tooltipTitle: String? { get set } -// var tooltipContent: String? { get set } -//} -// -//extension EntryFieldModel { -// -// public var labelModel: DefaultLabelModel { -// var model = DefaultLabelModel() -// model.textPosition = .left -// model.typograpicalStyle = .BodySmall -// model.text = labelText -// model.surface = surface -// model.disabled = disabled -// return model -// } -// -// public var helperLabelModel: DefaultLabelModel? { -// guard let helperText else { return nil } -// var model = DefaultLabelModel() -// model.textPosition = .left -// model.typograpicalStyle = .BodySmall -// model.text = helperText -// model.surface = surface -// model.disabled = disabled -// return model -// } -// -// public var errorLabelModel: DefaultLabelModel? { -// guard let errorText else { return nil } -// var model = DefaultLabelModel() -// model.textPosition = .left -// model.typograpicalStyle = .BodySmall -// model.text = errorText -// model.surface = surface -// model.disabled = disabled -// return model -// } -// -// public var tooltipTitleModel: DefaultLabelModel? { -// guard let tooltipTitle else { return nil } -// var model = DefaultLabelModel() -// model.textPosition = .left -// model.typograpicalStyle = .BodySmall -// model.text = tooltipTitle -// model.surface = surface -// model.disabled = disabled -// return model -// } -// -// public var tooltipContentModel: DefaultLabelModel? { -// guard let tooltipContent else { return nil } -// var model = DefaultLabelModel() -// model.textPosition = .left -// model.typograpicalStyle = .BodySmall -// model.text = tooltipContent -// model.surface = surface -// model.disabled = disabled -// return model -// } -// -//} diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift index 2c19fc33..7fc10471 100644 --- a/VDS/Components/TextFields/TextEntryField/TextEntryField.swift +++ b/VDS/Components/TextFields/TextEntryField/TextEntryField.swift @@ -49,13 +49,13 @@ open class TextEntryFieldBase: EntryField { // MARK: - Public Properties //-------------------------------------------------- - public var type: TextEntryFieldType + open var type: TextEntryFieldType = .text { didSet { didChange() }} - open var showSuccess: Bool + open var showSuccess: Bool = false { didSet { didChange() }} - open var successText: String? + open var successText: String? { didSet { didChange() }} - open var helperTextPlacement: HelperTextPlacement + open var helperTextPlacement: HelperTextPlacement = .bottom { didSet { didChange() }} private var successLabel = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) @@ -117,15 +117,19 @@ open class TextEntryFieldBase: EntryField { //-------------------------------------------------- // MARK: - State //-------------------------------------------------- - open override func updateView(viewModel: ModelType) { - super.updateView(viewModel: viewModel) + open override func updateView() { + super.updateView() //show error or success - if viewModel.showError, let _ = viewModel.errorLabelModel { + if showError, let _ = errorText { successLabel.isHidden = true - } else if viewModel.showSuccess, let successLabelModel = viewModel.successLabelModel { - successLabel.set(with: successLabelModel) + } else if showSuccess, let successText { + successLabel.textPosition = .left + successLabel.typograpicalStyle = .BodySmall + successLabel.text = successText + successLabel.surface = surface + successLabel.disabled = disabled successLabel.isHidden = false errorLabel.isHidden = true @@ -135,23 +139,26 @@ open class TextEntryFieldBase: EntryField { } //set the width constraints - if let width = viewModel.width, width > viewModel.type.width { + if let width, width > type.width { widthConstraint?.constant = width widthConstraint?.isActive = true minWidthConstraint?.isActive = false } else { - minWidthConstraint?.constant = viewModel.type.width + minWidthConstraint?.constant = type.width widthConstraint?.isActive = false minWidthConstraint?.isActive = true } } - open override func updateHelperLabel(viewModel: ModelType){ + open override func updateHelperLabel(){ + //remove first helperLabel.removeFromSuperview() + + super.updateHelperLabel() //set the helper label position - if let helperLabelModel = viewModel.helperLabelModel { - if viewModel.helperTextPlacement == .right { + if helperText != nil { + if helperTextPlacement == .right { containerStackView.spacing = 12 containerStackView.distribution = .fillEqually containerStackView.addArrangedSubview(helperLabel) @@ -160,10 +167,6 @@ open class TextEntryFieldBase: EntryField { containerStackView.distribution = .fill stackView.addArrangedSubview(helperLabel) } - helperLabel.set(with: helperLabelModel) - helperLabel.isHidden = false - } else { - helperLabel.isHidden = true } } @@ -175,22 +178,21 @@ open class TextEntryFieldBase: EntryField { required init(){} - func getColor(_ viewModel: ModelType) -> UIColor { + func getColor(_ object: TextEntryField) -> UIColor { //only show error is enabled and showError == true - let showErrorColor = !viewModel.disabled && viewModel.showError - let showSuccessColor = !viewModel.disabled && viewModel.showSuccess + let showErrorColor = !object.disabled && object.showError + let showSuccessColor = !object.disabled && object.showSuccess if showErrorColor { - return error.getColor(viewModel) + return error.getColor(object) } else if showSuccessColor { - return success.getColor(viewModel) + return success.getColor(object) } else { - return getDisabledColor(viewModel) + return getDisabledColor(object) } } - } } diff --git a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift b/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift deleted file mode 100644 index 064f8636..00000000 --- a/VDS/Components/TextFields/TextEntryField/TextEntryFieldModel.swift +++ /dev/null @@ -1,64 +0,0 @@ -//// -//// TextEntryFieldModel.swift -//// VDS -//// -//// Created by Matt Bruce on 10/3/22. -//// -// -//import Foundation -// -// -//public protocol TextEntryFieldModel: EntryFieldModel { -// var type: TextEntryFieldType { get set } -// var showSuccess: Bool { get set } -// var successText: String? { get set } -//} -// -//extension TextEntryFieldModel { -// -// public var successLabelModel: DefaultLabelModel? { -// var model = DefaultLabelModel() -// model.textPosition = .left -// model.typograpicalStyle = .BodySmall -// model.text = successText -// model.surface = surface -// model.disabled = disabled -// return model -// } -// -//} -// -// -//public struct DefaultTextEntryField: TextEntryFieldModel { -// public var id = UUID() -// public var inputId: String? -// -// public var type: TextEntryFieldType = .text -// public var value: AnyHashable? -// public var defaultVaue: AnyHashable? -// public var required: Bool = false -// public var readOnly: Bool = false -// -// public var labelText: String? -// -// public var helperText: String? -// public var helperTextPlacement: HelperTextPlacement = .bottom -// -// public var showError: Bool = false -// public var errorText: String? -// -// public var showSuccess: Bool = false -// public var successText: String? -// -// public var transparentBackground: Bool = false -// public var width: CGFloat? -// public var maxLength: Int? -// -// public var tooltipTitle: String? -// public var tooltipContent: String? -// -// public var surface: Surface = .light -// public var disabled: Bool = false -// -// public init() { } -//} From 85337833d455e1b5ecabebe345431793cb3f5109 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Nov 2022 11:04:34 -0500 Subject: [PATCH 20/23] refactored out layout subviews, causing infinite loop Signed-off-by: Matt Bruce --- VDS/Classes/Control.swift | 6 +----- VDS/Classes/View.swift | 6 +----- VDS/Components/Button/Button.swift | 21 ++++++++++----------- VDS/Components/Label/Label.swift | 28 ++++++++++++++-------------- VDS/Protocols/Handlerable.swift | 7 ++++++- 5 files changed, 32 insertions(+), 36 deletions(-) diff --git a/VDS/Classes/Control.swift b/VDS/Classes/Control.swift index 79a26591..e068d5db 100644 --- a/VDS/Classes/Control.swift +++ b/VDS/Classes/Control.swift @@ -66,6 +66,7 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable { if !initialSetupPerformed { initialSetupPerformed = true setup() + setupDidChangeEvent() } } @@ -79,11 +80,6 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable { //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- - open override func layoutSubviews() { - super.layoutSubviews() - updateView() - } - open func updateView() {} open func reset() { diff --git a/VDS/Classes/View.swift b/VDS/Classes/View.swift index 1a08301a..7ead2431 100644 --- a/VDS/Classes/View.swift +++ b/VDS/Classes/View.swift @@ -65,14 +65,10 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable { if !initialSetupPerformed { initialSetupPerformed = true setup() + setupDidChangeEvent() } } - open override func layoutSubviews() { - super.layoutSubviews() - updateView() - } - //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- diff --git a/VDS/Components/Button/Button.swift b/VDS/Components/Button/Button.swift index 0d5ed7d5..c21802fd 100644 --- a/VDS/Components/Button/Button.swift +++ b/VDS/Components/Button/Button.swift @@ -31,7 +31,8 @@ open class Button: UIButton, Handlerable, ViewProtocol, Resettable, Useable { private var minWidthConstraint: NSLayoutConstraint? private var widthConstraint: NSLayoutConstraint? private var heightConstraint: NSLayoutConstraint? - + private var initialSetupPerformed = false + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -120,11 +121,14 @@ open class Button: UIButton, Handlerable, ViewProtocol, Resettable, Useable { // MARK: - Public Functions //-------------------------------------------------- open func initialSetup() { - backgroundColor = .clear - translatesAutoresizingMaskIntoConstraints = false - accessibilityCustomActions = [] - accessibilityTraits = .staticText - setup() + if !initialSetupPerformed { + backgroundColor = .clear + translatesAutoresizingMaskIntoConstraints = false + accessibilityCustomActions = [] + accessibilityTraits = .staticText + setup() + setupDidChangeEvent() + } } open func setup() { @@ -150,11 +154,6 @@ open class Button: UIButton, Handlerable, ViewProtocol, Resettable, Useable { accessibilityCustomActions = [] accessibilityTraits = .staticText } - - open override func layoutSubviews() { - super.layoutSubviews() - updateView() - } //-------------------------------------------------- // MARK: - Overrides diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 06f610f8..45b5997a 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -26,11 +26,13 @@ open class LabelBase: UILabel, Handlerable, ViewProtocol, Resettable { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- + private var initialSetupPerformed = false + open var surface: Surface = .light { didSet { didChange() }} open var disabled: Bool = false { didSet { isEnabled = !disabled } } - open var attributes: [any LabelAttributeModel]? { didSet { didChange() }} + open var attributes: [any LabelAttributeModel]? { didSet { didChange() }} open var typograpicalStyle: TypographicalStyle = .defaultStyle { didSet { didChange() }} @@ -85,13 +87,16 @@ open class LabelBase: UILabel, Handlerable, ViewProtocol, Resettable { // MARK: - Public Functions //-------------------------------------------------- open func initialSetup() { - backgroundColor = .clear - numberOfLines = 0 - lineBreakMode = .byWordWrapping - translatesAutoresizingMaskIntoConstraints = false - accessibilityCustomActions = [] - accessibilityTraits = .staticText - setup() + if !initialSetupPerformed { + backgroundColor = .clear + numberOfLines = 0 + lineBreakMode = .byWordWrapping + translatesAutoresizingMaskIntoConstraints = false + accessibilityCustomActions = [] + accessibilityTraits = .staticText + setup() + setupDidChangeEvent() + } } open func setup() {} @@ -111,12 +116,7 @@ open class LabelBase: UILabel, Handlerable, ViewProtocol, Resettable { //-------------------------------------------------- // MARK: - Overrides - //-------------------------------------------------- - open override func layoutSubviews() { - super.layoutSubviews() - updateView() - } - + //-------------------------------------------------- open func updateView() { textAlignment = textPosition.textAlignment textColor = textColorConfiguration.getColor(self) diff --git a/VDS/Protocols/Handlerable.swift b/VDS/Protocols/Handlerable.swift index 70c2508f..db3ad4ab 100644 --- a/VDS/Protocols/Handlerable.swift +++ b/VDS/Protocols/Handlerable.swift @@ -17,6 +17,12 @@ public protocol Handlerable: AnyObject, Initable, Disabling, Surfaceable { extension Handlerable { + public func setupDidChangeEvent() { + handlerPublisher().sink { [weak self] _ in + self?.updateView() + }.store(in: &subscribers) + } + public func handlerPublisher() -> AnyPublisher { subject .eraseToAnyPublisher() @@ -28,6 +34,5 @@ extension Handlerable { extension Handlerable where Self: UIView { public func didChange() { subject.send() - setNeedsLayout() } } From d611960ac8e36cbe4926d44d3f1a8cf615e88cdd Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Nov 2022 11:04:49 -0500 Subject: [PATCH 21/23] refactored entryfield Signed-off-by: Matt Bruce --- .../TextFields/EntryField/EntryField.swift | 64 ++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index f0be2f88..8ed3782d 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -44,6 +44,7 @@ open class EntryField: Control, Accessable { internal var titleLabel = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) + $0.attributes = [] } internal var errorLabel = Label().with { @@ -273,23 +274,36 @@ open class EntryField: Control, Accessable { setAccessibilityHint() backgroundColor = surface.color - setNeedsLayout() - layoutIfNeeded() } open func updateTitleLabel() { + + //update the local vars for the label since we no + //long have a model + var attributes: [any LabelAttributeModel] = [] + var updatedLabelText = labelText - //remove all attributes - titleLabel.attributes?.removeAll() + //dealing with the "Optional" addition to the text + if let oldText = updatedLabelText, !required, !oldText.hasSuffix("Optional") { + let optionColorAttr = ColorLabelAttribute(location: oldText.count + 2, + length: 8, + color: secondaryColorConfig.getColor(self)) + + updatedLabelText = "\(oldText) Optional" + attributes.append(optionColorAttr) + } - //update the title model if the required flag is false - titleLabel.addOptional(required: required, colorConfiguration: secondaryColorConfig) - - //tooltip action - if let view = getToolTipView() { + //add the tool tip + if let view = getToolTipView(), let oldText = updatedLabelText { tooltipView = view let toolTipAction = PassthroughSubject() - titleLabel.addToolTip(action: toolTipAction, colorConfiguration: primaryColorConfig) + let toolTipUpdateText = "\(oldText) " //create a little space between the final character and tooltip image + let toolTipAttribute = ToolTipLabelAttribute(action: toolTipAction, + location: toolTipUpdateText.count, + length: 1, + tintColor: primaryColorConfig.getColor(self)) + updatedLabelText = toolTipUpdateText + attributes.append(toolTipAttribute) toolTipAction.sink { [weak self] in self?.showToolTipView() }.store(in: &subscribers) @@ -297,9 +311,11 @@ open class EntryField: Control, Accessable { tooltipView = nil } + //set the titleLabel titleLabel.textPosition = .left titleLabel.typograpicalStyle = .BodySmall - titleLabel.text = labelText + titleLabel.text = updatedLabelText + titleLabel.attributes = attributes titleLabel.surface = surface titleLabel.disabled = disabled @@ -355,29 +371,3 @@ internal class ErrorDisabledSurfaceColorConfiguration: DisabledSurfaceColorable } } } - -extension Label { - public func addOptional(required: Bool, colorConfiguration: DisabledSurfaceColorConfiguration) { - guard let oldText = text, !required, !oldText.hasSuffix("Optional") else { return } - let optionColorAttr = ColorLabelAttribute(location: oldText.count + 2, - length: 8, - color: colorConfiguration.getColor(self)) - - let newText = "\(oldText) Optional" - text = newText - attributes = [optionColorAttr] - } - - public func addToolTip(action: PassthroughSubject, colorConfiguration: DisabledSurfaceColorConfiguration) { - guard let oldText = text else { return} - var newAttributes = attributes ?? [] - let newText = "\(oldText) " //create a little space between the final character and tooltip image - let toolTip = ToolTipLabelAttribute(action: action, - location: newText.count, - length: 1, - tintColor: colorConfiguration.getColor(self)) - newAttributes.append(toolTip) - text = newText - attributes = newAttributes - } -} From 5c21e5469f64ec4df1df5126f3ed88653b2d9c2d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Nov 2022 11:06:43 -0500 Subject: [PATCH 22/23] adding print Signed-off-by: Matt Bruce --- VDS/Components/TextFields/EntryField/EntryField.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index 8ed3782d..88e4e7ed 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -250,7 +250,7 @@ open class EntryField: Control, Accessable { } open func showToolTipView(){ - + print("toolTip clicked: showToolTipView() called") } public override func reset() { From 53b43c6daf200bf2d5d60d7b570edc8dcc0d959d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Nov 2022 11:11:39 -0500 Subject: [PATCH 23/23] execute updateView() after setup Signed-off-by: Matt Bruce --- VDS/Classes/Control.swift | 1 + VDS/Classes/View.swift | 3 ++- VDS/Components/Button/Button.swift | 1 + VDS/Components/Label/Label.swift | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/VDS/Classes/Control.swift b/VDS/Classes/Control.swift index e068d5db..0f7a2631 100644 --- a/VDS/Classes/Control.swift +++ b/VDS/Classes/Control.swift @@ -67,6 +67,7 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable { initialSetupPerformed = true setup() setupDidChangeEvent() + updateView() } } diff --git a/VDS/Classes/View.swift b/VDS/Classes/View.swift index 7ead2431..837d81a8 100644 --- a/VDS/Classes/View.swift +++ b/VDS/Classes/View.swift @@ -66,7 +66,8 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable { initialSetupPerformed = true setup() setupDidChangeEvent() - } + updateView() + } } //-------------------------------------------------- diff --git a/VDS/Components/Button/Button.swift b/VDS/Components/Button/Button.swift index c21802fd..4a065e3e 100644 --- a/VDS/Components/Button/Button.swift +++ b/VDS/Components/Button/Button.swift @@ -128,6 +128,7 @@ open class Button: UIButton, Handlerable, ViewProtocol, Resettable, Useable { accessibilityTraits = .staticText setup() setupDidChangeEvent() + updateView() } } diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 45b5997a..449c9c80 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -96,7 +96,8 @@ open class LabelBase: UILabel, Handlerable, ViewProtocol, Resettable { accessibilityTraits = .staticText setup() setupDidChangeEvent() - } + updateView() + } } open func setup() {}