From 87ecc1e28a638298231d3aa464ff6c4eeacfab78 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 13 Jul 2023 14:41:07 -0500 Subject: [PATCH] added code comments Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 2 +- VDS/Classes/ColorConfiguration.swift | 2 +- VDS/Classes/Control.swift | 1 + VDS/Classes/View.swift | 5 +- .../BadgeIndicator/BadgeIndicator.swift | 134 +++++++++++------- VDS/Protocols/Colorable.swift | 20 ++- VDS/Protocols/Disabling.swift | 2 + VDS/Protocols/Surfaceable.swift | 2 + VDS/VDS.docc/VDS.md | 43 +++++- 9 files changed, 135 insertions(+), 76 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 00b8177b..3188ba91 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -406,8 +406,8 @@ EA33619D288B1E330071C351 /* Components */ = { isa = PBXGroup; children = ( - EAD062AE2A3B87210015965D /* BadgeIndicator */, EA4DB2FE28DCBC1900103EE3 /* Badge */, + EAD062AE2A3B87210015965D /* BadgeIndicator */, EA0FC2BE2912D18200DF80B4 /* Buttons */, EAF7F092289985E200B287F5 /* Checkbox */, EA985BF3296C609E00F2FF2E /* Icon */, diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index 3a4b468e..a1474610 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -23,7 +23,7 @@ public typealias ObjectColorable = Colorable & Initable & ObjectWithable /// let textColor = config.getColor(model) //returns .black /// -/// You can pass in a Surfaceable object and it will give you the color responding. +/// You can pass in a Surfaceable object and this will return the corresponding Color based on the object's surface property. open class SurfaceColorConfiguration: ObjectColorable { public typealias ObjectType = Surfaceable public var lightColor: UIColor = .clear diff --git a/VDS/Classes/Control.swift b/VDS/Classes/Control.swift index 50a10326..2823bb80 100644 --- a/VDS/Classes/Control.swift +++ b/VDS/Classes/Control.swift @@ -10,6 +10,7 @@ import UIKit import Combine @objc(VDSControl) +/// Base Class use to build Controls. open class Control: UIControl, Handlerable, ViewProtocol, Resettable, UserInfoable, Clickable { //-------------------------------------------------- diff --git a/VDS/Classes/View.swift b/VDS/Classes/View.swift index 56dae7bd..08bb2b34 100644 --- a/VDS/Classes/View.swift +++ b/VDS/Classes/View.swift @@ -11,6 +11,7 @@ import Combine @objc(VDSView) +/// Base Class used to build Views. open class View: UIView, Handlerable, ViewProtocol, Resettable, UserInfoable { //-------------------------------------------------- @@ -29,10 +30,10 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable, UserInfoable { /// Dictionary for keeping information for this Control use only Primitives open var userInfo = [String: Primitive]() - /// Current Surface used within this Control and used to passdown to child views + /// Current Surface and this is used to pass down to child objects that implement Surfacable open var surface: Surface = .light { didSet { setNeedsUpdate() } } - /// Control is disabled or not + /// Whether this object is disabled or not open var disabled: Bool = false { didSet { setNeedsUpdate(); isUserInteractionEnabled = !disabled } } //-------------------------------------------------- diff --git a/VDS/Components/BadgeIndicator/BadgeIndicator.swift b/VDS/Components/BadgeIndicator/BadgeIndicator.swift index ad64cf7b..748025e2 100644 --- a/VDS/Components/BadgeIndicator/BadgeIndicator.swift +++ b/VDS/Components/BadgeIndicator/BadgeIndicator.swift @@ -12,27 +12,32 @@ import VDSFormControlsTokens import Combine import VDSTypographyTokens -/// Badges are visual labels used to convey status or highlight supplemental information. +/// Badge Indicators are visual labels . @objc(VDSBadgeIndicator) open class BadgeIndicator: View { //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- + + /// Enum type for fill color public enum FillColor: String, CaseIterable { case red, yellow, green, orange, blue, gray, grayLowContrast, black, white } + /// Enum type for kind of BadgeIndicator public enum Kind: String, CaseIterable { case simple, numbered } - public enum MaxDigits: String, CaseIterable { + /// Enum type for maximum number of digits + public enum MaximumDigits: String, CaseIterable { case one case two case three case four case five case six + case none public var value: Int { switch self { @@ -48,17 +53,21 @@ open class BadgeIndicator: View { return 5 case .six: return 6 + case .none: + return 0 } } } + /// Enum type describing size of Badge Indicator public enum Size: String, CaseIterable { case xxlarge = "2XLarge" case xlarge = "XLarge" case large = "Large" case medium = "Medium" case small = "Small" - + + /// Dynamic TextStyle for the size public var textStyle: TextStyle { let style = TextStyle.bodySmall var pointSize: CGFloat = VDSTypography.fontSizeBody12 @@ -89,6 +98,7 @@ open class BadgeIndicator: View { letterSpacing: letterSpacing) } + //EdgeInsets for the label public var edgeInset: UIEdgeInsets { var horizontalPadding: CGFloat = VDSLayout.Spacing.space1X.value let verticalPadding: CGFloat = 0 @@ -109,6 +119,8 @@ open class BadgeIndicator: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + + /// Label used for the numeric kind open var label = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) $0.adjustsFontSizeToFitWidth = false @@ -117,6 +129,7 @@ open class BadgeIndicator: View { $0.numberOfLines = 1 } + /// BorderColor for Surface.light open var borderColorLight: UIColor? { didSet { if let borderColorLight { @@ -128,6 +141,7 @@ open class BadgeIndicator: View { } } + /// BorderColor for Surface.dark open var borderColorDark: UIColor? { didSet { if let borderColorDark { @@ -139,46 +153,97 @@ open class BadgeIndicator: View { } } + /// This will render the badges fill color based on the available options. + /// When used in conjunction with the surface prop, this fill color will change its tint automatically based on a light or dark surface. open var fillColor: FillColor = .red { didSet { setNeedsUpdate() }} - + + /// Badge Number that will be shown if you are using Kind.numbered open var number: Int? { didSet { setNeedsUpdate() }} + /// Type of Badge Indicator, simple is a dot, whereas numbered shows a number. open var kind: Kind = .simple { didSet { setNeedsUpdate() }} + /// Character that is always at the begging. Accepts any character and if unaffected by maximumDigits open var leadingCharacter: String? { didSet { setNeedsUpdate() }} + /// Determines the size of the Badge Indicator as well as the textStyle and padding used. open var size: Size = .xxlarge { didSet { setNeedsUpdate() }} + /// Pixel size of the dot when the kind is set to simple open var dotSize: CGFloat? { didSet { setNeedsUpdate() }} + /// Sets the padding at the top/bottom of the label open var verticalPadding: CGFloat? { didSet { setNeedsUpdate() }} + /// Sets the padding at the left/right of the label open var horitonalPadding: CGFloat? { didSet { setNeedsUpdate() }} + /// Hides the dot when you are in Kind.simple mode. open var hideDot: Bool = false { didSet { setNeedsUpdate() }} + /// Will not show the border open var hideBorder: Bool = false { didSet { setNeedsUpdate() }} - open var maxDigits: MaxDigits = .two { didSet { setNeedsUpdate() }} - + /// When in Kind.numbered this is the amount of digits that will show up when the user adds a number. + open var maximumDigits: MaximumDigits = .two { didSet { setNeedsUpdate() }} + + /// The Container's width open var width: CGFloat? { didSet { setNeedsUpdate() }} + /// The Container's height open var height: CGFloat? { didSet { setNeedsUpdate() }} //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - private let borderWidth: CGFloat = 1.0 - + private let badgeView = View() + private var badgeSize: CGFloat { max(minSize, size.textStyle.font.lineHeight) } + private var labelEdgeInset: UIEdgeInsets { + var newInset = size.edgeInset + if let verticalPadding, let horitonalPadding { + newInset = .init(top: verticalPadding, left: horitonalPadding, bottom: verticalPadding, right: horitonalPadding) + } else if let verticalPadding { + newInset = .init(top: verticalPadding, left: newInset.left, bottom: verticalPadding, right: newInset.right) + } else if let horitonalPadding { + newInset = .init(top: newInset.top, left: horitonalPadding, bottom: newInset.bottom, right: horitonalPadding) + } + + return newInset + } + //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- - private let badgeView = View() - private var badgeSize: CGFloat { max(16.0, size.textStyle.font.lineHeight) } private var widthConstraint: NSLayoutConstraint? private var heightConstraint: NSLayoutConstraint? private var labelContraints = NSLayoutConstraint.Container() + + //-------------------------------------------------- + // MARK: - Configuration + //-------------------------------------------------- + private let borderWidth: CGFloat = 1.0 + private let minSize: CGFloat = 16.0 + private let minDotSize: CGFloat = 4.0 + private let dotRatio: CGFloat = 0.24 + + private var borderColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteBlack) + private var backgroundColorConfiguration: AnyColorable = { + let config = KeyedColorConfiguration(keyPath: \.fillColor) + config.setSurfaceColors(VDSColor.backgroundBrandhighlight, VDSColor.backgroundBrandhighlight, forKey: .red) + config.setSurfaceColors(VDSColor.paletteYellow62, VDSColor.paletteYellow62, forKey: .yellow) + config.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen36, forKey: .green) + config.setSurfaceColors(VDSColor.paletteOrange41, VDSColor.paletteOrange58, forKey: .orange) + config.setSurfaceColors(VDSColor.paletteBlue38, VDSColor.paletteBlue46, forKey: .blue) + config.setSurfaceColors(VDSColor.paletteGray44, VDSColor.paletteGray65, forKey: .gray) + config.setSurfaceColors(VDSColor.paletteGray85, VDSColor.paletteGray20, forKey: .grayLowContrast) + config.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryDark, forKey: .black) + config.setSurfaceColors(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryLight, forKey: .white) + return config.eraseToAnyColorable() + }() + + private var textColorConfiguration = ViewColorConfiguration() + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- @@ -224,41 +289,7 @@ open class BadgeIndicator: View { shouldUpdateView = true setNeedsUpdate() } - - private var labelEdgeInset: UIEdgeInsets { - var newInset = size.edgeInset - if let verticalPadding, let horitonalPadding { - newInset = .init(top: verticalPadding, left: horitonalPadding, bottom: verticalPadding, right: horitonalPadding) - } else if let verticalPadding { - newInset = .init(top: verticalPadding, left: newInset.left, bottom: verticalPadding, right: newInset.right) - } else if let horitonalPadding { - newInset = .init(top: newInset.top, left: horitonalPadding, bottom: newInset.bottom, right: horitonalPadding) - } - - return newInset - } - - //-------------------------------------------------- - // MARK: - Configuration - //-------------------------------------------------- - private var borderColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteBlack) - - private var backgroundColorConfiguration: AnyColorable = { - let config = KeyedColorConfiguration(keyPath: \.fillColor) - config.setSurfaceColors(VDSColor.backgroundBrandhighlight, VDSColor.backgroundBrandhighlight, forKey: .red) - config.setSurfaceColors(VDSColor.paletteYellow62, VDSColor.paletteYellow62, forKey: .yellow) - config.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen36, forKey: .green) - config.setSurfaceColors(VDSColor.paletteOrange41, VDSColor.paletteOrange58, forKey: .orange) - config.setSurfaceColors(VDSColor.paletteBlue38, VDSColor.paletteBlue46, forKey: .blue) - config.setSurfaceColors(VDSColor.paletteGray44, VDSColor.paletteGray65, forKey: .gray) - config.setSurfaceColors(VDSColor.paletteGray85, VDSColor.paletteGray20, forKey: .grayLowContrast) - config.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryDark, forKey: .black) - config.setSurfaceColors(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryLight, forKey: .white) - return config.eraseToAnyColorable() - }() - - private var textColorConfiguration = ViewColorConfiguration() - + public func updateTextColorConfig() { textColorConfiguration.reset() @@ -323,19 +354,13 @@ open class BadgeIndicator: View { let badgeCount = number ?? 0 var text: String = "" if kind == .numbered && badgeCount >= 0 { - let maxBadgetCount = limitDigits(number: badgeCount, maxDigits: maxDigits.value) + let maxBadgetCount = maximumDigits == .none ? badgeCount : limitDigits(number: badgeCount, maxDigits: maximumDigits.value) let formatter = NumberFormatter() formatter.numberStyle = .decimal text = formatter.string(from: .init(integerLiteral: maxBadgetCount))! - if maxDigits.value < "\(badgeCount)".count { - let formatter = NumberFormatter() - formatter.numberStyle = .decimal - text = "\(text)+" - } + if let leadingCharacter { text = "\(leadingCharacter)\(text)" - } else { - text = "\(text)" } } return text @@ -368,7 +393,8 @@ open class BadgeIndicator: View { let frame = badgeView.frame //default calculation if a dotSize isn't given - var dot: CGFloat = frame.height * 0.1875 + let dotSizeRatio = frame.height * dotRatio + var dot: CGFloat = dotSizeRatio < minDotSize ? minDotSize : dotSizeRatio if let dotSize, dotSize < frame.width, dotSize < frame.height { dot = dotSize } diff --git a/VDS/Protocols/Colorable.swift b/VDS/Protocols/Colorable.swift index 3c43bf1a..db70123b 100644 --- a/VDS/Protocols/Colorable.swift +++ b/VDS/Protocols/Colorable.swift @@ -8,12 +8,17 @@ import Foundation import UIKit +/// Protocol used to be implemented on a object that can return a color for a Generic ObjectType. public protocol Colorable { associatedtype ObjectType + /// Method used to get the current color needed for the Generic ObjectType passed into the method. func getColor(_ object: ObjectType) -> UIColor } extension Colorable { + /// Helper method used where you don't know the ObjectType to return the color. + /// - Parameter object: Any object, but this objectType will be checked against the registered Generic ObjectType for the Colorable + /// - Returns: UIColor for the rule of this Colorable implementation for the object passed into the function fileprivate func getColor(_ object: Any) -> UIColor { guard let model = object as? ObjectType else { assertionFailure("Invalid ObjectType, Expecting type \(ObjectType.self), received \(object) ") @@ -22,21 +27,12 @@ extension Colorable { return getColor(model) } + /// TypeErasure for the Colorable to AnyColorable + /// - Returns: AnyColorable public func eraseToAnyColorable() -> AnyColorable { AnyColorable(self) } } -public struct GenericColorable: Colorable, Withable { - private var wrapped: any Colorable - - public init(colorable: C) where C.ObjectType == ObjectType { - wrapped = colorable - } - - public func getColor(_ object: ObjectType) -> UIColor { - wrapped.getColor(object) - } -} - +/// TypeErased Struct of a Colorable Type. This type can be used anywhere as long as the ObjectType being passed into this method matches the wrapped Colorable ObjectType. public struct AnyColorable: Colorable, Withable { private let wrapped: any Colorable diff --git a/VDS/Protocols/Disabling.swift b/VDS/Protocols/Disabling.swift index c0be6d22..51a5bb50 100644 --- a/VDS/Protocols/Disabling.swift +++ b/VDS/Protocols/Disabling.swift @@ -7,6 +7,8 @@ import Foundation +/// Any object that can be disabled, which may change the appearance public protocol Disabling { + /// Whether this object is disabled or not var disabled: Bool { get set } } diff --git a/VDS/Protocols/Surfaceable.swift b/VDS/Protocols/Surfaceable.swift index d7889f04..b3a2dc6e 100644 --- a/VDS/Protocols/Surfaceable.swift +++ b/VDS/Protocols/Surfaceable.swift @@ -9,6 +9,7 @@ import Foundation import UIKit import VDSColorTokens +/// The background tint that the component will be placed on. This will automatically adjust other elements as needed and takes "light" or "dark" public enum Surface: String, Equatable { case light, dark public var color: UIColor { @@ -17,5 +18,6 @@ public enum Surface: String, Equatable { } public protocol Surfaceable { + /// Current Surface and this is used to pass down to child objects that implement Surfacable var surface: Surface { get set } } diff --git a/VDS/VDS.docc/VDS.md b/VDS/VDS.docc/VDS.md index 0cf1e32e..fade2c59 100755 --- a/VDS/VDS.docc/VDS.md +++ b/VDS/VDS.docc/VDS.md @@ -8,19 +8,50 @@ Using the system allows designers and developers to collaborate more easily and ## Topics -### Components +### BaseComponents +- ``ButtonBase`` +- ``Control`` +- ``View`` +- ``SelfSizingCollectionView`` +- ``SelectorBase`` +- ``SelectorItemBase`` +- ``SelectorGroupHandlerBase`` +- ``SelectorGroupSelectedHandlerBase`` +### Components - ``Badge`` +- ``BadgeIndicator`` - ``Button`` -- ``TextLink`` -- ``TextLinkCaret`` -- ``CheckboxGroup`` +- ``ButtonIcon`` +- ``ButtonGroup`` - ``Checkbox`` +- ``CheckboxItem`` +- ``CheckboxGroup`` +- ``Icon`` - ``Label`` +- ``Line`` +- ``Loader`` +- ``RadioBoxItem`` - ``RadioBoxGroup`` -- ``RadioBox`` -- ``RadioButtonGroup`` - ``RadioButton`` +- ``RadioButtonItem`` +- ``RadioButtonGroup`` - ``RadioSwatchGroup`` - ``RadioSwatch`` +- ``Tabs`` +- ``TextLink`` +- ``TextLinkCaret`` +- ``TileContainer`` +- ``Tilelet`` +- ``TitleLockup`` - ``Toggle`` +- ``Tooltip`` + +### ColorConfiguration +- ``Colorable`` +- ``AnyColorable`` +- ``SurfaceColorConfiguration`` +- ``KeyColorConfiguration`` +- ``KeyedColorConfiguration`` +- ``ControlColorConfiguration`` +- ``ViewColorConfiguration``