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

# Conflicts:
#	MVMCoreUI/Atomic/Extensions/VDS-TextStyle.swift

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-02-16 10:09:18 -06:00
commit e331f28ca6
5 changed files with 125 additions and 248 deletions

View File

@ -68,23 +68,35 @@ open class TileletModel: MoleculeModelProtocol {
public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? {
guard let title else { return nil }
let attrs = title.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
let style: TextStyle? = title.fontStyle?.vdsTextStyle()
if let style, let standardStyle = Tilelet.TitleModel.StandardStyle(rawValue: style.toStandardStyle().rawValue) {
return .init(text: title.text, textAttributes: attrs, standardStyle: standardStyle)
} else {
return .init(text: title.text, textAttributes: attrs)
}
}
do {
if let style = title.fontStyle {
return .init(text: title.text,
textAttributes: attrs,
standardStyle: try style.vdsSubsetStyle())
}
} catch MVMCoreError.errorObject(let object) {
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
return .init(text: title.text, textAttributes: attrs)
}
public func subTitleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.SubTitleModel? {
guard let subTitle else { return nil }
let attrs = subTitle.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
let style: TextStyle? = subTitle.fontStyle?.vdsTextStyle()
if let style, let standardStyle = Tilelet.SubTitleModel.StandardStyle(rawValue: style.toStandardStyle().rawValue) {
return .init(text: subTitle.text, textAttributes: attrs, standardStyle: standardStyle)
} else {
return .init(text: subTitle.text, textAttributes: attrs)
}
do {
if let style = subTitle.fontStyle {
return .init(text: subTitle.text,
otherStandardStyle: try style.vdsSubsetStyle(),
textAttributes: attrs)
}
} catch MVMCoreError.errorObject(let object) {
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
return .init(text: subTitle.text, textAttributes: attrs)
}
public func encode(to encoder: Encoder) throws {

View File

@ -28,6 +28,7 @@ extension VDS.TextLinkCaret.IconPosition: Codable {}
extension VDS.TileContainer.BackgroundColor: Codable {}
extension VDS.TileContainer.Padding: Codable {}
extension VDS.TileContainer.AspectRatio: Codable {}
extension VDS.TitleLockup.TextAlignment: Codable {}
extension VDS.Tooltip.FillColor: Codable {}
extension VDS.Tooltip.Size: Codable {}
extension VDS.Line.Style: Codable {}

View File

@ -18,14 +18,16 @@ extension Styler.Font {
return style
}
public func vdsSubsetStyle<T: EnumSubset>() -> T? {
guard let style = vdsTextStyle() else { return nil }
guard let rawValue = style.rawValue as? T.RawValue,
let found = T(rawValue: rawValue) else {
print("Style: \(style.rawValue) is not in enum \(T.self)\ronly these cases exist:\r\(T.allCases)")
return nil
public func vdsSubsetStyle<T: EnumSubset>() throws -> T {
guard let style = vdsTextStyle(), let rawValue = style.toStandardStyle().rawValue as? T.RawValue, let standardStyle = T(rawValue: rawValue) else {
let err = "\(rawValue) was not found in the \(T.self), only these cases exist:\r\(T.allCases)"
throw MVMCoreError.errorObject(MVMCoreErrorObject(title: "\(T.self) conversion Issue",
messageToLog: err,
code: 999,
domain: ErrorDomainNative,
location: #file)!)
}
return found
return standardStyle
}
private func mapped() -> Styler.Font {

View File

@ -5,119 +5,43 @@
// Created by Nadigadda, Sumanth on 04/05/22.
// Copyright © 2022 Verizon Wireless. All rights reserved.
//
import VDS
@objcMembers open class TitleLockup: VDS.TitleLockup, VDSMoleculeViewProtocol {
@objcMembers open class TitleLockup: View {
//--------------------------------------------------
// MARK: - Outlets
// MARK: - Public Properties
//--------------------------------------------------
open var viewModel: TitleLockupModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
public let eyebrow = Label(fontStyle: .RegularBodySmall)
public let title = Label(fontStyle: .RegularBodySmall)
public let subTitle = Label(fontStyle: .RegularBodySmall)
public lazy var stack: UIStackView = {
let stack = UIStackView(arrangedSubviews: [eyebrow, title, subTitle])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .vertical
return stack
}()
var castModel: TitleLockupModel? {
get { return model as? TitleLockupModel }
//--------------------------------------------------
// MARK: - Public Functions
//--------------------------------------------------
open func viewModelDidUpdate() {
surface = viewModel.surface
textAlignment = viewModel.textAlignment
eyebrowModel = viewModel.eyebrowModel(delegateObject: delegateObject, additionalData: additionalData)
titleModel = viewModel.titleModel(delegateObject: delegateObject, additionalData: additionalData)
subTitleModel = viewModel.subTitleModel(delegateObject: delegateObject, additionalData: additionalData)
}
//--------------------------------------------------
// MARK: - Initialization
//--------------------------------------------------
public convenience init() {
public convenience required init() {
self.init(frame: .zero)
}
//--------------------------------------------------
// MARK: - MFViewProtocol
//--------------------------------------------------
open override func setupView() {
super.setupView()
addSubview(stack)
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
}
open override func updateView(_ size: CGFloat) {
super.updateView(size)
stack.updateView(size)
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
open override func reset() {
super.reset()
stack.reset()
}
//--------------------------------------------------
// 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? TitleLockupModel else { return }
stack.setCustomSpacing(model.defaultEyebrowTitleSpacing(), after: eyebrow)
stack.setCustomSpacing(model.defaultTitleSubTitleSpacing(), after: title)
stack.updateContainedMolecules(with: [model.eyebrow,
model.title,
model.subTitle],
delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 65
}
//--------------------------------------------------
// MARK: - Accessibility Helpers
//--------------------------------------------------
/// Returns the labels text in one message.
func getAccessibilityMessage() -> String? {
var message = ""
if let eyebrowLabel = eyebrow.text {
message += eyebrowLabel + ", "
}
if let headlineLabel = title.text {
message += headlineLabel + ", "
}
if let bodyLabel = subTitle.text {
message += bodyLabel
}
return message.count > 0 ? message : nil
}
/// Returns an array of the appropriate accessibility elements.
func getAccessibilityElements() -> [Any]? {
var elements: [UIView] = []
if eyebrow.hasText {
elements.append(eyebrow)
}
if title.hasText {
elements.append(title)
}
if subTitle.hasText {
elements.append(subTitle)
}
return elements.count > 0 ? elements : nil
}
open func updateView(_ size: CGFloat) {}
}

View File

@ -7,6 +7,7 @@
//
import VDSColorTokens
import VDS
public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
@ -18,47 +19,16 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
public var moleculeName: String = TitleLockupModel.identifier
public var id: String = UUID().uuidString
public var textAlignment: TitleLockup.TextAlignment = .left
public var eyebrow: LabelModel?
public var title: LabelModel
public var subTitle: LabelModel?
public var subTitleColor: Use = .primary
public var alignment: Alignment = .left {
didSet {
///Updating the text alignment for all labels
if let textAlignment = NSTextAlignment(rawValue: alignment.rawValue) {
eyebrow?.textAlignment = textAlignment
title.textAlignment = textAlignment
subTitle?.textAlignment = textAlignment
}
}
}
public var alignment: VDS.TitleLockup.TextAlignment = .left
public var inverted: Bool = false
public var inverted: Bool = false {
didSet {
///Updating the text color
eyebrow?.textColor = titleColor
title.textColor = titleColor
subTitle?.textColor = subTitleColor
}
}
private var _backgroundColor: Color?
public var backgroundColor: Color? {
get {
return inverted ? Color(uiColor: VDSColor.backgroundPrimaryDark) : Color(uiColor: VDSColor.backgroundPrimaryLight)
}
set {
_backgroundColor = newValue
}
}
public var titleColor: Color? {
return inverted ? Color(uiColor: VDSColor.elementsPrimaryOndark) : Color(uiColor: VDSColor.elementsPrimaryOnlight)
}
public var subTitleColor: Color? {
return inverted ? Color(uiColor: VDSColor.elementsSecondaryOndark) : Color(uiColor: VDSColor.elementsSecondaryOnlight)
}
public var backgroundColor: Color?
public var children: [MoleculeModelProtocol] {
[eyebrow, title, subTitle].compactMap { (molecule: MoleculeModelProtocol?) in molecule }
@ -72,58 +42,6 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
self.eyebrow = eyebrow
self.title = title
self.subTitle = subTitle
updateLabelAttributes()
}
//--------------------------------------------------
// MARK: - Enum
//--------------------------------------------------
public enum Alignment: String, Codable {
case left
case center
}
//--------------------------------------------------
// MARK: - Styling
//--------------------------------------------------
/// Returns the default fontStyle for the subtitle, based on the title fontStyle.
func defaultSubtitleFontStyle() -> Styler.Font {
switch title.fontStyle {
case .RegularTitleXLarge, .RegularTitle2XLarge, .RegularFeatureXSmall:
return .RegularBodyLarge
case .RegularFeatureSmall, .RegularFeatureMedium:
return .RegularTitleLarge
default:
return .RegularBodySmall
}
}
/// Returns the default spacing between the eyebrow and title, based on the title fontStyle.
func defaultEyebrowTitleSpacing() -> CGFloat {
switch title.fontStyle {
case .RegularTitleXLarge, .RegularTitle2XLarge, .RegularFeatureXSmall, .RegularFeatureSmall:
return Padding.Three
case .RegularFeatureMedium:
return subTitle?.fontStyle == .RegularBodyLarge ? Padding.Three : Padding.Four
default:
return Padding.Two
}
}
/// Returns the default spacing between the title and subTitle, based on the title fontStyle.
func defaultTitleSubTitleSpacing() -> CGFloat {
switch title.fontStyle {
case .RegularTitleXLarge:
return Padding.Three
case .RegularTitle2XLarge, .RegularFeatureXSmall, .RegularFeatureSmall:
return Padding.Four
case .RegularFeatureMedium:
return Padding.Five
default:
return Padding.Two
}
}
//--------------------------------------------------
@ -133,10 +51,11 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case backgroundColor
case textAlignment
case eyebrow
case title
case subTitle
case subTitleColor
case inverted
case alignment
}
@ -148,72 +67,91 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
title = try typeContainer.decodeMolecule(codingKey: .title)
textAlignment = try typeContainer.decodeIfPresent(TitleLockup.TextAlignment.self, forKey: .textAlignment) ?? .left
title = try typeContainer.decode(LabelModel.self, forKey: .title)
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
subTitle = try typeContainer.decodeMoleculeIfPresent(codingKey: .subTitle)
if let newAlignment = try typeContainer.decodeIfPresent(Alignment.self, forKey: .alignment) {
subTitle = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .subTitle)
subTitleColor = try typeContainer.decodeIfPresent(Use.self, forKey: .subTitleColor) ?? .primary
if let newAlignment = try typeContainer.decodeIfPresent(VDS.TitleLockup.TextAlignment.self, forKey: .alignment) {
alignment = newAlignment
}
if let invertedStatus = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
inverted = invertedStatus
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
updateLabelAttributes()
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(textAlignment, forKey: .textAlignment)
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
try container.encodeModel(title, forKey: .title)
try container.encodeIfPresent(subTitle, forKey: .subTitle)
try container.encode(subTitleColor, forKey: .subTitleColor)
try container.encode(alignment, forKey: .alignment)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
}
//--------------------------------------------------
// MARK: - Model updates
//--------------------------------------------------
public func eyebrowModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> VDS.TitleLockup.EyebrowModel? {
guard let eyebrow else { return nil }
let attrs = eyebrow.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
do {
if let style = eyebrow.fontStyle {
return .init(text: eyebrow.text,
isBold: style.isBold(),
standardStyle: try style.vdsSubsetStyle(),
textAttributes: attrs,
numberOfLines: eyebrow.numberOfLines ?? 0)
}
} catch MVMCoreError.errorObject(let object) {
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
return .init(text: eyebrow.text, textAttributes: attrs, numberOfLines: eyebrow.numberOfLines ?? 0)
}
public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> VDS.TitleLockup.TitleModel {
let attrs = title.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
do {
if let style = title.fontStyle {
return .init(text: title.text,
textAttributes: attrs,
isBold: style.isBold(),
standardStyle: try style.vdsSubsetStyle(),
numberOfLines: title.numberOfLines ?? 0)
}
private func updateLabelAttributes() {
// If subtitle style is not available, will set font style based on the component
if subTitle?.fontStyle == nil {
subTitle?.fontStyle = defaultSubtitleFontStyle()
}
} catch MVMCoreError.errorObject(let object) {
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
// If eyebrow style is not available, will set font style based on the component. Eyebrow and subtitle share the same font size
if eyebrow?.fontStyle == nil {
eyebrow?.fontStyle = subTitle?.fontStyle
}
return .init(text: title.text, textAttributes: attrs, numberOfLines: title.numberOfLines ?? 0)
}
public func subTitleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> VDS.TitleLockup.SubTitleModel? {
guard let subTitle else { return nil }
let attrs = subTitle.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
// Updating the text color
if eyebrow?.textColor == nil {
eyebrow?.textColor = subTitleColor
}
if title.textColor == nil {
title.textColor = titleColor
}
if subTitle?.textColor == nil {
subTitle?.textColor = subTitleColor
}
// Updating the text alignment for all labels
if let textAlignment = NSTextAlignment(rawValue: alignment.rawValue) {
if eyebrow?.textAlignment == nil {
eyebrow?.textAlignment = textAlignment
do {
if let style = subTitle.fontStyle {
return .init(text: subTitle.text,
otherStandardStyle: try style.vdsSubsetStyle(),
textColor: subTitleColor,
textAttributes: attrs,
numberOfLines: subTitle.numberOfLines ?? 0)
}
if title.textAlignment == nil {
title.textAlignment = textAlignment
}
if subTitle?.textAlignment == nil {
subTitle?.textAlignment = textAlignment
}
}
} catch MVMCoreError.errorObject(let object) {
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
return .init(text: subTitle.text, textColor: subTitleColor, textAttributes: attrs, numberOfLines: subTitle.numberOfLines ?? 0)
}
}
extension TitleLockupModel {
public var surface: Surface { inverted ? .dark : .light }
}