Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/monarch
This commit is contained in:
commit
0033009bb9
@ -572,9 +572,15 @@
|
|||||||
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
||||||
EA05EFA9278DDE2C00828819 /* ClearFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */; };
|
EA05EFA9278DDE2C00828819 /* ClearFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */; };
|
||||||
EA05EFAB278DE53600828819 /* ClearableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */; };
|
EA05EFAB278DE53600828819 /* ClearableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */; };
|
||||||
|
EA1758482BC97ED800A5C0D9 /* BadgeIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1758472BC97ED800A5C0D9 /* BadgeIndicator.swift */; };
|
||||||
|
EA17584A2BC97EF100A5C0D9 /* BadgeIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1758492BC97EF100A5C0D9 /* BadgeIndicatorModel.swift */; };
|
||||||
|
EA17584C2BC9894800A5C0D9 /* ButtonIconModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA17584B2BC9894800A5C0D9 /* ButtonIconModel.swift */; };
|
||||||
|
EA17584E2BC9895A00A5C0D9 /* ButtonIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA17584D2BC9895A00A5C0D9 /* ButtonIcon.swift */; };
|
||||||
EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; };
|
EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; };
|
||||||
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; };
|
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; };
|
||||||
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
|
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
|
||||||
|
EA6642912BCDA97300D81DC4 /* TileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642902BCDA97300D81DC4 /* TileContainer.swift */; };
|
||||||
|
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */; };
|
||||||
EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B942B504A43000139B4 /* ButtonGroup.swift */; };
|
EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B942B504A43000139B4 /* ButtonGroup.swift */; };
|
||||||
EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */; };
|
EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */; };
|
||||||
EA7D81602B2B6E6800D29F9E /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D815F2B2B6E6800D29F9E /* Icon.swift */; };
|
EA7D81602B2B6E6800D29F9E /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D815F2B2B6E6800D29F9E /* Icon.swift */; };
|
||||||
@ -1177,9 +1183,15 @@
|
|||||||
DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = "<group>"; };
|
DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = "<group>"; };
|
||||||
EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearableModelProtocol.swift; sourceTree = "<group>"; };
|
EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearableModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
EA1758472BC97ED800A5C0D9 /* BadgeIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeIndicator.swift; sourceTree = "<group>"; };
|
||||||
|
EA1758492BC97EF100A5C0D9 /* BadgeIndicatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeIndicatorModel.swift; sourceTree = "<group>"; };
|
||||||
|
EA17584B2BC9894800A5C0D9 /* ButtonIconModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIconModel.swift; sourceTree = "<group>"; };
|
||||||
|
EA17584D2BC9895A00A5C0D9 /* ButtonIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIcon.swift; sourceTree = "<group>"; };
|
||||||
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = "<group>"; };
|
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = "<group>"; };
|
||||||
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
|
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
|
||||||
|
EA6642902BCDA97300D81DC4 /* TileContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainer.swift; sourceTree = "<group>"; };
|
||||||
|
EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainerModel.swift; sourceTree = "<group>"; };
|
||||||
EA6E8B942B504A43000139B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
|
EA6E8B942B504A43000139B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
|
||||||
EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupModel.swift; sourceTree = "<group>"; };
|
EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupModel.swift; sourceTree = "<group>"; };
|
||||||
EA7D815F2B2B6E6800D29F9E /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = "<group>"; };
|
EA7D815F2B2B6E6800D29F9E /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = "<group>"; };
|
||||||
@ -2267,6 +2279,12 @@
|
|||||||
AA07EA922510A451009A2AE3 /* Star.swift */,
|
AA07EA922510A451009A2AE3 /* Star.swift */,
|
||||||
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */,
|
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */,
|
||||||
B4CC8FBC29DF34680005D28B /* Badge.swift */,
|
B4CC8FBC29DF34680005D28B /* Badge.swift */,
|
||||||
|
EA1758492BC97EF100A5C0D9 /* BadgeIndicatorModel.swift */,
|
||||||
|
EA1758472BC97ED800A5C0D9 /* BadgeIndicator.swift */,
|
||||||
|
EA17584B2BC9894800A5C0D9 /* ButtonIconModel.swift */,
|
||||||
|
EA17584D2BC9895A00A5C0D9 /* ButtonIcon.swift */,
|
||||||
|
EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */,
|
||||||
|
EA6642902BCDA97300D81DC4 /* TileContainer.swift */,
|
||||||
EA985C3F2970939A00F2FF2E /* TileletModel.swift */,
|
EA985C3F2970939A00F2FF2E /* TileletModel.swift */,
|
||||||
EA985C3D2970938F00F2FF2E /* Tilelet.swift */,
|
EA985C3D2970938F00F2FF2E /* Tilelet.swift */,
|
||||||
EA7D81612B2B6E7F00D29F9E /* IconModel.swift */,
|
EA7D81612B2B6E7F00D29F9E /* IconModel.swift */,
|
||||||
@ -2685,6 +2703,7 @@
|
|||||||
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,
|
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,
|
||||||
AAE96FA225341F6A0037A989 /* ListStoreLocatorModel.swift in Sources */,
|
AAE96FA225341F6A0037A989 /* ListStoreLocatorModel.swift in Sources */,
|
||||||
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */,
|
D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */,
|
||||||
|
EA17584A2BC97EF100A5C0D9 /* BadgeIndicatorModel.swift in Sources */,
|
||||||
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */,
|
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */,
|
||||||
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */,
|
AAB9C10824346F4B00151545 /* RadioSwatches.swift in Sources */,
|
||||||
94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */,
|
94C2D9A923872E5E0006CF46 /* LabelAttributeImageModel.swift in Sources */,
|
||||||
@ -2909,6 +2928,7 @@
|
|||||||
D22479942316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift in Sources */,
|
D22479942316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift in Sources */,
|
||||||
D2B18B94236214AD00A9AEDC /* NavigationController.swift in Sources */,
|
D2B18B94236214AD00A9AEDC /* NavigationController.swift in Sources */,
|
||||||
0A9D09222433796500D2E6C0 /* CarouselIndicator.swift in Sources */,
|
0A9D09222433796500D2E6C0 /* CarouselIndicator.swift in Sources */,
|
||||||
|
EA17584E2BC9895A00A5C0D9 /* ButtonIcon.swift in Sources */,
|
||||||
D29E28DA23D21AFA00ACEA85 /* StringAndMoleculeModel.swift in Sources */,
|
D29E28DA23D21AFA00ACEA85 /* StringAndMoleculeModel.swift in Sources */,
|
||||||
D260105D23D0BCD400764D80 /* Stack.swift in Sources */,
|
D260105D23D0BCD400764D80 /* Stack.swift in Sources */,
|
||||||
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */,
|
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */,
|
||||||
@ -2936,6 +2956,7 @@
|
|||||||
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */,
|
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */,
|
||||||
8DE5BECD2456F7A200772E76 /* ListTwoColumnDropdownSelectorsModel.swift in Sources */,
|
8DE5BECD2456F7A200772E76 /* ListTwoColumnDropdownSelectorsModel.swift in Sources */,
|
||||||
AA7F47732541AD560015A2C1 /* ListStarRatingModel.swift in Sources */,
|
AA7F47732541AD560015A2C1 /* ListStarRatingModel.swift in Sources */,
|
||||||
|
EA17584C2BC9894800A5C0D9 /* ButtonIconModel.swift in Sources */,
|
||||||
AA7F47762541AD6A0015A2C1 /* ListStarRating.swift in Sources */,
|
AA7F47762541AD6A0015A2C1 /* ListStarRating.swift in Sources */,
|
||||||
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */,
|
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */,
|
||||||
AF7E509829E477C1009DC2AD /* AlertHandler.swift in Sources */,
|
AF7E509829E477C1009DC2AD /* AlertHandler.swift in Sources */,
|
||||||
@ -2990,6 +3011,7 @@
|
|||||||
D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */,
|
D264FAAC2441009400D98315 /* RadioBoxCollectionViewCell.swift in Sources */,
|
||||||
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */,
|
BB2C969224330F73006FF80C /* ListRightVariableTextLinkAllTextAndLinks.swift in Sources */,
|
||||||
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
||||||
|
EA1758482BC97ED800A5C0D9 /* BadgeIndicator.swift in Sources */,
|
||||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||||
0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */,
|
0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */,
|
||||||
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
||||||
@ -3054,6 +3076,7 @@
|
|||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||||
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
|
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
|
||||||
D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */,
|
D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */,
|
||||||
|
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */,
|
||||||
AF7E509929E477C1009DC2AD /* AlertController.swift in Sources */,
|
AF7E509929E477C1009DC2AD /* AlertController.swift in Sources */,
|
||||||
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
|
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
|
||||||
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */,
|
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */,
|
||||||
@ -3181,6 +3204,7 @@
|
|||||||
D29C559625C099630082E7D6 /* VideoDataManager.swift in Sources */,
|
D29C559625C099630082E7D6 /* VideoDataManager.swift in Sources */,
|
||||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
||||||
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
||||||
|
EA6642912BCDA97300D81DC4 /* TileContainer.swift in Sources */,
|
||||||
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
||||||
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */,
|
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */,
|
||||||
EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */,
|
EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */,
|
||||||
|
|||||||
70
MVMCoreUI/Atomic/Atoms/Views/BadgeIndicator.swift
Normal file
70
MVMCoreUI/Atomic/Atoms/Views/BadgeIndicator.swift
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// BadgeIndicator.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/12/24.
|
||||||
|
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDS
|
||||||
|
|
||||||
|
open class BadgeIndicator: VDS.BadgeIndicator, VDSMoleculeViewProtocol {
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Public Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public var viewModel: BadgeIndicatorModel!
|
||||||
|
|
||||||
|
public var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
|
public var additionalData: [AnyHashable : Any]?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Public Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func viewModelDidUpdate() {
|
||||||
|
surface = viewModel.surface
|
||||||
|
number = viewModel.number
|
||||||
|
fillColor = viewModel.fillColor
|
||||||
|
borderColorLight = viewModel.borderColorLight?.uiColor
|
||||||
|
borderColorDark = viewModel.borderColorDark?.uiColor
|
||||||
|
kind = viewModel.kind
|
||||||
|
maximumDigits = viewModel.maximumDigits
|
||||||
|
size = viewModel.size
|
||||||
|
leadingCharacter = viewModel.leadingCharacter
|
||||||
|
trailingText = viewModel.trailingText
|
||||||
|
dotSize = viewModel.dotSize
|
||||||
|
verticalPadding = viewModel.verticalPadding
|
||||||
|
horizontalPadding = viewModel.horizontalPadding
|
||||||
|
hideDot = viewModel.hideDot
|
||||||
|
hideBorder = viewModel.hideBorder
|
||||||
|
width = viewModel.width
|
||||||
|
height = viewModel.height
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateView(_ size: CGFloat) {}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Overrides
|
||||||
|
//--------------------------------------------------
|
||||||
|
open override func updateAccessibility() {
|
||||||
|
super.updateAccessibility()
|
||||||
|
|
||||||
|
if let viewModel {
|
||||||
|
if let accessibilityText = viewModel.accessibilityText {
|
||||||
|
self.accessibilityLabel = accessibilityText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//to deal with how it's parent constrains this control
|
||||||
|
extension BadgeIndicator: MVMCoreUIViewConstrainingProtocol {
|
||||||
|
|
||||||
|
public func needsToBeConstrained() -> Bool { true }
|
||||||
|
|
||||||
|
public func horizontalAlignment() -> UIStackView.Alignment { .leading }
|
||||||
|
}
|
||||||
111
MVMCoreUI/Atomic/Atoms/Views/BadgeIndicatorModel.swift
Normal file
111
MVMCoreUI/Atomic/Atoms/Views/BadgeIndicatorModel.swift
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
//
|
||||||
|
// BadgeIndicatorModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/12/24.
|
||||||
|
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDS
|
||||||
|
|
||||||
|
|
||||||
|
open class BadgeIndicatorModel: MoleculeModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public static var identifier: String { "badgeIndicator" }
|
||||||
|
public var id: String = UUID().uuidString
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - VDS Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public var surface: Surface { inverted ? .dark : .light }
|
||||||
|
public var inverted: Bool = false
|
||||||
|
public var number: Int?
|
||||||
|
public var accessibilityText: String?
|
||||||
|
public var fillColor = BadgeIndicator.FillColor.red
|
||||||
|
public var borderColorLight: Color?
|
||||||
|
public var borderColorDark: Color?
|
||||||
|
public var kind = BadgeIndicator.Kind.simple
|
||||||
|
public var maximumDigits = BadgeIndicator.MaximumDigits.two
|
||||||
|
public var size = BadgeIndicator.Size.xxlarge
|
||||||
|
public var leadingCharacter: String?
|
||||||
|
public var trailingText: String?
|
||||||
|
public var dotSize: CGFloat?
|
||||||
|
public var verticalPadding: CGFloat?
|
||||||
|
public var horizontalPadding: CGFloat?
|
||||||
|
public var hideDot: Bool = false
|
||||||
|
public var hideBorder: Bool = false
|
||||||
|
public var width: CGFloat?
|
||||||
|
public var height: CGFloat?
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
case inverted
|
||||||
|
case accessibilityText
|
||||||
|
case number
|
||||||
|
case fillColor
|
||||||
|
case borderColorLight
|
||||||
|
case borderColorDark
|
||||||
|
case kind
|
||||||
|
case maximumDigits
|
||||||
|
case size
|
||||||
|
case leadingCharacter
|
||||||
|
case trailingText
|
||||||
|
case dotSize
|
||||||
|
case verticalPadding
|
||||||
|
case horizontalPadding
|
||||||
|
case hideDot
|
||||||
|
case hideBorder
|
||||||
|
case width
|
||||||
|
case height
|
||||||
|
}
|
||||||
|
|
||||||
|
required public convenience init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
self.init()
|
||||||
|
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
||||||
|
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
|
||||||
|
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
|
number = try container.decodeIfPresent(Int.self, forKey: .number)
|
||||||
|
fillColor = try container.decodeIfPresent(BadgeIndicator.FillColor.self, forKey: .fillColor) ?? .red
|
||||||
|
borderColorLight = try container.decodeIfPresent(Color.self, forKey: .borderColorLight)
|
||||||
|
borderColorDark = try container.decodeIfPresent(Color.self, forKey: .borderColorDark)
|
||||||
|
kind = try container.decodeIfPresent(BadgeIndicator.Kind.self, forKey: .kind) ?? .simple
|
||||||
|
maximumDigits = try container.decodeIfPresent(BadgeIndicator.MaximumDigits.self, forKey: .maximumDigits) ?? .two
|
||||||
|
size = try container.decodeIfPresent(BadgeIndicator.Size.self, forKey: .size) ?? .xxlarge
|
||||||
|
leadingCharacter = try container.decodeIfPresent(String.self, forKey: .leadingCharacter)
|
||||||
|
trailingText = try container.decodeIfPresent(String.self, forKey: .trailingText)
|
||||||
|
dotSize = try container.decodeIfPresent(CGFloat.self, forKey: .dotSize)
|
||||||
|
verticalPadding = try container.decodeIfPresent(CGFloat.self, forKey: .verticalPadding)
|
||||||
|
horizontalPadding = try container.decodeIfPresent(CGFloat.self, forKey: .horizontalPadding)
|
||||||
|
hideDot = try container.decodeIfPresent(Bool.self, forKey: .hideDot) ?? false
|
||||||
|
hideBorder = try container.decodeIfPresent(Bool.self, forKey: .hideBorder) ?? false
|
||||||
|
width = try container.decodeIfPresent(CGFloat.self, forKey: .width)
|
||||||
|
height = try container.decodeIfPresent(CGFloat.self, forKey: .height)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(id, forKey: .id)
|
||||||
|
try container.encode(inverted, forKey: .inverted)
|
||||||
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
|
try container.encodeIfPresent(number, forKey: .number)
|
||||||
|
try container.encodeIfPresent(fillColor, forKey: .fillColor)
|
||||||
|
try container.encodeIfPresent(borderColorLight, forKey: .borderColorLight)
|
||||||
|
try container.encodeIfPresent(borderColorDark, forKey: .borderColorDark)
|
||||||
|
try container.encodeIfPresent(kind, forKey: .kind)
|
||||||
|
try container.encodeIfPresent(maximumDigits, forKey: .maximumDigits)
|
||||||
|
try container.encodeIfPresent(size, forKey: .size)
|
||||||
|
try container.encodeIfPresent(leadingCharacter, forKey: .leadingCharacter)
|
||||||
|
try container.encodeIfPresent(trailingText, forKey: .trailingText)
|
||||||
|
try container.encodeIfPresent(dotSize, forKey: .dotSize)
|
||||||
|
try container.encodeIfPresent(verticalPadding, forKey: .verticalPadding)
|
||||||
|
try container.encodeIfPresent(hideDot, forKey: .hideDot)
|
||||||
|
try container.encodeIfPresent(hideBorder, forKey: .hideBorder)
|
||||||
|
try container.encodeIfPresent(width, forKey: .width)
|
||||||
|
try container.encodeIfPresent(height, forKey: .height)
|
||||||
|
}
|
||||||
|
}
|
||||||
72
MVMCoreUI/Atomic/Atoms/Views/ButtonIcon.swift
Normal file
72
MVMCoreUI/Atomic/Atoms/Views/ButtonIcon.swift
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// ButtonIcon.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/12/24.
|
||||||
|
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDS
|
||||||
|
|
||||||
|
open class ButtonIcon: VDS.ButtonIcon, VDSMoleculeViewProtocol {
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Public Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public var viewModel: ButtonIconModel!
|
||||||
|
|
||||||
|
public var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
|
||||||
|
public var additionalData: [AnyHashable : Any]?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Public Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func viewModelDidUpdate() {
|
||||||
|
surface = viewModel.surface
|
||||||
|
|
||||||
|
badgeIndicatorModel = viewModel.badgeIndicatorModel
|
||||||
|
kind = viewModel.kind
|
||||||
|
surfaceType = viewModel.surfaceType
|
||||||
|
iconName = viewModel.iconName
|
||||||
|
selectedIconName = viewModel.selectedIconName
|
||||||
|
size = viewModel.size
|
||||||
|
customSize = viewModel.customSize
|
||||||
|
floating = viewModel.floating
|
||||||
|
fitToIcon = viewModel.fitToIcon
|
||||||
|
hideBorder = viewModel.hideBorder
|
||||||
|
showBadgeIndicator = viewModel.showBadgeIndicator
|
||||||
|
selectable = viewModel.selectable
|
||||||
|
iconOffset = viewModel.iconOffset
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateView(_ size: CGFloat) {}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Overrides
|
||||||
|
//--------------------------------------------------
|
||||||
|
open override func updateAccessibility() {
|
||||||
|
super.updateAccessibility()
|
||||||
|
|
||||||
|
if let viewModel {
|
||||||
|
if let accessibilityText = viewModel.accessibilityText {
|
||||||
|
//since this is a container control and the
|
||||||
|
//icon & badgeIndicator (gets from it's own model) are traversed separatly
|
||||||
|
icon.accessibilityLabel = accessibilityText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//to deal with how it's parent constrains this control
|
||||||
|
extension ButtonIcon: MVMCoreUIViewConstrainingProtocol {
|
||||||
|
|
||||||
|
public func needsToBeConstrained() -> Bool { true }
|
||||||
|
|
||||||
|
public func horizontalAlignment() -> UIStackView.Alignment { .leading }
|
||||||
|
}
|
||||||
|
|
||||||
142
MVMCoreUI/Atomic/Atoms/Views/ButtonIconModel.swift
Normal file
142
MVMCoreUI/Atomic/Atoms/Views/ButtonIconModel.swift
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
//
|
||||||
|
// ButtonIconModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/12/24.
|
||||||
|
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDS
|
||||||
|
|
||||||
|
open class ButtonIconModel: ButtonModelProtocol, MoleculeModelProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public static var identifier: String = "buttonIcon"
|
||||||
|
public var id: String = UUID().uuidString
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - VDS Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public var surface: Surface { inverted ? .dark : .light }
|
||||||
|
public var inverted: Bool = false
|
||||||
|
public var accessibilityText: String?
|
||||||
|
|
||||||
|
public var action: ActionModelProtocol
|
||||||
|
|
||||||
|
public var kind = ButtonIcon.Kind.ghost
|
||||||
|
public var surfaceType = ButtonIcon.SurfaceType.colorFill
|
||||||
|
public var iconName: Icon.Name = .info
|
||||||
|
public var selectedIconName: Icon.Name?
|
||||||
|
public var size = ButtonIcon.Size.large
|
||||||
|
public var customSize : Int?
|
||||||
|
public var floating: Bool = false
|
||||||
|
public var fitToIcon: Bool = false
|
||||||
|
public var hideBorder: Bool = true
|
||||||
|
public var showBadgeIndicator: Bool = false
|
||||||
|
public var selectable: Bool = false
|
||||||
|
public var iconOffset: CGPoint = .zero
|
||||||
|
|
||||||
|
public var badgeIndicatorModel: VDS.ButtonIcon.BadgeIndicatorModel? {
|
||||||
|
guard let model = badgeIndicator else { return nil }
|
||||||
|
return .init(kind: model.kind,
|
||||||
|
fillColor: model.fillColor,
|
||||||
|
expandDirection: expandDirection,
|
||||||
|
size: model.size,
|
||||||
|
maximumDigits: model.maximumDigits,
|
||||||
|
width: model.width,
|
||||||
|
height: model.height,
|
||||||
|
number: model.number,
|
||||||
|
leadingCharacter: model.leadingCharacter,
|
||||||
|
trailingText: model.trailingText,
|
||||||
|
dotSize: model.dotSize,
|
||||||
|
verticalPadding: model.verticalPadding,
|
||||||
|
horizontalPadding: model.horizontalPadding,
|
||||||
|
hideDot: model.hideDot,
|
||||||
|
hideBorder: model.hideBorder)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var badgeIndicator: BadgeIndicatorModel?
|
||||||
|
private var expandDirection = ButtonIcon.BadgeIndicatorModel.ExpandDirection.right
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
public init(with iconName: VDS.Icon.Name, action: ActionModelProtocol) {
|
||||||
|
self.iconName = iconName
|
||||||
|
self.action = action
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
case inverted
|
||||||
|
case accessibilityText
|
||||||
|
case action
|
||||||
|
case badgeIndicator
|
||||||
|
case expandDirection
|
||||||
|
case kind
|
||||||
|
case surfaceType
|
||||||
|
case iconName
|
||||||
|
case selectedIconName
|
||||||
|
case size
|
||||||
|
case customSize
|
||||||
|
case floating
|
||||||
|
case fitToIcon
|
||||||
|
case hideBorder
|
||||||
|
case showBadgeIndicator
|
||||||
|
case selectable
|
||||||
|
case iconOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
action = try container.decodeModel(codingKey: .action)
|
||||||
|
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
||||||
|
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
|
||||||
|
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
|
badgeIndicator = try container.decodeIfPresent(BadgeIndicatorModel.self, forKey: .badgeIndicator)
|
||||||
|
expandDirection = try container.decodeIfPresent(ButtonIcon.BadgeIndicatorModel.ExpandDirection.self, forKey: .expandDirection) ?? .right
|
||||||
|
kind = try container.decodeIfPresent(ButtonIcon.Kind.self, forKey: .kind) ?? .ghost
|
||||||
|
surfaceType = try container.decodeIfPresent(ButtonIcon.SurfaceType.self, forKey: .kind) ?? .colorFill
|
||||||
|
iconName = try container.decode(Icon.Name.self, forKey: .iconName)
|
||||||
|
selectedIconName = try container.decodeIfPresent(Icon.Name.self, forKey: .selectedIconName)
|
||||||
|
size = try container.decodeIfPresent(ButtonIcon.Size.self, forKey: .size) ?? .large
|
||||||
|
customSize = try container.decodeIfPresent(Int.self, forKey: .customSize)
|
||||||
|
floating = try container.decodeIfPresent(Bool.self, forKey: .floating) ?? false
|
||||||
|
fitToIcon = try container.decodeIfPresent(Bool.self, forKey: .fitToIcon) ?? false
|
||||||
|
hideBorder = try container.decodeIfPresent(Bool.self, forKey: .hideBorder) ?? false
|
||||||
|
showBadgeIndicator = try container.decodeIfPresent(Bool.self, forKey: .showBadgeIndicator) ?? false
|
||||||
|
selectable = try container.decodeIfPresent(Bool.self, forKey: .selectable) ?? false
|
||||||
|
iconOffset = try container.decodeIfPresent(CGPoint.self, forKey: .iconOffset) ?? .zero
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(id, forKey: .id)
|
||||||
|
try container.encode(inverted, forKey: .inverted)
|
||||||
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
|
try container.encodeIfPresent(badgeIndicator, forKey: .badgeIndicator)
|
||||||
|
try container.encodeIfPresent(expandDirection, forKey: .expandDirection)
|
||||||
|
try container.encodeIfPresent(kind, forKey: .kind)
|
||||||
|
try container.encodeIfPresent(surfaceType, forKey: .kind)
|
||||||
|
try container.encode(iconName, forKey: .iconName)
|
||||||
|
try container.encodeIfPresent(selectedIconName, forKey: .selectedIconName)
|
||||||
|
try container.encodeIfPresent(size, forKey: .size)
|
||||||
|
try container.encodeIfPresent(customSize, forKey: .customSize)
|
||||||
|
try container.encodeIfPresent(floating, forKey: .floating)
|
||||||
|
try container.encodeIfPresent(fitToIcon, forKey: .fitToIcon)
|
||||||
|
try container.encodeIfPresent(hideBorder, forKey: .hideBorder)
|
||||||
|
try container.encodeIfPresent(showBadgeIndicator, forKey: .showBadgeIndicator)
|
||||||
|
try container.encodeIfPresent(selectable, forKey: .selectable)
|
||||||
|
try container.encodeIfPresent(iconOffset, forKey: .iconOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
134
MVMCoreUI/Atomic/Atoms/Views/TileContainer.swift
Normal file
134
MVMCoreUI/Atomic/Atoms/Views/TileContainer.swift
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
//
|
||||||
|
// TileContainer.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/15/24.
|
||||||
|
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDS
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
open class TileContainer: VDS.TileContainer, VDSMoleculeViewProtocol{
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public var model: MoleculeModelProtocol?
|
||||||
|
|
||||||
|
public var viewModel: TileContainerModel!
|
||||||
|
public var delegateObject: MVMCoreUIDelegateObject?
|
||||||
|
public var additionalData: [AnyHashable: Any]?
|
||||||
|
|
||||||
|
public var molecule: MoleculeViewProtocol? {
|
||||||
|
willSet {
|
||||||
|
if newValue == nil {
|
||||||
|
molecule?.removeFromSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
public convenience required init() {
|
||||||
|
self.init(frame: .zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Public
|
||||||
|
//--------------------------------------------------
|
||||||
|
public func viewModelDidUpdate() {
|
||||||
|
|
||||||
|
if let moleculeModel = viewModel.molecule {
|
||||||
|
if let molecule,
|
||||||
|
moleculeModel.moleculeName == molecule.model?.moleculeName {
|
||||||
|
molecule.set(with: moleculeModel, delegateObject, additionalData)
|
||||||
|
} else if let moleculeView = ModelRegistry.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
|
||||||
|
molecule = moleculeView
|
||||||
|
addContentView(moleculeView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let imageName = viewModel.backgroundImage {
|
||||||
|
loadImage(imageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
padding = viewModel.padding
|
||||||
|
color = viewModel.color
|
||||||
|
backgroundEffect = viewModel.backgroundEffect
|
||||||
|
aspectRatio = viewModel.aspectRatio
|
||||||
|
width = viewModel.width
|
||||||
|
height = viewModel.height
|
||||||
|
showBorder = viewModel.showBorder
|
||||||
|
showDropShadows = viewModel.showDropShadwows
|
||||||
|
//setup action
|
||||||
|
if let action = viewModel.action {
|
||||||
|
//add the subscriber
|
||||||
|
onClick = { [weak self] control in
|
||||||
|
guard let self, let viewModel = self.viewModel else { return }
|
||||||
|
MVMCoreUIActionHandler.performActionUnstructured(with: action,
|
||||||
|
sourceModel: viewModel,
|
||||||
|
additionalData: self.additionalData,
|
||||||
|
delegateObject: self.delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadImage(_ imageName: String? = nil) {
|
||||||
|
guard let imageName else {
|
||||||
|
if backgroundImage != nil {
|
||||||
|
backgroundImage = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let finishedLoadingBlock: MVMCoreGetImageBlock = {[weak self] (image, data, isFallbackImage) in MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.backgroundImage = image
|
||||||
|
})}
|
||||||
|
MVMCoreCache.shared()?.getImage(imageName, useWidth: false, widthForS7: 0, useHeight: false, heightForS7: 0, format: nil, localFallbackImageName: nil, allowServerQueryParameters: false, localBundle: nil, completionHandler: finishedLoadingBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - MVMCoreViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
open func updateView(_ size: CGFloat) {}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - MoleculeViewProtocol
|
||||||
|
//--------------------------------------------------
|
||||||
|
//since this is a class func, we can't reference it directly
|
||||||
|
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
|
100
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Allows the molecule to set its name for reuse. Default could be moleculeName. Mainly used for list or collections.
|
||||||
|
public static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||||
|
// This will aggregate names of molecules to make an id.
|
||||||
|
guard let containerModel = model as? TileContainerModel,
|
||||||
|
let molecule = containerModel.molecule,
|
||||||
|
let moleculeClass = ModelRegistry.getMoleculeClass(molecule),
|
||||||
|
let moleculeName = moleculeClass.nameForReuse(with: molecule, delegateObject)
|
||||||
|
else { return "\(model.moleculeName)<>" }
|
||||||
|
|
||||||
|
return "\(model.moleculeName)<\(moleculeName)>"
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Overrides
|
||||||
|
//--------------------------------------------------
|
||||||
|
open override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
// Accounts for any collection size changes
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TileContainer: MVMCoreUIViewConstrainingProtocol {
|
||||||
|
public func horizontalAlignment() -> UIStackView.Alignment { .leading }
|
||||||
|
}
|
||||||
107
MVMCoreUI/Atomic/Atoms/Views/TileContainerModel.swift
Normal file
107
MVMCoreUI/Atomic/Atoms/Views/TileContainerModel.swift
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
//
|
||||||
|
// TileContainerModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/15/24.
|
||||||
|
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDS
|
||||||
|
|
||||||
|
open class TileContainerModel: TileContainerBaseModel<TileContainer.Padding, TileContainer>, ParentMoleculeModelProtocol, MoleculeModelProtocol {
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public static var identifier: String = "tileContainer"
|
||||||
|
public var id: String = UUID().uuidString
|
||||||
|
public var backgroundColor: Color?
|
||||||
|
|
||||||
|
public var molecule: MoleculeModelProtocol?
|
||||||
|
public var children: [any MoleculeModelProtocol] {
|
||||||
|
guard let molecule else { return [] }
|
||||||
|
return [molecule]
|
||||||
|
}
|
||||||
|
|
||||||
|
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||||
|
return try replaceChildMolecule(at: &self.molecule, with: molecule)
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
case moleculeName
|
||||||
|
case molecule
|
||||||
|
}
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
||||||
|
molecule = try container.decodeModelIfPresent(codingKey: .molecule)
|
||||||
|
try super.init(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override 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.encodeModelIfPresent(molecule, forKey: .molecule)
|
||||||
|
try super.encode(to: encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open class TileContainerBaseModel<PaddingType: DefaultValuing & Codable, TileContainerType:TileContainerBase<PaddingType>> : Codable{
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
public var backgroundImage: String?
|
||||||
|
public var action: ActionModelProtocol?
|
||||||
|
public var imageFallbackColor: Surface = .light
|
||||||
|
public var width: CGFloat?
|
||||||
|
public var height: CGFloat?
|
||||||
|
public var showBorder: Bool = false
|
||||||
|
public var showDropShadwows: Bool = false
|
||||||
|
public var padding = PaddingType.defaultValue
|
||||||
|
public var color: TileContainerType.BackgroundColor = .black
|
||||||
|
public var aspectRatio: TileContainerType.AspectRatio = .ratio1x1
|
||||||
|
public var backgroundEffect: TileContainerType.BackgroundEffect = .none
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case backgroundImage
|
||||||
|
case action
|
||||||
|
case padding
|
||||||
|
case color
|
||||||
|
case aspectRatio
|
||||||
|
case imageFallbackColor
|
||||||
|
case width
|
||||||
|
case height
|
||||||
|
case showBorder
|
||||||
|
case showDropShadows
|
||||||
|
case backgroundEffect
|
||||||
|
}
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
backgroundImage = try container.decodeIfPresent(String.self, forKey: .backgroundImage)
|
||||||
|
width = try container.decodeIfPresent(CGFloat.self, forKey: .width)
|
||||||
|
height = try container.decodeIfPresent(CGFloat.self, forKey: .height)
|
||||||
|
action = try container.decodeModelIfPresent(codingKey: .action)
|
||||||
|
padding = try container.decodeIfPresent(PaddingType.self, forKey: .padding) ?? PaddingType.defaultValue
|
||||||
|
color = try container.decodeIfPresent(TileContainerType.BackgroundColor.self, forKey: .color) ?? .black
|
||||||
|
aspectRatio = try container.decodeIfPresent(TileContainerType.AspectRatio.self, forKey: .aspectRatio) ?? .ratio1x1
|
||||||
|
backgroundEffect = try container.decodeIfPresent(TileContainerType.BackgroundEffect.self, forKey: .backgroundEffect) ?? .none
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encodeIfPresent(backgroundImage, forKey: .backgroundImage)
|
||||||
|
try container.encodeIfPresent(width, forKey: .width)
|
||||||
|
try container.encodeIfPresent(height, forKey: .height)
|
||||||
|
try container.encodeIfPresent(backgroundEffect, forKey: .backgroundEffect)
|
||||||
|
try container.encodeIfPresent(padding, forKey: .padding)
|
||||||
|
try container.encodeIfPresent(color, forKey: .color)
|
||||||
|
try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio)
|
||||||
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -39,10 +39,16 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{
|
|||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public func viewModelDidUpdate() {
|
public func viewModelDidUpdate() {
|
||||||
color = viewModel.color
|
|
||||||
padding = viewModel.padding
|
padding = viewModel.padding
|
||||||
|
color = viewModel.color
|
||||||
|
backgroundEffect = viewModel.backgroundEffect
|
||||||
aspectRatio = viewModel.aspectRatio
|
aspectRatio = viewModel.aspectRatio
|
||||||
width = viewModel.width
|
width = viewModel.width
|
||||||
|
height = viewModel.height
|
||||||
|
showBorder = viewModel.showBorder
|
||||||
|
showDropShadows = viewModel.showDropShadwows
|
||||||
|
|
||||||
if let value = viewModel.textWidth {
|
if let value = viewModel.textWidth {
|
||||||
textWidth = .value(value)
|
textWidth = .value(value)
|
||||||
} else if let percentage = viewModel.textPercentage {
|
} else if let percentage = viewModel.textPercentage {
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import VDS
|
import VDS
|
||||||
|
|
||||||
open class TileletModel: MoleculeModelProtocol {
|
open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, MoleculeModelProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -17,52 +17,37 @@ open class TileletModel: MoleculeModelProtocol {
|
|||||||
public static var identifier: String = "tilelet"
|
public static var identifier: String = "tilelet"
|
||||||
public var id: String = UUID().uuidString
|
public var id: String = UUID().uuidString
|
||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var color: Tilelet.BackgroundColor
|
|
||||||
public var padding: Tilelet.Padding
|
|
||||||
public var aspectRatio: Tilelet.AspectRatio
|
|
||||||
public var badge: Tilelet.BadgeModel?
|
public var badge: Tilelet.BadgeModel?
|
||||||
public var title: LabelModel?
|
public var title: LabelModel?
|
||||||
public var subTitle: LabelModel?
|
public var subTitle: LabelModel?
|
||||||
public var descriptiveIcon: Tilelet.DescriptiveIcon?
|
public var descriptiveIcon: Tilelet.DescriptiveIcon?
|
||||||
public var directionalIcon: Tilelet.DirectionalIcon?
|
public var directionalIcon: Tilelet.DirectionalIcon?
|
||||||
public var width: CGFloat?
|
|
||||||
public var textWidth: CGFloat?
|
public var textWidth: CGFloat?
|
||||||
public var textPercentage: CGFloat?
|
public var textPercentage: CGFloat?
|
||||||
public var action: ActionModelProtocol?
|
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case id
|
case id
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case backgroundColor
|
|
||||||
case color
|
|
||||||
case padding
|
|
||||||
case aspectRatio
|
|
||||||
case badge
|
case badge
|
||||||
case title
|
case title
|
||||||
case subTitle
|
case subTitle
|
||||||
case descriptiveIcon
|
case descriptiveIcon
|
||||||
case directionalIcon
|
case directionalIcon
|
||||||
case width
|
|
||||||
case textWidth
|
case textWidth
|
||||||
case textPercentage
|
case textPercentage
|
||||||
case action
|
|
||||||
}
|
}
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
|
||||||
self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge)
|
||||||
self.color = try container.decodeIfPresent(Tilelet.BackgroundColor.self, forKey: .color) ?? Tilelet.BackgroundColor.black
|
title = try container.decodeIfPresent(LabelModel.self, forKey: .title)
|
||||||
self.padding = try container.decodeIfPresent(Tilelet.Padding.self, forKey: .padding) ?? Tilelet.Padding.small
|
subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle)
|
||||||
self.aspectRatio = try container.decodeIfPresent(Tilelet.AspectRatio.self, forKey: .aspectRatio) ?? Tilelet.AspectRatio.none
|
descriptiveIcon = try container.decodeIfPresent(Tilelet.DescriptiveIcon.self, forKey: .descriptiveIcon)
|
||||||
self.badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge)
|
directionalIcon = try container.decodeIfPresent(Tilelet.DirectionalIcon.self, forKey: .directionalIcon)
|
||||||
self.title = try container.decodeIfPresent(LabelModel.self, forKey: .title)
|
textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth)
|
||||||
self.subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle)
|
textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage)
|
||||||
self.descriptiveIcon = try container.decodeIfPresent(Tilelet.DescriptiveIcon.self, forKey: .descriptiveIcon)
|
try super.init(from: decoder)
|
||||||
self.directionalIcon = try container.decodeIfPresent(Tilelet.DirectionalIcon.self, forKey: .directionalIcon)
|
|
||||||
self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width)
|
|
||||||
self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth)
|
|
||||||
self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage)
|
|
||||||
action = try container.decodeModelIfPresent(codingKey: .action)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? {
|
public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? {
|
||||||
@ -99,22 +84,17 @@ open class TileletModel: MoleculeModelProtocol {
|
|||||||
return .init(text: subTitle.text, textAttributes: attrs)
|
return .init(text: subTitle.text, textAttributes: attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(id, forKey: .id)
|
try container.encode(id, forKey: .id)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
|
||||||
try container.encodeIfPresent(color, forKey: .color)
|
|
||||||
try container.encodeIfPresent(padding, forKey: .padding)
|
|
||||||
try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio)
|
|
||||||
try container.encodeIfPresent(badge, forKey: .badge)
|
try container.encodeIfPresent(badge, forKey: .badge)
|
||||||
try container.encodeIfPresent(title, forKey: .title)
|
try container.encodeIfPresent(title, forKey: .title)
|
||||||
try container.encodeIfPresent(subTitle, forKey: .subTitle)
|
try container.encodeIfPresent(subTitle, forKey: .subTitle)
|
||||||
try container.encodeIfPresent(descriptiveIcon, forKey: .descriptiveIcon)
|
try container.encodeIfPresent(descriptiveIcon, forKey: .descriptiveIcon)
|
||||||
try container.encodeIfPresent(directionalIcon, forKey: .directionalIcon)
|
try container.encodeIfPresent(directionalIcon, forKey: .directionalIcon)
|
||||||
try container.encodeIfPresent(width, forKey: .width)
|
|
||||||
try container.encodeIfPresent(textWidth, forKey: .textWidth)
|
try container.encodeIfPresent(textWidth, forKey: .textWidth)
|
||||||
try container.encodeIfPresent(textPercentage, forKey: .textPercentage)
|
try container.encodeIfPresent(textPercentage, forKey: .textPercentage)
|
||||||
try container.encodeModelIfPresent(action, forKey: .action)
|
try super.encode(to: encoder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,14 @@ import VDSTokens
|
|||||||
|
|
||||||
extension VDS.Surface: Codable {}
|
extension VDS.Surface: Codable {}
|
||||||
extension VDS.Badge.FillColor: Codable {}
|
extension VDS.Badge.FillColor: Codable {}
|
||||||
|
extension VDS.BadgeIndicator.FillColor: Codable {}
|
||||||
|
extension VDS.BadgeIndicator.Kind: Codable {}
|
||||||
|
extension VDS.BadgeIndicator.MaximumDigits: Codable {}
|
||||||
|
extension VDS.BadgeIndicator.Size: Codable {}
|
||||||
|
extension VDS.ButtonIcon.Kind: Codable {}
|
||||||
|
extension VDS.ButtonIcon.Size: Codable {}
|
||||||
|
extension VDS.ButtonIcon.BadgeIndicatorModel.ExpandDirection: Codable {}
|
||||||
|
extension VDS.ButtonIcon.SurfaceType: Codable {}
|
||||||
extension VDS.ButtonGroup.Alignment: Codable {}
|
extension VDS.ButtonGroup.Alignment: Codable {}
|
||||||
extension VDS.Icon.Name: Codable {}
|
extension VDS.Icon.Name: Codable {}
|
||||||
extension VDS.Icon.Size: Codable {}
|
extension VDS.Icon.Size: Codable {}
|
||||||
@ -92,6 +100,53 @@ extension VDS.TileContainerBase.BackgroundColor: Codable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension VDS.TileContainerBase.BackgroundEffect: Codable {
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case type
|
||||||
|
case firstColor
|
||||||
|
case secondColor
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BackgroundEffectType: String, Codable {
|
||||||
|
case transparency
|
||||||
|
case none
|
||||||
|
case gradient
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
let type = try container.decode(BackgroundEffectType.self, forKey: .type)
|
||||||
|
|
||||||
|
switch type {
|
||||||
|
case .transparency:
|
||||||
|
self = .transparency
|
||||||
|
case .none:
|
||||||
|
self = .none
|
||||||
|
case .gradient:
|
||||||
|
let firstColor = try container.decode(String.self, forKey: .firstColor)
|
||||||
|
let secondColor = try container.decode(String.self, forKey: .secondColor)
|
||||||
|
self = .gradient(firstColor, secondColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
switch self {
|
||||||
|
case .transparency:
|
||||||
|
try container.encode(BackgroundEffectType.transparency.rawValue, forKey: .type)
|
||||||
|
case .none:
|
||||||
|
try container.encode(BackgroundEffectType.none.rawValue, forKey: .type)
|
||||||
|
case .gradient(let firstColor, let secondColor):
|
||||||
|
try container.encode(BackgroundEffectType.gradient.rawValue, forKey: .type)
|
||||||
|
try container.encode(firstColor, forKey: .firstColor)
|
||||||
|
try container.encode(secondColor, forKey: .secondColor)
|
||||||
|
@unknown default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension VDS.TileContainer.Padding: Codable {
|
extension VDS.TileContainer.Padding: Codable {
|
||||||
enum PaddingError: Error {
|
enum PaddingError: Error {
|
||||||
case valueNotFound(type: String)
|
case valueNotFound(type: String)
|
||||||
|
|||||||
@ -73,8 +73,11 @@ open class CoreUIModelMapping: ModelMapping {
|
|||||||
ModelRegistry.register(handler: LoadingSpinner.self, for: LoadingSpinnerModel.self)
|
ModelRegistry.register(handler: LoadingSpinner.self, for: LoadingSpinnerModel.self)
|
||||||
ModelRegistry.register(handler: Video.self, for: VideoModel.self)
|
ModelRegistry.register(handler: Video.self, for: VideoModel.self)
|
||||||
ModelRegistry.register(handler: Tilelet.self, for: TileletModel.self)
|
ModelRegistry.register(handler: Tilelet.self, for: TileletModel.self)
|
||||||
|
ModelRegistry.register(handler: TileContainer.self, for: TileContainerModel.self)
|
||||||
ModelRegistry.register(handler: Badge.self, for: BadgeModel.self)
|
ModelRegistry.register(handler: Badge.self, for: BadgeModel.self)
|
||||||
|
ModelRegistry.register(handler: BadgeIndicator.self, for: BadgeIndicatorModel.self)
|
||||||
ModelRegistry.register(handler: Icon.self, for: IconModel.self)
|
ModelRegistry.register(handler: Icon.self, for: IconModel.self)
|
||||||
|
ModelRegistry.register(handler: ButtonIcon.self, for: ButtonIconModel.self)
|
||||||
ModelRegistry.register(handler: Tooltip.self, for: TooltipModel.self)
|
ModelRegistry.register(handler: Tooltip.self, for: TooltipModel.self)
|
||||||
|
|
||||||
// MARK:- Horizontal Combination Molecules
|
// MARK:- Horizontal Combination Molecules
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user