adding accessibility id. formatting. adding test logic.

This commit is contained in:
Kevin G Christiano 2020-12-17 13:03:25 -05:00
parent 7dcf1279b7
commit 9baf9e7d0d
14 changed files with 137 additions and 35 deletions

View File

@ -71,6 +71,7 @@ import UIKit
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
open override func setupView() {
super.setupView()
addTarget(self, action: #selector(tapAction), for: .touchUpInside)
@ -88,6 +89,7 @@ import UIKit
self.delegateObject = delegateObject
self.additionalData = additionalData
guard let model = model as? HeartModel else { return }
accessibilityIdentifier = model.accessibilityIdentifier
isSelected = model.isActive
}

View File

@ -6,15 +6,15 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class HeartModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "heart"
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var isActive: Bool = false
public var activeColor: Color = Color(uiColor: .mvmRed)
public var inActiveColor: Color = Color(uiColor: .clear)
@ -23,9 +23,11 @@ open class HeartModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case accessibilityIdentifier
case isActive
case activeColor
case inActiveColor
@ -41,13 +43,18 @@ open class HeartModel: MoleculeModelProtocol {
if let isActive = try typeContainer.decodeIfPresent(Bool.self, forKey: .isActive) {
self.isActive = isActive
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let activeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor) {
self.activeColor = activeColor
}
if let inActiveColor = try typeContainer.decodeIfPresent(Color.self, forKey: .inActiveColor) {
self.inActiveColor = inActiveColor
}
if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) {
self.action = action
}
@ -56,6 +63,7 @@ open class HeartModel: MoleculeModelProtocol {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(isActive, forKey: .isActive)
try container.encode(activeColor, forKey: .activeColor)

View File

@ -6,9 +6,12 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class RadioBox: Control, MFButtonProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public let label = Label(fontStyle: .RegularBodySmall)
public let subTextLabel = Label(fontStyle: .RegularMicro)
public var isOutOfStock = false
@ -26,22 +29,20 @@ open class RadioBox: Control, MFButtonProtocol {
var additionalData: [AnyHashable: Any]?
public var radioBoxModel: RadioBoxModel? {
return model as? RadioBoxModel
model as? RadioBoxModel
}
public override var isSelected: Bool {
didSet {
updateAccessibility()
}
didSet { updateAccessibility() }
}
public override var isEnabled: Bool {
didSet {
updateAccessibility()
}
didSet { updateAccessibility() }
}
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open override func updateView(_ size: CGFloat) {
super.updateView(size)
@ -75,8 +76,6 @@ open class RadioBox: Control, MFButtonProtocol {
isAccessibilityElement = true
}
// MARK: - MoleculeViewProtocol
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? RadioBoxModel else { return }
@ -86,6 +85,7 @@ open class RadioBox: Control, MFButtonProtocol {
subTextLabel.text = model.subText
isOutOfStock = model.strikethrough
subTextLabelHeightConstraint?.isActive = (subTextLabel.text?.count ?? 0) == 0
accessibilityIdentifier = model.accessibilityIdentifier
if let color = model.selectedAccentColor?.uiColor {
accentColor = color
}
@ -99,7 +99,9 @@ open class RadioBox: Control, MFButtonProtocol {
accentColor = .mvmRed
}
//--------------------------------------------------
// MARK: - State Handling
//--------------------------------------------------
open override func draw(_ layer: CALayer, in ctx: CGContext) {
// Draw the strikethrough
@ -213,21 +215,29 @@ open class RadioBox: Control, MFButtonProtocol {
return mask
}
//--------------------------------------------------
// MARK: - Accessibility
//--------------------------------------------------
public func updateAccessibility() {
var message = ""
if let labelText = label.text, label.hasText {
message += labelText + ", "
}
if let subLabelText = subTextLabel.text, subTextLabel.hasText {
message += subLabelText + ", "
}
accessibilityLabel = message
accessibilityLabel = message
accessibilityTraits = .button
if isSelected {
accessibilityTraits.insert(.selected)
}
if !isEnabled {
accessibilityTraits.insert(.notEnabled)
}

View File

@ -6,10 +6,17 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class RadioBoxCollectionViewCell: CollectionViewCell {
//--------------------------------------------------
// MARK: - Outlets
//--------------------------------------------------
public let radioBox = RadioBox()
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
open override func reset() {
super.reset()
backgroundColor = .clear

View File

@ -6,12 +6,16 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class RadioBoxModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioBox"
public var text: String
public var subText: String?
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var selectedAccentColor: Color?
public var selected: Bool = false
public var enabled: Bool = true
@ -19,12 +23,17 @@ import Foundation
public var fieldValue: String?
public var action: ActionModelProtocol?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case text
case subText
case selectedAccentColor
case backgroundColor
case accessibilityIdentifier
case selected
case enabled
case strikethrough
@ -32,18 +41,26 @@ import Foundation
case action
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
text = try typeContainer.decode(String.self, forKey: .text)
subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText)
selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
selected = isSelected
}
if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
enabled = isEnabled
}
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
strikethrough = isStrikeTrough
}
@ -59,6 +76,7 @@ import Foundation
try container.encodeIfPresent(subText, forKey: .subText)
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(selected, forKey: .selected)
try container.encode(enabled, forKey: .enabled)
try container.encode(strikethrough, forKey: .strikethrough)

View File

@ -57,11 +57,13 @@ open class RadioBoxes: View {
super.set(with: model, delegateObject, additionalData)
self.delegateObject = delegateObject
guard let radioBoxesModel = model as? RadioBoxesModel else { return }
boxes = radioBoxesModel.boxes
FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate)
guard let model = model as? RadioBoxesModel else { return }
boxes = model.boxes
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
backgroundColor = radioBoxesModel.backgroundColor?.uiColor
backgroundColor = model.backgroundColor?.uiColor
accessibilityIdentifier = model.accessibilityIdentifier
registerCells()
setHeight()
collectionView.reloadData()
@ -168,4 +170,3 @@ extension RadioBoxes: UICollectionViewDelegate {
cell.updateAccessibility()
}
}

View File

@ -6,17 +6,25 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class RadioBoxesModel: MoleculeModelProtocol, FormFieldProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioBoxes"
public var boxes: [RadioBoxModel]
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var selectedAccentColor: Color?
public var boxesColor: Color?
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
/// Returns the fieldValue of the selected box, otherwise the text of the selected box.
public func formFieldValue() -> AnyHashable? {
let selectedBox = boxes.first { (box) -> Bool in
@ -25,20 +33,30 @@ import Foundation
return selectedBox?.fieldValue ?? selectedBox?.text
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case selectedAccentColor
case backgroundColor
case accessibilityIdentifier
case boxesColor
case boxes
case fieldKey
case groupName
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
boxesColor = try typeContainer.decodeIfPresent(Color.self, forKey: .boxesColor)
boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
@ -54,6 +72,7 @@ import Foundation
try container.encode(boxes, forKey: .boxes)
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encode(groupName, forKey: .groupName)
}

View File

@ -6,8 +6,6 @@
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class RadioButtonSelectionHelper: FormFieldProtocol {
//--------------------------------------------------
@ -77,7 +75,5 @@ import Foundation
// MARK: - FormValidationFormFieldProtocol
extension RadioButtonSelectionHelper {
public func formFieldValue() -> AnyHashable? {
return selectedRadioButtonModel?.fieldValue
}
public func formFieldValue() -> AnyHashable? { selectedRadioButtonModel?.fieldValue }
}

View File

@ -62,6 +62,7 @@ open class RadioSwatch: Control, MFButtonProtocol {
guard let model = model as? RadioSwatchModel else { return }
self.delegateObject = delegateObject
self.additionalData = additionalData
accessibilityIdentifier = model.accessibilityIdentifier
bottomText.text = model.text
isSelected = model.selected
isEnabled = model.enabled
@ -77,6 +78,7 @@ open class RadioSwatch: Control, MFButtonProtocol {
//------------------------------------------------------
// MARK: - State Handling
//------------------------------------------------------
open override func draw(_ layer: CALayer, in ctx: CGContext) {
//Draw the swatch
circleLayer?.removeFromSuperlayer()

View File

@ -6,7 +6,7 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
open class RadioSwatchCollectionViewCell: CollectionViewCell {
public let radioSwatch = RadioSwatch()

View File

@ -6,11 +6,15 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class RadioSwatchModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioSwatch"
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var color: Color = Color(uiColor: .mvmBlue)
public var text: String?
public var selected: Bool = false
@ -19,9 +23,14 @@ import Foundation
public var fieldValue: String?
public var action: ActionModelProtocol?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case accessibilityIdentifier
case color
case text
case selected
@ -31,22 +40,33 @@ import Foundation
case action
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
self.color = color
}
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
if let selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
self.selected = selected
}
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.enabled = enabled
}
if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
self.strikethrough = strikethrough
}
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
}
@ -55,6 +75,7 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(color, forKey: .color)
try container.encodeIfPresent(text, forKey: .text)
try container.encode(selected, forKey: .selected)
@ -64,5 +85,3 @@ import Foundation
try container.encodeModelIfPresent(action, forKey: .action)
}
}

View File

@ -55,9 +55,10 @@ open class RadioSwatches: View {
super.set(with: model, delegateObject, additionalData)
self.delegateObject = delegateObject
guard let radioSwatchesModel = model as? RadioSwatchesModel else { return }
swatches = radioSwatchesModel.swatches
FormValidator.setupValidation(for: radioSwatchesModel, delegate: delegateObject?.formHolderDelegate)
guard let model = model as? RadioSwatchesModel else { return }
swatches = model.swatches
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
accessibilityIdentifier = model.accessibilityIdentifier
collectionView.reloadData()
}

View File

@ -6,16 +6,24 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class RadioSwatchesModel: MoleculeModelProtocol, FormFieldProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioSwatches"
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var swatches: [RadioSwatchModel]
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
/// Returns the fieldValue of the selected swatch, otherwise the text of selected swatch.
public func formFieldValue() -> AnyHashable? {
let selectedSwatch = swatches.first { (swatch) -> Bool in
@ -24,17 +32,27 @@ import Foundation
return selectedSwatch?.fieldValue ?? selectedSwatch?.text
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case accessibilityIdentifier
case swatches
case fieldKey
case groupName
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .backgaccessibilityIdentifierroundColor)
swatches = try typeContainer.decode([RadioSwatchModel].self, forKey: .swatches)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
@ -47,6 +65,7 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(swatches, forKey: .swatches)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encode(groupName, forKey: .groupName)

View File

@ -1104,7 +1104,7 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
}
+ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string {
return [MFStyler styleGetRegularBodySmallAttributedString:string genericScaling:YES];
return [MFStyler styleGetRegularMicroAttributedString:string genericScaling:YES];
}
+ (nonnull NSAttributedString *)styleGetRegularMicroAttributedString:(nullable NSString *)string genericScaling:(BOOL)genericScaling {