From 2f0600eafbeaa3f208b9d66bb3c2c7b401c0abed Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Nov 2022 10:07:42 -0500 Subject: [PATCH] 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() { } -//}