Merge branch 'feature/tilet' into 'develop'
refactored naming convention See merge request BPHV_MIPS/vds_ios!30
This commit is contained in:
commit
0af8093ca1
@ -57,7 +57,7 @@
|
||||
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 */; };
|
||||
EA985BF22968B5BB00F2FF2E /* TitleLockupTextStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BF12968B5BB00F2FF2E /* TitleLockupTextStyle.swift */; };
|
||||
EA985BF5296C60C000F2FF2E /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BF4296C60C000F2FF2E /* Icon.swift */; };
|
||||
EA985BF7296C665E00F2FF2E /* IconName.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BF6296C665E00F2FF2E /* IconName.swift */; };
|
||||
EA985BF9296C710100F2FF2E /* IconColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985BF8296C710100F2FF2E /* IconColor.swift */; };
|
||||
@ -65,6 +65,7 @@
|
||||
EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C22296E033A00F2FF2E /* TextArea.swift */; };
|
||||
EA985C2D296F03FE00F2FF2E /* TiletIconModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C2C296F03FE00F2FF2E /* TiletIconModels.swift */; };
|
||||
EA985C672970C21600F2FF2E /* VDSLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C662970C21600F2FF2E /* VDSLayout.swift */; };
|
||||
EA985C692971B90B00F2FF2E /* IconSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C682971B90B00F2FF2E /* IconSize.swift */; };
|
||||
EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */; };
|
||||
EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */; };
|
||||
EAA5EEB928ECD24B003B3210 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EAA5EEB828ECD24B003B3210 /* Icons.xcassets */; };
|
||||
@ -97,7 +98,7 @@
|
||||
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0A1289AFB3900B287F5 /* Errorable.swift */; };
|
||||
EAF7F0A4289B017C00B287F5 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0A3289B017C00B287F5 /* LabelAttributeModel.swift */; };
|
||||
EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0A5289B0CE000B287F5 /* Resetable.swift */; };
|
||||
EAF7F0AB289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AA289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift */; };
|
||||
EAF7F0AB289B13FD00B287F5 /* TextStyleLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AA289B13FD00B287F5 /* TextStyleLabelAttribute.swift */; };
|
||||
EAF7F0AD289B142900B287F5 /* StrikeThroughLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */; };
|
||||
EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0AE289B144C00B287F5 /* UnderlineLabelAttribute.swift */; };
|
||||
EAF7F0B1289B177F00B287F5 /* ColorLabelAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */; };
|
||||
@ -171,7 +172,7 @@
|
||||
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>"; };
|
||||
EA985BF12968B5BB00F2FF2E /* TitleLockupTextStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockupTextStyle.swift; sourceTree = "<group>"; };
|
||||
EA985BF4296C60C000F2FF2E /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = "<group>"; };
|
||||
EA985BF6296C665E00F2FF2E /* IconName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconName.swift; sourceTree = "<group>"; };
|
||||
EA985BF8296C710100F2FF2E /* IconColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconColor.swift; sourceTree = "<group>"; };
|
||||
@ -179,6 +180,7 @@
|
||||
EA985C22296E033A00F2FF2E /* TextArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextArea.swift; sourceTree = "<group>"; };
|
||||
EA985C2C296F03FE00F2FF2E /* TiletIconModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiletIconModels.swift; sourceTree = "<group>"; };
|
||||
EA985C662970C21600F2FF2E /* VDSLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSLayout.swift; sourceTree = "<group>"; };
|
||||
EA985C682971B90B00F2FF2E /* IconSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconSize.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>"; };
|
||||
EAA5EEB828ECD24B003B3210 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = "<group>"; };
|
||||
@ -211,7 +213,7 @@
|
||||
EAF7F0A1289AFB3900B287F5 /* Errorable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errorable.swift; sourceTree = "<group>"; };
|
||||
EAF7F0A3289B017C00B287F5 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = "<group>"; };
|
||||
EAF7F0A5289B0CE000B287F5 /* Resetable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Resetable.swift; sourceTree = "<group>"; };
|
||||
EAF7F0AA289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypographicalStyleLabelAttribute.swift; sourceTree = "<group>"; };
|
||||
EAF7F0AA289B13FD00B287F5 /* TextStyleLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextStyleLabelAttribute.swift; sourceTree = "<group>"; };
|
||||
EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StrikeThroughLabelAttribute.swift; sourceTree = "<group>"; };
|
||||
EAF7F0AE289B144C00B287F5 /* UnderlineLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderlineLabelAttribute.swift; sourceTree = "<group>"; };
|
||||
EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorLabelAttribute.swift; sourceTree = "<group>"; };
|
||||
@ -491,7 +493,7 @@
|
||||
EA985BEF2968A93600F2FF2E /* TitleLockupEyebrowModel.swift */,
|
||||
EA985BED2968A92400F2FF2E /* TitleLockupSubTitleModel.swift */,
|
||||
EA985BEB2968A91200F2FF2E /* TitleLockupTitleModel.swift */,
|
||||
EA985BF12968B5BB00F2FF2E /* TitleLockupTypography.swift */,
|
||||
EA985BF12968B5BB00F2FF2E /* TitleLockupTextStyle.swift */,
|
||||
);
|
||||
path = TitleLockup;
|
||||
sourceTree = "<group>";
|
||||
@ -523,6 +525,7 @@
|
||||
EA985BF4296C60C000F2FF2E /* Icon.swift */,
|
||||
EA985BF8296C710100F2FF2E /* IconColor.swift */,
|
||||
EA985BF6296C665E00F2FF2E /* IconName.swift */,
|
||||
EA985C682971B90B00F2FF2E /* IconSize.swift */,
|
||||
);
|
||||
path = Icon;
|
||||
sourceTree = "<group>";
|
||||
@ -614,7 +617,7 @@
|
||||
EA978EC4291D6AFE00ACC883 /* AnyLabelAttribute.swift */,
|
||||
EAF7F13228A2A16500B287F5 /* AttachmentLabelAttributeModel.swift */,
|
||||
EAF7F0B0289B177F00B287F5 /* ColorLabelAttribute.swift */,
|
||||
EAF7F0AA289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift */,
|
||||
EAF7F0AA289B13FD00B287F5 /* TextStyleLabelAttribute.swift */,
|
||||
EAA5EEB428ECBFB4003B3210 /* ImageLabelAttribute.swift */,
|
||||
EAF7F0AC289B142900B287F5 /* StrikeThroughLabelAttribute.swift */,
|
||||
EAA5EEB628ECC03A003B3210 /* ToolTipLabelAttribute.swift */,
|
||||
@ -773,7 +776,7 @@
|
||||
EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */,
|
||||
EAF7F11728A1475A00B287F5 /* RadioButton.swift in Sources */,
|
||||
EA985BEE2968A92400F2FF2E /* TitleLockupSubTitleModel.swift in Sources */,
|
||||
EA985BF22968B5BB00F2FF2E /* TitleLockupTypography.swift in Sources */,
|
||||
EA985BF22968B5BB00F2FF2E /* TitleLockupTextStyle.swift in Sources */,
|
||||
EAB1D2CD28ABE76100DAE764 /* Withable.swift in Sources */,
|
||||
EAC846F3294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift in Sources */,
|
||||
EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */,
|
||||
@ -806,7 +809,7 @@
|
||||
EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */,
|
||||
EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */,
|
||||
EA89200228AECF2A006B9984 /* UIButton+Publisher.swift in Sources */,
|
||||
EAF7F0AB289B13FD00B287F5 /* TypographicalStyleLabelAttribute.swift in Sources */,
|
||||
EAF7F0AB289B13FD00B287F5 /* TextStyleLabelAttribute.swift in Sources */,
|
||||
EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */,
|
||||
EA985BE629688F6A00F2FF2E /* TiletBadgeModel.swift in Sources */,
|
||||
EA336171288B19200071C351 /* VDS.docc in Sources */,
|
||||
@ -824,6 +827,7 @@
|
||||
EAB5FED429267EB300998C17 /* UIView.swift in Sources */,
|
||||
EA3361AD288B26190071C351 /* DataTrackable.swift in Sources */,
|
||||
EA33623E2892EE950071C351 /* UIDevice.swift in Sources */,
|
||||
EA985C692971B90B00F2FF2E /* IconSize.swift in Sources */,
|
||||
EA985C672970C21600F2FF2E /* VDSLayout.swift in Sources */,
|
||||
EA3362302891EB4A0071C351 /* Fonts.swift in Sources */,
|
||||
EAF7F0AD289B142900B287F5 /* StrikeThroughLabelAttribute.swift in Sources */,
|
||||
|
||||
@ -11,27 +11,31 @@ import VDSColorTokens
|
||||
import VDSFormControlsTokens
|
||||
import Combine
|
||||
|
||||
public enum BadgeFillColor: String, Codable, CaseIterable {
|
||||
case red, yellow, green, orange, blue, black, white
|
||||
}
|
||||
|
||||
|
||||
/// Badges are visual labels used to convey status or highlight supplemental information.
|
||||
@objc(VDSBadge)
|
||||
public class Badge: View, Accessable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum FillColor: String, Codable, CaseIterable {
|
||||
case red, yellow, green, orange, blue, black, white
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
private var label = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.adjustsFontSizeToFitWidth = false
|
||||
$0.lineBreakMode = .byTruncatingTail
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BoldBodySmall
|
||||
$0.textStyle = .BoldBodySmall
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
open var fillColor: BadgeFillColor = .red { didSet { didChange() }}
|
||||
open var fillColor: FillColor = .red { didSet { didChange() }}
|
||||
|
||||
open var text: String = "" { didSet { didChange() }}
|
||||
|
||||
@ -57,11 +61,10 @@ public class Badge: View, Accessable {
|
||||
private var maxWidthConstraint: NSLayoutConstraint?
|
||||
private var minWidthConstraint: NSLayoutConstraint?
|
||||
|
||||
//functions
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
|
||||
open override func setup() {
|
||||
super.setup()
|
||||
|
||||
@ -83,7 +86,7 @@ public class Badge: View, Accessable {
|
||||
label.reset()
|
||||
label.lineBreakMode = .byTruncatingTail
|
||||
label.textPosition = .left
|
||||
label.typograpicalStyle = .BoldBodySmall
|
||||
label.textStyle = .BoldBodySmall
|
||||
|
||||
fillColor = .red
|
||||
text = ""
|
||||
@ -102,8 +105,8 @@ public class Badge: View, Accessable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Configuration
|
||||
//--------------------------------------------------
|
||||
private var backgroundColorConfig: StateColorConfiguration<BadgeFillColor> = {
|
||||
let config = StateColorConfiguration<BadgeFillColor>()
|
||||
private var backgroundColorConfig: StateColorConfiguration<FillColor> = {
|
||||
let config = StateColorConfiguration<FillColor>()
|
||||
config.setSurfaceColors(VDSColor.backgroundBrandhighlight, VDSColor.backgroundBrandhighlight, forState: .red)
|
||||
config.setSurfaceColors(VDSColor.paletteYellow62, VDSColor.paletteYellow62, forState: .yellow)
|
||||
config.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen34, forState: .green)
|
||||
|
||||
@ -42,8 +42,8 @@ open class Button: ButtonBase, Useable {
|
||||
textColorConfiguration.getColor(self)
|
||||
}
|
||||
|
||||
open override var typograpicalStyle: TypographicalStyle {
|
||||
size == .large ? TypographicalStyle.BoldBodyLarge : TypographicalStyle.BoldBodySmall
|
||||
open override var textStyle: TextStyle {
|
||||
size == .large ? TextStyle.BoldBodyLarge : TextStyle.BoldBodySmall
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -66,7 +66,7 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
||||
}
|
||||
}
|
||||
|
||||
open var typograpicalStyle: TypographicalStyle { .defaultStyle }
|
||||
open var textStyle: TextStyle { .defaultStyle }
|
||||
|
||||
open var textColor: UIColor { .black }
|
||||
|
||||
@ -149,7 +149,7 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
||||
// MARK: - PRIVATE
|
||||
//--------------------------------------------------
|
||||
private func updateLabel() {
|
||||
let font = typograpicalStyle.font
|
||||
let font = textStyle.font
|
||||
|
||||
//clear the arrays holding actions
|
||||
accessibilityCustomActions = []
|
||||
@ -163,8 +163,8 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
||||
let entireRange = NSRange(location: 0, length: mutableText.length)
|
||||
|
||||
//set letterSpacing
|
||||
if typograpicalStyle.letterSpacing > 0.0 {
|
||||
mutableText.addAttribute(.kern, value: typograpicalStyle.letterSpacing, range: entireRange)
|
||||
if textStyle.letterSpacing > 0.0 {
|
||||
mutableText.addAttribute(.kern, value: textStyle.letterSpacing, range: entireRange)
|
||||
}
|
||||
|
||||
let paragraph = NSMutableParagraphStyle().with {
|
||||
@ -173,8 +173,8 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
||||
}
|
||||
|
||||
//set lineHeight
|
||||
if typograpicalStyle.lineHeight > 0.0 {
|
||||
let lineHeight = typograpicalStyle.lineHeight
|
||||
if textStyle.lineHeight > 0.0 {
|
||||
let lineHeight = textStyle.lineHeight
|
||||
let adjustment = lineHeight > font.lineHeight ? 2.0 : 1.0
|
||||
let baselineOffset = (lineHeight - font.lineHeight) / 2.0 / adjustment
|
||||
paragraph.maximumLineHeight = lineHeight
|
||||
|
||||
@ -13,9 +13,16 @@ import Combine
|
||||
|
||||
@objc(VDSButtonGroup)
|
||||
open class ButtonGroup: View, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, ButtongGroupPositionLayoutDelegate {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum ButtonPosition: String, CaseIterable {
|
||||
case left, center, right
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
//An object containing number of Button components per row, in each viewport
|
||||
open var rowQuantityPhone: Int = 0 { didSet { didChange() } }
|
||||
|
||||
@ -47,7 +47,7 @@ class ButtonCollectionViewRow {
|
||||
}
|
||||
}
|
||||
|
||||
func layout(for position: ButtonPosition, with collectionViewWidth: CGFloat){
|
||||
func layout(for position: ButtonGroup.ButtonPosition, with collectionViewWidth: CGFloat){
|
||||
var offset = 0.0
|
||||
let height = rowHeight
|
||||
attributes.last?.spacing = 0
|
||||
@ -120,10 +120,6 @@ class ButtonCollectionViewRow {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ButtonPosition: String, CaseIterable {
|
||||
case left, center, right
|
||||
}
|
||||
|
||||
protocol ButtongGroupPositionLayoutDelegate: AnyObject {
|
||||
func collectionView(_ collectionView: UICollectionView, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize
|
||||
func collectionView(_ collectionView: UICollectionView, buttonableAtIndexPath indexPath: IndexPath) -> any Buttonable
|
||||
@ -154,7 +150,7 @@ class ButtonGroupPositionLayout: UICollectionViewLayout {
|
||||
|
||||
// Total height of the content. Will be used to configure the scrollview content
|
||||
var layoutHeight: CGFloat = 0.0
|
||||
var position: ButtonPosition = .left
|
||||
var position: ButtonGroup.ButtonPosition = .left
|
||||
var rowQuantity: Int = 0
|
||||
var buttonPercentage: CGFloat?
|
||||
|
||||
|
||||
@ -26,8 +26,8 @@ open class TextLink: ButtonBase {
|
||||
|
||||
open override var availableSizes: [ButtonSize] { [.large, .small] }
|
||||
|
||||
open override var typograpicalStyle: TypographicalStyle {
|
||||
size == .large ? TypographicalStyle.BodyLarge : TypographicalStyle.BodySmall
|
||||
open override var textStyle: TextStyle {
|
||||
size == .large ? TextStyle.BodyLarge : TextStyle.BodySmall
|
||||
}
|
||||
|
||||
open override var textColor: UIColor {
|
||||
|
||||
@ -11,22 +11,25 @@ import VDSColorTokens
|
||||
import VDSFormControlsTokens
|
||||
import Combine
|
||||
|
||||
public enum TextLinkCaretPosition: String, CaseIterable {
|
||||
case left, right
|
||||
}
|
||||
|
||||
@objc(VDSTextLinkCaret)
|
||||
open class TextLinkCaret: ButtonBase {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum IconPosition: String, CaseIterable {
|
||||
case left, right
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
open override var typograpicalStyle: TypographicalStyle {
|
||||
TypographicalStyle.BoldBodyLarge
|
||||
open override var textStyle: TextStyle {
|
||||
TextStyle.BoldBodyLarge
|
||||
}
|
||||
|
||||
private var caretView = CaretView().with {
|
||||
$0.size = CaretView.CaretSize.small(.vertical)
|
||||
$0.size = CaretView.Size.small(.vertical)
|
||||
$0.lineWidth = 2
|
||||
}
|
||||
private var imageAttribute: ImageLabelAttribute?
|
||||
@ -41,7 +44,7 @@ open class TextLinkCaret: ButtonBase {
|
||||
//--------------------------------------------------
|
||||
public override var availableSizes: [ButtonSize] { [.large] }
|
||||
|
||||
open var iconPosition: TextLinkCaretPosition = .right { didSet { didChange() } }
|
||||
open var iconPosition: IconPosition = .right { didSet { didChange() } }
|
||||
|
||||
private var height: CGFloat {
|
||||
44
|
||||
@ -153,7 +156,7 @@ internal class CaretView: View {
|
||||
|
||||
public var direction: Direction = .right { didSet{ didChange() } }
|
||||
|
||||
public var size: CaretSize? { didSet{ didChange() } }
|
||||
public var size: Size? { didSet{ didChange() } }
|
||||
|
||||
public var colorConfiguration: AnyColorable = ViewColorConfiguration().with {
|
||||
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forDisabled: true)
|
||||
@ -166,7 +169,7 @@ internal class CaretView: View {
|
||||
//------------------------------------------------------
|
||||
|
||||
/// Sizes of CaretView are derived from InVision design specs. They are provided for convenience.
|
||||
public enum CaretSize {
|
||||
public enum Size {
|
||||
case small(Orientation)
|
||||
case medium(Orientation)
|
||||
case large(Orientation)
|
||||
@ -215,7 +218,7 @@ internal class CaretView: View {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public convenience init(size: CaretSize){
|
||||
public convenience init(size: Size){
|
||||
let dimensions = size.dimensions()
|
||||
self.init(frame: .init(x: 0, y: 0, width: dimensions.width, height: dimensions.height))
|
||||
self.size = size
|
||||
|
||||
@ -76,19 +76,19 @@ open class CheckboxBase: Control, Accessable, DataTrackable, Errorable {
|
||||
private var label = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BoldBodyLarge
|
||||
$0.textStyle = .BoldBodyLarge
|
||||
}
|
||||
|
||||
private var childLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodyLarge
|
||||
$0.textStyle = .BodyLarge
|
||||
}
|
||||
|
||||
private var errorLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodyMedium
|
||||
$0.textStyle = .BodyMedium
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -272,9 +272,9 @@ open class CheckboxBase: Control, Accessable, DataTrackable, Errorable {
|
||||
childLabel.reset()
|
||||
errorLabel.reset()
|
||||
|
||||
label.typograpicalStyle = .BoldBodyLarge
|
||||
childLabel.typograpicalStyle = .BodyLarge
|
||||
errorLabel.typograpicalStyle = .BodyMedium
|
||||
label.textStyle = .BoldBodyLarge
|
||||
childLabel.textStyle = .BodyLarge
|
||||
errorLabel.textStyle = .BodyMedium
|
||||
|
||||
labelText = nil
|
||||
labelTextAttributes = nil
|
||||
|
||||
@ -10,35 +10,6 @@ import UIKit
|
||||
import VDSColorTokens
|
||||
import Combine
|
||||
|
||||
public enum IconSize: String, CaseIterable, Codable {
|
||||
case xsmall
|
||||
case small
|
||||
case medium
|
||||
case large
|
||||
case XLarge
|
||||
|
||||
public var dimensions: CGSize {
|
||||
switch self {
|
||||
|
||||
case .xsmall:
|
||||
return .init(width: 12, height: 12)
|
||||
|
||||
case .small:
|
||||
return .init(width: 16, height: 16)
|
||||
|
||||
case .medium:
|
||||
return .init(width: 20, height: 20)
|
||||
|
||||
case .large:
|
||||
return .init(width: 24, height: 24)
|
||||
|
||||
case .XLarge:
|
||||
return .init(width: 28, height: 28)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(VDSIcon)
|
||||
public class Icon: View {
|
||||
|
||||
@ -57,9 +28,9 @@ public class Icon: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
open var color: IconColor = .black { didSet { didChange() }}
|
||||
open var size: IconSize = .medium { didSet { didChange() }}
|
||||
open var name: IconName? { didSet { didChange() }}
|
||||
open var color: Color = .black { didSet { didChange() }}
|
||||
open var size: Size = .medium { didSet { didChange() }}
|
||||
open var name: Name? { didSet { didChange() }}
|
||||
|
||||
//functions
|
||||
//--------------------------------------------------
|
||||
@ -95,9 +66,9 @@ public class Icon: View {
|
||||
var imageColor = color.value
|
||||
|
||||
//ensure the correct color for white/black colors
|
||||
if surface == .dark && color == IconColor.black {
|
||||
if surface == .dark && color == Color.black {
|
||||
imageColor = VDSColor.elementsPrimaryOndark
|
||||
} else if surface == .light && color == IconColor.black {
|
||||
} else if surface == .light && color == Color.black {
|
||||
imageColor = VDSColor.elementsPrimaryOnlight
|
||||
}
|
||||
|
||||
|
||||
@ -9,82 +9,84 @@ import Foundation
|
||||
import VDSColorTokens
|
||||
import UIKit
|
||||
|
||||
public enum IconColor: String, CaseIterable {
|
||||
case black
|
||||
case white
|
||||
case red
|
||||
case gray95
|
||||
case gray85
|
||||
case gray65
|
||||
case gray44
|
||||
case gray20
|
||||
case gray11
|
||||
case orange91
|
||||
case orange46
|
||||
case orange39
|
||||
case orange15
|
||||
case yellow94
|
||||
case yellow62
|
||||
case yellow20
|
||||
case blue91
|
||||
case blue45
|
||||
case blue35
|
||||
case blue13
|
||||
case green89
|
||||
case green34
|
||||
case green26
|
||||
case green11
|
||||
|
||||
public var value: UIColor {
|
||||
switch self {
|
||||
case .black:
|
||||
return VDSColor.paletteBlack
|
||||
case .white:
|
||||
return VDSColor.paletteWhite
|
||||
case .red:
|
||||
return VDSColor.paletteRed
|
||||
case .gray95:
|
||||
return VDSColor.paletteGray95
|
||||
case .gray85:
|
||||
return VDSColor.paletteGray85
|
||||
case .gray65:
|
||||
return VDSColor.paletteGray65
|
||||
case .gray44:
|
||||
return VDSColor.paletteGray44
|
||||
case .gray20:
|
||||
return VDSColor.paletteGray20
|
||||
case .gray11:
|
||||
return VDSColor.paletteGray11
|
||||
case .orange91:
|
||||
return VDSColor.paletteOrange91
|
||||
case .orange46:
|
||||
return VDSColor.paletteOrange46
|
||||
case .orange39:
|
||||
return VDSColor.paletteOrange39
|
||||
case .orange15:
|
||||
return VDSColor.paletteOrange15
|
||||
case .yellow94:
|
||||
return VDSColor.paletteYellow94
|
||||
case .yellow62:
|
||||
return VDSColor.paletteYellow62
|
||||
case .yellow20:
|
||||
return VDSColor.paletteYellow20
|
||||
case .blue91:
|
||||
return VDSColor.paletteBlue91
|
||||
case .blue45:
|
||||
return VDSColor.paletteBlue45
|
||||
case .blue35:
|
||||
return VDSColor.paletteBlue35
|
||||
case .blue13:
|
||||
return VDSColor.paletteBlue13
|
||||
case .green89:
|
||||
return VDSColor.paletteGreen89
|
||||
case .green34:
|
||||
return VDSColor.paletteGreen34
|
||||
case .green26:
|
||||
return VDSColor.paletteGreen26
|
||||
case .green11:
|
||||
return VDSColor.paletteGreen11
|
||||
extension Icon {
|
||||
public enum Color: String, CaseIterable {
|
||||
case black
|
||||
case white
|
||||
case red
|
||||
case gray95
|
||||
case gray85
|
||||
case gray65
|
||||
case gray44
|
||||
case gray20
|
||||
case gray11
|
||||
case orange91
|
||||
case orange46
|
||||
case orange39
|
||||
case orange15
|
||||
case yellow94
|
||||
case yellow62
|
||||
case yellow20
|
||||
case blue91
|
||||
case blue45
|
||||
case blue35
|
||||
case blue13
|
||||
case green89
|
||||
case green34
|
||||
case green26
|
||||
case green11
|
||||
|
||||
public var value: UIColor {
|
||||
switch self {
|
||||
case .black:
|
||||
return VDSColor.paletteBlack
|
||||
case .white:
|
||||
return VDSColor.paletteWhite
|
||||
case .red:
|
||||
return VDSColor.paletteRed
|
||||
case .gray95:
|
||||
return VDSColor.paletteGray95
|
||||
case .gray85:
|
||||
return VDSColor.paletteGray85
|
||||
case .gray65:
|
||||
return VDSColor.paletteGray65
|
||||
case .gray44:
|
||||
return VDSColor.paletteGray44
|
||||
case .gray20:
|
||||
return VDSColor.paletteGray20
|
||||
case .gray11:
|
||||
return VDSColor.paletteGray11
|
||||
case .orange91:
|
||||
return VDSColor.paletteOrange91
|
||||
case .orange46:
|
||||
return VDSColor.paletteOrange46
|
||||
case .orange39:
|
||||
return VDSColor.paletteOrange39
|
||||
case .orange15:
|
||||
return VDSColor.paletteOrange15
|
||||
case .yellow94:
|
||||
return VDSColor.paletteYellow94
|
||||
case .yellow62:
|
||||
return VDSColor.paletteYellow62
|
||||
case .yellow20:
|
||||
return VDSColor.paletteYellow20
|
||||
case .blue91:
|
||||
return VDSColor.paletteBlue91
|
||||
case .blue45:
|
||||
return VDSColor.paletteBlue45
|
||||
case .blue35:
|
||||
return VDSColor.paletteBlue35
|
||||
case .blue13:
|
||||
return VDSColor.paletteBlue13
|
||||
case .green89:
|
||||
return VDSColor.paletteGreen89
|
||||
case .green34:
|
||||
return VDSColor.paletteGreen34
|
||||
case .green26:
|
||||
return VDSColor.paletteGreen26
|
||||
case .green11:
|
||||
return VDSColor.paletteGreen11
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,40 +9,42 @@ import Foundation
|
||||
import UIKit
|
||||
import VDSColorTokens
|
||||
|
||||
public struct IconName: RawRepresentable, Codable {
|
||||
public typealias RawValue = String
|
||||
public var rawValue: String
|
||||
|
||||
public init?(rawValue: String) {
|
||||
self.rawValue = rawValue
|
||||
extension Icon {
|
||||
public struct Name: RawRepresentable, Codable {
|
||||
public typealias RawValue = String
|
||||
public var rawValue: String
|
||||
|
||||
public init?(rawValue: String) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
public init(name: String){
|
||||
self.rawValue = name
|
||||
}
|
||||
|
||||
public static let checkmark = Name(name: "checkmark")
|
||||
internal static let checkmarkBold = Name(name: "checkmark-bold")
|
||||
public static let checkmarkAlt = Name(name: "checkmark-alt")
|
||||
internal static let checkmarkAltBold = Name(name: "checkmark-alt-bold")
|
||||
public static let close = Name(name: "close")
|
||||
internal static let closeBold = Name(name: "close-bold")
|
||||
public static let error = Name(name: "error")
|
||||
internal static let errorBold = Name(name: "error-bold")
|
||||
public static let info = Name(name: "info")
|
||||
internal static let infoBold = Name(name: "info-bold")
|
||||
public static let multipleDocuments = Name(name: "multiple-documents")
|
||||
|
||||
public static let leftArrow = Name(name: "left-arrow")
|
||||
public static let leftCaret = Name(name: "left-caret")
|
||||
internal static let leftCaretBold = Name(name: "left-caret-bold")
|
||||
internal static let paginationLeftArrow = Name(name: "pagination-left-arrow")
|
||||
|
||||
public static let rightArrow = Name(name: "right-arrow")
|
||||
public static let rightCaret = Name(name: "right-caret")
|
||||
internal static let rightCaretBold = Name(name: "right-caret-bold")
|
||||
internal static let paginationRightArrow = Name(name: "pagination-right-arrow")
|
||||
|
||||
public static let warning = Name(name: "warning")
|
||||
internal static let warningBold = Name(name: "warning-bold")
|
||||
}
|
||||
|
||||
public init(name: String){
|
||||
self.rawValue = name
|
||||
}
|
||||
|
||||
public static let checkmark = IconName(name: "checkmark")
|
||||
internal static let checkmarkBold = IconName(name: "checkmark-bold")
|
||||
public static let checkmarkAlt = IconName(name: "checkmark-alt")
|
||||
internal static let checkmarkAltBold = IconName(name: "checkmark-alt-bold")
|
||||
public static let close = IconName(name: "close")
|
||||
internal static let closeBold = IconName(name: "close-bold")
|
||||
public static let error = IconName(name: "error")
|
||||
internal static let errorBold = IconName(name: "error-bold")
|
||||
public static let info = IconName(name: "info")
|
||||
internal static let infoBold = IconName(name: "info-bold")
|
||||
public static let multipleDocuments = IconName(name: "multiple-documents")
|
||||
|
||||
public static let leftArrow = IconName(name: "left-arrow")
|
||||
public static let leftCaret = IconName(name: "left-caret")
|
||||
internal static let leftCaretBold = IconName(name: "left-caret-bold")
|
||||
internal static let paginationLeftArrow = IconName(name: "pagination-left-arrow")
|
||||
|
||||
public static let rightArrow = IconName(name: "right-arrow")
|
||||
public static let rightCaret = IconName(name: "right-caret")
|
||||
internal static let rightCaretBold = IconName(name: "right-caret-bold")
|
||||
internal static let paginationRightArrow = IconName(name: "pagination-right-arrow")
|
||||
|
||||
public static let warning = IconName(name: "warning")
|
||||
internal static let warningBold = IconName(name: "warning-bold")
|
||||
}
|
||||
|
||||
39
VDS/Components/Icon/IconSize.swift
Normal file
39
VDS/Components/Icon/IconSize.swift
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// IconSize.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 1/13/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Icon {
|
||||
public enum Size: String, CaseIterable, Codable {
|
||||
case xsmall
|
||||
case small
|
||||
case medium
|
||||
case large
|
||||
case XLarge
|
||||
|
||||
public var dimensions: CGSize {
|
||||
switch self {
|
||||
|
||||
case .xsmall:
|
||||
return .init(width: 12, height: 12)
|
||||
|
||||
case .small:
|
||||
return .init(width: 16, height: 16)
|
||||
|
||||
case .medium:
|
||||
return .init(width: 20, height: 20)
|
||||
|
||||
case .large:
|
||||
return .init(width: 24, height: 24)
|
||||
|
||||
case .XLarge:
|
||||
return .init(width: 28, height: 28)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -51,7 +51,7 @@ public struct ActionLabelAttribute: ActionLabelAttributeModel {
|
||||
|
||||
public func setAttribute(on attributedString: NSMutableAttributedString) {
|
||||
if(shouldUnderline){
|
||||
attributedString.addAttribute(.underlineStyle, value: UnderlineStyle.single.value(), range: range)
|
||||
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single, range: range)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,11 +9,18 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
public struct ImageLabelAttribute: AttachmentLabelAttributeModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum Error: Swift.Error {
|
||||
case bundleNotFound
|
||||
case imageNotFound(String)
|
||||
case imageNotSet
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
public var id = UUID()
|
||||
public var location: Int
|
||||
public var length: Int = 1
|
||||
@ -21,6 +28,10 @@ public struct ImageLabelAttribute: AttachmentLabelAttributeModel {
|
||||
public var image: UIImage?
|
||||
public var frame: CGRect?
|
||||
public var tintColor: UIColor?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Equatable
|
||||
//--------------------------------------------------
|
||||
public static func == (lhs: ImageLabelAttribute, rhs: ImageLabelAttribute) -> Bool {
|
||||
lhs.isEqual(rhs)
|
||||
}
|
||||
@ -29,6 +40,9 @@ public struct ImageLabelAttribute: AttachmentLabelAttributeModel {
|
||||
return id == equatable.id && range == equatable.range && imageName == equatable.imageName
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Functions
|
||||
//--------------------------------------------------
|
||||
private func imageAttachment(image: UIImage) -> NSTextAttachment {
|
||||
let attachment = NSTextAttachment()
|
||||
attachment.image = tintColor != nil ? image.withTintColor(tintColor!) : image
|
||||
@ -36,6 +50,9 @@ public struct ImageLabelAttribute: AttachmentLabelAttributeModel {
|
||||
return attachment
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Functions
|
||||
//--------------------------------------------------
|
||||
public func getAttachment() throws -> NSTextAttachment {
|
||||
|
||||
//get a local asset
|
||||
|
||||
@ -40,10 +40,10 @@ public extension NSAttributedString {
|
||||
static func createAttributeModelFor(key: NSAttributedString.Key, range: NSRange, value: Any) -> (any LabelAttributeModel)? {
|
||||
guard let value = value as? AnyHashable else { return nil }
|
||||
|
||||
guard let font = value as? UIFont, let style = TypographicalStyle.style(for: font.fontName, size: font.pointSize), key == .font
|
||||
guard let font = value as? UIFont, let style = TextStyle.style(for: font.fontName, size: font.pointSize), key == .font
|
||||
else {
|
||||
return AnyAttribute(location: range.location, length: range.length, key: key, value: value)
|
||||
}
|
||||
return TypographicalStyleLabelAttribute(location: range.location, length: range.length, style: style)
|
||||
return TextStyleLabelAttribute(location: range.location, length: range.length, textStyle: style)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,13 +8,16 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public struct TypographicalStyleLabelAttribute: LabelAttributeModel {
|
||||
public struct TextStyleLabelAttribute: LabelAttributeModel {
|
||||
|
||||
public func isEqual(_ equatable: TypographicalStyleLabelAttribute) -> Bool {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Equatable
|
||||
//--------------------------------------------------
|
||||
public func isEqual(_ equatable: TextStyleLabelAttribute) -> Bool {
|
||||
return id == equatable.id
|
||||
&& range == equatable.range
|
||||
&& color == equatable.color
|
||||
&& style == equatable.style
|
||||
&& textColor == equatable.textColor
|
||||
&& textStyle == equatable.textStyle
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -23,19 +26,19 @@ public struct TypographicalStyleLabelAttribute: LabelAttributeModel {
|
||||
public var id = UUID()
|
||||
public var location: Int
|
||||
public var length: Int
|
||||
public var style: TypographicalStyle
|
||||
public var color: UIColor
|
||||
public var textStyle: TextStyle
|
||||
public var textColor: UIColor
|
||||
public var textPosition: TextPosition
|
||||
public var lineBreakMode: NSLineBreakMode
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
public init(location: Int, length: Int, style: TypographicalStyle, color: UIColor = .black, textPosition: TextPosition = .left, lineBreakMode: NSLineBreakMode = .byWordWrapping) {
|
||||
public init(location: Int, length: Int, textStyle: TextStyle, textColor: UIColor = .black, textPosition: TextPosition = .left, lineBreakMode: NSLineBreakMode = .byWordWrapping) {
|
||||
self.location = location
|
||||
self.length = length
|
||||
self.style = style
|
||||
self.color = color
|
||||
self.textStyle = textStyle
|
||||
self.textColor = textColor
|
||||
self.textPosition = textPosition
|
||||
self.lineBreakMode = lineBreakMode
|
||||
}
|
||||
@ -43,23 +46,23 @@ public struct TypographicalStyleLabelAttribute: LabelAttributeModel {
|
||||
public func setAttribute(on attributedString: NSMutableAttributedString) {
|
||||
attributedString.removeAttribute(.font, range: range)
|
||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||
attributedString.addAttribute(.font, value: style.font, range: range)
|
||||
attributedString.addAttribute(.foregroundColor, value: color, range: range)
|
||||
attributedString.addAttribute(.font, value: textStyle.font, range: range)
|
||||
attributedString.addAttribute(.foregroundColor, value: textColor, range: range)
|
||||
setStyleAttributes(attributedString)
|
||||
}
|
||||
|
||||
private func setStyleAttributes(_ attributedString: NSMutableAttributedString) {
|
||||
//set letterSpacing
|
||||
if style.letterSpacing > 0.0 {
|
||||
if textStyle.letterSpacing > 0.0 {
|
||||
attributedString.removeAttribute(.kern, range: range)
|
||||
attributedString.addAttribute(.kern, value: style.letterSpacing, range: range)
|
||||
attributedString.addAttribute(.kern, value: textStyle.letterSpacing, range: range)
|
||||
}
|
||||
|
||||
//set lineHeight
|
||||
if style.lineHeight > 0.0 {
|
||||
let lineHeight = style.lineHeight
|
||||
let adjustment = lineHeight > style.font.lineHeight ? 2.0 : 1.0
|
||||
let baselineOffset = (lineHeight - style.font.lineHeight) / 2.0 / adjustment
|
||||
if textStyle.lineHeight > 0.0 {
|
||||
let lineHeight = textStyle.lineHeight
|
||||
let adjustment = lineHeight > textStyle.font.lineHeight ? 2.0 : 1.0
|
||||
let baselineOffset = (lineHeight - textStyle.font.lineHeight) / 2.0 / adjustment
|
||||
let paragraph = NSMutableParagraphStyle().with {
|
||||
$0.maximumLineHeight = lineHeight
|
||||
$0.minimumLineHeight = lineHeight
|
||||
@ -9,7 +9,9 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
public struct UnderlineLabelAttribute: LabelAttributeModel {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Equatable
|
||||
//--------------------------------------------------
|
||||
public func isEqual(_ equatable: UnderlineLabelAttribute) -> Bool {
|
||||
return id == equatable.id
|
||||
&& range == equatable.range
|
||||
@ -18,12 +20,15 @@ public struct UnderlineLabelAttribute: LabelAttributeModel {
|
||||
&& pattern == equatable.pattern
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
public var id = UUID()
|
||||
public var location: Int
|
||||
public var length: Int
|
||||
public var color: UIColor?
|
||||
public var style: UnderlineStyle = .single
|
||||
public var pattern: UnderlineStyle.Pattern?
|
||||
public var style: Style = .single
|
||||
public var pattern: Pattern?
|
||||
|
||||
public var underlineValue: NSUnderlineStyle {
|
||||
if let pattern = pattern?.value() {
|
||||
@ -33,7 +38,10 @@ public struct UnderlineLabelAttribute: LabelAttributeModel {
|
||||
}
|
||||
}
|
||||
|
||||
public init(location: Int, length: Int, style: UnderlineStyle = .single, color: UIColor? = nil, pattern: UnderlineStyle.Pattern? = nil) {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
public init(location: Int, length: Int, style: Style = .single, color: UIColor? = nil, pattern: Pattern? = nil) {
|
||||
self.location = location
|
||||
self.length = length
|
||||
self.color = color
|
||||
@ -41,7 +49,10 @@ public struct UnderlineLabelAttribute: LabelAttributeModel {
|
||||
self.pattern = pattern
|
||||
}
|
||||
|
||||
public func setAttribute(on attributedString: NSMutableAttributedString) {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Functions
|
||||
//--------------------------------------------------
|
||||
public func setAttribute(on attributedString: NSMutableAttributedString) {
|
||||
attributedString.addAttribute(.underlineStyle, value: underlineValue.rawValue, range: range)
|
||||
if let color = color {
|
||||
attributedString.addAttribute(.underlineColor, value: color, range: range)
|
||||
@ -49,25 +60,30 @@ public struct UnderlineLabelAttribute: LabelAttributeModel {
|
||||
}
|
||||
}
|
||||
|
||||
public enum UnderlineStyle: String, Codable {
|
||||
case none
|
||||
case single
|
||||
case thick
|
||||
case double
|
||||
|
||||
func value() -> Int {
|
||||
switch self {
|
||||
case .none:
|
||||
return 0
|
||||
|
||||
case .single:
|
||||
return NSUnderlineStyle.single.rawValue
|
||||
|
||||
case .thick:
|
||||
return NSUnderlineStyle.thick.rawValue
|
||||
|
||||
case .double:
|
||||
return NSUnderlineStyle.double.rawValue
|
||||
extension UnderlineLabelAttribute {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum Style: String, Codable {
|
||||
case none
|
||||
case single
|
||||
case thick
|
||||
case double
|
||||
|
||||
func value() -> Int {
|
||||
switch self {
|
||||
case .none:
|
||||
return 0
|
||||
|
||||
case .single:
|
||||
return NSUnderlineStyle.single.rawValue
|
||||
|
||||
case .thick:
|
||||
return NSUnderlineStyle.thick.rawValue
|
||||
|
||||
case .double:
|
||||
return NSUnderlineStyle.double.rawValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,4 +114,3 @@ public enum UnderlineStyle: String, Codable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ public class Label: UILabel, Handlerable, ViewProtocol, Resettable {
|
||||
|
||||
open var attributes: [any LabelAttributeModel]? { didSet { didChange() }}
|
||||
|
||||
open var typograpicalStyle: TypographicalStyle = .defaultStyle { didSet { didChange() }}
|
||||
open var textStyle: TextStyle = .defaultStyle { didSet { didChange() }}
|
||||
|
||||
open var textPosition: TextPosition = .left { didSet { didChange() }}
|
||||
|
||||
@ -103,7 +103,7 @@ public class Label: UILabel, Handlerable, ViewProtocol, Resettable {
|
||||
surface = .light
|
||||
disabled = false
|
||||
attributes = nil
|
||||
typograpicalStyle = .defaultStyle
|
||||
textStyle = .defaultStyle
|
||||
textPosition = .left
|
||||
text = nil
|
||||
attributedText = nil
|
||||
@ -120,7 +120,7 @@ public class Label: UILabel, Handlerable, ViewProtocol, Resettable {
|
||||
if !useAttributedText {
|
||||
textAlignment = textPosition.textAlignment
|
||||
textColor = textColorConfiguration.getColor(self)
|
||||
font = typograpicalStyle.font
|
||||
font = textStyle.font
|
||||
|
||||
if let text = text, let font = font, let textColor = textColor {
|
||||
//clear the arrays holding actions
|
||||
@ -169,13 +169,13 @@ public class Label: UILabel, Handlerable, ViewProtocol, Resettable {
|
||||
let entireRange = NSRange(location: 0, length: attributedString.length)
|
||||
|
||||
//set letterSpacing
|
||||
if typograpicalStyle.letterSpacing > 0.0 {
|
||||
attributedString.addAttribute(.kern, value: typograpicalStyle.letterSpacing, range: entireRange)
|
||||
if textStyle.letterSpacing > 0.0 {
|
||||
attributedString.addAttribute(.kern, value: textStyle.letterSpacing, range: entireRange)
|
||||
}
|
||||
|
||||
//set lineHeight
|
||||
if typograpicalStyle.lineHeight > 0.0 {
|
||||
let lineHeight = typograpicalStyle.lineHeight
|
||||
if textStyle.lineHeight > 0.0 {
|
||||
let lineHeight = textStyle.lineHeight
|
||||
let adjustment = lineHeight > font.lineHeight ? 2.0 : 1.0
|
||||
let baselineOffset = (lineHeight - font.lineHeight) / 2.0 / adjustment
|
||||
let paragraph = NSMutableParagraphStyle().with {
|
||||
|
||||
@ -70,19 +70,19 @@ open class RadioBoxBase: Control, Accessable, DataTrackable{
|
||||
private var textLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BoldBodyLarge
|
||||
$0.textStyle = .BoldBodyLarge
|
||||
}
|
||||
|
||||
private var subTextLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodyLarge
|
||||
$0.textStyle = .BodyLarge
|
||||
}
|
||||
|
||||
private var subTextRightLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .right
|
||||
$0.typograpicalStyle = .BodyLarge
|
||||
$0.textStyle = .BodyLarge
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -226,9 +226,9 @@ open class RadioBoxBase: Control, Accessable, DataTrackable{
|
||||
subTextLabel.reset()
|
||||
subTextRightLabel.reset()
|
||||
|
||||
textLabel.typograpicalStyle = .BoldBodyLarge
|
||||
subTextLabel.typograpicalStyle = .BodyLarge
|
||||
subTextRightLabel.typograpicalStyle = .BodyLarge
|
||||
textLabel.textStyle = .BoldBodyLarge
|
||||
subTextLabel.textStyle = .BodyLarge
|
||||
subTextRightLabel.textStyle = .BodyLarge
|
||||
|
||||
text = "Default Text"
|
||||
textAttributes = nil
|
||||
|
||||
@ -83,19 +83,19 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, Errorable {
|
||||
private var label = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BoldBodyLarge
|
||||
$0.textStyle = .BoldBodyLarge
|
||||
}
|
||||
|
||||
private var childLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodyLarge
|
||||
$0.textStyle = .BodyLarge
|
||||
}
|
||||
|
||||
private var errorLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodyMedium
|
||||
$0.textStyle = .BodyMedium
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -269,9 +269,9 @@ open class RadioButtonBase: Control, Accessable, DataTrackable, Errorable {
|
||||
childLabel.reset()
|
||||
errorLabel.reset()
|
||||
|
||||
label.typograpicalStyle = .BoldBodyLarge
|
||||
childLabel.typograpicalStyle = .BodyLarge
|
||||
errorLabel.typograpicalStyle = .BodyMedium
|
||||
label.textStyle = .BoldBodyLarge
|
||||
childLabel.textStyle = .BodyLarge
|
||||
errorLabel.textStyle = .BodyMedium
|
||||
|
||||
labelText = nil
|
||||
labelTextAttributes = nil
|
||||
|
||||
@ -117,7 +117,7 @@ public class RadioSwatchGroupBase<HandlerType: RadioSwatchBase>: SelectorGroupSe
|
||||
|
||||
open override func updateView() {
|
||||
label.textPosition = .left
|
||||
label.typograpicalStyle = .BodySmall
|
||||
label.textStyle = .BodySmall
|
||||
label.text = selectedHandler?.text ?? " "
|
||||
label.surface = surface
|
||||
label.disabled = disabled
|
||||
|
||||
@ -11,12 +11,15 @@ import VDSColorTokens
|
||||
import VDSFormControlsTokens
|
||||
import Combine
|
||||
|
||||
public enum HelperTextPlacement: String, CaseIterable {
|
||||
case bottom, right
|
||||
}
|
||||
|
||||
@objc(VDSEntryField)
|
||||
open class EntryField: Control, Accessable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum HelperTextPlacement: String, CaseIterable {
|
||||
case bottom, right
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
@ -47,19 +50,19 @@ open class EntryField: Control, Accessable {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.attributes = []
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodySmall
|
||||
$0.textStyle = .BodySmall
|
||||
}
|
||||
|
||||
internal var errorLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodySmall
|
||||
$0.textStyle = .BodySmall
|
||||
}
|
||||
|
||||
internal var helperLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodySmall
|
||||
$0.textStyle = .BodySmall
|
||||
}
|
||||
|
||||
internal var containerView: UIView = {
|
||||
@ -246,7 +249,7 @@ open class EntryField: Control, Accessable {
|
||||
let title = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BoldBodySmall
|
||||
$0.textStyle = .BoldBodySmall
|
||||
$0.text = tooltipTitle
|
||||
$0.surface = surface
|
||||
$0.disabled = disabled
|
||||
@ -255,7 +258,7 @@ open class EntryField: Control, Accessable {
|
||||
let content = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BoldBodySmall
|
||||
$0.textStyle = .BoldBodySmall
|
||||
$0.text = tooltipContent
|
||||
$0.surface = surface
|
||||
$0.disabled = disabled
|
||||
@ -280,11 +283,11 @@ open class EntryField: Control, Accessable {
|
||||
helperLabel.reset()
|
||||
|
||||
titleLabel.textPosition = .left
|
||||
titleLabel.typograpicalStyle = .BodySmall
|
||||
titleLabel.textStyle = .BodySmall
|
||||
errorLabel.textPosition = .left
|
||||
errorLabel.typograpicalStyle = .BodySmall
|
||||
errorLabel.textStyle = .BodySmall
|
||||
helperLabel.textPosition = .left
|
||||
helperLabel.typograpicalStyle = .BodySmall
|
||||
helperLabel.textStyle = .BodySmall
|
||||
|
||||
labelText = nil
|
||||
helperText = nil
|
||||
|
||||
@ -11,12 +11,15 @@ import VDSColorTokens
|
||||
import VDSFormControlsTokens
|
||||
import Combine
|
||||
|
||||
public enum InputFieldType: String, CaseIterable {
|
||||
case text, number, calendar, inlineAction, password, creditCard, tel, date, securityCode
|
||||
}
|
||||
|
||||
@objc(VDSInputField)
|
||||
public class InputField: EntryField, UITextFieldDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum FieldType: String, CaseIterable {
|
||||
case text, number, calendar, inlineAction, password, creditCard, tel, date, securityCode
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
@ -48,7 +51,7 @@ public class InputField: EntryField, UITextFieldDelegate {
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
open var type: InputFieldType = .text { didSet { didChange() }}
|
||||
open var type: FieldType = .text { didSet { didChange() }}
|
||||
|
||||
var _showError: Bool = false
|
||||
open override var showError: Bool {
|
||||
@ -86,15 +89,18 @@ public class InputField: EntryField, UITextFieldDelegate {
|
||||
|
||||
open var helperTextPlacement: HelperTextPlacement = .bottom { didSet { didChange() }}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
private var successLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
$0.textPosition = .left
|
||||
$0.typograpicalStyle = .BodySmall
|
||||
$0.textStyle = .BodySmall
|
||||
}
|
||||
|
||||
private var textField = UITextField().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
$0.font = TypographicalStyle.BodyLarge.font
|
||||
$0.font = TextStyle.BodyLarge.font
|
||||
}
|
||||
|
||||
public var textFieldTextColorConfiguration: AnyColorable = ViewColorConfiguration().with {
|
||||
@ -105,7 +111,7 @@ public class InputField: EntryField, UITextFieldDelegate {
|
||||
internal var minWidthConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
// MARK: - Overrides
|
||||
//--------------------------------------------------
|
||||
open override func setup() {
|
||||
super.setup()
|
||||
@ -141,7 +147,7 @@ public class InputField: EntryField, UITextFieldDelegate {
|
||||
|
||||
successLabel.reset()
|
||||
successLabel.textPosition = .left
|
||||
successLabel.typograpicalStyle = .BodySmall
|
||||
successLabel.textStyle = .BodySmall
|
||||
|
||||
type = .text
|
||||
showSuccess = false
|
||||
@ -154,9 +160,6 @@ public class InputField: EntryField, UITextFieldDelegate {
|
||||
return inputFieldStackView
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - State
|
||||
//--------------------------------------------------
|
||||
open override func updateView() {
|
||||
super.updateView()
|
||||
|
||||
@ -216,7 +219,7 @@ public class InputField: EntryField, UITextFieldDelegate {
|
||||
|
||||
}
|
||||
|
||||
extension InputFieldType {
|
||||
extension InputField.FieldType {
|
||||
var width: CGFloat {
|
||||
switch self {
|
||||
case .inlineAction:
|
||||
|
||||
@ -48,7 +48,7 @@ public class TextArea: EntryField {
|
||||
|
||||
private var textView = UITextView().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
$0.font = TypographicalStyle.BodyLarge.font
|
||||
$0.font = TextStyle.BodyLarge.font
|
||||
$0.sizeToFit()
|
||||
$0.isScrollEnabled = false
|
||||
}
|
||||
|
||||
@ -31,14 +31,17 @@ open class TileContainer: Control {
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public enum ContainerBackgroundColor: String, Codable, CaseIterable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum BackgroundColor: String, Codable, CaseIterable {
|
||||
case white
|
||||
case black
|
||||
case gray
|
||||
case transparent
|
||||
}
|
||||
|
||||
public enum ContainerPadding: String, Codable {
|
||||
public enum Padding: String, Codable, CaseIterable {
|
||||
case padding2X
|
||||
case padding4X
|
||||
case padding6X
|
||||
@ -61,7 +64,7 @@ open class TileContainer: Control {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ContainerScalingType: String, Codable, CaseIterable {
|
||||
public enum AspectRatio: String, Codable, CaseIterable {
|
||||
case ratio1x1 = "1:1"
|
||||
case ratio3x4 = "3:4"
|
||||
case ratio4x3 = "4:3"
|
||||
@ -83,11 +86,11 @@ open class TileContainer: Control {
|
||||
|
||||
public var highlightView = View()
|
||||
|
||||
public var containerBackgroundColor: ContainerBackgroundColor = .white { didSet{ didChange() } }
|
||||
public var color: BackgroundColor = .white { didSet{ didChange() } }
|
||||
|
||||
public var containerPadding: ContainerPadding = .padding4X { didSet{ didChange() } }
|
||||
public var padding: Padding = .padding4X { didSet{ didChange() } }
|
||||
|
||||
public var aspectRatio: ContainerScalingType = .ratio1x1 { didSet{ didChange() } }
|
||||
public var aspectRatio: AspectRatio = .ratio1x1 { didSet{ didChange() } }
|
||||
|
||||
public var imageFallbackColor: Surface = .light { didSet{ didChange() } }
|
||||
|
||||
@ -166,13 +169,13 @@ open class TileContainer: Control {
|
||||
containerView.isUserInteractionEnabled = false
|
||||
containerView.backgroundColor = .clear
|
||||
|
||||
containerTopConstraint = containerView.topAnchor.constraint(equalTo: topAnchor, constant: containerPadding.value)
|
||||
containerTopConstraint = containerView.topAnchor.constraint(equalTo: topAnchor, constant: padding.value)
|
||||
containerTopConstraint?.isActive = true
|
||||
containerBottomConstraint = containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: containerPadding.value)
|
||||
containerBottomConstraint = containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: padding.value)
|
||||
containerBottomConstraint?.isActive = true
|
||||
containerLeadingConstraint = containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: containerPadding.value)
|
||||
containerLeadingConstraint = containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding.value)
|
||||
containerLeadingConstraint?.isActive = true
|
||||
containerTrailingConstraint = containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: containerPadding.value)
|
||||
containerTrailingConstraint = containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: padding.value)
|
||||
containerTrailingConstraint?.isActive = true
|
||||
|
||||
highlightView.pinToSuperView()
|
||||
@ -215,7 +218,7 @@ open class TileContainer: Control {
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - State
|
||||
// MARK: - Private Functions
|
||||
//--------------------------------------------------
|
||||
private func ratioSize(for width: CGFloat) -> CGSize {
|
||||
var height: CGFloat = width
|
||||
@ -247,6 +250,9 @@ open class TileContainer: Control {
|
||||
return CGSize(width: width, height: height)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Overrides
|
||||
//--------------------------------------------------
|
||||
open override func updateView() {
|
||||
super.updateView()
|
||||
|
||||
@ -265,10 +271,10 @@ open class TileContainer: Control {
|
||||
layer.borderColor = borderColorConfig.getColor(self).cgColor
|
||||
layer.borderWidth = showBorder ? VDSFormControls.widthBorder : 0
|
||||
|
||||
containerTopConstraint?.constant = containerPadding.value
|
||||
containerLeadingConstraint?.constant = containerPadding.value
|
||||
containerBottomConstraint?.constant = -containerPadding.value
|
||||
containerTrailingConstraint?.constant = -containerPadding.value
|
||||
containerTopConstraint?.constant = padding.value
|
||||
containerLeadingConstraint?.constant = padding.value
|
||||
containerBottomConstraint?.constant = -padding.value
|
||||
containerTrailingConstraint?.constant = -padding.value
|
||||
|
||||
if let width, aspectRatio == .none && height == nil{
|
||||
widthConstraint?.constant = width
|
||||
@ -294,20 +300,25 @@ open class TileContainer: Control {
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Functions
|
||||
//--------------------------------------------------
|
||||
public func addContentView(_ view: UIView, shouldPin: Bool = true) {
|
||||
containerView.addSubview(view)
|
||||
if shouldPin {
|
||||
view.pinToSuperView()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension TileContainer {
|
||||
class BackgroundColorConfiguration: ObjectColorable {
|
||||
typealias ObjectType = TileContainer
|
||||
|
||||
required init() { }
|
||||
|
||||
func getColor(_ object: TileContainer) -> UIColor {
|
||||
switch object.containerBackgroundColor {
|
||||
switch object.color {
|
||||
|
||||
case .white:
|
||||
return VDSColor.backgroundPrimaryLight
|
||||
|
||||
@ -12,8 +12,10 @@ import UIKit
|
||||
|
||||
@objc(VDSTilet)
|
||||
open class Tilet: TileContainer {
|
||||
|
||||
public enum TextPosition {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum TextPosition: String, Codable, CaseIterable {
|
||||
case top
|
||||
case bottom
|
||||
}
|
||||
@ -51,7 +53,7 @@ open class Tilet: TileContainer {
|
||||
|
||||
private var titleLockup = TitleLockup().with {
|
||||
let configs = [
|
||||
TypographicalStyleDeviceSpacingConfig([.TitleSmall, .BoldTitleSmall],
|
||||
TextStyle.DeviceSpacingConfig([.TitleSmall, .BoldTitleSmall],
|
||||
neighboring: [
|
||||
.BodySmall, .BoldBodySmall,
|
||||
.BodyMedium, .BoldBodyMedium
|
||||
@ -59,7 +61,7 @@ open class Tilet: TileContainer {
|
||||
spacing: 8.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.TitleMedium, .BoldTitleMedium,
|
||||
TextStyle.DeviceSpacingConfig([.TitleMedium, .BoldTitleMedium,
|
||||
.TitleLarge, .BoldTitleLarge],
|
||||
neighboring: [
|
||||
.BodySmall, .BoldBodySmall,
|
||||
@ -68,7 +70,7 @@ open class Tilet: TileContainer {
|
||||
spacing: 8.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge],
|
||||
TextStyle.DeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge],
|
||||
neighboring: [
|
||||
.BodySmall, .BoldBodySmall,
|
||||
.BodyMedium, .BoldBodyMedium,
|
||||
@ -78,7 +80,7 @@ open class Tilet: TileContainer {
|
||||
spacing: 12.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.TitleSmall, .BoldTitleSmall,
|
||||
TextStyle.DeviceSpacingConfig([.TitleSmall, .BoldTitleSmall,
|
||||
.TitleMedium, .BoldTitleMedium],
|
||||
neighboring: [
|
||||
.BodySmall, .BoldBodySmall,
|
||||
@ -88,7 +90,7 @@ open class Tilet: TileContainer {
|
||||
spacing: 8.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.TitleLarge, .BoldTitleLarge],
|
||||
TextStyle.DeviceSpacingConfig([.TitleLarge, .BoldTitleLarge],
|
||||
neighboring: [
|
||||
.BodySmall, .BoldBodySmall,
|
||||
.BodyMedium, .BoldBodyMedium,
|
||||
@ -98,7 +100,7 @@ open class Tilet: TileContainer {
|
||||
spacing: 12.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge],
|
||||
TextStyle.DeviceSpacingConfig([.TitleXLarge, .BoldTitleXLarge],
|
||||
neighboring: [
|
||||
.BodyLarge, .BoldBodyLarge,
|
||||
.TitleMedium, .BoldTitleMedium
|
||||
@ -108,7 +110,7 @@ open class Tilet: TileContainer {
|
||||
|
||||
]
|
||||
|
||||
$0.bottomTypographicalStyleSpacingConfig = TypographicalStyleSpacingConfig(configs: configs)
|
||||
$0.bottomTextStyleSpacingConfig = TextStyle.SpacingConfig(configs: configs)
|
||||
}
|
||||
|
||||
private var badgeContainerView = UIView().with {
|
||||
@ -210,7 +212,7 @@ open class Tilet: TileContainer {
|
||||
super.setup()
|
||||
width = 100
|
||||
aspectRatio = .none
|
||||
containerBackgroundColor = .black
|
||||
color = .black
|
||||
let view = UIView().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
@ -256,7 +258,7 @@ open class Tilet: TileContainer {
|
||||
super.reset()
|
||||
aspectRatio = .none
|
||||
surface = .light
|
||||
containerBackgroundColor = .black
|
||||
color = .black
|
||||
|
||||
//models
|
||||
badgeModel = nil
|
||||
@ -298,7 +300,7 @@ open class Tilet: TileContainer {
|
||||
|
||||
if showTitleLockup {
|
||||
//flip the surface for the titleLockup
|
||||
titleLockup.surface = containerBackgroundColor == .black ? .dark : .light
|
||||
titleLockup.surface = color == .black ? Surface.dark : Surface.light
|
||||
|
||||
//titleLockup
|
||||
if let textWidth {
|
||||
@ -328,8 +330,8 @@ open class Tilet: TileContainer {
|
||||
titleLockup.titleModel = titleModel?.toTitleLockupTitleModel()
|
||||
titleLockup.subTitleModel = subTitleModel?.toTitleLockupSubTitleModel()
|
||||
|
||||
if let style = subTitleModel?.typographicalStyle.value {
|
||||
titleLockup.otherTypograpicalStyle = style
|
||||
if let style = subTitleModel?.textStyle.value {
|
||||
titleLockup.otherTextStyle = style
|
||||
}
|
||||
|
||||
if titleLockupContainerView.superview == nil {
|
||||
@ -370,7 +372,7 @@ open class Tilet: TileContainer {
|
||||
view = titleLockupContainerView
|
||||
}
|
||||
if let view {
|
||||
stackView.setCustomSpacing(containerPadding.tiletSpacing, after: view)
|
||||
stackView.setCustomSpacing(padding.tiletSpacing, after: view)
|
||||
}
|
||||
if iconContainerView.superview == nil {
|
||||
stackView.addArrangedSubview(iconContainerView)
|
||||
@ -390,7 +392,7 @@ open class Tilet: TileContainer {
|
||||
}
|
||||
}
|
||||
|
||||
extension TileContainer.ContainerPadding {
|
||||
extension TileContainer.Padding {
|
||||
fileprivate var tiletSpacing: CGFloat {
|
||||
switch self {
|
||||
case .padding2X:
|
||||
|
||||
@ -9,11 +9,11 @@ import Foundation
|
||||
|
||||
public struct TiletBadgeModel: Codable {
|
||||
public var text: String = ""
|
||||
public var fillColor: BadgeFillColor
|
||||
public var fillColor:Badge.FillColor
|
||||
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) {
|
||||
public init(text: String, fillColor: Badge.FillColor = .red, surface: Surface = .light, numberOfLines: Int = 0, maxWidth: CGFloat? = nil) {
|
||||
self.text = text
|
||||
self.fillColor = fillColor
|
||||
self.surface = surface
|
||||
|
||||
@ -9,11 +9,11 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
public struct TiletDescriptiveIcon: Codable {
|
||||
public var name: IconName = .multipleDocuments
|
||||
public var size: IconSize = .medium
|
||||
public var name: Icon.Name = .multipleDocuments
|
||||
public var size: Icon.Size = .medium
|
||||
public var surface: Surface = .dark
|
||||
|
||||
public init(name: IconName = .multipleDocuments, size: IconSize, surface: Surface) {
|
||||
public init(name: Icon.Name = .multipleDocuments, size: Icon.Size, surface: Surface) {
|
||||
self.name = name
|
||||
self.size = size
|
||||
self.surface = surface
|
||||
@ -21,10 +21,10 @@ public struct TiletDescriptiveIcon: Codable {
|
||||
}
|
||||
|
||||
public struct TiletDirectionalIcon: Codable {
|
||||
public var size: IconSize = .medium
|
||||
public var size: Icon.Size = .medium
|
||||
public var surface: Surface = .dark
|
||||
|
||||
public init(size: IconSize, surface: Surface) {
|
||||
public init(size: Icon.Size, surface: Surface) {
|
||||
self.size = size
|
||||
self.surface = surface
|
||||
}
|
||||
|
||||
@ -8,7 +8,10 @@
|
||||
import Foundation
|
||||
|
||||
public struct TiletSubTitleModel: Codable {
|
||||
public enum SubTitleTypographicalStyle: String, Codable, EnumSubset {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum TextStyle: String, Codable, EnumSubset {
|
||||
case BodyLarge
|
||||
case BoldBodyLarge
|
||||
case BodyMedium
|
||||
@ -16,25 +19,34 @@ public struct TiletSubTitleModel: Codable {
|
||||
case BodySmall
|
||||
case BoldBodySmall
|
||||
|
||||
public var defaultValue: TitleLockupOtherTypographicalStyle { .BodySmall }
|
||||
public var defaultValue: TitleLockup.OtherTextStyle { .BodySmall }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
public var text: String = ""
|
||||
public var typographicalStyle: SubTitleTypographicalStyle = .BodySmall
|
||||
public var textStyle: TextStyle = .BodySmall
|
||||
public var textColor: Use = .primary
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
public init(text: String,
|
||||
textColor: Use = .primary,
|
||||
textAttributes: [any LabelAttributeModel]? = nil,
|
||||
typographicalStyle: SubTitleTypographicalStyle = .BodySmall) {
|
||||
textStyle: TextStyle = .BodySmall) {
|
||||
self.text = text
|
||||
self.textColor = textColor
|
||||
self.typographicalStyle = typographicalStyle
|
||||
self.textStyle = textStyle
|
||||
}
|
||||
|
||||
public func toTitleLockupSubTitleModel() -> TitleLockupSubTitleModel {
|
||||
TitleLockupSubTitleModel(text: text,
|
||||
textColor: textColor,
|
||||
textAttributes: nil)
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Functions
|
||||
//--------------------------------------------------
|
||||
public func toTitleLockupSubTitleModel() -> TitleLockup.SubTitleModel {
|
||||
TitleLockup.SubTitleModel(text: text,
|
||||
textColor: textColor,
|
||||
textAttributes: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,10 @@
|
||||
import Foundation
|
||||
|
||||
public struct TiletTitleModel: Codable {
|
||||
public enum TitleTypographicalStyle: String, EnumSubset, Codable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum TextStyle: String, EnumSubset, Codable {
|
||||
case TitleXLarge
|
||||
case BoldTitleXLarge
|
||||
case TitleLarge
|
||||
@ -18,21 +21,30 @@ public struct TiletTitleModel: Codable {
|
||||
case TitleSmall
|
||||
case BoldTitleSmall
|
||||
|
||||
public var defaultValue: TitleLockupTitleTypographicalStyle { .BoldTitleSmall }
|
||||
public var defaultValue: TitleLockup.TitleTextStyle { .BoldTitleSmall }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
public var text: String = ""
|
||||
public var typographicalStyle: TitleTypographicalStyle = .BoldTitleSmall
|
||||
public var textStyle: TextStyle = .BoldTitleSmall
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
public init(text: String,
|
||||
typographicalStyle: TitleTypographicalStyle = .BoldTitleSmall) {
|
||||
textStyle: TextStyle = .BoldTitleSmall) {
|
||||
self.text = text
|
||||
self.typographicalStyle = typographicalStyle
|
||||
self.textStyle = textStyle
|
||||
}
|
||||
|
||||
public func toTitleLockupTitleModel() -> TitleLockupTitleModel {
|
||||
TitleLockupTitleModel(text: text,
|
||||
textAttributes: nil,
|
||||
typographicalStyle: typographicalStyle.value)
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Functions
|
||||
//--------------------------------------------------
|
||||
public func toTitleLockupTitleModel() -> TitleLockup.TitleModel {
|
||||
TitleLockup.TitleModel(text: text,
|
||||
textAttributes: nil,
|
||||
textStyle: textStyle.value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,22 +10,18 @@ import UIKit
|
||||
import VDSColorTokens
|
||||
import Combine
|
||||
|
||||
public enum TitleLockupTextPosition: String, Codable, CaseIterable {
|
||||
case left, center
|
||||
|
||||
var labelTextPosition: TextPosition {
|
||||
switch self {
|
||||
case .left:
|
||||
return .left
|
||||
case .center:
|
||||
return .center
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(VDSTitleLockup)
|
||||
open class TitleLockup: View {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum TextPosition: String, Codable, EnumSubset {
|
||||
case left, center
|
||||
|
||||
public var defaultValue: VDS.TextPosition { .left }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
@ -54,151 +50,151 @@ open class TitleLockup: View {
|
||||
// MARK: - Configuration Properties
|
||||
//--------------------------------------------------
|
||||
// Sizes are from InVision design specs.
|
||||
open var topTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = {
|
||||
open var topTextStyleSpacingConfig: TextStyle.SpacingConfig = {
|
||||
let configs = [
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitleLarge, .TitleLarge],
|
||||
neighboring: [.BodySmall, .BodyMedium, .BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
neighboring: [.TitleMedium, .BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
neighboring: [.TitleMedium, .TitleLarge],
|
||||
spacing: 16.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
neighboring: [.BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.TitleMedium, .TitleLarge],
|
||||
spacing: 16.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
neighboring: [.BodyLarge, .BodyMedium, .TitleMedium],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall],
|
||||
neighboring: [.TitleLarge, .BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.TitleLarge, .TitleXLarge],
|
||||
spacing: 16.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPhone)
|
||||
]
|
||||
return TypographicalStyleSpacingConfig(configs: configs)
|
||||
return TextStyle.SpacingConfig(configs: configs)
|
||||
}()
|
||||
|
||||
open var bottomTypographicalStyleSpacingConfig: TypographicalStyleSpacingConfig = {
|
||||
open var bottomTextStyleSpacingConfig: TextStyle.SpacingConfig = {
|
||||
let configs = [
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitleLarge, .TitleLarge],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitleLarge, .TitleLarge],
|
||||
neighboring: [.BodySmall, .BodyMedium, .BodyLarge],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
neighboring: [.TitleMedium, .BodyLarge],
|
||||
spacing: 16.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
neighboring: [.TitleMedium, .TitleLarge],
|
||||
spacing: 24.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
neighboring: [.BodyLarge],
|
||||
spacing: 24.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.TitleMedium, .TitleLarge],
|
||||
spacing: 24.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall, .BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.BodyLarge],
|
||||
spacing: 24.0,
|
||||
deviceType: .iPad),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitleXLarge, .TitleXLarge],
|
||||
neighboring: [.BodyLarge, .BodyMedium, .BodySmall, .TitleMedium],
|
||||
spacing: 12.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldTitle2XLarge, .Title2XLarge, .BoldFeatureXSmall, .FeatureXSmall],
|
||||
neighboring: [.BodyLarge, .BodyMedium, .TitleMedium],
|
||||
spacing: 16,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureSmall, .FeatureSmall],
|
||||
neighboring: [.TitleLarge, .BodyLarge],
|
||||
spacing: 16.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.TitleLarge, .TitleXLarge],
|
||||
spacing: 24.0,
|
||||
deviceType: .iPhone),
|
||||
|
||||
TypographicalStyleDeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
TextStyle.DeviceSpacingConfig([.BoldFeatureMedium, .FeatureMedium],
|
||||
neighboring: [.BodyLarge],
|
||||
spacing: 24.0,
|
||||
deviceType: .iPhone)
|
||||
]
|
||||
return TypographicalStyleSpacingConfig(configs: configs)
|
||||
return TextStyle.SpacingConfig(configs: configs)
|
||||
}()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
open var textPosition: TitleLockupTextPosition = .left { didSet { didChange() }}
|
||||
open var textPosition: TextPosition = .left { didSet { didChange() }}
|
||||
|
||||
//style
|
||||
open var otherTypograpicalStyle: TitleLockupOtherTypographicalStyle = UIDevice.isIPad ? .BodyLarge : .BodyMedium { didSet { didChange() }}
|
||||
open var otherTextStyle: OtherTextStyle = UIDevice.isIPad ? .BodyLarge : .BodyMedium { didSet { didChange() }}
|
||||
|
||||
//first row
|
||||
open var eyebrowLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
}
|
||||
open var eyebrowModel: TitleLockupEyebrowModel? { didSet { didChange() }}
|
||||
open var eyebrowModel: EyebrowModel? { didSet { didChange() }}
|
||||
|
||||
//second row
|
||||
open var titleLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
}
|
||||
open var titleModel: TitleLockupTitleModel? { didSet { didChange() }}
|
||||
open var titleModel: TitleModel? { didSet { didChange() }}
|
||||
|
||||
//third row
|
||||
open var subTitleLabel = Label().with {
|
||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
}
|
||||
open var subTitleModel: TitleLockupSubTitleModel? { didSet { didChange() }}
|
||||
open var subTitleModel: SubTitleModel? { didSet { didChange() }}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
@ -231,7 +227,7 @@ open class TitleLockup: View {
|
||||
eyebrowModel = nil
|
||||
titleModel = nil
|
||||
subTitleModel = nil
|
||||
otherTypograpicalStyle = .BodyLarge
|
||||
otherTextStyle = .BodyLarge
|
||||
|
||||
}
|
||||
|
||||
@ -241,7 +237,7 @@ open class TitleLockup: View {
|
||||
open override func updateView() {
|
||||
super.updateView()
|
||||
|
||||
let allLabelsTextPosition = textPosition.labelTextPosition
|
||||
let allLabelsTextPosition = textPosition.value
|
||||
var eyebrowTextIsEmpty = true
|
||||
var titleTextIsEmpty = true
|
||||
var subTitleTextIsEmpty = true
|
||||
@ -249,7 +245,7 @@ open class TitleLockup: View {
|
||||
if let eyebrowModel, !eyebrowModel.text.isEmpty {
|
||||
eyebrowTextIsEmpty = false
|
||||
eyebrowLabel.textPosition = allLabelsTextPosition
|
||||
eyebrowLabel.typograpicalStyle = otherTypograpicalStyle.value
|
||||
eyebrowLabel.textStyle = otherTextStyle.value
|
||||
eyebrowLabel.text = eyebrowModel.text
|
||||
eyebrowLabel.attributes = eyebrowModel.textAttributes
|
||||
eyebrowLabel.numberOfLines = eyebrowModel.numberOfLines
|
||||
@ -261,7 +257,7 @@ open class TitleLockup: View {
|
||||
if let titleModel, !titleModel.text.isEmpty {
|
||||
titleTextIsEmpty = false
|
||||
titleLabel.textPosition = allLabelsTextPosition
|
||||
titleLabel.typograpicalStyle = titleModel.typographicalStyle.value
|
||||
titleLabel.textStyle = titleModel.textStyle.value
|
||||
titleLabel.text = titleModel.text
|
||||
titleLabel.attributes = titleModel.textAttributes
|
||||
titleLabel.numberOfLines = titleModel.numberOfLines
|
||||
@ -273,7 +269,7 @@ open class TitleLockup: View {
|
||||
if let subTitleModel, !subTitleModel.text.isEmpty {
|
||||
subTitleTextIsEmpty = false
|
||||
subTitleLabel.textPosition = allLabelsTextPosition
|
||||
subTitleLabel.typograpicalStyle = otherTypograpicalStyle.value
|
||||
subTitleLabel.textStyle = otherTextStyle.value
|
||||
subTitleLabel.text = subTitleModel.text
|
||||
subTitleLabel.attributes = subTitleModel.textAttributes
|
||||
subTitleLabel.numberOfLines = subTitleModel.numberOfLines
|
||||
@ -285,14 +281,14 @@ open class TitleLockup: View {
|
||||
|
||||
//if both first 2 rows not empty set spacing
|
||||
if let eyebrowModel, let titleModel, !eyebrowModel.text.isEmpty, !titleModel.text.isEmpty {
|
||||
stackView.spacing = topTypographicalStyleSpacingConfig.spacing(for: titleModel.typographicalStyle.value, neighboring: otherTypograpicalStyle.value)
|
||||
stackView.spacing = topTextStyleSpacingConfig.spacing(for: titleModel.textStyle.value, neighboring: otherTextStyle.value)
|
||||
} else {
|
||||
stackView.spacing = 0.0
|
||||
}
|
||||
|
||||
//if either first 2 rows not empty and subtile not empty, create space else collapse
|
||||
if let titleModel, (!eyebrowTextIsEmpty || !titleTextIsEmpty) && !subTitleTextIsEmpty {
|
||||
let bottomSpace = bottomTypographicalStyleSpacingConfig.spacing(for: titleModel.typographicalStyle.value, neighboring: otherTypograpicalStyle.value)
|
||||
let bottomSpace = bottomTextStyleSpacingConfig.spacing(for: titleModel.textStyle.value, neighboring: otherTextStyle.value)
|
||||
stackView.setCustomSpacing(bottomSpace, after: titleLabel)
|
||||
} else if (!eyebrowTextIsEmpty || !titleTextIsEmpty) && subTitleTextIsEmpty {
|
||||
stackView.setCustomSpacing(0.0, after: titleLabel)
|
||||
@ -304,10 +300,3 @@ open class TitleLockup: View {
|
||||
subTitleLabel.isHidden = subTitleTextIsEmpty
|
||||
}
|
||||
}
|
||||
|
||||
extension TypographicalStyle {
|
||||
func isWithin(_ collection: [TypographicalStyle]) -> Bool {
|
||||
(collection.first(where: {$0 == self}) != nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,16 +7,18 @@
|
||||
|
||||
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
|
||||
extension TitleLockup {
|
||||
public struct EyebrowModel {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,19 +7,21 @@
|
||||
|
||||
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
|
||||
extension TitleLockup {
|
||||
public struct SubTitleModel {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
48
VDS/Components/TitleLockup/TitleLockupTextStyle.swift
Normal file
48
VDS/Components/TitleLockup/TitleLockupTextStyle.swift
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// TitleLockupTextStyle.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 1/6/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension TitleLockup {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum TitleTextStyle: 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: TextStyle {.BoldFeatureXSmall }
|
||||
}
|
||||
|
||||
public enum OtherTextStyle: String, Codable, EnumSubset {
|
||||
case BodyLarge
|
||||
case BoldBodyLarge
|
||||
case BodyMedium
|
||||
case BoldBodyMedium
|
||||
case BodySmall
|
||||
case BoldBodySmall
|
||||
|
||||
public var defaultValue: TextStyle {.BodyLarge }
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,19 +7,21 @@
|
||||
|
||||
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
|
||||
extension TitleLockup {
|
||||
public struct TitleModel {
|
||||
public var text: String
|
||||
public var textAttributes: [any LabelAttributeModel]?
|
||||
public var textStyle: TitleTextStyle
|
||||
public var numberOfLines: Int
|
||||
|
||||
public init(text: String,
|
||||
textAttributes: [any LabelAttributeModel]? = nil,
|
||||
textStyle: TitleTextStyle = .BoldFeatureXSmall,
|
||||
numberOfLines: Int = 0) {
|
||||
self.text = text
|
||||
self.textAttributes = textAttributes
|
||||
self.textStyle = textStyle
|
||||
self.numberOfLines = numberOfLines
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
//
|
||||
// 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 }
|
||||
}
|
||||
@ -9,19 +9,6 @@ import Foundation
|
||||
import UIKit
|
||||
import VDSColorTokens
|
||||
import Combine
|
||||
|
||||
public enum ToggleTextSize: String, CaseIterable {
|
||||
case small, large
|
||||
}
|
||||
|
||||
public enum ToggleTextWeight: String, CaseIterable {
|
||||
case regular, bold
|
||||
}
|
||||
|
||||
public enum ToggleTextPosition: String, CaseIterable {
|
||||
case left, right
|
||||
}
|
||||
|
||||
/**
|
||||
A custom implementation of Apple's UISwitch.
|
||||
|
||||
@ -43,6 +30,20 @@ public class Toggle: ToggleBase{
|
||||
|
||||
@objc(VDSToggleBase)
|
||||
open class ToggleBase: Control, Accessable, DataTrackable {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
public enum TextSize: String, Codable, CaseIterable {
|
||||
case small, large
|
||||
}
|
||||
|
||||
public enum TextWeight: String, Codable, CaseIterable {
|
||||
case regular, bold
|
||||
}
|
||||
|
||||
public enum TextPosition: String, Codable, CaseIterable {
|
||||
case left, right
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
@ -101,7 +102,7 @@ open class ToggleBase: Control, Accessable, DataTrackable {
|
||||
$0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forState: .selected)
|
||||
}
|
||||
|
||||
private var typograpicalStyle: TypographicalStyle {
|
||||
private var textStyle: TextStyle {
|
||||
if textSize == .small {
|
||||
if textWeight == .bold {
|
||||
return .BoldBodySmall
|
||||
@ -138,11 +139,11 @@ open class ToggleBase: Control, Accessable, DataTrackable {
|
||||
|
||||
open var offText: String = "Off" { didSet { didChange() }}
|
||||
|
||||
open var textSize: ToggleTextSize = .small { didSet { didChange() }}
|
||||
open var textSize: TextSize = .small { didSet { didChange() }}
|
||||
|
||||
open var textWeight: ToggleTextWeight = .regular { didSet { didChange() }}
|
||||
open var textWeight: TextWeight = .regular { didSet { didChange() }}
|
||||
|
||||
open var textPosition: ToggleTextPosition = .left { didSet { didChange() }}
|
||||
open var textPosition: TextPosition = .left { didSet { didChange() }}
|
||||
|
||||
open var inputId: String? { didSet { didChange() }}
|
||||
|
||||
@ -224,7 +225,7 @@ open class ToggleBase: Control, Accessable, DataTrackable {
|
||||
|
||||
if showText {
|
||||
label.textPosition = textPosition == .left ? .left : .right
|
||||
label.typograpicalStyle = typograpicalStyle
|
||||
label.textStyle = textStyle
|
||||
label.text = isOn ? onText : offText
|
||||
label.surface = surface
|
||||
label.disabled = disabled
|
||||
|
||||
@ -23,7 +23,7 @@ public enum TextPosition: String, Codable, CaseIterable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum TypographicalStyle: String, Codable, CaseIterable {
|
||||
public enum TextStyle: String, Codable, CaseIterable {
|
||||
|
||||
case FeatureXLarge
|
||||
case BoldFeatureXLarge
|
||||
@ -57,13 +57,13 @@ public enum TypographicalStyle: String, Codable, CaseIterable {
|
||||
case Micro
|
||||
case BoldMicro
|
||||
|
||||
public static var defaultStyle: TypographicalStyle {
|
||||
public static var defaultStyle: TextStyle {
|
||||
return .BodyLarge
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: FontCategory
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public enum FontCategory: String, Codable, CaseIterable {
|
||||
case feature = "Feature"
|
||||
case title = "Title"
|
||||
@ -83,9 +83,9 @@ extension TypographicalStyle {
|
||||
}
|
||||
}
|
||||
|
||||
public func style(for fontSize: FontSize?, isBold: Bool = false) -> TypographicalStyle? {
|
||||
public func style(for fontSize: FontSize?, isBold: Bool = false) -> TextStyle? {
|
||||
let styleName = "\(isBold ? "Bold" : "")\(self.rawValue)\(fontSize?.rawValue ?? "")"
|
||||
guard let style = TypographicalStyle(rawValue: styleName) else {
|
||||
guard let style = TextStyle(rawValue: styleName) else {
|
||||
return nil
|
||||
}
|
||||
return style
|
||||
@ -94,7 +94,7 @@ extension TypographicalStyle {
|
||||
}
|
||||
|
||||
//MARK: FontSize
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public enum FontSize: String, Codable, CaseIterable {
|
||||
case xxlarge = "2XLarge"
|
||||
case xlarge = "XLarge"
|
||||
@ -106,7 +106,7 @@ extension TypographicalStyle {
|
||||
}
|
||||
|
||||
//MARK: PointSize
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public var pointSize: CGFloat {
|
||||
switch self {
|
||||
case .FeatureXLarge, .BoldFeatureXLarge:
|
||||
@ -142,7 +142,7 @@ extension TypographicalStyle {
|
||||
}
|
||||
|
||||
//MARK: LineHeight
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public var lineHeight: CGFloat {
|
||||
switch self {
|
||||
case .FeatureXLarge, .BoldFeatureXLarge:
|
||||
@ -178,7 +178,7 @@ extension TypographicalStyle {
|
||||
}
|
||||
|
||||
//MARK: LetterSpacing
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public var letterSpacing: CGFloat {
|
||||
switch self {
|
||||
case .FeatureXLarge,
|
||||
@ -202,14 +202,14 @@ extension TypographicalStyle {
|
||||
}
|
||||
|
||||
//MARK: Alignments
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public var aligments: [TextPosition] {
|
||||
return [.left, .center]
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: Fonts
|
||||
extension TypographicalStyle {
|
||||
extension TextStyle {
|
||||
public var fontFace: Fonts {
|
||||
switch self {
|
||||
case .BoldFeatureXLarge,
|
||||
@ -261,8 +261,8 @@ extension TypographicalStyle {
|
||||
}
|
||||
}
|
||||
|
||||
extension TypographicalStyle {
|
||||
public static func style(for fontName: String, size: CGFloat) -> TypographicalStyle? {
|
||||
extension TextStyle {
|
||||
public static func style(for fontName: String, size: CGFloat) -> TextStyle? {
|
||||
//filter all styles by fontName
|
||||
let styles = allCases.filter{$0.fontFace.fontName == fontName }.sorted { lhs, rhs in lhs.pointSize < rhs.pointSize }
|
||||
|
||||
@ -282,35 +282,44 @@ extension TypographicalStyle {
|
||||
}
|
||||
}
|
||||
|
||||
public struct TypographicalStyleSpacingConfig {
|
||||
public var defaultSpacing: CGFloat = 8.0
|
||||
public var configs: [TypographicalStyleDeviceSpacingConfig]
|
||||
|
||||
public func spacing(for style: TypographicalStyle, neighboring: TypographicalStyle) -> CGFloat {
|
||||
let deviceType: TypographicalStyleDeviceSpacingConfig.DeviceType = UIDevice.isIPad ? .iPad : .iPhone
|
||||
if let config = configs.first(where:
|
||||
{ style.isWithin($0.primaryStyles) && neighboring.isWithin($0.neighboringStyles) &&
|
||||
($0.deviceType == deviceType || $0.deviceType == .all )})
|
||||
{
|
||||
return config.spacing
|
||||
}
|
||||
return defaultSpacing
|
||||
extension TextStyle {
|
||||
public func isWithin(_ collection: [TextStyle]) -> Bool {
|
||||
(collection.first(where: {$0 == self}) != nil)
|
||||
}
|
||||
}
|
||||
|
||||
public struct TypographicalStyleDeviceSpacingConfig {
|
||||
public enum DeviceType {
|
||||
case iPhone, iPad, all
|
||||
extension TextStyle {
|
||||
public struct SpacingConfig {
|
||||
public var defaultSpacing: CGFloat = 8.0
|
||||
public var configs: [TextStyle.DeviceSpacingConfig]
|
||||
|
||||
public func spacing(for style: TextStyle, neighboring: TextStyle) -> CGFloat {
|
||||
let deviceType: TextStyle.DeviceSpacingConfig.DeviceType = UIDevice.isIPad ? .iPad : .iPhone
|
||||
if let config = configs.first(where:
|
||||
{ style.isWithin($0.primaryStyles) && neighboring.isWithin($0.neighboringStyles) &&
|
||||
($0.deviceType == deviceType || $0.deviceType == .all )})
|
||||
{
|
||||
return config.spacing
|
||||
}
|
||||
return defaultSpacing
|
||||
}
|
||||
}
|
||||
public var spacing: CGFloat
|
||||
public var deviceType: DeviceType = .iPhone
|
||||
public var primaryStyles: [TypographicalStyle]
|
||||
public var neighboringStyles: [TypographicalStyle]
|
||||
|
||||
public init(_ primaryStyles: [TypographicalStyle], neighboring: [TypographicalStyle], spacing: CGFloat, deviceType: DeviceType = .iPhone) {
|
||||
self.spacing = spacing
|
||||
self.primaryStyles = primaryStyles
|
||||
self.neighboringStyles = neighboring
|
||||
self.deviceType = deviceType
|
||||
public struct DeviceSpacingConfig {
|
||||
public enum DeviceType {
|
||||
case iPhone, iPad, all
|
||||
}
|
||||
public var spacing: CGFloat
|
||||
public var deviceType: DeviceType = .iPhone
|
||||
public var primaryStyles: [TextStyle]
|
||||
public var neighboringStyles: [TextStyle]
|
||||
|
||||
public init(_ primaryStyles: [TextStyle], neighboring: [TextStyle], spacing: CGFloat, deviceType: DeviceType = .iPhone) {
|
||||
self.spacing = spacing
|
||||
self.primaryStyles = primaryStyles
|
||||
self.neighboringStyles = neighboring
|
||||
self.deviceType = deviceType
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user