diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 1a7114bf..60866898 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */; }; EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */; }; EA4DB30228DCBCA500103EE3 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB30128DCBCA500103EE3 /* Badge.swift */; }; + EA513A952A4E1F82002A4DFF /* TitleLockupStyleConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA513A942A4E1F82002A4DFF /* TitleLockupStyleConfiguration.swift */; }; EA596ABD2A16B4EC00300C4B /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA596ABC2A16B4EC00300C4B /* Tab.swift */; }; EA596ABF2A16B4F500300C4B /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA596ABE2A16B4F500300C4B /* Tabs.swift */; }; EA5E304C294CBDD00082B959 /* TileContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304B294CBDD00082B959 /* TileContainer.swift */; }; @@ -177,6 +178,7 @@ EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupHandlerBase.swift; sourceTree = ""; }; EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyEquatable.swift; sourceTree = ""; }; EA4DB30128DCBCA500103EE3 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; + EA513A942A4E1F82002A4DFF /* TitleLockupStyleConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLockupStyleConfiguration.swift; sourceTree = ""; }; EA596ABC2A16B4EC00300C4B /* Tab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tab.swift; sourceTree = ""; }; EA596ABE2A16B4F500300C4B /* Tabs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = ""; }; EA5E304B294CBDD00082B959 /* TileContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainer.swift; sourceTree = ""; }; @@ -569,6 +571,7 @@ EA985BED2968A92400F2FF2E /* TitleLockupSubTitleModel.swift */, EA985BEB2968A91200F2FF2E /* TitleLockupTitleModel.swift */, EA985BF12968B5BB00F2FF2E /* TitleLockupTextStyle.swift */, + EA513A942A4E1F82002A4DFF /* TitleLockupStyleConfiguration.swift */, ); path = TitleLockup; sourceTree = ""; @@ -795,7 +798,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1340; - LastUpgradeCheck = 1340; + LastUpgradeCheck = 1430; TargetAttributes = { EA33616B288B19200071C351 = { CreatedOnToolsVersion = 13.4.1; @@ -917,6 +920,7 @@ EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */, EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */, EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */, + EA513A952A4E1F82002A4DFF /* TitleLockupStyleConfiguration.swift in Sources */, 44604AD729CE196600E62B51 /* Line.swift in Sources */, EA5E3058295105A40082B959 /* Tilelet.swift in Sources */, EA89201528B56CF4006B9984 /* RadioBoxGroup.swift in Sources */, @@ -1105,13 +1109,15 @@ isa = XCBuildConfiguration; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 24; + CURRENT_PROJECT_VERSION = 25; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../SharedFrameworks"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; @@ -1123,6 +1129,8 @@ "@loader_path/Frameworks", ); MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; PRODUCT_BUNDLE_IDENTIFIER = com.vzw.vds; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; @@ -1138,13 +1146,15 @@ isa = XCBuildConfiguration; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 24; + CURRENT_PROJECT_VERSION = 25; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../SharedFrameworks"; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; @@ -1156,6 +1166,8 @@ "@loader_path/Frameworks", ); MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; PRODUCT_BUNDLE_IDENTIFIER = com.vzw.vds; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; diff --git a/VDS/Components/BadgeIndicator/BadgeIndicator.swift b/VDS/Components/BadgeIndicator/BadgeIndicator.swift index a1d7fed1..ad64cf7b 100644 --- a/VDS/Components/BadgeIndicator/BadgeIndicator.swift +++ b/VDS/Components/BadgeIndicator/BadgeIndicator.swift @@ -368,7 +368,7 @@ open class BadgeIndicator: View { let frame = badgeView.frame //default calculation if a dotSize isn't given - var dot: CGFloat = frame.width * 0.1875 + var dot: CGFloat = frame.height * 0.1875 if let dotSize, dotSize < frame.width, dotSize < frame.height { dot = dotSize } diff --git a/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift b/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift index 594a51e5..d1b8559c 100644 --- a/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift +++ b/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift @@ -89,14 +89,7 @@ open class TextLinkCaret: ButtonBase { //-------------------------------------------------- override open var intrinsicContentSize: CGSize { //get the labels size, if not the button - let size = titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize - - var itemWidth = size.width - - if let caretWidth = imageAttribute?.width { - itemWidth += caretWidth - } - return CGSize(width: itemWidth, height: size.height) + return titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize } open override func updateView() { diff --git a/VDS/Components/Icon/IconName.swift b/VDS/Components/Icon/IconName.swift index 2fed2c94..ebb666b4 100644 --- a/VDS/Components/Icon/IconName.swift +++ b/VDS/Components/Icon/IconName.swift @@ -21,30 +21,30 @@ extension Icon { 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 checkmarkBold = Name(name: "checkmark-bold") 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 paginationLeftCaret = Name(name: "pagination-left-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 paginationRightCaret = Name(name: "pagination-right-caret") + internal static let verizonUp = Name(name: "verizon-up") internal static let warningBold = Name(name: "warning-bold") + + public static let checkmark = Name(name: "checkmark") + public static let checkmarkAlt = Name(name: "checkmark-alt") + public static let close = Name(name: "close") + public static let error = Name(name: "error") + public static let info = Name(name: "info") + public static let multipleDocuments = Name(name: "multiple-documents") + public static let leftArrow = Name(name: "left-arrow") + public static let leftCaret = Name(name: "left-caret") + public static let rightArrow = Name(name: "right-arrow") + public static let rightCaret = Name(name: "right-caret") + public static let warning = Name(name: "warning") } } diff --git a/VDS/Components/Tabs/Tab.swift b/VDS/Components/Tabs/Tab.swift index 4948fb6b..eabc4da3 100644 --- a/VDS/Components/Tabs/Tab.swift +++ b/VDS/Components/Tabs/Tab.swift @@ -73,7 +73,7 @@ extension Tabs { private var leadingSpace: CGFloat { guard orientation == .vertical else { return 0 } - return size == .medium ? VDSLayout.Spacing.space4X.value : VDSLayout.Spacing.space6X.value + return VDSLayout.Spacing.space4X.value } private var otherSpace: CGFloat { diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 99bc633b..c91c7eba 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -70,65 +70,50 @@ open class Tilelet: TileContainer { } open var titleLockup = TitleLockup().with { - let configs = [ - TextStyle.DeviceSpacingConfig([.titleSmall, .boldTitleSmall], - neighboring: [ - .bodySmall, .boldBodySmall, - .bodyMedium, .boldBodyMedium - ], - spacing: 8.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.titleMedium, .boldTitleMedium, - .titleLarge, .boldTitleLarge], - neighboring: [ - .bodySmall, .boldBodySmall, - .bodyMedium, .boldBodyMedium, - .bodyLarge, .boldBodyLarge], - spacing: 8.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.titleXLarge, .boldTitleXLarge], - neighboring: [ - .bodySmall, .boldBodySmall, - .bodyMedium, .boldBodyMedium, - .bodyLarge, .boldBodyLarge, - .titleMedium, .boldTitleMedium - ], - spacing: 12.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.titleSmall, .boldTitleSmall, - .titleMedium, .boldTitleMedium], - neighboring: [ - .bodySmall, .boldBodySmall, - .bodyMedium, .boldBodyMedium, - .bodyLarge, .boldBodyLarge - ], - spacing: 8.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.titleLarge, .boldTitleLarge], - neighboring: [ - .bodySmall, .boldBodySmall, - .bodyMedium, .boldBodyMedium, - .bodyLarge, .boldBodyLarge, - .titleSmall, .boldTitleSmall - ], - spacing: 12.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.titleXLarge, .boldTitleXLarge], - neighboring: [ - .bodyLarge, .boldBodyLarge, - .titleMedium, .boldTitleMedium - ], - spacing: 16.0, - deviceType: .iPad) - - ] - - $0.bottomTextStyleSpacingConfig = TextStyle.SpacingConfig(configs: configs) + $0.standardStyleConfiguration = .init(styleConfigurations: [ + .init(deviceType: .iPhone, + titleStandardStyles: [.titleSmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + .init(deviceType: .iPhone, + titleStandardStyles: [.titleMedium, .titleLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + .init(deviceType: .iPhone, + titleStandardStyles: [.titleXLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge, .bodySmall, .bodyMedium, .titleMedium], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space3X.value) + ]), + .init(deviceType: .iPad, + titleStandardStyles: [.titleSmall, .titleMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + .init(deviceType: .iPad, + titleStandardStyles: [.titleLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge, .bodySmall, .bodyMedium, .titleSmall], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space3X.value) + ]), + .init(deviceType: .iPad, + titleStandardStyles: [.titleXLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.titleMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space4X.value) + ]) + ]) } open var badge = Badge().with { @@ -332,10 +317,6 @@ open class Tilelet: TileContainer { titleLockup.titleModel = titleModel?.toTitleLockupTitleModel() titleLockup.subTitleModel = subTitleModel?.toTitleLockupSubTitleModel() - if let style = subTitleModel?.textStyle.value { - titleLockup.otherTextStyle = style - } - if titleLockupContainerView.superview == nil { stackView.insertArrangedSubview(titleLockupContainerView, at: badgeContainerView.superview == nil ? 0 : 1) setNeedsLayout() diff --git a/VDS/Components/Tilelet/TileletSubTitleModel.swift b/VDS/Components/Tilelet/TileletSubTitleModel.swift index 5c91cdb8..0d9f01f6 100644 --- a/VDS/Components/Tilelet/TileletSubTitleModel.swift +++ b/VDS/Components/Tilelet/TileletSubTitleModel.swift @@ -12,21 +12,18 @@ extension Tilelet { //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- - public enum TextStyle: String, EnumSubset { + public enum StandardStyle: String, EnumSubset { case bodyLarge - case boldBodyLarge case bodyMedium - case boldBodyMedium case bodySmall - case boldBodySmall - public var defaultValue: TitleLockup.OtherTextStyle { .bodySmall } + public var defaultValue: TitleLockup.OtherStandardStyle { .bodySmall } } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- public var text: String = "" - public var textStyle: TextStyle = .bodySmall + public var standardStyle: StandardStyle = .bodySmall public var textAttributes: [any LabelAttributeModel]? public var textColor: Use = .primary @@ -36,11 +33,11 @@ extension Tilelet { public init(text: String, textColor: Use = .primary, textAttributes: [any LabelAttributeModel]? = nil, - textStyle: TextStyle = .bodySmall) { + standardStyle: StandardStyle = .bodySmall) { self.text = text self.textAttributes = textAttributes self.textColor = textColor - self.textStyle = textStyle + self.standardStyle = standardStyle } //-------------------------------------------------- @@ -48,6 +45,7 @@ extension Tilelet { //-------------------------------------------------- public func toTitleLockupSubTitleModel() -> TitleLockup.SubTitleModel { TitleLockup.SubTitleModel(text: text, + standardStyle: standardStyle.value, textColor: textColor, textAttributes: textAttributes) } diff --git a/VDS/Components/Tilelet/TileletTitleModel.swift b/VDS/Components/Tilelet/TileletTitleModel.swift index 9802273c..4af7a038 100644 --- a/VDS/Components/Tilelet/TileletTitleModel.swift +++ b/VDS/Components/Tilelet/TileletTitleModel.swift @@ -12,44 +12,39 @@ extension Tilelet { //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- - public enum TextStyle: String, EnumSubset { + public enum StandardStyle: String, EnumSubset { case titleXLarge - case boldTitleXLarge case titleLarge - case boldTitleLarge case titleMedium - case boldTitleMedium case titleSmall - case boldTitleSmall - public var defaultValue: TitleLockup.TitleTextStyle { .boldTitleSmall } + public var defaultValue: TitleLockup.TitleStandardStyle { .titleSmall } } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- public var text: String = "" public var textAttributes: [any LabelAttributeModel]? - public var textStyle: TextStyle = .boldTitleSmall + public var standardStyle: StandardStyle = .titleSmall //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- public init(text: String, textAttributes: [any LabelAttributeModel]? = nil, - textStyle: TextStyle = .boldTitleSmall) { + standardStyle: StandardStyle = .titleSmall) { self.text = text self.textAttributes = textAttributes - self.textStyle = textStyle + self.standardStyle = standardStyle } - //-------------------------------------------------- // MARK: - Public Functions //-------------------------------------------------- public func toTitleLockupTitleModel() -> TitleLockup.TitleModel { TitleLockup.TitleModel(text: text, textAttributes: textAttributes, - textStyle: textStyle.value) + standardStyle: standardStyle.value) } } } diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index b64132f4..6381fed5 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -50,138 +50,114 @@ open class TitleLockup: View { // MARK: - Configuration Properties //-------------------------------------------------- // Sizes are from InVision design specs. - open var topTextStyleSpacingConfig: TextStyle.SpacingConfig = { - let configs = [ - TextStyle.DeviceSpacingConfig([.boldTitleLarge, .titleLarge], - neighboring: [.bodySmall, .bodyMedium, .bodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitleXLarge, .titleXLarge], - neighboring: [.titleMedium, .bodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitle2XLarge, .title2XLarge, .boldFeatureXSmall, .featureXSmall], - neighboring: [.titleMedium, .titleLarge], - spacing: 16.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitle2XLarge, .title2XLarge, .boldFeatureXSmall, .featureXSmall], - neighboring: [.bodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldFeatureSmall, .featureSmall, .boldFeatureMedium, .featureMedium], - neighboring: [.titleMedium, .titleLarge], - spacing: 16.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldFeatureSmall, .featureSmall, .boldFeatureMedium, .featureMedium], - neighboring: [.bodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitleXLarge, .titleXLarge], - neighboring: [.bodyLarge, .bodyMedium, .bodySmall, .titleMedium], - spacing: 12.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldTitle2XLarge, .title2XLarge, .boldFeatureXSmall, .featureXSmall], - neighboring: [.bodyLarge, .bodyMedium, .titleMedium], - spacing: 12.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldFeatureSmall, .featureSmall], - neighboring: [.titleLarge, .bodyLarge], - spacing: 12.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldFeatureMedium, .featureMedium], - neighboring: [.titleLarge, .titleXLarge], - spacing: 16.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldFeatureMedium, .featureMedium], - neighboring: [.bodyLarge], - spacing: 12.0, - deviceType: .iPhone) - ] - return TextStyle.SpacingConfig(configs: configs) - }() - - open var bottomTextStyleSpacingConfig: TextStyle.SpacingConfig = { - let configs = [ - TextStyle.DeviceSpacingConfig([.boldTitleLarge, .titleLarge], - neighboring: [.bodySmall, .bodyMedium, .bodyLarge], - spacing: 12.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitleXLarge, .titleXLarge], - neighboring: [.titleMedium, .bodyLarge], - spacing: 16.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitle2XLarge, .title2XLarge, .boldFeatureXSmall, .featureXSmall], - neighboring: [.titleMedium, .titleLarge], - spacing: 24.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitle2XLarge, .title2XLarge, .boldFeatureXSmall, .featureXSmall], - neighboring: [.bodyLarge], - spacing: 24.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldFeatureSmall, .featureSmall, .boldFeatureMedium, .featureMedium], - neighboring: [.titleMedium, .titleLarge], - spacing: 24.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldFeatureSmall, .featureSmall, .boldFeatureMedium, .featureMedium], - neighboring: [.bodyLarge], - spacing: 24.0, - deviceType: .iPad), - - TextStyle.DeviceSpacingConfig([.boldTitleXLarge, .titleXLarge], - neighboring: [.bodyLarge, .bodyMedium, .bodySmall, .titleMedium], - spacing: 12.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldTitle2XLarge, .title2XLarge, .boldFeatureXSmall, .featureXSmall], - neighboring: [.bodyLarge, .bodyMedium, .titleMedium], - spacing: 16, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldFeatureSmall, .featureSmall], - neighboring: [.titleLarge, .bodyLarge], - spacing: 16.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldFeatureMedium, .featureMedium], - neighboring: [.titleLarge, .titleXLarge], - spacing: 24.0, - deviceType: .iPhone), - - TextStyle.DeviceSpacingConfig([.boldFeatureMedium, .featureMedium], - neighboring: [.bodyLarge], - spacing: 24.0, - deviceType: .iPhone) - ] - return TextStyle.SpacingConfig(configs: configs) - }() + open var standardStyleConfiguration: StandardStyleConfigurationProvider = StandardStyleConfigurationProvider(styleConfigurations: [ + + .init(deviceType: .iPad, + titleStandardStyles: [.titleSmall, .titleMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.titleLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge, .bodySmall, .bodyMedium, .titleSmall], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space3X.value) + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.titleXLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.titleMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space4X.value) + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.title2XLarge, .featureXSmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space6X.value), + + .init(otherStandardStyles: [.titleMedium, .titleLarge], + topSpacing: VDSLayout.Spacing.space4X.value, + bottomSpacing: VDSLayout.Spacing.space6X.value), + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.featureSmall, .featureMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.titleLarge, .titleMedium], + topSpacing: VDSLayout.Spacing.space4X.value, + bottomSpacing: VDSLayout.Spacing.space6X.value), + + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space6X.value), + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.titleSmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.titleMedium, .titleLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.titleXLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge, .bodySmall, .bodyMedium, .titleMedium], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space3X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.title2XLarge, .featureXSmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge, .bodyMedium, .titleMedium], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space4X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.featureSmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.titleLarge, .bodyLarge], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space4X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.featureMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.titleLarge, .titleXLarge], + topSpacing: VDSLayout.Spacing.space4X.value, + bottomSpacing: VDSLayout.Spacing.space6X.value), + + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space3X.value, + bottomSpacing: VDSLayout.Spacing.space6X.value) + ]), + ]) //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- open var textPosition: TextPosition = .left { didSet { setNeedsUpdate() }} - //style - open var otherTextStyle: OtherTextStyle = UIDevice.isIPad ? .bodyLarge : .bodyMedium { - didSet { - setNeedsUpdate() - } - } - //first row open var eyebrowLabel = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) @@ -227,11 +203,20 @@ open class TitleLockup: View { eyebrowModel = nil titleModel = nil subTitleModel = nil - otherTextStyle = UIDevice.isIPad ? .bodyLarge : .bodyMedium shouldUpdateView = true setNeedsUpdate() } + private var otherStandardStyle: OtherStandardStyle { + if let subTitleModel, !subTitleModel.text.isEmpty { + return subTitleModel.standardStyle + } else if let eyebrowModel, !eyebrowModel.text.isEmpty { + return eyebrowModel.standardStyle + } else { + return .bodyLarge + } + } + //-------------------------------------------------- // MARK: - State //-------------------------------------------------- @@ -242,11 +227,21 @@ open class TitleLockup: View { var eyebrowTextIsEmpty = true var titleTextIsEmpty = true var subTitleTextIsEmpty = true - + + var topSpacing: CGFloat = 0.0 + var bottomSpacing: CGFloat = 0.0 + + //get the spacing based on the title style and other style used for eyebrow and subtitle + if let titleModel, + let config = standardStyleConfiguration.spacing(for: titleModel.standardStyle, otherStandardStyle: otherStandardStyle) { + topSpacing = config.topSpacing + bottomSpacing = config.bottomSpacing + } + if let eyebrowModel, !eyebrowModel.text.isEmpty { eyebrowTextIsEmpty = false eyebrowLabel.textPosition = allLabelsTextPosition - eyebrowLabel.textStyle = otherTextStyle.value + eyebrowLabel.textStyle = eyebrowModel.isBold ? otherStandardStyle.value.bold : otherStandardStyle.value.regular eyebrowLabel.text = eyebrowModel.text eyebrowLabel.attributes = eyebrowModel.textAttributes eyebrowLabel.numberOfLines = eyebrowModel.numberOfLines @@ -258,7 +253,7 @@ open class TitleLockup: View { if let titleModel, !titleModel.text.isEmpty { titleTextIsEmpty = false titleLabel.textPosition = allLabelsTextPosition - titleLabel.textStyle = titleModel.textStyle.value + titleLabel.textStyle = titleModel.textStyle titleLabel.text = titleModel.text titleLabel.attributes = titleModel.textAttributes titleLabel.numberOfLines = titleModel.numberOfLines @@ -270,7 +265,7 @@ open class TitleLockup: View { if let subTitleModel, !subTitleModel.text.isEmpty { subTitleTextIsEmpty = false subTitleLabel.textPosition = allLabelsTextPosition - subTitleLabel.textStyle = otherTextStyle.value + subTitleLabel.textStyle = otherStandardStyle.value.regular subTitleLabel.text = subTitleModel.text subTitleLabel.attributes = subTitleModel.textAttributes subTitleLabel.numberOfLines = subTitleModel.numberOfLines @@ -281,16 +276,15 @@ 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 = topTextStyleSpacingConfig.spacing(for: titleModel.textStyle.value, neighboring: otherTextStyle.value) + if !eyebrowTextIsEmpty && !titleTextIsEmpty { + stackView.spacing = topSpacing } 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 = bottomTextStyleSpacingConfig.spacing(for: titleModel.textStyle.value, neighboring: otherTextStyle.value) - stackView.setCustomSpacing(bottomSpace, after: titleLabel) + if (!eyebrowTextIsEmpty || !titleTextIsEmpty) && !subTitleTextIsEmpty { + stackView.setCustomSpacing(bottomSpacing, after: titleLabel) } else if (!eyebrowTextIsEmpty || !titleTextIsEmpty) && subTitleTextIsEmpty { stackView.setCustomSpacing(0.0, after: titleLabel) } @@ -300,5 +294,4 @@ open class TitleLockup: View { titleLabel.isHidden = titleTextIsEmpty subTitleLabel.isHidden = subTitleTextIsEmpty } - } diff --git a/VDS/Components/TitleLockup/TitleLockupEyebrowModel.swift b/VDS/Components/TitleLockup/TitleLockupEyebrowModel.swift index fc5ea48e..7d30e923 100644 --- a/VDS/Components/TitleLockup/TitleLockupEyebrowModel.swift +++ b/VDS/Components/TitleLockup/TitleLockupEyebrowModel.swift @@ -10,15 +10,23 @@ import Foundation extension TitleLockup { public struct EyebrowModel { public var text: String + public var isBold: Bool public var textAttributes: [any LabelAttributeModel]? + public var standardStyle: OtherStandardStyle public var numberOfLines: Int public init(text: String, + isBold: Bool = false, + standardStyle: OtherStandardStyle = .bodyLarge, textAttributes: [any LabelAttributeModel]? = nil, numberOfLines: Int = 0) { self.text = text + self.isBold = isBold + self.standardStyle = standardStyle self.textAttributes = textAttributes self.numberOfLines = numberOfLines } + + public var textStyle: TextStyle { isBold ? standardStyle.value.bold : standardStyle.value.regular } } } diff --git a/VDS/Components/TitleLockup/TitleLockupStyleConfiguration.swift b/VDS/Components/TitleLockup/TitleLockupStyleConfiguration.swift new file mode 100644 index 00000000..7940d91a --- /dev/null +++ b/VDS/Components/TitleLockup/TitleLockupStyleConfiguration.swift @@ -0,0 +1,85 @@ +// +// TitleLockupStandardStyleConfiguration.swift +// VDS +// +// Created by Matt Bruce on 6/29/23. +// + +import Foundation +import UIKit + +extension TitleLockup { + + public struct StandardStyleConfigurationProvider { + public var styleConfigurations: [StandardStyleConfiguration] + + public init(styleConfigurations: [StandardStyleConfiguration]) { + self.styleConfigurations = styleConfigurations + } + + public func configuration(for titleStandardStyle: TitleStandardStyle) -> StandardStyleConfiguration? { + let deviceType: StandardStyleConfiguration.DeviceType = UIDevice.isIPad ? .iPad : .iPhone + guard let config: StandardStyleConfiguration = styleConfigurations.first(where: { return titleStandardStyle.isWithin($0.titleStandardStyles) && ($0.deviceType == deviceType || $0.deviceType == .all )}) else { return nil } + return config + } + + public func isValid(otherStandardStyle: OtherStandardStyle, for titleStandardStyle: TitleStandardStyle) -> Bool { + guard let config = configuration(for: titleStandardStyle) else { return false } + return otherStandardStyle.isWithin(config.spacingConfigurations.flatMap {$0.otherStandardStyles}) + } + + public func spacing(for titleStandardStyle: TitleStandardStyle, otherStandardStyle: OtherStandardStyle) -> (otherStandardStyle: OtherStandardStyle, topSpacing: CGFloat, bottomSpacing: CGFloat)? { + guard let config = configuration(for: titleStandardStyle) else { return nil } + return config.styleSpacing(for: otherStandardStyle) + } + } + + public struct StandardStyleConfiguration { + public enum DeviceType { + case iPhone, iPad, all + } + public var deviceType: DeviceType + public var titleStandardStyles:[TitleStandardStyle] + public var spacingConfigurations: [SpacingConfiguration] + + public init(deviceType: DeviceType, titleStandardStyles: [TitleStandardStyle], spacingConfigurations: [SpacingConfiguration]) { + self.deviceType = deviceType + self.titleStandardStyles = titleStandardStyles + self.spacingConfigurations = spacingConfigurations + } + + public var allOtherStandardStyles: [OtherStandardStyle] { + spacingConfigurations.flatMap {$0.otherStandardStyles} + } + + public func styleSpacing(for otherStandardStyle: OtherStandardStyle) -> (otherStandardStyle: OtherStandardStyle, topSpacing: CGFloat, bottomSpacing: CGFloat) { + //set default return other style what you pass in + var realOtherStyle = otherStandardStyle + + //flatten all of the other styles registered for the title styles + let allOtherStyles = spacingConfigurations.flatMap {$0.otherStandardStyles} + + //get the default other style incase what is passed isn't within the registered collection + if let first = allOtherStyles.first, !realOtherStyle.isWithin(allOtherStyles) { + realOtherStyle = first + } + //get the config against the other style or return defaults + guard let styleSpacing = spacingConfigurations.first(where: {realOtherStyle.isWithin($0.otherStandardStyles)}) else { + return (realOtherStyle, VDSLayout.Spacing.space2X.value, VDSLayout.Spacing.space2X.value) + } + return (realOtherStyle, styleSpacing.topSpacing, styleSpacing.bottomSpacing) + } + } + + public struct SpacingConfiguration { + public var otherStandardStyles: [OtherStandardStyle] + public var topSpacing: CGFloat + public var bottomSpacing: CGFloat + + public init(otherStandardStyles: [OtherStandardStyle], topSpacing: CGFloat, bottomSpacing: CGFloat) { + self.otherStandardStyles = otherStandardStyles + self.topSpacing = topSpacing + self.bottomSpacing = bottomSpacing + } + } +} diff --git a/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift b/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift index 6be2782f..d7242dd7 100644 --- a/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift +++ b/VDS/Components/TitleLockup/TitleLockupSubTitleModel.swift @@ -10,18 +10,25 @@ import Foundation extension TitleLockup { public struct SubTitleModel { public var text: String + public var standardStyle: OtherStandardStyle public var textColor: Use public var textAttributes: [any LabelAttributeModel]? public var numberOfLines: Int public init(text: String, + standardStyle: OtherStandardStyle = .bodyLarge, textColor: Use = .primary, textAttributes: [any LabelAttributeModel]? = nil, numberOfLines: Int = 0) { self.text = text + self.standardStyle = standardStyle self.textColor = textColor self.textAttributes = textAttributes self.numberOfLines = numberOfLines } + + public var textStyle: TextStyle { standardStyle.value.regular } + } + } diff --git a/VDS/Components/TitleLockup/TitleLockupTextStyle.swift b/VDS/Components/TitleLockup/TitleLockupTextStyle.swift index a09491ae..fa2aefba 100644 --- a/VDS/Components/TitleLockup/TitleLockupTextStyle.swift +++ b/VDS/Components/TitleLockup/TitleLockupTextStyle.swift @@ -11,46 +11,39 @@ extension TitleLockup { //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- - public enum TitleTextStyle: String, CaseIterable { + public enum TitleStandardStyle: String, CaseIterable { 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 var defaultValue: TextStyle.StandardStyle {.featureXSmall } - public var value: TextStyle { - TextStyle.textStyle(for: self.rawValue) ?? defaultValue + public var value: TextStyle.StandardStyle { + TextStyle.StandardStyle(rawValue: self.rawValue) ?? defaultValue } } - public enum OtherTextStyle: String, CaseIterable { - case bodyLarge - case boldBodyLarge - case bodyMedium - case boldBodyMedium + public enum OtherStandardStyle: String, CaseIterable { case bodySmall - case boldBodySmall + case bodyMedium + case bodyLarge + case titleSmall + case titleMedium + case titleLarge + case titleXLarge - public var defaultValue: TextStyle {.bodyLarge } + public var defaultValue: TextStyle.StandardStyle { .bodyLarge } - public var value: TextStyle { - TextStyle.textStyle(for: self.rawValue) ?? defaultValue + public var value: TextStyle.StandardStyle { + TextStyle.StandardStyle(rawValue: self.rawValue) ?? defaultValue } } } diff --git a/VDS/Components/TitleLockup/TitleLockupTitleModel.swift b/VDS/Components/TitleLockup/TitleLockupTitleModel.swift index 4b5c1beb..da490ad5 100644 --- a/VDS/Components/TitleLockup/TitleLockupTitleModel.swift +++ b/VDS/Components/TitleLockup/TitleLockupTitleModel.swift @@ -11,17 +11,23 @@ extension TitleLockup { public struct TitleModel { public var text: String public var textAttributes: [any LabelAttributeModel]? - public var textStyle: TitleTextStyle + public var isBold: Bool + public var standardStyle: TitleStandardStyle public var numberOfLines: Int public init(text: String, textAttributes: [any LabelAttributeModel]? = nil, - textStyle: TitleTextStyle = .boldFeatureXSmall, + isBold: Bool = true, + standardStyle: TitleStandardStyle = .featureXSmall, numberOfLines: Int = 0) { self.text = text + self.isBold = isBold self.textAttributes = textAttributes - self.textStyle = textStyle + self.standardStyle = standardStyle self.numberOfLines = numberOfLines } + + public var textStyle: TextStyle { isBold ? standardStyle.value.bold : standardStyle.value.regular } + } } diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 634fc192..42f3c4a2 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -79,12 +79,14 @@ open class Toggle: Control, Changeable { private var toggleColorConfiguration = ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.paletteGray44, forState: .normal) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) + $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled]) $0.setSurfaceColors(VDSColor.paletteGreen26, VDSColor.paletteGreen36, forState: .selected) } private var knobColorConfiguration = ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forState: .normal) $0.setSurfaceColors(VDSColor.paletteGray95, VDSColor.paletteGray44, forState: .disabled) + $0.setSurfaceColors(VDSColor.paletteGray95, VDSColor.paletteGray44, forState: [.selected, .disabled]) $0.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOndark, forState: .selected) } diff --git a/VDS/Extensions/NSAttributedString.swift b/VDS/Extensions/NSAttributedString.swift index a4b94fb9..ec36fe67 100644 --- a/VDS/Extensions/NSAttributedString.swift +++ b/VDS/Extensions/NSAttributedString.swift @@ -20,7 +20,8 @@ extension NSAttributedString { extension NSMutableAttributedString { public static func mutableText(for text: String, textStyle: TextStyle, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString { - let startingAttributes = [NSAttributedString.Key.font: textStyle.font, NSAttributedString.Key.foregroundColor: textColor] + let font = textStyle.font + let startingAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor] let attributedString = NSMutableAttributedString(string: text, attributes: startingAttributes) //get the range @@ -35,13 +36,22 @@ extension NSMutableAttributedString { paragraph.alignment = alignment paragraph.lineBreakMode = lineBreakMode + if textStyle.lineSpacing > 0 { + paragraph.lineSpacing = textStyle.lineSpacing + } + //set lineHeight if textStyle.lineHeight > 0.0 { let lineHeight = textStyle.lineHeight - paragraph.maximumLineHeight = lineHeight - paragraph.minimumLineHeight = lineHeight +// if textStyle.lineHeight > textStyle.pointSize { + paragraph.maximumLineHeight = lineHeight + paragraph.minimumLineHeight = lineHeight +// paragraph.lineHeightMultiple = lineHeight / textStyle.pointSize +// } else { +// paragraph.lineHeightMultiple = lineHeight / font.pointSize +// } } - + attributedString.addAttribute( .baselineOffset, value: textStyle.baselineOffset, range: entireRange) attributedString.addAttribute( .paragraphStyle, value: paragraph, range: entireRange) return attributedString diff --git a/VDS/Extensions/UIColor+VDSColor.swift b/VDS/Extensions/UIColor+VDSColor.swift index 8717ab6b..9fd177d1 100644 --- a/VDS/Extensions/UIColor+VDSColor.swift +++ b/VDS/Extensions/UIColor+VDSColor.swift @@ -7,6 +7,7 @@ import Foundation import VDSColorTokens +import UIKit extension VDSColor { public static let paletteYellow62 = UIColor(hexString: "#FED60E") diff --git a/VDS/SupportingFiles/Icons.xcassets/Restricted/verizon-up.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/Restricted/verizon-up.imageset/Contents.json new file mode 100644 index 00000000..9a8aa3e9 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/Restricted/verizon-up.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "verizon-up.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/VDS/SupportingFiles/Icons.xcassets/Restricted/verizon-up.imageset/verizon-up.svg b/VDS/SupportingFiles/Icons.xcassets/Restricted/verizon-up.imageset/verizon-up.svg new file mode 100644 index 00000000..3c9168b9 --- /dev/null +++ b/VDS/SupportingFiles/Icons.xcassets/Restricted/verizon-up.imageset/verizon-up.svg @@ -0,0 +1,10 @@ + + + + + diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index b983e954..19fde7df 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,6 +1,14 @@ +1.0.26 +======= +- CXTDT-426626 - Toggle - Disabled "on" state +- CXTDT-427165 - Text Link Caret - Container should not have left/right padding + 1.0.25 ======= +- TEMPORARY: Added BaselineOffset, LineSpacing to TextStyle - Added Size, Width, Height, Horizontal/Vertical Padding + more to Badge Indicator +- CXTDT-424370 - Icons are fuzzy when resized +- CXTDT-426521 - Tabs - Vertical Tablet spacing 1.0.24 ======= diff --git a/VDS/Typography/Typography.swift b/VDS/Typography/Typography.swift index a89b75de..902eb09e 100644 --- a/VDS/Typography/Typography.swift +++ b/VDS/Typography/Typography.swift @@ -29,6 +29,8 @@ public struct TextStyle: Equatable, RawRepresentable { public let lineHeight: CGFloat public let letterSpacing: CGFloat public let fontFace: Font + public let lineSpacing: CGFloat + public let baselineOffset: CGFloat public init?(rawValue: String) { guard let style = TextStyle.textStyle(for: rawValue) else { return nil } @@ -37,14 +39,22 @@ public struct TextStyle: Equatable, RawRepresentable { self.lineHeight = style.lineHeight self.letterSpacing = style.letterSpacing self.fontFace = style.fontFace + self.lineSpacing = style.lineSpacing + self.baselineOffset = style.baselineOffset } - public init(rawValue: String, fontFace: Font, pointSize: CGFloat = 0.0, lineHeight: CGFloat = 0.0, letterSpacing: CGFloat = 0.0) { + public init(rawValue: String, fontFace: Font, pointSize: CGFloat = 0.0, lineHeight: CGFloat = 0.0, letterSpacing: CGFloat = 0.0, lineSpacing: CGFloat = 0.0, baselineOffset: CGFloat = 0.0) { self.rawValue = rawValue self.fontFace = fontFace self.pointSize = pointSize self.lineHeight = lineHeight self.letterSpacing = letterSpacing + self.lineSpacing = lineSpacing + self.baselineOffset = baselineOffset + } + + public var isBold: Bool { + rawValue.hasPrefix("bold") } } @@ -255,9 +265,43 @@ extension TextStyle { 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 { @@ -344,8 +388,8 @@ extension TextStyle { } } -extension TextStyle { - public func isWithin(_ collection: [TextStyle]) -> Bool { +extension RawRepresentable where Self.RawValue: Equatable { + public func isWithin(_ collection: [Self]) -> Bool { (collection.first(where: {$0 == self}) != nil) } }