added code comments
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
a75e254064
commit
87ecc1e28a
@ -406,8 +406,8 @@
|
||||
EA33619D288B1E330071C351 /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EAD062AE2A3B87210015965D /* BadgeIndicator */,
|
||||
EA4DB2FE28DCBC1900103EE3 /* Badge */,
|
||||
EAD062AE2A3B87210015965D /* BadgeIndicator */,
|
||||
EA0FC2BE2912D18200DF80B4 /* Buttons */,
|
||||
EAF7F092289985E200B287F5 /* Checkbox */,
|
||||
EA985BF3296C609E00F2FF2E /* Icon */,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -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 } }
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -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,10 +53,13 @@ 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"
|
||||
@ -59,6 +67,7 @@ open class BadgeIndicator: View {
|
||||
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<BadgeIndicator, FillColor>(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
|
||||
//--------------------------------------------------
|
||||
@ -225,40 +290,6 @@ open class BadgeIndicator: View {
|
||||
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<BadgeIndicator, FillColor>(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
|
||||
}
|
||||
|
||||
@ -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<ObjectType> {
|
||||
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<ObjectType>: Colorable, Withable {
|
||||
private var wrapped: any Colorable<ObjectType>
|
||||
|
||||
public init<C: Colorable>(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
|
||||
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
@ -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``
|
||||
|
||||
Loading…
Reference in New Issue
Block a user