Merge branch 'feature/buttonGroupUpdate' into 'develop'

removed double line height

See merge request BPHV_MIPS/vds_ios!20
This commit is contained in:
Bruce, Matt R 2022-12-09 00:18:25 +00:00
commit ab1d385330
19 changed files with 482 additions and 468 deletions

View File

@ -63,6 +63,7 @@
EAB5FEF12927F4AA00998C17 /* SelfSizingCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FEF02927F4AA00998C17 /* SelfSizingCollectionView.swift */; };
EAB5FEF5292D371F00998C17 /* ButtonBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FEF4292D371F00998C17 /* ButtonBase.swift */; };
EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FEF729393A7200998C17 /* ButtonGroupConstants.swift */; };
EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FF0029424ACB00998C17 /* UIControl.swift */; };
EAC9257D29119B5400091998 /* TextLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9257C29119B5400091998 /* TextLink.swift */; };
EAC925832911B35400091998 /* TextLinkCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC925822911B35300091998 /* TextLinkCaret.swift */; };
EAC925842911C63100091998 /* Colorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEDF28F49DB3003B3210 /* Colorable.swift */; };
@ -157,6 +158,7 @@
EAB5FEF02927F4AA00998C17 /* SelfSizingCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfSizingCollectionView.swift; sourceTree = "<group>"; };
EAB5FEF4292D371F00998C17 /* ButtonBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonBase.swift; sourceTree = "<group>"; };
EAB5FEF729393A7200998C17 /* ButtonGroupConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupConstants.swift; sourceTree = "<group>"; };
EAB5FF0029424ACB00998C17 /* UIControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = "<group>"; };
EAC9257C29119B5400091998 /* TextLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLink.swift; sourceTree = "<group>"; };
EAC925822911B35300091998 /* TextLinkCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkCaret.swift; sourceTree = "<group>"; };
EAC925872911C9DE00091998 /* TextEntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; };
@ -331,6 +333,7 @@
EAF7F0B4289C126F00B287F5 /* UILabel.swift */,
EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */,
EAB5FED329267EB300998C17 /* UIView.swift */,
EAB5FF0029424ACB00998C17 /* UIControl.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -694,6 +697,7 @@
EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */,
EA336171288B19200071C351 /* VDS.docc in Sources */,
EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */,
EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */,
EAB1D2E628AE842000DAE764 /* Publisher+Bind.swift in Sources */,
EA3361AA288B25E40071C351 /* Disabling.swift in Sources */,
EA3361B6288B2A410071C351 /* Control.swift in Sources */,
@ -864,7 +868,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../SharedFrameworks";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../SharedFrameworks";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -897,7 +901,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../../SharedFrameworks";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../SharedFrameworks";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";

View File

@ -10,26 +10,106 @@ import UIKit
public typealias ObjectColorable = Colorable & Initable & ObjectWithable
public class ControlColorConfiguration: StateColorConfiguration<UIControl.State>, ObjectColorable {
public typealias ObjectType = UIControl & Surfaceable
required public override init() {}
public override func getColor(_ surface: Surface, forState state: UIControl.State) -> UIColor {
// find the exact match
if let stateColor = stateColors.first(where: {$0.state == state }) {
return stateColor.surfaceConfig.getColor(surface)
} else if state.contains(.disabled), let stateColor = stateColors.first(where: {$0.state == .disabled }) {
return stateColor.surfaceConfig.getColor(surface)
} else if state.contains(.highlighted), let stateColor = stateColors.first(where: {$0.state == .highlighted }) {
return stateColor.surfaceConfig.getColor(surface)
} else {
return .clear
}
}
public func getColor(_ object: any ObjectType) -> UIColor {
return getColor(object.surface, forState: object.state)
}
}
public class ViewColorConfiguration: StateColorConfiguration<Bool>, ObjectColorable {
public typealias ObjectType = Disabling & Surfaceable
required public override init() {}
public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forDisabled disabled: Bool) {
setSurfaceColors(lightColor, darkColor, forState: disabled)
}
public func getColor(_ object: any ObjectType) -> UIColor {
return getColor(object.surface, forState: object.disabled)
}
}
public class StateColorConfiguration<StateType: Equatable> {
struct StateColor {
var state: StateType
var surfaceConfig: SurfaceColorConfiguration
}
internal var stateColors: [StateColor] = []
public init() { }
public func getColor(_ surface: Surface, forState state: StateType) -> UIColor {
if let stateColor = stateColors.first(where: {$0.state == state }) {
return stateColor.surfaceConfig.getColor(surface)
} else {
return .clear //default
}
}
public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forState state: StateType) {
stateColors.append(.init(state: state, surfaceConfig: .init(lightColor, darkColor)))
}
public func reset() {
stateColors.removeAll()
}
}
/// Meant to be used in a Object that implements the following interfaces for 2 possible color combinations
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.surface = .light
///
/// let config = SurfaceColorConfiguration<TestModel>()
///
/// let config = SurfaceColorConfiguration()
/// config.lightColor = .black
/// config.darkColor = .white
///
/// let textColor = config.getColor(model) //returns .black
final public class SurfaceColorConfiguration: ObjectColorable {
open class SurfaceColorConfiguration: ObjectColorable {
public typealias ObjectType = Surfaceable
public var lightColor: UIColor = .clear
public var darkColor: UIColor = .clear
required public init(){}
public init(_ lightColor: UIColor, _ darkColor: UIColor) {
self.lightColor = lightColor
self.darkColor = darkColor
}
public func getColor(_ surface: Surface) -> UIColor {
return surface == .light ? lightColor : darkColor
}
public func getColor(_ object: any ObjectType) -> UIColor {
return object.surface == .light ? lightColor : darkColor
return getColor(object.surface)
}
}
@ -189,3 +269,52 @@ final public class BinaryDisabledSurfaceColorConfiguration: BinaryDisabledSurfac
getBinaryColor(object)
}
}
public class ControlStateColorConfiguration: ObjectColorable {
public typealias ObjectType = UIControl & Surfaceable
public var disabled = SurfaceColorConfiguration()
public var normal = SurfaceColorConfiguration()
public var highlighted: SurfaceColorConfiguration?
public var selected: SurfaceColorConfiguration?
public var error: SurfaceColorConfiguration?
required public init(){}
public func setColorable(_ config: SurfaceColorConfiguration, for state: UIControl.State) {
switch state {
case .disabled:
disabled = config
case .highlighted:
highlighted = config
case .selected:
selected = config
case .error:
error = config
default:
normal = config
}
}
public func getColor(_ object: any ObjectType) -> UIColor {
if object.state == .disabled {
return disabled.getColor(object)
} else if let highlighted, object.state == .highlighted {
return highlighted.getColor(object)
} else if let selected, object.state == .selected {
return selected.getColor(object)
} else if let error, object.state == .error {
return error.getColor(object)
} else {
return normal.getColor(object)
}
}
}

View File

@ -29,8 +29,24 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable {
open override var isSelected: Bool { didSet { didChange() } }
open override var isHighlighted: Bool { didSet { updateView() } }
var isHighlightAnimating = false
open override var isHighlighted: Bool {
didSet {
if isHighlightAnimating == false {
isHighlightAnimating = true
UIView.animate(withDuration: 0.1, animations: { [weak self] in
self?.updateView()
}) { [weak self] _ in
//you update the view since this is typically a quick change
UIView.animate(withDuration: 0.1, animations: { [weak self] in
self?.updateView()
self?.isHighlightAnimating = false
})
}
}
}
}
open override var isEnabled: Bool {
get { !disabled }
set {

View File

@ -102,74 +102,36 @@ public class Badge: View, Accessable {
//--------------------------------------------------
// MARK: - Configuration
//--------------------------------------------------
public func backgroundColor() -> UIColor {
var config: SurfaceColorConfiguration
switch fillColor {
case .red:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.backgroundBrandhighlight
$0.darkColor = VDSColor.backgroundBrandhighlight
}
case .yellow:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.paletteYellow62
$0.darkColor = VDSColor.paletteYellow62
}
case .green:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.paletteGreen26
$0.darkColor = VDSColor.paletteGreen34
}
case .orange:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.paletteOrange39
$0.darkColor = VDSColor.paletteOrange46
}
case .blue:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.paletteBlue35
$0.darkColor = VDSColor.paletteBlue45
}
case .black:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.paletteBlack
$0.darkColor = VDSColor.paletteBlack
}
case .white:
config = SurfaceColorConfiguration().with {
$0.lightColor = VDSColor.paletteWhite
$0.darkColor = VDSColor.paletteWhite
}
}
return config.getColor(self)
}
public func textColorConfiguration() -> AnyColorable {
private var backgroundColorConfig: StateColorConfiguration<BadgeFillColor> = {
let config = StateColorConfiguration<BadgeFillColor>()
config.setSurfaceColors(VDSColor.backgroundBrandhighlight, VDSColor.backgroundBrandhighlight, forState: .red)
config.setSurfaceColors(VDSColor.paletteYellow62, VDSColor.paletteYellow62, forState: .yellow)
config.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen34, forState: .green)
config.setSurfaceColors(VDSColor.paletteOrange39, VDSColor.paletteOrange46, forState: .orange)
config.setSurfaceColors(VDSColor.paletteBlue35, VDSColor.paletteBlue45, forState: .blue)
config.setSurfaceColors(VDSColor.paletteBlack, VDSColor.paletteBlack, forState: .black)
config.setSurfaceColors(VDSColor.paletteWhite, VDSColor.paletteWhite, forState: .white)
return config
}()
private var textColorConfig = ViewColorConfiguration()
public func updateTextColorConfig() {
textColorConfig.reset()
switch fillColor {
case .red, .black:
return DisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.elementsPrimaryOndark
$0.disabled.darkColor = VDSColor.elementsPrimaryOndark
$0.enabled.lightColor = VDSColor.elementsPrimaryOndark
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
}.eraseToAnyColorable()
textColorConfig.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: false)
textColorConfig.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forDisabled: true)
case .yellow, .white:
return DisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.disabled.darkColor = VDSColor.elementsPrimaryOnlight
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.enabled.darkColor = VDSColor.elementsPrimaryOnlight
}.eraseToAnyColorable()
textColorConfig.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: false)
textColorConfig.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOnlight, forDisabled: true)
case .orange, .green, .blue:
return DisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.elementsPrimaryOndark
$0.disabled.darkColor = VDSColor.elementsPrimaryOnlight
$0.enabled.lightColor = VDSColor.elementsPrimaryOndark
$0.enabled.darkColor = VDSColor.elementsPrimaryOnlight
}.eraseToAnyColorable()
textColorConfig.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forDisabled: false)
textColorConfig.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forDisabled: true)
}
}
@ -177,9 +139,11 @@ public class Badge: View, Accessable {
// MARK: - State
//--------------------------------------------------
open override func updateView() {
backgroundColor = backgroundColor()
updateTextColorConfig()
label.textColorConfiguration = textColorConfiguration()
backgroundColor = backgroundColorConfig.getColor(surface, forState: fillColor)
label.textColorConfiguration = textColorConfig.eraseToAnyColorable()
label.numberOfLines = numberOfLines
label.text = text
label.surface = surface

View File

@ -39,7 +39,7 @@ open class Button: ButtonBase, Useable {
open var width: CGFloat? { didSet { didChange() }}
open override var textColor: UIColor {
buttonTitleColorConfiguration.getColor(self)
textColorConfiguration.getColor(self)
}
open override var typograpicalStyle: TypographicalStyle {
@ -49,58 +49,52 @@ open class Button: ButtonBase, Useable {
//--------------------------------------------------
// MARK: - Configuration Properties
//--------------------------------------------------
private var buttonBackgroundColorConfiguration = UseableColorConfiguration().with {
$0.primary.enabled.lightColor = VDSColor.backgroundPrimaryDark
$0.primary.enabled.darkColor = VDSColor.backgroundPrimaryLight
$0.primary.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.primary.disabled.darkColor = VDSColor.interactiveDisabledOndark
// Background Color Config
private var primaryBackgroundColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
$0.primaryHighlighted.lightColor = VDSColor.interactiveActiveOnlight
$0.primaryHighlighted.darkColor = VDSColor.interactiveActiveOndark
$0.secondary.enabled.lightColor = UIColor.clear
$0.secondary.enabled.darkColor = UIColor.clear
$0.secondary.disabled.lightColor = UIColor.clear
$0.secondary.disabled.darkColor = UIColor.clear
private var secondaryBackgroundColorConfiguration = ControlColorConfiguration()
$0.secondaryHighlighted.lightColor = UIColor.clear
$0.secondaryHighlighted.darkColor = UIColor.clear
private var backgroundColorConfiguration: ControlColorConfiguration{
use == .primary ? primaryBackgroundColorConfiguration : secondaryBackgroundColorConfiguration
}
private var buttonBorderColorConfiguration = UseableColorConfiguration().with {
$0.primary.enabled.lightColor = VDSColor.elementsPrimaryOndark
$0.primary.enabled.darkColor = VDSColor.elementsPrimaryOnlight
$0.primary.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.primary.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.primaryHighlighted.lightColor = VDSColor.elementsPrimaryOndark
$0.primaryHighlighted.darkColor = VDSColor.elementsPrimaryOnlight
$0.secondary.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.secondary.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.secondary.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.secondary.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.secondaryHighlighted.lightColor = VDSColor.interactiveActiveOnlight
$0.secondaryHighlighted.darkColor = VDSColor.interactiveActiveOndark
// Border Color Config
private var primaryBorderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .normal)
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
private var buttonTitleColorConfiguration = UseableColorConfiguration().with {
$0.primary.enabled.lightColor = VDSColor.elementsPrimaryOndark
$0.primary.enabled.darkColor = VDSColor.elementsPrimaryOnlight
$0.primary.disabled.lightColor = VDSColor.elementsPrimaryOndark
$0.primary.disabled.darkColor = VDSColor.elementsPrimaryOnlight
private var secondaryBorderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
private var borderColorConfiguration: ControlColorConfiguration {
use == .primary ? primaryBorderColorConfiguration : secondaryBorderColorConfiguration
}
$0.primaryHighlighted.lightColor = VDSColor.elementsPrimaryOndark
$0.primaryHighlighted.darkColor = VDSColor.elementsPrimaryOnlight
$0.secondary.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.secondary.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.secondary.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.secondary.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.secondaryHighlighted.lightColor = VDSColor.interactiveActiveOnlight
$0.secondaryHighlighted.darkColor = VDSColor.interactiveActiveOndark
// Text Color Config
private var primaryTextColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .normal)
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .highlighted)
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .disabled)
}
private var secondaryTextColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}
private var textColorConfiguration: ControlColorConfiguration {
use == .primary ? primaryTextColorConfiguration : secondaryTextColorConfiguration
}
//--------------------------------------------------
@ -150,8 +144,8 @@ open class Button: ButtonBase, Useable {
open override func updateView() {
super.updateView()
let bgColor = buttonBackgroundColorConfiguration.getColor(self)
let borderColor = buttonBorderColorConfiguration.getColor(self)
let bgColor = backgroundColorConfiguration.getColor(self)
let borderColor = borderColorConfiguration.getColor(self)
let borderWidth = use == .secondary ? 1.0 : 0.0
let buttonHeight = size.height
let cornerRadius = size.cornerRadius
@ -183,27 +177,20 @@ open class Button: ButtonBase, Useable {
private class UseableColorConfiguration: ObjectColorable {
typealias ObjectType = Buttonable & Useable
public var primary = DisabledSurfaceColorConfiguration()
public var secondary = DisabledSurfaceColorConfiguration()
public var primaryHighlighted = SurfaceColorConfiguration()
public var secondaryHighlighted = SurfaceColorConfiguration()
public var primary = ControlStateColorConfiguration()
public var secondary = ControlStateColorConfiguration()
required public init(){}
public func getColor(_ object: ObjectType) -> UIColor {
if object.isHighlighted {
return object.use == .primary ? primaryHighlighted.getColor(object) : secondaryHighlighted.getColor(object)
} else {
return object.use == .primary ? primary.getColor(object) : secondary.getColor(object)
}
return object.use == .primary ? primary.getColor(object) : secondary.getColor(object)
}
}
}
extension ButtonSize {
fileprivate extension ButtonSize {
public var height: CGFloat {
var height: CGFloat {
switch self {
case .large:
return 44
@ -212,11 +199,11 @@ extension ButtonSize {
}
}
public var cornerRadius: CGFloat {
var cornerRadius: CGFloat {
height / 2
}
public var minimumWidth: CGFloat {
var minimumWidth: CGFloat {
switch self {
case .large:
return 76
@ -225,7 +212,7 @@ extension ButtonSize {
}
}
public var edgeInsets: UIEdgeInsets {
var edgeInsets: UIEdgeInsets {
var verticalPadding = 0.0
var horizontalPadding = 0.0
switch self {

View File

@ -43,9 +43,25 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
open var surface: Surface = .light { didSet { didChange() }}
open var disabled: Bool = false { didSet { isEnabled = !disabled } }
open override var isHighlighted: Bool { didSet { if isHighlighted != oldValue { updateView() } } }
var isHighlightAnimating = false
open override var isHighlighted: Bool {
didSet {
if isHighlightAnimating == false {
isHighlightAnimating = true
UIView.animate(withDuration: 0.1, animations: { [weak self] in
self?.updateView()
}) { [weak self] _ in
//you update the view since this is typically a quick change
UIView.animate(withDuration: 0.1, animations: { [weak self] in
self?.updateView()
self?.isHighlightAnimating = false
})
}
}
}
}
open var typograpicalStyle: TypographicalStyle { .defaultStyle }
open var textColor: UIColor { .black }
@ -129,7 +145,6 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
// MARK: - PRIVATE
//--------------------------------------------------
private func updateLabel() {
let font = typograpicalStyle.font
//clear the arrays holding actions

View File

@ -152,7 +152,6 @@ open class ButtonGroup: View, UICollectionViewDataSource, UICollectionViewDelega
button.pinLeading()
button.pinTrailing()
button.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
//cell.debugBorder()
return cell
}

View File

@ -34,18 +34,13 @@ open class TextLink: ButtonBase {
open override var textColor: UIColor {
textColorConfiguration.getColor(self)
}
private var textColorConfiguration = HighlightDisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.elementsSecondaryOnlight
$0.disabled.darkColor = VDSColor.elementsSecondaryOndark
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.highlighted.lightColor = VDSColor.interactiveActiveOnlight
$0.highlighted.darkColor = VDSColor.interactiveActiveOndark
private var textColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
}
private var height: CGFloat {
switch size {
case .large:
@ -79,7 +74,7 @@ open class TextLink: ButtonBase {
//--------------------------------------------------
open override func setup() {
super.setup()
if let titleLabel {
addSubview(line)
line.pinLeading(titleLabel.leadingAnchor)
@ -112,7 +107,6 @@ open class TextLink: ButtonBase {
//need to set the properties so the super class
//can render out the label correctly
heightConstraint?.constant = height
lineHeightConstraint?.constant = isHighlighted ? 2.0 : 1.0
line.backgroundColor = textColor
//always call last so the label is rendered
@ -120,20 +114,3 @@ open class TextLink: ButtonBase {
}
}
class HighlightDisabledSurfaceColorConfiguration: ObjectColorable {
typealias ObjectType = Buttonable
public var highlighted = SurfaceColorConfiguration()
public var disabled = SurfaceColorConfiguration()
public var enabled = SurfaceColorConfiguration()
required public init(){}
public func getColor(_ object: any ObjectType) -> UIColor {
if object.isHighlighted {
return highlighted.getColor(object)
} else {
return object.disabled ? disabled.getColor(object) : enabled.getColor(object)
}
}
}

View File

@ -65,14 +65,10 @@ open class TextLinkCaret: ButtonBase {
textColorConfiguration.getColor(self)
}
private var textColorConfiguration = HighlightDisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.elementsSecondaryOnlight
$0.disabled.darkColor = VDSColor.elementsSecondaryOndark
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.highlighted.lightColor = VDSColor.interactiveActiveOnlight
$0.highlighted.darkColor = VDSColor.interactiveActiveOndark
private var textColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
}
//--------------------------------------------------

View File

@ -124,9 +124,28 @@ open class CheckboxBase: Control, Accessable, DataTrackable, BinaryColorable, Er
didChange()
}
}
var _showError: Bool = false
open var showError: Bool {
get { _showError }
set {
if !isSelected && _showError != newValue {
_showError = newValue
didChange()
}
}
}
open var showError: Bool = false { didSet { didChange() }}
open override var state: UIControl.State {
get {
var state = super.state
if showError {
state.insert(.error)
}
return state
}
}
open var errorText: String? { didSet { didChange() }}
open var inputId: String? { didSet { didChange() }}
@ -162,18 +181,13 @@ open class CheckboxBase: Control, Accessable, DataTrackable, BinaryColorable, Er
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
open override func setup() {
super.setup()
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
addSubview(mainStackView)
mainStackView.isUserInteractionEnabled = false
mainStackView.addArrangedSubview(selectorStackView)
mainStackView.addArrangedSubview(errorLabel)
@ -313,45 +327,27 @@ open class CheckboxBase: Control, Accessable, DataTrackable, BinaryColorable, Er
//--------------------------------------------------
public let checkboxSize = CGSize(width: 20, height: 20)
private var checkboxBackgroundColorConfiguration: ErrorBinaryDisabledSurfaceColorConfiguration = {
return ErrorBinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
//error doesn't care enabled/disable
$0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight
$0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark
$0.error.forFalse.lightColor = VDSColor.feedbackErrorBackgroundOnlight
$0.error.forFalse.darkColor = VDSColor.feedbackErrorBackgroundOndark
}
}()
private var checkboxBorderColorConfiguration: ErrorBinaryDisabledSurfaceColorConfiguration = {
return ErrorBinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight
$0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
//error doesn't care enabled/disable
$0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight
$0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark
$0.error.forFalse.lightColor = VDSColor.feedbackErrorOnlight
$0.error.forFalse.darkColor = VDSColor.feedbackErrorOndark
}
}()
private var backgroundColorConfig = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: [.selected,.highlighted])
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled])
$0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: .error)
}
private var borderColorConfig = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error)
}
private var checkColorConfig = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .selected)
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: [.selected, .disabled])
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: [.selected, .highlighted])
}
private var checkboxCheckColorConfiguration: BinarySurfaceColorConfiguration = {
return BinarySurfaceColorConfiguration().with {
$0.forTrue.lightColor = VDSColor.elementsPrimaryOndark
$0.forTrue.darkColor = VDSColor.elementsPrimaryOnlight
}
}()
//--------------------------------------------------
// MARK: - Checkbox View
//--------------------------------------------------
@ -364,9 +360,9 @@ open class CheckboxBase: Control, Accessable, DataTrackable, BinaryColorable, Er
open func updateSelector() {
//get the colors
let backgroundColor = checkboxBackgroundColorConfiguration.getColor(self)
let borderColor = checkboxBorderColorConfiguration.getColor(self)
let checkColor = checkboxCheckColorConfiguration.getColor(self)
let backgroundColor = backgroundColorConfig.getColor(self)
let borderColor = borderColorConfig.getColor(self)
let checkColor = checkColorConfig.getColor(self)
if let shapeLayer = shapeLayer, let sublayers = layer.sublayers, sublayers.contains(shapeLayer) {
shapeLayer.removeFromSuperlayer()
@ -413,27 +409,3 @@ open class CheckboxBase: Control, Accessable, DataTrackable, BinaryColorable, Er
}
}
}
//--------------------------------------------------
// MARK: - Color Class Configurations
//--------------------------------------------------
internal class ErrorBinaryDisabledSurfaceColorConfiguration: BinaryDisabledSurfaceColorable {
typealias ObjectType = Errorable & Disabling & Surfaceable & BinaryColorable
var error = BinarySurfaceColorConfiguration()
var forTrue = DisabledSurfaceColorConfiguration()
var forFalse = DisabledSurfaceColorConfiguration()
required init() {}
func getColor(_ object: ObjectType) -> UIColor {
//only show error is enabled and showError == true
let showErrorColor = !object.disabled && object.showError
if showErrorColor {
return error.getColor(object)
} else {
return getBinaryColor(object)
}
}
}

View File

@ -57,11 +57,9 @@ public class Label: UILabel, Handlerable, ViewProtocol, Resettable {
//--------------------------------------------------
// MARK: - Configuration Properties
//--------------------------------------------------
public var textColorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.elementsSecondaryOnlight
$0.disabled.darkColor = VDSColor.elementsSecondaryOndark
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
public var textColorConfiguration: AnyColorable = ViewColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forDisabled: true)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
}.eraseToAnyColorable()
//--------------------------------------------------

View File

@ -160,14 +160,10 @@ open class RadioBoxBase: Control, BinaryColorable, Accessable, DataTrackable{
open override func setup() {
super.setup()
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
addSubview(selectorView)
selectorView.isUserInteractionEnabled = false
selectorView.addSubview(mainStackView)
@ -289,29 +285,19 @@ open class RadioBoxBase: Control, BinaryColorable, Accessable, DataTrackable{
private var selectorCornerRadius: CGFloat = 4.0
private var selectorBorderWidthSelected: CGFloat = 2.0
private var selectorBorderWidth: CGFloat = 1.0
private var radioBoxBackgroundColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forFalse.disabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.forTrue.enabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark
private var backgroundColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .normal)
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .disabled)
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .selected)
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .highlighted)
}
private var radioBoxBorderColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight
$0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
private var borderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .highlighted)
}
//--------------------------------------------------
@ -323,9 +309,9 @@ open class RadioBoxBase: Control, BinaryColorable, Accessable, DataTrackable{
open func updateSelector() {
//get the colors
let backgroundColor = radioBoxBackgroundColorConfiguration.getColor(self)
let borderColor = radioBoxBorderColorConfiguration.getColor(self)
let borderWidth = isSelected ? selectorBorderWidthSelected : selectorBorderWidth
let backgroundColor = backgroundColorConfiguration.getColor(self)
let borderColor = borderColorConfiguration.getColor(self)
let borderWidth = isSelected || isHighlighted ? selectorBorderWidthSelected : selectorBorderWidth
selectorView.backgroundColor = backgroundColor
selectorView.layer.borderColor = borderColor.cgColor
@ -343,7 +329,7 @@ open class RadioBoxBase: Control, BinaryColorable, Accessable, DataTrackable{
open override func draw(_ layer: CALayer, in ctx: CGContext) {
let borderColor = radioBoxBorderColorConfiguration.getColor(self)
let borderColor = borderColorConfiguration.getColor(self)
shapeLayer?.removeFromSuperlayer()
shapeLayer = nil

View File

@ -131,6 +131,16 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, BinaryColorable,
open var showError: Bool = false { didSet { didChange() }}
open override var state: UIControl.State {
get {
var state = super.state
if showError {
state.insert(.error)
}
return state
}
}
open var errorText: String? { didSet { didChange() }}
open var inputId: String? { didSet { didChange() }}
@ -170,15 +180,11 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, BinaryColorable,
open override func setup() {
super.setup()
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
addSubview(mainStackView)
mainStackView.isUserInteractionEnabled = false
mainStackView.addArrangedSubview(selectorStackView)
mainStackView.addArrangedSubview(errorLabel)
selectorStackView.addArrangedSubview(selectorView)
@ -321,38 +327,24 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, BinaryColorable,
//--------------------------------------------------
public let radioButtonSize = CGSize(width: 20, height: 20)
public let radioButtonSelectedSize = CGSize(width: 10, height: 10)
private var radioButtonBackgroundColorConfiguration = ErrorBinaryDisabledSurfaceColorConfiguration().with {
//error doesn't care enabled/disable
$0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight
$0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark
$0.error.forFalse.lightColor = VDSColor.feedbackErrorBackgroundOnlight
$0.error.forFalse.darkColor = VDSColor.feedbackErrorBackgroundOndark
private var backgroundColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: .error)
}
private var borderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .highlighted)
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.disabled])
$0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error)
}
private var radioButtonBorderColorConfiguration = ErrorBinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight
$0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
//error doesn't care enabled/disable
$0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight
$0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark
$0.error.forFalse.lightColor = VDSColor.feedbackErrorOnlight
$0.error.forFalse.darkColor = VDSColor.feedbackErrorOndark
private var checkColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled])
}
private var radioButtonCheckColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
}
//--------------------------------------------------
// MARK: - RadioButton View
//--------------------------------------------------
@ -374,9 +366,9 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, BinaryColorable,
guard length > 0.0, shapeLayer == nil else { return }
//get the colors
let backgroundColor = radioButtonBackgroundColorConfiguration.getColor(self)
let borderColor = radioButtonBorderColorConfiguration.getColor(self)
let radioSelectedColor = radioButtonCheckColorConfiguration.getColor(self)
let backgroundColor = backgroundColorConfiguration.getColor(self)
let borderColor = borderColorConfiguration.getColor(self)
let radioSelectedColor = checkColorConfiguration.getColor(self)
selectorView.backgroundColor = backgroundColor
selectorView.layer.borderColor = borderColor.cgColor

View File

@ -13,6 +13,14 @@ import Combine
@objc(VDSRadioSwatch)
public class RadioSwatch: RadioSwatchBase{
//for groups allows "toggle"
open override func toggle() {
isSelected.toggle()
}
}
@objc(VDSSoloRadioSwatch)
public class SolorRadioSwatch: RadioSwatchBase{
public override func initialSetup() {
super.initialSetup()
publisher(for: .touchUpInside)
@ -92,15 +100,10 @@ open class RadioSwatchBase: Control, Accessable, DataTrackable, BinaryColorable
open override func setup() {
super.setup()
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
addSubview(selectorView)
selectorView.isUserInteractionEnabled = false
selectorView.addSubview(fillView)
selectorView.pinToSuperView()
@ -165,33 +168,11 @@ open class RadioSwatchBase: Control, Accessable, DataTrackable, BinaryColorable
public let fillSize = CGSize(width: 36, height: 36)
public let disabledAlpha = 0.5
private var radioSwatchBackgroundColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forFalse.disabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.forTrue.enabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark
}
private var radioSwatchBorderColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight
$0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
}
private var radioSwatchFillBorderColorConfiguration = DisabledSurfaceColorConfiguration().with {
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.disabled.darkColor = VDSColor.interactiveDisabledOndark
private var borderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
}
//--------------------------------------------------
@ -213,14 +194,14 @@ open class RadioSwatchBase: Control, Accessable, DataTrackable, BinaryColorable
}
open override func draw(_ layer: CALayer, in ctx: CGContext) {
let backgroundColor = radioSwatchBackgroundColorConfiguration.getColor(self)
let borderColor = isSelected ? radioSwatchBorderColorConfiguration.getColor(self) : .clear
let fillBorderColor = radioSwatchFillBorderColorConfiguration.getColor(self)
let drawOuterBorder = isSelected || isHighlighted
let backgroundColor = UIColor.clear
let borderColor = isSelected ? borderColorConfiguration.getColor(self) : .clear
let fillBorderColor = borderColorConfiguration.getColor(self)
selectorView.backgroundColor = backgroundColor
selectorView.layer.borderColor = borderColor.cgColor
selectorView.layer.cornerRadius = selectorView.bounds.width * 0.5
selectorView.layer.borderWidth = isSelected ? selectorBorderWidth : 0
selectorView.layer.borderWidth = drawOuterBorder ? selectorBorderWidth : 0
selectorView.layer.masksToBounds = true
gradientLayer?.removeFromSuperlayer()
@ -258,7 +239,7 @@ open class RadioSwatchBase: Control, Accessable, DataTrackable, BinaryColorable
shapeLayer = nil
if strikethrough {
let strikeThroughBorderColor = radioSwatchBorderColorConfiguration.getColor(self)
let strikeThroughBorderColor = borderColorConfiguration.getColor(self)
let bounds = selectorView.bounds
let length = max(bounds.size.height, bounds.size.width)
guard length > 0.0, shapeLayer == nil else { return }

View File

@ -16,6 +16,7 @@ public class RadioSwatchGroup: RadioSwatchGroupBase<RadioSwatch> {
selectedHandler?.toggle()
selector.toggle()
label.text = selector.text
didChange()
valueChanged()
}
@ -157,7 +158,11 @@ public class RadioSwatchGroupBase<HandlerType: RadioSwatchBase>: SelectorGroupSe
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath)
let handler = selectorViews[indexPath.row]
handler.isUserInteractionEnabled = false
handler.subscribers.forEach{ $0.cancel() }
handler.subscribers.removeAll()
handler.publisher(for: .touchUpInside).sink { [weak self] handler in
self?.didSelect(selector: handler)
}.store(in: &handler.subscribers)
cell.subviews.forEach { $0.removeFromSuperview() }
cell.addSubview(handler)
handler.pinToSuperView()

View File

@ -76,28 +76,28 @@ open class EntryField: Control, Accessable {
// Sizes are from InVision design specs.
internal let containerSize = CGSize(width: 45, height: 45)
internal let primaryColorConfig = DisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
internal let primaryColorConfig = ViewColorConfiguration().with {
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
}
internal let secondaryColorConfig = DisabledSurfaceColorConfiguration().with {
$0.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.enabled.lightColor = VDSColor.elementsSecondaryOnlight
$0.enabled.darkColor = VDSColor.elementsSecondaryOndark
internal let secondaryColorConfig = ViewColorConfiguration().with {
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forDisabled: false)
}
internal var backgroundColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .normal)
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.feedbackErrorBackgroundOnlight, VDSColor.feedbackErrorBackgroundOndark, forState: .error)
}
internal var borderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOnlight, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error)
}
internal lazy var backgroundColorConfiguration: AnyColorable = {
return getBackgroundConfig()
}()
internal lazy var borderColorConfiguration: AnyColorable = {
return getBorderConfig()
}()
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
@ -107,6 +107,16 @@ open class EntryField: Control, Accessable {
open var showError: Bool = false { didSet { didChange() }}
open override var state: UIControl.State {
get {
var state = super.state
if showError {
state.insert(.error)
}
return state
}
}
open var errorText: String? { didSet { didChange() }}
open var tooltipTitle: String? { didSet { didChange() }}
@ -152,15 +162,11 @@ open class EntryField: Control, Accessable {
//--------------------------------------------------
open override func setup() {
super.setup()
//add tapGesture to self
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
self?.sendActions(for: .touchUpInside)
}.store(in: &subscribers)
isAccessibilityElement = true
accessibilityTraits = .button
addSubview(stackView)
stackView.isUserInteractionEnabled = false
//create the wrapping view
heightConstraint = containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: containerSize.height)
@ -189,32 +195,6 @@ open class EntryField: Control, Accessable {
return containerView
}
open func getBackgroundConfig() -> AnyColorable {
return ErrorDisabledSurfaceColorConfiguration().with {
$0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.enabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.disabled.darkColor = VDSFormControlsColor.backgroundOndark
//error doesn't care enabled/disable
$0.error.lightColor = VDSColor.feedbackErrorBackgroundOnlight
$0.error.darkColor = VDSColor.feedbackErrorBackgroundOndark
}.eraseToAnyColorable()
}
open func getBorderConfig() -> AnyColorable {
return ErrorDisabledSurfaceColorConfiguration().with {
$0.enabled.lightColor = VDSFormControlsColor.borderOnlight
$0.enabled.darkColor = VDSFormControlsColor.borderOnlight
$0.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.disabled.darkColor = VDSColor.interactiveDisabledOndark
//error doesn't care enabled/disable
$0.error.lightColor = VDSColor.feedbackErrorOnlight
$0.error.darkColor = VDSColor.feedbackErrorOndark
}.eraseToAnyColorable()
}
open func getToolTipView() -> UIView? {
guard let tooltipTitle, let tooltipContent else {
return nil

View File

@ -52,7 +52,37 @@ open class TextEntryFieldBase: EntryField {
open var type: TextEntryFieldType = .text { didSet { didChange() }}
open var showSuccess: Bool = false { didSet { didChange() }}
var _showError: Bool = false
open override var showError: Bool {
get { _showError }
set {
if !showSuccess && _showError != newValue {
_showError = newValue
didChange()
}
}
}
var _showSuccess: Bool = false
open var showSuccess: Bool {
get { _showSuccess }
set {
if !showError && _showSuccess != newValue {
_showSuccess = newValue
didChange()
}
}
}
open override var state: UIControl.State {
get {
var state = super.state
if showSuccess {
state.insert(.success)
}
return state
}
}
open var successText: String? { didSet { didChange() }}
@ -80,6 +110,9 @@ open class TextEntryFieldBase: EntryField {
successLabel.textColorConfiguration = primaryColorConfig.eraseToAnyColorable()
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: .success)
borderColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessOnlight, VDSColor.feedbackSuccessOndark, forState: .success)
}
public override func reset() {
@ -99,36 +132,6 @@ open class TextEntryFieldBase: EntryField {
return containerStackView
}
open override func getBackgroundConfig() -> AnyColorable {
return TextEntryFieldColorConfiguration().with {
$0.enabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.enabled.darkColor = VDSFormControlsColor.backgroundOndark
$0.disabled.lightColor = VDSFormControlsColor.backgroundOnlight
$0.disabled.darkColor = VDSFormControlsColor.backgroundOndark
//error/success doesn't care enabled/disable
$0.error.lightColor = VDSColor.feedbackErrorBackgroundOnlight
$0.error.darkColor = VDSColor.feedbackErrorBackgroundOndark
$0.success.lightColor = VDSColor.feedbackSuccessBackgroundOnlight
$0.success.darkColor = VDSColor.feedbackSuccessBackgroundOndark
}.eraseToAnyColorable()
}
open override func getBorderConfig() -> AnyColorable {
return TextEntryFieldColorConfiguration().with {
$0.enabled.lightColor = VDSFormControlsColor.borderOnlight
$0.enabled.darkColor = VDSFormControlsColor.borderOnlight
$0.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.disabled.darkColor = VDSColor.interactiveDisabledOndark
//error/success doesn't care enabled/disable
$0.error.lightColor = VDSColor.feedbackErrorOnlight
$0.error.darkColor = VDSColor.feedbackErrorOndark
$0.success.lightColor = VDSColor.feedbackSuccessOnlight
$0.success.darkColor = VDSColor.feedbackSuccessOndark
}.eraseToAnyColorable()
}
//--------------------------------------------------
// MARK: - State
//--------------------------------------------------

View File

@ -88,27 +88,17 @@ open class ToggleBase: Control, Accessable, DataTrackable, BinaryColorable {
public let toggleSize = CGSize(width: 52, height: 24)
public let toggleContainerSize = CGSize(width: 52, height: 44)
public let knobSize = CGSize(width: 20, height: 20)
private var toggleColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.paletteGreen26
$0.forTrue.enabled.darkColor = VDSColor.paletteGreen34
$0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
$0.forFalse.enabled.lightColor = VDSColor.elementsSecondaryOnlight
$0.forFalse.enabled.darkColor = VDSColor.paletteGray44
$0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
$0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
private var toggleColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.paletteGray44, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen34, forState: .selected)
}
private var knobColorConfiguration = BinaryDisabledSurfaceColorConfiguration().with {
$0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOndark
$0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forTrue.disabled.lightColor = VDSColor.paletteGray95
$0.forTrue.disabled.darkColor = VDSColor.paletteGray44
$0.forFalse.enabled.lightColor = VDSColor.elementsPrimaryOndark
$0.forFalse.enabled.darkColor = VDSColor.elementsPrimaryOndark
$0.forFalse.disabled.lightColor = VDSColor.paletteGray95
$0.forFalse.disabled.darkColor = VDSColor.paletteGray44
private var knobColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.paletteGray95, VDSColor.paletteGray44, forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forState: .selected)
}
private var typograpicalStyle: TypographicalStyle {
@ -130,7 +120,15 @@ open class ToggleBase: Control, Accessable, DataTrackable, BinaryColorable {
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
open var isOn: Bool = false { didSet { didChange() }}
open var isOn: Bool {
get { isSelected }
set {
if isSelected != newValue {
isSelected = newValue
}
didChange()
}
}
open var isAnimated: Bool = true { didSet { didChange() }}
@ -292,7 +290,6 @@ open class ToggleBase: Control, Accessable, DataTrackable, BinaryColorable {
public override func reset() {
super.reset()
label.reset()
isSelected = false
isOn = false
isAnimated = true
@ -313,7 +310,6 @@ open class ToggleBase: Control, Accessable, DataTrackable, BinaryColorable {
/// This will toggle the state of the Toggle and execute the actionBlock if provided.
open func toggle() {
isOn.toggle()
isSelected = isOn
sendActions(for: .valueChanged)
}

View File

@ -0,0 +1,14 @@
//
// UIControl.swift
// VDS
//
// Created by Matt Bruce on 12/8/22.
//
import Foundation
import UIKit
extension UIControl.State {
public static var error = UIControl.State(rawValue: 1 << 16)
public static var success = UIControl.State(rawValue: 1 << 17)
}