From febbd282cefd3528241c27281ad3b72a0bc9c5dc Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Thu, 22 Feb 2024 22:53:19 +0530 Subject: [PATCH 1/4] Updated DropShadowable to multiple configs --- VDS.xcodeproj/project.pbxproj | 8 +- .../Icon/ButtonIcon/ButtonIcon.swift | 75 +++++++----- .../TileContainer/TileContainer.swift | 21 ++-- VDS/Protocols/DropShadowable.swift | 113 ++++++++++++++++++ VDS/Protocols/Dropshadowable.swift | 64 ---------- 5 files changed, 174 insertions(+), 107 deletions(-) create mode 100644 VDS/Protocols/DropShadowable.swift delete mode 100644 VDS/Protocols/Dropshadowable.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index b13f7df5..c7a20041 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -15,7 +15,7 @@ 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 */; }; + 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 */; }; @@ -181,7 +181,7 @@ 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 = ""; }; + 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 = ""; }; @@ -560,7 +560,7 @@ EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */, EAB1D2CC28ABE76000DAE764 /* Withable.swift */, 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */, - 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */, + 71BFA7092B7F70E6000DCE33 /* DropShadowable.swift */, ); path = Protocols; sourceTree = ""; @@ -999,7 +999,7 @@ EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */, EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */, EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */, - 71BFA70A2B7F70E6000DCE33 /* Dropshadowable.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 16f0416f..97bbbb77 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -232,19 +232,26 @@ open class ButtonIcon: Control, Changeable, FormFieldable { }() } - private struct LowContrastColorFillFloatingConfiguration: Configuration, Dropshadowable { + private struct LowContrastColorFillFloatingConfiguration: Configuration, DropShadowableConfiguration { var kind: Kind = .lowContrast var surfaceType: SurfaceType = .colorFill var floating: Bool = true var backgroundColorConfiguration: AnyColorable = { 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 let dropshadow1Configuration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.12), CGFloat(0.22)) + $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) + $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(10), CGFloat(12)) + } + private let dropshadow2Configuration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.15), CGFloat(0.22)) + $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) + $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(4), CGFloat(6)) + } + var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] } } private struct LowContrastMediaConfiguration: Configuration, Borderable { @@ -260,19 +267,26 @@ open class ButtonIcon: Control, Changeable, FormFieldable { }() } - private struct LowContrastMediaFloatingConfiguration: Configuration, Dropshadowable { + private struct LowContrastMediaFloatingConfiguration: Configuration, DropShadowableConfiguration { var kind: Kind = .lowContrast var surfaceType: SurfaceType = .media var floating: Bool = true var backgroundColorConfiguration: AnyColorable = { 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 let dropshadow1Configuration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.12), CGFloat(0.22)) + $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) + $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(10), CGFloat(12)) + } + private let dropshadow2Configuration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.05), CGFloat(0.15)) + $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) + $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(4), CGFloat(6)) + } + var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] } } private struct HighContrastConfiguration: Configuration { @@ -291,7 +305,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { }() } - private struct HighContrastFloatingConfiguration: Configuration, Dropshadowable { + private struct HighContrastFloatingConfiguration: Configuration, DropShadowableConfiguration { var kind: Kind = .highContrast var surfaceType: SurfaceType = .colorFill var floating: Bool = true @@ -305,12 +319,19 @@ open class ButtonIcon: Control, Changeable, FormFieldable { $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .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 + private let dropshadow1Configuration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.22), CGFloat(0.12)) + $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) + $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(12), CGFloat(10)) + } + private let dropshadow2Configuration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.15), CGFloat(0.05)) + $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) + $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(6), CGFloat(4)) + } + var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] } } private var badgeIndicatorDefaultSize: CGSize = .zero @@ -452,12 +473,6 @@ open class ButtonIcon: Control, Changeable, FormFieldable { layer.borderColor = nil layer.borderWidth = 0 } - - if let dropshadowable = currentConfig as? Dropshadowable { - addDropShadow(dropshadowable) - } else { - removeDropShadows() - } badgeIndicatorCenterXConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width/2 badgeIndicatorCenterYConstraint?.constant = badgeIndicatorOffset.y + badgeIndicatorDefaultSize.height/2 @@ -467,6 +482,12 @@ open class ButtonIcon: Control, Changeable, FormFieldable { if showBadgeIndicator { updateExpandDirectionalConstraints() } + + if let configurations = (currentConfig as? DropShadowableConfiguration)?.configurations { + addDropShadows(configurations) + } else { + removeDropShadows() + } } //-------------------------------------------------- diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 98090ae4..8dc2d9dd 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -184,9 +184,15 @@ open class TileContainer: Control { // MARK: - Configuration //-------------------------------------------------- private let cornerRadius = VDSFormControls.borderradius * 2 - private var backgroundColorConfiguration = BackgroundColorConfiguration() - private var dropshadowConfiguration = DropshadowConfiguration() + private let dropShadowConfiguration = DropShadowConfiguration().with { + $0.shadowColorConfiguration = SurfaceColorConfiguration().with { + $0.lightColor = VDSColor.elementsPrimaryOnlight + }.eraseToAnyColorable() + $0.shadowOffsetConfiguration = .init(.init(width: 0, height: 6), .zero) + $0.shadowRadiusConfiguration = .init(3.0, 0.0) + $0.shadowOpacityConfiguration = .init(0.01, 0.0) + } private var borderColorConfiguration = SurfaceColorConfiguration().with { $0.lightColor = VDSColor.elementsLowcontrastOnlight @@ -311,7 +317,7 @@ open class TileContainer: Control { heightConstraint?.isActive = false } if showDropShadows, surface == .light { - addDropShadow(dropshadowConfiguration) + addDropShadow(dropShadowConfiguration) } else { removeDropShadows() } @@ -397,15 +403,6 @@ open class TileContainer: Control { extension TileContainer { - 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 diff --git a/VDS/Protocols/DropShadowable.swift b/VDS/Protocols/DropShadowable.swift new file mode 100644 index 00000000..57c44036 --- /dev/null +++ b/VDS/Protocols/DropShadowable.swift @@ -0,0 +1,113 @@ +// +// DropShadowable.swift +// VDS +// +// Created by Bandaru, Krishna Kishore on 16/02/24. +// + +import Foundation +import UIKit + +protocol DropShadowable { + + var shadowColorConfiguration: AnyColorable { get set } + var shadowOpacityConfiguration: AnyConfigurationValue { get set } + var shadowOffsetConfiguration: AnyConfigurationValue { get set } + var shadowRadiusConfiguration: AnyConfigurationValue { get set } +} + +protocol DropShadowableConfiguration { + + var configurations: [DropShadowable] { get } +} + +final class DropShadowConfiguration: DropShadowable, ObjectWithable { + + typealias CGFloatConfigurationValue = AnyConfigurationValue + typealias CGSizeConfigurationValue = AnyConfigurationValue + + var shadowColorConfiguration: AnyColorable + var shadowOpacityConfiguration: CGFloatConfigurationValue + var shadowOffsetConfiguration: CGSizeConfigurationValue + var shadowRadiusConfiguration: CGFloatConfigurationValue + + init(shadowColorConfiguration: AnyColorable = SurfaceColorConfiguration().eraseToAnyColorable(), shadowOpacity: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0), shadowOffset: CGSizeConfigurationValue = CGSizeConfigurationValue(.zero, .zero), shadowRadius: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0)) { + self.shadowColorConfiguration = shadowColorConfiguration + self.shadowOpacityConfiguration = shadowOpacity + self.shadowOffsetConfiguration = shadowOffset + self.shadowRadiusConfiguration = shadowRadius + } +} + +extension ViewProtocol where Self: UIView { + + func addDropShadow(_ config: DropShadowable) { + addDropShadows([config]) + } + + func addDropShadows(_ configs: [DropShadowable]) { + removeDropShadows() + layer.backgroundColor = backgroundColor?.cgColor + layer.masksToBounds = false + for config in configs { + let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius) + let shadowLayer = CALayer() + shadowLayer.shadowPath = shadowPath.cgPath + shadowLayer.frame = bounds + shadowLayer.position = .init(x: bounds.midX, y: bounds.midY) + shadowLayer.backgroundColor = backgroundColor?.cgColor + shadowLayer.cornerRadius = layer.cornerRadius + shadowLayer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor + shadowLayer.shadowOpacity = Float(config.shadowOpacityConfiguration.getValue(self)) + shadowLayer.shadowOffset = config.shadowOffsetConfiguration.getValue(self) + shadowLayer.shadowRadius = config.shadowRadiusConfiguration.getValue(self) + 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.backgroundColor = UIColor.clear.cgColor + 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" } + } +} + +final class AnyConfigurationValue { + + var lightValue: ValueType + var darkValue: ValueType + + public init(_ lightValue: ValueType = ValueType.self, _ darkValue: ValueType = ValueType.self) { + self.lightValue = lightValue + self.darkValue = darkValue + } + + public func getValue(_ object: Any) -> ValueType { + guard let surfaceable = object as? Surfaceable else { + assertionFailure("Self doesn't confirms to Surfaceable") + return lightValue + } + return surfaceable.surface == .light ? lightValue : darkValue + } +} diff --git a/VDS/Protocols/Dropshadowable.swift b/VDS/Protocols/Dropshadowable.swift deleted file mode 100644 index 77f1a475..00000000 --- a/VDS/Protocols/Dropshadowable.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// 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" } - } -} From ab33a0030bae04cdb5c003686fdda19aa9365b6b Mon Sep 17 00:00:00 2001 From: vasavk Date: Mon, 4 Mar 2024 13:25:16 +0530 Subject: [PATCH 2/4] updated dropshadow values as per spec --- 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 97bbbb77..a11bf67e 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -247,7 +247,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { } private let dropshadow2Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.15), CGFloat(0.22)) + $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.05), CGFloat(0.15)) $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(4), CGFloat(6)) } From e7a85d16bc17f880a657fa406527ec606c636735 Mon Sep 17 00:00:00 2001 From: vasavk Date: Mon, 4 Mar 2024 16:25:16 +0530 Subject: [PATCH 3/4] Digital ACT-191 ONEAPP-6318 story: updated role as button for the button icon. --- 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 a11bf67e..f998c28c 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -343,7 +343,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable { open override func setup() { super.setup() isAccessibilityElement = true - accessibilityTraits = .image + accessibilityTraits = .button accessibilityElements = [badgeIndicator] //create a layoutGuide for the icon to key off of From 1c0b8bbf459e41272020e97e7e705e9e7fab78a6 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Tue, 5 Mar 2024 17:49:25 +0530 Subject: [PATCH 4/4] Addressed review comments --- VDS.xcodeproj/project.pbxproj | 8 +++ .../Icon/ButtonIcon/ButtonIcon.swift | 36 +++++------ VDS/Protocols/DropShadowable.swift | 64 ++++++------------- VDS/Utilities/DropShadowConfiguration.swift | 33 ++++++++++ VDS/Utilities/SurfaceConfigurationValue.swift | 31 +++++++++ 5 files changed, 110 insertions(+), 62 deletions(-) create mode 100644 VDS/Utilities/DropShadowConfiguration.swift create mode 100644 VDS/Utilities/SurfaceConfigurationValue.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 2b87c3c7..b6a3d192 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -18,6 +18,8 @@ 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 */; }; + 71FC86DE2B9738B900700965 /* SurfaceConfigurationValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86DD2B9738B900700965 /* SurfaceConfigurationValue.swift */; }; + 71FC86E02B973AE500700965 /* DropShadowConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86DF2B973AE500700965 /* DropShadowConfiguration.swift */; }; 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 */; }; @@ -186,6 +188,8 @@ 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 = ""; }; + 71FC86DD2B9738B900700965 /* SurfaceConfigurationValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceConfigurationValue.swift; sourceTree = ""; }; + 71FC86DF2B973AE500700965 /* DropShadowConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropShadowConfiguration.swift; 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 = ""; }; @@ -583,6 +587,8 @@ isa = PBXGroup; children = ( EA3361BC288B2C760071C351 /* TypeAlias.swift */, + 71FC86DD2B9738B900700965 /* SurfaceConfigurationValue.swift */, + 71FC86DF2B973AE500700965 /* DropShadowConfiguration.swift */, ); path = Utilities; sourceTree = ""; @@ -1031,6 +1037,7 @@ EAC846F3294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift in Sources */, EAF7F0952899861000B287F5 /* CheckboxItem.swift in Sources */, EA985BE82968951C00F2FF2E /* TileletTitleModel.swift in Sources */, + 71FC86DE2B9738B900700965 /* SurfaceConfigurationValue.swift in Sources */, EA297A5529FB07760031ED56 /* TooltipLabelAttribute.swift in Sources */, EA985BEA29689B6D00F2FF2E /* TileletSubTitleModel.swift in Sources */, EA3361C9289054C50071C351 /* Surfaceable.swift in Sources */, @@ -1101,6 +1108,7 @@ EAB2376829E9992800AABE9A /* TooltipAlertViewController.swift in Sources */, EA33623E2892EE950071C351 /* UIDevice.swift in Sources */, EA985C692971B90B00F2FF2E /* IconSize.swift in Sources */, + 71FC86E02B973AE500700965 /* DropShadowConfiguration.swift in Sources */, EA985C672970C21600F2FF2E /* VDSLayout.swift in Sources */, EA3362302891EB4A0071C351 /* Font.swift in Sources */, EAF7F0AD289B142900B287F5 /* StrikeThroughLabelAttribute.swift in Sources */, diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index f998c28c..65968214 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -241,15 +241,15 @@ open class ButtonIcon: Control, Changeable, FormFieldable { }() private let dropshadow1Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.12), CGFloat(0.22)) - $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) - $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(10), CGFloat(12)) + $0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.12), CGFloat(0.22)) + $0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) + $0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(10), CGFloat(12)) } private let dropshadow2Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.05), CGFloat(0.15)) - $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) - $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(4), CGFloat(6)) + $0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.05), CGFloat(0.15)) + $0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) + $0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(4), CGFloat(6)) } var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] } } @@ -276,15 +276,15 @@ open class ButtonIcon: Control, Changeable, FormFieldable { }() private let dropshadow1Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.12), CGFloat(0.22)) - $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) - $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(10), CGFloat(12)) + $0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.12), CGFloat(0.22)) + $0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) + $0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(10), CGFloat(12)) } private let dropshadow2Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.05), CGFloat(0.15)) - $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) - $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(4), CGFloat(6)) + $0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.05), CGFloat(0.15)) + $0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) + $0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(4), CGFloat(6)) } var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] } } @@ -321,15 +321,15 @@ open class ButtonIcon: Control, Changeable, FormFieldable { }() private let dropshadow1Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.22), CGFloat(0.12)) - $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) - $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(12), CGFloat(10)) + $0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.22), CGFloat(0.12)) + $0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1)) + $0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(12), CGFloat(10)) } private let dropshadow2Configuration = DropShadowConfiguration().with { $0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable() - $0.shadowOpacityConfiguration = AnyConfigurationValue(CGFloat(0.15), CGFloat(0.05)) - $0.shadowOffsetConfiguration = AnyConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) - $0.shadowRadiusConfiguration = AnyConfigurationValue(CGFloat(6), CGFloat(4)) + $0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.15), CGFloat(0.05)) + $0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2)) + $0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(6), CGFloat(4)) } var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] } } diff --git a/VDS/Protocols/DropShadowable.swift b/VDS/Protocols/DropShadowable.swift index 57c44036..b569ecab 100644 --- a/VDS/Protocols/DropShadowable.swift +++ b/VDS/Protocols/DropShadowable.swift @@ -8,37 +8,32 @@ import Foundation import UIKit +/** + DropShadowable protocol helps with the configuration values for adding drop shadows for light & dark surfaces. +*/ protocol DropShadowable { - + ///Shadow Color configuration for light and dark surfaces var shadowColorConfiguration: AnyColorable { get set } - var shadowOpacityConfiguration: AnyConfigurationValue { get set } - var shadowOffsetConfiguration: AnyConfigurationValue { get set } - var shadowRadiusConfiguration: AnyConfigurationValue { get set } + ///Shadow Opacity configuration for light and dark surfaces + var shadowOpacityConfiguration: SurfaceConfigurationValue { get set } + ///Shadow Offset configuration for light and dark surfaces + var shadowOffsetConfiguration: SurfaceConfigurationValue { get set } + ///Shadow Radius configuration for light and dark surfaces + var shadowRadiusConfiguration: SurfaceConfigurationValue { get set } } +/** + DropShadowableConfiguration protocol helps with multiple drop shadows configurations can be added to a view. + */ protocol DropShadowableConfiguration { + ///Configurations are the DropShadowable list, these are applied on the view var configurations: [DropShadowable] { get } } -final class DropShadowConfiguration: DropShadowable, ObjectWithable { - - typealias CGFloatConfigurationValue = AnyConfigurationValue - typealias CGSizeConfigurationValue = AnyConfigurationValue - - var shadowColorConfiguration: AnyColorable - var shadowOpacityConfiguration: CGFloatConfigurationValue - var shadowOffsetConfiguration: CGSizeConfigurationValue - var shadowRadiusConfiguration: CGFloatConfigurationValue - - init(shadowColorConfiguration: AnyColorable = SurfaceColorConfiguration().eraseToAnyColorable(), shadowOpacity: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0), shadowOffset: CGSizeConfigurationValue = CGSizeConfigurationValue(.zero, .zero), shadowRadius: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0)) { - self.shadowColorConfiguration = shadowColorConfiguration - self.shadowOpacityConfiguration = shadowOpacity - self.shadowOffsetConfiguration = shadowOffset - self.shadowRadiusConfiguration = shadowRadius - } -} - +/** + Extension on ViewProtocol for adding drop shadows & gradient layer on view. + */ extension ViewProtocol where Self: UIView { func addDropShadow(_ config: DropShadowable) { @@ -58,9 +53,9 @@ extension ViewProtocol where Self: UIView { shadowLayer.backgroundColor = backgroundColor?.cgColor shadowLayer.cornerRadius = layer.cornerRadius shadowLayer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor - shadowLayer.shadowOpacity = Float(config.shadowOpacityConfiguration.getValue(self)) - shadowLayer.shadowOffset = config.shadowOffsetConfiguration.getValue(self) - shadowLayer.shadowRadius = config.shadowRadiusConfiguration.getValue(self) + shadowLayer.shadowOpacity = Float(config.shadowOpacityConfiguration.value(for: self)) + shadowLayer.shadowOffset = config.shadowOffsetConfiguration.value(for: self) + shadowLayer.shadowRadius = config.shadowRadiusConfiguration.value(for: self) shadowLayer.name = "dropShadowLayer" shadowLayer.shouldRasterize = true shadowLayer.rasterizationScale = UIScreen.main.scale @@ -92,22 +87,3 @@ extension ViewProtocol where Self: UIView { layer.sublayers?.removeAll { $0.name == "gradientLayer" } } } - -final class AnyConfigurationValue { - - var lightValue: ValueType - var darkValue: ValueType - - public init(_ lightValue: ValueType = ValueType.self, _ darkValue: ValueType = ValueType.self) { - self.lightValue = lightValue - self.darkValue = darkValue - } - - public func getValue(_ object: Any) -> ValueType { - guard let surfaceable = object as? Surfaceable else { - assertionFailure("Self doesn't confirms to Surfaceable") - return lightValue - } - return surfaceable.surface == .light ? lightValue : darkValue - } -} diff --git a/VDS/Utilities/DropShadowConfiguration.swift b/VDS/Utilities/DropShadowConfiguration.swift new file mode 100644 index 00000000..e0cc3dd8 --- /dev/null +++ b/VDS/Utilities/DropShadowConfiguration.swift @@ -0,0 +1,33 @@ +// +// DropShadowConfiguration.swift +// VDS +// +// Created by Bandaru, Krishna Kishore on 05/03/24. +// + +import Foundation + +/** + DropShadowConfiguration confirms to DropShadowable where it has configurable properties required for drop shadow +*/ +final class DropShadowConfiguration: DropShadowable, ObjectWithable { + + typealias CGFloatConfigurationValue = SurfaceConfigurationValue + typealias CGSizeConfigurationValue = SurfaceConfigurationValue + + ///Shadow Color configuration for light and dark surfaces + var shadowColorConfiguration: AnyColorable + ///Shadow Opacity configuration for light and dark surfaces + var shadowOpacityConfiguration: CGFloatConfigurationValue + ///Shadow Offset configuration for light and dark surfaces + var shadowOffsetConfiguration: CGSizeConfigurationValue + ///Shadow Radius configuration for light and dark surfaces + var shadowRadiusConfiguration: CGFloatConfigurationValue + + init(shadowColorConfiguration: AnyColorable = SurfaceColorConfiguration().eraseToAnyColorable(), shadowOpacity: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0), shadowOffset: CGSizeConfigurationValue = CGSizeConfigurationValue(.zero, .zero), shadowRadius: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0)) { + self.shadowColorConfiguration = shadowColorConfiguration + self.shadowOpacityConfiguration = shadowOpacity + self.shadowOffsetConfiguration = shadowOffset + self.shadowRadiusConfiguration = shadowRadius + } +} diff --git a/VDS/Utilities/SurfaceConfigurationValue.swift b/VDS/Utilities/SurfaceConfigurationValue.swift new file mode 100644 index 00000000..1b304d2a --- /dev/null +++ b/VDS/Utilities/SurfaceConfigurationValue.swift @@ -0,0 +1,31 @@ +// +// SurfaceConfigurationValue.swift +// VDS +// +// Created by Bandaru, Krishna Kishore on 05/03/24. +// + +import Foundation + +/** +SurfaceConfiguration is a type that holds the generic datatype for light surface & dark surface and returns the value based on the surface. +*/ +struct SurfaceConfigurationValue { + + var lightValue: ValueType + var darkValue: ValueType + + public init(_ lightValue: ValueType, _ darkValue: ValueType) { + self.lightValue = lightValue + self.darkValue = darkValue + } + + public init(value: ValueType) { + self.lightValue = value + self.darkValue = value + } + + public func value(for object: Surfaceable) -> ValueType { + object.surface == .light ? lightValue : darkValue + } +}