From 2fca1a9a7f8b67c06d1f9c68d3f5a993dbb19d60 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 16 Dec 2022 15:30:28 -0600 Subject: [PATCH 01/23] 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") +} From 9150a62e57133102f49148ef4b0c7159f9a4b61f Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 19 Dec 2022 10:03:49 -0600 Subject: [PATCH 02/23] added highlight view Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 91af8cbc..98a61649 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -45,6 +45,8 @@ open class TileContainer: Control { public var containerView = View() + public var highlightView = View() + public var containerBackgroundColor: ContainerBackgroundColor = .white { didSet{ didChange() } } public var containerPadding: ContainerPadding = .sixteen { didSet{ didChange() } } @@ -114,13 +116,19 @@ open class TileContainer: Control { super.setup() addSubview(backgroundImageView) addSubview(containerView) - + addSubview(highlightView) backgroundImageView.pinToSuperView() + backgroundImageView.isUserInteractionEnabled = false backgroundImageView.isHidden = true containerView.pinToSuperView() + containerView.isUserInteractionEnabled = false containerView.backgroundColor = .clear - + + highlightView.pinToSuperView() + highlightView.isUserInteractionEnabled = false + highlightView.isHidden = true + highlightView.backgroundColor = .clear layer.cornerRadius = cornerRadius } @@ -146,6 +154,11 @@ open class TileContainer: Control { $0.lightColor = VDSColor.backgroundPrimaryLight $0.darkColor = VDSColor.backgroundPrimaryDark } + + private var hightLightViewColorConfig = SurfaceColorConfiguration().with { + $0.lightColor = VDSColor.paletteWhite.withAlphaComponent(0.3) + $0.darkColor = VDSColor.paletteBlack.withAlphaComponent(0.3) + } //-------------------------------------------------- // MARK: - State @@ -180,6 +193,9 @@ open class TileContainer: Control { open override func updateView() { super.updateView() + highlightView.backgroundColor = hightLightViewColorConfig.getColor(self) + highlightView.isHidden = !isHighlighted + if let backgroundImage { backgroundImageView.image = backgroundImage backgroundImageView.isHidden = false From c0e6436571eb58844f598bc6c3a47a2426b63ba9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 19 Dec 2022 10:36:31 -0600 Subject: [PATCH 03/23] added backgroundImage support Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 98a61649..ff7c3bad 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -75,7 +75,11 @@ open class TileContainer: Control { //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - private var backgroundImageView = UIImageView(frame: .zero) + private var backgroundImageView = UIImageView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.contentMode = .scaleAspectFill + $0.clipsToBounds = true + } private var padding: CGFloat { switch containerPadding { @@ -129,8 +133,11 @@ open class TileContainer: Control { highlightView.isUserInteractionEnabled = false highlightView.isHidden = true highlightView.backgroundColor = .clear - layer.cornerRadius = cornerRadius + //corner radius + layer.cornerRadius = cornerRadius + backgroundImageView.layer.cornerRadius = 8 + } public override func reset() { From fcf0b524b291e34e63488c603465f1f2c4f09ad6 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 19 Dec 2022 14:41:12 -0600 Subject: [PATCH 04/23] added objc Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index ff7c3bad..9ae75f5b 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -9,6 +9,7 @@ import Foundation import VDSColorTokens import UIKit +@objc(VDSTileContainer) open class TileContainer: Control { public enum ContainerBackgroundColor: String, CaseIterable { From 2630dc43bf23c4192478a195c3575f594a287dc9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 19 Dec 2022 14:41:22 -0600 Subject: [PATCH 05/23] added TitleLockup Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 12 ++ VDS/Components/TitleLockup/TitleLockup.swift | 204 +++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 VDS/Components/TitleLockup/TitleLockup.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 2389cfb7..0a4e82e2 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 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 */; }; + EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E30522950DDA60082B959 /* TitleLockup.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 */; }; @@ -139,6 +140,7 @@ 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 = ""; }; + EA5E30522950DDA60082B959 /* TitleLockup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockup.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 = ""; }; @@ -318,6 +320,7 @@ EA1F265F28B945070033E859 /* RadioSwatch */, EAC925852911C9DE00091998 /* TextFields */, EA5E304A294CBDBB0082B959 /* TileContainer */, + EA5E30512950DD8D0082B959 /* TitleLockup */, EA3361A0288B1E6F0071C351 /* Toggle */, ); path = Components; @@ -444,6 +447,14 @@ path = TileContainer; sourceTree = ""; }; + EA5E30512950DD8D0082B959 /* TitleLockup */ = { + isa = PBXGroup; + children = ( + EA5E30522950DDA60082B959 /* TitleLockup.swift */, + ); + path = TitleLockup; + sourceTree = ""; + }; EA89200B28B530F0006B9984 /* RadioBox */ = { isa = PBXGroup; children = ( @@ -716,6 +727,7 @@ EAF7F0AB289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift in Sources */, EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */, EA336171288B19200071C351 /* VDS.docc in Sources */, + EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */, EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */, EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */, EAB1D2E628AE842000DAE764 /* Publisher+Bind.swift in Sources */, diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift new file mode 100644 index 00000000..4f79e7a0 --- /dev/null +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -0,0 +1,204 @@ +// +// TitleLockup.swift +// VDS +// +// Created by Matt Bruce on 12/19/22. +// + +import Foundation +import UIKit +import VDSColorTokens +import Combine + +public enum TitleLockupTextPosition: String, Codable, CaseIterable { + case left, center + + var labelTextPosition: TextPosition { + switch self { + case .left: + return .left + case .center: + return .center + } + } +} + +public enum TitleLockupitleTypographicalStyle: String, Codable, CaseIterable { + case FeatureMedium + case BoldFeatureMedium + case FeatureSmall + case BoldFeatureSmall + case FeatureXSmall + case BoldFeatureXSmall + + case Title2XLarge + case BoldTitle2XLarge + case TitleXLarge + case BoldTitleXLarge + case TitleLarge + case BoldTitleLarge + case TitleMedium + case BoldTitleMedium + case TitleSmall + case BoldTitleSmall + + public var typographicalStyle: TypographicalStyle { + return TypographicalStyle(rawValue: self.rawValue) ?? .BoldFeatureXSmall + } +} + +public enum TitleLockupOtherTypographicalStyle: String, Codable, CaseIterable { + case BodyLarge + case BoldBodyLarge + case BodyMedium + case BoldBodyMedium + case BodySmall + case BoldBodySmall + + public var typographicalStyle: TypographicalStyle { + return TypographicalStyle(rawValue: self.rawValue) ?? .BodyLarge + } +} + +@objc(VDSTitleLockup) +open class TitleLockup: View { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var stackView = UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .vertical + $0.distribution = .fill + } + + //-------------------------------------------------- + // MARK: - Configuration Properties + //-------------------------------------------------- + // Sizes are from InVision design specs. + + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + open var textPosition: TitleLockupTextPosition = .left { didSet { didChange() }} + + //style + open var titleTypograpicalStyle: TitleLockupitleTypographicalStyle = .BoldFeatureXSmall { didSet { didChange() }} + open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = .BodyLarge { didSet { didChange() }} + + //first row + open var eyebrowLabel = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } + open var eyebrowText: String = "" { didSet { didChange() }} + open var eyebrowTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} + + //second row + open var titleLabel = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } + open var titleText: String = "" { didSet { didChange() }} + open var titleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} + + //third row + open var subTitleLabel = Label().with { + $0.setContentCompressionResistancePriority(.required, for: .vertical) + } + open var subTitleText: String = "" { didSet { didChange() }} + open var subTitleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} + open var subTitleColor: Use = .primary { didSet { didChange() }} + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func setup() { + super.setup() + + isAccessibilityElement = true + accessibilityTraits = .button + addSubview(stackView) + + stackView.spacing = 0.0 + + stackView.addArrangedSubview(eyebrowLabel) + stackView.addArrangedSubview(titleLabel) + stackView.addArrangedSubview(subTitleLabel) + + //pin stackview to edges + stackView.pinToSuperView() + } + + public override func reset() { + super.reset() + titleLabel.reset() + eyebrowLabel.reset() + subTitleLabel.reset() + + textPosition = .left + + eyebrowText = "" + titleText = "" + subTitleText = "" + + titleTypograpicalStyle = .BoldFeatureXSmall + otherTypograpicalStyle = .BodyLarge + + } + + //-------------------------------------------------- + // MARK: - State + //-------------------------------------------------- + open override func updateView() { + super.updateView() + + let allLabelsTextPosition = textPosition.labelTextPosition + + eyebrowLabel.textPosition = allLabelsTextPosition + eyebrowLabel.typograpicalStyle = otherTypograpicalStyle.typographicalStyle + eyebrowLabel.text = eyebrowText + eyebrowLabel.attributes = eyebrowTextAttributes + eyebrowLabel.surface = surface + + titleLabel.textPosition = allLabelsTextPosition + titleLabel.typograpicalStyle = titleTypograpicalStyle.typographicalStyle + titleLabel.text = titleText + titleLabel.attributes = titleTextAttributes + titleLabel.surface = surface + + subTitleLabel.textPosition = allLabelsTextPosition + subTitleLabel.typograpicalStyle = otherTypograpicalStyle.typographicalStyle + subTitleLabel.text = subTitleText + subTitleLabel.attributes = subTitleTextAttributes + subTitleLabel.surface = surface + subTitleLabel.disabled = subTitleColor == .secondary + + //if both first 2 rows not empty set spacing + if !eyebrowText.isEmpty && !titleText.isEmpty { + stackView.spacing = 12.0 + } else { + stackView.spacing = 0.0 + } + + //if either first 2 rows not empty and subtile not empty, create space else collapse + if (!eyebrowText.isEmpty || !titleText.isEmpty) && !subTitleText.isEmpty { + stackView.setCustomSpacing(24.0, after: titleLabel) + } else if (!eyebrowText.isEmpty || !titleText.isEmpty) && subTitleText.isEmpty { + stackView.setCustomSpacing(0.0, after: titleLabel) + } + } +} From d995ac395458f4529d1058fb4fd9ddf4afef5380 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 08:33:11 -0600 Subject: [PATCH 06/23] fixed tilecontainer issue Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 73 ++++++++++++++----- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 9ae75f5b..0e54bfc1 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -12,6 +12,24 @@ import UIKit @objc(VDSTileContainer) open class TileContainer: Control { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + initialSetup() + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + initialSetup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + public enum ContainerBackgroundColor: String, CaseIterable { case white case black @@ -96,22 +114,18 @@ open class TileContainer: Control { 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 - }() - + private var widthConstraint: NSLayoutConstraint? + private var heightConstraint: NSLayoutConstraint? + internal var containerTopConstraint: NSLayoutConstraint? + internal var containerBottomConstraint: NSLayoutConstraint? + internal var containerLeadingConstraint: NSLayoutConstraint? + internal var containerTrailingConstraint: NSLayoutConstraint? + //functions //-------------------------------------------------- // MARK: - Lifecycle @@ -122,13 +136,28 @@ open class TileContainer: Control { addSubview(backgroundImageView) addSubview(containerView) addSubview(highlightView) + + widthConstraint = widthAnchor.constraint(equalToConstant: width) + widthConstraint?.isActive = true + + heightConstraint = heightAnchor.constraint(equalToConstant: width) + heightConstraint?.isActive = true + backgroundImageView.pinToSuperView() backgroundImageView.isUserInteractionEnabled = false backgroundImageView.isHidden = true - containerView.pinToSuperView() containerView.isUserInteractionEnabled = false containerView.backgroundColor = .clear + + containerTopConstraint = containerView.topAnchor.constraint(lessThanOrEqualTo: topAnchor, constant: padding) + containerTopConstraint?.isActive = true + containerBottomConstraint = containerView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: padding) + containerBottomConstraint?.isActive = true + containerLeadingConstraint = containerView.leadingAnchor.constraint(lessThanOrEqualTo: leadingAnchor, constant: padding) + containerLeadingConstraint?.isActive = true + containerTrailingConstraint = containerView.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor, constant: padding) + containerTrailingConstraint?.isActive = true highlightView.pinToSuperView() highlightView.isUserInteractionEnabled = false @@ -138,6 +167,7 @@ open class TileContainer: Control { //corner radius layer.cornerRadius = cornerRadius backgroundImageView.layer.cornerRadius = 8 + highlightView.layer.cornerRadius = 8 } @@ -215,16 +245,19 @@ open class TileContainer: Control { layer.borderColor = borderColorConfig.getColor(self).cgColor layer.borderWidth = showBorder ? 1 : 0 - - containerView.layoutMargins = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding) - + + containerTopConstraint?.constant = padding + containerLeadingConstraint?.constant = padding + containerBottomConstraint?.constant = -padding + containerTrailingConstraint?.constant = -padding + if let height { - widthConstraint.constant = width - heightConstraint.constant = height + widthConstraint?.constant = width + heightConstraint?.constant = height } else { let size = ratioSize - widthConstraint.constant = size.width - heightConstraint.constant = size.height + widthConstraint?.constant = size.width + heightConstraint?.constant = size.height } } From 83e11dcb0961a8ee440af563ffaf5c84298dcce3 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 08:33:49 -0600 Subject: [PATCH 07/23] added enumb protocol Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 16 ++++++++++++++++ VDS/Protocols/EnumSubset.swift | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 VDS/Protocols/EnumSubset.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 0a4e82e2..7ef890b9 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -43,6 +43,8 @@ EA5E304C294CBDD00082B959 /* TileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304B294CBDD00082B959 /* TileContainer.swift */; }; EA5E304E294CC7F00082B959 /* VDSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304D294CC7F00082B959 /* VDSColor.swift */; }; EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E30522950DDA60082B959 /* TitleLockup.swift */; }; + EA5E3058295105A40082B959 /* Tilet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E3057295105A40082B959 /* Tilet.swift */; }; + EA5E305A29510F8B0082B959 /* EnumSubset.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E305929510F8B0082B959 /* EnumSubset.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 */; }; @@ -141,6 +143,8 @@ EA5E304B294CBDD00082B959 /* TileContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainer.swift; sourceTree = ""; }; EA5E304D294CC7F00082B959 /* VDSColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSColor.swift; sourceTree = ""; }; EA5E30522950DDA60082B959 /* TitleLockup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockup.swift; sourceTree = ""; }; + EA5E3057295105A40082B959 /* Tilet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tilet.swift; sourceTree = ""; }; + EA5E305929510F8B0082B959 /* EnumSubset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnumSubset.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 = ""; }; @@ -320,6 +324,7 @@ EA1F265F28B945070033E859 /* RadioSwatch */, EAC925852911C9DE00091998 /* TextFields */, EA5E304A294CBDBB0082B959 /* TileContainer */, + EA5E3056295105930082B959 /* Tilet */, EA5E30512950DD8D0082B959 /* TitleLockup */, EA3361A0288B1E6F0071C351 /* Toggle */, ); @@ -358,6 +363,7 @@ EAA5EEDF28F49DB3003B3210 /* Colorable.swift */, EA3361AC288B26190071C351 /* DataTrackable.swift */, EA3361A9288B25E40071C351 /* Disabling.swift */, + EA5E305929510F8B0082B959 /* EnumSubset.swift */, EAF7F0A1289AFB3900B287F5 /* Errorable.swift */, EA3361AE288B26310071C351 /* FormFieldable.swift */, EA3361BE288B2EA60071C351 /* Handlerable.swift */, @@ -455,6 +461,14 @@ path = TitleLockup; sourceTree = ""; }; + EA5E3056295105930082B959 /* Tilet */ = { + isa = PBXGroup; + children = ( + EA5E3057295105A40082B959 /* Tilet.swift */, + ); + path = Tilet; + sourceTree = ""; + }; EA89200B28B530F0006B9984 /* RadioBox */ = { isa = PBXGroup; children = ( @@ -689,6 +703,7 @@ EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */, EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */, EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */, + EA5E305A29510F8B0082B959 /* EnumSubset.swift in Sources */, EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */, EAC925842911C63100091998 /* Colorable.swift in Sources */, EA3361C5289030FC0071C351 /* Accessable.swift in Sources */, @@ -718,6 +733,7 @@ EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */, EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */, EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */, + EA5E3058295105A40082B959 /* Tilet.swift in Sources */, EA5E304E294CC7F00082B959 /* VDSColor.swift in Sources */, EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */, EAF7F09E289AAEC000B287F5 /* Constants.swift in Sources */, diff --git a/VDS/Protocols/EnumSubset.swift b/VDS/Protocols/EnumSubset.swift new file mode 100644 index 00000000..5f92a1cd --- /dev/null +++ b/VDS/Protocols/EnumSubset.swift @@ -0,0 +1,19 @@ +// +// EnumSubset.swift +// VDS +// +// Created by Matt Bruce on 12/19/22. +// + +import Foundation + +public protocol EnumSubset: RawRepresentable, CaseIterable { + associatedtype T:RawRepresentable + var defaultValue: T { get } +} + +extension EnumSubset where RawValue == T.RawValue { + public var value: T { + T(rawValue: rawValue) ?? defaultValue + } +} From 556055c38af8079e67066340479c35d0bf29af6b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 08:34:06 -0600 Subject: [PATCH 08/23] refactored to use new enum Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 4f79e7a0..a93607ed 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -23,7 +23,8 @@ public enum TitleLockupTextPosition: String, Codable, CaseIterable { } } -public enum TitleLockupitleTypographicalStyle: String, Codable, CaseIterable { +public enum TitleLockupTitleTypographicalStyle: String, Codable, EnumSubset { + case FeatureMedium case BoldFeatureMedium case FeatureSmall @@ -42,12 +43,10 @@ public enum TitleLockupitleTypographicalStyle: String, Codable, CaseIterable { case TitleSmall case BoldTitleSmall - public var typographicalStyle: TypographicalStyle { - return TypographicalStyle(rawValue: self.rawValue) ?? .BoldFeatureXSmall - } + public var defaultValue: TypographicalStyle {.BoldFeatureXSmall } } -public enum TitleLockupOtherTypographicalStyle: String, Codable, CaseIterable { +public enum TitleLockupOtherTypographicalStyle: String, Codable, EnumSubset { case BodyLarge case BoldBodyLarge case BodyMedium @@ -55,9 +54,7 @@ public enum TitleLockupOtherTypographicalStyle: String, Codable, CaseIterable { case BodySmall case BoldBodySmall - public var typographicalStyle: TypographicalStyle { - return TypographicalStyle(rawValue: self.rawValue) ?? .BodyLarge - } + public var defaultValue: TypographicalStyle {.BodyLarge } } @objc(VDSTitleLockup) @@ -99,7 +96,7 @@ open class TitleLockup: View { open var textPosition: TitleLockupTextPosition = .left { didSet { didChange() }} //style - open var titleTypograpicalStyle: TitleLockupitleTypographicalStyle = .BoldFeatureXSmall { didSet { didChange() }} + open var titleTypograpicalStyle: TitleLockupTitleTypographicalStyle = .BoldFeatureXSmall { didSet { didChange() }} open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = .BodyLarge { didSet { didChange() }} //first row @@ -152,9 +149,12 @@ open class TitleLockup: View { textPosition = .left eyebrowText = "" + eyebrowTextAttributes = nil titleText = "" + titleTextAttributes = nil subTitleText = "" - + subTitleTextAttributes = nil + titleTextAttributes titleTypograpicalStyle = .BoldFeatureXSmall otherTypograpicalStyle = .BodyLarge @@ -169,19 +169,19 @@ open class TitleLockup: View { let allLabelsTextPosition = textPosition.labelTextPosition eyebrowLabel.textPosition = allLabelsTextPosition - eyebrowLabel.typograpicalStyle = otherTypograpicalStyle.typographicalStyle + eyebrowLabel.typograpicalStyle = otherTypograpicalStyle.value eyebrowLabel.text = eyebrowText eyebrowLabel.attributes = eyebrowTextAttributes eyebrowLabel.surface = surface titleLabel.textPosition = allLabelsTextPosition - titleLabel.typograpicalStyle = titleTypograpicalStyle.typographicalStyle + titleLabel.typograpicalStyle = titleTypograpicalStyle.value titleLabel.text = titleText titleLabel.attributes = titleTextAttributes titleLabel.surface = surface subTitleLabel.textPosition = allLabelsTextPosition - subTitleLabel.typograpicalStyle = otherTypograpicalStyle.typographicalStyle + subTitleLabel.typograpicalStyle = otherTypograpicalStyle.value subTitleLabel.text = subTitleText subTitleLabel.attributes = subTitleTextAttributes subTitleLabel.surface = surface From fce5bec18fa9bbe14035c979520103adda21f26a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 08:34:17 -0600 Subject: [PATCH 09/23] first cut of tilet Signed-off-by: Matt Bruce --- VDS/Components/Tilet/Tilet.swift | 123 +++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 VDS/Components/Tilet/Tilet.swift diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift new file mode 100644 index 00000000..35c59b49 --- /dev/null +++ b/VDS/Components/Tilet/Tilet.swift @@ -0,0 +1,123 @@ +// +// Tilet.swift +// VDS +// +// Created by Matt Bruce on 12/19/22. +// + +import Foundation +import Foundation +import VDSColorTokens +import UIKit + +public enum TiletTitleTypographicalStyle: String, Codable, EnumSubset { + case TitleXLarge + case BoldTitleXLarge + case TitleLarge + case BoldTitleLarge + case TitleMedium + case BoldTitleMedium + case TitleSmall + case BoldTitleSmall + + public var defaultValue: TypographicalStyle { .BoldTitleSmall } +} + +public enum TiletOtherTypographicalStyle: String, Codable, CaseIterable { + case BodyLarge + case BoldBodyLarge + case BodyMedium + case BoldBodyMedium + case BodySmall + case BoldBodySmall + + public var defaultValue: TypographicalStyle { .BodySmall } +} + + +@objc(VDSTilet) +open class Tilet: TileContainer { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + initialSetup() + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + initialSetup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + private var titleLockup = TitleLockup() + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + //style + open var titleTypograpicalStyle: TiletTitleTypographicalStyle = .BoldTitleSmall { didSet { didChange() }} + open var otherTypograpicalStyle: TiletOtherTypographicalStyle = .BodySmall { didSet { didChange() }} + + //text + open var titleText: String = "" { didSet { didChange() }} + open var titleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} + + open var subTitleText: String = "" { didSet { didChange() }} + open var subTitleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} + + open var subTitleColor: Use = .primary { didSet { didChange() }} + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + + //functions + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + open override func setup() { + super.setup() + containerView.addSubview(titleLockup) + titleLockup.pinToSuperView() + titleLockup.pinTop() + titleLockup.pinLeading() + titleLockup.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor).isActive = true + titleLockup.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor).isActive = true + } + + public override func reset() { + super.reset() + titleLockup.reset() + + titleText = "" + titleTextAttributes = nil + subTitleText = "" + subTitleTextAttributes = nil + subTitleColor = .primary + } + + //-------------------------------------------------- + // MARK: - State + //-------------------------------------------------- + + open override func updateView() { + super.updateView() + + titleLockup.titleText = titleText + titleLockup.titleTextAttributes = titleTextAttributes + + titleLockup.subTitleText = titleText + titleLockup.subTitleTextAttributes = titleTextAttributes + titleLockup.subTitleColor = subTitleColor + } +} From fbca279f7e5ee45298ce673fba36e6a7174545f6 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 11:10:54 -0600 Subject: [PATCH 10/23] updated for typography spacing config Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 144 ++++++++++++++++++- VDS/Typography/Typography.swift | 33 +++++ 2 files changed, 172 insertions(+), 5 deletions(-) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index a93607ed..55448bd7 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -89,7 +89,6 @@ open class TitleLockup: View { //-------------------------------------------------- // Sizes are from InVision design specs. - //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -97,7 +96,7 @@ open class TitleLockup: View { //style open var titleTypograpicalStyle: TitleLockupTitleTypographicalStyle = .BoldFeatureXSmall { didSet { didChange() }} - open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = .BodyLarge { didSet { didChange() }} + open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = UIDevice.isIPad ? .BodyLarge : .BodyMedium { didSet { didChange() }} //first row open var eyebrowLabel = Label().with { @@ -154,7 +153,7 @@ open class TitleLockup: View { titleTextAttributes = nil subTitleText = "" subTitleTextAttributes = nil - titleTextAttributes + titleTextAttributes = nil titleTypograpicalStyle = .BoldFeatureXSmall otherTypograpicalStyle = .BodyLarge @@ -189,16 +188,151 @@ open class TitleLockup: View { //if both first 2 rows not empty set spacing if !eyebrowText.isEmpty && !titleText.isEmpty { - stackView.spacing = 12.0 + stackView.spacing = getTopSpacing() } else { stackView.spacing = 0.0 } //if either first 2 rows not empty and subtile not empty, create space else collapse if (!eyebrowText.isEmpty || !titleText.isEmpty) && !subTitleText.isEmpty { - stackView.setCustomSpacing(24.0, after: titleLabel) + stackView.setCustomSpacing(getBottomSpacing(), after: titleLabel) } else if (!eyebrowText.isEmpty || !titleText.isEmpty) && subTitleText.isEmpty { stackView.setCustomSpacing(0.0, after: titleLabel) } } + + internal var topTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = { + let configs = [ + TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge], + neighboring: [.BodySmall, .BodyMedium, .BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.TitleMedium, .BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 16.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 16.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge, .BodyMedium, .TitleMedium], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall], + neighboring: [.TitleLarge, .BodyLarge], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleLarge, .TitleXLarge], + spacing: 16.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 12.0, + deviceType: .iPhone) + ] + return TypographicalStyleSpacingConfig(configs: configs) + }() + + internal var bottomTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = { + let configs = [ + TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge], + neighboring: [.BodySmall, .BodyMedium, .BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.TitleMedium, .BodyLarge], + spacing: 16.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge, .BodyMedium, .TitleMedium], + spacing: 16, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall], + neighboring: [.TitleLarge, .BodyLarge], + spacing: 16.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleLarge, .TitleXLarge], + spacing: 24.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 24.0, + deviceType: .iPhone) + ] + return TypographicalStyleSpacingConfig(configs: configs) + }() + + open func getTopSpacing() -> CGFloat { + topTypographicalStyleSpacingConfig.spacing(for: titleTypograpicalStyle.value, neighboring: otherTypograpicalStyle.value) + } + + open func getBottomSpacing() -> CGFloat { + bottomTypographicalStyleSpacingConfig.spacing(for: titleTypograpicalStyle.value, neighboring: otherTypograpicalStyle.value) + } } + +extension TypographicalStyle { + func isWithin(_ collection: [TypographicalStyle]) -> Bool { + (collection.first(where: {$0 == self}) != nil) + } +} + diff --git a/VDS/Typography/Typography.swift b/VDS/Typography/Typography.swift index 86629d91..daecf91b 100644 --- a/VDS/Typography/Typography.swift +++ b/VDS/Typography/Typography.swift @@ -281,3 +281,36 @@ extension TypographicalStyle { } } } + +public struct TypographicalStyleSpacingConfig { + public var defaultSpacing: CGFloat = 8.0 + public var configs: [TypographicalStyleDeviceSpacingConfig] + + public func spacing(for style: TypographicalStyle, neighboring: TypographicalStyle) -> CGFloat { + let deviceType: TypographicalStyleDeviceSpacingConfig.DeviceType = UIDevice.isIPad ? .iPad : .iPhone + if let config = configs.first(where: + { style.isWithin($0.primaryStyles) && neighboring.isWithin($0.neighboringStyles) && + ($0.deviceType == deviceType || $0.deviceType == .all )}) + { + return config.spacing + } + return defaultSpacing + } +} + +public struct TypographicalStyleDeviceSpacingConfig { + public enum DeviceType { + case iPhone, iPad, all + } + public var spacing: CGFloat + public var deviceType: DeviceType = .iPhone + public var primaryStyles: [TypographicalStyle] + public var neighboringStyles: [TypographicalStyle] + + public init(_ primaryStyles: [TypographicalStyle], neighboring: [TypographicalStyle], spacing: CGFloat, deviceType: DeviceType = .iPhone) { + self.spacing = spacing + self.primaryStyles = primaryStyles + self.neighboringStyles = neighboring + self.deviceType = deviceType + } +} From 9a69c2c112d297cc5e6ba92b159b9c4798343005 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 11:17:53 -0600 Subject: [PATCH 11/23] fixed bugs Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 12 ++++++---- VDS/Components/Tilet/Tilet.swift | 23 ++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 0e54bfc1..78bde32a 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -100,7 +100,7 @@ open class TileContainer: Control { $0.clipsToBounds = true } - private var padding: CGFloat { + internal var padding: CGFloat { switch containerPadding { case .twelve: return 12.0 @@ -115,12 +115,11 @@ open class TileContainer: Control { } } - //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- - private var widthConstraint: NSLayoutConstraint? - private var heightConstraint: NSLayoutConstraint? + internal var widthConstraint: NSLayoutConstraint? + internal var heightConstraint: NSLayoutConstraint? internal var containerTopConstraint: NSLayoutConstraint? internal var containerBottomConstraint: NSLayoutConstraint? internal var containerLeadingConstraint: NSLayoutConstraint? @@ -261,6 +260,11 @@ open class TileContainer: Control { } } + public func addContentView(_ view: UIView) { + containerView.addSubview(view) + view.pinToSuperView() + } + class BackgroundColorConfiguration: ObjectColorable { typealias ObjectType = TileContainer diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift index 35c59b49..117c185f 100644 --- a/VDS/Components/Tilet/Tilet.swift +++ b/VDS/Components/Tilet/Tilet.swift @@ -20,10 +20,10 @@ public enum TiletTitleTypographicalStyle: String, Codable, EnumSubset { case TitleSmall case BoldTitleSmall - public var defaultValue: TypographicalStyle { .BoldTitleSmall } + public var defaultValue: TitleLockupTitleTypographicalStyle { .BoldTitleSmall } } -public enum TiletOtherTypographicalStyle: String, Codable, CaseIterable { +public enum TiletOtherTypographicalStyle: String, Codable, EnumSubset { case BodyLarge case BoldBodyLarge case BodyMedium @@ -31,7 +31,7 @@ public enum TiletOtherTypographicalStyle: String, Codable, CaseIterable { case BodySmall case BoldBodySmall - public var defaultValue: TypographicalStyle { .BodySmall } + public var defaultValue: TitleLockupOtherTypographicalStyle { .BodySmall } } @@ -79,7 +79,7 @@ open class Tilet: TileContainer { //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- - + internal var contentViewWithConstraint: NSLayoutConstraint? //functions //-------------------------------------------------- // MARK: - Lifecycle @@ -87,12 +87,9 @@ open class Tilet: TileContainer { open override func setup() { super.setup() - containerView.addSubview(titleLockup) - titleLockup.pinToSuperView() - titleLockup.pinTop() - titleLockup.pinLeading() - titleLockup.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor).isActive = true - titleLockup.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor).isActive = true + addContentView(titleLockup) + contentViewWithConstraint = titleLockup.widthAnchor.constraint(equalToConstant: width - (padding * 2)) + contentViewWithConstraint?.isActive = true } public override func reset() { @@ -113,10 +110,14 @@ open class Tilet: TileContainer { open override func updateView() { super.updateView() + contentViewWithConstraint?.constant = width - (padding * 2) + titleLockup.titleText = titleText + titleLockup.titleTypograpicalStyle = titleTypograpicalStyle.value titleLockup.titleTextAttributes = titleTextAttributes - titleLockup.subTitleText = titleText + titleLockup.subTitleText = subTitleText + titleLockup.otherTypograpicalStyle = otherTypograpicalStyle.value titleLockup.subTitleTextAttributes = titleTextAttributes titleLockup.subTitleColor = subTitleColor } From 10f0d35ff2e76641554f5aa6bda8c99b8f068d32 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 11:30:43 -0600 Subject: [PATCH 12/23] moved to public properties Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 241 +++++++++---------- 1 file changed, 120 insertions(+), 121 deletions(-) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 55448bd7..958d7a81 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -88,7 +88,126 @@ open class TitleLockup: View { // MARK: - Configuration Properties //-------------------------------------------------- // Sizes are from InVision design specs. + open var topTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = { + let configs = [ + TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge], + neighboring: [.BodySmall, .BodyMedium, .BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.TitleMedium, .BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 16.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 16.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge, .BodyMedium, .TitleMedium], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall], + neighboring: [.TitleLarge, .BodyLarge], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleLarge, .TitleXLarge], + spacing: 16.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 12.0, + deviceType: .iPhone) + ] + return TypographicalStyleSpacingConfig(configs: configs) + }() + open var bottomTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = { + let configs = [ + TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge], + neighboring: [.BodySmall, .BodyMedium, .BodyLarge], + spacing: 12.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.TitleMedium, .BodyLarge], + spacing: 16.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleMedium, .TitleLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 24.0, + deviceType: .iPad), + + TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], + neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium], + spacing: 12.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], + neighboring: [.BodyLarge, .BodyMedium, .TitleMedium], + spacing: 16, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall], + neighboring: [.TitleLarge, .BodyLarge], + spacing: 16.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.TitleLarge, .TitleXLarge], + spacing: 24.0, + deviceType: .iPhone), + + TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], + neighboring: [.BodyLarge], + spacing: 24.0, + deviceType: .iPhone) + ] + return TypographicalStyleSpacingConfig(configs: configs) + }() + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -200,127 +319,7 @@ open class TitleLockup: View { stackView.setCustomSpacing(0.0, after: titleLabel) } } - - internal var topTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = { - let configs = [ - TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge], - neighboring: [.BodySmall, .BodyMedium, .BodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], - neighboring: [.TitleMedium, .BodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], - neighboring: [.TitleMedium, .TitleLarge], - spacing: 16.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], - neighboring: [.BodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], - neighboring: [.TitleMedium, .TitleLarge], - spacing: 16.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], - neighboring: [.BodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], - neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium], - spacing: 12.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], - neighboring: [.BodyLarge, .BodyMedium, .TitleMedium], - spacing: 12.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall], - neighboring: [.TitleLarge, .BodyLarge], - spacing: 12.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], - neighboring: [.TitleLarge, .TitleXLarge], - spacing: 16.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], - neighboring: [.BodyLarge], - spacing: 12.0, - deviceType: .iPhone) - ] - return TypographicalStyleSpacingConfig(configs: configs) - }() - - internal var bottomTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = { - let configs = [ - TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge], - neighboring: [.BodySmall, .BodyMedium, .BodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], - neighboring: [.TitleMedium, .BodyLarge], - spacing: 16.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], - neighboring: [.TitleMedium, .TitleLarge], - spacing: 24.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], - neighboring: [.BodyLarge], - spacing: 24.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], - neighboring: [.TitleMedium, .TitleLarge], - spacing: 24.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium], - neighboring: [.BodyLarge], - spacing: 24.0, - deviceType: .iPad), - - TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge], - neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium], - spacing: 12.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall], - neighboring: [.BodyLarge, .BodyMedium, .TitleMedium], - spacing: 16, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall], - neighboring: [.TitleLarge, .BodyLarge], - spacing: 16.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], - neighboring: [.TitleLarge, .TitleXLarge], - spacing: 24.0, - deviceType: .iPhone), - - TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium], - neighboring: [.BodyLarge], - spacing: 24.0, - deviceType: .iPhone) - ] - return TypographicalStyleSpacingConfig(configs: configs) - }() - + open func getTopSpacing() -> CGFloat { topTypographicalStyleSpacingConfig.spacing(for: titleTypograpicalStyle.value, neighboring: otherTypograpicalStyle.value) } From 76454b277159489c3c28b474fd8e19c4198f2e1f Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 11:49:37 -0600 Subject: [PATCH 13/23] fixed bug in flipping colors Signed-off-by: Matt Bruce --- VDS/Components/Tilet/Tilet.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift index 117c185f..dea145af 100644 --- a/VDS/Components/Tilet/Tilet.swift +++ b/VDS/Components/Tilet/Tilet.swift @@ -59,6 +59,17 @@ open class Tilet: TileContainer { // MARK: - Public Properties //-------------------------------------------------- private var titleLockup = TitleLockup() + open override var surface: Surface { + didSet { + //flip the color + let flippedColor:ContainerBackgroundColor = surface == .dark ? .white : .black + containerBackgroundColor = flippedColor + + //flip the surface for the titleLockup + let flippedSurface: Surface = surface == .dark ? .light : .dark + titleLockup.surface = flippedSurface + } + } //-------------------------------------------------- // MARK: - Public Properties @@ -87,6 +98,7 @@ open class Tilet: TileContainer { open override func setup() { super.setup() + surface = .light addContentView(titleLockup) contentViewWithConstraint = titleLockup.widthAnchor.constraint(equalToConstant: width - (padding * 2)) contentViewWithConstraint?.isActive = true From a340598861544e924ec52c12d80d80742569cc45 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 12:04:44 -0600 Subject: [PATCH 14/23] updating to fix for height Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 20 +++++++++++++++++-- VDS/Components/Tilet/Tilet.swift | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 78bde32a..afdbe27c 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -55,6 +55,7 @@ open class TileContainer: Control { case ratio16x9 = "16:9" case ratio1x2 = "1:2" case ratio2x1 = "2:1" + case none } //-------------------------------------------------- @@ -120,6 +121,7 @@ open class TileContainer: Control { //-------------------------------------------------- internal var widthConstraint: NSLayoutConstraint? internal var heightConstraint: NSLayoutConstraint? + internal var heightGreaterThanConstraint: NSLayoutConstraint? internal var containerTopConstraint: NSLayoutConstraint? internal var containerBottomConstraint: NSLayoutConstraint? internal var containerLeadingConstraint: NSLayoutConstraint? @@ -138,7 +140,10 @@ open class TileContainer: Control { widthConstraint = widthAnchor.constraint(equalToConstant: width) widthConstraint?.isActive = true - + + heightGreaterThanConstraint = heightAnchor.constraint(greaterThanOrEqualToConstant: 44.0) + heightGreaterThanConstraint?.isActive = false + heightConstraint = heightAnchor.constraint(equalToConstant: width) heightConstraint?.isActive = true @@ -222,6 +227,9 @@ open class TileContainer: Control { height = (2 / 1) * width case .ratio2x1: height = (1 / 2) * width + + default: + break } return CGSize(width: width, height: height) @@ -250,13 +258,21 @@ open class TileContainer: Control { containerBottomConstraint?.constant = -padding containerTrailingConstraint?.constant = -padding - if let height { + if aspectRatio == .none { + widthConstraint?.constant = width + heightConstraint?.isActive = false + heightGreaterThanConstraint?.isActive = true + } else if let height { widthConstraint?.constant = width heightConstraint?.constant = height + heightConstraint?.isActive = true + heightGreaterThanConstraint?.isActive = false } else { let size = ratioSize widthConstraint?.constant = size.width heightConstraint?.constant = size.height + heightConstraint?.isActive = true + heightGreaterThanConstraint?.isActive = false } } diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift index dea145af..30b43525 100644 --- a/VDS/Components/Tilet/Tilet.swift +++ b/VDS/Components/Tilet/Tilet.swift @@ -98,6 +98,7 @@ open class Tilet: TileContainer { open override func setup() { super.setup() + aspectRatio = .none surface = .light addContentView(titleLockup) contentViewWithConstraint = titleLockup.widthAnchor.constraint(equalToConstant: width - (padding * 2)) From ae97c2cc80b824c6a03d46c2fc8f5824c2b7c41e Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 12:33:29 -0600 Subject: [PATCH 15/23] added height Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index afdbe27c..d2956b7b 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -86,7 +86,18 @@ open class TileContainer: Control { } } - public var height: CGFloat? { didSet{ didChange() } } + private var _height: CGFloat? + public var height: CGFloat? { + get { return _height } + set { + if let newValue, newValue > 44 { + _height = newValue + } else { + _height = nil + } + didChange() + } + } public var showBorder: Bool = false { didSet{ didChange() } } From 70d269d4399da17b8c03d582f33b6c55546d62f2 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 14:24:01 -0600 Subject: [PATCH 16/23] fixed bug Signed-off-by: Matt Bruce --- VDS/Components/TileContainer/TileContainer.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index d2956b7b..7c8d738d 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -165,13 +165,13 @@ open class TileContainer: Control { containerView.isUserInteractionEnabled = false containerView.backgroundColor = .clear - containerTopConstraint = containerView.topAnchor.constraint(lessThanOrEqualTo: topAnchor, constant: padding) + containerTopConstraint = containerView.topAnchor.constraint(equalTo: topAnchor, constant: padding) containerTopConstraint?.isActive = true - containerBottomConstraint = containerView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: padding) + containerBottomConstraint = containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: padding) containerBottomConstraint?.isActive = true - containerLeadingConstraint = containerView.leadingAnchor.constraint(lessThanOrEqualTo: leadingAnchor, constant: padding) + containerLeadingConstraint = containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding) containerLeadingConstraint?.isActive = true - containerTrailingConstraint = containerView.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor, constant: padding) + containerTrailingConstraint = containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: padding) containerTrailingConstraint?.isActive = true highlightView.pinToSuperView() From 32c02ad088494aec4ff4bcbf8455c29d55debc40 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 14:26:00 -0600 Subject: [PATCH 17/23] removed code Signed-off-by: Matt Bruce --- VDS/Components/Tilet/Tilet.swift | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift index 30b43525..dfbdca15 100644 --- a/VDS/Components/Tilet/Tilet.swift +++ b/VDS/Components/Tilet/Tilet.swift @@ -101,8 +101,7 @@ open class Tilet: TileContainer { aspectRatio = .none surface = .light addContentView(titleLockup) - contentViewWithConstraint = titleLockup.widthAnchor.constraint(equalToConstant: width - (padding * 2)) - contentViewWithConstraint?.isActive = true + titleLockup.pinToSuperView() } public override func reset() { @@ -122,9 +121,7 @@ open class Tilet: TileContainer { open override func updateView() { super.updateView() - - contentViewWithConstraint?.constant = width - (padding * 2) - + titleLockup.titleText = titleText titleLockup.titleTypograpicalStyle = titleTypograpicalStyle.value titleLockup.titleTextAttributes = titleTextAttributes From b7c53360b2419b258fbbc3a85e50643dac532a25 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 16:52:15 -0600 Subject: [PATCH 18/23] fixed issue with tilet percentage Signed-off-by: Matt Bruce --- .../TileContainer/TileContainer.swift | 6 +- VDS/Components/Tilet/Tilet.swift | 114 +++++++++++++++--- 2 files changed, 99 insertions(+), 21 deletions(-) diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index 7c8d738d..1f676421 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -287,9 +287,11 @@ open class TileContainer: Control { } } - public func addContentView(_ view: UIView) { + public func addContentView(_ view: UIView, shouldPin: Bool = true) { containerView.addSubview(view) - view.pinToSuperView() + if shouldPin { + view.pinToSuperView() + } } class BackgroundColorConfiguration: ObjectColorable { diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift index dfbdca15..b33eb006 100644 --- a/VDS/Components/Tilet/Tilet.swift +++ b/VDS/Components/Tilet/Tilet.swift @@ -36,7 +36,7 @@ public enum TiletOtherTypographicalStyle: String, Codable, EnumSubset { @objc(VDSTilet) -open class Tilet: TileContainer { +open class Tilet: View { //-------------------------------------------------- // MARK: - Initializers @@ -56,21 +56,15 @@ open class Tilet: TileContainer { initialSetup() } //-------------------------------------------------- - // MARK: - Public Properties + // MARK: - Private Properties //-------------------------------------------------- - private var titleLockup = TitleLockup() - open override var surface: Surface { - didSet { - //flip the color - let flippedColor:ContainerBackgroundColor = surface == .dark ? .white : .black - containerBackgroundColor = flippedColor - - //flip the surface for the titleLockup - let flippedSurface: Surface = surface == .dark ? .light : .dark - titleLockup.surface = flippedSurface - } + private var tileContainer = TileContainer().with { + $0.aspectRatio = .none + $0.surface = .light } + private var titleLockup = TitleLockup() + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -78,6 +72,43 @@ open class Tilet: TileContainer { open var titleTypograpicalStyle: TiletTitleTypographicalStyle = .BoldTitleSmall { didSet { didChange() }} open var otherTypograpicalStyle: TiletOtherTypographicalStyle = .BodySmall { didSet { didChange() }} + open var width: CGFloat = 100 { didSet { didChange() }} + + private var _textWidth: CGFloat? + open var textWidth: CGFloat? { + get { _textWidth } + set { + if let newValue, newValue > 44.0 && newValue <= width { + _textWidth = newValue + if _textPercentage != nil { + _textPercentage = nil + } + } else { + _textWidth = nil + } + print("_textWidth: \(_textWidth)") + didChange() + } + + } + + private var _textPercentage: CGFloat? + open var textPercentage: CGFloat? { + get { _textPercentage } + set { + if let newValue, newValue >= 5 && newValue <= 100.0 { + _textPercentage = newValue + if textWidth != nil { + _textWidth = nil + } + } else { + _textPercentage = nil + } + print("_textPercentage: \(_textPercentage)") + didChange() + } + } + //text open var titleText: String = "" { didSet { didChange() }} open var titleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} @@ -90,7 +121,8 @@ open class Tilet: TileContainer { //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- - internal var contentViewWithConstraint: NSLayoutConstraint? + internal var titleLockupWidthConstraint: NSLayoutConstraint? + internal var titleLockupTrailingConstraint: NSLayoutConstraint? //functions //-------------------------------------------------- // MARK: - Lifecycle @@ -98,14 +130,24 @@ open class Tilet: TileContainer { open override func setup() { super.setup() - aspectRatio = .none - surface = .light - addContentView(titleLockup) - titleLockup.pinToSuperView() + addSubview(tileContainer) + tileContainer.pinToSuperView() + tileContainer.addContentView(titleLockup, shouldPin: false) + titleLockup.pinTop() + titleLockup.pinLeading() + titleLockup.pinBottom() + + //either you are 100% width of the tileContainer.contentView + titleLockupTrailingConstraint = titleLockup.trailingAnchor.constraint(equalTo: tileContainer.containerView.trailingAnchor) + titleLockupTrailingConstraint?.isActive = true } public override func reset() { super.reset() + tileContainer.reset() + tileContainer.aspectRatio = .none + tileContainer.surface = .light + titleLockup.reset() titleText = "" @@ -121,7 +163,41 @@ open class Tilet: TileContainer { open override func updateView() { super.updateView() - + + //flip the color + let flippedColor:TileContainer.ContainerBackgroundColor = surface == .dark ? .white : .black + tileContainer.containerBackgroundColor = flippedColor + tileContainer.width = width + + //flip the surface for the titleLockup + let flippedSurface: Surface = surface == .dark ? .light : .dark + titleLockup.surface = flippedSurface + + //either use textWidth + if let textWidth { + titleLockupTrailingConstraint?.isActive = false + titleLockupWidthConstraint?.isActive = false + titleLockupWidthConstraint = titleLockup.widthAnchor.constraint(equalToConstant: textWidth) + titleLockupWidthConstraint?.isActive = true + + } else if let textPercentage { + titleLockupTrailingConstraint?.isActive = false + titleLockupWidthConstraint?.isActive = false + titleLockupWidthConstraint = NSLayoutConstraint(item: titleLockup, + attribute: .width, + relatedBy: .equal, + toItem: tileContainer.containerView, + attribute: .width, + multiplier: textPercentage / 100, + constant: 0.0) + titleLockupWidthConstraint?.isActive = true + + } else { + titleLockupWidthConstraint?.isActive = false + titleLockupTrailingConstraint?.isActive = true + + } + titleLockup.titleText = titleText titleLockup.titleTypograpicalStyle = titleTypograpicalStyle.value titleLockup.titleTextAttributes = titleTextAttributes From 9d9f23c0be82d3e70aee7a8ffe614857c5c8274a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 20 Dec 2022 16:54:25 -0600 Subject: [PATCH 19/23] removed prints Signed-off-by: Matt Bruce --- VDS/Components/Tilet/Tilet.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/VDS/Components/Tilet/Tilet.swift b/VDS/Components/Tilet/Tilet.swift index b33eb006..417a7f08 100644 --- a/VDS/Components/Tilet/Tilet.swift +++ b/VDS/Components/Tilet/Tilet.swift @@ -86,7 +86,6 @@ open class Tilet: View { } else { _textWidth = nil } - print("_textWidth: \(_textWidth)") didChange() } @@ -104,7 +103,6 @@ open class Tilet: View { } else { _textPercentage = nil } - print("_textPercentage: \(_textPercentage)") didChange() } } From abda0b740236506869f05e9eb44f9887fb7265a8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 21 Dec 2022 07:53:03 -0600 Subject: [PATCH 20/23] fixed bug in radio swatch Signed-off-by: Matt Bruce --- VDS/Components/RadioSwatch/RadioSwatchGroup.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/VDS/Components/RadioSwatch/RadioSwatchGroup.swift b/VDS/Components/RadioSwatch/RadioSwatchGroup.swift index 9929da63..420302e9 100644 --- a/VDS/Components/RadioSwatch/RadioSwatchGroup.swift +++ b/VDS/Components/RadioSwatch/RadioSwatchGroup.swift @@ -124,6 +124,10 @@ public class RadioSwatchGroupBase: SelectorGroupSe collectionView.reloadData() } + public func reload() { + collectionView.reloadData() + } + //-------------------------------------------------- // MARK: - UICollectionViewDelegateFlowLayout //-------------------------------------------------- From 42e2c5673f10b1210ddac188d3b972b8d79a75a1 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 21 Dec 2022 08:56:51 -0600 Subject: [PATCH 21/23] fixed highlight bug in entry field Signed-off-by: Matt Bruce --- VDS/Classes/Control.swift | 4 +++- VDS/Components/TextFields/EntryField/EntryField.swift | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/VDS/Classes/Control.swift b/VDS/Classes/Control.swift index d5af7f46..ba2acd42 100644 --- a/VDS/Classes/Control.swift +++ b/VDS/Classes/Control.swift @@ -29,10 +29,12 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable { open override var isSelected: Bool { didSet { didChange() } } + internal var enabledHighlight: Bool = true + var isHighlightAnimating = false open override var isHighlighted: Bool { didSet { - if isHighlightAnimating == false { + if isHighlightAnimating == false && enabledHighlight { isHighlightAnimating = true UIView.animate(withDuration: 0.1, animations: { [weak self] in self?.updateView() diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index d38d4453..9687efa9 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -163,6 +163,7 @@ open class EntryField: Control, Accessable { open override func setup() { super.setup() + enabledHighlight = false isAccessibilityElement = true accessibilityTraits = .button addSubview(stackView) From be265e5d648870b99f2d1c6fd2be0a42e1b24130 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 21 Dec 2022 09:07:36 -0600 Subject: [PATCH 22/23] fixed bug in tooltip Signed-off-by: Matt Bruce --- VDS/Components/TextFields/EntryField/EntryField.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index 9687efa9..d1d0ada0 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -167,7 +167,6 @@ open class EntryField: Control, Accessable { isAccessibilityElement = true accessibilityTraits = .button addSubview(stackView) - stackView.isUserInteractionEnabled = false //create the wrapping view heightConstraint = containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: containerSize.height) From 119190178709de5bafc2d46f9e01fa4e1fbdf4b8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 21 Dec 2022 10:19:23 -0600 Subject: [PATCH 23/23] fixed bug in layout for textEntry Signed-off-by: Matt Bruce --- VDS/Components/TextFields/EntryField/EntryField.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index d1d0ada0..851fb0e5 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -184,8 +184,12 @@ open class EntryField: Control, Accessable { stackView.setCustomSpacing(8, after: container) stackView.setCustomSpacing(8, after: errorLabel) - stackView.pinToSuperView() - + stackView + .pinTop() + .pinBottom() + .pinLeading() + .trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor).isActive = true + titleLabel.textColorConfiguration = primaryColorConfig.eraseToAnyColorable() errorLabel.textColorConfiguration = primaryColorConfig.eraseToAnyColorable() helperLabel.textColorConfiguration = secondaryColorConfig.eraseToAnyColorable()