updated states
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
cfc21c2727
commit
1813661f7d
@ -83,6 +83,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
open var rules = [AnyRule<String>]()
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Configuration Properties
|
// MARK: - Configuration Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -103,11 +105,13 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
$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])
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forState: [.focused, .error])
|
||||||
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
|
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
|
||||||
$0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error)
|
$0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error)
|
||||||
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.disabled,.error])
|
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.disabled,.error])
|
||||||
@ -159,7 +163,10 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
internal var validator: (any FormFieldValidatorable)?
|
internal var validator: (any FormFieldValidatorable)?
|
||||||
|
|
||||||
/// Whether or not to show the internal error
|
/// Whether or not to show the internal error
|
||||||
open var hasInternalError: Bool { !(validator?.isValid ?? true) }
|
open var hasInternalError: Bool {
|
||||||
|
guard let validator, !showError else { return false }
|
||||||
|
return !validator.isValid
|
||||||
|
}
|
||||||
|
|
||||||
/// 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 {
|
||||||
@ -304,6 +311,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
/// Used to make changes to the View based off a change events or from local properties.
|
/// Used to make changes to the View based off a change events or from local properties.
|
||||||
open override func updateView() {
|
open override func updateView() {
|
||||||
super.updateView()
|
super.updateView()
|
||||||
|
updateRules()
|
||||||
|
validator = FormFieldValidator<EntryFieldBase>(field: self, rules: rules)
|
||||||
|
|
||||||
updateContainerView()
|
updateContainerView()
|
||||||
updateTitleLabel()
|
updateTitleLabel()
|
||||||
@ -311,8 +320,21 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
updateHelperLabel()
|
updateHelperLabel()
|
||||||
|
|
||||||
backgroundColor = surface.color
|
backgroundColor = surface.color
|
||||||
validator?.validate()
|
|
||||||
internalErrorText = validator?.errorMessage
|
if let validator {
|
||||||
|
validator.validate()
|
||||||
|
if validator.isValid {
|
||||||
|
internalErrorText = nil
|
||||||
|
} else {
|
||||||
|
if let errorText, errorText.isEmpty {
|
||||||
|
internalErrorText = errorText
|
||||||
|
} else {
|
||||||
|
internalErrorText = validator.errorMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
internalErrorText = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -338,6 +360,21 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
return bottomContainerView
|
return bottomContainerView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal func updateRules() {
|
||||||
|
rules.removeAll()
|
||||||
|
if self.required {
|
||||||
|
let rule = RequiredRule()
|
||||||
|
if let errorText {
|
||||||
|
rule.errorMessage = errorText
|
||||||
|
} else if let labelText{
|
||||||
|
rule.errorMessage = "You must enter a \(labelText)"
|
||||||
|
} else {
|
||||||
|
rule.errorMessage = "You must enter a value"
|
||||||
|
}
|
||||||
|
rules.append(.init(rule))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -369,22 +406,14 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func updateErrorLabel(){
|
open func updateErrorLabel(){
|
||||||
if showError, hasInternalError, let errorText, let internalErrorText {
|
if showError, let errorText {
|
||||||
errorLabel.text = [internalErrorText, errorText].joined(separator: "\n")
|
|
||||||
errorLabel.surface = surface
|
|
||||||
errorLabel.isEnabled = isEnabled
|
|
||||||
errorLabel.isHidden = false
|
|
||||||
statusIcon.name = .error
|
|
||||||
statusIcon.surface = surface
|
|
||||||
statusIcon.isHidden = !isEnabled
|
|
||||||
} else if showError, let errorText {
|
|
||||||
errorLabel.text = errorText
|
errorLabel.text = errorText
|
||||||
errorLabel.surface = surface
|
errorLabel.surface = surface
|
||||||
errorLabel.isEnabled = isEnabled
|
errorLabel.isEnabled = isEnabled
|
||||||
errorLabel.isHidden = false
|
errorLabel.isHidden = false
|
||||||
statusIcon.name = .error
|
statusIcon.name = .error
|
||||||
statusIcon.surface = surface
|
statusIcon.surface = surface
|
||||||
statusIcon.isHidden = !isEnabled
|
statusIcon.isHidden = !isEnabled || state.contains(.focused)
|
||||||
} else if hasInternalError, let internalErrorText {
|
} else if hasInternalError, let internalErrorText {
|
||||||
errorLabel.text = internalErrorText
|
errorLabel.text = internalErrorText
|
||||||
errorLabel.surface = surface
|
errorLabel.surface = surface
|
||||||
@ -392,7 +421,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
errorLabel.isHidden = false
|
errorLabel.isHidden = false
|
||||||
statusIcon.name = .error
|
statusIcon.name = .error
|
||||||
statusIcon.surface = surface
|
statusIcon.surface = surface
|
||||||
statusIcon.isHidden = !isEnabled
|
statusIcon.isHidden = !isEnabled || state.contains(.focused)
|
||||||
} else {
|
} else {
|
||||||
statusIcon.isHidden = true
|
statusIcon.isHidden = true
|
||||||
errorLabel.isHidden = true
|
errorLabel.isHidden = true
|
||||||
|
|||||||
@ -210,13 +210,15 @@ open class InputField: EntryFieldBase {
|
|||||||
|
|
||||||
/// Used to make changes to the View based off a change events or from local properties.
|
/// Used to make changes to the View based off a change events or from local properties.
|
||||||
open override func updateView() {
|
open override func updateView() {
|
||||||
|
|
||||||
|
//update fieldType first
|
||||||
|
updateFieldType()
|
||||||
|
|
||||||
super.updateView()
|
super.updateView()
|
||||||
|
|
||||||
textField.isEnabled = isEnabled
|
textField.isEnabled = isEnabled
|
||||||
textField.textColor = textFieldTextColorConfiguration.getColor(self)
|
textField.textColor = textFieldTextColorConfiguration.getColor(self)
|
||||||
|
|
||||||
updateFieldType()
|
|
||||||
|
|
||||||
//show error or success
|
//show error or success
|
||||||
if showError, let _ = errorText {
|
if showError, let _ = errorText {
|
||||||
successLabel.isHidden = true
|
successLabel.isHidden = true
|
||||||
@ -264,6 +266,15 @@ open class InputField: EntryFieldBase {
|
|||||||
var actionModel: InputField.TextLinkModel?
|
var actionModel: InputField.TextLinkModel?
|
||||||
var toolTipModel: Tooltip.TooltipModel? = tooltipModel
|
var toolTipModel: Tooltip.TooltipModel? = tooltipModel
|
||||||
var isSecureTextEntry = false
|
var isSecureTextEntry = false
|
||||||
|
var rules = [AnyRule<String>]()
|
||||||
|
|
||||||
|
if self.required {
|
||||||
|
let rule = RequiredRule()
|
||||||
|
if let errorText {
|
||||||
|
rule.errorMessage = errorText
|
||||||
|
}
|
||||||
|
rules.append(.init(rule))
|
||||||
|
}
|
||||||
|
|
||||||
switch fieldType {
|
switch fieldType {
|
||||||
case .text:
|
case .text:
|
||||||
|
|||||||
@ -83,7 +83,7 @@ open class TextArea: EntryFieldBase {
|
|||||||
open override var state: UIControl.State {
|
open override var state: UIControl.State {
|
||||||
get {
|
get {
|
||||||
var state = super.state
|
var state = super.state
|
||||||
if textView.isFirstResponder && !showError && !hasInternalError {
|
if textView.isFirstResponder {
|
||||||
state.insert(.focused)
|
state.insert(.focused)
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
@ -162,8 +162,6 @@ open class TextArea: EntryFieldBase {
|
|||||||
open override func setup() {
|
open override func setup() {
|
||||||
super.setup()
|
super.setup()
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
validator = FormFieldValidator<TextArea>(field: self, rules: [.init(countRule)])
|
|
||||||
|
|
||||||
containerStackView.pinToSuperView(.uniform(VDSFormControls.spaceInset))
|
containerStackView.pinToSuperView(.uniform(VDSFormControls.spaceInset))
|
||||||
minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: containerSize.width)
|
minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: containerSize.width)
|
||||||
minWidthConstraint?.isActive = true
|
minWidthConstraint?.isActive = true
|
||||||
@ -229,6 +227,12 @@ open class TextArea: EntryFieldBase {
|
|||||||
highlightCharacterOverflow()
|
highlightCharacterOverflow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func updateRules() {
|
||||||
|
super.updateRules()
|
||||||
|
|
||||||
|
rules.append(.init(countRule))
|
||||||
|
}
|
||||||
|
|
||||||
/// Container for the area showing helper text, error text, character count, maximum length value.
|
/// Container for the area showing helper text, error text, character count, maximum length value.
|
||||||
open override func getBottomContainer() -> UIView {
|
open override func getBottomContainer() -> UIView {
|
||||||
bottomStackView.addArrangedSubview(bottomContainerView)
|
bottomStackView.addArrangedSubview(bottomContainerView)
|
||||||
@ -293,16 +297,6 @@ open class TextArea: EntryFieldBase {
|
|||||||
// MARK: - Validation
|
// MARK: - Validation
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
var countRule = CharacterCountRule()
|
var countRule = CharacterCountRule()
|
||||||
|
|
||||||
class CharacterCountRule: Rule {
|
|
||||||
var maxLength: Int?
|
|
||||||
var errorMessage: String = "You have exceeded the character limit."
|
|
||||||
|
|
||||||
func isValid(value: String?) -> Bool {
|
|
||||||
guard let text = value, let maxLength, maxLength > 0 else { return true }
|
|
||||||
return text.count <= maxLength
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TextArea: UITextViewDelegate {
|
extension TextArea: UITextViewDelegate {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user