Merge branch 'feature/vds-form-controls' into feature/vds-radiobox

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

View File

@ -7,6 +7,7 @@
//
import Foundation
import VDS
@objcMembers open class FormFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol {
@ -28,6 +29,16 @@ import Foundation
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
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 {
didSet { updateUI?() }
@ -36,6 +47,9 @@ import Foundation
/// 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: - Initializer
//--------------------------------------------------
@ -56,6 +70,7 @@ import Foundation
case required
case fieldKey
case groupName
case inverted
}
//--------------------------------------------------
@ -63,7 +78,7 @@ import Foundation
//--------------------------------------------------
open func formFieldValue() -> AnyHashable? {
fatalError("developer must implement")
fatalError("developer must implement")
}
open func formFieldServerValue() -> AnyHashable? {
@ -93,9 +108,13 @@ import Foundation
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
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)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
@ -106,5 +125,6 @@ import Foundation
try container.encode(readOnly, forKey: .readOnly)
try container.encode(enabled, forKey: .enabled)
try container.encode(required, forKey: .required)
try container.encode(inverted, forKey: .inverted)
}
}

View File

@ -9,79 +9,39 @@
import Foundation
@objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol, ClearableModelProtocol {
@objcMembers open class EntryFieldModel: FormFieldModel, ClearableModelProtocol {
//--------------------------------------------------
// 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 dynamicErrorMessage: String? {
didSet {
isValid = dynamicErrorMessage?.isEmpty ?? true
updateUIDynamicError?()
}
}
public var errorMessage: String?
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 locked: 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 text: String?
public var title: String?
public var feedback: String?
public var shouldMaskRecordedView: Bool? = true
//used to drive the EntryFieldView UI
public var titleStateLabel: FormLabelModel
public var feedbackStateLabel: FormLabelModel
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?
public var titleStateLabel = FormLabelModel(text: "")
public var feedbackStateLabel = FormLabelModel(text: "")
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case backgroundColor
case accessibilityIdentifier
case title
case enabled
case readOnly
case feedback
case errorMessage
case errorTextColor
case locked
case selected
case showError
case hideBorders
case text
case fieldKey
case groupName
case required
case shouldMaskRecordedView
}
@ -92,7 +52,7 @@ import Foundation
// MARK: - Validation Methods
//--------------------------------------------------
public func formFieldValue() -> AnyHashable? {
open override func formFieldValue() -> AnyHashable? {
guard enabled else { return nil }
if dynamicErrorMessage != nil {
@ -100,30 +60,15 @@ import Foundation
}
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
//--------------------------------------------------
public init(with text: String) {
super.init()
self.text = text
baseValue = text
self.titleStateLabel = FormLabelModel(text: "")
self.feedbackStateLabel = FormLabelModel(text: "")
setDefaults()
}
@ -131,7 +76,7 @@ import Foundation
// MARK: - Initializers
//--------------------------------------------------
public func clear() {
self.text = ""
text = ""
}
//--------------------------------------------------
@ -139,54 +84,35 @@ import Foundation
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
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)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
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)
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false
baseValue = text
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
shouldMaskRecordedView = try typeContainer.decodeIfPresent(Bool.self, forKey: .shouldMaskRecordedView) ?? shouldMaskRecordedView
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
self.titleStateLabel = FormLabelModel(text: title ?? "")
self.feedbackStateLabel = FormLabelModel(model: LabelModel(text: feedback ?? "",
titleStateLabel = FormLabelModel(text: title ?? "")
feedbackStateLabel = FormLabelModel(model: LabelModel(text: feedback ?? "",
fontStyle: FormLabelModel.defaultFontStyle,
textColor: Color(uiColor: .mvmCoolGray6)))
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)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(title, forKey: .title)
try container.encodeIfPresent(feedback, forKey: .feedback)
try container.encodeIfPresent(text, forKey: .text)
try container.encodeIfPresent(locked, forKey: .locked)
try container.encodeIfPresent(showError, forKey: .showError)
try container.encodeIfPresent(selected, forKey: .selected)
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(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.SurfaceType: 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.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.IndicatorPosition: Codable {}
extension VDS.Tabs.Overflow: Codable {}
extension VDS.Tabs.Size: Codable {}
extension VDS.TextArea.Height: Codable {}
extension VDS.TextLink.Size: Codable {}
extension VDS.TextLinkCaret.IconPosition: Codable {}
extension VDS.TileContainerBase.AspectRatio: Codable {}
extension VDS.Tilelet.Padding: 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.Size: Codable {}
extension VDS.Line.Style: Codable {}
extension VDS.Line.Orientation: Codable {}
extension VDS.Use: Codable {}
extension VDS.Button.Size: RawRepresentableCodable {