Merge branch 'feature/monarch' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/monarch
@ -74,7 +74,7 @@ extension BaseItemPickerEntryField {
|
||||
|
||||
@objc open override func setAccessibilityString(_ accessibilityString: String?) {
|
||||
|
||||
var accessibilityString = accessibilityString ?? ""
|
||||
let accessibilityString = accessibilityString ?? ""
|
||||
textField.accessibilityTraits = .staticText
|
||||
textField.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item")
|
||||
textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")"
|
||||
|
||||
@ -397,7 +397,7 @@ extension TextEntryField {
|
||||
|
||||
@objc open override func setAccessibilityString(_ accessibilityString: String?) {
|
||||
|
||||
var accessibilityString = accessibilityString ?? ""
|
||||
let accessibilityString = accessibilityString ?? ""
|
||||
|
||||
textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")"
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
|
||||
/// Sets the current Index to focus on.
|
||||
public var currentIndex: Int = 0
|
||||
public var animated: Bool = true
|
||||
public var hidesForSinglePage: Bool = false
|
||||
public var hidesForSinglePage: Bool = true
|
||||
public var inverted: Bool = false
|
||||
/// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false
|
||||
public var accessibilityHasSlidesInsteadOfPage: Bool = false
|
||||
|
||||
@ -94,7 +94,7 @@ open class HeadlineBodyModel: ParentMoleculeModelProtocol {
|
||||
public extension HeadlineBodyModel {
|
||||
func createHeaderTitleLockupModel(defaultStyle: Style = .header) throws -> TitleLockupModel {
|
||||
guard let headline = headline else { throw ModelRegistry.Error.decoderOther(message: "headline is required for this use case.") }
|
||||
var body = self.body
|
||||
let body = self.body
|
||||
switch style ?? defaultStyle {
|
||||
case .landingHeader:
|
||||
headline.fontStyle = Styler.Font.RegularTitle2XLarge
|
||||
@ -106,7 +106,7 @@ public extension HeadlineBodyModel {
|
||||
headline.fontStyle = Styler.Font.RegularTitleXLarge
|
||||
body?.fontStyle = Styler.Font.RegularTitleMedium
|
||||
}
|
||||
let model = try TitleLockupModel(title: headline, subTitle: body)
|
||||
let model = TitleLockupModel(title: headline, subTitle: body)
|
||||
model.id = id
|
||||
return model
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ open class Carousel: View {
|
||||
public var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
private var size: CGFloat?
|
||||
|
||||
|
||||
// Updates the model and index.
|
||||
public func updateModelIndex() {
|
||||
(model as? CarouselModel)?.index = pageIndex
|
||||
@ -90,12 +90,29 @@ open class Carousel: View {
|
||||
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.
|
||||
guard let model = model as? CarouselModel, !model.molecules.isEmpty,
|
||||
(model.paging == true || loop == true) else { return }
|
||||
guard let model = model as? CarouselModel, !model.molecules.isEmpty else { return }
|
||||
guard (model.paging == true || loop == true) else {
|
||||
DispatchQueue.main.async { [self] in
|
||||
updatePagerVisibility()
|
||||
}
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async { [self] in
|
||||
collectionView.scrollToItem(at: IndexPath(row: currentIndex, section: 0), at: itemAlignment, animated: false)
|
||||
collectionView.layoutIfNeeded()
|
||||
showPeaking(true)
|
||||
updatePagerVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates if the pager is visible or not.
|
||||
private func updatePagerVisibility() {
|
||||
guard let pagingView = pagingView else { return }
|
||||
let shouldHidePager = collectionView.contentSize.width < bounds.width
|
||||
if (shouldHidePager && !pagingView.isHidden) || (!shouldHidePager && pagingView.isHidden) {
|
||||
pagingView.isHidden = shouldHidePager
|
||||
pagingBottomPin?.isActive = !shouldHidePager
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,16 +157,6 @@ open class Carousel: View {
|
||||
(cell as? MVMCoreViewProtocol)?.updateView(size)
|
||||
}
|
||||
layoutCollection()
|
||||
|
||||
// Check must be dispatched to main for the layout to complete in layoutCollection.
|
||||
DispatchQueue.main.async { [self] in
|
||||
let shouldHidePager = molecules?.count ?? 0 < 2 || collectionView.contentSize.width < bounds.width
|
||||
if let pagingView = pagingView, shouldHidePager != pagingView.isHidden {
|
||||
pagingView.isHidden = shouldHidePager
|
||||
pagingBottomPin?.isActive = !shouldHidePager
|
||||
delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -244,7 +251,7 @@ open class Carousel: View {
|
||||
|
||||
var pagingView: (MoleculeViewProtocol & CarouselPageControlProtocol)? = nil
|
||||
if let molecule = molecule,
|
||||
(!molecule.hidesForSinglePage || numberOfPages > 1) {
|
||||
(numberOfPages > 1 || !molecule.hidesForSinglePage) {
|
||||
pagingView = ModelRegistry.createMolecule(molecule, delegateObject: delegateObject) as? (MoleculeViewProtocol & CarouselPageControlProtocol)
|
||||
pagingMoleculeName = molecule.moleculeName
|
||||
} else {
|
||||
|
||||
@ -35,16 +35,16 @@ public class PageGetContactBehavior: PageVisibilityBehavior {
|
||||
CNContactStore().requestAccess(for: .contacts) { [weak self] (access, error) in
|
||||
guard access,
|
||||
error == nil,
|
||||
let rootMolecules = self?.delegate?.moleculeDelegate?.getRootMolecules() else { return }
|
||||
let rootMolecules = delegateObject?.moleculeDelegate?.getRootMolecules() else { return }
|
||||
// Iterate models and provide contact
|
||||
self?.getContacts(for: rootMolecules)
|
||||
|
||||
// Tell template to update
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||
Task { @MainActor in
|
||||
// TODO: move to protocol function instead
|
||||
guard let controller = self?.delegate?.moleculeDelegate as? ViewController else { return }
|
||||
guard let controller = delegateObject?.moleculeDelegate as? ViewController else { return }
|
||||
controller.handleNewData()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ extension UIColor {
|
||||
/// Dictionary to access brand approved colors by name.
|
||||
public static let names: [String: ColorHexTuple] = ["black": (.mvmBlack, "#000000"),
|
||||
"white": (.mvmWhite, "#FFFFFF"),
|
||||
"red": (.mvmRed, "#F50A23"),
|
||||
"red": (.mvmRed, "#EE0000"),
|
||||
"pink": (.mvmPink, "#D90368"),
|
||||
"pink33": (.mvmPink33, "#F2ABCD"),
|
||||
"pink66": (.mvmPink66, "#E6589B"),
|
||||
@ -88,7 +88,7 @@ extension UIColor {
|
||||
// MARK: - Red
|
||||
//--------------------------------------------------
|
||||
|
||||
/// HEX: ##F50A23
|
||||
/// HEX: #EE0000
|
||||
@objc
|
||||
public static let mvmRed = UIColor.assetColor(named: "red")
|
||||
|
||||
@ -256,6 +256,7 @@ extension UIColor {
|
||||
return UIColor(named: name, in: MVMCoreUIUtility.bundleForMVMCoreUI(), compatibleWith: nil)!
|
||||
}
|
||||
|
||||
/// Returns a color corresponding to the passed in color name.
|
||||
@objc
|
||||
public static func mvmCoreUIColor(with name: String) -> UIColor? {
|
||||
return UIColor.names[name]?.uiColor
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
#pragma mark - legacy
|
||||
|
||||
+ (nonnull UIColor *)mfRedColor {
|
||||
return [UIColor colorWithRed:.804 green:.016 blue:.043 alpha:1.0];
|
||||
return [UIColor mvmRed];
|
||||
}
|
||||
|
||||
+ (nonnull UIColor *)mfDarkerRedColor {
|
||||
@ -299,6 +299,10 @@
|
||||
}
|
||||
|
||||
+ (nullable UIColor *)mfGetColorForString:(nullable NSString *)string {
|
||||
if ([string hasPrefix:@"#"]) {
|
||||
return [self mfGetColorForHex:string];
|
||||
}
|
||||
|
||||
static NSDictionary *stringColorMapping;
|
||||
static dispatch_once_t once;
|
||||
dispatch_once(&once, ^{
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MVMCore
|
||||
|
||||
extension UIStackView: MVMCoreViewProtocol {
|
||||
public func updateView(_ size: CGFloat) {
|
||||
@ -16,7 +17,7 @@ extension UIStackView: MVMCoreViewProtocol {
|
||||
}
|
||||
|
||||
/// A convenience function for updating molecules. If model is nil, view is hidden.
|
||||
open func updateContainedMolecules(with models: [MoleculeModelProtocol?], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
public func updateContainedMolecules(with models: [MoleculeModelProtocol?], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
for (index, item) in arrangedSubviews.enumerated() {
|
||||
if let model = models[index] {
|
||||
(item as? MoleculeViewProtocol)?.set(with: model, delegateObject, additionalData)
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x23",
|
||||
"green" : "0x0A",
|
||||
"red" : "0xF5"
|
||||
"blue" : "0x00",
|
||||
"green" : "0x00",
|
||||
"red" : "0xEE"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
@ -404,7 +404,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
|
||||
|
||||
public func update(percentage: CGFloat) {
|
||||
guard customInteractor?.interactive == true,
|
||||
let index = index else { return }
|
||||
let _ = index else { return }
|
||||
// tabs.progress(from: tabs.selectedIndex, toIndex: index, percentage: percentage)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,23 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "exportBlack.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "exportBlack@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "exportBlack@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename" : "Vector.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Vector.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 -3.05176e-05V7.11108H18.7555V2.1333L11.9555 8.9333L11.0666 8.04441L17.8666 1.25553H12.8889V-3.05176e-05H20ZM15 18.7555H1.25553V4.99997H12.2222L13.3333 3.75552H-2.28882e-05V20H16.2555V6.66664L15 7.77775V18.7555Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 343 B |
|
Before Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 589 B |
|
Before Width: | Height: | Size: 869 B |
@ -1,23 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "nav_back.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "nav_back@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "nav_back@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"filename" : "Vector.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
||||
|
||||
3
MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Vector.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 10.6361H2.46073L10.9975 19.1001L10.0897 20L0 10L10.0897 0L10.9974 0.899867L2.46077 9.36388H20V10.6361Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 235 B |
|
Before Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 302 B |
|
Before Width: | Height: | Size: 394 B |
|
Before Width: | Height: | Size: 435 B |
|
Before Width: | Height: | Size: 631 B |
|
Before Width: | Height: | Size: 257 B |
@ -1,23 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Close.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Close-1.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Close-2.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"filename" : "Vector.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
||||
|
||||
3
MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Vector.svg
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.87772 9.00001L17.7777 16.8889L16.8888 17.7778L8.99995 9.87778L1.11106 17.7778L0.222168 16.8889L8.11106 9.00001L0.222168 1.11112L1.11106 0.222229L8.99995 8.11112L16.8888 0.222229L17.7777 1.11112L9.87772 9.00001Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 342 B |