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

This commit is contained in:
Matt Bruce 2024-07-03 11:43:42 -05:00
commit 1d048f9389
7 changed files with 123 additions and 14 deletions

View File

@ -581,6 +581,7 @@
EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; };
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; };
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
EA5DBDAB2C35B6C500290DF8 /* FormFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5DBDAA2C35B6C500290DF8 /* FormFieldModel.swift */; };
EA6642912BCDA97300D81DC4 /* TileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642902BCDA97300D81DC4 /* TileContainer.swift */; };
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */; };
EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B942B504A43000139B4 /* ButtonGroup.swift */; };
@ -1201,6 +1202,7 @@
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = "<group>"; };
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = "<group>"; };
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
EA5DBDAA2C35B6C500290DF8 /* FormFieldModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormFieldModel.swift; sourceTree = "<group>"; };
EA6642902BCDA97300D81DC4 /* TileContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainer.swift; sourceTree = "<group>"; };
EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainerModel.swift; sourceTree = "<group>"; };
EA6E8B942B504A43000139B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
@ -2487,6 +2489,7 @@
D2BEFEF5248A954C00FAB3A9 /* FormFields */ = {
isa = PBXGroup;
children = (
EA5DBDAA2C35B6C500290DF8 /* FormFieldModel.swift */,
D2BEFEF6248A957A00FAB3A9 /* Tags */,
D29DF22B21E6A0FA003B2FB9 /* TextFields */,
);
@ -3292,6 +3295,7 @@
D28BA7432480284E00B75CB8 /* TabBar.swift in Sources */,
AA3561AE24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift in Sources */,
AA26850C244840AE00CE34CC /* HeadersH2TinyButton.swift in Sources */,
EA5DBDAB2C35B6C500290DF8 /* FormFieldModel.swift in Sources */,
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */,
D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */,
0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */,

View File

@ -0,0 +1,110 @@
//
// FormFieldModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 7/3/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class FormFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public class var identifier: String { "" }
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var enabled: Bool = true
public var required: Bool = true
public var readOnly: Bool = false
public var showError: Bool?
public var errorMessage: String?
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
public var isValid: Bool? = true {
didSet { updateUI?() }
}
/// Temporary binding mechanism for the view to update on enable changes.
public var updateUI: ActionBlock?
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init() {}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case errorMessage
case enabled
case readOnly
case required
case fieldKey
case groupName
}
//--------------------------------------------------
// MARK: - Validation Methods
//--------------------------------------------------
open func formFieldValue() -> AnyHashable? {
fatalError("developer must implement")
}
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: - Codable
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
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
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) ?? FormValidator.defaultGroupName
}
public 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)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
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)
}
}

View File

@ -135,8 +135,6 @@ open class TileContainer: VDS.TileContainer, VDSMoleculeViewProtocol{
}
extension TileContainer: MVMCoreUIViewConstrainingProtocol {
public func horizontalAlignment() -> UIStackView.Alignment { .leading }
public func isClippable() -> Bool {
return false
}

View File

@ -67,7 +67,7 @@ open class TileContainerBaseModel<PaddingType: DefaultValuing & Codable, TileCon
public var showDropShadow: Bool = false
public var padding = PaddingType.defaultValue
public var color: TileContainerType.BackgroundColor = .black
public var aspectRatio: TileContainerType.AspectRatio = .ratio1x1
public var aspectRatio: TileContainerType.AspectRatio = .none
public var backgroundEffect: TileContainerType.BackgroundEffect = .none
public var surface: Surface { inverted ? .dark : .light }
@ -98,7 +98,7 @@ open class TileContainerBaseModel<PaddingType: DefaultValuing & Codable, TileCon
showDropShadow = try container.decodeIfPresent(Bool.self, forKey: .showDropShadow) ?? false
padding = try container.decodeIfPresent(PaddingType.self, forKey: .padding) ?? PaddingType.defaultValue
color = try container.decodeIfPresent(TileContainerType.BackgroundColor.self, forKey: .color) ?? .black
aspectRatio = try container.decodeIfPresent(TileContainerType.AspectRatio.self, forKey: .aspectRatio) ?? .ratio1x1
aspectRatio = try container.decodeIfPresent(TileContainerType.AspectRatio.self, forKey: .aspectRatio) ?? .none
backgroundEffect = try container.decodeIfPresent(TileContainerType.BackgroundEffect.self, forKey: .backgroundEffect) ?? .none
}

View File

@ -136,10 +136,6 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{
}
extension Tilelet: MVMCoreUIViewConstrainingProtocol {
// Investigate later.
//public func horizontalAlignment() -> UIStackView.Alignment { .leading }
public func isClippable() -> Bool {
return false
}

View File

@ -45,6 +45,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
case textWidth
case textPercentage
}
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
@ -86,7 +87,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
} else {
subTitleColor = .primary
}
try super.init(from: decoder)
}

View File

@ -137,7 +137,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
open override func pageShown() {
// Currently not calling super until we can decouple page shown logics for managers.
hideNavigationBarLine(true)
hideNavigationBarLine(!tabs.isHidden)
}
open override func viewWillDisappear(_ animated: Bool) {
@ -148,7 +148,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
hideNavigationBarLine(true)
hideNavigationBarLine(!tabs.isHidden)
}
/// ensures margin for tabs are correct
private func updateTabsMargin() {
@ -263,7 +263,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
}
tabs.selectIndex(index, animated: true)
self.index = nil
hideNavigationBarLine(true)
hideNavigationBarLine(!tabs.isHidden)
}
public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
@ -354,12 +354,12 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
open func newDataReceived(in viewController: UIViewController) {
manager?.newDataReceived?(in: viewController)
hideNavigationBarLine(true)
hideNavigationBarLine(!tabs.isHidden)
}
public func willDisplay(_ viewController: UIViewController) {
manager?.willDisplay?(viewController)
hideNavigationBarLine(true)
hideNavigationBarLine(!tabs.isHidden)
}
public func displayedViewController(_ viewController: UIViewController) {