Merge branch 'feature/ListStoreLocatorMoleculeEnhancement' into 'develop'

ListStoreLocator component enhancement

### Summary
We have got confirmation from businesses to use the existing listStoreLocator molecule instead of having a new one created.
Updated heart with badge as per the new design.

### JIRA Ticket
https://onejira.verizon.com/browse/PRODDEF-5098

Co-authored-by: Keerthy <keerthy.marakanti@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1012
This commit is contained in:
Bruce, Matt R 2023-10-26 16:42:53 +00:00
commit 58afcc596d
2 changed files with 33 additions and 105 deletions

View File

@ -11,149 +11,77 @@
// MARK: - Outlets // MARK: - Outlets
//-------------------------------------------------- //--------------------------------------------------
public let heart = Heart() public let badge = Badge()
public let leftHeadline = Label(fontStyle: .BoldBodySmall) public let leftHeadline = Label(fontStyle: .BoldTitleSmall)
public let leftBody = Label(fontStyle: .RegularBodySmall) public let leftBody = Label(fontStyle: .RegularMicro)
public let leftSubBody = Label(fontStyle: .RegularBodySmall) public let leftSubBody = Label(fontStyle: .RegularBodySmall)
public let rightLabel = Label(fontStyle: .RegularBodySmall) public let rightLabel = Label(fontStyle: .RegularBodySmall)
private lazy var rightLabelStackItem: StackItem = { public var model: ListStoreLocatorModel?
StackItem(andContain: rightLabel)
}()
public lazy var horizontalStack: Stack<StackModel> = { public lazy var horizontalStack: Stack<StackModel> = {
return Stack<StackModel>(with: StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), return Stack<StackModel>(with: StackModel(molecules: [StackItemModel(horizontalAlignment: .fill),
StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .trailing, verticalAlignment: .center)],
StackItemModel(horizontalAlignment: .trailing)], axis: .horizontal, spacing: Padding.Two), stackItems: [StackItem(andContain: stack), StackItem(andContain: rightLabel)])
axis: .horizontal, spacing: Padding.Two), stackItems: [StackItem(andContain: leftHeadline), StackItem(andContain: heart), rightLabelStackItem])
}() }()
public lazy var stack: Stack<StackModel> = { public lazy var stack: Stack<StackModel> = {
return Stack<StackModel>.createStack(with: [horizontalStack, leftBody, leftSubBody], axis: .vertical, spacing: 0) return Stack<StackModel>(with: .init(molecules: [StackItemModel(horizontalAlignment: .leading),
}() StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill)],
public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: 12, standardiPadPortraitSize: 18) axis: .vertical, spacing: Padding.One), stackItems: [StackItem(andContain: badge), StackItem(andContain: leftHeadline), StackItem(andContain: leftBody), StackItem(andContain: leftSubBody)])
}()
//------------------------------------------------------- //-------------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//------------------------------------------------------- //-------------------------------------------------------
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal) rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal) rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: .horizontal)
addMolecule(stack) addMolecule(horizontalStack)
stack.restack() stack.restack()
horizontalStack.restack() horizontalStack.restack()
leftSubBody.textColor = UIColor.mfTextLightGray()
} }
public override func updateView(_ size: CGFloat) {
super.updateView(size)
if let dimension = sizeObject?.getValueBased(onSize: size) {
heart.widthConstraint?.constant = dimension
}
}
//------------------------------------------------------ //------------------------------------------------------
// MARK: - Molecule // MARK: - Molecule
//------------------------------------------------------ //------------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListStoreLocatorModel else { return } guard let model = model as? ListStoreLocatorModel else { return }
horizontalStack.updateContainedMolecules(with: [model.leftHeadline, model.heart, model.rightLabel], delegateObject, additionalData) stack.updateContainedMolecules(with: [model.badge, model.leftHeadline, model.leftBody, model.leftSubBody], delegateObject, additionalData)
leftBody.set(with: model.leftBody, delegateObject, additionalData) rightLabel.set(with: model.rightLabel, delegateObject, additionalData)
leftSubBody.set(with: model.leftSubBody, delegateObject, additionalData) self.model = model
updateAccessibilityLabel() updateAccessibilityLabel()
} }
open override func alignAccessoryToHero() -> CGPoint? {
let heroCenter = super.alignAccessoryToHero()
if let heroCenter = heroCenter {
let convertedPoint = horizontalStack.convert(heroCenter, from: self)
rightLabelStackItem.containerHelper.alignCenterVerticalConstraint?.constant = convertedPoint.y - horizontalStack.bounds.midY
}
return heroCenter
}
public override func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
if listItemModel?.action != nil {
super.didSelectCell(at: index, delegateObject: delegateObject, additionalData: additionalData)
} else {
heart.tapAction()
updateAccessibilityLabel()
}
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 120 } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 120 }
open override func reset() { open override func reset() {
super.reset() super.reset()
leftHeadline.setFontStyle(.BoldBodySmall) leftHeadline.setFontStyle(.BoldTitleSmall)
leftBody.setFontStyle(.RegularBodySmall) leftBody.setFontStyle(.RegularMicro)
leftSubBody.setFontStyle(.RegularBodySmall) leftSubBody.setFontStyle(.RegularBodySmall)
rightLabel.setFontStyle(.RegularBodySmall) rightLabel.setFontStyle(.RegularBodySmall)
leftSubBody.textColor = UIColor.mfTextLightGray()
} }
//--------------------------------------------------
// MARK: - Accessibility
//--------------------------------------------------
func getAccessibilityMessage() -> String? {
var message = ""
heart.updateAccessibilityLabel()
if let leftHeadlineText = leftHeadline.text, !leftHeadlineText.isEmpty {
message += leftHeadlineText + ", "
}
if let leftBodyText = leftBody.text, !leftBodyText.isEmpty {
message += leftBodyText + ", "
}
if let leftSubBodyText = leftSubBody.text, !leftSubBodyText.isEmpty {
message += leftSubBodyText + ", "
}
if let rightLabelText = rightLabel.text, !rightLabelText.isEmpty {
message += rightLabelText
}
return message.count > 0 ? message : nil
}
func updateAccessibilityLabel() {
let hasHeart = !(horizontalStack.stackModel?.molecules[1].gone ?? true)
if let accessoryView = accessoryView,
hasHeart {
// Both accessory and heart actions.
isAccessibilityElement = false
accessoryView.accessibilityLabel = getAccessibilityMessage()
accessibilityElements = [accessoryView, heart]
} else {
// Make whole cell focusable if no action.
isAccessibilityElement = true
var message = getAccessibilityMessage()
if hasHeart {
accessibilityHint = heart.accessibilityHint
if let heartLabel = heart.accessibilityLabel {
message = (message ?? "") + ", " + heartLabel
}
} else {
accessibilityHint = nil
}
accessibilityLabel = message
}
}
// 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 {
if (accessoryView != nil) { if (accessoryView != nil) {
return .button return .button
} else if (!(horizontalStack.stackModel?.molecules[1].gone ?? true)) {
return heart.accessibilityTraits
} else { } else {
return .none return .none
} }
} }
set { } set { }
} }
func updateAccessibilityLabel() {
isAccessibilityElement = true
let message = [model?.badge?.text, model?.leftHeadline.text, model?.leftBody.text, model?.leftSubBody.text, model?.rightLabel.text].compactMap { $0 }.joined(separator: ", ")
accessibilityLabel = message
}
} }

View File

@ -12,7 +12,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
//-------------------------------------------------- //--------------------------------------------------
public static var identifier = "listStoreLocator" public static var identifier = "listStoreLocator"
public var heart: HeartModel? public var badge: BadgeModel?
public var leftHeadline: LabelModel public var leftHeadline: LabelModel
public var leftBody: LabelModel public var leftBody: LabelModel
public var leftSubBody: LabelModel public var leftSubBody: LabelModel
@ -22,8 +22,8 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------
public init(heart: HeartModel?, leftHeadline: LabelModel, leftBody: LabelModel, leftSubBody: LabelModel, rightLabel: LabelModel) { public init(badge: BadgeModel?, leftHeadline: LabelModel, leftBody: LabelModel, leftSubBody: LabelModel, rightLabel: LabelModel) {
self.heart = heart self.badge = badge
self.leftHeadline = leftHeadline self.leftHeadline = leftHeadline
self.leftBody = leftBody self.leftBody = leftBody
self.leftSubBody = leftSubBody self.leftSubBody = leftSubBody
@ -49,7 +49,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case heart case badge
case leftHeadline case leftHeadline
case leftBody case leftBody
case leftSubBody case leftSubBody
@ -62,7 +62,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
public required init(from decoder: Decoder) throws { public required init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self) let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
heart = try typeContainer.decodeIfPresent(HeartModel.self, forKey:.heart) badge = try typeContainer.decodeIfPresent(BadgeModel.self, forKey:.badge)
leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline) leftHeadline = try typeContainer.decode(LabelModel.self, forKey: .leftHeadline)
leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody) leftBody = try typeContainer.decode(LabelModel.self, forKey: .leftBody)
leftSubBody = try typeContainer.decode(LabelModel.self, forKey: .leftSubBody) leftSubBody = try typeContainer.decode(LabelModel.self, forKey: .leftSubBody)
@ -74,7 +74,7 @@ public class ListStoreLocatorModel: ListItemModel, MoleculeModelProtocol {
try super.encode(to: encoder) try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(heart, forKey: .heart) try container.encodeIfPresent(badge, forKey: .badge)
try container.encode(leftHeadline, forKey: .leftHeadline) try container.encode(leftHeadline, forKey: .leftHeadline)
try container.encode(leftBody, forKey: .leftBody) try container.encode(leftBody, forKey: .leftBody)
try container.encode(leftSubBody, forKey: .leftSubBody) try container.encode(leftSubBody, forKey: .leftSubBody)