From b58cfbe1753a2d25322c4bb9738e09f13e420d0c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 24 Jan 2024 16:50:58 -0600 Subject: [PATCH 01/47] added contentHugging and compressionResistance Signed-off-by: Matt Bruce --- VDS/Classes/SelfSizingCollectionView.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/VDS/Classes/SelfSizingCollectionView.swift b/VDS/Classes/SelfSizingCollectionView.swift index b75e61e4..70ccc083 100644 --- a/VDS/Classes/SelfSizingCollectionView.swift +++ b/VDS/Classes/SelfSizingCollectionView.swift @@ -60,6 +60,10 @@ public final class SelfSizingCollectionView: UICollectionView { // MARK: - Private Methods //-------------------------------------------------- private func setupContentSizeObservation() { + //ensure autoLayout uses intrinsic height + setContentHuggingPriority(.required, for: .vertical) + setContentCompressionResistancePriority(.required, for: .vertical) + // Observing the value of contentSize seems to be the only reliable way to get the contentSize after the collection view lays out its subviews. self.contentSizeObservation = self.observe(\.contentSize, options: [.old, .new]) { [weak self] _, change in // If we don't specify `options: [.old, .new]`, the change.oldValue and .newValue will always be `nil`. From ddd363e2da0da4b61cbb9476f60fe735ba3f5229 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 26 Jan 2024 09:22:54 -0600 Subject: [PATCH 02/47] fix issue with height Signed-off-by: Matt Bruce --- VDS/Classes/SelfSizingCollectionView.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/VDS/Classes/SelfSizingCollectionView.swift b/VDS/Classes/SelfSizingCollectionView.swift index 70ccc083..9d24607f 100644 --- a/VDS/Classes/SelfSizingCollectionView.swift +++ b/VDS/Classes/SelfSizingCollectionView.swift @@ -56,6 +56,12 @@ public final class SelfSizingCollectionView: UICollectionView { } } + public override func reloadData() { + super.reloadData() + setNeedsLayout() + layoutIfNeeded() + } + //-------------------------------------------------- // MARK: - Private Methods //-------------------------------------------------- From 4632d3caa5978e33247d3ab5615e07ae46779980 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 26 Jan 2024 14:08:40 -0600 Subject: [PATCH 03/47] added for intrinsicSize fix Signed-off-by: Matt Bruce --- VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 273f11ff..9cf82696 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -103,6 +103,8 @@ open class ButtonGroup: View { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- + fileprivate var collectionViewHeight: NSLayoutConstraint? + fileprivate lazy var positionLayout = ButtonGroupPositionLayout().with { $0.position = .center $0.delegate = self @@ -130,6 +132,8 @@ open class ButtonGroup: View { super.setup() addSubview(collectionView) collectionView.pinToSuperView() + collectionViewHeight = heightAnchor.constraint(equalToConstant: VDS.Button.Size.large.height) + collectionViewHeight?.activate() } //-------------------------------------------------- @@ -169,6 +173,7 @@ open class ButtonGroup: View { DispatchQueue.main.async { [weak self] in guard let self else { return } self.collectionView.collectionViewLayout.invalidateLayout() + self.collectionViewHeight?.constant = self.collectionView.intrinsicContentSize.height } } } From 6e724503158624259b73b8c5f19dc1d26aaaa96d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 26 Jan 2024 16:13:41 -0600 Subject: [PATCH 04/47] removed old fix Signed-off-by: Matt Bruce --- VDS/Classes/SelfSizingCollectionView.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/VDS/Classes/SelfSizingCollectionView.swift b/VDS/Classes/SelfSizingCollectionView.swift index 9d24607f..7954a50e 100644 --- a/VDS/Classes/SelfSizingCollectionView.swift +++ b/VDS/Classes/SelfSizingCollectionView.swift @@ -56,11 +56,11 @@ public final class SelfSizingCollectionView: UICollectionView { } } - public override func reloadData() { - super.reloadData() - setNeedsLayout() - layoutIfNeeded() - } +// public override func reloadData() { +// super.reloadData() +// setNeedsLayout() +// layoutIfNeeded() +// } //-------------------------------------------------- // MARK: - Private Methods From d54a1d4b0296b6c1b831c8d745d653573dda53d9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 26 Jan 2024 16:17:07 -0600 Subject: [PATCH 05/47] removed code Signed-off-by: Matt Bruce --- VDS/Classes/SelfSizingCollectionView.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/VDS/Classes/SelfSizingCollectionView.swift b/VDS/Classes/SelfSizingCollectionView.swift index 7954a50e..3a99404a 100644 --- a/VDS/Classes/SelfSizingCollectionView.swift +++ b/VDS/Classes/SelfSizingCollectionView.swift @@ -55,12 +55,6 @@ public final class SelfSizingCollectionView: UICollectionView { self.collectionViewLayout.invalidateLayout() } } - -// public override func reloadData() { -// super.reloadData() -// setNeedsLayout() -// layoutIfNeeded() -// } //-------------------------------------------------- // MARK: - Private Methods From 8f3f5ae84349a583d67dbb5d42ae8ede96c4a987 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 29 Jan 2024 09:29:37 -0600 Subject: [PATCH 06/47] ensure voiceover is running Signed-off-by: Matt Bruce --- VDS/Components/Loader/Loader.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Loader/Loader.swift b/VDS/Components/Loader/Loader.swift index 691fed89..f765c4e6 100644 --- a/VDS/Components/Loader/Loader.swift +++ b/VDS/Components/Loader/Loader.swift @@ -107,10 +107,18 @@ open class Loader: View { rotation.duration = 0.5 rotation.repeatCount = .infinity icon.layer.add(rotation, forKey: rotationLayerName) - + + // check to make sure VoiceOver is running + guard UIAccessibility.isVoiceOverRunning else { + loadingTimer?.invalidate() + loadingTimer = nil + return + } + // Focus VoiceOver on this view UIAccessibility.post(notification: .layoutChanged, argument: self) - + + // setup timer for post loadingTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in self?.accessibilityLabel = "Still Loading" UIAccessibility.post(notification: .announcement, argument: "Still Loading") From 3448954ddca1de08e1ff646c34248ef85133443f Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 29 Jan 2024 15:07:31 -0600 Subject: [PATCH 07/47] updated reset() Signed-off-by: Matt Bruce --- .../Buttons/ButtonGroup/ButtonGroup.swift | 13 ++++++++++++- VDS/Components/Checkbox/CheckboxGroup.swift | 5 +++++ .../RadioButton/RadioButtonGroup.swift | 5 +++++ VDS/Components/Tabs/Tabs.swift | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 9cf82696..1fdbc56d 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -99,7 +99,7 @@ open class ButtonGroup: View { buttons.forEach { $0.surface = surface } } } - + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -167,6 +167,17 @@ open class ButtonGroup: View { collectionView.reloadData() } + open override func reset() { + super.reset() + shouldUpdateView = false + rowQuantityPhone = 0 + rowQuantityTablet = 0 + alignment = .center + buttons.forEach { $0.reset() } + shouldUpdateView = true + setNeedsUpdate() + } + open override func layoutSubviews() { super.layoutSubviews() // Accounts for any collection size changes diff --git a/VDS/Components/Checkbox/CheckboxGroup.swift b/VDS/Components/Checkbox/CheckboxGroup.swift index 34fc657d..ef9b5405 100644 --- a/VDS/Components/Checkbox/CheckboxGroup.swift +++ b/VDS/Components/Checkbox/CheckboxGroup.swift @@ -88,6 +88,11 @@ open class CheckboxGroup: SelectorGroupBase, SelectorGroupMultiSel } valueChanged() } + + open override func reset() { + super.reset() + showError = false + } } extension CheckboxGroup { diff --git a/VDS/Components/RadioButton/RadioButtonGroup.swift b/VDS/Components/RadioButton/RadioButtonGroup.swift index c33a376e..6b12f60a 100644 --- a/VDS/Components/RadioButton/RadioButtonGroup.swift +++ b/VDS/Components/RadioButton/RadioButtonGroup.swift @@ -73,6 +73,11 @@ open class RadioButtonGroup: SelectorGroupBase, SelectorGroupSi } } + open override func reset() { + super.reset() + showError = false + } + public override func didSelect(_ selectedControl: RadioButtonItem) { if let selectedItem { updateToggle(selectedItem) diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index 0b6b8fac..d6273771 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -219,6 +219,24 @@ open class Tabs: View { updateContentView() } + open override func reset() { + super.reset() + shouldUpdateView = false + orientation = .horizontal + borderLine = true + fillContainer = false + indicatorFillTab = false + indicatorPosition = .bottom + minWidth = 44.0 + overflow = .scroll + selectedIndex = 0 + size = .medium + sticky = false + tabViews.forEach{ $0.reset() } + shouldUpdateView = true + setNeedsUpdate() + } + //-------------------------------------------------- // MARK: - Private Methods //-------------------------------------------------- From 1646eb75dc11b4c281a366bc2418055322994136 Mon Sep 17 00:00:00 2001 From: vasavk Date: Tue, 30 Jan 2024 10:48:20 +0530 Subject: [PATCH 08/47] story:ONEAPP-6315: Updated background color, drop shadow according to states based on component surface. --- .../Icon/ButtonIcon/ButtonIcon.swift | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 85e0ae6e..dd0c0c71 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -181,13 +181,19 @@ open class ButtonIcon: Control { }() } - private struct LowContrastColorFillFloatingConfiguration: Configuration { + private struct LowContrastColorFillFloatingConfiguration: Configuration, Dropshadowable { var kind: Kind = .lowContrast var surfaceType: SurfaceType = .colorFill var floating: Bool = true var backgroundColorConfiguration: AnyColorable = { - SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, .clear).eraseToAnyColorable() + SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteGray20).eraseToAnyColorable() }() + var shadowColorConfiguration: AnyColorable = { + SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + }() + var shadowOpacity: CGFloat = 0.16 + var shadowOffset: CGSize = .init(width: 0, height: 2) + var shadowRadius: CGFloat = 4 } private struct LowContrastMediaConfiguration: Configuration, Borderable { @@ -195,11 +201,11 @@ open class ButtonIcon: Control { var surfaceType: SurfaceType = .media var floating: Bool = false var backgroundColorConfiguration: AnyColorable = { - SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, .clear).eraseToAnyColorable() + SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryDark).eraseToAnyColorable() }() var borderWidth: CGFloat = 1.0 var borderColorConfiguration: AnyColorable = { - SurfaceColorConfiguration(VDSColor.elementsLowcontrastOnlight, .clear).eraseToAnyColorable() + SurfaceColorConfiguration(VDSColor.elementsLowcontrastOnlight, VDSColor.elementsLowcontrastOndark).eraseToAnyColorable() }() } @@ -208,14 +214,14 @@ open class ButtonIcon: Control { var surfaceType: SurfaceType = .media var floating: Bool = true var backgroundColorConfiguration: AnyColorable = { - SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, .clear).eraseToAnyColorable() + SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteGray20).eraseToAnyColorable() }() var shadowColorConfiguration: AnyColorable = { - SurfaceColorConfiguration(VDSColor.paletteBlack, .clear).eraseToAnyColorable() + SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() }() var shadowOpacity: CGFloat = 0.16 var shadowOffset: CGSize = .init(width: 0, height: 2) - var shadowRadius: CGFloat = 2 + var shadowRadius: CGFloat = 4 } private struct HighContrastConfiguration: Configuration { @@ -232,17 +238,23 @@ open class ButtonIcon: Control { }() } - private struct HighContrastFloatingConfiguration: Configuration { + private struct HighContrastFloatingConfiguration: Configuration, Dropshadowable { var kind: Kind = .highContrast var surfaceType: SurfaceType = .colorFill var floating: Bool = true var backgroundColorConfiguration: AnyColorable = { return ControlColorConfiguration().with { - $0.setSurfaceColors(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryLight, forState: .normal) + $0.setSurfaceColors(VDSColor.paletteGray20, VDSColor.paletteWhite, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) }.eraseToAnyColorable() }() + var shadowColorConfiguration: AnyColorable = { + SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + }() + var shadowOpacity: CGFloat = 0.16 + var shadowOffset: CGSize = .init(width: 0, height: 2) + var shadowRadius: CGFloat = 6 } //-------------------------------------------------- From 578cb2ef120cea8ec0105812b2784cc0c152849b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 31 Jan 2024 10:10:01 -0600 Subject: [PATCH 09/47] ONEAPP-6244 - TitleLockup TitleLabel marked as .heading for Accessibility Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 2 ++ VDS/SupportingFiles/ReleaseNotes.txt | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 455ed92b..6567de25 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -77,6 +77,7 @@ open class TitleLockup: View { /// Label used to render the title model. open var titleLabel = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) + $0.accessibilityTraits.insert([.header]) } /// Model used in rendering the title label. @@ -388,3 +389,4 @@ open class TitleLockup: View { } } +6 diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index bf045627..b4ae5bbb 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,7 @@ +1.0.52 +---------------- +- ONEAPP-6244 - TitleLockup TitleLabel marked as .heading for Accessibility. + 1.0.51 ---------------- - ONEAPP-6239 - Loader is still showing when inactive. From 4e0832fa64fe7a33995b2ebe6cc204338f00e99b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 31 Jan 2024 14:37:59 -0600 Subject: [PATCH 10/47] updated version Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 28cadb8a..c28da8f9 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1233,7 +1233,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 51; + CURRENT_PROJECT_VERSION = 52; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1270,7 +1270,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 51; + CURRENT_PROJECT_VERSION = 52; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; From 01fcc57ba2fae8454bc7743108e20ef6fdfb7739 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 31 Jan 2024 14:40:07 -0600 Subject: [PATCH 11/47] updated textLinkCaret to allow word wrapping Signed-off-by: Matt Bruce --- VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift b/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift index fd990720..aaa9f3cb 100644 --- a/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift +++ b/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift @@ -80,6 +80,8 @@ open class TextLinkCaret: ButtonBase { open override func setup() { super.setup() accessibilityTraits = .link + titleLabel?.numberOfLines = 0 + titleLabel?.lineBreakMode = .byWordWrapping } /// Used to make changes to the View based off a change events or from local properties. From 928483657d679bce17fa0da99183ea64d6b42974 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 31 Jan 2024 14:47:01 -0600 Subject: [PATCH 12/47] remvoed bug Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 6567de25..dbfd8637 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -389,4 +389,3 @@ open class TitleLockup: View { } } -6 From 3720541b42c8078aec0c734aa1d22db341b9dddd Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 6 Feb 2024 14:38:22 -0600 Subject: [PATCH 13/47] ONEAPP-4683 - updated to accesibilityValue for the tabs position. Signed-off-by: Matt Bruce --- VDS/Components/Tabs/Tabs.swift | 5 ++++- VDS/SupportingFiles/ReleaseNotes.txt | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index d6273771..0aa81bdf 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -171,6 +171,8 @@ open class Tabs: View { /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() + isAccessibilityElement = false + scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.showsHorizontalScrollIndicator = false @@ -262,6 +264,7 @@ open class Tabs: View { model.onClick?(tab.index) self.selectedIndex = tab.index self.onTabDidSelect?(tab.index) + let t = tabViews[tab.index] } } } @@ -301,7 +304,7 @@ open class Tabs: View { tabItem.orientation = orientation tabItem.surface = surface tabItem.indicatorPosition = indicatorPosition - tabItem.accessibilityHint = "\(index+1) of \(tabViews.count) Tabs" + tabItem.accessibilityValue = "\(index+1) of \(tabViews.count) Tabs" } } diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index b4ae5bbb..04a04a10 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,7 @@ +1.0.53 +---------------- +- ONEAPP-4683 - Updated to accesibilityValue for the tabs position. + 1.0.52 ---------------- - ONEAPP-6244 - TitleLockup TitleLabel marked as .heading for Accessibility. From f66d15fdfca05dcbaec20ef932a028bf43b523ce Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 6 Feb 2024 14:48:23 -0600 Subject: [PATCH 14/47] updated version Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index c28da8f9..74159fed 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1233,7 +1233,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 52; + CURRENT_PROJECT_VERSION = 53; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1270,7 +1270,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 52; + CURRENT_PROJECT_VERSION = 53; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; From 95d638ebf43f968b1ee8e2cc8be419143f44b4e2 Mon Sep 17 00:00:00 2001 From: vasavk Date: Wed, 7 Feb 2024 13:12:39 +0530 Subject: [PATCH 15/47] having badge indicator object for the buttonIcon --- .../Icon/ButtonIcon/ButtonIcon.swift | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index dd0c0c71..7a768c80 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -43,6 +43,11 @@ open class ButtonIcon: Control { case colorFill, media } + /// Enum used to describe the badge indicator direction of icon button determining the expand direction. + public enum ExpandDirection: String, CaseIterable { + case right, center, left + } + /// Enum used to describe the size of button icon. public enum Size: String, EnumSubset { case large @@ -67,6 +72,8 @@ open class ButtonIcon: Control { private var centerYConstraint: NSLayoutConstraint? private var layoutGuideWidthConstraint: NSLayoutConstraint? private var layoutGuideHeightConstraint: NSLayoutConstraint? + private var badgeIndicatorLeadingConstraint: NSLayoutConstraint? + private var badgeIndicatorBottomConstraint: NSLayoutConstraint? private var currentIconName: Icon.Name? { if let selectedIconName { return selectedIconName @@ -75,9 +82,31 @@ open class ButtonIcon: Control { } } + private var badgeIndicatorOffset: CGPoint { + switch (size, kind) { + case (.small, .ghost): + return .init(x: 1, y: 0) + case (.large, .ghost): + return .init(x: 1, y: 1) + case (.small, .lowContrast), (.small, .highContrast): + return .init(x: 4, y: 4) + case (.large, .lowContrast), (.large, .highContrast): + return .init(x: 6, y: 6) + } + } + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + + ///BadgeIndicator object used to render for the ButtonIcon. + open var badgeIndicator = BadgeIndicator().with { + $0.translatesAutoresizingMaskIntoConstraints = false +// $0.hideBorder = true +// $0.borderWidth = 0 + $0.size = .small + } + /// Icon object used to render out the Icon for this ButtonIcon. open var icon = Icon().with { $0.isUserInteractionEnabled = false } @@ -107,7 +136,13 @@ open class ButtonIcon: Control { /// If set to true, the button icon will not have a border. open var hideBorder: Bool = true { didSet { setNeedsUpdate() } } + + /// If provided, the badge indicator will present. + open var showBadge: Bool = false { didSet { setNeedsUpdate() } } + /// If provided, the button icon will have selectable Icon. + open var selectable: Bool = false { didSet { setNeedsUpdate() } } + /// Used to move the icon inside the button in both x and y axis. open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } } @@ -270,11 +305,16 @@ open class ButtonIcon: Control { //add the icon addSubview(icon) + addSubview(badgeIndicator) + badgeIndicator.isHidden = !showBadge //determines the height/width of the icon layoutGuideWidthConstraint = iconLayoutGuide.width(constant: size.containerSize) layoutGuideHeightConstraint = iconLayoutGuide.height(constant: size.containerSize) - + badgeIndicatorBottomConstraint = icon.centerYAnchor.constraint(equalTo: badgeIndicator.bottomAnchor) + badgeIndicatorLeadingConstraint = badgeIndicator.leadingAnchor.constraint(equalTo: icon.centerXAnchor) + badgeIndicatorBottomConstraint?.isActive = true + badgeIndicatorLeadingConstraint?.isActive = true //pin layout guide iconLayoutGuide .pinTop() @@ -300,6 +340,9 @@ open class ButtonIcon: Control { hideBorder = true iconOffset = .init(x: 0, y: 0) iconName = nil +// selectableIconName = nil + showBadge = false + selectable = false shouldUpdateView = true setNeedsUpdate() } @@ -318,6 +361,8 @@ open class ButtonIcon: Control { } else { icon.reset() } + badgeIndicatorLeadingConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorBottomConstraint?.constant = badgeIndicatorOffset.y setNeedsLayout() } From 4f79547bf8f947a0d8a3ef5329399111359c3a08 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Wed, 7 Feb 2024 20:14:43 +0530 Subject: [PATCH 16/47] Updated constraints for NotificationView for layout horizontal --- .../Notification/Notification.swift | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index 274ad8af..bd2f778c 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -69,17 +69,25 @@ open class Notification: View { } private var labelsView = UIStackView().with { + $0.spacing = 1.0 $0.translatesAutoresizingMaskIntoConstraints = false - $0.alignment = .top + $0.alignment = .fill + $0.distribution = .equalSpacing $0.axis = .vertical } - private var labelButtonView = UIStackView().with { + private var labelButtonView = View().with { $0.translatesAutoresizingMaskIntoConstraints = false - $0.alignment = .top - $0.distribution = .fillEqually - $0.axis = .vertical - $0.spacing = VDSLayout.Spacing.space2X.value + } + + private var labelButtonViewSpacing: CGFloat { + let spacing: CGFloat = UIDevice.isIPad ? 20 : 16 + return switch layout { + case .vertical: + 0 + case .horizontal: + spacing + } } internal var onCloseSubscriber: AnyCancellable? @@ -215,6 +223,15 @@ open class Notification: View { return 1232 } + private var labelViewWidthConstraint: NSLayoutConstraint? + private var labelViewBottomConstraint: NSLayoutConstraint? + private var labelViewAndButtonViewConstraint: NSLayoutConstraint? + private var buttonViewTopConstraint: NSLayoutConstraint? + private var typeIconWidthConstraint: NSLayoutConstraint? + private var closeIconWidthConstraint: NSLayoutConstraint? + private var buttonGroupCenterYConstraint: NSLayoutConstraint? + private var buttonGroupBottomConstraint: NSLayoutConstraint? + //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- @@ -240,12 +257,29 @@ open class Notification: View { ]) maxWidthConstraint = layoutGuide.widthAnchor.constraint(lessThanOrEqualToConstant: maxViewWidth) - labelButtonView.addArrangedSubview(labelsView) - + labelButtonView.addSubview(labelsView) + labelsView + .pinTop() + .pinLeading() + labelViewWidthConstraint = labelsView.widthAnchor.constraint(equalTo: labelButtonView.widthAnchor, multiplier: 1.0) + labelViewWidthConstraint?.activate() + labelViewBottomConstraint = labelButtonView.bottomAnchor.constraint(equalTo: labelsView.bottomAnchor) + + labelButtonView.addSubview(buttonGroup) + buttonGroup + .pinTrailing() + buttonGroupBottomConstraint = labelButtonView.bottomAnchor.constraint(equalTo: buttonGroup.bottomAnchor) + buttonGroupCenterYConstraint = buttonGroup.centerYAnchor.constraint(equalTo: labelButtonView.centerYAnchor) + labelViewAndButtonViewConstraint = buttonGroup.topAnchor.constraint(equalTo: labelsView.bottomAnchor, constant: 3.0) + buttonGroup.widthAnchor.constraint(equalTo: labelsView.widthAnchor).activate() + mainStackView.addArrangedSubview(typeIcon) mainStackView.addArrangedSubview(labelButtonView) mainStackView.addArrangedSubview(closeButton) - + + typeIconWidthConstraint = typeIcon.width(constant: typeIcon.size.dimensions.width) + closeIconWidthConstraint = closeButton.width(constant: closeButton.size.dimensions.width) + //labels titleLabel.textColorConfiguration = textColorConfiguration.eraseToAnyColorable() subTitleLabel.textColorConfiguration = textColorConfiguration.eraseToAnyColorable() @@ -342,28 +376,28 @@ open class Notification: View { secondaryButton.onClick = secondaryButtonModel.onClick buttons.append(secondaryButton) } - + labelViewWidthConstraint?.deactivate() if buttons.isEmpty { - labelsView.setCustomSpacing(0, after: subTitleLabel) - buttonGroup.removeFromSuperview() + buttonGroup.isHidden = true + labelViewWidthConstraint = labelsView.widthAnchor.constraint(equalTo: labelButtonView.widthAnchor) + buttonGroup.buttons.removeAll() } else { labelsView.setCustomSpacing(VDSLayout.Spacing.space3X.value, after: subTitleLabel) - buttonGroup.buttons = buttons - labelButtonView.axis = layout == .vertical ? .vertical : .horizontal - labelButtonView.addArrangedSubview(buttonGroup) - - buttonGroup - .pinLeading() - .pinTrailing() + buttonGroup.isHidden = false + labelViewWidthConstraint = labelsView.widthAnchor.constraint(equalTo: labelButtonView.widthAnchor, multiplier: layout == .vertical ? 1.0 : 0.5, constant: layout == .vertical ? 0 : -labelButtonViewSpacing) } + labelViewWidthConstraint?.activate() } private func setConstraints() { - maxWidthConstraint?.constant = maxViewWidth maxWidthConstraint?.isActive = UIDevice.isIPad - + labelViewAndButtonViewConstraint?.isActive = layout == .vertical && !buttonGroup.buttons.isEmpty + typeIconWidthConstraint?.constant = typeIcon.size.dimensions.width + closeIconWidthConstraint?.constant = closeButton.size.dimensions.width + labelViewBottomConstraint?.isActive = layout == .horizontal || buttonGroup.buttons.isEmpty + buttonGroupCenterYConstraint?.isActive = layout == .horizontal + buttonGroupBottomConstraint?.isActive = layout == .vertical } } - From bbc36c72d3ec34884de64fdc3bbcfe6e3d1f34a3 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 7 Feb 2024 15:45:56 -0600 Subject: [PATCH 17/47] CXTDT-516206 - ButtonGroup iOS 16 issue Signed-off-by: Matt Bruce --- VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 9cf82696..ba2a83d8 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -190,8 +190,8 @@ extension ButtonGroup: UICollectionViewDataSource, UICollectionViewDelegate { public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let button = buttons[indexPath.row] guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as? ButtonGroupCollectionViewCell else { return UICollectionViewCell() } - cell.subviews.forEach { $0.removeFromSuperview() } - cell.addSubview(button) + cell.contentView.subviews.forEach { $0.removeFromSuperview() } + cell.contentView.addSubview(button) button.pinToSuperView() if hasDebugBorder { cell.addDebugBorder() From ba63562445da2e8c9e1c546800d51756c8c6a9be Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 7 Feb 2024 15:45:56 -0600 Subject: [PATCH 18/47] CXTDT-516206 - ButtonGroup iOS 16 issue Signed-off-by: Matt Bruce --- VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 1fdbc56d..113d19f5 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -201,8 +201,8 @@ extension ButtonGroup: UICollectionViewDataSource, UICollectionViewDelegate { public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let button = buttons[indexPath.row] guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as? ButtonGroupCollectionViewCell else { return UICollectionViewCell() } - cell.subviews.forEach { $0.removeFromSuperview() } - cell.addSubview(button) + cell.contentView.subviews.forEach { $0.removeFromSuperview() } + cell.contentView.addSubview(button) button.pinToSuperView() if hasDebugBorder { cell.addDebugBorder() From 206cbf04e47208bd605653c5c9263b51bff1d4d1 Mon Sep 17 00:00:00 2001 From: vasavk Date: Thu, 8 Feb 2024 13:19:47 +0530 Subject: [PATCH 19/47] story:ONEAPP-6315: using struct to set badge indicator properties --- VDS.xcodeproj/project.pbxproj | 4 + .../Icon/ButtonIcon/ButtonIcon.swift | 34 +++++++- .../ButtonIconBadgeIndicatorModel.swift | 78 +++++++++++++++++++ 3 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 28cadb8a..0356c108 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 18792A902B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */; }; 445BA07829C07B3D0036A7C5 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07729C07B3D0036A7C5 /* Notification.swift */; }; 44604AD429CE186A00E62B51 /* NotificationButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */; }; 44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; }; @@ -168,6 +169,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIconBadgeIndicatorModel.swift; sourceTree = ""; }; 445BA07729C07B3D0036A7C5 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; }; 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationButtonModel.swift; sourceTree = ""; }; 44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; @@ -671,6 +673,7 @@ isa = PBXGroup; children = ( EA81410A2A0E8E3C004F60D2 /* ButtonIcon.swift */, + 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */, ); path = ButtonIcon; sourceTree = ""; @@ -1060,6 +1063,7 @@ EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */, EAD062B02A3B873E0015965D /* BadgeIndicator.swift in Sources */, EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */, + 18792A902B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift in Sources */, EA0B18062A9E2D2D00F2D0CD /* SelectorItemBase.swift in Sources */, EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */, EA985BF5296C60C000F2FF2E /* Icon.swift in Sources */, diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 7a768c80..a15cef68 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -99,14 +99,15 @@ open class ButtonIcon: Control { // MARK: - Public Properties //-------------------------------------------------- - ///BadgeIndicator object used to render for the ButtonIcon. + ///Badge Indicator object used to render for the ButtonIcon. open var badgeIndicator = BadgeIndicator().with { $0.translatesAutoresizingMaskIntoConstraints = false -// $0.hideBorder = true -// $0.borderWidth = 0 $0.size = .small } + /// If set, this is used to render the badge indicator. + open var badgeIndicatorModel: BadgeIndicatorModel? { didSet { setNeedsUpdate() } } + /// Icon object used to render out the Icon for this ButtonIcon. open var icon = Icon().with { $0.isUserInteractionEnabled = false } @@ -305,6 +306,8 @@ open class ButtonIcon: Control { //add the icon addSubview(icon) + + //add badgeIndicator addSubview(badgeIndicator) badgeIndicator.isHidden = !showBadge @@ -343,6 +346,7 @@ open class ButtonIcon: Control { // selectableIconName = nil showBadge = false selectable = false + badgeIndicatorModel = nil shouldUpdateView = true setNeedsUpdate() } @@ -361,6 +365,7 @@ open class ButtonIcon: Control { } else { icon.reset() } + updateBadgeIndicator() badgeIndicatorLeadingConstraint?.constant = badgeIndicatorOffset.x badgeIndicatorBottomConstraint?.constant = badgeIndicatorOffset.y setNeedsLayout() @@ -410,6 +415,29 @@ open class ButtonIcon: Control { } } + + //-------------------------------------------------- + // MARK: - Private Methods + //-------------------------------------------------- + private func updateBadgeIndicator() { + if let badgeIndicatorModel { + badgeIndicator.kind = badgeIndicatorModel.kind + badgeIndicator.fillColor = badgeIndicatorModel.fillColor + badgeIndicator.surface = badgeIndicatorModel.surface + badgeIndicator.size = badgeIndicatorModel.size + badgeIndicator.maximumDigits = badgeIndicatorModel.maximumDigits + badgeIndicator.width = badgeIndicatorModel.width + badgeIndicator.height = badgeIndicatorModel.height + badgeIndicator.number = badgeIndicatorModel.number + badgeIndicator.leadingCharacter = badgeIndicatorModel.leadingCharacter + badgeIndicator.trailingText = badgeIndicatorModel.trailingText + badgeIndicator.dotSize = badgeIndicatorModel.dotSize + badgeIndicator.verticalPadding = badgeIndicatorModel.verticalPadding + badgeIndicator.horizontalPadding = badgeIndicatorModel.horizontalPadding + badgeIndicator.hideDot = badgeIndicatorModel.hideDot + badgeIndicator.hideBorder = badgeIndicatorModel.hideBorder + } + } } // MARK: AppleGuidelinesTouchable diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift b/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift new file mode 100644 index 00000000..b30e64e8 --- /dev/null +++ b/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift @@ -0,0 +1,78 @@ +// +// ButtonIconBadgeIndicatorModel.swift +// VDS +// +// Created by Kanamarlapudi, Vasavi on 08/02/24. +// + +import Foundation + +extension ButtonIcon { + + //Model that represents the options available for the Badge Indicator + public struct BadgeIndicatorModel { + + /// Kind that will be used for the badge indicator. + public var kind: BadgeIndicator.Kind + + /// Fill color that will be used for the badge indicator. + public var fillColor: BadgeIndicator.FillColor + + /// Current Surface and this is used to pass down to child objects that implement Surfacable + public var surface: Surface + + /// Size that will be used for the badge indicator. + public var size: BadgeIndicator.Size + + /// Number of digits that will be used for the badge indicator. + public var maximumDigits: BadgeIndicator.MaximumDigits + + /// Max width that will be used for the badge indicator. + public var width: CGFloat? + + /// Max height that will be used for the badge indicator. + public var height: CGFloat? + + /// Number that will be used for the badge indicator. + public var number: Int? + + /// Leading Character that will be used for the badge indicator. + public var leadingCharacter: String? + + /// Trailing Text height that will be used for the badge indicator. + public var trailingText: String? + + /// Dot Size that will be used for the badge indicator. + public var dotSize: CGFloat? + + /// Vertical Padding that will be used for the badge indicator. + public var verticalPadding: CGFloat? + + /// Horizontal Padding that will be used for the badge indicator. + public var horizontalPadding: CGFloat? + + /// Hide Dot that will be used for the badge indicator. + public var hideDot: Bool = false + + /// Hide Border that will be used for the badge indicator. + public var hideBorder: Bool = false + + public init(kind: BadgeIndicator.Kind = .simple, fillColor: BadgeIndicator.FillColor = .red, surface: Surface = .light, size: BadgeIndicator.Size = .xxlarge, maximumDigits: BadgeIndicator.MaximumDigits = .two, width: CGFloat? = nil, height: CGFloat? = nil, number: Int? = nil, leadingCharacter: String = "", trailingText: String = "", dotSize: CGFloat? = nil, verticalPadding: CGFloat? = nil, horizontalPadding: CGFloat? = nil, hideDot: Bool = false, hideBorder: Bool = false) { + self.kind = kind + self.fillColor = fillColor + self.surface = surface + self.size = size + self.maximumDigits = maximumDigits + self.width = width + self.height = height + self.number = number + self.leadingCharacter = leadingCharacter + self.trailingText = trailingText + self.dotSize = dotSize + self.verticalPadding = verticalPadding + self.horizontalPadding = horizontalPadding + self.hideDot = hideDot + self.hideBorder = hideBorder + } + } +} From 77c1026278cb8c456ec75824c003bda128dd1360 Mon Sep 17 00:00:00 2001 From: vasavk Date: Thu, 8 Feb 2024 22:58:15 +0530 Subject: [PATCH 20/47] story:ONEAPP-6315: Changes for the ExpandDirection picker, the button icon has no border if hideBorder is turned on --- .../Icon/ButtonIcon/ButtonIcon.swift | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index a15cef68..5b09a13d 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -139,7 +139,7 @@ open class ButtonIcon: Control { open var hideBorder: Bool = true { didSet { setNeedsUpdate() } } /// If provided, the badge indicator will present. - open var showBadge: Bool = false { didSet { setNeedsUpdate() } } + open var showBadgeIndicator: Bool = false { didSet { setNeedsUpdate() } } /// If provided, the button icon will have selectable Icon. open var selectable: Bool = false { didSet { setNeedsUpdate() } } @@ -147,6 +147,9 @@ open class ButtonIcon: Control { /// Used to move the icon inside the button in both x and y axis. open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } } + /// Applies expand direction to Badge Indicator if shows badge indicator. + open var expandDirection: ExpandDirection = .right { didSet { setNeedsUpdate() } } + //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- @@ -309,7 +312,7 @@ open class ButtonIcon: Control { //add badgeIndicator addSubview(badgeIndicator) - badgeIndicator.isHidden = !showBadge + badgeIndicator.isHidden = !showBadgeIndicator //determines the height/width of the icon layoutGuideWidthConstraint = iconLayoutGuide.width(constant: size.containerSize) @@ -344,9 +347,10 @@ open class ButtonIcon: Control { iconOffset = .init(x: 0, y: 0) iconName = nil // selectableIconName = nil - showBadge = false + showBadgeIndicator = false selectable = false badgeIndicatorModel = nil + expandDirection = .right shouldUpdateView = true setNeedsUpdate() } @@ -400,7 +404,7 @@ open class ButtonIcon: Control { layoutGuideHeightConstraint?.constant = iconLayoutSize //border - if let borderable = currentConfig as? Borderable { + if let borderable = currentConfig as? Borderable, self.hideBorder { layer.borderColor = borderable.borderColorConfiguration.getColor(self).cgColor layer.borderWidth = borderable.borderWidth } else { @@ -413,7 +417,10 @@ open class ButtonIcon: Control { } else { removeDropShadow() } - + + if showBadgeIndicator { + updateExpandDirectionalConstraints() + } } //-------------------------------------------------- @@ -438,6 +445,16 @@ open class ButtonIcon: Control { badgeIndicator.hideBorder = badgeIndicatorModel.hideBorder } } + + private func updateExpandDirectionalConstraints() { + if expandDirection == .right { + print("expandDirection -> Right") + } else if expandDirection == .center { + print("expandDirection -> center") + } else if expandDirection == .left { + print("expandDirection -> left") + } + } } // MARK: AppleGuidelinesTouchable From 0c9a689e13d9d41cf6456a0a1edda3ca43453118 Mon Sep 17 00:00:00 2001 From: vasavk Date: Thu, 8 Feb 2024 23:11:34 +0530 Subject: [PATCH 21/47] story:ONEAPP-6315: added buttonIcon changeLog --- VDS.xcodeproj/project.pbxproj | 4 + .../Icon/ButtonIcon/ButtonIconChangeLog.txt | 79 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 0356c108..7a9467eb 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 18792A902B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */; }; + 18BDEE822B75316E00452358 /* ButtonIconChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */; }; 445BA07829C07B3D0036A7C5 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07729C07B3D0036A7C5 /* Notification.swift */; }; 44604AD429CE186A00E62B51 /* NotificationButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */; }; 44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; }; @@ -170,6 +171,7 @@ /* Begin PBXFileReference section */ 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIconBadgeIndicatorModel.swift; sourceTree = ""; }; + 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ButtonIconChangeLog.txt; sourceTree = ""; }; 445BA07729C07B3D0036A7C5 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; }; 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationButtonModel.swift; sourceTree = ""; }; 44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; @@ -674,6 +676,7 @@ children = ( EA81410A2A0E8E3C004F60D2 /* ButtonIcon.swift */, 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */, + 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */, ); path = ButtonIcon; sourceTree = ""; @@ -941,6 +944,7 @@ EAEEECAF2B1FC2BA00531FC2 /* ToggleViewChangeLog.txt in Resources */, EAEEEC922B1F807300531FC2 /* BadgeChangeLog.txt in Resources */, EAEEEC9E2B1F8F7700531FC2 /* ButtonGroupChangeLog.txt in Resources */, + 18BDEE822B75316E00452358 /* ButtonIconChangeLog.txt in Resources */, EA3362062891E14D0071C351 /* VerizonNHGeTX-Regular.otf in Resources */, EA3362052891E14D0071C351 /* VerizonNHGeDS-Bold.otf in Resources */, EAEEECA02B1F908200531FC2 /* BadgeIndicatorChangeLog.txt in Resources */, diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt b/VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt new file mode 100644 index 00000000..df1dcb5f --- /dev/null +++ b/VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt @@ -0,0 +1,79 @@ + +03/30/2023 +---------------- +- Dev handoff + +04/06/2023 +---------------- +- Changed component name to Button Icon. + +04/13/2023 +---------------- +- Dev handoff (additional states) + +04/20/2023 +---------------- +- Added Selectable and Selected properties in Configuration. + +05/01/2023 +---------------- +- Added fitToIcon prop for Ghost variation. + +05/03/2023 +---------------- +- Updated drop shadows for light and dark floating buttons (all states) +- Removed border from all floating buttons +- Updated all dark floating button backgrounds to gray.20
 +- Disabled icons on gray.20 changed to palette.black 70% opacity for floating buttons +- Reduce Inside focusborderPosition to 1px + +05/25/2023 +---------------- +- Added hideBorder prop back to Configurations
 +- Added showBadgeIndicator prop to Configurations
 +- Added Hit Area support for Button Icon with Badge Indicator
 +- Added Elements page for Badge Indicator with default settings and offset information
 +- Updated Badge Indicator Offset to be based on center of Icon container + +05/30/2023 +---------------- +- Added expandDirection prop to Configurations under Badge Indicator section. + +06/02/2023 +---------------- +- Added Additional Border Color specification if hideBorder=True on Low Contrast hover states. + +06/12/2023 +---------------- +- Ghost Icon Cart position updated from {1,2} to {1,1}. + +06/13/2023 +---------------- +- Updated Drop shadow properties layout in States. + +06/29/2023 +---------------- +- Updated Badge Indicator simple dot size to 4px. + +08/18/2023 +---------------- +- Updated default icon color for all selected Button Icon states to element.primary.onlight for light surfaces and element.primary.ondark for dark surfaces. +- Added a dev note that this default color can be set to a custom color (like red). + +11/16/2023 +---------------- +- Added component tokens +- Applied component tokens throughout states +- Applied semantic inverse to primary element, background states on light and dark surfaces + +12/1/2023 +---------------- +- Reapplied component token updates to Ghost States + +1/9/2024 +---------------- +- Fixed incorrect Low Contrast border token + +1/25/2024 +---------------- +- Removed redundant opacity specs in States (dark surface). From b535fe5323ff3512ba534f117dd3107023c56c6c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 8 Feb 2024 17:05:28 -0600 Subject: [PATCH 22/47] CXTDT-518373 - Accessibility on Loader Signed-off-by: Matt Bruce --- VDS/Components/Loader/Loader.swift | 7 +++--- VDS/Extensions/UIView+Accessibility.swift | 26 +++++++++++++++++++++++ VDS/SupportingFiles/ReleaseNotes.txt | 4 ++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/VDS/Components/Loader/Loader.swift b/VDS/Components/Loader/Loader.swift index f765c4e6..90d589be 100644 --- a/VDS/Components/Loader/Loader.swift +++ b/VDS/Components/Loader/Loader.swift @@ -120,11 +120,12 @@ open class Loader: View { // setup timer for post loadingTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in - self?.accessibilityLabel = "Still Loading" + guard let self, self.isActive, self.isVisibleOnScreen else { return } + self.accessibilityLabel = "Still Loading" UIAccessibility.post(notification: .announcement, argument: "Still Loading") } } - + private func stopAnimating() { isAccessibilityElement = false icon.isHidden = true @@ -132,7 +133,7 @@ open class Loader: View { loadingTimer?.invalidate() loadingTimer = nil } - + deinit { stopAnimating() } diff --git a/VDS/Extensions/UIView+Accessibility.swift b/VDS/Extensions/UIView+Accessibility.swift index 6c785c5e..e85b3f74 100644 --- a/VDS/Extensions/UIView+Accessibility.swift +++ b/VDS/Extensions/UIView+Accessibility.swift @@ -24,4 +24,30 @@ extension UIView { public func setAccessibilityLabel(for views: [UIView]) { accessibilityLabel = combineAccessibilityLabel(for: views) } + + /// Will tell if the view is actually visibile on screen, also it will check the hierarchy above this view. + public var isVisibleOnScreen: Bool { + // Ensure the view has a window, meaning it's part of the view hierarchy + guard let window = self.window, !self.isHidden, self.alpha > 0 else { + return false + } + + // Check if the view's frame intersects with the window's bounds + let viewFrameInWindow = self.convert(self.bounds, to: window) + var isIntersecting = viewFrameInWindow.intersects(window.bounds) + + // Check parent views for visibility + var currentView: UIView? = self + while let view = currentView, isIntersecting { + // If any parent has a constraint making it effectively invisible, set isIntersecting to false + if view.bounds.size.width == 0 || view.bounds.size.height == 0 { + isIntersecting = false + break + } + currentView = view.superview + } + + return isIntersecting + } + } diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 04a04a10..fb0acb61 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,7 @@ +1.0.54 +---------------- +- CXTDT-518373 Accessibility Voiceover is reading “Still Loading” after waiting for a short time in all the screens. + 1.0.53 ---------------- - ONEAPP-4683 - Updated to accesibilityValue for the tabs position. From 960cf33b4193e3765c218bea71c52550e039bdfd Mon Sep 17 00:00:00 2001 From: vasavk Date: Fri, 9 Feb 2024 16:45:50 +0530 Subject: [PATCH 23/47] story:ONEAPP-6315: made changes for selectedIconName, and selected state of buttonIcon --- VDS/Components/Icon/ButtonIcon/ButtonIcon.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 5b09a13d..5e1e792e 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -75,7 +75,7 @@ open class ButtonIcon: Control { private var badgeIndicatorLeadingConstraint: NSLayoutConstraint? private var badgeIndicatorBottomConstraint: NSLayoutConstraint? private var currentIconName: Icon.Name? { - if let selectedIconName { + if let selectedIconName, selectable { return selectedIconName } else { return iconName @@ -120,7 +120,7 @@ open class ButtonIcon: Control { /// Icon Name used within the Icon. open var iconName: Icon.Name? { didSet { setNeedsUpdate() } } - /// Icon Name used within the Icon within the Selected State. + /// Selected Icon Name used within the Icon if selectable true. open var selectedIconName: Icon.Name? { didSet { setNeedsUpdate() } } /// Sets the size of button icon and icon. @@ -141,7 +141,7 @@ open class ButtonIcon: Control { /// If provided, the badge indicator will present. open var showBadgeIndicator: Bool = false { didSet { setNeedsUpdate() } } - /// If provided, the button icon will have selectable Icon. + /// If true, button will be rendered as selected, when it is selectable. open var selectable: Bool = false { didSet { setNeedsUpdate() } } /// Used to move the icon inside the button in both x and y axis. @@ -154,7 +154,7 @@ open class ButtonIcon: Control { // MARK: - Configuration //-------------------------------------------------- private var iconColorConfiguration: AnyColorable { - if selectedIconName != nil { + if selectedIconName != nil, selectable { return selectedIconColorConfiguration } else { if kind == .highContrast { @@ -346,7 +346,7 @@ open class ButtonIcon: Control { hideBorder = true iconOffset = .init(x: 0, y: 0) iconName = nil -// selectableIconName = nil + selectedIconName = nil showBadgeIndicator = false selectable = false badgeIndicatorModel = nil From ff5f7e5f5582143d08671bb963f9cb6087b53ef5 Mon Sep 17 00:00:00 2001 From: vasavk Date: Mon, 12 Feb 2024 13:25:58 +0530 Subject: [PATCH 24/47] story:ONEAPP-6315: expand direction configuration changes --- .../Icon/ButtonIcon/ButtonIcon.swift | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 5e1e792e..19b78e6f 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -73,7 +73,9 @@ open class ButtonIcon: Control { private var layoutGuideWidthConstraint: NSLayoutConstraint? private var layoutGuideHeightConstraint: NSLayoutConstraint? private var badgeIndicatorLeadingConstraint: NSLayoutConstraint? - private var badgeIndicatorBottomConstraint: NSLayoutConstraint? + private var badgeIndicatorTrailingConstraint: NSLayoutConstraint? + private var badgeIndicatorCenterXConstraint: NSLayoutConstraint? + private var badgeIndicatorCenterYConstraint: NSLayoutConstraint? private var currentIconName: Icon.Name? { if let selectedIconName, selectable { return selectedIconName @@ -295,7 +297,9 @@ open class ButtonIcon: Control { var shadowOffset: CGSize = .init(width: 0, height: 2) var shadowRadius: CGFloat = 6 } - + + private var badgeIndicatorDefaultSize: CGSize = .zero + //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- @@ -313,13 +317,17 @@ open class ButtonIcon: Control { //add badgeIndicator addSubview(badgeIndicator) badgeIndicator.isHidden = !showBadgeIndicator - + badgeIndicatorDefaultSize = badgeIndicator.frame.size + //determines the height/width of the icon layoutGuideWidthConstraint = iconLayoutGuide.width(constant: size.containerSize) layoutGuideHeightConstraint = iconLayoutGuide.height(constant: size.containerSize) - badgeIndicatorBottomConstraint = icon.centerYAnchor.constraint(equalTo: badgeIndicator.bottomAnchor) badgeIndicatorLeadingConstraint = badgeIndicator.leadingAnchor.constraint(equalTo: icon.centerXAnchor) - badgeIndicatorBottomConstraint?.isActive = true + badgeIndicatorTrailingConstraint = badgeIndicator.trailingAnchor.constraint(equalTo: icon.centerXAnchor) + badgeIndicatorCenterXConstraint = badgeIndicator.centerXAnchor.constraint(equalTo: icon.centerXAnchor) + badgeIndicatorCenterYConstraint = icon.centerYAnchor.constraint(equalTo: badgeIndicator.centerYAnchor) + badgeIndicatorCenterYConstraint?.isActive = true + badgeIndicatorLeadingConstraint?.isActive = true //pin layout guide iconLayoutGuide @@ -370,8 +378,6 @@ open class ButtonIcon: Control { icon.reset() } updateBadgeIndicator() - badgeIndicatorLeadingConstraint?.constant = badgeIndicatorOffset.x - badgeIndicatorBottomConstraint?.constant = badgeIndicatorOffset.y setNeedsLayout() } @@ -417,7 +423,12 @@ open class ButtonIcon: Control { } else { removeDropShadow() } - + + badgeIndicatorCenterXConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width/2 + badgeIndicatorCenterYConstraint?.constant = badgeIndicatorOffset.y + badgeIndicatorDefaultSize.height/2 + badgeIndicatorLeadingConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorTrailingConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width + if showBadgeIndicator { updateExpandDirectionalConstraints() } @@ -447,12 +458,19 @@ open class ButtonIcon: Control { } private func updateExpandDirectionalConstraints() { - if expandDirection == .right { - print("expandDirection -> Right") - } else if expandDirection == .center { - print("expandDirection -> center") - } else if expandDirection == .left { - print("expandDirection -> left") + switch expandDirection { + case .right: + badgeIndicatorLeadingConstraint?.isActive = true + badgeIndicatorTrailingConstraint?.isActive = false + badgeIndicatorCenterXConstraint?.isActive = false + case .center: + badgeIndicatorLeadingConstraint?.isActive = false + badgeIndicatorTrailingConstraint?.isActive = false + badgeIndicatorCenterXConstraint?.isActive = true + case .left: + badgeIndicatorLeadingConstraint?.isActive = false + badgeIndicatorCenterXConstraint?.isActive = false + badgeIndicatorTrailingConstraint?.isActive = true } } } From 7ec8b792eeb0008034dce7a821d9003bd7e9c65d Mon Sep 17 00:00:00 2001 From: vasavk Date: Mon, 12 Feb 2024 16:04:33 +0530 Subject: [PATCH 25/47] story:ONEAPP-6315: added accessibility --- VDS/Components/Icon/ButtonIcon/ButtonIcon.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 19b78e6f..12e5ee70 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -306,7 +306,10 @@ open class ButtonIcon: Control { /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() - + isAccessibilityElement = true + accessibilityTraits = .image + accessibilityElements = [badgeIndicator] + //create a layoutGuide for the icon to key off of let iconLayoutGuide = UILayoutGuide() addLayoutGuide(iconLayoutGuide) @@ -473,8 +476,14 @@ open class ButtonIcon: Control { badgeIndicatorTrailingConstraint?.isActive = true } } + + /// Used to update any Accessibility properties. + open override func updateAccessibility() { + super.updateAccessibility() + setAccessibilityLabel(for: [icon, badgeIndicator.label]) + } } - + // MARK: AppleGuidelinesTouchable extension ButtonIcon: AppleGuidelinesTouchable { /// Overrides to ensure that the touch point meets a minimum of the minimumTappableArea. From b3b3fa6965115633c1880b066ec6525ece131414 Mon Sep 17 00:00:00 2001 From: vasavk Date: Mon, 12 Feb 2024 20:27:19 +0530 Subject: [PATCH 26/47] story:ONEAPP-6315: updated icon and background color configurations as per spec --- .../Icon/ButtonIcon/ButtonIcon.swift | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 12e5ee70..247be717 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -156,14 +156,12 @@ open class ButtonIcon: Control { // MARK: - Configuration //-------------------------------------------------- private var iconColorConfiguration: AnyColorable { - if selectedIconName != nil, selectable { - return selectedIconColorConfiguration + if kind == .highContrast { + return highContrastIconColorConfiguration + } else if kind == .lowContrast { + return (surfaceType == .colorFill) ? lowContrastIconColorConfiguration : (floating ? lowContrastIconColorConfiguration : standardIconColorConfiguration) } else { - if kind == .highContrast { - return highContrastIconColorConfiguration - } else { - return standardIconColorConfiguration - } + return standardIconColorConfiguration } } @@ -192,16 +190,16 @@ open class ButtonIcon: Control { }.eraseToAnyColorable() }() - private var highContrastIconColorConfiguration: AnyColorable = { - return SurfaceColorConfiguration(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight).eraseToAnyColorable() + private var lowContrastIconColorConfiguration: AnyColorable = { + return ControlColorConfiguration().with { + $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal) + $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: .disabled) + }.eraseToAnyColorable() }() - private var selectedIconColorConfiguration: AnyColorable = { - return ControlColorConfiguration().with { - $0.setSurfaceColors(VDSColor.elementsBrandhighlight, VDSColor.elementsPrimaryOndark, forState: .normal) - $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) - $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) - }.eraseToAnyColorable() + private var highContrastIconColorConfiguration: AnyColorable = { + return SurfaceColorConfiguration(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight).eraseToAnyColorable() }() private struct GhostConfiguration: Configuration { From 7b9ba1acba58f23dc44a8c53560ea5f5088e0b70 Mon Sep 17 00:00:00 2001 From: vasavk Date: Tue, 13 Feb 2024 20:40:30 +0530 Subject: [PATCH 27/47] story:ONEAPP-6315: added the selected state for the color configuration --- VDS/Components/Icon/ButtonIcon/ButtonIcon.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 247be717..020f6c7d 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -186,7 +186,7 @@ open class ButtonIcon: Control { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) - $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -194,7 +194,7 @@ open class ButtonIcon: Control { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) - $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -271,7 +271,7 @@ open class ButtonIcon: Control { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) - $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -285,7 +285,7 @@ open class ButtonIcon: Control { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.paletteGray20, VDSColor.paletteWhite, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) - $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() }() var shadowColorConfiguration: AnyColorable = { From b80e1ed18a7577f38e29170a278f68c51aee924e Mon Sep 17 00:00:00 2001 From: vasavk Date: Tue, 13 Feb 2024 22:11:57 +0530 Subject: [PATCH 28/47] story:ONEAPP-6315: updated color configurations for each state. --- VDS/Components/Icon/ButtonIcon/ButtonIcon.swift | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 020f6c7d..59f6a96a 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -122,7 +122,7 @@ open class ButtonIcon: Control { /// Icon Name used within the Icon. open var iconName: Icon.Name? { didSet { setNeedsUpdate() } } - /// Selected Icon Name used within the Icon if selectable true. + /// Icon Name used within the Icon within the Selected State. open var selectedIconName: Icon.Name? { didSet { setNeedsUpdate() } } /// Sets the size of button icon and icon. @@ -186,6 +186,9 @@ open class ButtonIcon: Control { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected) + $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -194,6 +197,9 @@ open class ButtonIcon: Control { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: .disabled) + $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected) + $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -270,7 +276,10 @@ open class ButtonIcon: Control { var backgroundColorConfiguration: AnyColorable = { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .normal) + $0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .selected) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() @@ -284,7 +293,10 @@ open class ButtonIcon: Control { var backgroundColorConfiguration: AnyColorable = { return ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.paletteGray20, VDSColor.paletteWhite, forState: .normal) + $0.setSurfaceColors(VDSColor.paletteGray20, VDSColor.paletteWhite, forState: .selected) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() }() From 3dc55db8eaab31eb967174938be422f44dc225bb Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Tue, 13 Feb 2024 22:18:03 +0530 Subject: [PATCH 29/47] added spacing constants --- VDS/Components/Notification/Notification.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index bd2f778c..5caebaa7 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -65,7 +65,7 @@ open class Notification: View { $0.translatesAutoresizingMaskIntoConstraints = false $0.alignment = .top $0.axis = .horizontal - $0.spacing = VDSLayout.Spacing.space2X.value + $0.spacing = UIDevice.isIPad ? VDSLayout.Spacing.space3X.value : VDSLayout.Spacing.space2X.value } private var labelsView = UIStackView().with { @@ -270,7 +270,7 @@ open class Notification: View { .pinTrailing() buttonGroupBottomConstraint = labelButtonView.bottomAnchor.constraint(equalTo: buttonGroup.bottomAnchor) buttonGroupCenterYConstraint = buttonGroup.centerYAnchor.constraint(equalTo: labelButtonView.centerYAnchor) - labelViewAndButtonViewConstraint = buttonGroup.topAnchor.constraint(equalTo: labelsView.bottomAnchor, constant: 3.0) + labelViewAndButtonViewConstraint = buttonGroup.topAnchor.constraint(equalTo: labelsView.bottomAnchor, constant: VDSLayout.Spacing.space3X.value) buttonGroup.widthAnchor.constraint(equalTo: labelsView.widthAnchor).activate() mainStackView.addArrangedSubview(typeIcon) @@ -358,7 +358,6 @@ open class Notification: View { } else { subTitleLabel.removeFromSuperview() } - } private func updateButtons() { From 3b3d7eff600a3fdac7df72b70e49c2e632700259 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Tue, 13 Feb 2024 22:36:50 +0530 Subject: [PATCH 30/47] added Notification Type --- VDS/Components/Notification/Notification.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index 5caebaa7..6e63a8aa 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -58,6 +58,11 @@ open class Notification: View { case vertical, horizontal } + /// Enum used to describe the type of the Notification. + public enum `Type`: String, CaseIterable { + case fullBleed, inLine + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -69,7 +74,7 @@ open class Notification: View { } private var labelsView = UIStackView().with { - $0.spacing = 1.0 + $0.spacing = VDSLayout.Spacing.space1X.value $0.translatesAutoresizingMaskIntoConstraints = false $0.alignment = .fill $0.distribution = .equalSpacing @@ -173,7 +178,10 @@ open class Notification: View { /// Add this attribute determine your type of Notification. open var style: Style = .info { didSet { setNeedsUpdate()}} - var _layout: Layout = .vertical + /// If true, will hide the close button. + open var type: Type = .inLine { didSet { setNeedsUpdate()} } + + private var _layout: Layout = .vertical /// Determines the orientation of buttons and text in the Notification. open var layout: Layout { @@ -323,6 +331,7 @@ open class Notification: View { open override func updateView() { super.updateView() + layer.cornerRadius = type == .fullBleed ? 0 : 4.0 backgroundColor = backgroundColorConfiguration.getColor(self) updateIcons() updateLabels() From e8a03cbea29a60473763692b9d6646f455720603 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Tue, 13 Feb 2024 22:41:59 +0530 Subject: [PATCH 31/47] Added change log --- VDS.xcodeproj/project.pbxproj | 4 ++ .../Notification/NotificationChangeLog.txt | 55 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 VDS/Components/Notification/NotificationChangeLog.txt diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index c28da8f9..00ef0933 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; }; 5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; }; 5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; }; + 71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */; }; EA0B18022A9E236900F2D0CD /* SelectorGroupBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */; }; EA0B18052A9E2D2D00F2D0CD /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */; }; EA0B18062A9E2D2D00F2D0CD /* SelectorItemBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18042A9E2D2D00F2D0CD /* SelectorItemBase.swift */; }; @@ -173,6 +174,7 @@ 44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = ""; }; 5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; + 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NotificationChangeLog.txt; sourceTree = ""; }; EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorGroupBase.swift; sourceTree = ""; }; EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = ""; }; EA0B18042A9E2D2D00F2D0CD /* SelectorItemBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorItemBase.swift; sourceTree = ""; }; @@ -347,6 +349,7 @@ children = ( 445BA07729C07B3D0036A7C5 /* Notification.swift */, 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */, + 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */, ); path = Notification; sourceTree = ""; @@ -928,6 +931,7 @@ files = ( EAEEECA42B1F934600531FC2 /* IconChangeLog.txt in Resources */, EA3362042891E14D0071C351 /* VerizonNHGeTX-Bold.otf in Resources */, + 71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */, EAEEECA72B1F952000531FC2 /* TabsChangeLog.txt in Resources */, EAEEEC962B1F893B00531FC2 /* ButtonChangeLog.txt in Resources */, EA5F86CC2A1D28B500BC83E4 /* ReleaseNotes.txt in Resources */, diff --git a/VDS/Components/Notification/NotificationChangeLog.txt b/VDS/Components/Notification/NotificationChangeLog.txt new file mode 100644 index 00000000..e8026180 --- /dev/null +++ b/VDS/Components/Notification/NotificationChangeLog.txt @@ -0,0 +1,55 @@ +MM/DD/YYYY +---------------- + +12/30/2021 +---------------- +- Updated Hover and Active state trigger specs. If triggered by mouse, Active same as Hover. If not, Active same as Default. + +03/03/2022 +---------------- +- Initial Brand 3.0 handoff + +03/07/2022 +---------------- +- Added Native positioning examples + +05/03/2022 +---------------- +- Finalized Native Positioning and Triggers sections. + +07/28/2022 +---------------- +- Added note to Anatomy that Border radius is only for Inline Notifications. + +11/30/2022 +---------------- +- Added "(web only)" to any instance of "keyboard focus" + +12/13/2022 +---------------- +- Replaced focus border pixel and style & spacing values with tokens. + +01/12/2023 +---------------- +- Change VDS Button to Button in Anatomy
Moved Button combinations from Anatomy to Elements. + +04/12/2023 +---------------- +- Updated hex colors to reflect updated color tokens values. +- Updated visuals on the Native frame to reflect new guideline that the notification surface color should be based on whatever it is placed upon, or based on the color of the top navigation bar when displaying above the global nav. Added spec notation about this also. + +05/04/2023 +---------------- +- Button Icon Threading - CloseButton +- Anatomy section updated with info on Button Icon +- CloseButton updated with VDS Button Icon details +- Updated Viewport section with Button Icon Config +- Removed Elements section. Button combination is now part of Configurations section +- Updated visuals in all sections to cater to changes caused by Button Icon threading + +11/21/2023 +---------------- +- Added hideCloseButton property to align with React component build +- Added dev note to Error variant +- Removed close button from Error variant examples +- Removed Web/App Discrepancies list From 78a63cdc3ecb8e9a1cd2623a09399d93f3c724fd Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Tue, 13 Feb 2024 23:18:40 +0530 Subject: [PATCH 32/47] Added Publisher for layoutHeight to update collectionViewHeight dynamically --- VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 6 ++++++ .../Buttons/ButtonGroup/ButtonGroupPositionLayout.swift | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 1fdbc56d..296a5224 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -64,6 +64,8 @@ open class ButtonGroup: View { private var _childWidth: ChildWidth? + private var anyCancellable: AnyCancellable? + /// If provided, width of Button components will be rendered based on this value. If omitted, default button widths are rendered. open var childWidth: ChildWidth? { get { _childWidth } @@ -134,6 +136,10 @@ open class ButtonGroup: View { collectionView.pinToSuperView() collectionViewHeight = heightAnchor.constraint(equalToConstant: VDS.Button.Size.large.height) collectionViewHeight?.activate() + anyCancellable = positionLayout.$layoutHeight.receive(on: RunLoop.main).sink { [weak self] _ in + guard let self else { return } + self.collectionViewHeight?.constant = self.collectionView.intrinsicContentSize.height + } } //-------------------------------------------------- diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift index c1a315eb..7c099a7c 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift @@ -149,7 +149,7 @@ class ButtonGroupPositionLayout: UICollectionViewLayout { weak var delegate: ButtongGroupPositionLayoutDelegate? // Total height of the content. Will be used to configure the scrollview content - var layoutHeight: CGFloat = 0.0 + @Published var layoutHeight: CGFloat = 0.0 var position: ButtonGroup.Alignment = .left var rowQuantity: Int = 0 var buttonPercentage: CGFloat? From c98b103092dc1e25b158cbea84a8cf090270105d Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Wed, 14 Feb 2024 00:47:28 +0530 Subject: [PATCH 33/47] Added TODO --- VDS/Components/Notification/Notification.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index 6e63a8aa..f24d2bd6 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -291,6 +291,8 @@ open class Notification: View { //labels titleLabel.textColorConfiguration = textColorConfiguration.eraseToAnyColorable() subTitleLabel.textColorConfiguration = textColorConfiguration.eraseToAnyColorable() + + //TODO: Need to add setup animation for displaying the Notification view for iOS. } /// Resets to default settings. From 83bead926fd7c1f5cfd3121bf62e58752904998f Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 13 Feb 2024 16:45:17 -0600 Subject: [PATCH 34/47] fixed bug for ButtonGroupPositionLayout - take the min between collectionViewWidth and button width Signed-off-by: Matt Bruce --- .../Buttons/ButtonGroup/ButtonGroupPositionLayout.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift index 7c099a7c..c87f8989 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift @@ -229,7 +229,7 @@ class ButtonGroupPositionLayout: UICollectionViewLayout { // create the custom layout attribute let attributes = ButtonLayoutAttributes(spacing: itemSpacing, button: itemButtonBase, forCellWith: indexPath) - attributes.frame = CGRect(x: 0, y: 0, width: itemSize.width, height: itemSize.height) + attributes.frame = CGRect(x: 0, y: 0, width: min(itemSize.width, collectionViewWidth), height: itemSize.height) // add it to the array rows.last?.add(attribute: attributes) From fd29a57d19251a918b9e9b649115453618b61bc4 Mon Sep 17 00:00:00 2001 From: vasavk Date: Wed, 14 Feb 2024 18:37:42 +0530 Subject: [PATCH 35/47] story:ONEAPP-6315: Changes to determine if a control is "iselected" or not, and removed unnecessary states for surface colors. --- .../Icon/ButtonIcon/ButtonIcon.swift | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 59f6a96a..a26765e6 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -8,12 +8,13 @@ import Foundation import UIKit import VDSColorTokens +import Combine /// A button icon is an interactive element that visually communicates the action it triggers via an icon. /// It usually represents a supplementary or utilitarian action. A button icon can stand alone, but often /// exists in a group when there are several actions that can be performed. @objc(VDSButtonIcon) -open class ButtonIcon: Control { +open class ButtonIcon: Control, Changeable, FormFieldable { //-------------------------------------------------- // MARK: - Initializers @@ -77,7 +78,7 @@ open class ButtonIcon: Control { private var badgeIndicatorCenterXConstraint: NSLayoutConstraint? private var badgeIndicatorCenterYConstraint: NSLayoutConstraint? private var currentIconName: Icon.Name? { - if let selectedIconName, selectable { + if let selectedIconName, isSelected { return selectedIconName } else { return iconName @@ -144,7 +145,15 @@ open class ButtonIcon: Control { open var showBadgeIndicator: Bool = false { didSet { setNeedsUpdate() } } /// If true, button will be rendered as selected, when it is selectable. - open var selectable: Bool = false { didSet { setNeedsUpdate() } } + open var selectable: Bool = false { + didSet { + //unselect + if !selectable && isSelected { + isSelected = false + } + setNeedsUpdate() + } + } /// Used to move the icon inside the button in both x and y axis. open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } } @@ -152,6 +161,12 @@ open class ButtonIcon: Control { /// Applies expand direction to Badge Indicator if shows badge indicator. open var expandDirection: ExpandDirection = .right { didSet { setNeedsUpdate() } } + open var onChangeSubscriber: AnyCancellable? + + open var inputId: String? { didSet { setNeedsUpdate() } } + + open var value: AnyHashable? { didSet { setNeedsUpdate() } } + //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- @@ -199,7 +214,6 @@ open class ButtonIcon: Control { $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: .disabled) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected) - $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -279,7 +293,6 @@ open class ButtonIcon: Control { $0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .selected) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) - $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() @@ -356,6 +369,24 @@ open class ButtonIcon: Control { centerYConstraint?.activate() } + /// Executed on initialization for this View. + open override func initialSetup() { + super.initialSetup() + onClick = { control in + guard control.isEnabled else { return } + if let selectedIconName = control.selectedIconName, control.selectable { + control.toggle() + } + } + } + + /// This will change the state of the Selector and execute the actionBlock if provided. + open func toggle() { + //removed error + isSelected.toggle() + sendActions(for: .valueChanged) + } + /// Resets to default settings. open override func reset() { super.reset() From ba33824576704b02c34116b1d3b906732bfe7c22 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 13 Feb 2024 16:45:17 -0600 Subject: [PATCH 36/47] fixed bug for ButtonGroupPositionLayout - take the min between collectionViewWidth and button width Signed-off-by: Matt Bruce --- .../Buttons/ButtonGroup/ButtonGroupPositionLayout.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift index c1a315eb..040ac1b3 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift @@ -229,7 +229,7 @@ class ButtonGroupPositionLayout: UICollectionViewLayout { // create the custom layout attribute let attributes = ButtonLayoutAttributes(spacing: itemSpacing, button: itemButtonBase, forCellWith: indexPath) - attributes.frame = CGRect(x: 0, y: 0, width: itemSize.width, height: itemSize.height) + attributes.frame = CGRect(x: 0, y: 0, width: min(itemSize.width, collectionViewWidth), height: itemSize.height) // add it to the array rows.last?.add(attribute: attributes) From 0aea28663099d94f2cb1d0f6af7c1ae2751ff8e2 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 14 Feb 2024 09:05:41 -0600 Subject: [PATCH 37/47] pushing the heightConstraint into the selfsizingcv Signed-off-by: Matt Bruce --- VDS/Classes/SelfSizingCollectionView.swift | 8 ++++++++ VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/VDS/Classes/SelfSizingCollectionView.swift b/VDS/Classes/SelfSizingCollectionView.swift index 3a99404a..c50082c4 100644 --- a/VDS/Classes/SelfSizingCollectionView.swift +++ b/VDS/Classes/SelfSizingCollectionView.swift @@ -7,6 +7,7 @@ import Foundation import UIKit +import Combine /// UICollectionView subclassed to deal with Changing the size of itself based on its children and layout and changes of its contentSize. @objc(VDSSelfSizingCollectionView) @@ -34,10 +35,13 @@ public final class SelfSizingCollectionView: UICollectionView { // MARK: - Private Properties //-------------------------------------------------- private var contentSizeObservation: NSKeyValueObservation? + private var collectionViewHeight: NSLayoutConstraint? + private var anyCancellable: AnyCancellable? //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- + /// The natural size for the receiving view, considering only properties of the view itself. public override var intrinsicContentSize: CGSize { let contentSize = self.contentSize @@ -63,12 +67,16 @@ public final class SelfSizingCollectionView: UICollectionView { //ensure autoLayout uses intrinsic height setContentHuggingPriority(.required, for: .vertical) setContentCompressionResistancePriority(.required, for: .vertical) + collectionViewHeight = heightAnchor.constraint(equalToConstant: 0).activate() // Observing the value of contentSize seems to be the only reliable way to get the contentSize after the collection view lays out its subviews. self.contentSizeObservation = self.observe(\.contentSize, options: [.old, .new]) { [weak self] _, change in // If we don't specify `options: [.old, .new]`, the change.oldValue and .newValue will always be `nil`. if change.newValue != change.oldValue { self?.invalidateIntrinsicContentSize() + if let height = change.newValue?.height { + self?.collectionViewHeight?.constant = height + } } } } diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 113d19f5..a80594fc 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -103,7 +103,6 @@ open class ButtonGroup: View { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - fileprivate var collectionViewHeight: NSLayoutConstraint? fileprivate lazy var positionLayout = ButtonGroupPositionLayout().with { $0.position = .center @@ -132,8 +131,6 @@ open class ButtonGroup: View { super.setup() addSubview(collectionView) collectionView.pinToSuperView() - collectionViewHeight = heightAnchor.constraint(equalToConstant: VDS.Button.Size.large.height) - collectionViewHeight?.activate() } //-------------------------------------------------- @@ -184,7 +181,6 @@ open class ButtonGroup: View { DispatchQueue.main.async { [weak self] in guard let self else { return } self.collectionView.collectionViewLayout.invalidateLayout() - self.collectionViewHeight?.constant = self.collectionView.intrinsicContentSize.height } } } From e9df7018363f38d57ce2f187b33a729c7282841a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 14 Feb 2024 09:32:14 -0600 Subject: [PATCH 38/47] fixed other issue with button group layout Signed-off-by: Matt Bruce --- .../Buttons/ButtonGroup/ButtonGroupPositionLayout.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift index 040ac1b3..353bd4f5 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift @@ -193,6 +193,9 @@ class ButtonGroupPositionLayout: UICollectionViewLayout { // get the rect size of the button itemSize = delegate.collectionView(collectionView, sizeForItemAtIndexPath: indexPath) + // ensure the width is not greater than the collectionViewWidth + itemSize.width = min(itemSize.width, collectionViewWidth) + // determine if the current button will fit in the row let rowItemCount = rows.last?.attributes.count ?? 0 @@ -229,7 +232,7 @@ class ButtonGroupPositionLayout: UICollectionViewLayout { // create the custom layout attribute let attributes = ButtonLayoutAttributes(spacing: itemSpacing, button: itemButtonBase, forCellWith: indexPath) - attributes.frame = CGRect(x: 0, y: 0, width: min(itemSize.width, collectionViewWidth), height: itemSize.height) + attributes.frame = CGRect(x: 0, y: 0, width: itemSize.width, height: itemSize.height) // add it to the array rows.last?.add(attribute: attributes) From 3b6e8948bb3bb51377e5031ab14bb30c03020c59 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 14 Feb 2024 09:46:23 -0600 Subject: [PATCH 39/47] removed @PUblished, since this is no longer needed Signed-off-by: Matt Bruce --- .../Buttons/ButtonGroup/ButtonGroupPositionLayout.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift index ba0cec7c..f4ccf276 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroupPositionLayout.swift @@ -8,7 +8,6 @@ import Foundation import UIKit - class ButtonCollectionViewRow { var attributes = [ButtonLayoutAttributes]() @@ -149,7 +148,7 @@ class ButtonGroupPositionLayout: UICollectionViewLayout { weak var delegate: ButtongGroupPositionLayoutDelegate? // Total height of the content. Will be used to configure the scrollview content - @Published var layoutHeight: CGFloat = 0.0 + var layoutHeight: CGFloat = 0.0 var position: ButtonGroup.Alignment = .left var rowQuantity: Int = 0 var buttonPercentage: CGFloat? From e15a4321b33da841020910db0239b1f305754799 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 14 Feb 2024 10:48:44 -0600 Subject: [PATCH 40/47] removed Type/type added layoutSubViews to deal with cornerRadius logic. Signed-off-by: Matt Bruce --- VDS/Components/Notification/Notification.swift | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index f24d2bd6..2ed84116 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -58,11 +58,6 @@ open class Notification: View { case vertical, horizontal } - /// Enum used to describe the type of the Notification. - public enum `Type`: String, CaseIterable { - case fullBleed, inLine - } - //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -177,9 +172,6 @@ open class Notification: View { /// Add this attribute determine your type of Notification. open var style: Style = .info { didSet { setNeedsUpdate()}} - - /// If true, will hide the close button. - open var type: Type = .inLine { didSet { setNeedsUpdate()} } private var _layout: Layout = .vertical @@ -333,7 +325,6 @@ open class Notification: View { open override func updateView() { super.updateView() - layer.cornerRadius = type == .fullBleed ? 0 : 4.0 backgroundColor = backgroundColorConfiguration.getColor(self) updateIcons() updateLabels() @@ -341,6 +332,12 @@ open class Notification: View { setConstraints() } + /// Override to check the screen width to determine cornerRadius + open override func layoutSubviews() { + super.layoutSubviews() + layer.cornerRadius = UIScreen.main.bounds.width == bounds.width ? 0 : 4.0 + } + //-------------------------------------------------- // MARK: - Private Methods //-------------------------------------------------- From 8fd74d5ef9ee01dba35b407dc866d69bcdd1b7e5 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 14 Feb 2024 11:57:08 -0600 Subject: [PATCH 41/47] refactored ExpandDirect to the BadgeIndicatorModel Signed-off-by: Matt Bruce --- .../Icon/ButtonIcon/ButtonIcon.swift | 57 +++++++++---------- .../ButtonIconBadgeIndicatorModel.swift | 16 ++++-- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index a26765e6..05b41224 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -43,12 +43,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { public enum SurfaceType: String, CaseIterable { case colorFill, media } - - /// Enum used to describe the badge indicator direction of icon button determining the expand direction. - public enum ExpandDirection: String, CaseIterable { - case right, center, left - } - + /// Enum used to describe the size of button icon. public enum Size: String, EnumSubset { case large @@ -106,6 +101,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { open var badgeIndicator = BadgeIndicator().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.size = .small + $0.isHidden = true } /// If set, this is used to render the badge indicator. @@ -157,10 +153,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { /// Used to move the icon inside the button in both x and y axis. open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } } - - /// Applies expand direction to Badge Indicator if shows badge indicator. - open var expandDirection: ExpandDirection = .right { didSet { setNeedsUpdate() } } - + open var onChangeSubscriber: AnyCancellable? open var inputId: String? { didSet { setNeedsUpdate() } } @@ -203,7 +196,6 @@ open class ButtonIcon: Control, Changeable, FormFieldable { $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected) - $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted]) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) }.eraseToAnyColorable() }() @@ -374,7 +366,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { super.initialSetup() onClick = { control in guard control.isEnabled else { return } - if let selectedIconName = control.selectedIconName, control.selectable { + if control.selectedIconName != nil && control.selectable { control.toggle() } } @@ -402,7 +394,6 @@ open class ButtonIcon: Control, Changeable, FormFieldable { showBadgeIndicator = false selectable = false badgeIndicatorModel = nil - expandDirection = .right shouldUpdateView = true setNeedsUpdate() } @@ -482,27 +473,33 @@ open class ButtonIcon: Control, Changeable, FormFieldable { // MARK: - Private Methods //-------------------------------------------------- private func updateBadgeIndicator() { - if let badgeIndicatorModel { - badgeIndicator.kind = badgeIndicatorModel.kind - badgeIndicator.fillColor = badgeIndicatorModel.fillColor - badgeIndicator.surface = badgeIndicatorModel.surface - badgeIndicator.size = badgeIndicatorModel.size - badgeIndicator.maximumDigits = badgeIndicatorModel.maximumDigits - badgeIndicator.width = badgeIndicatorModel.width - badgeIndicator.height = badgeIndicatorModel.height - badgeIndicator.number = badgeIndicatorModel.number - badgeIndicator.leadingCharacter = badgeIndicatorModel.leadingCharacter - badgeIndicator.trailingText = badgeIndicatorModel.trailingText - badgeIndicator.dotSize = badgeIndicatorModel.dotSize - badgeIndicator.verticalPadding = badgeIndicatorModel.verticalPadding - badgeIndicator.horizontalPadding = badgeIndicatorModel.horizontalPadding - badgeIndicator.hideDot = badgeIndicatorModel.hideDot - badgeIndicator.hideBorder = badgeIndicatorModel.hideBorder + badgeIndicator.isHidden = !showBadgeIndicator + + guard let badgeIndicatorModel else { + badgeIndicator.isHidden = true + return } + + badgeIndicator.surface = surface + badgeIndicator.kind = badgeIndicatorModel.kind + badgeIndicator.fillColor = badgeIndicatorModel.fillColor + badgeIndicator.size = badgeIndicatorModel.size + badgeIndicator.maximumDigits = badgeIndicatorModel.maximumDigits + badgeIndicator.width = badgeIndicatorModel.width + badgeIndicator.height = badgeIndicatorModel.height + badgeIndicator.number = badgeIndicatorModel.number + badgeIndicator.leadingCharacter = badgeIndicatorModel.leadingCharacter + badgeIndicator.trailingText = badgeIndicatorModel.trailingText + badgeIndicator.dotSize = badgeIndicatorModel.dotSize + badgeIndicator.verticalPadding = badgeIndicatorModel.verticalPadding + badgeIndicator.horizontalPadding = badgeIndicatorModel.horizontalPadding + badgeIndicator.hideDot = badgeIndicatorModel.hideDot + badgeIndicator.hideBorder = badgeIndicatorModel.hideBorder } private func updateExpandDirectionalConstraints() { - switch expandDirection { + guard let badgeIndicatorModel else { return } + switch badgeIndicatorModel.expandDirection { case .right: badgeIndicatorLeadingConstraint?.isActive = true badgeIndicatorTrailingConstraint?.isActive = false diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift b/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift index b30e64e8..61b94c12 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift @@ -11,16 +11,20 @@ extension ButtonIcon { //Model that represents the options available for the Badge Indicator public struct BadgeIndicatorModel { + /// Enum used to describe the badge indicator direction of icon button determining the expand direction. + public enum ExpandDirection: String, CaseIterable { + case right, center, left + } + + /// Applies expand direction to Badge Indicator if shows badge indicator. + public var expandDirection: ExpandDirection = .right /// Kind that will be used for the badge indicator. public var kind: BadgeIndicator.Kind /// Fill color that will be used for the badge indicator. public var fillColor: BadgeIndicator.FillColor - - /// Current Surface and this is used to pass down to child objects that implement Surfacable - public var surface: Surface - + /// Size that will be used for the badge indicator. public var size: BadgeIndicator.Size @@ -57,10 +61,10 @@ extension ButtonIcon { /// Hide Border that will be used for the badge indicator. public var hideBorder: Bool = false - public init(kind: BadgeIndicator.Kind = .simple, fillColor: BadgeIndicator.FillColor = .red, surface: Surface = .light, size: BadgeIndicator.Size = .xxlarge, maximumDigits: BadgeIndicator.MaximumDigits = .two, width: CGFloat? = nil, height: CGFloat? = nil, number: Int? = nil, leadingCharacter: String = "", trailingText: String = "", dotSize: CGFloat? = nil, verticalPadding: CGFloat? = nil, horizontalPadding: CGFloat? = nil, hideDot: Bool = false, hideBorder: Bool = false) { + public init(kind: BadgeIndicator.Kind = .simple, fillColor: BadgeIndicator.FillColor = .red, expandDirection: ExpandDirection = .right, size: BadgeIndicator.Size = .xxlarge, maximumDigits: BadgeIndicator.MaximumDigits = .two, width: CGFloat? = nil, height: CGFloat? = nil, number: Int? = nil, leadingCharacter: String = "", trailingText: String = "", dotSize: CGFloat? = nil, verticalPadding: CGFloat? = nil, horizontalPadding: CGFloat? = nil, hideDot: Bool = false, hideBorder: Bool = false) { self.kind = kind self.fillColor = fillColor - self.surface = surface + self.expandDirection = expandDirection self.size = size self.maximumDigits = maximumDigits self.width = width From 1591c50fd0c2fd049a7cfa9566b8ba5747b0a56e Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 14 Feb 2024 11:59:19 -0600 Subject: [PATCH 42/47] removed self. Signed-off-by: Matt Bruce --- VDS/Components/Icon/ButtonIcon/ButtonIcon.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 05b41224..922b9153 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -445,7 +445,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { layoutGuideHeightConstraint?.constant = iconLayoutSize //border - if let borderable = currentConfig as? Borderable, self.hideBorder { + if let borderable = currentConfig as? Borderable, hideBorder { layer.borderColor = borderable.borderColorConfiguration.getColor(self).cgColor layer.borderWidth = borderable.borderWidth } else { From f6b89ef90d06520e88314021fd0e48d117e7f5fa Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 15 Feb 2024 09:46:07 -0600 Subject: [PATCH 43/47] updated version and release notes Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- VDS/SupportingFiles/ReleaseNotes.txt | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 67652e0a..73225921 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1245,7 +1245,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 54; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1282,7 +1282,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 54; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index fb0acb61..404e531b 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,6 +1,8 @@ 1.0.54 ---------------- - CXTDT-518373 Accessibility Voiceover is reading “Still Loading” after waiting for a short time in all the screens. +- ONEAPP-6358 - Notification - Finished Development +- ONEAPP-6315- ButtonIcon - Finished Development 1.0.53 ---------------- From 3d303e6c0788611ba7a9cd34516b745b37fb1451 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 15 Feb 2024 10:54:42 -0600 Subject: [PATCH 44/47] allow overriding Signed-off-by: Matt Bruce --- VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 113d19f5..ddb5d617 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -198,7 +198,7 @@ extension ButtonGroup: UICollectionViewDataSource, UICollectionViewDelegate { return buttons.count } - public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let button = buttons[indexPath.row] guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as? ButtonGroupCollectionViewCell else { return UICollectionViewCell() } cell.contentView.subviews.forEach { $0.removeFromSuperview() } From 39638e77bbf05e751c0a03ccfe3c8edf92281eda Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 15 Feb 2024 10:54:42 -0600 Subject: [PATCH 45/47] allow overriding Signed-off-by: Matt Bruce --- VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index 6fdf4ff5..7d506961 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -193,7 +193,7 @@ extension ButtonGroup: UICollectionViewDataSource, UICollectionViewDelegate { return buttons.count } - public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let button = buttons[indexPath.row] guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as? ButtonGroupCollectionViewCell else { return UICollectionViewCell() } cell.contentView.subviews.forEach { $0.removeFromSuperview() } From 2da62b01fc35a95a752aec3625be64e92c3f0d5a Mon Sep 17 00:00:00 2001 From: "Bruce, Matt R" Date: Thu, 15 Feb 2024 21:39:01 +0000 Subject: [PATCH 46/47] fixed bug where someone could nil out attributedText and resetting the text... --- VDS/Components/Label/Label.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 7ecb79cd..67e53abe 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -135,15 +135,15 @@ open class Label: UILabel, ViewProtocol, UserInfoable { override open var text: String? { get { _text } set { - if _text != newValue { + if _text != newValue || newValue != attributedText?.string { _text = newValue useAttributedText = false - attributes = nil + attributes?.removeAll() setNeedsUpdate() } } } - + /// Whether the View is enabled or not. open override var isEnabled: Bool { didSet { setNeedsUpdate() } } From 8b3eb632a84a0eea9658ca3fba3abfdd370e7a1b Mon Sep 17 00:00:00 2001 From: "Bandaru, Krishna Kishore" Date: Wed, 21 Feb 2024 21:04:51 +0000 Subject: [PATCH 47/47] TileContainer VDS changes --- VDS.xcodeproj/project.pbxproj | 8 ++ .../Icon/ButtonIcon/ButtonIcon.swift | 30 +---- .../TileContainer/TileContainer.swift | 117 ++++++++++++++---- .../TileContainer/TileContainerChangeLog.txt | 90 ++++++++++++++ VDS/Protocols/Dropshadowable.swift | 64 ++++++++++ 5 files changed, 258 insertions(+), 51 deletions(-) create mode 100644 VDS/Components/TileContainer/TileContainerChangeLog.txt create mode 100644 VDS/Protocols/Dropshadowable.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 73225921..b13f7df5 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -14,6 +14,8 @@ 44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; }; 5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; }; 5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; }; + 7115BD3C2B84C0C200E0A610 /* TileContainerChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */; }; + 71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */; }; 71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */; }; EA0B18022A9E236900F2D0CD /* SelectorGroupBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */; }; EA0B18052A9E2D2D00F2D0CD /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */; }; @@ -178,6 +180,8 @@ 44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = ""; }; 5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; + 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = TileContainerChangeLog.txt; sourceTree = ""; }; + 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dropshadowable.swift; sourceTree = ""; }; 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NotificationChangeLog.txt; sourceTree = ""; }; EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorGroupBase.swift; sourceTree = ""; }; EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = ""; }; @@ -556,6 +560,7 @@ EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */, EAB1D2CC28ABE76000DAE764 /* Withable.swift */, 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */, + 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */, ); path = Protocols; sourceTree = ""; @@ -644,6 +649,7 @@ isa = PBXGroup; children = ( EA5E304B294CBDD00082B959 /* TileContainer.swift */, + 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */, ); path = TileContainer; sourceTree = ""; @@ -936,6 +942,7 @@ buildActionMask = 2147483647; files = ( EAEEECA42B1F934600531FC2 /* IconChangeLog.txt in Resources */, + 7115BD3C2B84C0C200E0A610 /* TileContainerChangeLog.txt in Resources */, EA3362042891E14D0071C351 /* VerizonNHGeTX-Bold.otf in Resources */, 71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */, EAEEECA72B1F952000531FC2 /* TabsChangeLog.txt in Resources */, @@ -992,6 +999,7 @@ EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */, EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */, EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */, + 71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */, EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */, EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */, EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */, diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 922b9153..16f0416f 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -454,9 +454,9 @@ open class ButtonIcon: Control, Changeable, FormFieldable { } if let dropshadowable = currentConfig as? Dropshadowable { - addDropShadow(config: dropshadowable) + addDropShadow(dropshadowable) } else { - removeDropShadow() + removeDropShadows() } badgeIndicatorCenterXConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width/2 @@ -530,37 +530,11 @@ extension ButtonIcon: AppleGuidelinesTouchable { } } -extension UIView { - fileprivate func addDropShadow(config: Dropshadowable) { - layer.masksToBounds = false - layer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor - layer.shadowOpacity = Float(config.shadowOpacity) - layer.shadowOffset = config.shadowOffset - layer.shadowRadius = config.shadowRadius - layer.shouldRasterize = true - layer.rasterizationScale = UIScreen.main.scale - layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath - } - - fileprivate func removeDropShadow() { - layer.shadowOpacity = 0 - layer.shadowRadius = 0 - layer.shadowPath = nil - } -} - private protocol Borderable { var borderWidth: CGFloat { get set } var borderColorConfiguration: AnyColorable { get set } } -private protocol Dropshadowable { - var shadowColorConfiguration: AnyColorable { get set } - var shadowOpacity: CGFloat { get set } - var shadowOffset: CGSize { get set } - var shadowRadius: CGFloat { get set } -} - private protocol Configuration { var kind: ButtonIcon.Kind { get set } var surfaceType: ButtonIcon.SurfaceType { get set } diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index bad144e2..98090ae4 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -32,20 +32,36 @@ open class TileContainer: Control { // MARK: - Enums //-------------------------------------------------- /// Enum used to describe the background color choices used for this component. - public enum BackgroundColor: String, CaseIterable { + public enum BackgroundColor: Equatable { + + case primary + case secondary case white case black - case gray - case transparent + case custom(String) + + private var reflectedValue: String { String(reflecting: self) } + + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.reflectedValue == rhs.reflectedValue + } } + /// Enum used to describe the background effect choices used for this component. + public enum BackgroundEffect { + case transparency + case gradient(String, String) + case none + } + /// Enum used to describe the padding choices used for this component. - public enum Padding: String, CaseIterable { + public enum Padding { case padding2X case padding4X case padding6X case padding8X case padding12X + case custom(CGFloat) public var value: CGFloat { switch self { @@ -59,6 +75,8 @@ open class TileContainer: Control { return VDSLayout.Spacing.space8X.value case .padding12X: return VDSLayout.Spacing.space12X.value + case .custom(let padding): + return padding } } } @@ -106,8 +124,11 @@ open class TileContainer: Control { open var aspectRatio: AspectRatio = .ratio1x1 { didSet { setNeedsUpdate() } } /// Sets the background color for the component. - open var color: BackgroundColor = .white { didSet { setNeedsUpdate() } } + open var color: BackgroundColor = .secondary { didSet { setNeedsUpdate() } } + /// Sets the background effect for the component. + open var backgroundEffect: BackgroundEffect = .none { didSet { setNeedsUpdate() } } + /// Sets the inside padding for the component open var padding: Padding = .padding4X { didSet { setNeedsUpdate() } } @@ -165,6 +186,7 @@ open class TileContainer: Control { private let cornerRadius = VDSFormControls.borderradius * 2 private var backgroundColorConfiguration = BackgroundColorConfiguration() + private var dropshadowConfiguration = DropshadowConfiguration() private var borderColorConfiguration = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.elementsLowcontrastOnlight @@ -201,24 +223,20 @@ open class TileContainer: Control { addSubview(highlightView) widthConstraint = layoutGuide.widthAnchor.constraint(equalToConstant: 0) - widthConstraint?.priority = .defaultHigh heightGreaterThanConstraint = layoutGuide.heightAnchor.constraint(greaterThanOrEqualToConstant: 44.0) heightGreaterThanConstraint?.isActive = false heightConstraint = layoutGuide.heightAnchor.constraint(equalToConstant: 0) - heightConstraint?.priority = .defaultHigh backgroundImageView.pin(layoutGuide) backgroundImageView.isUserInteractionEnabled = false backgroundImageView.isHidden = true - - containerView.backgroundColor = .clear containerTopConstraint = containerView.pinTop(anchor: layoutGuide.topAnchor, constant: padding.value) - containerBottomConstraint = containerView.pinBottom(anchor: layoutGuide.bottomAnchor, constant: padding.value) + containerBottomConstraint = layoutGuide.pinBottom(anchor: containerView.bottomAnchor, constant: padding.value) containerLeadingConstraint = containerView.pinLeading(anchor: layoutGuide.leadingAnchor, constant: padding.value) - containerTrailingConstraint = containerView.pinTrailing(anchor: layoutGuide.trailingAnchor, constant: padding.value) + containerTrailingConstraint = layoutGuide.pinTrailing(anchor: containerView.trailingAnchor, constant: padding.value) highlightView.pin(layoutGuide) highlightView.isHidden = true @@ -228,7 +246,6 @@ open class TileContainer: Control { layer.cornerRadius = cornerRadius backgroundImageView.layer.cornerRadius = cornerRadius highlightView.layer.cornerRadius = cornerRadius - } /// Resets to default settings. @@ -268,8 +285,8 @@ open class TileContainer: Control { containerTopConstraint?.constant = padding.value containerLeadingConstraint?.constant = padding.value - containerBottomConstraint?.constant = -padding.value - containerTrailingConstraint?.constant = -padding.value + containerBottomConstraint?.constant = padding.value + containerTrailingConstraint?.constant = padding.value if let width, aspectRatio == .none && height == nil{ widthConstraint?.constant = width @@ -293,6 +310,12 @@ open class TileContainer: Control { widthConstraint?.isActive = false heightConstraint?.isActive = false } + if showDropShadows, surface == .light { + addDropShadow(dropshadowConfiguration) + } else { + removeDropShadows() + } + applyBackgroundEffects() } //-------------------------------------------------- @@ -310,6 +333,36 @@ open class TileContainer: Control { //-------------------------------------------------- // MARK: - Private Methods //-------------------------------------------------- + + private func applyBackgroundEffects() { + let color = backgroundColorConfiguration.getColor(self) + var alphaConfiguration: CGFloat = 1.0 + let imageFallbackColor = imageFallbackColorConfiguration.getColor(self) + switch backgroundEffect { + case .transparency: + alphaConfiguration = 0.8 + removeGradientLayer() + case .gradient(let firstColor, let secondColor): + alphaConfiguration = 1.0 + addGradientLayer(with: UIColor(hexString: firstColor), secondColor: UIColor(hexString: secondColor)) + backgroundImageView.isHidden = true + backgroundImageView.alpha = 1.0 + case .none: + alphaConfiguration = 1.0 + removeGradientLayer() + } + if let backgroundImage { + backgroundImageView.image = backgroundImage + backgroundImageView.isHidden = false + backgroundImageView.alpha = alphaConfiguration + backgroundColor = imageFallbackColor.withAlphaComponent(alphaConfiguration) + } else { + backgroundImageView.isHidden = true + backgroundImageView.alpha = 1.0 + backgroundColor = color.withAlphaComponent(alphaConfiguration) + } + } + private func ratioSize(for width: CGFloat) -> CGSize { var height: CGFloat = width @@ -343,22 +396,40 @@ open class TileContainer: Control { } extension TileContainer { - class BackgroundColorConfiguration: ObjectColorable { + + struct DropshadowConfiguration: Dropshadowable { + var shadowColorConfiguration: AnyColorable = SurfaceColorConfiguration().with { + $0.lightColor = VDSColor.elementsPrimaryOnlight + }.eraseToAnyColorable() + var shadowOpacity: CGFloat = 0.01 + var shadowOffset: CGSize = .init(width: 0, height: 6) + var shadowRadius: CGFloat = 3 + } + + final class BackgroundColorConfiguration: ObjectColorable { + typealias ObjectType = TileContainer + let primaryColorConfig = SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryDark) + let secondaryColorConfig = SurfaceColorConfiguration(VDSColor.backgroundSecondaryLight, VDSColor.backgroundSecondaryDark) + let grayColorConfig = SurfaceColorConfiguration(VDSColor.backgroundSecondaryLight, VDSColor.backgroundSecondaryDark) + let whiteColorConfig = SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteWhite) + let blackColorConfig = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack) + required init() { } - + func getColor(_ object: TileContainer) -> UIColor { switch object.color { - + case .primary: + primaryColorConfig.getColor(object.surface) + case .secondary: + secondaryColorConfig.getColor(object.surface) case .white: - return VDSColor.backgroundPrimaryLight + whiteColorConfig.getColor(object.surface) case .black: - return VDSColor.backgroundPrimaryDark - case .gray: - return VDSColor.backgroundSecondaryLight - case .transparent: - return UIColor.clear + blackColorConfig.getColor(object.surface) + case .custom(let hexCode): + UIColor(hexString: hexCode) } } } diff --git a/VDS/Components/TileContainer/TileContainerChangeLog.txt b/VDS/Components/TileContainer/TileContainerChangeLog.txt new file mode 100644 index 00000000..fa0206e2 --- /dev/null +++ b/VDS/Components/TileContainer/TileContainerChangeLog.txt @@ -0,0 +1,90 @@ +MM/DD/YYYY +---------------- + +02/01/2022 +---------------- +- ACTION | Migrated Spec file from working file into VDS Brand 3.0 Core SPECs & Test App. + +02/02/2022 +---------------- +- Elements | Added option for user to manually define a custom Padding valueElements. +- Elements | Removed option for 40px Padding 
 +- Elements | Added background options of Hex code and Transparency. + +02/07/2022 +---------------- +- Anatomy | Updated descriptions to simplify. (Removed “Tile” from many) + +02/08/2022 +---------------- +- Elements | Background color section updated +- Elements | Removed option for 20px Padding value +- Configurations | Surface section added +- Configurations | Multiple sections updated +- Behaviors | Interaction section added +- States | Multiple sections updated/moved +- ACTION | Sent to Accessibility Team to review + +02/14/2022 +---------------- +- ACTION | Received sign off from Accessibility +- ACTION | Sent to Talia for design review + +02/21/2022 +---------------- +- Elements | Background colors and tokens updated. +- ACTION | Ready for dev review. + +02/22/2022 +---------------- +- Elements | Background names updated to infer surface prop selection. +- ACTION | Web dev handoff completed. + +12/15/2022 +---------------- +- States | Android drop shadow specs added, along with screenshot to the right of specs. +- States | Added "(web only)" to any instance of "keyboard focus". +- States | Replaced focus border pixel and style & spacing values with tokens. +- Elements | Updated border color values to use element tokens. +- Configurations | Updated border and drop shadow section titles to “Show border” and “Show drop shadow.” + +01/18/2023 +---------------- +- Anatomy | Updated item #2 to “Padding” from “Container Internal Padding” + +05/11/2023 +---------------- +- Removed showdropshadow prop from Configurations (dropshadow will be on automatically now for Surface=Light) +- Updated states frame to remove states featuring dropshadow suppression, clarified state names, and removed inaccurate dev notes. + +06/15/2023 +---------------- +- Added showDropShadow prop back into Configurations. +- Moved Padding to Configurations + +11/09/2023 +---------------- +- Updated showBorder section to match API prop names/values. +- Moved Padding to Configurations. + +11/20/2023 +---------------- +- Added corner radius token in the Anatomy +- Updated visuals to reflect new corner radius value - 12px +- Updated focus border corner radius to 14px +- View changes + +11/27/2023 +---------------- +- Updated “border radius” to “corner radius” in Anatomy +- Updated “focus border radius” to “focus corner radius” in States +- View changes + +12/14/2023 +---------------- +- Added backgroundColor configuration section, removed Background Colors element section +- Added secondary, primary backgroundColor options +- Simplified backgroundImage section to remove backgroundColor example +- Added background property section, with examples +- Deprecated the gray backgroundColor option +- View changes diff --git a/VDS/Protocols/Dropshadowable.swift b/VDS/Protocols/Dropshadowable.swift new file mode 100644 index 00000000..77f1a475 --- /dev/null +++ b/VDS/Protocols/Dropshadowable.swift @@ -0,0 +1,64 @@ +// +// Dropshadowable.swift +// VDS +// +// Created by Bandaru, Krishna Kishore on 16/02/24. +// + +import Foundation +import UIKit + +protocol Dropshadowable { + + var shadowColorConfiguration: AnyColorable { get set } + var shadowOpacity: CGFloat { get set } + var shadowOffset: CGSize { get set } + var shadowRadius: CGFloat { get set } +} + +extension ViewProtocol where Self: UIView { + + func addDropShadow(_ config: Dropshadowable) { + removeDropShadows() + layer.backgroundColor = backgroundColor?.cgColor + layer.masksToBounds = false + let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius) + let shadowLayer = CALayer() + shadowLayer.shadowPath = shadowPath.cgPath + shadowLayer.frame = bounds + shadowLayer.position = center + shadowLayer.backgroundColor = UIColor.clear.cgColor + shadowLayer.cornerRadius = layer.cornerRadius + shadowLayer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor + shadowLayer.shadowOpacity = Float(config.shadowOpacity) + shadowLayer.shadowOffset = .init(width: config.shadowOffset.width, height: config.shadowOffset.height) + shadowLayer.shadowRadius = config.shadowRadius + shadowLayer.name = "dropShadowLayer" + shadowLayer.shouldRasterize = true + shadowLayer.rasterizationScale = UIScreen.main.scale + layer.insertSublayer(shadowLayer, at: 0) + } + + func removeDropShadows() { + layer.sublayers?.removeAll { $0.name == "dropShadowLayer" } + } + + func addGradientLayer(with firstColor: UIColor, secondColor: UIColor) { + removeGradientLayer() + let gradientLayer = CAGradientLayer() + gradientLayer.frame = bounds + gradientLayer.startPoint = CGPoint(x: 0, y: 1) + gradientLayer.endPoint = CGPoint(x: 1, y: 0) + gradientLayer.position = center + gradientLayer.shouldRasterize = true + gradientLayer.rasterizationScale = UIScreen.main.scale + gradientLayer.cornerRadius = layer.cornerRadius + gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor] + gradientLayer.name = "gradientLayer" + layer.insertSublayer(gradientLayer, at: 0) + } + + func removeGradientLayer() { + layer.sublayers?.removeAll { $0.name == "gradientLayer" } + } +}