From a09d77760d22bd080f04305c8e7115d72fe4d3ee Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 20 Jul 2023 13:06:02 -0500 Subject: [PATCH 01/10] updated version Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- VDS/SupportingFiles/ReleaseNotes.txt | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index db7de433..dadd0df1 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1135,7 +1135,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 29; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1172,7 +1172,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 29; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 057162db..663f2ae5 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,8 @@ +1.0.29 +======= +- Upated TextStyle and Label for dealing with Top/Bottom insets +- Refactored Code for Checkbox/RadioButton/Toggle + 1.0.28 ======= - CXTDT-423141- Tabs - Incorrect spacing on top-aligned Fill container From 61e843f8f806fca028c176485b09f9a70f3a9614 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 21 Jul 2023 10:43:36 -0500 Subject: [PATCH 02/10] added check for change of scaledFonts Signed-off-by: Matt Bruce --- VDS/Components/Buttons/Button/ButtonBase.swift | 3 +++ VDS/Components/Label/Label.swift | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/VDS/Components/Buttons/Button/ButtonBase.swift b/VDS/Components/Buttons/Button/ButtonBase.swift index c27a4a06..a3bd1941 100644 --- a/VDS/Components/Buttons/Button/ButtonBase.swift +++ b/VDS/Components/Buttons/Button/ButtonBase.swift @@ -53,6 +53,8 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab open var attributes: [any LabelAttributeModel]? { nil } + open var useScaledFont: Bool = false { didSet { setNeedsUpdate() }} + open var surface: Surface = .light { didSet { setNeedsUpdate() }} open var userInfo = [String: Primitive]() @@ -177,6 +179,7 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab //create the primary string let mutableText = NSMutableAttributedString.mutableText(for: text ?? "No Text", textStyle: textStyle, + useScaledFont: useScaledFont, textColor: textColor, alignment: titleLabel?.textAlignment ?? .center, lineBreakMode: titleLabel?.lineBreakMode ?? .byTruncatingTail) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 5b0b6ffb..203e669d 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -27,6 +27,8 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { open var useAttributedText: Bool = false + open var useScaledFont: Bool = false { didSet { setNeedsUpdate() }} + open var surface: Surface = .light { didSet { setNeedsUpdate() }} open var attributes: [any LabelAttributeModel]? { didSet { setNeedsUpdate() }} @@ -89,6 +91,13 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { //-------------------------------------------------- open func initialSetup() { if !initialSetupPerformed { + //register for ContentSizeChanges + NotificationCenter + .Publisher(center: .default, name: UIContentSizeCategory.didChangeNotification) + .sink { [weak self] notification in + self?.setNeedsUpdate() + }.store(in: &subscribers) + backgroundColor = .clear numberOfLines = 0 lineBreakMode = .byWordWrapping @@ -135,6 +144,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { //create the primary string let mutableText = NSMutableAttributedString.mutableText(for: text, textStyle: textStyle, + useScaledFont: useScaledFont, textColor: textColorConfiguration.getColor(self), alignment: textPosition.textAlignment, lineBreakMode: lineBreakMode) From 02150f8e8cf6c730f958bbab03001ea098a83eaa Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 21 Jul 2023 10:43:55 -0500 Subject: [PATCH 03/10] added helper for scaledFonts Signed-off-by: Matt Bruce --- VDS/Fonts/FontProtocol.swift | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/VDS/Fonts/FontProtocol.swift b/VDS/Fonts/FontProtocol.swift index 9524f2a4..74ad8701 100644 --- a/VDS/Fonts/FontProtocol.swift +++ b/VDS/Fonts/FontProtocol.swift @@ -39,13 +39,16 @@ extension FontProtocol { throw error!.takeUnretainedValue() } } - - public func font(ofSize size: CGFloat) -> UIFont{ + + public func font(ofSize size: CGFloat, isScaled: Bool = true) -> UIFont{ DispatchQueue.once(block: { self.register() }) - if let font = UIFont(name: self.fontName, size: size){ - return UIFontMetrics.default.scaledFont(for: font) - } else { - return UIFontMetrics.default.scaledFont(for: UIFont.systemFont(ofSize: size)) - } + guard let found = UIFont(name: self.fontName, size: size) else { return .systemFont(ofSize: size) } + return found + } +} + +extension UIFont { + public var scaledFont: UIFont { + UIFontMetrics.default.scaledFont(for: self) } } From 2d0252311a872c61f8159a8af143d9cdc60edd52 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 21 Jul 2023 10:44:06 -0500 Subject: [PATCH 04/10] updated attributedString Signed-off-by: Matt Bruce --- VDS/Extensions/NSAttributedString.swift | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/VDS/Extensions/NSAttributedString.swift b/VDS/Extensions/NSAttributedString.swift index 814f3c98..871f6b18 100644 --- a/VDS/Extensions/NSAttributedString.swift +++ b/VDS/Extensions/NSAttributedString.swift @@ -19,20 +19,28 @@ extension NSAttributedString { } extension NSMutableAttributedString { - public static func mutableText(for text: String, textStyle: TextStyle, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString { + public static func mutableText(for text: String, textStyle: TextStyle, useScaledFont: Bool = true, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString { //create the paragraph for specific properties let paragraph = NSMutableParagraphStyle() paragraph.alignment = alignment paragraph.lineBreakMode = lineBreakMode + var defaultFont = textStyle.font + var lineHeight = textStyle.lineHeight + + if useScaledFont { + lineHeight = textStyle.scaledLineHeight + defaultFont = defaultFont.scaledFont + } + //set lineHeight if textStyle.lineHeight > 0.0 { - paragraph.maximumLineHeight = textStyle.lineHeight + paragraph.maximumLineHeight = lineHeight } //create the attributeArray - var attributes: [NSAttributedString.Key : Any] = [.font: textStyle.font, + var attributes: [NSAttributedString.Key : Any] = [.font: defaultFont, .foregroundColor: textColor, .paragraphStyle: paragraph] From dffede13500acb7994b4eba69598f810ad5ee96c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 21 Jul 2023 10:44:24 -0500 Subject: [PATCH 05/10] refactored Typography into new files Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 28 ++ VDS/Extensions/RawRepresentable.swift | 15 + VDS/Extensions/VDSTypography.swift | 14 + VDS/Typography/Typogprahy+Styles.swift | 251 +++++++++++ VDS/Typography/Typography+Additional.swift | 76 ++++ .../Typography+ContentSizeCategory.swift | 30 ++ VDS/Typography/Typography+Enums.swift | 92 ++++ VDS/Typography/Typography+SpacingConfig.swift | 44 ++ VDS/Typography/Typography.swift | 402 +----------------- 9 files changed, 551 insertions(+), 401 deletions(-) create mode 100644 VDS/Extensions/RawRepresentable.swift create mode 100644 VDS/Extensions/VDSTypography.swift create mode 100644 VDS/Typography/Typogprahy+Styles.swift create mode 100644 VDS/Typography/Typography+Additional.swift create mode 100644 VDS/Typography/Typography+ContentSizeCategory.swift create mode 100644 VDS/Typography/Typography+Enums.swift create mode 100644 VDS/Typography/Typography+SpacingConfig.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index dadd0df1..491b4bda 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -13,6 +13,13 @@ 5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; }; 5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; }; EA0D1C372A681CCE00E5C127 /* ToggleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C362A681CCE00E5C127 /* ToggleView.swift */; }; + EA0D1C392A6AD4DF00E5C127 /* Typography+SpacingConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */; }; + EA0D1C3B2A6AD51B00E5C127 /* Typogprahy+Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */; }; + EA0D1C3D2A6AD57600E5C127 /* Typography+Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */; }; + EA0D1C3F2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C3E2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift */; }; + EA0D1C412A6AD61C00E5C127 /* Typography+Additional.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */; }; + EA0D1C432A6AD70900E5C127 /* VDSTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C422A6AD70900E5C127 /* VDSTypography.swift */; }; + EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */; }; EA0FC2C62914222900DF80B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */; }; EA1DA1CB2A2E36DC001C51D2 /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1DA1CA2A2E36DC001C51D2 /* SelectorBase.swift */; }; EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1F266128B945070033E859 /* RadioSwatch.swift */; }; @@ -150,6 +157,13 @@ 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = ""; }; 5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; EA0D1C362A681CCE00E5C127 /* ToggleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleView.swift; sourceTree = ""; }; + EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+SpacingConfig.swift"; sourceTree = ""; }; + EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typogprahy+Styles.swift"; sourceTree = ""; }; + EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+Enums.swift"; sourceTree = ""; }; + EA0D1C3E2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+ContentSizeCategory.swift"; sourceTree = ""; }; + EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+Additional.swift"; sourceTree = ""; }; + EA0D1C422A6AD70900E5C127 /* VDSTypography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSTypography.swift; sourceTree = ""; }; + EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawRepresentable.swift; sourceTree = ""; }; EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = ""; }; EA1DA1CA2A2E36DC001C51D2 /* SelectorBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = ""; }; EA1F266128B945070033E859 /* RadioSwatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = ""; }; @@ -446,6 +460,7 @@ EAF7F0992899B17200B287F5 /* CATransaction.swift */, EA33622D2891EA3C0071C351 /* DispatchQueue+Once.swift */, EABFEB632A26473700C4C106 /* NSAttributedString.swift */, + EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */, EAB2376529E9952D00AABE9A /* UIApplication.swift */, EA3361A7288B23300071C351 /* UIColor.swift */, EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */, @@ -455,6 +470,7 @@ EAD062A62A3B67770015965D /* UIView+CALayer.swift */, EAB5FF0029424ACB00998C17 /* UIControl.swift */, EA985C662970C21600F2FF2E /* VDSLayout.swift */, + EA0D1C422A6AD70900E5C127 /* VDSTypography.swift */, ); path = Extensions; sourceTree = ""; @@ -638,6 +654,11 @@ isa = PBXGroup; children = ( EAB1D2CE28ABEF2B00DAE764 /* Typography.swift */, + EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */, + EA0D1C3E2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift */, + EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */, + EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */, + EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */, ); path = Typography; sourceTree = ""; @@ -881,7 +902,9 @@ EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */, EA985C2D296F03FE00F2FF2E /* TileletIconModels.swift in Sources */, EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */, + EA0D1C3F2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift in Sources */, EA5F86C82A1BD99100BC83E4 /* TabModel.swift in Sources */, + EA0D1C432A6AD70900E5C127 /* VDSTypography.swift in Sources */, EA297A5729FB0A360031ED56 /* AppleGuidlinesTouchable.swift in Sources */, EA3361C328902D960071C351 /* Toggle.swift in Sources */, EAF7F0A0289AB7EC00B287F5 /* View.swift in Sources */, @@ -891,6 +914,7 @@ EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */, EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */, EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */, + EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */, EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */, EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */, EAC925832911B35400091998 /* TextLinkCaret.swift in Sources */, @@ -900,6 +924,7 @@ EA985BF7296C665E00F2FF2E /* IconName.swift in Sources */, EA8141102A127066004F60D2 /* UIColor+VDSColor.swift in Sources */, EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */, + EA0D1C412A6AD61C00E5C127 /* Typography+Additional.swift in Sources */, EAC925842911C63100091998 /* Colorable.swift in Sources */, EAB5FEF5292D371F00998C17 /* ButtonBase.swift in Sources */, EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */, @@ -935,7 +960,9 @@ EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */, EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */, EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */, + EA0D1C3B2A6AD51B00E5C127 /* Typogprahy+Styles.swift in Sources */, EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */, + EA0D1C3D2A6AD57600E5C127 /* Typography+Enums.swift in Sources */, EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */, EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */, EA985C7D297DAED300F2FF2E /* Primitive.swift in Sources */, @@ -966,6 +993,7 @@ EA3361B6288B2A410071C351 /* Control.swift in Sources */, 5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */, EAF7F0B7289C12A600B287F5 /* UITapGestureRecognizer.swift in Sources */, + EA0D1C392A6AD4DF00E5C127 /* Typography+SpacingConfig.swift in Sources */, EAB2376629E9952D00AABE9A /* UIApplication.swift in Sources */, EAB5FED429267EB300998C17 /* UIView.swift in Sources */, EAB2376829E9992800AABE9A /* TooltipAlertViewController.swift in Sources */, diff --git a/VDS/Extensions/RawRepresentable.swift b/VDS/Extensions/RawRepresentable.swift new file mode 100644 index 00000000..7b1f0bca --- /dev/null +++ b/VDS/Extensions/RawRepresentable.swift @@ -0,0 +1,15 @@ +// +// RawRepresentable.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation + +/// Helper method to check to see if you exist in a collection +extension RawRepresentable where Self.RawValue: Equatable { + public func isWithin(_ collection: [Self]) -> Bool { + (collection.first(where: {$0 == self}) != nil) + } +} diff --git a/VDS/Extensions/VDSTypography.swift b/VDS/Extensions/VDSTypography.swift new file mode 100644 index 00000000..f8e29c44 --- /dev/null +++ b/VDS/Extensions/VDSTypography.swift @@ -0,0 +1,14 @@ +// +// VDSTypography.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation +import VDSTypographyTokens + +extension VDSTypography { + public static let letterSpacingSemiWide: CGFloat = 0.25 +} + diff --git a/VDS/Typography/Typogprahy+Styles.swift b/VDS/Typography/Typogprahy+Styles.swift new file mode 100644 index 00000000..3894b3f7 --- /dev/null +++ b/VDS/Typography/Typogprahy+Styles.swift @@ -0,0 +1,251 @@ +// +// Typogprahy+Styles.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation +import VDSTypographyTokens + +//MARK: Definitions +extension TextStyle { + + // Static properties for different text styles + public static let featureXLarge = TextStyle(rawValue: "featureXLarge", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldFeatureXLarge = TextStyle(rawValue: "boldFeatureXLarge", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, + letterSpacing: 0) + + public static let featureLarge = TextStyle(rawValue: "featureLarge", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldFeatureLarge = TextStyle(rawValue: "boldFeatureLarge", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, + letterSpacing: 0) + + public static let featureMedium = TextStyle(rawValue: "featureMedium", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldFeatureMedium = TextStyle(rawValue: "boldFeatureMedium", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, + letterSpacing: 0) + + public static let featureSmall = TextStyle(rawValue: "featureSmall", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldFeatureSmall = TextStyle(rawValue: "boldFeatureSmall", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, + letterSpacing: 0) + + public static let featureXSmall = TextStyle(rawValue: "featureXSmall", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldFeatureXSmall = TextStyle(rawValue: "boldFeatureXSmall", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, + letterSpacing: 0) + + public static let title2XLarge = TextStyle(rawValue: "title2XLarge", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldTitle2XLarge = TextStyle(rawValue: "boldTitle2XLarge", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, + letterSpacing: 0) + + public static let titleXLarge = TextStyle(rawValue: "titleXLarge", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldTitleXLarge = TextStyle(rawValue: "boldTitleXLarge", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36, + letterSpacing: 0) + + public static let titleLarge = TextStyle(rawValue: "titleLarge", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28, + letterSpacing: VDSTypography.letterSpacingSemiWide) + + public static let boldTitleLarge = TextStyle(rawValue: "boldTitleLarge", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28, + letterSpacing: 0) + + public static let titleMedium = TextStyle(rawValue: "titleMedium", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24, + letterSpacing: 0) + + public static let boldTitleMedium = TextStyle(rawValue: "boldTitleMedium", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24, + letterSpacing: 0) + + public static let titleSmall = TextStyle(rawValue: "titleSmall", + fontFace: .dsLight, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20, + letterSpacing: 0) + + public static let boldTitleSmall = TextStyle(rawValue: "boldTitleSmall", + fontFace: .dsBold, + pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, + lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20, + letterSpacing: 0) + + public static let bodyLarge = TextStyle(rawValue: "bodyLarge", + fontFace: .dsRegular, + pointSize: VDSTypography.fontSizeBody16, + lineHeight: VDSTypography.lineHeightBody20, + letterSpacing:VDSTypography.letterSpacingWide) + + public static let boldBodyLarge = TextStyle(rawValue: "boldBodyLarge", + fontFace: .dsBold, + pointSize: VDSTypography.fontSizeBody16, + lineHeight: VDSTypography.lineHeightBody20, + letterSpacing: VDSTypography.letterSpacingWide) + + public static let bodyMedium = TextStyle(rawValue: "bodyMedium", + fontFace: .dsRegular, + pointSize: VDSTypography.fontSizeBody14, + lineHeight: VDSTypography.lineHeightBody18, + letterSpacing: VDSTypography.letterSpacingWide) + + public static let boldBodyMedium = TextStyle(rawValue: "boldBodyMedium", + fontFace: .dsBold, + pointSize: VDSTypography.fontSizeBody14, + lineHeight: VDSTypography.lineHeightBody18, + letterSpacing: VDSTypography.letterSpacingWide) + + public static let bodySmall = TextStyle(rawValue: "bodySmall", + fontFace: .dsRegular, + pointSize: VDSTypography.fontSizeBody12, + lineHeight: VDSTypography.lineHeightBody16, + letterSpacing: 0) + + public static let boldBodySmall = TextStyle(rawValue: "boldBodySmall", + fontFace: .dsBold, + pointSize: VDSTypography.fontSizeBody12, + lineHeight: VDSTypography.lineHeightBody16, + letterSpacing: 0) + + public static let micro = TextStyle(rawValue: "micro", + fontFace: .dsRegular, + pointSize: VDSTypography.fontSizeMicro11, + lineHeight: VDSTypography.lineHeightMicro16, + letterSpacing: 0) + + public static let boldMicro = TextStyle(rawValue: "boldMicro", + fontFace: .dsBold, + pointSize: VDSTypography.fontSizeMicro11, + lineHeight: VDSTypography.lineHeightMicro16, + letterSpacing: 0) + + public static var allCases: [TextStyle] { + return [ + featureXLarge, + boldFeatureXLarge, + featureLarge, + boldFeatureLarge, + featureMedium, + boldFeatureMedium, + featureSmall, + boldFeatureSmall, + featureXSmall, + boldFeatureXSmall, + title2XLarge, + boldTitle2XLarge, + titleXLarge, + boldTitleXLarge, + titleLarge, + boldTitleLarge, + titleMedium, + boldTitleMedium, + titleSmall, + boldTitleSmall, + bodyLarge, + boldBodyLarge, + bodyMedium, + boldBodyMedium, + bodySmall, + boldBodySmall, + micro, + boldMicro + ] + } +} + +extension TextStyle { + public enum StandardStyle: String, CaseIterable { + case featureXLarge, + featureLarge, + featureMedium, + featureSmall, + featureXSmall, + title2XLarge, + titleXLarge, + titleLarge, + titleMedium, + titleSmall, + bodyLarge, + bodyMedium, + bodySmall, + micro + + public var bold: TextStyle { + return TextStyle(rawValue: "bold\(rawValue.prefix(1).uppercased())\(rawValue.dropFirst())")! + } + + public var regular: TextStyle { + TextStyle(rawValue: rawValue)! + } + } + + public func toStandardStyle() -> StandardStyle { + var rawName = rawValue + if rawName.hasPrefix("bold") { + let updatedRaw = rawName.replacingOccurrences(of: "bold", with: "") + rawName = updatedRaw.prefix(1).lowercased() + updatedRaw.dropFirst() + } + return StandardStyle(rawValue: rawName)! + } +} diff --git a/VDS/Typography/Typography+Additional.swift b/VDS/Typography/Typography+Additional.swift new file mode 100644 index 00000000..1e998b89 --- /dev/null +++ b/VDS/Typography/Typography+Additional.swift @@ -0,0 +1,76 @@ +// +// Typography+Additional.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation +import UIKit +import VDSTypographyTokens + +//MARK: Alignments +extension TextStyle { + + /// Alignments Available for the TextStyle + public var aligments: [TextPosition] { + return [.left, .center] + } +} + +//MARK: Fonts +extension TextStyle { + + /// Font for the TextStyle. + public var font: UIFont { + return fontFace.font(ofSize: pointSize) + } +} + +//MARK: Style Helper +extension TextStyle { + + /// Default style used if no style is given. + public static var defaultStyle: TextStyle { return bodyLarge } + + + /// Find a TextStyle based off a Name. + /// - Parameter name: Name of the TextStyle you want to find. + /// - Returns: TextStyle for the given name. + public static func textStyle(for name: String) -> TextStyle? { + guard let style = TextStyle.allCases.first(where: {$0.rawValue == name }) else { return nil } + return style + } + + /// Returns a TextStyle based off a Font-Name and Size + /// - Parameters: + /// - fontName: Name of the font you want to find. + /// - size: PointSize of the Font you want to find. + /// - Returns: The exact TextStyle based on the FontName and Point Size. + 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 } + + //if there are no styles then return nil + guard styles.count > 0 else { return nil } + + //if there is an exact match on a style with this pointSize then return it + if let style = styles.first(where: {$0.pointSize == size }) { + return style + + } else if let largerIndex = styles.firstIndex(where: { $0.pointSize > size}) { //find the closet one to pointSize + return styles[max(largerIndex - 1, 0)] + + } else { //return the last style + return styles.last! + } + } +} + +extension TextStyle: CustomDebugStringConvertible { + + /// Used for showing the TextStyle Properties. + public var debugDescription: String { + "Name: \(self.rawValue) FontFace: \(font.fontName) FontWeight: \(self.rawValue.hasPrefix("bold") ? "bold" : "normal") PointSize: \(font.pointSize) LetterSpacing: \(letterSpacing) LineHeight: \(lineHeight)" + } +} diff --git a/VDS/Typography/Typography+ContentSizeCategory.swift b/VDS/Typography/Typography+ContentSizeCategory.swift new file mode 100644 index 00000000..a28b0c48 --- /dev/null +++ b/VDS/Typography/Typography+ContentSizeCategory.swift @@ -0,0 +1,30 @@ +// +// Typography+ContentSizeCategory.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation +import UIKit + +extension TextStyle { + /// Determines if the Framework can use scaled fonts for preferredContentSizeCategory + public static var allowScaledFonts: Bool = true + + /// Determines is the User has changed their default preferredContentSizeCategory + public static var canScaleFonts: Bool { + UIApplication.shared.preferredContentSizeCategory != .large && allowScaledFonts + } + + /// The scaled version of the hardcode value 'lineHeight' within a TextStyle. This will only be different + /// from the original if the preferredContentSizeCategory has changed. + public var scaledLineHeight: CGFloat { + let defaultFont = font + let scaledFont = defaultFont.scaledFont + let ratio = scaledFont.pointSize / defaultFont.pointSize + let newLineHeight = (lineHeight * ratio).rounded() + return newLineHeight + } +} + diff --git a/VDS/Typography/Typography+Enums.swift b/VDS/Typography/Typography+Enums.swift new file mode 100644 index 00000000..104515f7 --- /dev/null +++ b/VDS/Typography/Typography+Enums.swift @@ -0,0 +1,92 @@ +// +// Typography+Enums.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation +import UIKit + +//MARK: FontCategory +extension TextStyle { + + /// Used in the Sample App but could be used elsewhere to allow selection of TextStyles + public enum FontCategory: String, CaseIterable { + case feature + case title + case body + case micro + + public var sizes: [FontSize] { + switch self { + case .feature: + return [.xlarge, .large, .medium, .small, .xsmall] + case .title: + return [.xxlarge, .xlarge, .large, .medium, .small] + case .body: + return [.large, .medium, .small] + case .micro: + return [] + } + } + + /// Find the TextStyle for the FontSize. + /// - Parameters: + /// - fontSize: FontSize you are looking for using this FontCategory. + /// - isBold: Whether or not the Font is bold. + /// - Returns: A TextStyle will be returned if all criteria is met, otherwise nil will be returned. + public func style(for fontSize: FontSize?, isBold: Bool = false) -> TextStyle? { + var styleName = "" + if isBold { + let newRaw = rawValue.prefix(1).description.uppercased() + rawValue.dropFirst() + styleName = "\(isBold ? "bold" : "")\(newRaw)\(fontSize?.rawValue ?? "")" + } else { + styleName = "\(rawValue)\(fontSize?.rawValue ?? "")" + } + + guard let style = TextStyle.textStyle(for: styleName) else { + return nil + } + return style + } + } + + /// Find the TextStyle for the specific FontCategory and FontSize. + /// - Parameters: + /// - category: FontCategory you are looking for in the TextStyle + /// - fontSize: FontSize you are looking for using the given FontCategory. + /// - isBold: Whether or not the Font is bold. + /// - Returns: A TextStyle will be returned if all criteria is met, otherwise nil will be returned. + public func style(for category: FontCategory, with size: FontSize, isBold: Bool) -> TextStyle? { + category.style(for: size, isBold: isBold) + } +} + +//MARK: FontSize +extension TextStyle { + public enum FontSize: String, CaseIterable { + case xxlarge = "2XLarge" + case xlarge = "XLarge" + case large = "Large" + case medium = "Medium" + case small = "Small" + case xsmall = "XSmall" + } +} + + +public enum TextPosition: String, CaseIterable { + case left, right, center + + var textAlignment: NSTextAlignment { + switch self { + case .left: + return NSTextAlignment.left + case .right: + return NSTextAlignment.right + case .center: + return NSTextAlignment.center + } + } +} diff --git a/VDS/Typography/Typography+SpacingConfig.swift b/VDS/Typography/Typography+SpacingConfig.swift new file mode 100644 index 00000000..84b61e20 --- /dev/null +++ b/VDS/Typography/Typography+SpacingConfig.swift @@ -0,0 +1,44 @@ +// +// Typography+Spacing.swift +// VDS +// +// Created by Matt Bruce on 7/21/23. +// + +import Foundation +import UIKit + +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 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 + } + } +} diff --git a/VDS/Typography/Typography.swift b/VDS/Typography/Typography.swift index de0a9289..00cf598d 100644 --- a/VDS/Typography/Typography.swift +++ b/VDS/Typography/Typography.swift @@ -8,21 +8,8 @@ import Foundation import VDSTypographyTokens -public enum TextPosition: String, CaseIterable { - case left, right, center - - var textAlignment: NSTextAlignment { - switch self { - case .left: - return NSTextAlignment.left - case .right: - return NSTextAlignment.right - case .center: - return NSTextAlignment.center - } - } -} +/// This is the Definition that will determine how the Text is drawn public struct TextStyle: Equatable, RawRepresentable { public let rawValue: String public let pointSize: CGFloat @@ -54,390 +41,3 @@ public struct TextStyle: Equatable, RawRepresentable { rawValue.hasPrefix("bold") } } - -extension VDSTypography { - public static let letterSpacingSemiWide: CGFloat = 0.25 -} -//MARK: Definitions -extension TextStyle { - - // Static properties for different text styles - public static let featureXLarge = TextStyle(rawValue: "featureXLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldFeatureXLarge = TextStyle(rawValue: "boldFeatureXLarge", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88, - letterSpacing: 0) - - public static let featureLarge = TextStyle(rawValue: "featureLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldFeatureLarge = TextStyle(rawValue: "boldFeatureLarge", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76, - letterSpacing: 0) - - public static let featureMedium = TextStyle(rawValue: "featureMedium", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldFeatureMedium = TextStyle(rawValue: "boldFeatureMedium", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64, - letterSpacing: 0) - - public static let featureSmall = TextStyle(rawValue: "featureSmall", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldFeatureSmall = TextStyle(rawValue: "boldFeatureSmall", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48, - letterSpacing: 0) - - public static let featureXSmall = TextStyle(rawValue: "featureXSmall", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldFeatureXSmall = TextStyle(rawValue: "boldFeatureXSmall", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40, - letterSpacing: 0) - - public static let title2XLarge = TextStyle(rawValue: "title2XLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldTitle2XLarge = TextStyle(rawValue: "boldTitle2XLarge", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40, - letterSpacing: 0) - - public static let titleXLarge = TextStyle(rawValue: "titleXLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldTitleXLarge = TextStyle(rawValue: "boldTitleXLarge", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36, - letterSpacing: 0) - - public static let titleLarge = TextStyle(rawValue: "titleLarge", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28, - letterSpacing: VDSTypography.letterSpacingSemiWide) - - public static let boldTitleLarge = TextStyle(rawValue: "boldTitleLarge", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28, - letterSpacing: 0) - - public static let titleMedium = TextStyle(rawValue: "titleMedium", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24, - letterSpacing: 0) - - public static let boldTitleMedium = TextStyle(rawValue: "boldTitleMedium", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24, - letterSpacing: 0) - - public static let titleSmall = TextStyle(rawValue: "titleSmall", - fontFace: .dsLight, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20, - letterSpacing: 0) - - public static let boldTitleSmall = TextStyle(rawValue: "boldTitleSmall", - fontFace: .dsBold, - pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16, - lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20, - letterSpacing: 0) - - public static let bodyLarge = TextStyle(rawValue: "bodyLarge", - fontFace: .dsRegular, - pointSize: VDSTypography.fontSizeBody16, - lineHeight: VDSTypography.lineHeightBody20, - letterSpacing:VDSTypography.letterSpacingWide) - - public static let boldBodyLarge = TextStyle(rawValue: "boldBodyLarge", - fontFace: .dsBold, - pointSize: VDSTypography.fontSizeBody16, - lineHeight: VDSTypography.lineHeightBody20, - letterSpacing: VDSTypography.letterSpacingWide) - - public static let bodyMedium = TextStyle(rawValue: "bodyMedium", - fontFace: .dsRegular, - pointSize: VDSTypography.fontSizeBody14, - lineHeight: VDSTypography.lineHeightBody18, - letterSpacing: VDSTypography.letterSpacingWide) - - public static let boldBodyMedium = TextStyle(rawValue: "boldBodyMedium", - fontFace: .dsBold, - pointSize: VDSTypography.fontSizeBody14, - lineHeight: VDSTypography.lineHeightBody18, - letterSpacing: VDSTypography.letterSpacingWide) - - public static let bodySmall = TextStyle(rawValue: "bodySmall", - fontFace: .dsRegular, - pointSize: VDSTypography.fontSizeBody12, - lineHeight: VDSTypography.lineHeightBody16, - letterSpacing: 0) - - public static let boldBodySmall = TextStyle(rawValue: "boldBodySmall", - fontFace: .dsBold, - pointSize: VDSTypography.fontSizeBody12, - lineHeight: VDSTypography.lineHeightBody16, - letterSpacing: 0) - - public static let micro = TextStyle(rawValue: "micro", - fontFace: .dsRegular, - pointSize: VDSTypography.fontSizeMicro11, - lineHeight: VDSTypography.lineHeightMicro16, - letterSpacing: 0) - - public static let boldMicro = TextStyle(rawValue: "boldMicro", - fontFace: .dsBold, - pointSize: VDSTypography.fontSizeMicro11, - lineHeight: VDSTypography.lineHeightMicro16, - letterSpacing: 0) - - public static var allCases: [TextStyle] { - return [ - featureXLarge, - boldFeatureXLarge, - featureLarge, - boldFeatureLarge, - featureMedium, - boldFeatureMedium, - featureSmall, - boldFeatureSmall, - featureXSmall, - boldFeatureXSmall, - title2XLarge, - boldTitle2XLarge, - titleXLarge, - boldTitleXLarge, - titleLarge, - boldTitleLarge, - titleMedium, - boldTitleMedium, - titleSmall, - boldTitleSmall, - bodyLarge, - boldBodyLarge, - bodyMedium, - boldBodyMedium, - bodySmall, - boldBodySmall, - micro, - boldMicro - ] - } -} - -extension TextStyle { - public enum StandardStyle: String, CaseIterable { - case featureXLarge, - featureLarge, - featureMedium, - featureSmall, - featureXSmall, - title2XLarge, - titleXLarge, - titleLarge, - titleMedium, - titleSmall, - bodyLarge, - bodyMedium, - bodySmall, - micro - - public var bold: TextStyle { - return TextStyle(rawValue: "bold\(rawValue.prefix(1).uppercased())\(rawValue.dropFirst())")! - } - - public var regular: TextStyle { - TextStyle(rawValue: rawValue)! - } - } - - public func toStandardStyle() -> StandardStyle { - var rawName = rawValue - if rawName.hasPrefix("bold") { - let updatedRaw = rawName.replacingOccurrences(of: "bold", with: "") - rawName = updatedRaw.prefix(1).lowercased() + updatedRaw.dropFirst() - } - return StandardStyle(rawValue: rawName)! - } -} - -//MARK: FontCategory -extension TextStyle { - public enum FontCategory: String, CaseIterable { - case feature - case title - case body - case micro - - public var sizes: [FontSize] { - switch self { - case .feature: - return [.xlarge, .large, .medium, .small, .xsmall] - case .title: - return [.xxlarge, .xlarge, .large, .medium, .small] - case .body: - return [.large, .medium, .small] - case .micro: - return [] - } - } - - public func style(for fontSize: FontSize?, isBold: Bool = false) -> TextStyle? { - var styleName = "" - if isBold { - let newRaw = rawValue.prefix(1).description.uppercased() + rawValue.dropFirst() - styleName = "\(isBold ? "bold" : "")\(newRaw)\(fontSize?.rawValue ?? "")" - } else { - styleName = "\(rawValue)\(fontSize?.rawValue ?? "")" - } - - guard let style = TextStyle.textStyle(for: styleName) else { - return nil - } - return style - } - } -} - -//MARK: FontSize -extension TextStyle { - public enum FontSize: String, CaseIterable { - case xxlarge = "2XLarge" - case xlarge = "XLarge" - case large = "Large" - case medium = "Medium" - case small = "Small" - case xsmall = "XSmall" - } -} - -//MARK: Alignments -extension TextStyle { - public var aligments: [TextPosition] { - return [.left, .center] - } -} - -//MARK: Fonts -extension TextStyle { - public var font: UIFont { - return fontFace.font(ofSize: pointSize) - } -} - -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 } - - //if there are no styles then return nil - guard styles.count > 0 else { return nil } - - //if there is an exact match on a style with this pointSize then return it - if let style = styles.first(where: {$0.pointSize == size }) { - return style - - } else if let largerIndex = styles.firstIndex(where: { $0.pointSize > size}) { //find the closet one to pointSize - return styles[max(largerIndex - 1, 0)] - - } else { //return the last style - return styles.last! - } - } -} - -extension RawRepresentable where Self.RawValue: Equatable { - public func isWithin(_ collection: [Self]) -> Bool { - (collection.first(where: {$0 == self}) != nil) - } -} - -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 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 - } - } - -} - -extension TextStyle: CustomDebugStringConvertible { - public var debugDescription: String { - "Name: \(self.rawValue) FontFace: \(font.fontName) FontWeight: \(self.rawValue.hasPrefix("bold") ? "bold" : "normal") PointSize: \(font.pointSize) LetterSpacing: \(letterSpacing) LineHeight: \(lineHeight)" - } -} - -extension TextStyle { - public static var defaultStyle: TextStyle { return bodyLarge } - - public static func textStyle(for name: String) -> TextStyle? { - guard let style = TextStyle.allCases.first(where: {$0.rawValue == name }) else { return nil } - return style - } -} From 55641beccf3b5036c3ea0d76bed5c19f652262e7 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 21 Jul 2023 16:08:37 -0500 Subject: [PATCH 06/10] updated version Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- VDS/Publishers/UITextField+Publisher.swift | 9 +++++++++ VDS/SupportingFiles/ReleaseNotes.txt | 5 +++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 491b4bda..b2add536 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1163,7 +1163,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 29; + CURRENT_PROJECT_VERSION = 30; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1200,7 +1200,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 29; + CURRENT_PROJECT_VERSION = 30; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/VDS/Publishers/UITextField+Publisher.swift b/VDS/Publishers/UITextField+Publisher.swift index 2e2a4ebc..4cc582d4 100644 --- a/VDS/Publishers/UITextField+Publisher.swift +++ b/VDS/Publishers/UITextField+Publisher.swift @@ -15,4 +15,13 @@ extension UITextField { .map { _ in self.text ?? "" } .eraseToAnyPublisher() } + + public var numberPublisher: AnyPublisher { + publisher(for: .editingChanged) + .map { textField in + guard let text = textField.text, let foundNumber = NumberFormatter().number(from: text) else { return nil } + return foundNumber + } + .eraseToAnyPublisher() + } } diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 663f2ae5..e457386d 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,8 @@ +1.0.30 +======= +- Upated Label to allow Scaled Fonts +- Refactored Code TextStyle + 1.0.29 ======= - Upated TextStyle and Label for dealing with Top/Bottom insets From b9082ac1d28b9e12eb69469368d7b86e686206b9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 21 Jul 2023 16:55:20 -0500 Subject: [PATCH 07/10] updated version Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- VDS/SupportingFiles/ReleaseNotes.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index b2add536..77fc4990 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1163,7 +1163,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1200,7 +1200,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index e457386d..0401f37d 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,4 +1,4 @@ -1.0.30 +1.0.31 ======= - Upated Label to allow Scaled Fonts - Refactored Code TextStyle From d00b1d0a0ec35b3f62d9c225c0ab6bac52756879 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 22 Jul 2023 09:17:42 -0500 Subject: [PATCH 08/10] updated makeAttributedString to use min lineHeight as well as read a var to help determine if this is really needed or not Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- VDS/Extensions/NSAttributedString.swift | 10 +++++++++- VDS/SupportingFiles/ReleaseNotes.txt | 13 +++++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 77fc4990..e320cb6c 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1163,7 +1163,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 32; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1200,7 +1200,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 32; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/VDS/Extensions/NSAttributedString.swift b/VDS/Extensions/NSAttributedString.swift index 871f6b18..49f39f45 100644 --- a/VDS/Extensions/NSAttributedString.swift +++ b/VDS/Extensions/NSAttributedString.swift @@ -19,8 +19,13 @@ extension NSAttributedString { } extension NSMutableAttributedString { + + public static var useMinimumLineHeight: Bool = true public static func mutableText(for text: String, textStyle: TextStyle, useScaledFont: Bool = true, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString { + //var for if you can scale or not + let scaledMode = useScaledFont && TextStyle.canScaleFonts + //create the paragraph for specific properties let paragraph = NSMutableParagraphStyle() paragraph.alignment = alignment @@ -29,13 +34,16 @@ extension NSMutableAttributedString { var defaultFont = textStyle.font var lineHeight = textStyle.lineHeight - if useScaledFont { + if scaledMode { lineHeight = textStyle.scaledLineHeight defaultFont = defaultFont.scaledFont } //set lineHeight if textStyle.lineHeight > 0.0 { + if useMinimumLineHeight { + paragraph.minimumLineHeight = lineHeight + } paragraph.maximumLineHeight = lineHeight } diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 0401f37d..f587beb6 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,11 +1,20 @@ +1.0.32 +======= +- Fixed bug dealing with Scaled +- Added ability to use minimumLineheight in Paragraph for AttributedString creation + 1.0.31 ======= -- Upated Label to allow Scaled Fonts +- updated version only + +1.0.30 +======= +- Updated Label to allow Scaled Fonts - Refactored Code TextStyle 1.0.29 ======= -- Upated TextStyle and Label for dealing with Top/Bottom insets +- Updated TextStyle and Label for dealing with Top/Bottom insets - Refactored Code for Checkbox/RadioButton/Toggle 1.0.28 From 090a65e998bb255baaf7fa7b45c73a6a8135f61d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 22 Jul 2023 12:14:52 -0500 Subject: [PATCH 09/10] added another test property useScaledLineHeight Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 4 ++-- VDS/Extensions/NSAttributedString.swift | 7 +++++-- VDS/SupportingFiles/ReleaseNotes.txt | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index e320cb6c..aea11af8 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -1163,7 +1163,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 32; + CURRENT_PROJECT_VERSION = 33; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1200,7 +1200,7 @@ BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 32; + CURRENT_PROJECT_VERSION = 33; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/VDS/Extensions/NSAttributedString.swift b/VDS/Extensions/NSAttributedString.swift index 49f39f45..ed6f08b8 100644 --- a/VDS/Extensions/NSAttributedString.swift +++ b/VDS/Extensions/NSAttributedString.swift @@ -21,6 +21,7 @@ extension NSAttributedString { extension NSMutableAttributedString { public static var useMinimumLineHeight: Bool = true + public static var useScaledLineHeight: Bool = false public static func mutableText(for text: String, textStyle: TextStyle, useScaledFont: Bool = true, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString { //var for if you can scale or not @@ -35,10 +36,12 @@ extension NSMutableAttributedString { var lineHeight = textStyle.lineHeight if scaledMode { - lineHeight = textStyle.scaledLineHeight defaultFont = defaultFont.scaledFont + if useScaledLineHeight { + lineHeight = textStyle.scaledLineHeight + } } - + //set lineHeight if textStyle.lineHeight > 0.0 { if useMinimumLineHeight { diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index f587beb6..ccf05f42 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,6 @@ +1.0.33 +======= +- 1.0.32 ======= - Fixed bug dealing with Scaled From c16381ce08964f686357ab469d0553b4f06a52fc Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 22 Jul 2023 12:18:11 -0500 Subject: [PATCH 10/10] comments Signed-off-by: Matt Bruce --- VDS/SupportingFiles/ReleaseNotes.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index ccf05f42..c05fd2f4 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,6 +1,7 @@ 1.0.33 ======= -- +- Add test variable to use ratio line height or not + 1.0.32 ======= - Fixed bug dealing with Scaled