From 170da5f47725374946271718b85369a9a5522eee Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 15 Sep 2023 09:10:39 -0500 Subject: [PATCH 1/6] refactored to use buttongroup Signed-off-by: Matt Bruce --- .../TwoButtonView.swift | 149 +++++------------- 1 file changed, 41 insertions(+), 108 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift index 9a70c12e..debd2c8d 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonView.swift @@ -9,144 +9,70 @@ import UIKit import VDS -@objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol { +@objcMembers open class TwoButtonView: VDS.View, VDSMoleculeViewProtocol { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - open var primaryButton: PillButton = PillButton() - open var secondaryButton: PillButton = PillButton() - private var stack = UIStackView() - - //-------------------------------------------------- - // MARK: - Constraints - //-------------------------------------------------- - - private var equalWidthConstraint: NSLayoutConstraint? - + open var viewModel: TwoButtonViewModel! + open var delegateObject: MVMCoreUIDelegateObject? + open var additionalData: [AnyHashable : Any]? + + open var primaryButton = PillButton() + open var secondaryButton = PillButton() + private var buttonGroup = VDS.ButtonGroup() + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- - public func setDefaultAppearance() { - primaryButton.use = .primary - secondaryButton.use = .secondary - } - - open override func updateView(_ size: CGFloat) { - super.updateView(size) - - primaryButton.updateView(size) - secondaryButton.updateView(size) - } - - open override func setupView() { - super.setupView() - - stack.translatesAutoresizingMaskIntoConstraints = false + open override func setup() { + super.setup() isAccessibilityElement = false - addSubview(stack) - stack.addArrangedSubview(secondaryButton) - stack.addArrangedSubview(primaryButton) - NSLayoutConstraint.constraintPinSubview(toSuperview: stack) - stack.axis = .horizontal - stack.spacing = Padding.Component.gutterForApplicationWidth - equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1) - equalWidthConstraint?.isActive = true + addSubview(buttonGroup) + buttonGroup.pinToSuperView() + buttonGroup.alignment = .center + buttonGroup.rowQuantityPhone = 2 + buttonGroup.rowQuantityTablet = 2 + buttonGroup.childWidth = .percentage(50) } - - //-------------------------------------------------- - // MARK: - Stack Manipulation - //-------------------------------------------------- - - public func showPrimaryButton() { - if !stack.arrangedSubviews.contains(primaryButton) { - stack.addArrangedSubview(primaryButton) - primaryButton.isHidden = false - } - - if secondaryButton.superview != nil { - equalWidthConstraint?.isActive = true - } - - primaryButton.isAccessibilityElement = true - } - - public func showSecondaryButton() { - - if !stack.arrangedSubviews.contains(secondaryButton) { - stack.insertArrangedSubview(secondaryButton, at: 0) - secondaryButton.isHidden = false - } - - if primaryButton.superview != nil { - equalWidthConstraint?.isActive = true - } - - secondaryButton.isAccessibilityElement = true - } - - public func hidePrimaryButton() { - - if primaryButton.superview != nil { - stack.removeArrangedSubview(primaryButton) - primaryButton.isHidden = true - } - - primaryButton.isAccessibilityElement = false - equalWidthConstraint?.isActive = false - } - - public func hideSecondaryButton() { - - if secondaryButton.superview != nil { - stack.removeArrangedSubview(secondaryButton) - secondaryButton.isHidden = true - } - - secondaryButton.isAccessibilityElement = false - equalWidthConstraint?.isActive = false - } - //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- open override func reset() { super.reset() - - setDefaultAppearance() + primaryButton.reset() + secondaryButton.reset() + primaryButton.use = .primary + secondaryButton.use = .secondary + buttonGroup.reset() } - public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let model = model as? TwoButtonViewModel, let buttonModel = model.primaryButton ?? model.secondaryButton else { return 0 } return PillButton.estimatedHeight(with: buttonModel, delegateObject) } - - public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.set(with: model, delegateObject, additionalData) - - guard let model = model as? TwoButtonViewModel else { return } - - if let secondaryModel = model.secondaryButton { - showSecondaryButton() + + public func viewModelDidUpdate() { + var buttons = [PillButton]() + if let secondaryModel = viewModel.secondaryButton { secondaryButton.set(with: secondaryModel, delegateObject, additionalData) - } else { - hideSecondaryButton() + buttons.append(secondaryButton) } - if let primaryModel = model.primaryButton { - showPrimaryButton() + if let primaryModel = viewModel.primaryButton { primaryButton.set(with: primaryModel, delegateObject, additionalData) - } else { - hidePrimaryButton() + buttons.append(primaryButton) } + + buttonGroup.buttons = buttons } + //-------------------------------------------------- // MARK: - MVMCoreUIViewConstrainingProtocol //-------------------------------------------------- @@ -154,4 +80,11 @@ import VDS open func horizontalAlignment() -> UIStackView.Alignment { return .center } + + //-------------------------------------------------- + // MARK: - MVMCoreViewProtocol + //-------------------------------------------------- + public func updateView(_ size: CGFloat) { + setNeedsUpdate() + } } From 83b2cb80ad702f7c63ba3d1fdaed5681c49f06b7 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 15 Dec 2023 16:17:36 -0600 Subject: [PATCH 2/6] refactored two link view Signed-off-by: Matt Bruce --- .../TwoLinkView.swift | 119 +++++++++--------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift index 09a09dcd..cd15066e 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkView.swift @@ -7,79 +7,81 @@ // import Foundation +import VDS - -@objcMembers open class TwoLinkView: View, MVMCoreUIViewConstrainingProtocol { +@objcMembers open class TwoLinkView: VDS.View, VDSMoleculeViewProtocol { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - + open var viewModel: TwoLinkViewModel! + open var delegateObject: MVMCoreUIDelegateObject? + open var additionalData: [AnyHashable : Any]? + open var leftLink = Link() open var rightLink = Link() - private var stack = UIStackView() + private var buttonGroup = VDS.ButtonGroup() + private var buttons: [Link] = [] + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + open override func setup() { + super.setup() + isAccessibilityElement = false + addSubview(buttonGroup) + buttonGroup.pinToSuperView() + buttonGroup.alignment = .center + buttonGroup.rowQuantityPhone = 2 + buttonGroup.rowQuantityTablet = 2 + buttonGroup.childWidth = .percentage(50) + } + //-------------------------------------------------- // MARK: - MVMCoreViewProtocol //-------------------------------------------------- - - open override func updateView(_ size: CGFloat) { - super.updateView(size) - stack.updateView(size) + open override func reset() { + super.reset() + leftLink.reset() + rightLink.reset() + buttonGroup.reset() } - - open override func setupView() { - super.setupView() - - stack.translatesAutoresizingMaskIntoConstraints = false - addSubview(stack) - stack.addArrangedSubview(leftLink) - stack.addArrangedSubview(rightLink) - NSLayoutConstraint.constraintPinSubview(toSuperview: stack) - stack.axis = .horizontal - stack.spacing = 8 - } - + + open func updateView(_ size: CGFloat) { } + //-------------------------------------------------- // MARK: - Stack Manipulation //-------------------------------------------------- public func showRightLink() { - if !stack.arrangedSubviews.contains(rightLink) { - stack.addArrangedSubview(rightLink) - rightLink.isHidden = false + if !buttons.contains(rightLink) { + buttons.insert(rightLink, at: buttons.count) } + buttonGroup.buttons = buttons } public func showLeftLink() { - if !stack.arrangedSubviews.contains(leftLink) { - stack.insertArrangedSubview(leftLink, at: 0) - leftLink.isHidden = false + if !buttons.contains(leftLink) { + buttons.insert(leftLink, at: 0) } + buttonGroup.buttons = buttons } public func hideRightLink() { - if rightLink.superview != nil { - stack.removeArrangedSubview(rightLink) - rightLink.isHidden = true + if let index = buttons.firstIndex(of: rightLink) { + buttons.remove(at: index) } + buttonGroup.buttons = buttons } public func hideLeftLink() { - if leftLink.superview != nil { - stack.removeArrangedSubview(leftLink) - leftLink.isHidden = true + if let index = buttons.firstIndex(of: leftLink) { + buttons.remove(at: index) } + buttonGroup.buttons = buttons } - - //-------------------------------------------------- - // MARK: - MoleculeViewProtocol - //-------------------------------------------------- - - open override func reset() { - super.reset() - stack.reset() - } - + //-------------------------------------------------- // MARK: - MVMCoreUIViewConstrainingProtocol //-------------------------------------------------- @@ -92,27 +94,26 @@ import Foundation // MARK: - MoleculeViewProtocol //-------------------------------------------------- - public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 16 + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? TwoButtonViewModel, + let buttonModel = model.primaryButton ?? model.secondaryButton + else { return 0 } + + return PillButton.estimatedHeight(with: buttonModel, delegateObject) } - - public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - super.set(with: model, delegateObject, additionalData) - - guard let model = model as? TwoLinkViewModel else { return } - - if let model = model.leftLink { - showLeftLink() + + public func viewModelDidUpdate() { + if let model = viewModel.leftLink { leftLink.set(with: model, delegateObject, additionalData) - } else { - hideLeftLink() + buttons.append(leftLink) } - if let model = model.rightLink { - showRightLink() + if let model = viewModel.rightLink { rightLink.set(with: model, delegateObject, additionalData) - } else { - hideRightLink() + buttons.append(rightLink) } + + buttonGroup.buttons = buttons } + } From 71a10f1055c694d06c722f6186e21c0b7c1a79bf Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 11 Jan 2024 11:19:18 -0600 Subject: [PATCH 3/6] added buttonGroup Signed-off-by: Matt Bruce --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++-- .../Atomic/Atoms/Buttons/ButtonGroup.swift | 68 +++++++++++++++++ .../Atoms/Buttons/ButtonGroupModel.swift | 73 +++++++++++++++++++ .../Atomic/Extensions/VDS-Enums+Codable.swift | 4 +- 4 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e8c2d064..569b13cb 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -171,7 +171,6 @@ 608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */; }; 7199C8162A4F3A64001568B7 /* AccessibilityHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7199C8152A4F3A64001568B7 /* AccessibilityHandler.swift */; }; 71BE969E2AD96BE6000B5DB7 /* RotorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BE969D2AD96BE6000B5DB7 /* RotorHandler.swift */; }; - 608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */; }; 8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */; }; 8D070BB2241B56AD0099AC56 /* ListRightVariableTotalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */; }; 8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */; }; @@ -300,8 +299,8 @@ AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; }; AFE4A1D127DFB5EE00C458D0 /* VDSColorTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */; }; AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */; }; - B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; }; B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; }; + B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; }; BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; }; BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; }; BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; }; @@ -574,10 +573,12 @@ EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; }; EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; }; EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; }; + EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B942B504A43000139B4 /* ButtonGroup.swift */; }; + EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */; }; EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; }; EA7E67762758365300ABF773 /* UIUpdatableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */; }; - EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; }; EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3D2970938F00F2FF2E /* Tilelet.swift */; }; + EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; }; EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C5F2970A3F000F2FF2E /* VDS.framework */; }; EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */; }; EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */; }; @@ -763,7 +764,6 @@ 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingHandler.swift; sourceTree = ""; }; 7199C8152A4F3A64001568B7 /* AccessibilityHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityHandler.swift; sourceTree = ""; }; 71BE969D2AD96BE6000B5DB7 /* RotorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotorHandler.swift; sourceTree = ""; }; - 608211262AC6AF8200C3FC39 /* MVMCoreUILoggingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingHandler.swift; sourceTree = ""; }; 8D070BAF241B56530099AC56 /* ListRightVariableTotalDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalDataModel.swift; sourceTree = ""; }; 8D070BB1241B56AD0099AC56 /* ListRightVariableTotalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableTotalData.swift; sourceTree = ""; }; 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyTextModel.swift; sourceTree = ""; }; @@ -892,8 +892,8 @@ AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = ""; }; AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSColorTokens.xcframework; path = ../SharedFrameworks/VDSColorTokens.xcframework; sourceTree = ""; }; AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = ""; }; - B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = ""; }; B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = ""; }; BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = ""; }; BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = ""; }; BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = ""; }; @@ -1167,6 +1167,8 @@ EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = ""; }; EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = ""; }; EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = ""; }; + EA6E8B942B504A43000139B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = ""; }; + EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupModel.swift; sourceTree = ""; }; EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = ""; }; EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIUpdatableModelProtocol.swift; sourceTree = ""; }; EA985C3D2970938F00F2FF2E /* Tilelet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tilelet.swift; sourceTree = ""; }; @@ -2198,6 +2200,8 @@ DBC4391A224421A0001AB423 /* CaretLink.swift */, D28A838A23CCDA6B00DFE4FC /* ButtonModel.swift */, D2E2A99E23E07F8A000B42E6 /* PillButton.swift */, + EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */, + EA6E8B942B504A43000139B4 /* ButtonGroup.swift */, ); path = Buttons; sourceTree = ""; @@ -2663,6 +2667,7 @@ BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, 01F2C20527C81F9700DC3D36 /* SubNavSwipeAnimator.swift in Sources */, 0AE277EC25D2EE310048A38D /* MultiItemDropdownEntryFieldModel.swift in Sources */, + EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */, 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, 3265B30424BCA749000D154B /* HeadersH1NoButtonsBodyText.swift in Sources */, AAA7CD69250641F90045B959 /* HeartModel.swift in Sources */, @@ -2940,6 +2945,7 @@ D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */, + EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, 526A265E240D200500B0D828 /* ListTwoColumnCompareChanges.swift in Sources */, B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift new file mode 100644 index 00000000..8fe15acb --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift @@ -0,0 +1,68 @@ +// +// ButtonGroup.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/11/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation +import UIKit +import VDS + +@objcMembers open class ButtonGroup: VDS.ButtonGroup, VDSMoleculeViewProtocol { + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + open var viewModel: ButtonGroupModel! + open var delegateObject: MVMCoreUIDelegateObject? + open var additionalData: [AnyHashable : Any]? + + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol + //-------------------------------------------------- + + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + guard let model = model as? ButtonGroupModel, + let buttonModel = model.buttons.first + else { return 0 } + + return PillButton.estimatedHeight(with: buttonModel, delegateObject) + } + + public func viewModelDidUpdate() { + var buttonBases = [ButtonBase]() + viewModel.buttons.forEach { buttonModel in + if let buttonBaseType = try? ModelRegistry.getHandler(buttonModel) as? MoleculeViewProtocol.Type, + let button = buttonBaseType.init(model: buttonModel, delegateObject, additionalData) as? VDS.ButtonBase { + buttonBases.append(button) + } + } + surface = viewModel.surface + alignment = viewModel.alignment + rowQuantityPhone = viewModel.rowQuantityPhone + rowQuantityTablet = viewModel.rowQuantityTablet + if let childWidthValue = viewModel.childWidthValue { + childWidth = .value(childWidthValue) + } else if let childWidthPercentage = viewModel.childWidthPercentage { + childWidth = .percentage(childWidthPercentage) + } + buttons = buttonBases + } + + //-------------------------------------------------- + // MARK: - MVMCoreUIViewConstrainingProtocol + //-------------------------------------------------- + + open func horizontalAlignment() -> UIStackView.Alignment { + return .center + } + + //-------------------------------------------------- + // MARK: - MVMCoreViewProtocol + //-------------------------------------------------- + public func updateView(_ size: CGFloat) { + setNeedsUpdate() + } +} diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift new file mode 100644 index 00000000..060c11af --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift @@ -0,0 +1,73 @@ +// +// ButtonGroupModel.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/11/24. +// Copyright © 2024 Verizon Wireless. All rights reserved. +// + +import Foundation +import VDS + +public class ButtonGroupModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "buttonGroup" + public var id: String = UUID().uuidString + public var backgroundColor: Color? + + public var buttons: [ButtonModelProtocol & MoleculeModelProtocol] + public var alignment: VDS.ButtonGroup.Alignment = .center + public var rowQuantityPhone: Int = 0 + public var rowQuantityTablet: Int = 0 + public var childWidthValue: CGFloat? + public var childWidthPercentage: CGFloat? + public var surface: VDS.Surface = .light + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case id + case moleculeName + case backgroundColor + case buttons + case alignment + case rowQuantityPhone + case rowQuantityTablet + case childWidthValue + case childWidthPercentage + case surface + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + + 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 + surface = try typeContainer.decodeIfPresent(Surface.self, forKey: .surface) ?? .light + buttons = try typeContainer.decodeModels(codingKey: .buttons) + alignment = try typeContainer.decodeIfPresent(VDS.ButtonGroup.Alignment.self, forKey: .alignment) ?? .center + rowQuantityPhone = try typeContainer.decodeIfPresent(Int.self, forKey: .rowQuantityPhone) ?? 0 + rowQuantityTablet = try typeContainer.decodeIfPresent(Int.self, forKey: .rowQuantityTablet) ?? 0 + childWidthValue = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .childWidthValue) ?? 0.0 + childWidthPercentage = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .childWidthPercentage) ?? 0.0 + } + + 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.encodeModels(buttons, forKey: .buttons) + try container.encode(alignment, forKey: .alignment) + try container.encode(rowQuantityPhone, forKey: .rowQuantityPhone) + try container.encode(rowQuantityTablet, forKey: .rowQuantityTablet) + try container.encodeIfPresent(childWidthValue, forKey: .childWidthValue) + try container.encodeIfPresent(childWidthPercentage, forKey: .childWidthPercentage) + } +} diff --git a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift index 1d24a0bd..a9666cba 100644 --- a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift +++ b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift @@ -11,6 +11,7 @@ import VDS extension Surface: Codable {} extension Badge.FillColor: Codable {} +extension VDS.ButtonGroup.Alignment: Codable {} extension Icon.Name: Codable {} extension Icon.Size: Codable {} extension TileContainer.BackgroundColor: Codable {} @@ -23,4 +24,5 @@ extension Use: Codable {} extension VDS.Button.Size: RawRepresentableCodable { public static var mapping: [String : VDS.Button.Size] { ["standard": .large, "tiny": .small] } public static var defaultValue: VDS.Button.Size? { nil } -} \ No newline at end of file +} + From 8ba25bb6611bdd2646d3bef39360f8acb803d908 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 11 Jan 2024 11:31:58 -0600 Subject: [PATCH 4/6] registered ButtonGroup Atom Signed-off-by: Matt Bruce --- MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index b339cf94..8b3d5529 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -36,7 +36,8 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: ExternalLink.self, for: ExternalLinkModel.self) ModelRegistry.register(handler: Link.self, for: LinkModel.self) ModelRegistry.register(handler: CaretLink.self, for: CaretLinkModel.self) - + ModelRegistry.register(handler: ButtonGroup.self, for: ButtonGroupModel.self) + // MARK:- Entry Field ModelRegistry.register(handler: TextEntryField.self, for: TextEntryFieldModel.self) ModelRegistry.register(handler: MdnEntryField.self, for: MdnEntryFieldModel.self) From ea3ee2addab585d0682b2d906c0a68df147c98a7 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 11 Jan 2024 11:42:53 -0600 Subject: [PATCH 5/6] added comments Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift index 060c11af..0ee3b68e 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift @@ -18,6 +18,9 @@ public class ButtonGroupModel: MoleculeModelProtocol { public var id: String = UUID().uuidString public var backgroundColor: Color? + //-------------------------------------------------- + // MARK: - VDS Properties + //-------------------------------------------------- public var buttons: [ButtonModelProtocol & MoleculeModelProtocol] public var alignment: VDS.ButtonGroup.Alignment = .center public var rowQuantityPhone: Int = 0 @@ -55,8 +58,8 @@ public class ButtonGroupModel: MoleculeModelProtocol { alignment = try typeContainer.decodeIfPresent(VDS.ButtonGroup.Alignment.self, forKey: .alignment) ?? .center rowQuantityPhone = try typeContainer.decodeIfPresent(Int.self, forKey: .rowQuantityPhone) ?? 0 rowQuantityTablet = try typeContainer.decodeIfPresent(Int.self, forKey: .rowQuantityTablet) ?? 0 - childWidthValue = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .childWidthValue) ?? 0.0 - childWidthPercentage = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .childWidthPercentage) ?? 0.0 + childWidthValue = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .childWidthValue) + childWidthPercentage = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .childWidthPercentage) } public func encode(to encoder: Encoder) throws { From 1f74c88ce6602699e553a25b4fa7fb402e8c9e28 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 11 Jan 2024 12:07:42 -0600 Subject: [PATCH 6/6] added enabled Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift | 1 + MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift index 8fe15acb..53c0a476 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroup.swift @@ -40,6 +40,7 @@ import VDS } } surface = viewModel.surface + isEnabled = viewModel.enabled alignment = viewModel.alignment rowQuantityPhone = viewModel.rowQuantityPhone rowQuantityTablet = viewModel.rowQuantityTablet diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift index 0ee3b68e..4921d0f0 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonGroupModel.swift @@ -28,7 +28,7 @@ public class ButtonGroupModel: MoleculeModelProtocol { public var childWidthValue: CGFloat? public var childWidthPercentage: CGFloat? public var surface: VDS.Surface = .light - + public var enabled: Bool = true //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -44,6 +44,7 @@ public class ButtonGroupModel: MoleculeModelProtocol { case childWidthValue case childWidthPercentage case surface + case enabled } //-------------------------------------------------- @@ -54,6 +55,7 @@ public class ButtonGroupModel: MoleculeModelProtocol { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString surface = try typeContainer.decodeIfPresent(Surface.self, forKey: .surface) ?? .light + enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true buttons = try typeContainer.decodeModels(codingKey: .buttons) alignment = try typeContainer.decodeIfPresent(VDS.ButtonGroup.Alignment.self, forKey: .alignment) ?? .center rowQuantityPhone = try typeContainer.decodeIfPresent(Int.self, forKey: .rowQuantityPhone) ?? 0 @@ -66,6 +68,8 @@ public class ButtonGroupModel: MoleculeModelProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(surface, forKey: .surface) + try container.encode(enabled, forKey: .enabled) try container.encodeModels(buttons, forKey: .buttons) try container.encode(alignment, forKey: .alignment) try container.encode(rowQuantityPhone, forKey: .rowQuantityPhone)