vds_ios/VDS/Components/TitleLockup/TitleLockupStyleConfiguration.swift

121 lines
6.1 KiB
Swift

//
// TitleLockupStandardStyleConfiguration.swift
// VDS
//
// Created by Matt Bruce on 6/29/23.
//
import Foundation
import UIKit
import VDSCoreTokens
extension TitleLockup {
/// Configuration that will set the spacing between labels based off their textStyles.
public struct StandardStyleConfigurationProvider {
/// Array of standard style configurations.
public var styleConfigurations: [StandardStyleConfiguration]
public init(styleConfigurations: [StandardStyleConfiguration]) {
self.styleConfigurations = styleConfigurations
}
/// Will find a standard style configuration for the title standard style against the running device type.
/// - titleStandardStyle: title standard style
/// - Returns: Standard Style configuration that matches
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
}
/// Determines if there is a configuration for this title style as well as a matching spacing configuration against the other standard style.
/// - Parameters:
/// - otherStandardStyle: other standard style
/// - titleStandardStyle: title standard style
/// - Returns: Whether or not there is a
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})
}
/// Will find the spacing for a specific title standard style against a other standard style. If one isn't found a default spacing is returned.
/// - Parameters:
/// - titleStandardStyle: title standard style
/// - otherStandardStyle: other standard style
/// - Returns: Tuple of the standard style as well as the top and bottom spacing.
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)
}
}
/// Configuration that will set the spacing between labels based off the device type and their textStyles.
public struct StandardStyleConfiguration {
/// Enum for the devices for this configuration.
public enum DeviceType {
case iPhone, iPad, all
}
/// Device type for this configuration.
public var deviceType: DeviceType
/// Array of title standard styles, first style is always the default.
public var titleStandardStyles:[TitleStandardStyle]
/// Array of spacing configurations for spacing.
public var spacingConfigurations: [SpacingConfiguration]
public init(deviceType: DeviceType, titleStandardStyles: [TitleStandardStyle], spacingConfigurations: [SpacingConfiguration]) {
self.deviceType = deviceType
self.titleStandardStyles = titleStandardStyles
self.spacingConfigurations = spacingConfigurations
}
/// Flattend array of all spacingConfigurations array of other standard styles.
public var allOtherStandardStyles: [OtherStandardStyle] {
spacingConfigurations.flatMap {$0.otherStandardStyles}
}
/// Takes a other standard style and will either find the spacing configuration that matches or returns a default top and bottom spacing.
/// - Parameter otherStandardStyle: other standard style you need to find the configuration for top and bottom spacing
/// - Returns: Tuple of the other standard style passed in and the configuration for top and bottom spacing.
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.space2X, VDSLayout.space2X)
}
return (realOtherStyle, styleSpacing.topSpacing, styleSpacing.bottomSpacing)
}
}
/// Configuration to define spacing for an array of standard styles.
public struct SpacingConfiguration {
/// Array of other standard styles
public var otherStandardStyles: [OtherStandardStyle]
/// Configuration of topSpacing for the other standard styles
public var topSpacing: CGFloat
/// Configuration of bottomSpacing for the other standard styles
public var bottomSpacing: CGFloat
public init(otherStandardStyles: [OtherStandardStyle], topSpacing: CGFloat, bottomSpacing: CGFloat) {
self.otherStandardStyles = otherStandardStyles
self.topSpacing = topSpacing
self.bottomSpacing = bottomSpacing
}
}
}