Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui.git into feature/atomic_vds_loader

This commit is contained in:
Matt Bruce 2024-01-29 15:29:01 -06:00
commit e9b2a62bc9
58 changed files with 164 additions and 133 deletions

View File

@ -168,8 +168,10 @@
526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */; }; 526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */; };
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; }; 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; };
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */; }; 52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */; };
608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */; };
7199C8162A4F3A64001568B7 /* AccessibilityHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7199C8152A4F3A64001568B7 /* AccessibilityHandler.swift */; }; 7199C8162A4F3A64001568B7 /* AccessibilityHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7199C8152A4F3A64001568B7 /* AccessibilityHandler.swift */; };
71BE969E2AD96BE6000B5DB7 /* RotorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BE969D2AD96BE6000B5DB7 /* RotorHandler.swift */; }; 71BE969E2AD96BE6000B5DB7 /* RotorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BE969D2AD96BE6000B5DB7 /* RotorHandler.swift */; };
608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */; };
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */; }; 8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */; };
8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */; }; 8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */; };
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */; }; 8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */; };
@ -473,8 +475,6 @@
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */; }; D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */; };
D29DF26E21E6AA0B003B2FB9 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF26E21E6AA0B003B2FB9 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29DF26F21E6AA0B003B2FB9 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF26B21E6AA0B003B2FB9 /* FLAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF26F21E6AA0B003B2FB9 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF26B21E6AA0B003B2FB9 /* FLAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF27321E79E81003B2FB9 /* MVMCoreUILoggingHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */; };
D29DF27921E7A533003B2FB9 /* MVMCoreUISession.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF27921E7A533003B2FB9 /* MVMCoreUISession.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF27821E7A533003B2FB9 /* MVMCoreUISession.m */; }; D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF27821E7A533003B2FB9 /* MVMCoreUISession.m */; };
D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF27F21E7AA50003B2FB9 /* MVMCoreUIDetailViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF27F21E7AA50003B2FB9 /* MVMCoreUIDetailViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -761,8 +761,10 @@
526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnCompareChanges.swift; sourceTree = "<group>"; }; 526A265D240D200500B0D828 /* ListTwoColumnCompareChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnCompareChanges.swift; sourceTree = "<group>"; };
52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = "<group>"; }; 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = "<group>"; };
52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethodModel.swift; sourceTree = "<group>"; }; 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethodModel.swift; sourceTree = "<group>"; };
608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingHandler.swift; sourceTree = "<group>"; };
7199C8152A4F3A64001568B7 /* AccessibilityHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityHandler.swift; sourceTree = "<group>"; }; 7199C8152A4F3A64001568B7 /* AccessibilityHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityHandler.swift; sourceTree = "<group>"; };
71BE969D2AD96BE6000B5DB7 /* RotorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotorHandler.swift; sourceTree = "<group>"; }; 71BE969D2AD96BE6000B5DB7 /* RotorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotorHandler.swift; sourceTree = "<group>"; };
608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingHandler.swift; sourceTree = "<group>"; };
8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalDataModel.swift; sourceTree = "<group>"; }; 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalDataModel.swift; sourceTree = "<group>"; };
8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalData.swift; sourceTree = "<group>"; }; 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalData.swift; sourceTree = "<group>"; };
8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyTextModel.swift; sourceTree = "<group>"; }; 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyTextModel.swift; sourceTree = "<group>"; };
@ -1074,8 +1076,6 @@
D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = "<group>"; }; D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = "<group>"; };
D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImage.h; sourceTree = "<group>"; }; D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImage.h; sourceTree = "<group>"; };
D29DF26B21E6AA0B003B2FB9 /* FLAnimatedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImageView.h; sourceTree = "<group>"; }; D29DF26B21E6AA0B003B2FB9 /* FLAnimatedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImageView.h; sourceTree = "<group>"; };
D29DF27321E79E81003B2FB9 /* MVMCoreUILoggingHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUILoggingHandler.h; sourceTree = "<group>"; };
D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUILoggingHandler.m; sourceTree = "<group>"; };
D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUISession.h; sourceTree = "<group>"; }; D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUISession.h; sourceTree = "<group>"; };
D29DF27821E7A533003B2FB9 /* MVMCoreUISession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUISession.m; sourceTree = "<group>"; }; D29DF27821E7A533003B2FB9 /* MVMCoreUISession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUISession.m; sourceTree = "<group>"; };
D29DF27F21E7AA50003B2FB9 /* MVMCoreUIDetailViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIDetailViewProtocol.h; sourceTree = "<group>"; }; D29DF27F21E7AA50003B2FB9 /* MVMCoreUIDetailViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIDetailViewProtocol.h; sourceTree = "<group>"; };
@ -2294,8 +2294,7 @@
D2B18B912361E65A00A9AEDC /* CoreUIObject.swift */, D2B18B912361E65A00A9AEDC /* CoreUIObject.swift */,
D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */, D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */,
D29DF27821E7A533003B2FB9 /* MVMCoreUISession.m */, D29DF27821E7A533003B2FB9 /* MVMCoreUISession.m */,
D29DF27321E79E81003B2FB9 /* MVMCoreUILoggingHandler.h */, 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */,
D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */,
AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */, AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */,
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */, D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */,
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */, D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */,
@ -2533,7 +2532,6 @@
D29DF25921E6A22D003B2FB9 /* MFButtonProtocol.h in Headers */, D29DF25921E6A22D003B2FB9 /* MFButtonProtocol.h in Headers */,
D29DF28421E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.h in Headers */, D29DF28421E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.h in Headers */,
D29DF2CE21E7C104003B2FB9 /* MFLoadingViewController.h in Headers */, D29DF2CE21E7C104003B2FB9 /* MFLoadingViewController.h in Headers */,
D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */,
D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */, D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */,
D20492A424329A2800A5EED6 /* MVMCoreUIPagingProtocol.h in Headers */, D20492A424329A2800A5EED6 /* MVMCoreUIPagingProtocol.h in Headers */,
D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */, D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */,
@ -2759,6 +2757,7 @@
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */, D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */, D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */,
608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */,
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */, 014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */, 0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */,
BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */, BBAA4F04243D8E3B005AAD5F /* RadioBoxModel.swift in Sources */,
@ -2766,7 +2765,6 @@
D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */, D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */,
AAA905E124D1759A00D1EFAB /* ListThreeColumnBillHistory.swift in Sources */, AAA905E124D1759A00D1EFAB /* ListThreeColumnBillHistory.swift in Sources */,
C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */, C7F8012323E846C300396FBD /* ListRVWheelModel.swift in Sources */,
D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */,
D2ED27EC254B0CE700A1C293 /* UIAlertControllerStyle+Extension.swift in Sources */, D2ED27EC254B0CE700A1C293 /* UIAlertControllerStyle+Extension.swift in Sources */,
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */, C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */, 014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */,

View File

@ -31,6 +31,8 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
public var size: VDS.Button.Size = .large public var size: VDS.Button.Size = .large
public var groupName: String = "" public var groupName: String = ""
public var inverted: Bool = false public var inverted: Bool = false
public var accessibilityTraits: UIAccessibilityTraits?
public var disabledAccessibilityTraits: UIAccessibilityTraits?
public var backgroundColor: Color? public var backgroundColor: Color?
//-------------------------------------------------- //--------------------------------------------------
@ -77,6 +79,8 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
case size case size
case groupName case groupName
case width case width
case accessibilityTraits
case disabledAccessibilityTraits
} }
//-------------------------------------------------- //--------------------------------------------------
@ -118,6 +122,10 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
} else { } else {
try setInverted(deprecatedFrom: decoder) try setInverted(deprecatedFrom: decoder)
} }
accessibilityTraits = try typeContainer.decodeIfPresent(UIAccessibilityTraits.self, forKey: .accessibilityTraits)
disabledAccessibilityTraits = try typeContainer.decodeIfPresent(UIAccessibilityTraits.self, forKey: .disabledAccessibilityTraits)
} }
private enum DeprecatedCodingKeys: String, CodingKey { private enum DeprecatedCodingKeys: String, CodingKey {
@ -158,6 +166,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
self.inverted = !backgroundColor.uiColor.isDark() self.inverted = !backgroundColor.uiColor.isDark()
} }
} }
} }
open func encode(to encoder: Encoder) throws { open func encode(to encoder: Encoder) throws {
@ -174,5 +183,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
try container.encode(size, forKey: .size) try container.encode(size, forKey: .size)
try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encodeIfPresent(width, forKey: .width) try container.encodeIfPresent(width, forKey: .width)
try container.encodeIfPresent(accessibilityTraits, forKey: .accessibilityTraits)
try container.encodeIfPresent(disabledAccessibilityTraits, forKey: .disabledAccessibilityTraits)
} }
} }

View File

@ -33,7 +33,6 @@ import Foundation
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
FormValidator.setupValidation(for: castModel, delegate: delegateObject?.formHolderDelegate) FormValidator.setupValidation(for: castModel, delegate: delegateObject?.formHolderDelegate)
} }
public func setState() { public func setState() {
@ -47,6 +46,9 @@ import Foundation
} else if let disabledTintColor = castModel.disabledTintColor { } else if let disabledTintColor = castModel.disabledTintColor {
image.imageView.tintColor = disabledTintColor.uiColor image.imageView.tintColor = disabledTintColor.uiColor
} }
if let traits = model?.accessibilityTraits {
accessibilityTraits = traits
}
} }

View File

@ -24,7 +24,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
public var enabled: Bool = true public var enabled: Bool = true
public var enabledTintColor: Color? public var enabledTintColor: Color?
public var disabledTintColor: Color? public var disabledTintColor: Color?
public var accessibilityTraits: UIAccessibilityTraits?
public var groupName: String = "" public var groupName: String = ""
public var updateUI: ActionBlock? public var updateUI: ActionBlock?
@ -45,6 +45,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
case groupName case groupName
case enabledTintColor case enabledTintColor
case disabledTintColor case disabledTintColor
case accessibilityTraits
} }
//-------------------------------------------------- //--------------------------------------------------
@ -59,7 +60,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
image = try typeContainer.decodeIfPresent(ImageViewModel.self, forKey: .image) image = try typeContainer.decodeIfPresent(ImageViewModel.self, forKey: .image)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
action = try typeContainer.decodeModel(codingKey: .action) action = try typeContainer.decodeModel(codingKey: .action)
accessibilityTraits = try typeContainer.decodeIfPresent(UIAccessibilityTraits.self, forKey: .accessibilityTraits) ?? .button
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled self.enabled = enabled
} }
@ -90,5 +91,6 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encodeIfPresent(enabledTintColor, forKey: .enabledTintColor) try container.encodeIfPresent(enabledTintColor, forKey: .enabledTintColor)
try container.encodeIfPresent(disabledTintColor, forKey: .disabledTintColor) try container.encodeIfPresent(disabledTintColor, forKey: .disabledTintColor)
try container.encodeIfPresent(accessibilityTraits, forKey: .accessibilityTraits)
} }
} }

View File

@ -41,7 +41,9 @@ open class PillButton: VDS.Button, MVMCoreUIViewConstrainingProtocol, MFButtonPr
if let accessibilityText = viewModel.accessibilityText { if let accessibilityText = viewModel.accessibilityText {
accessibilityLabel = accessibilityText accessibilityLabel = accessibilityText
} }
accessibilityTraits = isEnabled ? (viewModel?.accessibilityTraits ?? .button) : (viewModel?.disabledAccessibilityTraits ?? .none)
set(with: viewModel.action, delegateObject: delegateObject, additionalData: additionalData) set(with: viewModel.action, delegateObject: delegateObject, additionalData: additionalData)
viewModel.updateUI = { [weak self] in viewModel.updateUI = { [weak self] in
@ -58,8 +60,10 @@ open class PillButton: VDS.Button, MVMCoreUIViewConstrainingProtocol, MFButtonPr
// MARK: - MVMCoreViewProtocol // MARK: - MVMCoreViewProtocol
//-------------------------------------------------- //--------------------------------------------------
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return (model as? ButtonModel)?.size.height return (model as? ButtonModel)?.size.height
} }
open func updateView(_ size: CGFloat) {} open func updateView(_ size: CGFloat) {}

View File

@ -161,7 +161,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
bottomConstraint?.isActive = true bottomConstraint?.isActive = true
heightConstraint = textView.heightAnchor.constraint(equalToConstant: 0) heightConstraint = textView.heightAnchor.constraint(equalToConstant: 0)
accessibilityElements = [titleLabel, textView, feedbackLabel] accessibilityElements = [textView]
} }
open override func updateView(_ size: CGFloat) { open override func updateView(_ size: CGFloat) {
@ -281,6 +281,25 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
if model.hideBorders { if model.hideBorders {
adjustMarginConstraints(constant: 0) adjustMarginConstraints(constant: 0)
} }
updateAccessibility(model: model)
}
func updateAccessibility(model: TextViewEntryFieldModel) {
var message = ""
if let titleText = model.accessibilityText ?? model.title {
message += "\(titleText) \( model.enabled ? String(format: (MVMCoreUIUtility.hardcodedString(withKey: "textfield_optional")) ?? "") : "" ) \(self.textView.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")"
}
if let feedback = model.feedback {
message += ", " + feedback
}
if let errorMessage = errorLabel.text {
message += ", " + errorMessage
}
textView.accessibilityLabel = message
} }
} }

View File

@ -64,7 +64,7 @@ public class FormLabelModel: EnableableModelProtocol {
if enabled { if enabled {
required.attributes = [LabelAttributeColorModel(FormLabelModel.defaultRequiredTextColor, model.text.count + 1, 8)] required.attributes = [LabelAttributeColorModel(FormLabelModel.defaultRequiredTextColor, model.text.count + 1, 8)]
} }
required.text = "\(model.text) Optional" required.text = "\(model.text) \(MVMCoreUIUtility.hardcodedString(withKey: "textfield_optional") ?? "")"
return required return required
} }

View File

@ -231,7 +231,7 @@ public typealias ActionBlock = () -> ()
documentAttributes: nil) documentAttributes: nil)
} catch { } catch {
if let coreErrorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "LabelHTMLParse") { if let coreErrorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "LabelHTMLParse") {
MVMCoreUILoggingHandler.addError(toLog: coreErrorObject) MVMCoreUILoggingHandler.shared()?.addError(toLog: coreErrorObject)
} }
} }
} }
@ -1013,17 +1013,13 @@ extension Label {
func validateAttribute(range: NSRange, in string: NSAttributedString, type: String = "") -> NSRange? { func validateAttribute(range: NSRange, in string: NSAttributedString, type: String = "") -> NSRange? {
guard range.location >= 0 && range.location <= string.length else { guard range.location >= 0 && range.location <= string.length else {
if let loggingHandler = MVMCoreLoggingHandler.shared(), loggingHandler.responds(to: #selector(MVMCoreLoggingHandler.addError(toLog:))) { MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Attribute starting location \(range.lowerBound) is out of bounds for '\(string.string)'. Attribute is discarded.", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: "\(#file): \(#function)")!)
loggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Attribute starting location \(range.lowerBound) is out of bounds for '\(string.string)'. Attribute is discarded.", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: "\(#file): \(#function)")!)
}
return nil return nil
} }
if type != "image" && range.upperBound > string.length { if type != "image" && range.upperBound > string.length {
let newRange = NSRange(location: range.location, length: string.length - range.location) let newRange = NSRange(location: range.location, length: string.length - range.location)
if let loggingHandler = MVMCoreLoggingHandler.shared(), loggingHandler.responds(to: #selector(MVMCoreLoggingHandler.addError(toLog:))) { MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Attribute ending location \(range.upperBound) is out of bounds for '\(string)'. Adjusting to \(newRange.upperBound).", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: "\(#file): \(#function)")!)
loggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Attribute ending location \(range.upperBound) is out of bounds for '\(string)'. Adjusting to \(newRange.upperBound).", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: "\(#file): \(#function)")!)
}
return newRange return newRange
} }

View File

@ -54,7 +54,7 @@ import Foundation
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
public func setupView() { open func setupView() {
clipsToBounds = true clipsToBounds = true
translatesAutoresizingMaskIntoConstraints = false translatesAutoresizingMaskIntoConstraints = false
@ -70,7 +70,7 @@ import Foundation
// MARK: - MVMCoreViewProtocol // MARK: - MVMCoreViewProtocol
//-------------------------------------------------- //--------------------------------------------------
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let progressBarModel = model as? ProgressBarModel else { return } guard let progressBarModel = model as? ProgressBarModel else { return }

View File

@ -8,8 +8,8 @@
import Foundation import Foundation
@objcMembers public class ProgressBarModel: MoleculeModelProtocol { @objcMembers open class ProgressBarModel: MoleculeModelProtocol {
public static var identifier: String = "progressBar" open class var identifier: String { "progressBar" }
public var id: String = UUID().uuidString public var id: String = UUID().uuidString
@Percent public var percent: CGFloat @Percent public var percent: CGFloat
@ -46,7 +46,7 @@ import Foundation
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness) thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
} }
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.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)

View File

@ -89,7 +89,7 @@ open class Video: View {
}) })
case .failed: case .failed:
if let errorObject = item.loadFailedError { if let errorObject = item.loadFailedError {
MVMCoreLoggingHandler.addError(toLog: errorObject) MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject)
} }
default: default:
break break

View File

@ -75,6 +75,7 @@ import Foundation
delegateObject, additionalData) delegateObject, additionalData)
rightImageView.set(with: model.image, delegateObject, additionalData) rightImageView.set(with: model.image, delegateObject, additionalData)
updateAccessibilityLabel() updateAccessibilityLabel()
accessibilityTraits.update(with: model.accessibilityTraits ?? button.accessibilityTraits)
} }
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {

View File

@ -73,6 +73,7 @@
delegateObject, additionalData) delegateObject, additionalData)
rightImageView.set(with: model.image, delegateObject, additionalData) rightImageView.set(with: model.image, delegateObject, additionalData)
updateAccessibilityLabel() updateAccessibilityLabel()
accessibilityTraits.update(with: model.accessibilityTraits ?? button.accessibilityTraits)
} }
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {

View File

@ -79,7 +79,7 @@
let linkShowing = (model as? ListLeftVariableIconAllTextLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil let linkShowing = (model as? ListLeftVariableIconAllTextLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil
isAccessibilityElement = !linkShowing isAccessibilityElement = !linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((isAccessibilityElement && accessoryView != nil) ? .button : .none)
if !linkShowing { if !linkShowing {
// Make whole cell focusable if no link. // Make whole cell focusable if no link.

View File

@ -91,6 +91,6 @@
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -100,7 +100,7 @@
func updateAccessibilityLabel() { func updateAccessibilityLabel() {
let linkShowing = (model as? ListLeftVariableIconWithRightCaretAllTextLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil let linkShowing = (model as? ListLeftVariableIconWithRightCaretAllTextLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil
isAccessibilityElement = !linkShowing isAccessibilityElement = !linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((isAccessibilityElement && accessoryView != nil) ? .button : .none)
if !linkShowing { if !linkShowing {
// Make whole cell focusable if no link. // Make whole cell focusable if no link.

View File

@ -109,6 +109,6 @@
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -89,7 +89,7 @@
let linkShowing = (model as? ListLeftVariableNumberedListAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil let linkShowing = (model as? ListLeftVariableNumberedListAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil
isAccessibilityElement = !linkShowing isAccessibilityElement = !linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((isAccessibilityElement && accessoryView != nil) ? .button : .none)
if !linkShowing { if !linkShowing {
// Make whole cell focusable if no link. // Make whole cell focusable if no link.

View File

@ -89,7 +89,7 @@
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -134,6 +134,6 @@ open class ListProgressBarThin: TableViewCell {
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -70,11 +70,7 @@
override public var accessibilityTraits: UIAccessibilityTraits { override public var accessibilityTraits: UIAccessibilityTraits {
get { get {
if (accessoryView != nil) { return (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
return .button
} else {
return .none
}
} }
set { } set { }
} }

View File

@ -97,7 +97,8 @@ import Foundation
// Ensures voice over does not read "selected" after user triggers action on cell. // Ensures voice over does not read "selected" after user triggers action on cell.
override public var accessibilityTraits: UIAccessibilityTraits { override public var accessibilityTraits: UIAccessibilityTraits {
get { get {
return (accessoryView != nil) ? .button : .none return (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
set {} set {}
} }

View File

@ -46,7 +46,7 @@ import Foundation
/// Ensures voice over does not read "selected" after user triggers action on cell. /// Ensures voice over does not read "selected" after user triggers action on cell.
override public var accessibilityTraits: UIAccessibilityTraits { override public var accessibilityTraits: UIAccessibilityTraits {
get { get {
return (accessoryView != nil) ? .button : .none return (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
set {} set {}
} }

View File

@ -91,6 +91,6 @@
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -47,7 +47,7 @@
stack.restack() stack.restack()
accessibilityValue = button.accessibilityValue accessibilityValue = button.accessibilityValue
accessibilityHint = button.accessibilityHint accessibilityHint = button.accessibilityHint
accessibilityTraits = .button accessibilityTraits = (listItemModel?.accessibilityTraits ?? .button)
} }
//----------------------------------------------------- //-----------------------------------------------------

View File

@ -83,6 +83,6 @@
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -102,7 +102,7 @@
let linkShowing = (model as? ListRightVariablePriceChangeAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil let linkShowing = (model as? ListRightVariablePriceChangeAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil
isAccessibilityElement = !linkShowing isAccessibilityElement = !linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((isAccessibilityElement && accessoryView != nil) ? .button : .none)
if !linkShowing { if !linkShowing {
// Make whole cell focusable if no link. // Make whole cell focusable if no link.

View File

@ -98,6 +98,6 @@
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -99,8 +99,8 @@
let linkShowing = (model as? ListRightVariableRightCaretAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil let linkShowing = (model as? ListRightVariableRightCaretAllTextAndLinksModel)?.eyebrowHeadlineBodyLink.link?.title != nil
isAccessibilityElement = !linkShowing isAccessibilityElement = !linkShowing
accessibilityTraits = (isAccessibilityElement && accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((isAccessibilityElement && accessoryView != nil) ? .button : .none)
if !linkShowing { if !linkShowing {
// Make whole cell focusable if no link. // Make whole cell focusable if no link.
accessibilityLabel = getAccessibilityMessage() accessibilityLabel = getAccessibilityMessage()

View File

@ -89,7 +89,7 @@
func updateAccessibilityLabel() { func updateAccessibilityLabel() {
let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0 let linkShowing = eyebrowHeadlineBodyLink.link.titleLabel?.text?.count ?? 0 > 0
accessibilityTraits = .button accessibilityTraits = listItemModel?.accessibilityTraits ?? .button
if !linkShowing && accessoryView == nil { if !linkShowing && accessoryView == nil {
// Make whole cell focusable if one action // Make whole cell focusable if one action

View File

@ -103,6 +103,6 @@ open class ListRightVariableTotalData: TableViewCell {
} }
accessibilityLabel = message accessibilityLabel = message
accessibilityTraits = (accessoryView != nil) ? .button : .none accessibilityTraits = (listItemModel?.accessibilityTraits) ?? ((accessoryView != nil) ? .button : .none)
} }
} }

View File

@ -84,16 +84,22 @@ import VDSColorTokens
// MARK: - TabBarProtocol // MARK: - TabBarProtocol
@MainActor @MainActor
public func highlightTab(at index: Int) { public func highlightTab(at index: Int) {
guard let newSelectedItem = items?[index] else { return } guard let items = items, index >= 0, index < items.count else {
MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Invalid tab index \(index). \(items?.count ?? 0) tabs available .", code: 0, domain: ErrorDomainSystem, location: #function)!)
return
}
tabModel.selectedTab = index tabModel.selectedTab = index
selectedItem = newSelectedItem selectedItem = items[index]
} }
@MainActor @MainActor
public func selectTab(at index: Int) { public func selectTab(at index: Int) {
guard let newSelectedItem = items?[index] else { return } guard let items = items, index >= 0, index < items.count else {
selectedItem = newSelectedItem MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Invalid tab index \(index). \(items?.count ?? 0) tabs available.", code: 0, domain: ErrorDomainSystem, location: #function)!)
tabBar(self, didSelect: newSelectedItem) return
}
selectedItem = items[index]
tabBar(self, didSelect: items[index])
} }
public func currentTabIndex() -> Int { tabModel.selectedTab } public func currentTabIndex() -> Int { tabModel.selectedTab }

View File

@ -18,8 +18,9 @@
public var hideArrow: Bool? public var hideArrow: Bool?
public var line: LineModel? public var line: LineModel?
public var style: ListItemStyle? public var style: ListItemStyle?
public var accessibilityTraits: UIAccessibilityTraits?
public var accessibilityValue: String?
public var accessibilityText: String? public var accessibilityText: String?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Keys // MARK: - Keys
//-------------------------------------------------- //--------------------------------------------------
@ -30,6 +31,8 @@
case hideArrow case hideArrow
case line case line
case style case style
case accessibilityTraits
case accessibilityValue
case accessibilityText case accessibilityText
} }
@ -104,7 +107,8 @@
hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow) hideArrow = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideArrow)
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
style = try typeContainer.decodeIfPresent(ListItemStyle.self, forKey: .style) style = try typeContainer.decodeIfPresent(ListItemStyle.self, forKey: .style)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) accessibilityTraits = try typeContainer.decodeIfPresent(UIAccessibilityTraits.self, forKey: .accessibilityTraits)
accessibilityValue = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityValue)
try super.init(from: decoder) try super.init(from: decoder)
} }
@ -116,6 +120,8 @@
try container.encodeIfPresent(hideArrow, forKey: .hideArrow) try container.encodeIfPresent(hideArrow, forKey: .hideArrow)
try container.encodeIfPresent(line, forKey: .line) try container.encodeIfPresent(line, forKey: .line)
try container.encodeIfPresent(style, forKey: .style) try container.encodeIfPresent(style, forKey: .style)
try container.encodeIfPresent(accessibilityTraits, forKey: .accessibilityTraits)
try container.encodeIfPresent(accessibilityValue, forKey: .accessibilityValue)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
} }
} }

View File

@ -75,7 +75,7 @@ open class ModuleMolecule: Container {
let _ = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else { let _ = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) { if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) {
error?.pointee = errorObject error?.pointee = errorObject
MVMCoreUILoggingHandler.addError(toLog: errorObject) MVMCoreUILoggingHandler.shared()?.addError(toLog: errorObject)
} }
return nil return nil
} }

View File

@ -88,15 +88,15 @@
var message = "" var message = ""
if let eyebrowLabel = eyebrow.text { if let eyebrowLabel = eyebrow.accessibilityLabel ?? eyebrow.text {
message += eyebrowLabel + ", " message += eyebrowLabel + ", "
} }
if let headlineLabel = headline.text { if let headlineLabel = headline.accessibilityLabel ?? headline.text {
message += headlineLabel + ", " message += headlineLabel + ", "
} }
if let bodyLabel = body.text { if let bodyLabel = body.accessibilityLabel ?? body.text {
message += bodyLabel message += bodyLabel
} }

View File

@ -87,7 +87,7 @@ open class Carousel: View {
showPeaking(false) showPeaking(false)
// Go to current cell. layoutIfNeeded is needed otherwise cellForItem returns nil for peaking logic. The dispatch is a sad way to ensure the collection view is ready to be scrolled. // Go to current cell. layoutIfNeeded is needed otherwise cellForItem returns nil for peaking logic. The dispatch is a sad way to ensure the collection view is ready to be scrolled.
guard let model = model as? CarouselModel, guard let model = model as? CarouselModel, !model.molecules.isEmpty,
(model.paging == true || loop == true) else { return } (model.paging == true || loop == true) else { return }
DispatchQueue.main.async { DispatchQueue.main.async {
self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false) self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false)

View File

@ -8,7 +8,6 @@
import UIKit import UIKit
@objcMembers public class CarouselModel: ParentMoleculeModelProtocol, FormFieldProtocol { @objcMembers public class CarouselModel: ParentMoleculeModelProtocol, FormFieldProtocol {
//-------------------------------------------------- //--------------------------------------------------
@ -57,14 +56,14 @@ import UIKit
guard selectable else { guard selectable else {
// Use visible item value, else index // Use visible item value, else index
if let fieldValue = molecules[index].formFieldValue() { if let fieldValue = molecules[safe: index]?.formFieldValue() {
return fieldValue return fieldValue
} }
return index return index
} }
// Use selected item value, else index // Use selected item value, else index
guard let selectedIndex = selectedIndex else { return nil } guard let selectedIndex = selectedIndex else { return nil }
guard let fieldValue = molecules[selectedIndex].formFieldValue() else { return selectedIndex } guard let fieldValue = molecules[safe: selectedIndex]?.formFieldValue() else { return selectedIndex }
return fieldValue return fieldValue
} }

View File

@ -15,6 +15,7 @@ public protocol AccessibilityModelProtocol {
var accessibilityTraits: UIAccessibilityTraits? { get set } var accessibilityTraits: UIAccessibilityTraits? { get set }
var accessibilityText: String? { get set } var accessibilityText: String? { get set }
var accessibilityValue: String? { get set } var accessibilityValue: String? { get set }
var accessibilityHint: String? { get set }
} }
public extension AccessibilityModelProtocol { public extension AccessibilityModelProtocol {
@ -38,4 +39,9 @@ public extension AccessibilityModelProtocol {
get { nil } get { nil }
set { } set { }
} }
var accessibilityHint: String? {
get { nil }
set {}
}
} }

View File

@ -15,7 +15,7 @@ public enum ListItemStyle: String, Codable {
case none case none
} }
public protocol ListItemModelProtocol: ContainerModelProtocol { public protocol ListItemModelProtocol: ContainerModelProtocol, AccessibilityModelProtocol {
var line: LineModel? { get set } var line: LineModel? { get set }
var action: ActionModelProtocol? { get set } var action: ActionModelProtocol? { get set }
var hideArrow: Bool? { get set } var hideArrow: Bool? { get set }

View File

@ -77,7 +77,7 @@ public extension ModelRegistry {
return type return type
} catch { } catch {
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) { if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
MVMCoreLoggingHandler.addError(toLog: errorObject) MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject)
} }
return nil return nil
} }

View File

@ -163,6 +163,15 @@ import UIKit
// align if needed. // align if needed.
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol) containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)
if let traits = model.accessibilityTraits {
accessibilityTraits.update(with: traits)
}
if let accessibilityText = model.accessibilityText {
accessibilityLabel = accessibilityText
isAccessibilityElement = true
}
accessibilityValue = model.accessibilityValue
} }
open func reset() { open func reset() {

View File

@ -98,7 +98,6 @@ import UIKit
smartInsertDeleteType = .no smartInsertDeleteType = .no
inputAccessoryView = nil inputAccessoryView = nil
isAccessibilityElement = true isAccessibilityElement = true
accessibilityTraits = .staticText
font = fontStyle.getFont() font = fontStyle.getFont()
keyboardType = .default keyboardType = .default
isEditable = true isEditable = true

View File

@ -115,7 +115,7 @@ import MVMCore
}) })
} catch { } catch {
if let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: "updateJSON for pageType: \(String(describing: pageType))") { if let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: "updateJSON for pageType: \(String(describing: pageType))") {
MVMCoreLoggingHandler.addError(toLog: coreError) MVMCoreLoggingHandler.shared()?.addError(toLog: coreError)
} }
} }
} }

View File

@ -33,7 +33,7 @@ public extension PageBehaviorHandlerProtocol {
behaviors.append(behavior) behaviors.append(behavior)
} catch { } catch {
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) { if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
MVMCoreLoggingHandler.addError(toLog: errorObject) MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject)
} }
} }
} }

View File

@ -83,7 +83,6 @@ import Combine
} }
extension NavigationController: MVMCoreViewManagerProtocol { extension NavigationController: MVMCoreViewManagerProtocol {
public func getAccessibilityElements() -> [Any]? { public func getAccessibilityElements() -> [Any]? {
nil nil
} }

View File

@ -249,7 +249,6 @@ public extension MVMCoreUISplitViewController {
} }
extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol { extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol {
public func getAccessibilityElements() -> [Any]? { public func getAccessibilityElements() -> [Any]? {
nil nil
} }
@ -263,7 +262,7 @@ extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol {
} }
public func willDisplay(_ viewController: UIViewController) { public func willDisplay(_ viewController: UIViewController) {
setupPanels() setupPanels(viewController)
updateState(with: viewController) updateState(with: viewController)
} }

View File

@ -99,7 +99,7 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
- (void)setNavigationIconColor:(nullable UIColor *)color; - (void)setNavigationIconColor:(nullable UIColor *)color;
/// Updates the panels that are used. /// Updates the panels that are used.
- (void)setupPanels; - (void)setupPanels:(nullable UIViewController*)viewController;
/// Returns if the left panel is staying extended (usually do to screen size threshold) /// Returns if the left panel is staying extended (usually do to screen size threshold)
- (BOOL)leftPanelStaysExtended; - (BOOL)leftPanelStaysExtended;

View File

@ -723,9 +723,9 @@ CGFloat const PanelAnimationDuration = 0.2;
[panel removeFromParentViewController]; [panel removeFromParentViewController];
} }
- (void)setupLeftPanel { - (void)setupLeftPanel:(nullable UIViewController*)viewController {
UIViewController <MVMCoreUIPanelProtocol> *panel = nil; UIViewController <MVMCoreUIPanelProtocol> *panel = nil;
UIViewController *currentViewController = [self getCurrentDetailViewController]; UIViewController *currentViewController = viewController ? viewController : [self getCurrentDetailViewController];
if ([currentViewController respondsToSelector:@selector(overrideLeftPanel)]) { if ([currentViewController respondsToSelector:@selector(overrideLeftPanel)]) {
panel = [((UIViewController <MVMCoreUIDetailViewProtocol> *)currentViewController) overrideLeftPanel]; panel = [((UIViewController <MVMCoreUIDetailViewProtocol> *)currentViewController) overrideLeftPanel];
} else { } else {
@ -735,6 +735,7 @@ CGFloat const PanelAnimationDuration = 0.2;
if (!panel) { if (!panel) {
[self removePanel:self.leftPanel]; [self removePanel:self.leftPanel];
self.leftPanel = nil;
} else if (panel && panel != self.leftPanel) { } else if (panel && panel != self.leftPanel) {
[self removePanel:self.leftPanel]; [self removePanel:self.leftPanel];
[self addPanel:panel]; [self addPanel:panel];
@ -795,9 +796,9 @@ CGFloat const PanelAnimationDuration = 0.2;
} }
} }
- (void)setupPanels { - (void)setupPanels:(nullable UIViewController*)viewController {
[self forceHideBothDrawers]; [self forceHideBothDrawers];
[self setupLeftPanel]; [self setupLeftPanel:viewController];
[self setupRightPanel]; [self setupRightPanel];
self.explictlyShowingPanel = nil; self.explictlyShowingPanel = nil;
[self.view layoutIfNeeded]; [self.view layoutIfNeeded];
@ -968,7 +969,7 @@ CGFloat const PanelAnimationDuration = 0.2;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:coverView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:coverView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
[self setupPanels]; [self setupPanels:nil];
} }
- (void)viewDidLoad { - (void)viewDidLoad {

View File

@ -95,7 +95,7 @@ import MVMCore
groupValid = try validateGroup(group) groupValid = try validateGroup(group)
} catch { } catch {
if let err = MVMCoreErrorObject.createErrorObject(for: error, location: "FormValidator"){ if let err = MVMCoreErrorObject.createErrorObject(for: error, location: "FormValidator"){
MVMCoreLoggingHandler.addError(toLog: err) MVMCoreLoggingHandler.shared()?.addError(toLog: err)
fatalError(err.description) fatalError(err.description)
} }
} }

View File

@ -17,7 +17,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <MVMCoreUI/PublicHeader.h> // In this header, you should import all the public headers of your framework using statements like #import <MVMCoreUI/PublicHeader.h>
#pragma mark - OtherHandlers #pragma mark - OtherHandlers
#import <MVMCoreUI/MVMCoreUISession.h> #import <MVMCoreUI/MVMCoreUISession.h>
#import <MVMCoreUI/MVMCoreUILoggingHandler.h>
#import <MVMCoreUI/MVMCoreUIViewControllerMappingObject.h> #import <MVMCoreUI/MVMCoreUIViewControllerMappingObject.h>
#import <MVMCoreUI/MVMCoreUIViewConstrainingProtocol.h> #import <MVMCoreUI/MVMCoreUIViewConstrainingProtocol.h>

View File

@ -399,7 +399,7 @@ open class NotificationHandler {
try await showNotification(for: json, delegateObject: delegateObject) try await showNotification(for: json, delegateObject: delegateObject)
} catch { } catch {
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "\(self)") { if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "\(self)") {
MVMCoreUILoggingHandler.addError(toLog: errorObject) MVMCoreUILoggingHandler.shared()?.addError(toLog: errorObject)
} }
} }
} }

View File

@ -1,24 +0,0 @@
//
// MVMCoreUILoggingHandler.h
// MVMCoreUI
//
// Created by Scott Pfeil on 1/10/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
@import MVMCore.MVMCoreLoggingHandler;
NS_ASSUME_NONNULL_BEGIN
@interface MVMCoreUILoggingHandler : MVMCoreLoggingHandler
// Page State Logging
- (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller;
// Action Logging
- (void)defaultLogActionForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,23 +0,0 @@
//
// MVMCoreUILoggingHandler.m
// MVMCoreUI
//
// Created by Scott Pfeil on 1/10/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
#import "MVMCoreUILoggingHandler.h"
@implementation MVMCoreUILoggingHandler
- (void)defaultLogPageStateForController:(nonnull id <MVMCoreViewControllerProtocol>)controller {
}
- (void)defaultLogActionForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
}
- (nullable NSDictionary *)defaultGetActionTrackDataDictionaryForController:(nullable id <MVMCoreViewControllerProtocol>)controller actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {
return nil;
}
@end

View File

@ -0,0 +1,16 @@
//
// MVMCoreUILoggingHandler.swift
// MVMCoreUI
//
// Created by Nandhini Rajendran on 29/09/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
@objc open class MVMCoreUILoggingHandler: MVMCoreLoggingHandler {
// Page State Logging
@objc open func defaultLogPageState(forController controller: MVMCoreViewControllerProtocol) { }
// Action Logging
@objc open func defaultLogAction(forController controller: MVMCoreViewControllerProtocol?, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) { }
}

View File

@ -27,10 +27,11 @@
// MARK: Textfield // MARK: Textfield
"textfield_today_string" = "Today"; "textfield_today_string" = "Today";
"textfield_error_message" = "%@.\n The error message.\n %@"; "textfield_error_message" = "%@.\n The error message.\n %@";
"textView_error_message" = "%@.\n The error message.\n %@";
"textfield_picker_item" = " picker item"; "textfield_picker_item" = " picker item";
"textfield_regular" = " regular"; "textfield_regular" = " regular";
"textfield_disabled_state" = "disabled"; "textfield_disabled_state" = "disabled";
"textfield_optional" = "Optional";
// MARK: MDNTextfield // MARK: MDNTextfield
"textfield_contacts_barbutton" = "My Contacts"; "textfield_contacts_barbutton" = "My Contacts";
@ -62,7 +63,7 @@
// MARK: Switch / Toggle // MARK: Switch / Toggle
"mfswitch_buttonlabel" = "Switch Button"; "mfswitch_buttonlabel" = "Switch Button";
"Toggle_buttonlabel" = "Toggle Button"; "Toggle_buttonlabel" = "Toggle";
"AccOn" = "on"; "AccOn" = "on";
"AccOff" = "off"; "AccOff" = "off";
"AccToggleHint" = "double tap to toggle"; "AccToggleHint" = "double tap to toggle";

View File

@ -23,9 +23,11 @@
// Textfield // Textfield
"textfield_today_string" = "Hoy"; "textfield_today_string" = "Hoy";
"textfield_error_message" = "%@.\n El mensaje de error.\n %@"; "textfield_error_message" = "%@.\n El mensaje de error.\n %@";
"textView_error_message" = "%@.\n El mensaje de error.\n %@";
"textfield_picker_item" = " artículo de selector"; "textfield_picker_item" = " artículo de selector";
"textfield_regular" = " regular"; "textfield_regular" = " regular";
"textfield_disabled_state" = "inactivo"; "textfield_disabled_state" = "inactivo";
"textfield_optional" = "Opcional";
//MDNTextfield //MDNTextfield
"textfield_contacts_barbutton" = "Mis contactos"; "textfield_contacts_barbutton" = "Mis contactos";
"textfield_phone_format_error_message" = "Formato de número de teléfono inválido."; "textfield_phone_format_error_message" = "Formato de número de teléfono inválido.";

View File

@ -23,9 +23,11 @@
// Textfield // Textfield
"textfield_today_string" = "Hoy"; "textfield_today_string" = "Hoy";
"textfield_error_message" = "%@.\n El mensaje de error.\n %@"; "textfield_error_message" = "%@.\n El mensaje de error.\n %@";
"textView_error_message" = "%@.\n El mensaje de error.\n %@";
"textfield_picker_item" = " artículo de selector"; "textfield_picker_item" = " artículo de selector";
"textfield_regular" = " regular"; "textfield_regular" = " regular";
"textfield_disabled_state" = "inactivo"; "textfield_disabled_state" = "inactivo";
"textfield_optional" = "Opcional";
//MDNTextfield //MDNTextfield
"textfield_contacts_barbutton" = "Mis contactos"; "textfield_contacts_barbutton" = "Mis contactos";
"textfield_phone_format_error_message" = "Formato de número de teléfono inválido."; "textfield_phone_format_error_message" = "Formato de número de teléfono inválido.";

View File

@ -9,8 +9,11 @@
#import "MFFonts.h" #import "MFFonts.h"
#import <CoreText/CoreText.h> #import <CoreText/CoreText.h>
#import "MVMCoreUIUtility.h" #import "MVMCoreUIUtility.h"
@import MVMCore.MVMCoreLoggingHandler; #import <MVMCore/MVMCoreLoggingHandlerHelper.h>
@import MVMCore.Swift;
@import MVMCore.MVMCoreErrorConstants; @import MVMCore.MVMCoreErrorConstants;
@import MVMCore.MVMCoreLoadHandler;
@import MVMCore.MVMCoreErrorObject;
NSString * const DSBold = @"VerizonNHGeDS-Bold"; NSString * const DSBold = @"VerizonNHGeDS-Bold";
NSString * const DSRegular = @"VerizonNHGeDS-Regular"; NSString * const DSRegular = @"VerizonNHGeDS-Regular";
@ -108,7 +111,7 @@ NSString * const TXRegular = @"VerizonNHGeTX-Regular";
+ (void)validFont:(UIFont *)font fontName:(NSString *)fontName { + (void)validFont:(UIFont *)font fontName:(NSString *)fontName {
if (font == nil) { if (font == nil) {
MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:@"font can not load" message:[NSString stringWithFormat:@"missing font name is %@", fontName] code:ErrorCodeFontNotFound domain:ErrorDomainNative location:@"MFStyler"]; MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:@"font can not load" message:[NSString stringWithFormat:@"missing font name is %@", fontName] code:ErrorCodeFontNotFound domain:ErrorDomainNative location:@"MFStyler"];
[MVMCoreLoggingHandler addErrorToLog:errorObject]; [[MVMCoreLoggingHandler sharedLoggingHandler]addErrorToLog:errorObject];
} }
} }
@end @end