initial generic entryfield
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
06b0c80a58
commit
c326213302
@ -6,7 +6,7 @@ import Combine
|
|||||||
/// A dropdown select is an expandable menu of predefined options that allows a customer to make a single selection.
|
/// A dropdown select is an expandable menu of predefined options that allows a customer to make a single selection.
|
||||||
@objcMembers
|
@objcMembers
|
||||||
@objc(VDSDatePicker)
|
@objc(VDSDatePicker)
|
||||||
open class DatePicker: EntryFieldBase {
|
open class DatePicker: EntryFieldBase<String> {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import Combine
|
|||||||
/// A dropdown select is an expandable menu of predefined options that allows a customer to make a single selection.
|
/// A dropdown select is an expandable menu of predefined options that allows a customer to make a single selection.
|
||||||
@objcMembers
|
@objcMembers
|
||||||
@objc(VDSDropdownSelect)
|
@objc(VDSDropdownSelect)
|
||||||
open class DropdownSelect: EntryFieldBase {
|
open class DropdownSelect: EntryFieldBase<String> {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -10,9 +10,10 @@ import UIKit
|
|||||||
import VDSCoreTokens
|
import VDSCoreTokens
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
/// A stepper is a two-segment control that people use to increase or decrease an incremental value.
|
/// A stepper is a two-segment control that people use to increase or decrease an incremental value.'
|
||||||
|
@objcMembers
|
||||||
@objc(VDSInputStepper)
|
@objc(VDSInputStepper)
|
||||||
open class InputStepper: EntryFieldBase {
|
open class InputStepper: EntryFieldBase<Int> {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
@ -70,6 +71,8 @@ open class InputStepper: EntryFieldBase {
|
|||||||
/// Allows an id to be passed to input stepper.
|
/// Allows an id to be passed to input stepper.
|
||||||
open var id: Int? { didSet { setNeedsUpdate() } }
|
open var id: Int? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
open override var value: Int? { return defaultValue }
|
||||||
|
|
||||||
/// Maximum value of the input stepper, defaults to '99'.
|
/// Maximum value of the input stepper, defaults to '99'.
|
||||||
open var maxValue: Int? = 99 {
|
open var maxValue: Int? = 99 {
|
||||||
didSet {
|
didSet {
|
||||||
@ -101,20 +104,9 @@ open class InputStepper: EntryFieldBase {
|
|||||||
/// Accepts any text or character to appear next to input stepper value.
|
/// Accepts any text or character to appear next to input stepper value.
|
||||||
open var trailingText: String? { didSet { setNeedsUpdate() } }
|
open var trailingText: String? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
/// Value for the textField
|
|
||||||
open override var value: String? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
/// Default Int value of the input stepper, defaults to '0'.
|
|
||||||
internal var defaultIntValue: Int {
|
|
||||||
guard let intValue = defaultValue as? Int else { return 0 }
|
|
||||||
return intValue
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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 stepperStackView.
|
/// The only subview of this view is the stepperStackView.
|
||||||
internal var stepperContainerView = View().with {
|
internal var stepperContainerView = View().with {
|
||||||
@ -186,6 +178,7 @@ open class InputStepper: EntryFieldBase {
|
|||||||
super.setup()
|
super.setup()
|
||||||
|
|
||||||
// Set initial states
|
// Set initial states
|
||||||
|
defaultValue = 0
|
||||||
containerView.isEnabled = false
|
containerView.isEnabled = false
|
||||||
statusIcon.isHidden = true
|
statusIcon.isHidden = true
|
||||||
|
|
||||||
@ -227,7 +220,7 @@ open class InputStepper: EntryFieldBase {
|
|||||||
statusIcon.isHidden = true
|
statusIcon.isHidden = true
|
||||||
|
|
||||||
// Update label text, style, color, ande surface.
|
// Update label text, style, color, ande surface.
|
||||||
textLabel.text = String(defaultIntValue) + " " + (trailingText ?? "")
|
textLabel.text = "\(value ?? 0) " + (trailingText ?? "")
|
||||||
textLabel.textStyle = size == .large ? .boldBodyLarge : .boldBodySmall
|
textLabel.textStyle = size == .large ? .boldBodyLarge : .boldBodySmall
|
||||||
textLabel.textColorConfiguration = !isEnabled ? labelDisabledColorConfiguration.eraseToAnyColorable() : labelColorConfiguration.eraseToAnyColorable()
|
textLabel.textColorConfiguration = !isEnabled ? labelDisabledColorConfiguration.eraseToAnyColorable() : labelColorConfiguration.eraseToAnyColorable()
|
||||||
textLabel.surface = surface
|
textLabel.surface = surface
|
||||||
@ -275,6 +268,7 @@ open class InputStepper: EntryFieldBase {
|
|||||||
controlWidthPercentage = nil
|
controlWidthPercentage = nil
|
||||||
widthPercentage = nil
|
widthPercentage = nil
|
||||||
id = nil
|
id = nil
|
||||||
|
defaultValue = 0
|
||||||
minValue = 0
|
minValue = 0
|
||||||
maxValue = 99
|
maxValue = 99
|
||||||
trailingText = nil
|
trailingText = nil
|
||||||
@ -314,18 +308,18 @@ open class InputStepper: EntryFieldBase {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
internal func checkDefaultValue() {
|
internal func checkDefaultValue() {
|
||||||
if let minValue, let maxValue {
|
if let minValue, let maxValue {
|
||||||
defaultValue = defaultIntValue > maxValue ? maxValue : defaultIntValue < minValue ? minValue : defaultIntValue
|
defaultValue = defaultValue! > maxValue ? maxValue : defaultValue! < minValue ? minValue : defaultValue!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func decrementButtonClick() {
|
internal func decrementButtonClick() {
|
||||||
defaultValue = defaultIntValue - 1
|
defaultValue = defaultValue! - 1
|
||||||
checkDefaultValue()
|
checkDefaultValue()
|
||||||
updateButtonStates()
|
updateButtonStates()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func incrementButtonClick() {
|
internal func incrementButtonClick() {
|
||||||
defaultValue = defaultIntValue + 1
|
defaultValue = defaultValue! + 1
|
||||||
checkDefaultValue()
|
checkDefaultValue()
|
||||||
updateButtonStates()
|
updateButtonStates()
|
||||||
}
|
}
|
||||||
@ -340,8 +334,8 @@ open class InputStepper: EntryFieldBase {
|
|||||||
decrementButton.isEnabled = false
|
decrementButton.isEnabled = false
|
||||||
incrementButton.isEnabled = false
|
incrementButton.isEnabled = false
|
||||||
} else {
|
} else {
|
||||||
decrementButton.isEnabled = defaultIntValue > minValue ?? 0 ? true : false
|
decrementButton.isEnabled = defaultValue! > minValue ?? 0 ? true : false
|
||||||
incrementButton.isEnabled = defaultIntValue < maxValue ?? 99 ? true : false
|
incrementButton.isEnabled = defaultValue! < maxValue ?? 99 ? true : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,10 +11,7 @@ import VDSCoreTokens
|
|||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
/// Base Class used to build out a Input controls.
|
/// Base Class used to build out a Input controls.
|
||||||
@objcMembers
|
open class EntryFieldBase<ValueType>: Control, Changeable, FormFieldInternalValidatable {
|
||||||
@objc(VDSEntryField)
|
|
||||||
open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -229,11 +226,11 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
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: ValueType? {
|
||||||
get { fatalError("must be read from subclass")}
|
get { fatalError("must be read from subclass")}
|
||||||
}
|
}
|
||||||
|
|
||||||
open var defaultValue: AnyHashable? { didSet { setNeedsUpdate() } }
|
open var defaultValue: ValueType? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
open var isRequired: Bool = false { didSet { setNeedsUpdate() } }
|
open var isRequired: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
@ -245,7 +242,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open var rules = [AnyRule<String>]()
|
open var rules = [AnyRule<ValueType>]()
|
||||||
|
|
||||||
open var accessibilityHintText: String = "Double tap to open"
|
open var accessibilityHintText: String = "Double tap to open"
|
||||||
|
|
||||||
@ -342,8 +339,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
containerView.bridge_accessibilityValueBlock = { [weak self] in
|
containerView.bridge_accessibilityValueBlock = { [weak self] in
|
||||||
guard let self else { return "" }
|
guard let self, let value else { return "" }
|
||||||
return value
|
return "\(value)"
|
||||||
}
|
}
|
||||||
|
|
||||||
statusIcon.bridge_accessibilityLabelBlock = { [weak self] in
|
statusIcon.bridge_accessibilityLabelBlock = { [weak self] in
|
||||||
@ -523,8 +520,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
internal func updateRules() {
|
internal func updateRules() {
|
||||||
rules.removeAll()
|
rules.removeAll()
|
||||||
if isRequired && useRequiredRule {
|
if isRequired && useRequiredRule && ValueType.self == String.self {
|
||||||
let rule = RequiredRule()
|
let rule = RequiredRule<ValueType>()
|
||||||
if let errorText, !errorText.isEmpty {
|
if let errorText, !errorText.isEmpty {
|
||||||
rule.errorMessage = errorText
|
rule.errorMessage = errorText
|
||||||
} else if let labelText{
|
} else if let labelText{
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import Combine
|
|||||||
/// dates and security codes in their correct formats.
|
/// dates and security codes in their correct formats.
|
||||||
@objcMembers
|
@objcMembers
|
||||||
@objc(VDSInputField)
|
@objc(VDSInputField)
|
||||||
open class InputField: EntryFieldBase {
|
open class InputField: EntryFieldBase<String> {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
|
|||||||
@ -7,12 +7,14 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class RequiredRule: Rule {
|
class RequiredRule<ValueType>: Rule {
|
||||||
var maxLength: Int?
|
var maxLength: Int?
|
||||||
var errorMessage: String = "This field is required."
|
var errorMessage: String = "This field is required."
|
||||||
|
|
||||||
func isValid(value: String?) -> Bool {
|
func isValid(value: ValueType?) -> Bool {
|
||||||
guard let value, !value.isEmpty, value.count > 0 else { return false }
|
guard let value,
|
||||||
|
!"\(value)".isEmpty,
|
||||||
|
"\(value)".count > 0 else { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import Combine
|
|||||||
/// Use a text area when you want customers to enter text that’s longer than a single line.
|
/// Use a text area when you want customers to enter text that’s longer than a single line.
|
||||||
@objcMembers
|
@objcMembers
|
||||||
@objc(VDSTextArea)
|
@objc(VDSTextArea)
|
||||||
open class TextArea: EntryFieldBase {
|
open class TextArea: EntryFieldBase<String> {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// Protocol used for a FormField object.
|
/// Protocol used for a FormField object.
|
||||||
public protocol FormFieldable {
|
public protocol FormFieldable<ValueType> {
|
||||||
associatedtype ValueType = AnyHashable
|
associatedtype ValueType = AnyHashable
|
||||||
|
|
||||||
/// Unique Id for the Form Field object within a Form.
|
/// Unique Id for the Form Field object within a Form.
|
||||||
@ -19,7 +19,7 @@ public protocol FormFieldable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Protocol for FormFieldable that require internal validation.
|
/// Protocol for FormFieldable that require internal validation.
|
||||||
public protocol FormFieldInternalValidatable: FormFieldable, Errorable {
|
public protocol FormFieldInternalValidatable<ValueType>: FormFieldable, Errorable {
|
||||||
/// Rules that drive the validator
|
/// Rules that drive the validator
|
||||||
var rules: [AnyRule<ValueType>] { get set }
|
var rules: [AnyRule<ValueType>] { get set }
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user