Merge branch 'feature/tilet' into 'develop'

refactored to use tokens instead of hardcoded values

See merge request BPHV_MIPS/vds_ios!23
This commit is contained in:
Bruce, Matt R 2023-01-06 21:31:23 +00:00
commit 2b164f9f25
19 changed files with 515 additions and 199 deletions

View File

@ -51,6 +51,13 @@
EA89201328B568D8006B9984 /* RadioBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201228B568D8006B9984 /* RadioBox.swift */; }; EA89201328B568D8006B9984 /* RadioBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201228B568D8006B9984 /* RadioBox.swift */; };
EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201428B56CF4006B9984 /* RadioBoxGroup.swift */; }; EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89201428B56CF4006B9984 /* RadioBoxGroup.swift */; };
EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA978EC4291D6AFE00ACC883 /* AnyLabelAttribute.swift */; }; EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA978EC4291D6AFE00ACC883 /* AnyLabelAttribute.swift */; };
EA985BE629688F6A00F2FF2E /* TiletBadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BE529688F6A00F2FF2E /* TiletBadgeModel.swift */; };
EA985BE82968951C00F2FF2E /* TiletTitleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BE72968951C00F2FF2E /* TiletTitleModel.swift */; };
EA985BEA29689B6D00F2FF2E /* TiletSubTitleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BE929689B6D00F2FF2E /* TiletSubTitleModel.swift */; };
EA985BEC2968A91200F2FF2E /* TitleLockupTitleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BEB2968A91200F2FF2E /* TitleLockupTitleModel.swift */; };
EA985BEE2968A92400F2FF2E /* TitleLockupSubTitleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BED2968A92400F2FF2E /* TitleLockupSubTitleModel.swift */; };
EA985BF02968A93600F2FF2E /* TitleLockupEyebrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BEF2968A93600F2FF2E /* TitleLockupEyebrowModel.swift */; };
EA985BF22968B5BB00F2FF2E /* TitleLockupTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BF12968B5BB00F2FF2E /* TitleLockupTypography.swift */; };
EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */; }; EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */; };
EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */; }; EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */; };
EAA5EEB928ECD24B003B3210 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EAA5EEB828ECD24B003B3210 /* Icons.xcassets */; }; EAA5EEB928ECD24B003B3210 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EAA5EEB828ECD24B003B3210 /* Icons.xcassets */; };
@ -151,6 +158,13 @@
EA89201228B568D8006B9984 /* RadioBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBox.swift; sourceTree = "<group>"; }; EA89201228B568D8006B9984 /* RadioBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBox.swift; sourceTree = "<group>"; };
EA89201428B56CF4006B9984 /* RadioBoxGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxGroup.swift; sourceTree = "<group>"; }; EA89201428B56CF4006B9984 /* RadioBoxGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxGroup.swift; sourceTree = "<group>"; };
EA978EC4291D6AFE00ACC883 /* AnyLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyLabelAttribute.swift; sourceTree = "<group>"; }; EA978EC4291D6AFE00ACC883 /* AnyLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyLabelAttribute.swift; sourceTree = "<group>"; };
EA985BE529688F6A00F2FF2E /* TiletBadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiletBadgeModel.swift; sourceTree = "<group>"; };
EA985BE72968951C00F2FF2E /* TiletTitleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiletTitleModel.swift; sourceTree = "<group>"; };
EA985BE929689B6D00F2FF2E /* TiletSubTitleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiletSubTitleModel.swift; sourceTree = "<group>"; };
EA985BEB2968A91200F2FF2E /* TitleLockupTitleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockupTitleModel.swift; sourceTree = "<group>"; };
EA985BED2968A92400F2FF2E /* TitleLockupSubTitleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockupSubTitleModel.swift; sourceTree = "<group>"; };
EA985BEF2968A93600F2FF2E /* TitleLockupEyebrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockupEyebrowModel.swift; sourceTree = "<group>"; };
EA985BF12968B5BB00F2FF2E /* TitleLockupTypography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockupTypography.swift; sourceTree = "<group>"; };
EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLabelAttribute.swift; sourceTree = "<group>"; }; EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLabelAttribute.swift; sourceTree = "<group>"; };
EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolTipLabelAttribute.swift; sourceTree = "<group>"; }; EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolTipLabelAttribute.swift; sourceTree = "<group>"; };
EAA5EEB828ECD24B003B3210 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = "<group>"; }; EAA5EEB828ECD24B003B3210 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = "<group>"; };
@ -457,6 +471,10 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
EA5E30522950DDA60082B959 /* TitleLockup.swift */, EA5E30522950DDA60082B959 /* TitleLockup.swift */,
EA985BEF2968A93600F2FF2E /* TitleLockupEyebrowModel.swift */,
EA985BED2968A92400F2FF2E /* TitleLockupSubTitleModel.swift */,
EA985BEB2968A91200F2FF2E /* TitleLockupTitleModel.swift */,
EA985BF12968B5BB00F2FF2E /* TitleLockupTypography.swift */,
); );
path = TitleLockup; path = TitleLockup;
sourceTree = "<group>"; sourceTree = "<group>";
@ -465,6 +483,9 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
EA5E3057295105A40082B959 /* Tilet.swift */, EA5E3057295105A40082B959 /* Tilet.swift */,
EA985BE529688F6A00F2FF2E /* TiletBadgeModel.swift */,
EA985BE929689B6D00F2FF2E /* TiletSubTitleModel.swift */,
EA985BE72968951C00F2FF2E /* TiletTitleModel.swift */,
); );
path = Tilet; path = Tilet;
sourceTree = "<group>"; sourceTree = "<group>";
@ -711,9 +732,13 @@
EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */, EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */,
EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */, EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */,
EAF7F11728A1475A00B287F5 /* RadioButton.swift in Sources */, EAF7F11728A1475A00B287F5 /* RadioButton.swift in Sources */,
EA985BEE2968A92400F2FF2E /* TitleLockupSubTitleModel.swift in Sources */,
EA985BF22968B5BB00F2FF2E /* TitleLockupTypography.swift in Sources */,
EAB1D2CD28ABE76100DAE764 /* Withable.swift in Sources */, EAB1D2CD28ABE76100DAE764 /* Withable.swift in Sources */,
EAC846F3294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift in Sources */, EAC846F3294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift in Sources */,
EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */, EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */,
EA985BE82968951C00F2FF2E /* TiletTitleModel.swift in Sources */,
EA985BEA29689B6D00F2FF2E /* TiletSubTitleModel.swift in Sources */,
EA3361C9289054C50071C351 /* Surfaceable.swift in Sources */, EA3361C9289054C50071C351 /* Surfaceable.swift in Sources */,
EAB5FEED2927E1B200998C17 /* ButtonGroupPositionLayout.swift in Sources */, EAB5FEED2927E1B200998C17 /* ButtonGroupPositionLayout.swift in Sources */,
EA4DB30228DCBCA500103EE3 /* Badge.swift in Sources */, EA4DB30228DCBCA500103EE3 /* Badge.swift in Sources */,
@ -742,7 +767,9 @@
EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */, EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */,
EAF7F0AB289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift in Sources */, EAF7F0AB289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift in Sources */,
EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */, EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */,
EA985BE629688F6A00F2FF2E /* TiletBadgeModel.swift in Sources */,
EA336171288B19200071C351 /* VDS.docc in Sources */, EA336171288B19200071C351 /* VDS.docc in Sources */,
EA985BF02968A93600F2FF2E /* TitleLockupEyebrowModel.swift in Sources */,
EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */, EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */,
EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */, EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */,
EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */, EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */,
@ -762,6 +789,7 @@
EA3361A8288B23300071C351 /* UIColor.swift in Sources */, EA3361A8288B23300071C351 /* UIColor.swift in Sources */,
EAC9257D29119B5400091998 /* TextLink.swift in Sources */, EAC9257D29119B5400091998 /* TextLink.swift in Sources */,
EA1F266628B945070033E859 /* RadioSwatchGroup.swift in Sources */, EA1F266628B945070033E859 /* RadioSwatchGroup.swift in Sources */,
EA985BEC2968A91200F2FF2E /* TitleLockupTitleModel.swift in Sources */,
5FC35BE328D51405004EBEAC /* Button.swift in Sources */, 5FC35BE328D51405004EBEAC /* Button.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -67,7 +67,7 @@ public class Badge: View, Accessable {
isAccessibilityElement = true isAccessibilityElement = true
accessibilityTraits = .staticText accessibilityTraits = .staticText
layer.cornerRadius = 2 layer.cornerRadius = VDSFormControls.borderradius
addSubview(label) addSubview(label)
label.pinToSuperView(.init(top: 2, left: 4, bottom: 2, right: 4)) label.pinToSuperView(.init(top: 2, left: 4, bottom: 2, right: 4))

View File

@ -146,7 +146,7 @@ open class Button: ButtonBase, Useable {
super.updateView() super.updateView()
let bgColor = backgroundColorConfiguration.getColor(self) let bgColor = backgroundColorConfiguration.getColor(self)
let borderColor = borderColorConfiguration.getColor(self) let borderColor = borderColorConfiguration.getColor(self)
let borderWidth = use == .secondary ? 1.0 : 0.0 let borderWidth = use == .secondary ? VDSFormControls.widthBorder : 0.0
let buttonHeight = size.height let buttonHeight = size.height
let cornerRadius = size.cornerRadius let cornerRadius = size.cornerRadius
let minWidth = size.minimumWidth let minWidth = size.minimumWidth

View File

@ -371,8 +371,8 @@ open class CheckboxBase: Control, Accessable, DataTrackable, Errorable {
selectorView.backgroundColor = backgroundColor selectorView.backgroundColor = backgroundColor
selectorView.layer.borderColor = borderColor.cgColor selectorView.layer.borderColor = borderColor.cgColor
selectorView.layer.cornerRadius = 2.0 selectorView.layer.cornerRadius = VDSFormControls.borderradius
selectorView.layer.borderWidth = 1.0 selectorView.layer.borderWidth = VDSFormControls.widthBorder
if shapeLayer == nil { if shapeLayer == nil {
let bounds = selectorView.bounds let bounds = selectorView.bounds

View File

@ -281,10 +281,10 @@ open class RadioBoxBase: Control, Accessable, DataTrackable{
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Configuration Properties // MARK: - Configuration Properties
//-------------------------------------------------- //--------------------------------------------------
private var strikeThroughLineThickness: CGFloat = 1.0 private var strikeThroughLineThickness: CGFloat = VDSFormControls.widthBorder
private var selectorCornerRadius: CGFloat = 4.0 private var selectorCornerRadius: CGFloat = VDSFormControls.borderradius
private var selectorBorderWidthSelected: CGFloat = 2.0 private var selectorBorderWidthSelected: CGFloat = VDSFormControls.widthBorder + VDSFormControls.widthBorder
private var selectorBorderWidth: CGFloat = 1.0 private var selectorBorderWidth: CGFloat = VDSFormControls.widthBorder
private var backgroundColorConfiguration = ControlColorConfiguration().with { private var backgroundColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .normal) $0.setSurfaceColors(VDSFormControlsColor.backgroundOnlight, VDSFormControlsColor.backgroundOndark, forState: .normal)
@ -311,7 +311,7 @@ open class RadioBoxBase: Control, Accessable, DataTrackable{
//get the colors //get the colors
let backgroundColor = backgroundColorConfiguration.getColor(self) let backgroundColor = backgroundColorConfiguration.getColor(self)
let borderColor = borderColorConfiguration.getColor(self) let borderColor = borderColorConfiguration.getColor(self)
let borderWidth = isSelected || isHighlighted ? selectorBorderWidthSelected : selectorBorderWidth let borderWidth = isSelected ? selectorBorderWidthSelected : selectorBorderWidth
selectorView.backgroundColor = backgroundColor selectorView.backgroundColor = backgroundColor
selectorView.layer.borderColor = borderColor.cgColor selectorView.layer.borderColor = borderColor.cgColor

View File

@ -373,7 +373,7 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, Errorable {
selectorView.backgroundColor = backgroundColor selectorView.backgroundColor = backgroundColor
selectorView.layer.borderColor = borderColor.cgColor selectorView.layer.borderColor = borderColor.cgColor
selectorView.layer.cornerRadius = selectorView.bounds.width * 0.5 selectorView.layer.cornerRadius = selectorView.bounds.width * 0.5
selectorView.layer.borderWidth = 1.0 selectorView.layer.borderWidth = VDSFormControls.widthBorder
if shapeLayer == nil { if shapeLayer == nil {
let selectedBounds = radioButtonSelectedSize let selectedBounds = radioButtonSelectedSize

View File

@ -162,8 +162,8 @@ open class RadioSwatchBase: Control, Accessable, DataTrackable {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Configuration Properties // MARK: - Configuration Properties
//-------------------------------------------------- //--------------------------------------------------
private var strikeThroughLineThickness: CGFloat = 1.0 private var strikeThroughLineThickness: CGFloat = VDSFormControls.widthBorder
private var selectorBorderWidth: CGFloat = 1.0 private var selectorBorderWidth: CGFloat = VDSFormControls.widthBorder
public let swatchSize = CGSize(width: 48, height: 48) public let swatchSize = CGSize(width: 48, height: 48)
public let fillSize = CGSize(width: 36, height: 36) public let fillSize = CGSize(width: 36, height: 36)
public let disabledAlpha = 0.5 public let disabledAlpha = 0.5

View File

@ -285,8 +285,8 @@ open class EntryField: Control, Accessable {
containerView.backgroundColor = backgroundColorConfiguration.getColor(self) containerView.backgroundColor = backgroundColorConfiguration.getColor(self)
containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor
containerView.layer.borderWidth = 1 containerView.layer.borderWidth = VDSFormControls.widthBorder
containerView.layer.cornerRadius = 4 containerView.layer.cornerRadius = VDSFormControls.borderradius
updateTitleLabel() updateTitleLabel()
updateErrorLabel() updateErrorLabel()

View File

@ -7,6 +7,7 @@
import Foundation import Foundation
import VDSColorTokens import VDSColorTokens
import VDSFormControlsTokens
import UIKit import UIKit
@objc(VDSTileContainer) @objc(VDSTileContainer)
@ -81,8 +82,10 @@ open class TileContainer: Control {
set { set {
if newValue > 100 { if newValue > 100 {
_width = newValue _width = newValue
didChange() } else {
_width = 100
} }
didChange()
} }
} }
@ -181,8 +184,8 @@ open class TileContainer: Control {
//corner radius //corner radius
layer.cornerRadius = cornerRadius layer.cornerRadius = cornerRadius
backgroundImageView.layer.cornerRadius = 8 backgroundImageView.layer.cornerRadius = cornerRadius
highlightView.layer.cornerRadius = 8 highlightView.layer.cornerRadius = cornerRadius
} }
@ -194,7 +197,7 @@ open class TileContainer: Control {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Configuration // MARK: - Configuration
//-------------------------------------------------- //--------------------------------------------------
private let cornerRadius = 8.0 private let cornerRadius = VDSFormControls.borderradius * 2
private var backgroundColorConfig = BackgroundColorConfiguration() private var backgroundColorConfig = BackgroundColorConfiguration()
@ -262,14 +265,14 @@ open class TileContainer: Control {
} }
layer.borderColor = borderColorConfig.getColor(self).cgColor layer.borderColor = borderColorConfig.getColor(self).cgColor
layer.borderWidth = showBorder ? 1 : 0 layer.borderWidth = showBorder ? VDSFormControls.widthBorder : 0
containerTopConstraint?.constant = padding containerTopConstraint?.constant = padding
containerLeadingConstraint?.constant = padding containerLeadingConstraint?.constant = padding
containerBottomConstraint?.constant = -padding containerBottomConstraint?.constant = -padding
containerTrailingConstraint?.constant = -padding containerTrailingConstraint?.constant = -padding
if aspectRatio == .none { if aspectRatio == .none && height == nil{
widthConstraint?.constant = width widthConstraint?.constant = width
heightConstraint?.isActive = false heightConstraint?.isActive = false
heightGreaterThanConstraint?.isActive = true heightGreaterThanConstraint?.isActive = true

View File

@ -10,33 +10,8 @@ import Foundation
import VDSColorTokens import VDSColorTokens
import UIKit import UIKit
public enum TiletTitleTypographicalStyle: String, Codable, EnumSubset {
case TitleXLarge
case BoldTitleXLarge
case TitleLarge
case BoldTitleLarge
case TitleMedium
case BoldTitleMedium
case TitleSmall
case BoldTitleSmall
public var defaultValue: TitleLockupTitleTypographicalStyle { .BoldTitleSmall }
}
public enum TiletOtherTypographicalStyle: String, Codable, EnumSubset {
case BodyLarge
case BoldBodyLarge
case BodyMedium
case BoldBodyMedium
case BodySmall
case BoldBodySmall
public var defaultValue: TitleLockupOtherTypographicalStyle { .BodySmall }
}
@objc(VDSTilet) @objc(VDSTilet)
open class Tilet: View { open class Tilet: TileContainer {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
@ -58,22 +33,91 @@ open class Tilet: View {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Properties // MARK: - Private Properties
//-------------------------------------------------- //--------------------------------------------------
private var tileContainer = TileContainer().with { private var stackView = UIStackView().with {
$0.aspectRatio = .none $0.translatesAutoresizingMaskIntoConstraints = false
$0.surface = .light $0.axis = .vertical
$0.distribution = .fill
$0.spacing = 5
} }
private var titleLockup = TitleLockup() private var titleLockupContainerView = UIView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
}
private var titleLockup = TitleLockup().with {
let configs = [
TypographicalStyleDeviceSpacingConfig([.TitleSmall, .BoldTitleSmall],
neighboring: [
.BodySmall, .BoldBodySmall,
.BodyMedium, .BoldBodyMedium
],
spacing: 8.0,
deviceType: .iPhone),
TypographicalStyleDeviceSpacingConfig([.TitleMedium, .BoldTitleMedium,
.TitleLarge, .BoldTitleLarge],
neighboring: [
.BodySmall, .BoldBodySmall,
.BodyMedium, .BoldBodyMedium,
.BodyLarge, .BoldBodyLarge],
spacing: 8.0,
deviceType: .iPhone),
TypographicalStyleDeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge],
neighboring: [
.BodySmall, .BoldBodySmall,
.BodyMedium, .BoldBodyMedium,
.BodyLarge, .BoldBodyLarge,
.TitleMedium, .BoldTitleMedium
],
spacing: 12.0,
deviceType: .iPhone),
TypographicalStyleDeviceSpacingConfig([.TitleSmall, .BoldTitleSmall,
.TitleMedium, .BoldTitleMedium],
neighboring: [
.BodySmall, .BoldBodySmall,
.BodyMedium, .BoldBodyMedium,
.BodyLarge, .BoldBodyLarge
],
spacing: 8.0,
deviceType: .iPad),
TypographicalStyleDeviceSpacingConfig([.TitleLarge, .BoldTitleLarge],
neighboring: [
.BodySmall, .BoldBodySmall,
.BodyMedium, .BoldBodyMedium,
.BodyLarge, .BoldBodyLarge,
.TitleSmall, .BoldTitleSmall
],
spacing: 12.0,
deviceType: .iPad),
TypographicalStyleDeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge],
neighboring: [
.BodyLarge, .BoldBodyLarge,
.TitleMedium, .BoldTitleMedium
],
spacing: 16.0,
deviceType: .iPad)
]
$0.bottomTypographicalStyleSpacingConfig = TypographicalStyleSpacingConfig(configs: configs)
}
private var badgeContainerView = UIView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
}
private var badge = Badge().with {
$0.fillColor = .red
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Public Properties // MARK: - Public Properties
//-------------------------------------------------- //--------------------------------------------------
//style //style
open var titleTypograpicalStyle: TiletTitleTypographicalStyle = .BoldTitleSmall { didSet { didChange() }}
open var otherTypograpicalStyle: TiletOtherTypographicalStyle = .BodySmall { didSet { didChange() }}
open var width: CGFloat = 100 { didSet { didChange() }}
private var _textWidth: CGFloat? private var _textWidth: CGFloat?
open var textWidth: CGFloat? { open var textWidth: CGFloat? {
get { _textWidth } get { _textWidth }
@ -107,15 +151,14 @@ open class Tilet: View {
} }
} }
//text //models
open var titleText: String = "" { didSet { didChange() }} public var badgeModel: TiletBadgeModel? { didSet { didChange() }}
open var titleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }} public var titleModel: TiletTitleModel? { didSet { didChange() }}
public var subTitleModel: TiletSubTitleModel? { didSet { didChange() }}
//icons
open var subTitleText: String = "" { didSet { didChange() }}
open var subTitleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }}
open var subTitleColor: Use = .primary { didSet { didChange() }}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Constraints // MARK: - Constraints
//-------------------------------------------------- //--------------------------------------------------
@ -128,81 +171,128 @@ open class Tilet: View {
open override func setup() { open override func setup() {
super.setup() super.setup()
addSubview(tileContainer) width = 100
tileContainer.pinToSuperView() aspectRatio = .none
tileContainer.addContentView(titleLockup, shouldPin: false) containerBackgroundColor = .black
titleLockup.pinTop()
titleLockup.pinLeading()
titleLockup.pinBottom()
//either you are 100% width of the tileContainer.contentView addContentView(stackView)
titleLockupTrailingConstraint = titleLockup.trailingAnchor.constraint(equalTo: tileContainer.containerView.trailingAnchor)
//badge
badgeContainerView.addSubview(badge)
badge
.pinTop()
.pinLeading()
.pinBottom()
badge.trailingAnchor.constraint(lessThanOrEqualTo: badgeContainerView.trailingAnchor).isActive = true
titleLockupContainerView.addSubview(titleLockup)
titleLockup
.pinTop()
.pinLeading()
.pinBottom()
titleLockupTrailingConstraint = titleLockup.trailingAnchor.constraint(equalTo: titleLockupContainerView.trailingAnchor)
titleLockupTrailingConstraint?.isActive = true titleLockupTrailingConstraint?.isActive = true
//stackView.addArrangedSubview(badgeContainerView)
//stackView.addArrangedSubview(titleLockupContainerView)
} }
public override func reset() { public override func reset() {
super.reset() super.reset()
tileContainer.reset() aspectRatio = .none
tileContainer.aspectRatio = .none surface = .light
tileContainer.surface = .light containerBackgroundColor = .black
titleLockup.reset()
titleText = "" //badge
titleTextAttributes = nil badge.reset()
subTitleText = "" badgeModel = nil
subTitleTextAttributes = nil
subTitleColor = .primary //titleLockup
titleLockup.reset()
titleModel = nil
subTitleModel = nil
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - State // MARK: - State
//-------------------------------------------------- //--------------------------------------------------
open override func updateView() { open override func updateView() {
super.updateView() super.updateView()
//flip the color
let flippedColor:TileContainer.ContainerBackgroundColor = surface == .dark ? .white : .black
tileContainer.containerBackgroundColor = flippedColor
tileContainer.width = width
//flip the surface for the titleLockup //flip the surface for the titleLockup
let flippedSurface: Surface = surface == .dark ? .light : .dark let titleLockupSurface: Surface = containerBackgroundColor == .black ? .dark : .light
titleLockup.surface = flippedSurface titleLockup.surface = titleLockupSurface
//either use textWidth //update constraints
if let textWidth {
titleLockupTrailingConstraint?.isActive = false //badge
titleLockupWidthConstraint?.isActive = false if let badgeModel {
titleLockupWidthConstraint = titleLockup.widthAnchor.constraint(equalToConstant: textWidth) if badgeContainerView.superview == nil {
titleLockupWidthConstraint?.isActive = true stackView.insertArrangedSubview(badgeContainerView, at: 0)
}
} else if let textPercentage { badge.text = badgeModel.text
titleLockupTrailingConstraint?.isActive = false badge.fillColor = badgeModel.fillColor
titleLockupWidthConstraint?.isActive = false badge.numberOfLines = badgeModel.numberOfLines
titleLockupWidthConstraint = NSLayoutConstraint(item: titleLockup, badge.surface = badgeModel.surface
attribute: .width, badge.maxWidth = badgeModel.maxWidth
relatedBy: .equal,
toItem: tileContainer.containerView,
attribute: .width,
multiplier: textPercentage / 100,
constant: 0.0)
titleLockupWidthConstraint?.isActive = true
} else { } else {
titleLockupWidthConstraint?.isActive = false badge.reset()
titleLockupTrailingConstraint?.isActive = true badgeContainerView.removeFromSuperview()
} }
titleLockup.titleText = titleText var showTitleLockup = false
titleLockup.titleTypograpicalStyle = titleTypograpicalStyle.value
titleLockup.titleTextAttributes = titleTextAttributes
titleLockup.subTitleText = subTitleText if let titleModel, !titleModel.text.isEmpty {
titleLockup.otherTypograpicalStyle = otherTypograpicalStyle.value showTitleLockup = true
titleLockup.subTitleTextAttributes = titleTextAttributes }
titleLockup.subTitleColor = subTitleColor
if let subTitleModel, !subTitleModel.text.isEmpty {
showTitleLockup = true
}
if showTitleLockup {
if titleLockupContainerView.superview == nil {
stackView.insertArrangedSubview(titleLockupContainerView, at: badgeContainerView.superview == nil ? 0 : 1)
}
//titleLockup
if let textWidth {
titleLockupTrailingConstraint?.isActive = false
titleLockupWidthConstraint?.isActive = false
titleLockupWidthConstraint = titleLockup.widthAnchor.constraint(equalToConstant: textWidth)
titleLockupWidthConstraint?.isActive = true
} else if let textPercentage {
titleLockupTrailingConstraint?.isActive = false
titleLockupWidthConstraint?.isActive = false
titleLockupWidthConstraint = NSLayoutConstraint(item: titleLockup,
attribute: .width,
relatedBy: .equal,
toItem: containerView,
attribute: .width,
multiplier: textPercentage / 100,
constant: 0.0)
titleLockupWidthConstraint?.isActive = true
} else {
titleLockupWidthConstraint?.isActive = false
titleLockupTrailingConstraint?.isActive = true
}
//set models
titleLockup.titleModel = titleModel?.toTitleLockupTitleModel()
titleLockup.subTitleModel = subTitleModel?.toTitleLockupSubTitleModel()
if let style = subTitleModel?.typographicalStyle.value {
titleLockup.otherTypograpicalStyle = style
}
} else {
titleLockupContainerView.removeFromSuperview()
}
} }
} }

View File

@ -0,0 +1,23 @@
//
// TiletBadgeModel.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public struct TiletBadgeModel {
public var text: String = ""
public var fillColor: BadgeFillColor
public var surface: Surface
public var numberOfLines: Int
public var maxWidth: CGFloat?
public init(text: String, fillColor: BadgeFillColor = .red, surface: Surface = .light, numberOfLines: Int = 0, maxWidth: CGFloat? = nil) {
self.text = text
self.fillColor = fillColor
self.surface = surface
self.numberOfLines = numberOfLines
self.maxWidth = maxWidth
}
}

View File

@ -0,0 +1,42 @@
//
// TiletSubTitleModel.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public struct TiletSubTitleModel {
public enum SubTitleTypographicalStyle: String, Codable, EnumSubset {
case BodyLarge
case BoldBodyLarge
case BodyMedium
case BoldBodyMedium
case BodySmall
case BoldBodySmall
public var defaultValue: TitleLockupOtherTypographicalStyle { .BodySmall }
}
public var text: String = ""
public var textAttributes: [any LabelAttributeModel]?
public var typographicalStyle: SubTitleTypographicalStyle
public var textColor: Use
public init(text: String,
textColor: Use = .primary,
textAttributes: [any LabelAttributeModel]? = nil,
typographicalStyle: SubTitleTypographicalStyle = .BodySmall) {
self.text = text
self.textColor = textColor
self.textAttributes = textAttributes
self.typographicalStyle = typographicalStyle
}
public func toTitleLockupSubTitleModel() -> TitleLockupSubTitleModel {
TitleLockupSubTitleModel(text: text,
textColor: textColor,
textAttributes: textAttributes)
}
}

View File

@ -0,0 +1,39 @@
//
// TiletTitleModel.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public struct TiletTitleModel {
public enum TitleTypographicalStyle: String, EnumSubset {
case TitleXLarge
case BoldTitleXLarge
case TitleLarge
case BoldTitleLarge
case TitleMedium
case BoldTitleMedium
case TitleSmall
case BoldTitleSmall
public var defaultValue: TitleLockupTitleTypographicalStyle { .BoldTitleSmall }
}
public var text: String = ""
public var textAttributes: [any LabelAttributeModel]?
public var typographicalStyle: TitleTypographicalStyle
public init(text: String,
textAttributes: [any LabelAttributeModel]? = nil,
typographicalStyle: TitleTypographicalStyle = .BoldTitleSmall) {
self.text = text
self.textAttributes = textAttributes
self.typographicalStyle = typographicalStyle
}
public func toTitleLockupTitleModel() -> TitleLockupTitleModel {
TitleLockupTitleModel(text: text, textAttributes: textAttributes, typographicalStyle: typographicalStyle.value)
}
}

View File

@ -23,40 +23,6 @@ public enum TitleLockupTextPosition: String, Codable, CaseIterable {
} }
} }
public enum TitleLockupTitleTypographicalStyle: String, Codable, EnumSubset {
case FeatureMedium
case BoldFeatureMedium
case FeatureSmall
case BoldFeatureSmall
case FeatureXSmall
case BoldFeatureXSmall
case Title2XLarge
case BoldTitle2XLarge
case TitleXLarge
case BoldTitleXLarge
case TitleLarge
case BoldTitleLarge
case TitleMedium
case BoldTitleMedium
case TitleSmall
case BoldTitleSmall
public var defaultValue: TypographicalStyle {.BoldFeatureXSmall }
}
public enum TitleLockupOtherTypographicalStyle: String, Codable, EnumSubset {
case BodyLarge
case BoldBodyLarge
case BodyMedium
case BoldBodyMedium
case BodySmall
case BoldBodySmall
public var defaultValue: TypographicalStyle {.BodyLarge }
}
@objc(VDSTitleLockup) @objc(VDSTitleLockup)
open class TitleLockup: View { open class TitleLockup: View {
@ -214,30 +180,26 @@ open class TitleLockup: View {
open var textPosition: TitleLockupTextPosition = .left { didSet { didChange() }} open var textPosition: TitleLockupTextPosition = .left { didSet { didChange() }}
//style //style
open var titleTypograpicalStyle: TitleLockupTitleTypographicalStyle = .BoldFeatureXSmall { didSet { didChange() }}
open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = UIDevice.isIPad ? .BodyLarge : .BodyMedium { didSet { didChange() }} open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = UIDevice.isIPad ? .BodyLarge : .BodyMedium { didSet { didChange() }}
//first row //first row
open var eyebrowLabel = Label().with { open var eyebrowLabel = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical) $0.setContentCompressionResistancePriority(.required, for: .vertical)
} }
open var eyebrowText: String = "" { didSet { didChange() }} open var eyebrowModel: TitleLockupEyebrowModel? { didSet { didChange() }}
open var eyebrowTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }}
//second row //second row
open var titleLabel = Label().with { open var titleLabel = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical) $0.setContentCompressionResistancePriority(.required, for: .vertical)
} }
open var titleText: String = "" { didSet { didChange() }} open var titleModel: TitleLockupTitleModel? { didSet { didChange() }}
open var titleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }}
//third row //third row
open var subTitleLabel = Label().with { open var subTitleLabel = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical) $0.setContentCompressionResistancePriority(.required, for: .vertical)
} }
open var subTitleText: String = "" { didSet { didChange() }} open var subTitleModel: TitleLockupSubTitleModel? { didSet { didChange() }}
open var subTitleTextAttributes: [any LabelAttributeModel]? { didSet { didChange() }}
open var subTitleColor: Use = .primary { didSet { didChange() }}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
@ -266,14 +228,9 @@ open class TitleLockup: View {
textPosition = .left textPosition = .left
eyebrowText = "" eyebrowModel = nil
eyebrowTextAttributes = nil titleModel = nil
titleText = "" subTitleModel = nil
titleTextAttributes = nil
subTitleText = ""
subTitleTextAttributes = nil
titleTextAttributes = nil
titleTypograpicalStyle = .BoldFeatureXSmall
otherTypograpicalStyle = .BodyLarge otherTypograpicalStyle = .BodyLarge
} }
@ -285,47 +242,66 @@ open class TitleLockup: View {
super.updateView() super.updateView()
let allLabelsTextPosition = textPosition.labelTextPosition let allLabelsTextPosition = textPosition.labelTextPosition
var eyebrowTextIsEmpty = true
var titleTextIsEmpty = true
var subTitleTextIsEmpty = true
eyebrowLabel.textPosition = allLabelsTextPosition if let eyebrowModel, !eyebrowModel.text.isEmpty {
eyebrowLabel.typograpicalStyle = otherTypograpicalStyle.value eyebrowTextIsEmpty = false
eyebrowLabel.text = eyebrowText eyebrowLabel.textPosition = allLabelsTextPosition
eyebrowLabel.attributes = eyebrowTextAttributes eyebrowLabel.typograpicalStyle = otherTypograpicalStyle.value
eyebrowLabel.surface = surface eyebrowLabel.text = eyebrowModel.text
eyebrowLabel.attributes = eyebrowModel.textAttributes
titleLabel.textPosition = allLabelsTextPosition eyebrowLabel.numberOfLines = eyebrowModel.numberOfLines
titleLabel.typograpicalStyle = titleTypograpicalStyle.value eyebrowLabel.surface = surface
titleLabel.text = titleText } else {
titleLabel.attributes = titleTextAttributes eyebrowLabel.reset()
titleLabel.surface = surface }
subTitleLabel.textPosition = allLabelsTextPosition
subTitleLabel.typograpicalStyle = otherTypograpicalStyle.value
subTitleLabel.text = subTitleText
subTitleLabel.attributes = subTitleTextAttributes
subTitleLabel.surface = surface
subTitleLabel.disabled = subTitleColor == .secondary
if let titleModel, !titleModel.text.isEmpty {
titleTextIsEmpty = false
titleLabel.textPosition = allLabelsTextPosition
titleLabel.typograpicalStyle = titleModel.typographicalStyle.value
titleLabel.text = titleModel.text
titleLabel.attributes = titleModel.textAttributes
titleLabel.numberOfLines = titleModel.numberOfLines
titleLabel.surface = surface
} else {
titleLabel.reset()
}
if let subTitleModel, !subTitleModel.text.isEmpty {
subTitleTextIsEmpty = false
subTitleLabel.textPosition = allLabelsTextPosition
subTitleLabel.typograpicalStyle = otherTypograpicalStyle.value
subTitleLabel.text = subTitleModel.text
subTitleLabel.attributes = subTitleModel.textAttributes
subTitleLabel.numberOfLines = subTitleModel.numberOfLines
subTitleLabel.surface = surface
subTitleLabel.disabled = subTitleModel.textColor == .secondary
} else {
subTitleLabel.reset()
}
//if both first 2 rows not empty set spacing //if both first 2 rows not empty set spacing
if !eyebrowText.isEmpty && !titleText.isEmpty { if let eyebrowModel, let titleModel, !eyebrowModel.text.isEmpty, !titleModel.text.isEmpty {
stackView.spacing = getTopSpacing() stackView.spacing = topTypographicalStyleSpacingConfig.spacing(for: titleModel.typographicalStyle.value, neighboring: otherTypograpicalStyle.value)
} else { } else {
stackView.spacing = 0.0 stackView.spacing = 0.0
} }
//if either first 2 rows not empty and subtile not empty, create space else collapse //if either first 2 rows not empty and subtile not empty, create space else collapse
if (!eyebrowText.isEmpty || !titleText.isEmpty) && !subTitleText.isEmpty { if let titleModel, (!eyebrowTextIsEmpty || !titleTextIsEmpty) && !subTitleTextIsEmpty {
stackView.setCustomSpacing(getBottomSpacing(), after: titleLabel) let bottomSpace = bottomTypographicalStyleSpacingConfig.spacing(for: titleModel.typographicalStyle.value, neighboring: otherTypograpicalStyle.value)
} else if (!eyebrowText.isEmpty || !titleText.isEmpty) && subTitleText.isEmpty { stackView.setCustomSpacing(bottomSpace, after: titleLabel)
} else if (!eyebrowTextIsEmpty || !titleTextIsEmpty) && subTitleTextIsEmpty {
stackView.setCustomSpacing(0.0, after: titleLabel) stackView.setCustomSpacing(0.0, after: titleLabel)
} }
}
open func getTopSpacing() -> CGFloat { //hide/show
topTypographicalStyleSpacingConfig.spacing(for: titleTypograpicalStyle.value, neighboring: otherTypograpicalStyle.value) eyebrowLabel.isHidden = eyebrowTextIsEmpty
} titleLabel.isHidden = titleTextIsEmpty
subTitleLabel.isHidden = subTitleTextIsEmpty
open func getBottomSpacing() -> CGFloat {
bottomTypographicalStyleSpacingConfig.spacing(for: titleTypograpicalStyle.value, neighboring: otherTypograpicalStyle.value)
} }
} }

View File

@ -0,0 +1,22 @@
//
// TitleLockupEyebrowModel.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public struct TitleLockupEyebrowModel {
public var text: String
public var textAttributes: [any LabelAttributeModel]?
public var numberOfLines: Int
public init(text: String,
textAttributes: [any LabelAttributeModel]? = nil,
numberOfLines: Int = 0) {
self.text = text
self.textAttributes = textAttributes
self.numberOfLines = numberOfLines
}
}

View File

@ -0,0 +1,25 @@
//
// TitleLockupSubTitleModel.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public struct TitleLockupSubTitleModel {
public var text: String
public var textColor: Use
public var textAttributes: [any LabelAttributeModel]?
public var numberOfLines: Int
public init(text: String,
textColor: Use = .primary,
textAttributes: [any LabelAttributeModel]? = nil,
numberOfLines: Int = 0) {
self.text = text
self.textColor = textColor
self.textAttributes = textAttributes
self.numberOfLines = numberOfLines
}
}

View File

@ -0,0 +1,25 @@
//
// TitleLockupTitleModel.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public struct TitleLockupTitleModel {
public var text: String
public var textAttributes: [any LabelAttributeModel]?
public var typographicalStyle: TitleLockupTitleTypographicalStyle
public var numberOfLines: Int
public init(text: String,
textAttributes: [any LabelAttributeModel]? = nil,
typographicalStyle: TitleLockupTitleTypographicalStyle = .BoldFeatureXSmall,
numberOfLines: Int = 0) {
self.text = text
self.textAttributes = textAttributes
self.typographicalStyle = typographicalStyle
self.numberOfLines = numberOfLines
}
}

View File

@ -0,0 +1,42 @@
//
// TitleLockupTypography.swift
// VDS
//
// Created by Matt Bruce on 1/6/23.
//
import Foundation
public enum TitleLockupTitleTypographicalStyle: String, Codable, EnumSubset {
case FeatureMedium
case BoldFeatureMedium
case FeatureSmall
case BoldFeatureSmall
case FeatureXSmall
case BoldFeatureXSmall
case Title2XLarge
case BoldTitle2XLarge
case TitleXLarge
case BoldTitleXLarge
case TitleLarge
case BoldTitleLarge
case TitleMedium
case BoldTitleMedium
case TitleSmall
case BoldTitleSmall
public var defaultValue: TypographicalStyle {.BoldFeatureXSmall }
}
public enum TitleLockupOtherTypographicalStyle: String, Codable, EnumSubset {
case BodyLarge
case BoldBodyLarge
case BodyMedium
case BoldBodyMedium
case BodySmall
case BoldBodySmall
public var defaultValue: TypographicalStyle {.BodyLarge }
}

View File

@ -7,6 +7,7 @@
import Foundation import Foundation
import UIKit import UIKit
import VDSFormControlsTokens
extension UIView { extension UIView {
public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) { public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) {
@ -122,7 +123,7 @@ extension UIView {
public func debugBorder(show shouldShow: Bool = true, color: UIColor = .red) { public func debugBorder(show shouldShow: Bool = true, color: UIColor = .red) {
if shouldShow { if shouldShow {
layer.borderColor = color.cgColor layer.borderColor = color.cgColor
layer.borderWidth = 1 layer.borderWidth = VDSFormControls.widthBorder
} else { } else {
layer.borderColor = UIColor.clear.cgColor layer.borderColor = UIColor.clear.cgColor
layer.borderWidth = 0 layer.borderWidth = 0