From 98968bacbde3b48293fb8e0ced41fc513e0c9ecb Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 29 Jun 2023 12:06:28 -0500 Subject: [PATCH] refactored out top/bottom spacing config and created new one updated models to use a StandardStyle updated Tilelet/TitleLockup to use new features Signed-off-by: Matt Bruce --- VDS/Components/Tilelet/Tilelet.swift | 107 +++--- .../Tilelet/TileletSubTitleModel.swift | 14 +- .../Tilelet/TileletTitleModel.swift | 17 +- VDS/Components/TitleLockup/TitleLockup.swift | 341 +++++++++++------- .../TitleLockup/TitleLockupEyebrowModel.swift | 8 + .../TitleLockupSubTitleModel.swift | 7 + .../TitleLockup/TitleLockupTextStyle.swift | 35 +- .../TitleLockup/TitleLockupTitleModel.swift | 12 +- 8 files changed, 299 insertions(+), 242 deletions(-) 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..88b0c499 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) } @@ -302,3 +296,78 @@ open class TitleLockup: View { } } + +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/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/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 } + } }