fixed issue with showing errorIcon without error message

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-07-11 10:53:41 -05:00
parent d943202e83
commit 46d4098cf2

View File

@ -28,7 +28,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Enums // MARK: - Enums
//-------------------------------------------------- //--------------------------------------------------
@ -91,7 +91,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
$0.spacing = VDSLayout.space2X $0.spacing = VDSLayout.space2X
} }
}() }()
/// This is the view that will be wrapped with the border for userInteraction. /// This is the view that will be wrapped with the border for userInteraction.
/// The only subview of this view is the fieldStackView /// The only subview of this view is the fieldStackView
internal var containerView = View().with { internal var containerView = View().with {
@ -115,7 +115,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
internal var widthConstraint: NSLayoutConstraint? internal var widthConstraint: NSLayoutConstraint?
internal var trailingEqualsConstraint: NSLayoutConstraint? internal var trailingEqualsConstraint: NSLayoutConstraint?
internal var trailingLessThanEqualsConstraint: NSLayoutConstraint? internal var trailingLessThanEqualsConstraint: NSLayoutConstraint?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Configuration Properties // MARK: - Configuration Properties
//-------------------------------------------------- //--------------------------------------------------
@ -133,14 +133,14 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forDisabled: false) $0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forDisabled: false)
} }
internal var backgroundColorConfiguration = ControlColorConfiguration().with { internal var backgroundColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .normal) $0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .normal)
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .disabled) $0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: .error) $0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: .error)
$0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: [.error, .focused]) $0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: [.error, .focused])
} }
internal var borderColorConfiguration = ControlColorConfiguration().with { internal var borderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal) $0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forState: .focused) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forState: .focused)
@ -155,7 +155,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .error) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .error)
} }
internal var readOnlyBorderColorConfiguration = ControlColorConfiguration().with { internal var readOnlyBorderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderReadonlyOnlight, VDSFormControlsColor.borderReadonlyOndark, forState: .normal) $0.setSurfaceColors(VDSFormControlsColor.borderReadonlyOnlight, VDSFormControlsColor.borderReadonlyOndark, forState: .normal)
} }
@ -164,7 +164,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
// MARK: - Public Properties // MARK: - Public Properties
//-------------------------------------------------- //--------------------------------------------------
open var onChangeSubscriber: AnyCancellable? open var onChangeSubscriber: AnyCancellable?
open var titleLabel = Label().with { open var titleLabel = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical) $0.setContentCompressionResistancePriority(.required, for: .vertical)
$0.textStyle = .bodySmall $0.textStyle = .bodySmall
@ -185,7 +185,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
$0.size = .medium $0.size = .medium
$0.isAccessibilityElement = true $0.isAccessibilityElement = true
} }
open var labelText: String? { didSet { setNeedsUpdate() } } open var labelText: String? { didSet { setNeedsUpdate() } }
open var helperText: String? { didSet { setNeedsUpdate() } } open var helperText: String? { didSet { setNeedsUpdate() } }
@ -195,7 +195,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
/// FormFieldValidator /// FormFieldValidator
open var validator: (any FormFieldValidatorable)? open var validator: (any FormFieldValidatorable)?
/// Override UIControl state to add the .error state if showError is true. /// Override UIControl state to add the .error state if showError is true.
open override var state: UIControl.State { open override var state: UIControl.State {
get { get {
@ -214,17 +214,17 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
return state return state
} }
} }
open var errorText: String? { didSet { setNeedsUpdate() } } open var errorText: String? { didSet { setNeedsUpdate() } }
open var tooltipModel: Tooltip.TooltipModel? { didSet { setNeedsUpdate() } } open var tooltipModel: Tooltip.TooltipModel? { didSet { setNeedsUpdate() } }
open var transparentBackground: Bool = false { didSet { setNeedsUpdate() } } open var transparentBackground: Bool = false { didSet { setNeedsUpdate() } }
open var width: CGFloat? { didSet { setNeedsUpdate() } } open var width: CGFloat? { didSet { setNeedsUpdate() } }
open var inputId: String? { didSet { setNeedsUpdate() } } open var inputId: String? { didSet { setNeedsUpdate() } }
/// The text of this textField. /// The text of this textField.
open var value: String? { open var value: String? {
get { fatalError("must be read from subclass")} get { fatalError("must be read from subclass")}
@ -235,21 +235,21 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
open var isRequired: Bool = false { didSet { setNeedsUpdate() } } open var isRequired: Bool = false { didSet { setNeedsUpdate() } }
open var isReadOnly: Bool = false { didSet { setNeedsUpdate() } } open var isReadOnly: Bool = false { didSet { setNeedsUpdate() } }
open var helperTextPlacement: HelperTextPlacement = .bottom { open var helperTextPlacement: HelperTextPlacement = .bottom {
didSet { didSet {
updateHelperTextPosition() updateHelperTextPosition()
} }
} }
open var rules = [AnyRule<String>]() open var rules = [AnyRule<String>]()
open var accessibilityHintText: String = "Double tap to open" open var accessibilityHintText: String = "Double tap to open"
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Overrides // MARK: - Overrides
//-------------------------------------------------- //--------------------------------------------------
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() { open override func setup() {
super.setup() super.setup()
@ -371,7 +371,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
titleLabel.textStyle = .bodySmall titleLabel.textStyle = .bodySmall
errorLabel.textStyle = .bodySmall errorLabel.textStyle = .bodySmall
helperLabel.textStyle = .bodySmall helperLabel.textStyle = .bodySmall
labelText = nil labelText = nil
helperText = nil helperText = nil
showError = false showError = false
@ -389,19 +389,19 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
open override var canBecomeFirstResponder: Bool { open override var canBecomeFirstResponder: Bool {
responder?.canBecomeFirstResponder ?? super.canBecomeFirstResponder responder?.canBecomeFirstResponder ?? super.canBecomeFirstResponder
} }
open override func becomeFirstResponder() -> Bool { open override func becomeFirstResponder() -> Bool {
responder?.becomeFirstResponder() ?? super.becomeFirstResponder() responder?.becomeFirstResponder() ?? super.becomeFirstResponder()
} }
open override var canResignFirstResponder: Bool { open override var canResignFirstResponder: Bool {
responder?.canResignFirstResponder ?? super.canResignFirstResponder responder?.canResignFirstResponder ?? super.canResignFirstResponder
} }
open override func resignFirstResponder() -> Bool { open override func resignFirstResponder() -> Bool {
responder?.resignFirstResponder() ?? super.resignFirstResponder() responder?.resignFirstResponder() ?? super.resignFirstResponder()
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Public Methods // MARK: - Public Methods
//-------------------------------------------------- //--------------------------------------------------
@ -409,21 +409,21 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
open func getFieldContainer() -> UIView { open func getFieldContainer() -> UIView {
fatalError("Subclass must return the view that contains the field/view the user will interact with.") fatalError("Subclass must return the view that contains the field/view the user will interact with.")
} }
/// Container for the area in which helper or error text presents. /// Container for the area in which helper or error text presents.
open func getBottomContainer() -> UIView { open func getBottomContainer() -> UIView {
return bottomContainerStackView return bottomContainerStackView
} }
open func validate(){ open func validate(){
updateRules() updateRules()
validator = FormFieldValidator<EntryFieldBase>(field: self, rules: rules) validator = FormFieldValidator<EntryFieldBase>(field: self, rules: rules)
validator?.validate() validator?.validate()
setNeedsUpdate() setNeedsUpdate()
} }
open func updateTitleLabel() { open func updateTitleLabel() {
//update the local vars for the label since we no //update the local vars for the label since we no
//long have a model //long have a model
var attributes: [any LabelAttributeModel] = [] var attributes: [any LabelAttributeModel] = []
@ -444,36 +444,43 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
if let tooltipModel { if let tooltipModel {
attributes.append(TooltipLabelAttribute(surface: surface, model: tooltipModel, presenter: self)) attributes.append(TooltipLabelAttribute(surface: surface, model: tooltipModel, presenter: self))
} }
//set the titleLabel //set the titleLabel
titleLabel.text = updatedLabelText titleLabel.text = updatedLabelText
titleLabel.attributes = attributes titleLabel.attributes = attributes
titleLabel.surface = surface titleLabel.surface = surface
titleLabel.isEnabled = isEnabled titleLabel.isEnabled = isEnabled
} }
open func updateErrorLabel(){ open func updateErrorLabel(){
if showError, let errorText {
errorLabel.text = errorText /// always show the errorIcon if there is an error
errorLabel.surface = surface if showError || hasInternalError {
errorLabel.isEnabled = isEnabled
errorLabel.isHidden = false
statusIcon.name = .error
statusIcon.surface = surface
statusIcon.isHidden = !isEnabled || state.contains(.focused)
} else if hasInternalError, let internalErrorText {
errorLabel.text = internalErrorText
errorLabel.surface = surface
errorLabel.isEnabled = isEnabled
errorLabel.isHidden = false
statusIcon.name = .error statusIcon.name = .error
statusIcon.surface = surface statusIcon.surface = surface
statusIcon.isHidden = !isEnabled || state.contains(.focused) statusIcon.isHidden = !isEnabled || state.contains(.focused)
} else { } else {
statusIcon.isHidden = true statusIcon.isHidden = true
errorLabel.isHidden = true
} }
statusIcon.color = iconColorConfiguration.getColor(self) statusIcon.color = iconColorConfiguration.getColor(self)
// only show errorLabel if there is a message
var message: String?
if showError, let errorText {
message = errorText
} else if hasInternalError, let internalErrorText {
message = internalErrorText
}
if let message {
errorLabel.text = message
errorLabel.surface = surface
errorLabel.isEnabled = isEnabled
errorLabel.isHidden = false
} else {
errorLabel.isHidden = true
}
} }
open func updateHelperLabel(){ open func updateHelperLabel(){