From 2fca1a9a7f8b67c06d1f9c68d3f5a993dbb19d60 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 16 Dec 2022 15:30:28 -0600 Subject: [PATCH] added tileContainer and extension for VDSColor Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 16 ++ .../TileContainer/TileContainer.swift | 226 ++++++++++++++++++ VDS/Extensions/VDSColor.swift | 15 ++ 3 files changed, 257 insertions(+) create mode 100644 VDS/Components/TileContainer/TileContainer.swift create mode 100644 VDS/Extensions/VDSColor.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 5e4a1b76..2389cfb7 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */; }; EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */; }; EA4DB30228DCBCA500103EE3 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB30128DCBCA500103EE3 /* Badge.swift */; }; + EA5E304C294CBDD00082B959 /* TileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304B294CBDD00082B959 /* TileContainer.swift */; }; + EA5E304E294CC7F00082B959 /* VDSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304D294CC7F00082B959 /* VDSColor.swift */; }; EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89200128AECF2A006B9984 /* UIButton+Publisher.swift */; }; EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */; }; EA89200628B526D6006B9984 /* CheckboxGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89200528B526D6006B9984 /* CheckboxGroup.swift */; }; @@ -135,6 +137,8 @@ EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupHandlerBase.swift; sourceTree = ""; }; EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyEquatable.swift; sourceTree = ""; }; EA4DB30128DCBCA500103EE3 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + EA5E304B294CBDD00082B959 /* TileContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainer.swift; sourceTree = ""; }; + EA5E304D294CC7F00082B959 /* VDSColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSColor.swift; sourceTree = ""; }; EA89200128AECF2A006B9984 /* UIButton+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Publisher.swift"; sourceTree = ""; }; EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+Publisher.swift"; sourceTree = ""; }; EA89200528B526D6006B9984 /* CheckboxGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxGroup.swift; sourceTree = ""; }; @@ -313,6 +317,7 @@ EAF7F11428A1470D00B287F5 /* RadioButton */, EA1F265F28B945070033E859 /* RadioSwatch */, EAC925852911C9DE00091998 /* TextFields */, + EA5E304A294CBDBB0082B959 /* TileContainer */, EA3361A0288B1E6F0071C351 /* Toggle */, ); path = Components; @@ -337,6 +342,7 @@ EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */, EAB5FED329267EB300998C17 /* UIView.swift */, EAB5FF0029424ACB00998C17 /* UIControl.swift */, + EA5E304D294CC7F00082B959 /* VDSColor.swift */, ); path = Extensions; sourceTree = ""; @@ -430,6 +436,14 @@ path = Badge; sourceTree = ""; }; + EA5E304A294CBDBB0082B959 /* TileContainer */ = { + isa = PBXGroup; + children = ( + EA5E304B294CBDD00082B959 /* TileContainer.swift */, + ); + path = TileContainer; + sourceTree = ""; + }; EA89200B28B530F0006B9984 /* RadioBox */ = { isa = PBXGroup; children = ( @@ -651,6 +665,7 @@ buildActionMask = 2147483647; files = ( EAF7F0B5289C126F00B287F5 /* UILabel.swift in Sources */, + EA5E304C294CBDD00082B959 /* TileContainer.swift in Sources */, EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */, EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */, EA3361C328902D960071C351 /* Toggle.swift in Sources */, @@ -692,6 +707,7 @@ EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */, EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */, EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */, + EA5E304E294CC7F00082B959 /* VDSColor.swift in Sources */, EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */, EAF7F09E289AAEC000B287F5 /* Constants.swift in Sources */, EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */, diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift new file mode 100644 index 00000000..91af8cbc --- /dev/null +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -0,0 +1,226 @@ +// +// TileContainer.swift +// VDS +// +// Created by Matt Bruce on 12/16/22. +// + +import Foundation +import VDSColorTokens +import UIKit + +open class TileContainer: Control { + + public enum ContainerBackgroundColor: String, CaseIterable { + case white + case black + case gray + case transparent + } + + public enum ContainerPadding: String, CaseIterable { + case twelve = "12" + case sixteen = "16" + case twentyFour = "24" + case thirtyTwo = "32" + case fourtyEight = "48" + } + + public enum ContainerScalingType: String, CaseIterable { + case ratio1x1 = "1:1" + case ratio3x4 = "3:4" + case ratio4x3 = "4:3" + case ratio2x3 = "2:3" + case ratio3x2 = "3:2" + case ratio9x16 = "9:16" + case ratio16x9 = "16:9" + case ratio1x2 = "1:2" + case ratio2x1 = "2:1" + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + public var backgroundImage: UIImage? { didSet{ didChange() } } + + public var containerView = View() + + public var containerBackgroundColor: ContainerBackgroundColor = .white { didSet{ didChange() } } + + public var containerPadding: ContainerPadding = .sixteen { didSet{ didChange() } } + + public var aspectRatio: ContainerScalingType = .ratio1x1 { didSet{ didChange() } } + + public var imageFallbackColor: Surface = .light { didSet{ didChange() } } + + private var _width: CGFloat = 100 + public var width: CGFloat { + get { return _width } + set { + if newValue > 100 { + _width = newValue + didChange() + } + } + } + + public var height: CGFloat? { didSet{ didChange() } } + + public var showBorder: Bool = false { didSet{ didChange() } } + + public var showDropShadows: Bool = false { didSet{ didChange() } } + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var backgroundImageView = UIImageView(frame: .zero) + + private var padding: CGFloat { + switch containerPadding { + case .twelve: + return 12.0 + case .sixteen: + return 16.0 + case .twentyFour: + return 24.0 + case .thirtyTwo: + return 32.0 + case .fourtyEight: + return 48.0 + } + } + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + private lazy var widthConstraint: NSLayoutConstraint = { + let constraint = widthAnchor.constraint(equalToConstant: width) + constraint.isActive = true + return constraint + }() + + private lazy var heightConstraint: NSLayoutConstraint = { + let constraint = heightAnchor.constraint(equalToConstant: 100) + constraint.isActive = true + return constraint + }() + + //functions + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + open override func setup() { + super.setup() + addSubview(backgroundImageView) + addSubview(containerView) + + backgroundImageView.pinToSuperView() + backgroundImageView.isHidden = true + + containerView.pinToSuperView() + containerView.backgroundColor = .clear + + layer.cornerRadius = cornerRadius + + } + + public override func reset() { + super.reset() + + } + + //-------------------------------------------------- + // MARK: - Configuration + //-------------------------------------------------- + private let cornerRadius = 8.0 + + private var backgroundColorConfig = BackgroundColorConfiguration() + + private var borderColorConfig = SurfaceColorConfiguration().with { + $0.lightColor = VDSColor.elementsLowContrastOnLight + $0.darkColor = VDSColor.elementsLowContrastOnDark + } + + private var imageFallbackColorConfig = SurfaceColorConfiguration().with { + $0.lightColor = VDSColor.backgroundPrimaryLight + $0.darkColor = VDSColor.backgroundPrimaryDark + } + + //-------------------------------------------------- + // MARK: - State + //-------------------------------------------------- + var ratioSize: CGSize { + var height: CGFloat = width + + switch aspectRatio { + case .ratio1x1: + break; + case .ratio3x4: + height = (4 / 3) * width + case .ratio4x3: + height = (3 / 4) * width + case .ratio2x3: + height = (3 / 2) * width + case .ratio3x2: + height = (2 / 3) * width + case .ratio9x16: + height = (16 / 9) * width + case .ratio16x9: + height = (9 / 16) * width + case .ratio1x2: + height = (2 / 1) * width + case .ratio2x1: + height = (1 / 2) * width + } + + return CGSize(width: width, height: height) + } + + open override func updateView() { + super.updateView() + + if let backgroundImage { + backgroundImageView.image = backgroundImage + backgroundImageView.isHidden = false + backgroundColor = imageFallbackColorConfig.getColor(self) + } else { + backgroundImageView.isHidden = true + backgroundColor = backgroundColorConfig.getColor(self) + } + + layer.borderColor = borderColorConfig.getColor(self).cgColor + layer.borderWidth = showBorder ? 1 : 0 + + containerView.layoutMargins = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding) + + if let height { + widthConstraint.constant = width + heightConstraint.constant = height + } else { + let size = ratioSize + widthConstraint.constant = size.width + heightConstraint.constant = size.height + } + } + + class BackgroundColorConfiguration: ObjectColorable { + typealias ObjectType = TileContainer + + required init() { } + + func getColor(_ object: TileContainer) -> UIColor { + switch object.containerBackgroundColor { + + case .white: + return VDSColor.backgroundPrimaryLight + case .black: + return VDSColor.backgroundPrimaryDark + case .gray: + return VDSColor.backgroundSecondaryLight + case .transparent: + return UIColor.clear + } + } + } +} diff --git a/VDS/Extensions/VDSColor.swift b/VDS/Extensions/VDSColor.swift new file mode 100644 index 00000000..d1b7cffe --- /dev/null +++ b/VDS/Extensions/VDSColor.swift @@ -0,0 +1,15 @@ +// +// VDSColor.swift +// VDS +// +// Created by Matt Bruce on 12/16/22. +// + +import Foundation +import VDSColorTokens +import UIKit + +extension VDSColor { + public static let elementsLowContrastOnLight = UIColor.init(hexString: "#D8DADA") + public static let elementsLowContrastOnDark = UIColor.init(hexString: "#333333") +}