Merge branch 'feature/vds-form-controls' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui.git into feature/vds-radioButton

This commit is contained in:
Matt Bruce 2024-07-11 12:53:16 -05:00
commit cb30a58db6
4 changed files with 60 additions and 90 deletions

View File

@ -7,6 +7,7 @@
// //
import Foundation import Foundation
import VDS
@objcMembers open class FormFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol { @objcMembers open class FormFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol {
@ -28,6 +29,16 @@ import Foundation
public var fieldKey: String? public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable? public var baseValue: AnyHashable?
public var inverted: Bool = false
public var surface: Surface { inverted ? .dark : .light }
public var dynamicErrorMessage: String? {
didSet {
isValid = dynamicErrorMessage?.isEmpty ?? true
updateUIDynamicError?()
}
}
public var isValid: Bool? = true { public var isValid: Bool? = true {
didSet { updateUI?() } didSet { updateUI?() }
@ -36,6 +47,9 @@ import Foundation
/// Temporary binding mechanism for the view to update on enable changes. /// Temporary binding mechanism for the view to update on enable changes.
public var updateUI: ActionBlock? public var updateUI: ActionBlock?
// TODO: Remove once updateUI is fixed with isSelected
public var updateUIDynamicError: ActionBlock?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------
@ -56,6 +70,7 @@ import Foundation
case required case required
case fieldKey case fieldKey
case groupName case groupName
case inverted
} }
//-------------------------------------------------- //--------------------------------------------------
@ -63,7 +78,7 @@ import Foundation
//-------------------------------------------------- //--------------------------------------------------
open func formFieldValue() -> AnyHashable? { open func formFieldValue() -> AnyHashable? {
fatalError("developer must implement") fatalError("developer must implement")
} }
open func formFieldServerValue() -> AnyHashable? { open func formFieldServerValue() -> AnyHashable? {
@ -93,9 +108,13 @@ import Foundation
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) ?? FormValidator.defaultGroupName groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) ?? FormValidator.defaultGroupName
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
} }
public func encode(to encoder: Encoder) throws { open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id) try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
@ -106,5 +125,6 @@ import Foundation
try container.encode(readOnly, forKey: .readOnly) try container.encode(readOnly, forKey: .readOnly)
try container.encode(enabled, forKey: .enabled) try container.encode(enabled, forKey: .enabled)
try container.encode(required, forKey: .required) try container.encode(required, forKey: .required)
try container.encode(inverted, forKey: .inverted)
} }
} }

View File

@ -9,79 +9,39 @@
import Foundation import Foundation
@objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol, ClearableModelProtocol { @objcMembers open class EntryFieldModel: FormFieldModel, ClearableModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
public class var identifier: String { "" }
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var shouldClearText: Bool = false public var shouldClearText: Bool = false
public var dynamicErrorMessage: String? {
didSet {
isValid = dynamicErrorMessage?.isEmpty ?? true
updateUIDynamicError?()
}
}
public var errorMessage: String?
public var errorTextColor: Color? public var errorTextColor: Color?
public var enabled: Bool = true
public var required: Bool = true
public var readOnly: Bool = false
public var showError: Bool?
public var hideBorders = false public var hideBorders = false
public var locked: Bool? public var locked: Bool?
public var selected: Bool? public var selected: Bool?
public var text: String?
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
public var wasInitiallySelected: Bool = false public var wasInitiallySelected: Bool = false
public var text: String?
public var title: String? public var title: String?
public var feedback: String? public var feedback: String?
public var shouldMaskRecordedView: Bool? = true public var shouldMaskRecordedView: Bool? = true
//used to drive the EntryFieldView UI //used to drive the EntryFieldView UI
public var titleStateLabel: FormLabelModel public var titleStateLabel = FormLabelModel(text: "")
public var feedbackStateLabel: FormLabelModel public var feedbackStateLabel = FormLabelModel(text: "")
public var isValid: Bool? = true {
didSet { updateUI?() }
}
/// Temporary binding mechanism for the view to update on enable changes.
public var updateUI: ActionBlock?
// TODO: Remove once updateUI is fixed with isSelected
public var updateUIDynamicError: ActionBlock?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Keys // MARK: - Keys
//-------------------------------------------------- //--------------------------------------------------
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case backgroundColor case backgroundColor
case accessibilityIdentifier
case title case title
case enabled
case readOnly
case feedback case feedback
case errorMessage
case errorTextColor case errorTextColor
case locked case locked
case selected case selected
case showError
case hideBorders case hideBorders
case text case text
case fieldKey
case groupName
case required
case shouldMaskRecordedView case shouldMaskRecordedView
} }
@ -92,7 +52,7 @@ import Foundation
// MARK: - Validation Methods // MARK: - Validation Methods
//-------------------------------------------------- //--------------------------------------------------
public func formFieldValue() -> AnyHashable? { open override func formFieldValue() -> AnyHashable? {
guard enabled else { return nil } guard enabled else { return nil }
if dynamicErrorMessage != nil { if dynamicErrorMessage != nil {
@ -100,30 +60,15 @@ import Foundation
} }
return text return text
} }
open func formFieldServerValue() -> AnyHashable? {
return formFieldValue()
}
public func setValidity(_ valid: Bool, errorMessage: String?) {
if let ruleErrorMessage = errorMessage, fieldKey != nil {
self.errorMessage = ruleErrorMessage
}
self.isValid = valid
updateUI?()
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
public init(with text: String) { public init(with text: String) {
super.init()
self.text = text self.text = text
baseValue = text baseValue = text
self.titleStateLabel = FormLabelModel(text: "")
self.feedbackStateLabel = FormLabelModel(text: "")
setDefaults() setDefaults()
} }
@ -131,7 +76,7 @@ import Foundation
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
public func clear() { public func clear() {
self.text = "" text = ""
} }
//-------------------------------------------------- //--------------------------------------------------
@ -139,54 +84,35 @@ import Foundation
//-------------------------------------------------- //--------------------------------------------------
required public init(from decoder: Decoder) throws { required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
let typeContainer = try decoder.container(keyedBy: CodingKeys.self) let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
title = try typeContainer.decodeIfPresent(String.self, forKey: .title) title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
errorTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .errorTextColor) errorTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .errorTextColor)
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? true
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked) locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
text = try typeContainer.decodeIfPresent(String.self, forKey: .text) text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false
baseValue = text baseValue = text
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
shouldMaskRecordedView = try typeContainer.decodeIfPresent(Bool.self, forKey: .shouldMaskRecordedView) ?? shouldMaskRecordedView shouldMaskRecordedView = try typeContainer.decodeIfPresent(Bool.self, forKey: .shouldMaskRecordedView) ?? shouldMaskRecordedView
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { titleStateLabel = FormLabelModel(text: title ?? "")
self.groupName = groupName feedbackStateLabel = FormLabelModel(model: LabelModel(text: feedback ?? "",
}
self.titleStateLabel = FormLabelModel(text: title ?? "")
self.feedbackStateLabel = FormLabelModel(model: LabelModel(text: feedback ?? "",
fontStyle: FormLabelModel.defaultFontStyle, fontStyle: FormLabelModel.defaultFontStyle,
textColor: Color(uiColor: .mvmCoolGray6))) textColor: Color(uiColor: .mvmCoolGray6)))
setDefaults() setDefaults()
} }
public func encode(to encoder: Encoder) throws { open override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(title, forKey: .title) try container.encodeIfPresent(title, forKey: .title)
try container.encodeIfPresent(feedback, forKey: .feedback) try container.encodeIfPresent(feedback, forKey: .feedback)
try container.encodeIfPresent(text, forKey: .text) try container.encodeIfPresent(text, forKey: .text)
try container.encodeIfPresent(locked, forKey: .locked) try container.encodeIfPresent(locked, forKey: .locked)
try container.encodeIfPresent(showError, forKey: .showError)
try container.encodeIfPresent(selected, forKey: .selected) try container.encodeIfPresent(selected, forKey: .selected)
try container.encodeIfPresent(errorTextColor, forKey: .errorTextColor) try container.encodeIfPresent(errorTextColor, forKey: .errorTextColor)
try container.encodeIfPresent(errorMessage, forKey: .errorMessage)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encode(readOnly, forKey: .readOnly)
try container.encode(enabled, forKey: .enabled)
try container.encode(required, forKey: .required)
try container.encode(hideBorders, forKey: .hideBorders) try container.encode(hideBorders, forKey: .hideBorders)
try container.encode(shouldMaskRecordedView, forKey: .shouldMaskRecordedView) try container.encode(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
} }

View File

@ -96,3 +96,17 @@ open class TooltipModel: MoleculeModelProtocol {
} }
} }
extension TooltipModel {
public func toVDSTooltipModel() -> Tooltip.TooltipModel {
var moleculeView: MoleculeViewProtocol?
if let molecule, let view = ModelRegistry.createMolecule(molecule) {
moleculeView = view
}
return .init(closeButtonText: closeButtonText,
title: title,
content: content,
contentView: moleculeView
)
}
}

View File

@ -25,21 +25,31 @@ extension VDS.ButtonIcon.Size: Codable {}
extension VDS.ButtonIcon.BadgeIndicatorModel.ExpandDirection: Codable {} extension VDS.ButtonIcon.BadgeIndicatorModel.ExpandDirection: Codable {}
extension VDS.ButtonIcon.SurfaceType: Codable {} extension VDS.ButtonIcon.SurfaceType: Codable {}
extension VDS.ButtonGroup.Alignment: Codable {} extension VDS.ButtonGroup.Alignment: Codable {}
extension VDS.CarouselScrollbar.Layout: Codable {}
extension VDS.DatePicker.DateFormat: Codable {}
extension VDS.EntryFieldBase.HelperTextPlacement: Codable {}
extension VDS.Icon.Name: Codable {} extension VDS.Icon.Name: Codable {}
extension VDS.Icon.Size: Codable {} extension VDS.Icon.Size: Codable {}
extension VDS.InputField.CreditCardType: Codable {}
extension VDS.InputField.DateFormat: Codable {}
extension VDS.InputField.FieldType: Codable {}
extension VDS.Line.Style: Codable {}
extension VDS.Line.Orientation: Codable {}
extension VDS.Tabs.Orientation: Codable {} extension VDS.Tabs.Orientation: Codable {}
extension VDS.Tabs.IndicatorPosition: Codable {} extension VDS.Tabs.IndicatorPosition: Codable {}
extension VDS.Tabs.Overflow: Codable {} extension VDS.Tabs.Overflow: Codable {}
extension VDS.Tabs.Size: Codable {} extension VDS.Tabs.Size: Codable {}
extension VDS.TextArea.Height: Codable {}
extension VDS.TextLink.Size: Codable {} extension VDS.TextLink.Size: Codable {}
extension VDS.TextLinkCaret.IconPosition: Codable {} extension VDS.TextLinkCaret.IconPosition: Codable {}
extension VDS.TileContainerBase.AspectRatio: Codable {} extension VDS.TileContainerBase.AspectRatio: Codable {}
extension VDS.Tilelet.Padding: Codable {} extension VDS.Tilelet.Padding: Codable {}
extension VDS.TitleLockup.TextAlignment: Codable {} extension VDS.TitleLockup.TextAlignment: Codable {}
extension VDS.Toggle.TextSize: Codable {}
extension VDS.Toggle.TextPosition: Codable {}
extension VDS.Toggle.TextWeight: Codable {}
extension VDS.Tooltip.FillColor: Codable {} extension VDS.Tooltip.FillColor: Codable {}
extension VDS.Tooltip.Size: Codable {} extension VDS.Tooltip.Size: Codable {}
extension VDS.Line.Style: Codable {}
extension VDS.Line.Orientation: Codable {}
extension VDS.Use: Codable {} extension VDS.Use: Codable {}
extension VDS.Button.Size: RawRepresentableCodable { extension VDS.Button.Size: RawRepresentableCodable {