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:
commit
e331f28ca6
@ -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 {
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {}
|
||||
}
|
||||
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user