diff --git a/.circleci/config.yml b/.circleci/config.yml index 54bcf99..39cc3b4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,13 +14,15 @@ jobs: macos: # Specify the Xcode version you desire here # See: https://circleci.com/docs/using-macos/ - xcode: 15.2.0 + xcode: 16.1.0 # Add steps to the job # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps steps: + # Checkout the code as the first step. - checkout - - run: fastlane scan --project "DSKitExplorer/DSKitExplorer.xcodeproj" --device "iPhone SE (3rd generation) (17.0)" # Run tests using Fastlane + - run: fastlane scan --device "iPhone 15 Pro" --result_bundle --output_directory test_output + # Collect XML test results data to show in the UI, and save the same XML # files under test-results folder in the Artifacts tab - store_test_results: @@ -28,6 +30,9 @@ jobs: - store_artifacts: path: test_output destination: scan-output + - store_artifacts: + path: test_output/Test.xcresult/Attachments + destination: failed-test-screenshots # Orchestrate jobs using workflows # See: https://circleci.com/docs/workflows/ & https://circleci.com/docs/configuration-reference/#workflows diff --git a/DSKit/Sources/DSKit/Appearances/BlueAppearance.swift b/DSKit/Sources/DSKit/Appearances/BlueAppearance.swift index 93e02b9..232a66c 100644 --- a/DSKit/Sources/DSKit/Appearances/BlueAppearance.swift +++ b/DSKit/Sources/DSKit/Appearances/BlueAppearance.swift @@ -6,8 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - public class BlueAppearance: DSAppearance { public var title: String @@ -24,7 +22,7 @@ public class BlueAppearance: DSAppearance { /// Init system appearance with brand color, or primary color of your app /// - Parameter primaryBrandColor: UIColor - public init(brandColor: UIColor? = nil, title: String = "Blue") { + public init(brandColor: DSUIColor? = nil, title: String = "Blue") { self.title = title @@ -79,7 +77,7 @@ public class BlueAppearance: DSAppearance { // MARK: - Tabbar - tabBar = DSTabbarAppearance( + tabBar = DSTabBarAppearance( barTint: primaryView.background, itemTint: primaryView.button.accentColor, unselectedItemTint: secondaryText.subheadline, diff --git a/DSKit/Sources/DSKit/Appearances/DSKitAppearance.swift b/DSKit/Sources/DSKit/Appearances/DSKitAppearance.swift index d1f7356..8278088 100644 --- a/DSKit/Sources/DSKit/Appearances/DSKitAppearance.swift +++ b/DSKit/Sources/DSKit/Appearances/DSKitAppearance.swift @@ -6,8 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - public struct LightBlueAppearance: DSAppearance { public var title: String @@ -25,7 +23,7 @@ public struct LightBlueAppearance: DSAppearance { /// Init DSKit appearance with specific brand color /// - Parameter brandColor: UIColor - public init(brandColor: UIColor? = nil) { + public init(brandColor: DSUIColor? = nil) { self.title = "Light Blue" @@ -60,10 +58,10 @@ public struct LightBlueAppearance: DSAppearance { ) // Background - let background: UIColor = .dynamic(light: 0xfefffe, dark: 0x15202b) + let background: DSUIColor = .dynamic(light: 0xfefffe, dark: 0x15202b) // Separator - let separator: UIColor = .dynamic(light: 0xd0dbe3, dark: 0x38444d) + let separator: DSUIColor = .dynamic(light: 0xd0dbe3, dark: 0x38444d) // Corner radius let cornerRadius: CGFloat = 10 @@ -109,10 +107,10 @@ public struct LightBlueAppearance: DSAppearance { ) // Background - let sBackground: UIColor = .dynamic(light: 0xf3f4f2, dark: 0x101a24) + let sBackground: DSUIColor = .dynamic(light: 0xf3f4f2, dark: 0x101a24) // Separator - let sSeparator: UIColor = .dynamic(light: 0xd0dbe3, dark: 0x15202b) + let sSeparator: DSUIColor = .dynamic(light: 0xd0dbe3, dark: 0x15202b) // Corner radius let sCornerRadius: CGFloat = 10 @@ -129,7 +127,7 @@ public struct LightBlueAppearance: DSAppearance { // MARK: - Tabbar - tabBar = DSTabbarAppearance( + tabBar = DSTabBarAppearance( barTint: primaryView.background, itemTint: primaryView.button.accentColor, unselectedItemTint: text.subheadline, @@ -158,7 +156,7 @@ public struct LightBlueAppearance: DSAppearance { price = DSPriceAppearance( regularAmount: text.subheadline, - badgeBackground: UIColor(0xFF656B) + badgeBackground: DSUIColor(0xFF656B) ) } diff --git a/DSKit/Sources/DSKit/Appearances/DarkAppearance.swift b/DSKit/Sources/DSKit/Appearances/DarkAppearance.swift index 309d56f..702fa81 100644 --- a/DSKit/Sources/DSKit/Appearances/DarkAppearance.swift +++ b/DSKit/Sources/DSKit/Appearances/DarkAppearance.swift @@ -6,8 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - public class DarkAppearance: DSAppearance { public var title: String @@ -24,7 +22,7 @@ public class DarkAppearance: DSAppearance { /// Init system appearance with brand color, or primary color of your app /// - Parameter primaryBrandColor: UIColor - public init(brandColor: UIColor? = nil, title: String = "Dark") { + public init(brandColor: DSUIColor? = nil, title: String = "Dark") { self.title = title @@ -84,11 +82,11 @@ public class DarkAppearance: DSAppearance { // MARK: - Tabbar - tabBar = DSTabbarAppearance( + tabBar = DSTabBarAppearance( barTint: primaryView.background, itemTint: primaryView.button.accentColor, unselectedItemTint: secondaryText.subheadline, - badge: UIColor.red, + badge: DSUIColor.red, translucent: true ) diff --git a/DSKit/Sources/DSKit/Appearances/PeachAppearance.swift b/DSKit/Sources/DSKit/Appearances/PeachAppearance.swift index 44458ae..a312ec0 100644 --- a/DSKit/Sources/DSKit/Appearances/PeachAppearance.swift +++ b/DSKit/Sources/DSKit/Appearances/PeachAppearance.swift @@ -6,10 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - -import UIKit - public class PeachAppearance: DSAppearance { public var title: String @@ -24,7 +20,7 @@ public class PeachAppearance: DSAppearance { public var actionElementHeight: CGFloat = 48 public var screenMargins: CGFloat = 16 - public init(brandColor: UIColor? = nil, title: String = "Peach") { + public init(brandColor: DSUIColor? = nil, title: String = "Peach") { self.title = title @@ -83,11 +79,11 @@ public class PeachAppearance: DSAppearance { // MARK: - Tabbar - tabBar = DSTabbarAppearance( - barTint: .dynamic(light: 0xFFFFFF, dark: 0x1A1A1A), - itemTint: .dynamic(light: 0xE84F3D, dark: 0xE84F3D), - unselectedItemTint: .dynamic(light: 0x717171, dark: 0x999999), - badge: .dynamic(light: 0xE84F3D, dark: 0xE84F3D), + tabBar = DSTabBarAppearance( + barTint: DSUIColor.dynamic(light: 0xFFFFFF, dark: 0x1A1A1A), + itemTint: DSUIColor.dynamic(light: 0xE84F3D, dark: 0xE84F3D), + unselectedItemTint: DSUIColor.dynamic(light: 0x717171, dark: 0x999999), + badge: DSUIColor.dynamic(light: 0xE84F3D, dark: 0xE84F3D), translucent: true ) diff --git a/DSKit/Sources/DSKit/Appearances/RetroAppearance.swift b/DSKit/Sources/DSKit/Appearances/RetroAppearance.swift index ca3eabe..eaabe07 100644 --- a/DSKit/Sources/DSKit/Appearances/RetroAppearance.swift +++ b/DSKit/Sources/DSKit/Appearances/RetroAppearance.swift @@ -6,8 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - public final class RetroAppearance: DSAppearance { public var title: String @@ -27,7 +25,7 @@ public final class RetroAppearance: DSAppearance { /// Init system appearance with brand color, or primary color of your app /// - Parameter primaryBrandColor: UIColor - public init(brandColor: UIColor? = nil, title: String = "Retro") { + public init(brandColor: DSUIColor? = nil, title: String = "Retro") { self.title = title @@ -101,7 +99,7 @@ public final class RetroAppearance: DSAppearance { // MARK: - Tabbar - tabBar = DSTabbarAppearance( + tabBar = DSTabBarAppearance( barTint: primaryView.background, itemTint: primaryView.button.accentColor, unselectedItemTint: text.subheadline, diff --git a/DSKit/Sources/DSKit/Designable/DSAppearance.swift b/DSKit/Sources/DSKit/Designable/DSAppearance.swift index 0d30cdd..2a6fc60 100644 --- a/DSKit/Sources/DSKit/Designable/DSAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSAppearance.swift @@ -7,7 +7,8 @@ // import SwiftUI -import UIKit + +// MARK: - Environment Key for DSAppearance struct AppearanceEnvironment: EnvironmentKey { static let defaultValue: DSAppearance = LightBlueAppearance() @@ -20,6 +21,8 @@ public extension EnvironmentValues { } } +// MARK: - DSAppearance Protocol + public protocol DSAppearance { var title: String { get set } var primaryView: DSViewAppearanceProtocol { get set } @@ -42,7 +45,10 @@ extension DSAppearance { } public extension DSAppearance { + /// Override the system appearance settings (iOS only) func overrideTheSystemAppearance() { + #if canImport(UIKit) + // Configure Navigation Bar Appearance let navigationBarAppearance = UINavigationBarAppearance() navigationBarAppearance.configureWithOpaqueBackground() navigationBarAppearance.backgroundColor = self.navigationBar.bar @@ -77,13 +83,16 @@ public extension DSAppearance { UITabBar.appearance().standardAppearance = tabBarAppearance UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance + #endif } } +// MARK: - SwiftUI View Extension + public extension View { + /// Apply the `DSAppearance` to the SwiftUI view func dsAppearance(_ appearance: DSAppearance) -> some View { appearance.overrideTheSystemAppearance() - return self - .environment(\.appearance, appearance) + return self.environment(\.appearance, appearance) } } diff --git a/DSKit/Sources/DSKit/Designable/DSButtonAppearance.swift b/DSKit/Sources/DSKit/Designable/DSButtonAppearance.swift index dd19211..bd2c887 100644 --- a/DSKit/Sources/DSKit/Designable/DSButtonAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSButtonAppearance.swift @@ -6,21 +6,21 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public protocol DSButtonAppearanceProtocol { - var accentColor: UIColor { get set } - var supportColor: UIColor { get set } + var accentColor: DSUIColor { get set } + var supportColor: DSUIColor { get set } } public extension DSButtonAppearanceProtocol { + /// Returns a SwiftUI `Color` based on the given `DSButtonColorKey` func color(key: DSButtonColorKey) -> Color { switch key { case .accentColor: - accentColor.color + return Color(accentColor) case .supportColor: - supportColor.color + return Color(supportColor) } } } @@ -32,12 +32,13 @@ public enum DSButtonColorKey { public struct DSButtonAppearance: DSButtonAppearanceProtocol { - public var accentColor: UIColor - public var supportColor: UIColor + public var accentColor: DSUIColor + public var supportColor: DSUIColor + /// Initialize `DSButtonAppearance` with colors public init( - accentColor: UIColor, - supportColor: UIColor + accentColor: DSUIColor, + supportColor: DSUIColor ) { self.accentColor = accentColor self.supportColor = supportColor diff --git a/DSKit/Sources/DSKit/Designable/DSColorKey.swift b/DSKit/Sources/DSKit/Designable/DSColorKey.swift index ffac65c..2e10495 100644 --- a/DSKit/Sources/DSKit/Designable/DSColorKey.swift +++ b/DSKit/Sources/DSKit/Designable/DSColorKey.swift @@ -5,7 +5,6 @@ // Created by Ivan Borinschi on 26.12.2022. // -import UIKit import SwiftUI public enum DSColorKey: Equatable, Hashable { diff --git a/DSKit/Sources/DSKit/Designable/DSDesignableTextFieldColor.swift b/DSKit/Sources/DSKit/Designable/DSDesignableTextFieldColor.swift index bcfc0c5..13bba0d 100644 --- a/DSKit/Sources/DSKit/Designable/DSDesignableTextFieldColor.swift +++ b/DSKit/Sources/DSKit/Designable/DSDesignableTextFieldColor.swift @@ -6,22 +6,20 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - protocol DSTextFieldColorsProtocol { - var border: UIColor { get set } - var background: UIColor { get set } - var text: UIColor { get set } - var placeHolder: UIColor { get set } + var border: DSUIColor { get set } + var background: DSUIColor { get set } + var text: DSUIColor { get set } + var placeHolder: DSUIColor { get set } } public struct DSTextFieldColors: DSTextFieldColorsProtocol { public init( - border: UIColor, - background: UIColor, - text: UIColor, - placeHolder: UIColor + border: DSUIColor, + background: DSUIColor, + text: DSUIColor, + placeHolder: DSUIColor ) { self.border = border self.background = background @@ -29,8 +27,8 @@ public struct DSTextFieldColors: DSTextFieldColorsProtocol { self.placeHolder = placeHolder } - public var border: UIColor - public var background: UIColor - public var text: UIColor - public var placeHolder: UIColor + public var border: DSUIColor + public var background: DSUIColor + public var text: DSUIColor + public var placeHolder: DSUIColor } diff --git a/DSKit/Sources/DSKit/Designable/DSDynamicColor.swift b/DSKit/Sources/DSKit/Designable/DSDynamicColor.swift index 5c3f45f..1b56c2f 100644 --- a/DSKit/Sources/DSKit/Designable/DSDynamicColor.swift +++ b/DSKit/Sources/DSKit/Designable/DSDynamicColor.swift @@ -5,48 +5,31 @@ // Created by Borinschi Ivan on 16.12.2020. // -import UIKit - public class DSDynamicColor { - - /// Generate light and dark color for dynamic interfaces - /// - Parameters: - /// - light: UIColor for light interface - /// - dark: UIColor for dark interface - /// - Returns: UIColor - public static func color(light: UIColor, dark: UIColor) -> UIColor { - return UIColor { (traitCollection: UITraitCollection) -> UIColor in - if traitCollection.userInterfaceStyle == .dark { - return dark - } else { - return light - } - } - } /// Generate light and dark color for dynamic interfaces /// - Parameters: - /// - light: UIColor fo light interface - /// - dark: UIColor for dark interface - /// - Returns: UIColor - public static func color(light: Int, dark: Int) -> UIColor { - return color(light: UIColor(light), dark: UIColor(dark)) - } -} - -extension UIColor { - static func dynamic(light: UIColor, dark: UIColor) -> UIColor { - return UIColor { traitCollection -> UIColor in - switch traitCollection.userInterfaceStyle { - case .dark: - return dark - default: - return light - } + /// - light: DSUIColor for light interface + /// - dark: DSUIColor for dark interface + /// - Returns: DSUIColor + public static func color(light: DSUIColor, dark: DSUIColor) -> DSUIColor { + #if canImport(UIKit) + return DSUIColor { traitCollection in + traitCollection.userInterfaceStyle == .dark ? dark : light } + #elseif canImport(AppKit) + return DSUIColor(name: nil, dynamicProvider: { appearance in + appearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua ? dark : light + }) + #endif } - static func dynamic(light: Int, dark: Int) -> UIColor { - dynamic(light: UIColor(light), dark: UIColor(dark)) + /// Generate light and dark color for dynamic interfaces using hex values + /// - Parameters: + /// - light: Hex color for light interface + /// - dark: Hex color for dark interface + /// - Returns: DSUIColor + public static func color(light: Int, dark: Int) -> DSUIColor { + return color(light: DSUIColor(light), dark: DSUIColor(dark)) } } diff --git a/DSKit/Sources/DSKit/Designable/DSFonts.swift b/DSKit/Sources/DSKit/Designable/DSFonts.swift index 6e8a37c..ee7180f 100644 --- a/DSKit/Sources/DSKit/Designable/DSFonts.swift +++ b/DSKit/Sources/DSKit/Designable/DSFonts.swift @@ -6,20 +6,18 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit - public protocol DSFontsProtocol { - var body: UIFont { get } - var callout: UIFont { get } - var caption1: UIFont { get } - var caption2: UIFont { get } - var footnote: UIFont { get } - var headline: UIFont { get } - var subheadline: UIFont { get } - var largeTitle: UIFont { get } - var title1: UIFont { get } - var title2: UIFont { get } - var title3: UIFont { get } + var body: DSFont { get } + var callout: DSFont { get } + var caption1: DSFont { get } + var caption2: DSFont { get } + var footnote: DSFont { get } + var headline: DSFont { get } + var subheadline: DSFont { get } + var largeTitle: DSFont { get } + var title1: DSFont { get } + var title2: DSFont { get } + var title3: DSFont { get } } public class DSFonts: DSFontsProtocol { @@ -34,47 +32,47 @@ public class DSFonts: DSFontsProtocol { DSScaledFont(fontName: fontName) }() - lazy public var body: UIFont = { + lazy public var body: DSFont = { return scaledFont.font(forTextStyle: .body) }() - lazy public var callout: UIFont = { + lazy public var callout: DSFont = { return scaledFont.font(forTextStyle: .callout) }() - lazy public var caption1: UIFont = { + lazy public var caption1: DSFont = { return scaledFont.font(forTextStyle: .caption1) }() - lazy public var caption2: UIFont = { + lazy public var caption2: DSFont = { return scaledFont.font(forTextStyle: .caption2) }() - lazy public var footnote: UIFont = { + lazy public var footnote: DSFont = { return scaledFont.font(forTextStyle: .footnote) }() - lazy public var headline: UIFont = { + lazy public var headline: DSFont = { return scaledFont.font(forTextStyle: .headline) }() - lazy public var subheadline: UIFont = { + lazy public var subheadline: DSFont = { return scaledFont.font(forTextStyle: .subheadline) }() - lazy public var largeTitle: UIFont = { + lazy public var largeTitle: DSFont = { return scaledFont.font(forTextStyle: .largeTitle) }() - lazy public var title1: UIFont = { + lazy public var title1: DSFont = { return scaledFont.font(forTextStyle: .title1) }() - lazy public var title2: UIFont = { + lazy public var title2: DSFont = { return scaledFont.font(forTextStyle: .title2) }() - lazy public var title3: UIFont = { + lazy public var title3: DSFont = { return scaledFont.font(forTextStyle: .title3) }() } diff --git a/DSKit/Sources/DSKit/Designable/DSNavigationBarAppearance.swift b/DSKit/Sources/DSKit/Designable/DSNavigationBarAppearance.swift index f69d5ac..03aba15 100644 --- a/DSKit/Sources/DSKit/Designable/DSNavigationBarAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSNavigationBarAppearance.swift @@ -6,17 +6,17 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public protocol DSNavigationBarAppearanceProtocol { - var buttons: UIColor { get set } - var text: UIColor { get set } - var bar: UIColor { get set } + var buttons: DSUIColor { get set } + var text: DSUIColor { get set } + var bar: DSUIColor { get set } var translucent: Bool { get set } } extension DSNavigationBarAppearanceProtocol { + /// Returns a SwiftUI Color based on the DSNavigationBarColor key func color(key: DSNavigationBarColor) -> Color { switch key { case .button: @@ -37,9 +37,9 @@ public enum DSNavigationBarColor { public struct DSNavigationBarAppearance: DSNavigationBarAppearanceProtocol { public init( - buttons: UIColor, - text: UIColor, - bar: UIColor, + buttons: DSUIColor, + text: DSUIColor, + bar: DSUIColor, translucent: Bool = false ) { self.buttons = buttons @@ -48,8 +48,8 @@ public struct DSNavigationBarAppearance: DSNavigationBarAppearanceProtocol { self.translucent = translucent } - public var buttons: UIColor - public var text: UIColor - public var bar: UIColor + public var buttons: DSUIColor + public var text: DSUIColor + public var bar: DSUIColor public var translucent: Bool } diff --git a/DSKit/Sources/DSKit/Designable/DSPriceAppearance.swift b/DSKit/Sources/DSKit/Designable/DSPriceAppearance.swift index 454c4be..da4212b 100644 --- a/DSKit/Sources/DSKit/Designable/DSPriceAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSPriceAppearance.swift @@ -6,13 +6,12 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public protocol DSPriceAppearanceProtocol { - var regularAmount: UIColor { get set } - var badgeBackground: UIColor { get set } - var badgeText: UIColor { get set } + var regularAmount: DSUIColor { get set } + var badgeBackground: DSUIColor { get set } + var badgeText: DSUIColor { get set } var badgeCornerRadius: CGFloat { get set } } @@ -23,14 +22,15 @@ public enum DSPriceColorKey { } extension DSPriceAppearanceProtocol { + /// Returns a SwiftUI Color based on the DSPriceColorKey func color(key: DSPriceColorKey) -> Color { switch key { case .regularAmount: - regularAmount.color + return Color(regularAmount) case .badgeBackground: - badgeBackground.color + return Color(badgeBackground) case .badgeText: - badgeText.color + return Color(badgeText) } } } @@ -38,19 +38,19 @@ extension DSPriceAppearanceProtocol { public struct DSPriceAppearance: DSPriceAppearanceProtocol { public init( - regularAmount: UIColor, - badgeBackground: UIColor = .red, - badgeText: UIColor = .white, + regularAmount: DSUIColor, + badgeBackground: DSUIColor = DSUIColor.red, + badgeText: DSUIColor = DSUIColor.white, badgeCornerRadius: CGFloat = 4.0 ) { - self.badgeText = badgeText + self.regularAmount = regularAmount self.badgeBackground = badgeBackground + self.badgeText = badgeText self.badgeCornerRadius = badgeCornerRadius - self.regularAmount = regularAmount } - public var regularAmount: UIColor - public var badgeBackground: UIColor - public var badgeText: UIColor + public var regularAmount: DSUIColor + public var badgeBackground: DSUIColor + public var badgeText: DSUIColor public var badgeCornerRadius: CGFloat } diff --git a/DSKit/Sources/DSKit/Designable/DSTabbarAppearance.swift b/DSKit/Sources/DSKit/Designable/DSTabbarAppearance.swift index 4d43f4a..b2e563f 100644 --- a/DSKit/Sources/DSKit/Designable/DSTabbarAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSTabbarAppearance.swift @@ -6,56 +6,55 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public protocol DSTabBarAppearanceProtocol { - var barTint: UIColor { get set } - var itemTint: UIColor { get set } - var unselectedItemTint: UIColor { get set } - var badge: UIColor { get set } + var barTint: DSUIColor { get set } + var itemTint: DSUIColor { get set } + var unselectedItemTint: DSUIColor { get set } + var badge: DSUIColor { get set } var translucent: Bool { get set } } +public enum DSTabBarColorKey { + case tint + case itemTint + case unselectedItemTint + case badge +} + extension DSTabBarAppearanceProtocol { + /// Returns a SwiftUI Color based on the DSTabBarColorKey func color(key: DSTabBarColorKey) -> Color { switch key { case .tint: - barTint.color + return Color(barTint) case .itemTint: - itemTint.color + return Color(itemTint) case .unselectedItemTint: - unselectedItemTint.color + return Color(unselectedItemTint) case .badge: - badge.color + return Color(badge) } } } -public enum DSTabBarColorKey { - case tint - case itemTint - case unselectedItemTint - case badge -} - -public struct DSTabbarAppearance: DSTabBarAppearanceProtocol { +public struct DSTabBarAppearance: DSTabBarAppearanceProtocol { - /// Init tabbar colors + /// Initialize tab bar colors /// - Parameters: - /// - barTint: UIColor - /// - itemTint: UIColor - /// - unselectedItemTint: UIColor - /// - badge: UIColor + /// - barTint: DSUIColor + /// - itemTint: DSUIColor + /// - unselectedItemTint: DSUIColor + /// - badge: DSUIColor /// - translucent: Bool public init( - barTint: UIColor, - itemTint: UIColor, - unselectedItemTint: UIColor, - badge: UIColor, + barTint: DSUIColor, + itemTint: DSUIColor, + unselectedItemTint: DSUIColor, + badge: DSUIColor, translucent: Bool = false ) { - self.barTint = barTint self.itemTint = itemTint self.unselectedItemTint = unselectedItemTint @@ -63,9 +62,9 @@ public struct DSTabbarAppearance: DSTabBarAppearanceProtocol { self.translucent = translucent } - public var barTint: UIColor - public var itemTint: UIColor - public var unselectedItemTint: UIColor - public var badge: UIColor + public var barTint: DSUIColor + public var itemTint: DSUIColor + public var unselectedItemTint: DSUIColor + public var badge: DSUIColor public var translucent: Bool } diff --git a/DSKit/Sources/DSKit/Designable/DSTextAppearance.swift b/DSKit/Sources/DSKit/Designable/DSTextAppearance.swift index 9b10ae8..ecab5b2 100644 --- a/DSKit/Sources/DSKit/Designable/DSTextAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSTextAppearance.swift @@ -6,36 +6,36 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit +import SwiftUI public protocol DSTextAppearanceProtocol { - var largeTitle: UIColor { get set } - var title1: UIColor { get set } - var title2: UIColor { get set } - var title3: UIColor { get set } - var headline: UIColor { get set } - var subheadline: UIColor { get set } - var body: UIColor { get set } - var callout: UIColor { get set } - var caption1: UIColor { get set } - var caption2: UIColor { get set } - var footnote: UIColor { get set } + var largeTitle: DSUIColor { get set } + var title1: DSUIColor { get set } + var title2: DSUIColor { get set } + var title3: DSUIColor { get set } + var headline: DSUIColor { get set } + var subheadline: DSUIColor { get set } + var body: DSUIColor { get set } + var callout: DSUIColor { get set } + var caption1: DSUIColor { get set } + var caption2: DSUIColor { get set } + var footnote: DSUIColor { get set } } public struct DSTextAppearance: DSTextAppearanceProtocol { public init( - largeTitle: UIColor, - title1: UIColor, - title2: UIColor, - title3: UIColor, - headline: UIColor, - subheadline: UIColor, - body: UIColor, - callout: UIColor, - caption1: UIColor, - caption2: UIColor, - footnote: UIColor + largeTitle: DSUIColor, + title1: DSUIColor, + title2: DSUIColor, + title3: DSUIColor, + headline: DSUIColor, + subheadline: DSUIColor, + body: DSUIColor, + callout: DSUIColor, + caption1: DSUIColor, + caption2: DSUIColor, + footnote: DSUIColor ) { self.largeTitle = largeTitle self.title1 = title1 @@ -50,28 +50,28 @@ public struct DSTextAppearance: DSTextAppearanceProtocol { self.footnote = footnote } - public var largeTitle: UIColor - public var title1: UIColor - public var title2: UIColor - public var title3: UIColor - public var headline: UIColor - public var subheadline: UIColor - public var body: UIColor - public var callout: UIColor - public var caption1: UIColor - public var caption2: UIColor - public var footnote: UIColor + public var largeTitle: DSUIColor + public var title1: DSUIColor + public var title2: DSUIColor + public var title3: DSUIColor + public var headline: DSUIColor + public var subheadline: DSUIColor + public var body: DSUIColor + public var callout: DSUIColor + public var caption1: DSUIColor + public var caption2: DSUIColor + public var footnote: DSUIColor } public extension DSTextAppearance { - /// Get DSTextAppearance using only 2 colors to fill them all + /// Get DSTextAppearance using only 2 colors to fill all text styles /// - Parameters: - /// - main: UIColor - /// - secondary: UIColor + /// - main: DSUIColor + /// - secondary: DSUIColor /// - Returns: DSTextAppearance static func textColors( - main: UIColor, secondary: UIColor + main: DSUIColor, secondary: DSUIColor ) -> DSTextAppearance { DSTextAppearance( largeTitle: main, diff --git a/DSKit/Sources/DSKit/Designable/DSTextColorKey.swift b/DSKit/Sources/DSKit/Designable/DSTextColorKey.swift index 1a10526..bf8e05e 100644 --- a/DSKit/Sources/DSKit/Designable/DSTextColorKey.swift +++ b/DSKit/Sources/DSKit/Designable/DSTextColorKey.swift @@ -6,7 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public indirect enum DSTextColorKey: Equatable, Hashable { @@ -27,7 +26,7 @@ public indirect enum DSTextColorKey: Equatable, Hashable { uiColor(for: font, appearance: appearance, viewStyle: viewStyle).color } - public func uiColor(for font: DSTextFontKey, appearance: DSAppearance, viewStyle: DSViewStyle) -> UIColor { + public func uiColor(for font: DSTextFontKey, appearance: DSAppearance, viewStyle: DSViewStyle) -> DSUIColor { let designableTextColor: DSTextAppearanceProtocol @@ -62,7 +61,7 @@ public indirect enum DSTextColorKey: Equatable, Hashable { case .footnote: return designableTextColor.footnote case .custom(_): - return UIColor.black + return DSUIColor.black case .fontWithSize(let font, _): return uiColor(for: font, appearance: appearance, viewStyle: viewStyle) case .smallHeadline: diff --git a/DSKit/Sources/DSKit/Designable/DSTextFieldAppearance.swift b/DSKit/Sources/DSKit/Designable/DSTextFieldAppearance.swift index 71ec89d..dbd2a37 100644 --- a/DSKit/Sources/DSKit/Designable/DSTextFieldAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSTextFieldAppearance.swift @@ -6,24 +6,24 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public protocol DSTextFieldAppearanceProtocol { - var background: UIColor { get set } - var text: UIColor { get set } - var placeHolder: UIColor { get set } + var background: DSUIColor { get set } + var text: DSUIColor { get set } + var placeHolder: DSUIColor { get set } } public extension DSTextFieldAppearanceProtocol { + /// Returns a SwiftUI Color based on the DSTextFieldColorKey func color(key: DSTextFieldColorKey) -> Color { switch key { case .background: - background.color + return Color(background) case .text: - text.color + return Color(text) case .placeholder: - placeHolder.color + return Color(placeHolder) } } } @@ -37,16 +37,16 @@ public enum DSTextFieldColorKey { public struct DSTextFieldAppearance: DSTextFieldAppearanceProtocol { public init( - background: UIColor, - text: UIColor, - placeHolder: UIColor + background: DSUIColor, + text: DSUIColor, + placeHolder: DSUIColor ) { self.background = background self.text = text self.placeHolder = placeHolder } - public var background: UIColor - public var text: UIColor - public var placeHolder: UIColor + public var background: DSUIColor + public var text: DSUIColor + public var placeHolder: DSUIColor } diff --git a/DSKit/Sources/DSKit/Designable/DSTextFontKey.swift b/DSKit/Sources/DSKit/Designable/DSTextFontKey.swift index 92aadfe..688fe9b 100644 --- a/DSKit/Sources/DSKit/Designable/DSTextFontKey.swift +++ b/DSKit/Sources/DSKit/Designable/DSTextFontKey.swift @@ -6,7 +6,6 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public indirect enum DSTextFontKey: Equatable, Hashable { @@ -22,7 +21,7 @@ public indirect enum DSTextFontKey: Equatable, Hashable { case caption1 case caption2 case footnote - case custom(UIFont) + case custom(DSFont) case fontWithSize(DSTextFontKey, CGFloat) case smallHeadline case smallSubheadline @@ -36,7 +35,7 @@ public indirect enum DSTextFontKey: Equatable, Hashable { return Font(uiFont(for: appearance)) } - public func uiFont(for appearance: DSAppearance) -> UIFont { + public func uiFont(for appearance: DSAppearance) -> DSFont { return switch self { case .title1: appearance.fonts.title1 @@ -73,7 +72,7 @@ public indirect enum DSTextFontKey: Equatable, Hashable { } } - func color(for textColors: DSTextAppearance) -> UIColor { + func color(for textColors: DSTextAppearance) -> DSUIColor { return switch self { case .largeTitle: textColors.largeTitle @@ -98,7 +97,7 @@ public indirect enum DSTextFontKey: Equatable, Hashable { case .footnote: textColors.footnote case .custom(_): - UIColor.black + DSUIColor.black case .fontWithSize(let font, _): font.color(for: textColors) case .smallHeadline: diff --git a/DSKit/Sources/DSKit/Designable/DSViewAppearance.swift b/DSKit/Sources/DSKit/Designable/DSViewAppearance.swift index 9e7a611..353b429 100644 --- a/DSKit/Sources/DSKit/Designable/DSViewAppearance.swift +++ b/DSKit/Sources/DSKit/Designable/DSViewAppearance.swift @@ -6,31 +6,31 @@ // Copyright © 2021 Borinschi Ivan. All rights reserved. // -import UIKit import SwiftUI public protocol DSViewAppearanceProtocol { var button: DSButtonAppearanceProtocol { get } var text: DSTextAppearanceProtocol { get } var textField: DSTextFieldAppearanceProtocol { get } - var background: UIColor { get } - var separator: UIColor { get } + var background: DSUIColor { get } + var separator: DSUIColor { get } var cornerRadius: CGFloat { get } } public extension DSViewAppearanceProtocol { + /// Returns a SwiftUI Color based on the DSViewColorKey func color(for viewKey: DSViewColorKey, appearance: DSAppearance, style: DSViewStyle) -> Color { switch viewKey { case .button(let buttonKey): - button.color(key: buttonKey) + return button.color(key: buttonKey) case .background: - background.color + return Color(background) case .separator: - separator.color + return Color(separator) case .textField(let textFieldKey): - textField.color(key: textFieldKey) + return textField.color(key: textFieldKey) case .text(let textKey): - textKey.color(for: appearance, and: style) + return textKey.color(for: appearance, and: style) } } } @@ -49,24 +49,22 @@ public struct DSViewAppearance: DSViewAppearanceProtocol { button: DSButtonAppearanceProtocol, text: DSTextAppearanceProtocol, textField: DSTextFieldAppearanceProtocol, - background: UIColor, - separator: UIColor, + background: DSUIColor, + separator: DSUIColor, cornerRadius: CGFloat ) { - self.button = button self.text = text + self.textField = textField self.background = background self.separator = separator self.cornerRadius = cornerRadius - self.textField = textField } public var button: DSButtonAppearanceProtocol public var text: DSTextAppearanceProtocol public var textField: DSTextFieldAppearanceProtocol - public var background: UIColor - public var separator: UIColor + public var background: DSUIColor + public var separator: DSUIColor public var cornerRadius: CGFloat } - diff --git a/DSKit/Sources/DSKit/Designable/Fonts/DSFont.swift b/DSKit/Sources/DSKit/Designable/Fonts/DSFont.swift new file mode 100644 index 0000000..cd329bf --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/Fonts/DSFont.swift @@ -0,0 +1,18 @@ +// +// DSFont.swift +// DSKit +// +// Created by Ivan Borinschi on 15.11.2024. +// + +import Foundation + +#if canImport(UIKit) +import UIKit +/// Cross-platform font alias for iOS, tvOS, watchOS +public typealias DSFont = UIFont +#elseif canImport(AppKit) +import AppKit +/// Cross-platform font alias for macOS +public typealias DSFont = NSFont +#endif diff --git a/DSKit/Sources/DSKit/Designable/Fonts/DSScaledFont.swift b/DSKit/Sources/DSKit/Designable/Fonts/DSScaledFont.swift index a71955c..84ed9e2 100644 --- a/DSKit/Sources/DSKit/Designable/Fonts/DSScaledFont.swift +++ b/DSKit/Sources/DSKit/Designable/Fonts/DSScaledFont.swift @@ -27,89 +27,75 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -import UIKit - -/// A utility class to help you use custom fonts with -/// dynamic type. -/// -/// To use this class you must supply the name of a style -/// dictionary for the font when creating the class. The -/// style dictionary should be stored as a property list -/// file in the main bundle. -/// -/// The style dictionary contains an entry for each text -/// style that uses the raw string value for each -/// `UIFontTextStyle` as the key. -/// -/// The value of each entry is a dictionary with two keys: -/// -/// + fontName: A String which is the font name. -/// + fontSize: A number which is the point size to use -/// at the `.large` content size. -/// -/// For example to use a 17 pt Noteworthy-Bold font -/// for the `.headline` style at the `.large` content size: -/// -/// -/// UICTFontTextStyleHeadline -/// -/// fontName -/// Noteworthy-Bold -/// fontSize -/// 17 -/// -/// -/// -/// You do not need to include an entry for every text style -/// but if you try to use a text style that is not included -/// in the dictionary it will fallback to the system preferred -/// font. +import Foundation +import SwiftUI public final class DSScaledFont { private struct FontDescription: Decodable { let fontSize: CGFloat let fontName: String } - - private typealias DSStyleDictionary = [UIFont.TextStyle.RawValue: FontDescription] + + private typealias DSStyleDictionary = [String: FontDescription] private var styleDictionary: DSStyleDictionary? - - /// Create a `ScaledFont` + + /// Create a `DSScaledFont` /// /// - Parameter fontName: Name of a plist file (without the extension) /// in the main bundle that contains the style dictionary used to /// scale fonts for each text style. - public init(fontName: String) { - if let url = Bundle(for: DSScaledFont.self).url(forResource: fontName, withExtension: "plist"), - let data = try? Data(contentsOf: url) { + let data = try? Data(contentsOf: url) { let decoder = PropertyListDecoder() styleDictionary = try? decoder.decode(DSStyleDictionary.self, from: data) } } - + /// Get the scaled font for the given text style using the /// style dictionary supplied at initialization. /// - /// - Parameter textStyle: The `UIFontTextStyle` for the - /// font. - /// - Returns: A `UIFont` of the custom font that has been - /// scaled for the users currently selected preferred - /// text size. + /// - Parameter textStyle: The `DSFont.TextStyle` for the font. + /// - Returns: A `DSFont` of the custom font that has been scaled + /// for the user's currently selected preferred text size. /// - /// - Note: If the style dictionary does not have - /// a font for this text style the default preferred - /// font is returned. - - public func font(forTextStyle textStyle: UIFont.TextStyle) -> UIFont { - - guard let fontDescription = styleDictionary?[textStyle.rawValue], - let font = UIFont(name: fontDescription.fontName, size: fontDescription.fontSize) else { - return UIFont.preferredFont(forTextStyle: textStyle) + /// - Note: If the style dictionary does not have a font for this + /// text style, the default preferred font is returned. + public func font(forTextStyle textStyle: DSFont.TextStyle) -> DSFont { + guard let fontDescription = styleDictionary?[textStyle.rawValue] else { + return defaultFont(for: textStyle) } - + + guard let font = DSFont(name: fontDescription.fontName, size: fontDescription.fontSize) else { + return defaultFont(for: textStyle) + } + + #if canImport(UIKit) let fontMetrics = UIFontMetrics(forTextStyle: textStyle) return fontMetrics.scaledFont(for: font) + #elseif canImport(AppKit) + return font // macOS does not have `UIFontMetrics` + #endif + } + + /// Fallback to the default system font for the given text style. + private func defaultFont(for textStyle: DSFont.TextStyle) -> DSFont { + #if canImport(UIKit) + return DSFont.preferredFont(forTextStyle: textStyle) + #elseif canImport(AppKit) + switch textStyle { + case .title1: return DSFont.systemFont(ofSize: 28, weight: .bold) + case .title2: return DSFont.systemFont(ofSize: 22, weight: .semibold) + case .title3: return DSFont.systemFont(ofSize: 20, weight: .regular) + case .headline: return DSFont.systemFont(ofSize: 17, weight: .semibold) + case .subheadline: return DSFont.systemFont(ofSize: 15, weight: .regular) + case .body: return DSFont.systemFont(ofSize: 17, weight: .regular) + case .callout: return DSFont.systemFont(ofSize: 16, weight: .regular) + case .caption1: return DSFont.systemFont(ofSize: 12, weight: .regular) + case .caption2: return DSFont.systemFont(ofSize: 11, weight: .regular) + case .footnote: return DSFont.systemFont(ofSize: 13, weight: .regular) + default: return DSFont.systemFont(ofSize: 17, weight: .regular) + } + #endif } } diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/DSHostingController.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/DSHostingController.swift new file mode 100644 index 0000000..48a697c --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/DSHostingController.swift @@ -0,0 +1,21 @@ +// +// DSHostingController.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import Foundation + +#if canImport(UIKit) +import UIKit +import SwiftUI + +public typealias DSHostingController = UIHostingController + +#elseif canImport(AppKit) +import AppKit +import SwiftUI + +public typealias DSHostingController = NSHostingController +#endif diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/DSKeyboard.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/DSKeyboard.swift new file mode 100644 index 0000000..f8c3870 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/DSKeyboard.swift @@ -0,0 +1,41 @@ +// +// DSKeyboard.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import Foundation + +// Define cross-platform types +#if canImport(UIKit) +import UIKit +public typealias DSKeyboardType = UIKeyboardType +public typealias DSTextContentType = UITextContentType +public typealias DSAutocapitalizationType = UITextAutocapitalizationType +#elseif canImport(AppKit) +import AppKit +// macOS does not have equivalents, so we'll define our own types +public enum DSKeyboardType { + case `default` + case asciiCapable + case numbersAndPunctuation + case URL + case numberPad + case phonePad + case namePhonePad + case emailAddress + case decimalPad + case twitter + case webSearch + case asciiCapableNumberPad +} + +public typealias DSTextContentType = NSTextContentType +public enum DSAutocapitalizationType { + case none + case words + case sentences + case allCharacters +} +#endif diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIColor.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIColor.swift new file mode 100644 index 0000000..c8b9c83 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIColor.swift @@ -0,0 +1,16 @@ +// +// DSUIColor.swift +// DSKit +// +// Created by Ivan Borinschi on 15.11.2024. +// + +import Foundation + +#if canImport(UIKit) +import UIKit +public typealias DSUIColor = UIColor +#elseif canImport(AppKit) +import AppKit +public typealias DSUIColor = NSColor +#endif diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIImage.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIImage.swift new file mode 100644 index 0000000..d74bb61 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIImage.swift @@ -0,0 +1,53 @@ +// +// DSUIImage.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import Foundation + +#if canImport(UIKit) +import UIKit +public typealias DSUIImage = UIImage +#elseif canImport(AppKit) +import AppKit +public typealias DSUIImage = NSImage +#endif + +extension DSUIImage { + /// Cross-platform initializer for loading an image from a bundle. + /// + /// - Parameters: + /// - named: The name of the image resource. + /// - bundle: The bundle to search for the image. + /// - options: Additional options (iOS only). + /// - Returns: An optional `DSUIImage` if the image is found, otherwise `nil`. + public convenience init?( + named: String, + in bundle: Bundle?, + with options: Any? = nil + ) { + #if canImport(UIKit) + self.init(named: named, in: bundle, with: options) + #elseif canImport(AppKit) + guard let bundle = bundle, + let path = bundle.path(forResource: named, ofType: nil) else { + return nil + } + self.init(contentsOfFile: path) + #endif + } +} + +import SwiftUI + +extension Image { + init(dsUIImage: DSUIImage) { + #if canImport(UIKit) + self.init(uiImage: dsUIImage) + #elseif canImport(AppKit) + self.init(nsImage: dsUIImage) + #endif + } +} diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIScrollView.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIScrollView.swift new file mode 100644 index 0000000..69b3496 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/DSUIScrollView.swift @@ -0,0 +1,18 @@ +// +// DSUIScrollView.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import Foundation + +#if canImport(UIKit) +import UIKit +public typealias DSUIScrollView = UIScrollView +public typealias DSScrollViewDelegate = UIScrollViewDelegate +#elseif canImport(AppKit) +import AppKit +public typealias DSUIScrollView = NSScrollView +public protocol DSScrollViewDelegate: AnyObject {} +#endif diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/DSViewReprezentable.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/DSViewReprezentable.swift new file mode 100644 index 0000000..9556935 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/DSViewReprezentable.swift @@ -0,0 +1,24 @@ +// +// DSViewReprezentable.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import Foundation + +#if canImport(UIKit) +import UIKit +import SwiftUI + +public typealias DSViewRepresentable = UIViewRepresentable +public typealias DSPlatformView = UIView + +#elseif canImport(AppKit) +import AppKit +import SwiftUI + +public typealias DSViewRepresentable = NSViewRepresentable +public typealias DSPlatformView = NSView + +#endif diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/NavigationBarHidden.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/NavigationBarHidden.swift new file mode 100644 index 0000000..caad6b6 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/NavigationBarHidden.swift @@ -0,0 +1,19 @@ +// +// NavigationBarHidden.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import SwiftUI + +public extension View { + @ViewBuilder + func plaftormBasedNavigationBarHidden(_ hidden: Bool) -> some View { + #if os(iOS) + self.navigationBarHidden(hidden) + #else + self + #endif + } +} diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/NavigationBarTitleDisplayMode.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/NavigationBarTitleDisplayMode.swift new file mode 100644 index 0000000..34ea122 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/NavigationBarTitleDisplayMode.swift @@ -0,0 +1,20 @@ +// +// NavigationBarTitleDisplayMode.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import SwiftUI + +public extension View { + /// Applies `.navigationBarTitleDisplayMode` only on iOS, does nothing on macOS. + @ViewBuilder + func platformBasedNavigationBarTitleDisplayModeInline() -> some View { + #if os(iOS) + self.navigationBarTitleDisplayMode(.inline) + #else + self + #endif + } +} diff --git a/DSKit/Sources/DSKit/Designable/PlatformBased/ToolbarItemPlacement.swift b/DSKit/Sources/DSKit/Designable/PlatformBased/ToolbarItemPlacement.swift new file mode 100644 index 0000000..a969257 --- /dev/null +++ b/DSKit/Sources/DSKit/Designable/PlatformBased/ToolbarItemPlacement.swift @@ -0,0 +1,18 @@ +// +// ToolbarItemPlacement.swift +// DSKit +// +// Created by Ivan Borinschi on 18.11.2024. +// + +import SwiftUI + +public extension ToolbarItemPlacement { + static var platformBasedTrailing: ToolbarItemPlacement { + #if canImport(UIKit) + return .navigationBarTrailing + #elseif canImport(AppKit) + return .automatic + #endif + } +} diff --git a/DSKit/Sources/DSKit/Fonts/DSFuturaFont.swift b/DSKit/Sources/DSKit/Fonts/DSFuturaFont.swift index 3fdcf4e..fd18c9c 100644 --- a/DSKit/Sources/DSKit/Fonts/DSFuturaFont.swift +++ b/DSKit/Sources/DSKit/Fonts/DSFuturaFont.swift @@ -5,65 +5,76 @@ // Created by Ivan Borinschi on 21.05.2024. // +#if canImport(UIKit) import UIKit +#elseif canImport(AppKit) +import AppKit +#endif public class DSFuturaFont: DSFontsProtocol { - public var body: UIFont { + + public var body: DSFont { return regularFont(size: 17.0) } - public var callout: UIFont { + public var callout: DSFont { return regularFont(size: 16.0) } - public var caption1: UIFont { + public var caption1: DSFont { return regularFont(size: 12.0) } - public var caption2: UIFont { + public var caption2: DSFont { return regularFont(size: 11.0) } - public var footnote: UIFont { + public var footnote: DSFont { return regularFont(size: 13.0) } - public var headline: UIFont { - return bolfFont(size: 17.0) + public var headline: DSFont { + return boldFont(size: 17.0) } - public var subheadline: UIFont { + public var subheadline: DSFont { return regularFont(size: 15.0) } - public var largeTitle: UIFont { + public var largeTitle: DSFont { return regularFont(size: 34.0) } - public var title1: UIFont { + public var title1: DSFont { return regularFont(size: 28.0) } - public var title2: UIFont { + public var title2: DSFont { return regularFont(size: 22.0) } - public var title3: UIFont { + public var title3: DSFont { return regularFont(size: 20.0) } public init() {} - private func regularFont(size: CGFloat) -> UIFont { - scaledFont(for: "Futura-Medium", textStyle: .body, defaultSize: size) + // MARK: - Private Helpers + + private func regularFont(size: CGFloat) -> DSFont { + return scaledFont(for: "Futura-Medium", textStyle: .body, defaultSize: size) } - private func bolfFont(size: CGFloat) -> UIFont { - scaledFont(for: "Futura-Bold", textStyle: .body, defaultSize: size) + private func boldFont(size: CGFloat) -> DSFont { + return scaledFont(for: "Futura-Bold", textStyle: .body, defaultSize: size) } - private func scaledFont(for fontName: String, textStyle: UIFont.TextStyle, defaultSize: CGFloat) -> UIFont { - let font = UIFont(name: fontName, size: defaultSize) ?? UIFont.systemFont(ofSize: defaultSize) + private func scaledFont(for fontName: String, textStyle: DSFont.TextStyle, defaultSize: CGFloat) -> DSFont { + let font = DSFont(name: fontName, size: defaultSize) ?? DSFont.systemFont(ofSize: defaultSize) + #if canImport(UIKit) return UIFontMetrics(forTextStyle: textStyle).scaledFont(for: font) + #elseif canImport(AppKit) + return font + #endif } } diff --git a/DSKit/Sources/DSKit/Fonts/DSHelveticaNeueFont.swift b/DSKit/Sources/DSKit/Fonts/DSHelveticaNeueFont.swift index 95b332e..12590e9 100644 --- a/DSKit/Sources/DSKit/Fonts/DSHelveticaNeueFont.swift +++ b/DSKit/Sources/DSKit/Fonts/DSHelveticaNeueFont.swift @@ -5,65 +5,76 @@ // Created by Ivan Borinschi on 21.05.2024. // +#if canImport(UIKit) import UIKit +#elseif canImport(AppKit) +import AppKit +#endif public class DSHelveticaNeueFont: DSFontsProtocol { - public var body: UIFont { + + public var body: DSFont { return regularFont(size: 17.0) } - public var callout: UIFont { + public var callout: DSFont { return regularFont(size: 16.0) } - public var caption1: UIFont { + public var caption1: DSFont { return regularFont(size: 12.0) } - public var caption2: UIFont { + public var caption2: DSFont { return regularFont(size: 11.0) } - public var footnote: UIFont { + public var footnote: DSFont { return regularFont(size: 13.0) } - public var headline: UIFont { - return bolfFont(size: 17.0) + public var headline: DSFont { + return boldFont(size: 17.0) } - public var subheadline: UIFont { + public var subheadline: DSFont { return regularFont(size: 15.0) } - public var largeTitle: UIFont { + public var largeTitle: DSFont { return regularFont(size: 34.0) } - public var title1: UIFont { + public var title1: DSFont { return regularFont(size: 28.0) } - public var title2: UIFont { + public var title2: DSFont { return regularFont(size: 22.0) } - public var title3: UIFont { + public var title3: DSFont { return regularFont(size: 20.0) } public init() {} - private func regularFont(size: CGFloat) -> UIFont { - scaledFont(for: "HelveticaNeue", textStyle: .body, defaultSize: size) + // MARK: - Private Helpers + + private func regularFont(size: CGFloat) -> DSFont { + return scaledFont(for: "HelveticaNeue", textStyle: .body, defaultSize: size) } - private func bolfFont(size: CGFloat) -> UIFont { - scaledFont(for: "HelveticaNeue-Bold", textStyle: .body, defaultSize: size) + private func boldFont(size: CGFloat) -> DSFont { + return scaledFont(for: "HelveticaNeue-Bold", textStyle: .body, defaultSize: size) } - private func scaledFont(for fontName: String, textStyle: UIFont.TextStyle, defaultSize: CGFloat) -> UIFont { - let font = UIFont(name: fontName, size: defaultSize) ?? UIFont(name: "Georgia", size: defaultSize) ?? UIFont.systemFont(ofSize: defaultSize) + private func scaledFont(for fontName: String, textStyle: DSFont.TextStyle, defaultSize: CGFloat) -> DSFont { + let font = DSFont(name: fontName, size: defaultSize) ?? DSFont(name: "Georgia", size: defaultSize) ?? DSFont.systemFont(ofSize: defaultSize) + #if canImport(UIKit) return UIFontMetrics(forTextStyle: textStyle).scaledFont(for: font) + #elseif canImport(AppKit) + return font // macOS does not support UIFontMetrics + #endif } } diff --git a/DSKit/Sources/DSKit/Fonts/DSVerdanaFont.swift b/DSKit/Sources/DSKit/Fonts/DSVerdanaFont.swift index d83bd2b..246c68f 100644 --- a/DSKit/Sources/DSKit/Fonts/DSVerdanaFont.swift +++ b/DSKit/Sources/DSKit/Fonts/DSVerdanaFont.swift @@ -1,69 +1,81 @@ // -// RetroFont.swift +// DSVerdanaFont.swift // DSKit // -// Created by Ivan Borinschi on 21.05.2024. +// Created by Ivan Borinschi on 15.11.2024. // +#if canImport(UIKit) import UIKit +#elseif canImport(AppKit) +import AppKit +#endif public class DSVerdanaFont: DSFontsProtocol { - public var body: UIFont { + + public var body: DSFont { return regularFont(size: 17.0) } - public var callout: UIFont { + public var callout: DSFont { return regularFont(size: 16.0) } - public var caption1: UIFont { + public var caption1: DSFont { return regularFont(size: 12.0) } - public var caption2: UIFont { + public var caption2: DSFont { return regularFont(size: 11.0) } - public var footnote: UIFont { + public var footnote: DSFont { return regularFont(size: 13.0) } - public var headline: UIFont { - return bolfFont(size: 17.0) + public var headline: DSFont { + return boldFont(size: 17.0) } - public var subheadline: UIFont { + public var subheadline: DSFont { return regularFont(size: 15.0) } - public var largeTitle: UIFont { + public var largeTitle: DSFont { return regularFont(size: 34.0) } - public var title1: UIFont { + public var title1: DSFont { return regularFont(size: 28.0) } - public var title2: UIFont { + public var title2: DSFont { return regularFont(size: 22.0) } - public var title3: UIFont { + public var title3: DSFont { return regularFont(size: 20.0) } public init() {} - private func regularFont(size: CGFloat) -> UIFont { - scaledFont(for: "Verdana", textStyle: .body, defaultSize: size) + // MARK: - Private Helpers + + private func regularFont(size: CGFloat) -> DSFont { + return scaledFont(for: "Verdana", textStyle: .body, defaultSize: size) } - private func bolfFont(size: CGFloat) -> UIFont { - scaledFont(for: "Verdana-Bold", textStyle: .body, defaultSize: size) + private func boldFont(size: CGFloat) -> DSFont { + return scaledFont(for: "Verdana-Bold", textStyle: .body, defaultSize: size) } - private func scaledFont(for fontName: String, textStyle: UIFont.TextStyle, defaultSize: CGFloat) -> UIFont { - let font = UIFont(name: fontName, size: defaultSize) ?? UIFont(name: "Georgia", size: defaultSize) ?? UIFont.systemFont(ofSize: defaultSize) + private func scaledFont(for fontName: String, textStyle: DSFont.TextStyle, defaultSize: CGFloat) -> DSFont { + let font = DSFont(name: fontName, size: defaultSize) ?? DSFont(name: "Georgia", size: defaultSize) ?? DSFont.systemFont(ofSize: defaultSize) + + #if canImport(UIKit) return UIFontMetrics(forTextStyle: textStyle).scaledFont(for: font) + #elseif canImport(AppKit) + return font // macOS does not support UIFontMetrics scaling + #endif } } diff --git a/DSKit/Sources/DSKit/Helpers/DSCustomUITextField.swift b/DSKit/Sources/DSKit/Helpers/DSCustomUITextField.swift index 21541d3..f26631c 100644 --- a/DSKit/Sources/DSKit/Helpers/DSCustomUITextField.swift +++ b/DSKit/Sources/DSKit/Helpers/DSCustomUITextField.swift @@ -7,24 +7,37 @@ import SwiftUI -struct DSCustomUITextField: UIViewRepresentable { +struct DSCustomUITextField: DSViewRepresentable { @Environment(\.appearance) var appearance: DSAppearance @Environment(\.viewStyle) var viewStyle: DSViewStyle - + @Binding var text: String @Binding var isSecureEntry: Bool @Binding var isEditing: Bool - + var placeholder: String - - var keyboardType: UIKeyboardType - var textContentType: UITextContentType? - var autocapitalizationType: UITextAutocapitalizationType + + // Use the cross-platform types + var keyboardType: DSKeyboardType + var textContentType: DSTextContentType? + var autocapitalizationType: DSAutocapitalizationType var onCommit: (() -> Void)? + // MARK: - iOS Implementation + #if canImport(UIKit) func makeUIView(context: Context) -> UITextField { let textField = UITextField() + configureUITextField(textField, context: context) + return textField + } + + func updateUIView(_ uiView: UITextField, context: Context) { + uiView.text = text + uiView.isSecureTextEntry = isSecureEntry + } + + private func configureUITextField(_ textField: UITextField, context: Context) { textField.placeholder = placeholder textField.attributedPlaceholder = NSAttributedString( string: placeholder, @@ -37,40 +50,77 @@ struct DSCustomUITextField: UIViewRepresentable { textField.autocapitalizationType = autocapitalizationType textField.delegate = context.coordinator textField.textColor = viewStyle.colors(from: appearance).textField.text + } + #elseif canImport(AppKit) + func makeNSView(context: Context) -> NSTextField { + let textField = NSTextField() + configureNSTextField(textField, context: context) return textField } - func updateUIView(_ uiView: UITextField, context: Context) { - uiView.text = text - uiView.isSecureTextEntry = isSecureEntry + func updateNSView(_ nsView: NSTextField, context: Context) { + nsView.stringValue = text + } + + private func configureNSTextField(_ textField: NSTextField, context: Context) { + textField.placeholderString = placeholder + textField.font = NSFont.systemFont(ofSize: 14) + textField.delegate = context.coordinator + textField.textColor = viewStyle.colors(from: appearance).textField.text + textField.isBezeled = true + textField.isBordered = true + textField.isEditable = true + textField.isSelectable = true + textField.contentType = .addressCity + } + #endif + + // MARK: - Coordinator + func makeCoordinator() -> DSCustomUITextFieldCoordinator { + DSCustomUITextFieldCoordinator(self) } +} - func makeCoordinator() -> Coordinator { - Coordinator(self) +final class DSCustomUITextFieldCoordinator: NSObject { + var parent: DSCustomUITextField + init(_ textField: DSCustomUITextField) { + self.parent = textField } +} - class Coordinator: NSObject, UITextFieldDelegate { - var parent: DSCustomUITextField - - init(_ textField: DSCustomUITextField) { - self.parent = textField - } - - func textFieldDidChangeSelection(_ textField: UITextField) { - parent.text = textField.text ?? "" - } - - func textFieldShouldReturn(_ textField: UITextField) -> Bool { - parent.onCommit?() - return true - } - - func textFieldDidBeginEditing(_ textField: UITextField) { - parent.isEditing = true - } - - func textFieldDidEndEditing(_ textField: UITextField) { - parent.isEditing = false - } +#if canImport(UIKit) +extension DSCustomUITextFieldCoordinator: UITextFieldDelegate { + func textFieldDidChangeSelection(_ textField: UITextField) { + parent.text = textField.text ?? "" + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + parent.onCommit?() + return true + } + + func textFieldDidBeginEditing(_ textField: UITextField) { + parent.isEditing = true + } + + func textFieldDidEndEditing(_ textField: UITextField) { + parent.isEditing = false + } +} +#elseif canImport(AppKit) +extension DSCustomUITextFieldCoordinator: NSTextFieldDelegate { + func controlTextDidChange(_ obj: Notification) { + guard let textField = obj.object as? NSTextField else { return } + parent.text = textField.stringValue + } + + func controlTextDidBeginEditing(_ obj: Notification) { + parent.isEditing = true + } + + func controlTextDidEndEditing(_ obj: Notification) { + parent.isEditing = false + parent.onCommit?() } } +#endif diff --git a/DSKit/Sources/DSKit/Helpers/KeyboardObserver.swift b/DSKit/Sources/DSKit/Helpers/KeyboardObserver.swift index 26984aa..48287ca 100644 --- a/DSKit/Sources/DSKit/Helpers/KeyboardObserver.swift +++ b/DSKit/Sources/DSKit/Helpers/KeyboardObserver.swift @@ -5,6 +5,8 @@ // Created by Ivan Borinschi on 08.02.2023. // +#if canImport(UIKit) + import SwiftUI import Combine @@ -68,3 +70,5 @@ public final class KeyboardObserver: ObservableObject { } } } + +#endif diff --git a/DSKit/Sources/DSKit/Helpers/UIColor+Conveniences.swift b/DSKit/Sources/DSKit/Helpers/UIColor+Conveniences.swift index 9b1fc00..8b64d4c 100644 --- a/DSKit/Sources/DSKit/Helpers/UIColor+Conveniences.swift +++ b/DSKit/Sources/DSKit/Helpers/UIColor+Conveniences.swift @@ -1,9 +1,11 @@ // Copyright © 2020 Flinesoft. All rights reserved. -import UIKit import SwiftUI -public extension UIColor { +// MARK: - DSUIColor Extensions +public extension DSUIColor { + + /// Initialize `DSUIColor` with RGB values convenience init(red: Int, green: Int, blue: Int) { assert(red >= 0 && red <= 255, "Invalid red component") assert(green >= 0 && green <= 255, "Invalid green component") @@ -11,13 +13,30 @@ public extension UIColor { self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) } + /// Initialize `DSUIColor` with a hex integer value convenience init(_ netHex: Int) { - self.init(red: (netHex >> 16) & 0xff, green: (netHex >> 8) & 0xff, blue: netHex & 0xff) + self.init( + red: (netHex >> 16) & 0xFF, + green: (netHex >> 8) & 0xFF, + blue: netHex & 0xFF + ) } -} - -public extension UIColor { + + /// Create a dynamic color that adapts to light and dark mode + static func dynamic(light: Int, dark: Int) -> DSUIColor { + #if canImport(UIKit) + return DSUIColor { traitCollection in + return traitCollection.userInterfaceStyle == .dark ? DSUIColor(dark) : DSUIColor(light) + } + #elseif canImport(AppKit) + return DSUIColor(name: nil, dynamicProvider: { appearance in + return appearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua ? DSUIColor(dark) : DSUIColor(light) + }) ?? DSUIColor(light) + #endif + } + + /// Convert `DSUIColor` to `SwiftUI.Color` var color: Color { - Color(uiColor: self) + Color(self) } } diff --git a/DSKit/Sources/DSKit/Modifiers/DSBackgroundModifier.swift b/DSKit/Sources/DSKit/Modifiers/DSBackgroundModifier.swift index 9619652..e556d0b 100644 --- a/DSKit/Sources/DSKit/Modifiers/DSBackgroundModifier.swift +++ b/DSKit/Sources/DSKit/Modifiers/DSBackgroundModifier.swift @@ -20,7 +20,7 @@ public struct DSBackgroundModifier: ViewModifier { } public func body(content: Content) -> some View { - content.background(Color(uiColor: group.colors(from: appearance).background)) + content.background(Color(group.colors(from: appearance).background)) .environment(\.viewStyle, viewStyle) } } diff --git a/DSKit/Sources/DSKit/Modifiers/DSBlurBackgroundModifier.swift b/DSKit/Sources/DSKit/Modifiers/DSBlurBackgroundModifier.swift index 747cff8..2a8bba1 100644 --- a/DSKit/Sources/DSKit/Modifiers/DSBlurBackgroundModifier.swift +++ b/DSKit/Sources/DSKit/Modifiers/DSBlurBackgroundModifier.swift @@ -8,35 +8,100 @@ import SwiftUI +#if canImport(UIKit) +import UIKit + +// iOS Implementation public struct BlurredBackgroundView: UIViewRepresentable { var style: UIBlurEffect.Style public func makeUIView(context: Context) -> UIVisualEffectView { - let view = UIVisualEffectView(effect: UIBlurEffect(style: style)) - return view + return UIVisualEffectView(effect: UIBlurEffect(style: style)) } public func updateUIView(_ uiView: UIVisualEffectView, context: Context) {} } +#elseif canImport(AppKit) +import AppKit + +// macOS Implementation +public struct BlurredBackgroundView: NSViewRepresentable { + var material: NSVisualEffectView.Material + + public func makeNSView(context: Context) -> NSVisualEffectView { + let view = NSVisualEffectView() + view.material = material + view.blendingMode = .behindWindow + view.state = .active + return view + } + + public func updateNSView(_ nsView: NSVisualEffectView, context: Context) {} +} +#endif + +// MARK: - Cross-Platform Modifier + public struct DSBlurBackgroundModifier: ViewModifier { - + #if canImport(UIKit) let style: UIBlurEffect.Style - + #elseif canImport(AppKit) + let material: NSVisualEffectView.Material + #endif + public func body(content: Content) -> some View { + #if canImport(UIKit) + content + .background( + BlurredBackgroundView(style: style) + .edgesIgnoringSafeArea(.all) + ) + #elseif canImport(AppKit) content - .background(BlurredBackgroundView(style: style) - .edgesIgnoringSafeArea(.all)) + .background( + BlurredBackgroundView(material: material) + .edgesIgnoringSafeArea(.all) + + ) + #endif } } public extension View { + #if canImport(UIKit) func dsBlurBackground(style: UIBlurEffect.Style = .systemThinMaterialDark) -> some View { let modifier = DSBlurBackgroundModifier(style: style) return self.modifier(modifier) } + #elseif canImport(AppKit) + func dsBlurBackground(material: NSVisualEffectView.Material = .hudWindow) -> some View { + let modifier = DSBlurBackgroundModifier(material: material) + return self.modifier(modifier) + } + #endif + + func dsBlurBackgroundLight() -> some View { + #if canImport(UIKit) + return self.dsBlurBackground(style: .light) + #else + self + #endif + } + + func dsBlurSystemThinMaterialLight() -> some View { + #if canImport(UIKit) + return self.dsBlurBackground(style: .systemThinMaterialLight) + #else + self + #endif + } + + + } + #Preview { VStack { DSVStack { diff --git a/DSKit/Sources/DSKit/Modifiers/DSHideKeyboardWhenTappedModifier.swift b/DSKit/Sources/DSKit/Modifiers/DSHideKeyboardWhenTappedModifier.swift index 4094983..e9f84c8 100644 --- a/DSKit/Sources/DSKit/Modifiers/DSHideKeyboardWhenTappedModifier.swift +++ b/DSKit/Sources/DSKit/Modifiers/DSHideKeyboardWhenTappedModifier.swift @@ -25,7 +25,9 @@ public struct DSHideKeyboardWhenTappedModifier: ViewModifier { } private func dismissKeyboard() { + #if canImport(UIKit) UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) + #endif } } diff --git a/DSKit/Sources/DSKit/Modifiers/DSKeyboardAwareModifier.swift b/DSKit/Sources/DSKit/Modifiers/DSKeyboardAwareModifier.swift index 145af01..553dfc7 100644 --- a/DSKit/Sources/DSKit/Modifiers/DSKeyboardAwareModifier.swift +++ b/DSKit/Sources/DSKit/Modifiers/DSKeyboardAwareModifier.swift @@ -7,6 +7,8 @@ import SwiftUI +#if canImport(UIKit) + public struct DSKeyboardAwareModifier: ViewModifier { @ObservedObject var keyboard = KeyboardObserver.shared @@ -24,12 +26,22 @@ public struct DSKeyboardAwareModifier: ViewModifier { } } +#endif + public extension View { func hideWhenKeyboardIsDisplayed(transition: AnyTransition = .opacity) -> some View { + #if canImport(UIKit) self.modifier(DSKeyboardAwareModifier(hide: true, transition: transition)) + #else + self + #endif } func showWhenKeyboardIsDisplayed(transition: AnyTransition = .opacity) -> some View { + #if canImport(UIKit) self.modifier(DSKeyboardAwareModifier(hide: false, transition: transition)) + #else + self + #endif } } diff --git a/DSKit/Sources/DSKit/Modifiers/DSOnTapModifier.swift b/DSKit/Sources/DSKit/Modifiers/DSOnTapModifier.swift index 6feea2a..3dbc25e 100644 --- a/DSKit/Sources/DSKit/Modifiers/DSOnTapModifier.swift +++ b/DSKit/Sources/DSKit/Modifiers/DSOnTapModifier.swift @@ -11,6 +11,7 @@ public struct DSOnTapModifier: ViewModifier { var action: () -> Void public func body(content: Content) -> some View { Button(action: action, label: { content }) + .buttonStyle(.plain) } } diff --git a/DSKit/Sources/DSKit/Views/DSButton.swift b/DSKit/Sources/DSKit/Views/DSButton.swift index 8b76e5f..a8da327 100644 --- a/DSKit/Sources/DSKit/Views/DSButton.swift +++ b/DSKit/Sources/DSKit/Views/DSButton.swift @@ -96,11 +96,11 @@ public struct DSButton: View { self.title = title if let leftImageNamed { - self.leftImage = DSImage(content: .image(image: UIImage(named: leftImageNamed)), size: .smallIcon) + self.leftImage = DSImage(content: .image(image: DSUIImage(named: leftImageNamed)), size: .smallIcon) } if let rightImageNamed { - self.rightImage = DSImage(content: .image(image: UIImage(named: rightImageNamed)), size: .smallIcon) + self.rightImage = DSImage(content: .image(image: DSUIImage(named: rightImageNamed)), size: .smallIcon) } self.pushContentToSides = pushContentToSides @@ -190,7 +190,7 @@ public struct DSButton: View { .stroke(titleColor.color(for: appearance, and: viewStyle), lineWidth: 1) ).padding(1) } - }) + }).buttonStyle(.plain) } var buttonView: some View { diff --git a/DSKit/Sources/DSKit/Views/DSCoverFlow.swift b/DSKit/Sources/DSKit/Views/DSCoverFlow.swift index f406801..c6bafa4 100644 --- a/DSKit/Sources/DSKit/Views/DSCoverFlow.swift +++ b/DSKit/Sources/DSKit/Views/DSCoverFlow.swift @@ -31,6 +31,7 @@ Initializes `DSCoverFlow` with specific layout and behavioral settings. - `content`: Closure that returns a `Content` view for each data item. */ + public struct DSCoverFlow: View where Data: RandomAccessCollection, ID: Hashable, Data.Element: Equatable, Content: View { @Environment(\.appearance) var appearance: DSAppearance @@ -85,7 +86,7 @@ public struct DSCoverFlow: View where Data: RandomAccessColle DSHStack { ForEach(data, id: id) { element in Circle() - .fill(Color(uiColor: appearance.primaryView.text.headline)) + .fill(Color(appearance.primaryView.text.headline)) .dsSize(7) .opacity(currentElementID == element ? 1 : 0.1) } @@ -93,7 +94,11 @@ public struct DSCoverFlow: View where Data: RandomAccessColle } } -fileprivate struct DSPaginatedScrollView: UIViewRepresentable where Data: RandomAccessCollection, Data.Element: Equatable, ID: Hashable, Content: View { +import SwiftUI + +import SwiftUI + +struct DSPaginatedScrollView: DSViewRepresentable where Data: RandomAccessCollection, Data.Element: Equatable, ID: Hashable, Content: View { let data: Data let content: (Data.Element) -> Content @@ -118,115 +123,100 @@ fileprivate struct DSPaginatedScrollView: UIViewRepresentable self._currentPage = currentPage } - typealias UIViewType = UIScrollView - func makeCoordinator() -> Coordinator { - Coordinator(parent: self) + return Coordinator(parent: self) } - func makeUIView(context: Context) -> UIScrollView { - let scrollView = UIScrollView() + // MARK: - Cross-Platform Implementations + #if canImport(UIKit) + func makeUIView(context: Context) -> DSUIScrollView { + let scrollView = DSUIScrollView() setupScrollView(scrollView, context: context) - addContentView(to: scrollView) + addContentView(to: scrollView, context: context) return scrollView } - - private func setupScrollView(_ scrollView: UIScrollView, context: Context) { - scrollView.isPagingEnabled = false + + func updateUIView(_ uiView: DSUIScrollView, context: Context) {} + #elseif canImport(AppKit) + func makeNSView(context: Context) -> DSUIScrollView { + let scrollView = DSUIScrollView() + setupScrollView(scrollView, context: context) + addContentView(to: scrollView, context: context) + return scrollView + } + + func updateNSView(_ nsView: DSUIScrollView, context: Context) {} + #endif + + // MARK: - Setup Methods + private func setupScrollView(_ scrollView: DSUIScrollView, context: Context) { + #if canImport(UIKit) + scrollView.isPagingEnabled = true scrollView.showsHorizontalScrollIndicator = false scrollView.showsVerticalScrollIndicator = false - scrollView.clipsToBounds = false + scrollView.backgroundColor = .clear scrollView.delegate = context.coordinator - scrollView.decelerationRate = .fast + #elseif canImport(AppKit) + scrollView.hasHorizontalScroller = true + scrollView.hasVerticalScroller = false + scrollView.drawsBackground = false scrollView.backgroundColor = .clear + #endif } - - private func addContentView(to scrollView: UIScrollView) { - let contentView = createContentView() - contentView.view.backgroundColor = .clear - contentView.view.translatesAutoresizingMaskIntoConstraints = false - scrollView.addSubview(contentView.view) + + private func addContentView(to scrollView: DSUIScrollView, context: Context) { + let hostingController = DSHostingController(rootView: createContentView()) + hostingController.view.translatesAutoresizingMaskIntoConstraints = false + #if canImport(UIKit) + scrollView.addSubview(hostingController.view) NSLayoutConstraint.activate([ - contentView.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), - contentView.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), - contentView.view.topAnchor.constraint(equalTo: scrollView.topAnchor), - contentView.view.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), - contentView.view.heightAnchor.constraint(equalTo: scrollView.heightAnchor) + hostingController.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), + hostingController.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), + hostingController.view.topAnchor.constraint(equalTo: scrollView.topAnchor), + hostingController.view.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), + hostingController.view.heightAnchor.constraint(equalTo: scrollView.heightAnchor) ]) + #elseif canImport(AppKit) + scrollView.documentView = hostingController.view + #endif } - - private func createContentView() -> UIHostingController { - let hostedContent = HStack(spacing: interItemSpacing) { + + private func createContentView() -> some View { + HStack(spacing: interItemSpacing) { ForEach(data, id: id) { element in - content(element).frame(width: pageWidth) + content(element) + .frame(width: pageWidth) } } - return UIHostingController(rootView: AnyView(hostedContent)) } - func updateUIView(_ uiView: UIScrollView, context: Context) { - // Update the view if needed - } - - class Coordinator: NSObject, UIScrollViewDelegate { + // MARK: - Coordinator + class Coordinator: NSObject, DSScrollViewDelegate { var parent: DSPaginatedScrollView init(parent: DSPaginatedScrollView) { self.parent = parent } - func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { - let maxIndex = CGFloat(parent.data.count) - let targetIndex = calculateTargetIndex(scrollView: scrollView, velocity: velocity, maxIndex: maxIndex) - let targetOffset = calculateTargetOffset(scrollView: scrollView, targetIndex: targetIndex) - targetContentOffset.pointee.x = targetOffset - setDecelerationRate(for: scrollView) - setCurrentPage(for: Int(targetIndex)) - } - - private func calculateTargetIndex(scrollView: UIScrollView, velocity: CGPoint, maxIndex: CGFloat) -> CGFloat { - let pageWidth = parent.pageWidth - let interItemSpacing = parent.interItemSpacing - let targetX = scrollView.contentOffset.x + velocity.x * 60.0 - var targetIndex: CGFloat = 0.0 - - if velocity.x > 0 { - targetIndex = ceil(targetX / (pageWidth + interItemSpacing)) - } else if velocity.x == 0 { - targetIndex = round(targetX / (pageWidth + interItemSpacing)) - } else if velocity.x < 0 { - targetIndex = floor(targetX / (pageWidth + interItemSpacing)) - } - - return min(max(targetIndex, 0), maxIndex) - } - - private func calculateTargetOffset(scrollView: UIScrollView, targetIndex: CGFloat) -> CGFloat { - let pageWidth = parent.pageWidth - let interItemSpacing = parent.interItemSpacing - return targetIndex * (pageWidth + interItemSpacing) - } - - private func setDecelerationRate(for scrollView: UIScrollView) { - scrollView.decelerationRate = .fast - } - - private func setCurrentPage(for index: Int) { - let index = parent.data.index(parent.data.startIndex, offsetBy: index) - if index >= parent.data.startIndex && index < parent.data.endIndex { - self.parent.currentPage = self.parent.data[index] + #if canImport(UIKit) + func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + let pageIndex = Int(round(scrollView.contentOffset.x / parent.pageWidth)) + if pageIndex >= 0 && pageIndex < parent.data.count { + let index = parent.data.index(parent.data.startIndex, offsetBy: pageIndex) + parent.currentPage = parent.data[index] } } + #endif } } struct Testable_DSCoverFlow: View { let colors = [ - UIColor(0x006A7A), - UIColor(0x28527a), - UIColor(0xfbeeac) + DSUIColor(0x006A7A), + DSUIColor(0x28527a), + DSUIColor(0xfbeeac) ] var body: some View { diff --git a/DSKit/Sources/DSKit/Views/DSGrid.swift b/DSKit/Sources/DSKit/Views/DSGrid.swift index 5940bca..259cec9 100644 --- a/DSKit/Sources/DSKit/Views/DSGrid.swift +++ b/DSKit/Sources/DSKit/Views/DSGrid.swift @@ -70,7 +70,8 @@ public struct DSGrid: View where Data: RandomAccessCollection } else { self.content(element) } - }.dsResetContentMargins() + } + .dsResetContentMargins() }.dsContentMargins() } } diff --git a/DSKit/Sources/DSKit/Views/DSImageView.swift b/DSKit/Sources/DSKit/Views/DSImageView.swift index 14a0e97..443d31f 100644 --- a/DSKit/Sources/DSKit/Views/DSImageView.swift +++ b/DSKit/Sources/DSKit/Views/DSImageView.swift @@ -55,7 +55,7 @@ public struct DSImageView: View { } public init( - uiImage: UIImage?, + uiImage: DSUIImage?, displayShape: DSDisplayShape = .none, size: DSSize = .fillUpTheSpace, tintColor: DSColorKey? = nil, @@ -117,7 +117,7 @@ public struct DSImageView: View { .dsSize(image.size) .setDisplayShape(shape: image.displayShape) } else if let uiImage { - Image(uiImage: uiImage) + Image(dsUIImage: uiImage) .resizable() .setImageTint(tint: image.tintColor) .setContentMode(mode: image.contentMode) @@ -136,7 +136,7 @@ public struct DSImageView: View { Color.gray.opacity(0.1) .overlay(alignment: .center) { - Image(uiImage: imageManager.image!) + Image(dsUIImage: imageManager.image!) .resizable() .setContentMode(mode: image.contentMode) .opacity(imageLoaded ? 1 : 0) @@ -177,7 +177,7 @@ public struct DSImageView: View { public enum DSImageContentType { case system(name: String) - case image(image: UIImage?) + case image(image: DSUIImage?) case imageURL(url: URL?) } @@ -227,7 +227,7 @@ public struct DSImage { contentMode: DSContentMode = .scaleAspectFit ) { self.init( - content: .image(image: UIImage(named: named)), + content: .image(image: DSUIImage(named: named)), displayShape: displayShape, size: size, tintColor: tintColor, @@ -236,7 +236,7 @@ public struct DSImage { } public init( - uiImage: UIImage?, + uiImage: DSUIImage?, displayShape: DSDisplayShape = .none, size: DSSize = .fillUpTheSpace, tintColor: DSColorKey? = nil, @@ -278,8 +278,10 @@ extension DSImage { struct Testable_DSImageView: View { - let imageUrl = URL(string: "https://images.unsplash.com/photo-1702540122576-dd7d387f652f?q=80&w=1932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D") - let testImage = UIImage( + let imageUrl = URL(string: "https://images.unsplash.com/photo-1702540122576-dd7d387f652f?q=80&w=1932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" + ) + + let testImage = DSUIImage( named: "demo", in: Bundle(identifier: "app.DSKit"), with: nil diff --git a/DSKit/Sources/DSKit/Views/DSPickerView.swift b/DSKit/Sources/DSKit/Views/DSPickerView.swift index 4c31509..5f0dde4 100644 --- a/DSKit/Sources/DSKit/Views/DSPickerView.swift +++ b/DSKit/Sources/DSKit/Views/DSPickerView.swift @@ -85,7 +85,9 @@ public struct DSPickerView: View where Data: RandomAccessColl .dsCornerRadius() .dsSelectedStyle(isSelected: selected == element) .onTap { + #if canImport(UIKit) UIImpactFeedbackGenerator(style: .light).impactOccurred() + #endif selected = element } } diff --git a/DSKit/Sources/DSKit/Views/DSQuantityPicker.swift b/DSKit/Sources/DSKit/Views/DSQuantityPicker.swift index 393161d..1051c71 100644 --- a/DSKit/Sources/DSKit/Views/DSQuantityPicker.swift +++ b/DSKit/Sources/DSKit/Views/DSQuantityPicker.swift @@ -51,7 +51,9 @@ public struct DSQuantityPicker: View { .onTap { if quantity > 1 { quantity = quantity - 1 + #if canImport(UIKit) UIImpactFeedbackGenerator(style: .light).impactOccurred() + #endif } } DSDivider() @@ -61,7 +63,9 @@ public struct DSQuantityPicker: View { .dsPadding(.horizontal, .regular) .onTap { quantity = quantity + 1 + #if canImport(UIKit) UIImpactFeedbackGenerator(style: .light).impactOccurred() + #endif } } .dsHeight(20) diff --git a/DSKit/Sources/DSKit/Views/DSRadioPickerView.swift b/DSKit/Sources/DSKit/Views/DSRadioPickerView.swift index f5f4414..8ef6439 100644 --- a/DSKit/Sources/DSKit/Views/DSRadioPickerView.swift +++ b/DSKit/Sources/DSKit/Views/DSRadioPickerView.swift @@ -62,7 +62,9 @@ public struct DSRadioPickerView: View where Data: RandomAcces } } .onTap { + #if canImport(UIKit) UIImpactFeedbackGenerator(style: .light).impactOccurred() + #endif selected = element } .dsCardStyle() diff --git a/DSKit/Sources/DSKit/Views/DSTextField.swift b/DSKit/Sources/DSKit/Views/DSTextField.swift index 55b9dd3..bd24fc4 100644 --- a/DSKit/Sources/DSKit/Views/DSTextField.swift +++ b/DSKit/Sources/DSKit/Views/DSTextField.swift @@ -6,7 +6,7 @@ // import SwiftUI -import UIKit + /* ## DSTextField @@ -23,6 +23,8 @@ Initializes a `DSTextField` with various options for handling different types of `DSTextField` is suitable for forms, login screens, and any interface where user input is required. The secure entry option and input validation make it particularly useful for handling sensitive information. */ +import SwiftUI + public struct DSTextField: View { // Environment properties for theming and color customization @@ -43,9 +45,9 @@ public struct DSTextField: View { // Boolean to determine if the text field should be secure (for passwords) let isSecureEntry: Bool // Keyboard configuration properties - let keyboardType: UIKeyboardType - let textContentType: UITextContentType? - let autocapitalizationType: UITextAutocapitalizationType + let keyboardType: DSKeyboardType + let textContentType: DSTextContentType? + let autocapitalizationType: DSAutocapitalizationType let validationPattern: String let leftSystemName: String? let validateMinimumLength: Int diff --git a/DSKitExplorer.xcodeproj/project.pbxproj b/DSKitExplorer.xcodeproj/project.pbxproj index feb1a9f..0b04620 100644 --- a/DSKitExplorer.xcodeproj/project.pbxproj +++ b/DSKitExplorer.xcodeproj/project.pbxproj @@ -17,8 +17,8 @@ 41A858222BF3420000375D4D /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = 41A858212BF3420000375D4D /* SDWebImage */; }; 41A858242BF3421200375D4D /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = 41A858232BF3421200375D4D /* SDWebImage */; }; 604EED4B2BD23BE9009E3278 /* DSKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 604EED4A2BD23BE9009E3278 /* DSKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 604EED4F2BD23BE9009E3278 /* DSKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 604EED482BD23BE9009E3278 /* DSKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 604EED602BD23D23009E3278 /* DSKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 604EED482BD23BE9009E3278 /* DSKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + 604EED4F2BD23BE9009E3278 /* DSKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 604EED482BD23BE9009E3278 /* DSKit.framework */; platformFilters = (ios, macos, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 604EED602BD23D23009E3278 /* DSKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 604EED482BD23BE9009E3278 /* DSKit.framework */; platformFilters = (ios, macos, ); settings = {ATTRIBUTES = (Required, ); }; }; 604EEDC62BD23E1B009E3278 /* DSBackgroundModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604EED632BD23E1A009E3278 /* DSBackgroundModifier.swift */; }; 604EEDC72BD23E1B009E3278 /* DSBlurBackgroundModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604EED642BD23E1A009E3278 /* DSBlurBackgroundModifier.swift */; }; 604EEDC82BD23E1B009E3278 /* DSCardStyleModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604EED652BD23E1A009E3278 /* DSCardStyleModifier.swift */; }; @@ -109,6 +109,14 @@ 608350B52BCC5892002E4F47 /* ScreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608350B42BCC5892002E4F47 /* ScreenView.swift */; }; 6092FE5C2BD2AC600016CB4A /* DSKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 604EED482BD23BE9009E3278 /* DSKit.framework */; }; 6092FE5D2BD2AC600016CB4A /* DSKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 604EED482BD23BE9009E3278 /* DSKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 60AD1FAA2CE78DE200DF81AF /* DSFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FA92CE78DE200DF81AF /* DSFont.swift */; }; + 60AD1FAC2CE78F9700DF81AF /* DSUIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FAB2CE78F9700DF81AF /* DSUIColor.swift */; }; + 60AD1FAE2CEB39CD00DF81AF /* DSUIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FAD2CEB39CD00DF81AF /* DSUIImage.swift */; }; + 60AD1FB02CEB489100DF81AF /* DSViewReprezentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FAF2CEB489100DF81AF /* DSViewReprezentable.swift */; }; + 60AD1FB22CEB491100DF81AF /* DSUIScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FB12CEB491100DF81AF /* DSUIScrollView.swift */; }; + 60AD1FB42CEB4A7900DF81AF /* DSHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FB32CEB4A7900DF81AF /* DSHostingController.swift */; }; + 60AD1FB62CEB4BF700DF81AF /* ToolbarItemPlacement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AD1FB52CEB4BF700DF81AF /* ToolbarItemPlacement.swift */; }; + 60AF8F792CEB6A5E0014E1D7 /* NavigationBarHidden.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AF8F782CEB6A5E0014E1D7 /* NavigationBarHidden.swift */; }; 60D469BB2BCAF0DC00A6F7FC /* AppearanceSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60D4697F2BCAF0D800A6F7FC /* AppearanceSelectionView.swift */; }; 60D469BC2BCAF0DC00A6F7FC /* DSKitExplorerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60D469802BCAF0D800A6F7FC /* DSKitExplorerApp.swift */; }; 60D469BD2BCAF0DC00A6F7FC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 60D469812BCAF0DA00A6F7FC /* Assets.xcassets */; }; @@ -171,6 +179,8 @@ 60D46A092BCAF16600A6F7FC /* DSKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60D46A082BCAF16600A6F7FC /* DSKitTests.swift */; }; 60D46A192BCAF25A00A6F7FC /* AssertSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60D46A182BCAF25A00A6F7FC /* AssertSnapshot.swift */; }; 60D46A1B2BCAF29600A6F7FC /* AssertSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60D46A1A2BCAF29600A6F7FC /* AssertSnapshot.swift */; }; + 60E268112CEB4CF400C3E256 /* NavigationBarTitleDisplayMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60E268102CEB4CF400C3E256 /* NavigationBarTitleDisplayMode.swift */; }; + 60E268132CEB622E00C3E256 /* DSKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60E268122CEB622E00C3E256 /* DSKeyboard.swift */; }; 901D2D482C00CA260017DC0C /* BookingScreen3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 901D2D472C00CA260017DC0C /* BookingScreen3.swift */; }; 901D2D4A2C0705640017DC0C /* BookingScreen4.swift in Sources */ = {isa = PBXBuildFile; fileRef = 901D2D492C0705640017DC0C /* BookingScreen4.swift */; }; 901D2D4C2C070B280017DC0C /* BookingScreen5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 901D2D4B2C070B280017DC0C /* BookingScreen5.swift */; }; @@ -339,6 +349,14 @@ 604EEE2C2BD256C8009E3278 /* DSKitExplorer.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = DSKitExplorer.xctestplan; sourceTree = ""; }; 608350B12BCC565F002E4F47 /* ScreenKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenKey.swift; sourceTree = ""; }; 608350B42BCC5892002E4F47 /* ScreenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenView.swift; sourceTree = ""; }; + 60AD1FA92CE78DE200DF81AF /* DSFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSFont.swift; sourceTree = ""; }; + 60AD1FAB2CE78F9700DF81AF /* DSUIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSUIColor.swift; sourceTree = ""; }; + 60AD1FAD2CEB39CD00DF81AF /* DSUIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSUIImage.swift; sourceTree = ""; }; + 60AD1FAF2CEB489100DF81AF /* DSViewReprezentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSViewReprezentable.swift; sourceTree = ""; }; + 60AD1FB12CEB491100DF81AF /* DSUIScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSUIScrollView.swift; sourceTree = ""; }; + 60AD1FB32CEB4A7900DF81AF /* DSHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSHostingController.swift; sourceTree = ""; }; + 60AD1FB52CEB4BF700DF81AF /* ToolbarItemPlacement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarItemPlacement.swift; sourceTree = ""; }; + 60AF8F782CEB6A5E0014E1D7 /* NavigationBarHidden.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarHidden.swift; sourceTree = ""; }; 60D4696E2BCAF07F00A6F7FC /* DSKitExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DSKitExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 60D4697F2BCAF0D800A6F7FC /* AppearanceSelectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearanceSelectionView.swift; sourceTree = ""; }; 60D469802BCAF0D800A6F7FC /* DSKitExplorerApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DSKitExplorerApp.swift; sourceTree = ""; }; @@ -404,6 +422,8 @@ 60D46A082BCAF16600A6F7FC /* DSKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSKitTests.swift; sourceTree = ""; }; 60D46A182BCAF25A00A6F7FC /* AssertSnapshot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssertSnapshot.swift; sourceTree = ""; }; 60D46A1A2BCAF29600A6F7FC /* AssertSnapshot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssertSnapshot.swift; sourceTree = ""; }; + 60E268102CEB4CF400C3E256 /* NavigationBarTitleDisplayMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarTitleDisplayMode.swift; sourceTree = ""; }; + 60E268122CEB622E00C3E256 /* DSKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSKeyboard.swift; sourceTree = ""; }; 901D2D472C00CA260017DC0C /* BookingScreen3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookingScreen3.swift; sourceTree = ""; }; 901D2D492C0705640017DC0C /* BookingScreen4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookingScreen4.swift; sourceTree = ""; }; 901D2D4B2C070B280017DC0C /* BookingScreen5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookingScreen5.swift; sourceTree = ""; }; @@ -532,6 +552,7 @@ isa = PBXGroup; children = ( 604EED822BD23E1A009E3278 /* DSScaledFont.swift */, + 60AD1FA92CE78DE200DF81AF /* DSFont.swift */, ); path = Fonts; sourceTree = ""; @@ -539,6 +560,7 @@ 604EED982BD23E1A009E3278 /* Designable */ = { isa = PBXGroup; children = ( + 605343722CEC883900B19AA1 /* PlatformBased */, 604EED832BD23E1A009E3278 /* Fonts */, 604EED842BD23E1A009E3278 /* DSAppearance.swift */, 604EED852BD23E1A009E3278 /* DSButtonAppearance.swift */, @@ -610,6 +632,22 @@ path = Sources/DSKit/Views; sourceTree = ""; }; + 605343722CEC883900B19AA1 /* PlatformBased */ = { + isa = PBXGroup; + children = ( + 60AD1FB52CEB4BF700DF81AF /* ToolbarItemPlacement.swift */, + 60E268102CEB4CF400C3E256 /* NavigationBarTitleDisplayMode.swift */, + 60E268122CEB622E00C3E256 /* DSKeyboard.swift */, + 60AF8F782CEB6A5E0014E1D7 /* NavigationBarHidden.swift */, + 60AD1FB32CEB4A7900DF81AF /* DSHostingController.swift */, + 60AD1FB12CEB491100DF81AF /* DSUIScrollView.swift */, + 60AD1FAF2CEB489100DF81AF /* DSViewReprezentable.swift */, + 60AD1FAB2CE78F9700DF81AF /* DSUIColor.swift */, + 60AD1FAD2CEB39CD00DF81AF /* DSUIImage.swift */, + ); + path = PlatformBased; + sourceTree = ""; + }; 60D469652BCAF07F00A6F7FC = { isa = PBXGroup; children = ( @@ -968,10 +1006,13 @@ 604EEDE72BD23E1B009E3278 /* DSDesignable.swift in Sources */, 604EEDDD2BD23E1B009E3278 /* DSTintColorModifier.swift in Sources */, 604EEDF22BD23E1B009E3278 /* DSSpacingSystem.swift in Sources */, + 60AD1FB22CEB491100DF81AF /* DSUIScrollView.swift in Sources */, 604EEE0E2BD23E1B009E3278 /* DSDesignGuideView.swift in Sources */, 604EEDD32BD23E1B009E3278 /* DSMaxWidthCenteredModifier.swift in Sources */, 604EEDDA2BD23E1B009E3278 /* DSSelectedStyleModifier.swift in Sources */, 604EEDF52BD23E1B009E3278 /* DSTextFieldAppearance.swift in Sources */, + 60AD1FB42CEB4A7900DF81AF /* DSHostingController.swift in Sources */, + 60E268112CEB4CF400C3E256 /* NavigationBarTitleDisplayMode.swift in Sources */, 604EEDFE2BD23E1B009E3278 /* BlueAppearance.swift in Sources */, 604EEE192BD23E1B009E3278 /* DSRatingView.swift in Sources */, 604EEDC72BD23E1B009E3278 /* DSBlurBackgroundModifier.swift in Sources */, @@ -979,6 +1020,7 @@ 604EEE062BD23E1B009E3278 /* DSText.swift in Sources */, 604EEDEA2BD23E1B009E3278 /* DSDynamicColor.swift in Sources */, 604EEDC62BD23E1B009E3278 /* DSBackgroundModifier.swift in Sources */, + 60AD1FB02CEB489100DF81AF /* DSViewReprezentable.swift in Sources */, 604EEE162BD23E1B009E3278 /* DSPriceView.swift in Sources */, 604EEE0F2BD23E1B009E3278 /* DSDivider.swift in Sources */, 604EEDD92BD23E1B009E3278 /* DSSectionStyleModifier.swift in Sources */, @@ -988,6 +1030,7 @@ 90FB4AD22BFCDECD008178DF /* DSVerdanaFont.swift in Sources */, 604EEDD22BD23E1B009E3278 /* DSKeyboardAwareModifier.swift in Sources */, 604EEE172BD23E1B009E3278 /* DSQuantityPicker.swift in Sources */, + 60AD1FAC2CE78F9700DF81AF /* DSUIColor.swift in Sources */, 604EEDD12BD23E1B009E3278 /* DSHideKeyboardWhenTappedModifier.swift in Sources */, 604EEDCE2BD23E1B009E3278 /* DSDebugLayoutModifier.swift in Sources */, 604EEDFF2BD23E1B009E3278 /* DSCustomUITextField.swift in Sources */, @@ -1013,9 +1056,11 @@ 604EEDDC2BD23E1B009E3278 /* DSSizeModifier.swift in Sources */, 604EEE002BD23E1B009E3278 /* DSTextField.swift in Sources */, 604EEDE32BD23E1B009E3278 /* DSScaledFont.swift in Sources */, + 60AD1FB62CEB4BF700DF81AF /* ToolbarItemPlacement.swift in Sources */, 604EEDF12BD23E1B009E3278 /* DSSpace.swift in Sources */, 604EEDFC2BD23E1B009E3278 /* PeachAppearance.swift in Sources */, 604EEE012BD23E1B009E3278 /* DSTextField+Factory.swift in Sources */, + 60AD1FAE2CEB39CD00DF81AF /* DSUIImage.swift in Sources */, 604EEDE82BD23E1B009E3278 /* DSDesignableTextFieldColor.swift in Sources */, 604EEE112BD23E1B009E3278 /* DSGroupedList.swift in Sources */, 604EEDCF2BD23E1B009E3278 /* DSDisplayShapeModifier.swift in Sources */, @@ -1024,12 +1069,15 @@ 604EEE182BD23E1B009E3278 /* DSRadioPickerView.swift in Sources */, 604EEDDE2BD23E1B009E3278 /* DSWidthModifier.swift in Sources */, 604EEDF62BD23E1B009E3278 /* DSViewAppearance.swift in Sources */, + 60AF8F792CEB6A5E0014E1D7 /* NavigationBarHidden.swift in Sources */, 604EEE1C2BD23E1B009E3278 /* DSSFSymbolButton.swift in Sources */, 90FB4AD02BFCDD20008178DF /* DSHelveticaNeueFont.swift in Sources */, 604EEE022BD23E1B009E3278 /* DSTextfieldValidator.swift in Sources */, 604EEDD62BD23E1B009E3278 /* DSPreviewForEachAppearance.swift in Sources */, 604EEDF02BD23E1B009E3278 /* DSSize.swift in Sources */, + 60E268132CEB622E00C3E256 /* DSKeyboard.swift in Sources */, 604EEE132BD23E1B009E3278 /* DSHStack.swift in Sources */, + 60AD1FAA2CE78DE200DF81AF /* DSFont.swift in Sources */, 604EEE2B2BD24797009E3278 /* DSScrollableContentMarginsModifier.swift in Sources */, 604EEDE02BD23E1B009E3278 /* KeyboardObserver.swift in Sources */, 604EEDE52BD23E1B009E3278 /* DSButtonAppearance.swift in Sources */, @@ -1161,6 +1209,10 @@ }; 604EED4D2BD23BE9009E3278 /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilters = ( + ios, + macos, + ); target = 604EED472BD23BE9009E3278 /* DSKit */; targetProxy = 604EED4C2BD23BE9009E3278 /* PBXContainerItemProxy */; }; @@ -1197,24 +1249,30 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + REGISTER_APP_GROUPS = NO; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; + SUPPORTS_MACCATALYST = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,7"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + XROS_DEPLOYMENT_TARGET = 1.3; }; name = Debug; }; @@ -1233,24 +1291,30 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + REGISTER_APP_GROUPS = NO; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; + SUPPORTS_MACCATALYST = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,7"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + XROS_DEPLOYMENT_TARGET = 1.3; }; name = Release; }; @@ -1386,6 +1450,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"DSKitExplorer/Preview Content\""; DEVELOPMENT_TEAM = 27XPF5QBGW; + ENABLE_CODE_COVERAGE = NO; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -1393,14 +1458,21 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = "-fprofile-instr-generate"; + OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKitExplorer.com; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + REGISTER_APP_GROUPS = NO; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1421,6 +1493,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"DSKitExplorer/Preview Content\""; DEVELOPMENT_TEAM = 27XPF5QBGW; + ENABLE_CODE_COVERAGE = NO; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -1428,14 +1501,21 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = "-fprofile-instr-generate"; + OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKitExplorer.com; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + REGISTER_APP_GROUPS = NO; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1450,6 +1530,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = T4R84BG8N8; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKitExplorerTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1468,6 +1549,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = T4R84BG8N8; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKitExplorerTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1486,6 +1568,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = T4R84BG8N8; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1504,6 +1587,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = T4R84BG8N8; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = dskit.app.DSKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/DSKitExplorer/AppearanceSelectionView.swift b/DSKitExplorer/AppearanceSelectionView.swift index 003d1ba..58ca35b 100644 --- a/DSKitExplorer/AppearanceSelectionView.swift +++ b/DSKitExplorer/AppearanceSelectionView.swift @@ -35,9 +35,16 @@ struct AppearanceSelectionView: View { Spacer() } + #if os(iOS) .fullScreenCover(item: $selectedAppearance) { identifiableDesignable in ScreensView(appearance: identifiableDesignable.appearance) } + #elseif os(macOS) + .sheet(item: $selectedAppearance) { identifiableDesignable in + ScreensView(appearance: identifiableDesignable.appearance) + .frame(minWidth: 800, minHeight: 600) + } + #endif PoweredByDSKitView() }.dsScreen() } @@ -66,6 +73,7 @@ fileprivate struct AppearanceView: View { .dsPadding() .dsSecondaryBackground() .dsCornerRadius() + } } diff --git a/DSKitExplorer/ScreenView.swift b/DSKitExplorer/ScreenView.swift index b463be4..fda17c6 100644 --- a/DSKitExplorer/ScreenView.swift +++ b/DSKitExplorer/ScreenView.swift @@ -18,142 +18,142 @@ struct ScreenView: View { case .foodCategoriesScreen1: FoodCategoriesScreen1() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .navigationTitle("Menu") case .foodNearbyRestaurantScreen1: FoodNearbyRestaurantScreen1() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .navigationTitle("Nearby") case .foodRestaurantScreen1: FoodRestaurantScreen1() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .navigationTitle("Restaurant") case .foodDetailsScreen1: Testable_FoodDetailsScreen1() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .foodHomeScreen1: Testable_FoodHomeScreen1() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .bookingScreen1: Testable_BookingScreen1() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .bookingScreen2: Testable_BookingScreen2() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .bookingScreen3: Testable_BookingScreen3() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .bookingScreen4: Testable_BookingScreen4() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .bookingScreen5: Testable_BookingScreen5() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .imageGalleryScreen1: ImageGalleryScreen1() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .imageGalleryScreen2: ImageGalleryScreen2() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .newsScreen1: Testable_NewsScreen1() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .newsScreen2: Testable_NewsScreen2() .environment(\.appearance, appearance) - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) case .cartScreen1: CartScreen1() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .cartScreen2: CartScreen2() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .cartScreen3: CartScreen3() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .cartScreen4: CartScreen4() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .cartScreen5: CartScreen5() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .signUpScreen1: SignUpScreen1() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() case .signUpScreen2: SignUpScreen2() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() case .signUpScreen3: SignUpScreen3() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() case .signUpScreen4: SignUpScreen4() .environment(\.appearance, appearance) - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() case .homeScreen1: Testable_HomeScreen1() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .homeScreen2: Testable_HomeScreen2() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .homeScreen3: Testable_HomeScreen3() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .homeScreen4: Testable_HomeScreen4() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .profileScreen1: ProfileScreen1() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .profileScreen2: ProfileScreen2() - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .profileScreen3: ProfileScreen3() - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .logInScreen1: LogInScreen1() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .logInScreen2: LogInScreen2() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .logInScreen3: LogInScreen3() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .logInScreen4: LogInScreen4() @@ -161,87 +161,87 @@ struct ScreenView: View { case .notificationsScreen1: NotificationsScreen1() .navigationTitle("Settings") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .aboutUsScreen1: AboutUsScreen1() .navigationTitle("About us") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .aboutUsScreen2: AboutUsScreen2() .navigationTitle("About us") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .itemDetails1: ItemDetails1() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .itemDetails2: ItemDetails2() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .itemDetails3: ItemDetails3() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .itemDetails4: ItemDetails4() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .itemDetails5: ItemDetails5() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items1: Items1() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items2: Items2() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items3: Items3() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items4: Items4() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items5: Items5() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items6: Items6() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items7: Items7() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .items8: Items8() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .categories1: Categories1() .navigationTitle("Categories") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .environment(\.appearance, appearance) case .categories2: Categories2() @@ -269,11 +269,11 @@ struct ScreenView: View { .environment(\.appearance, appearance) case .order3: Order3() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .order4: Order4() - .navigationBarHidden(true) + .plaftormBasedNavigationBarHidden(true) .environment(\.appearance, appearance) case .shipping1: Shipping1() diff --git a/DSKitExplorer/Screens/BookingScreen5.swift b/DSKitExplorer/Screens/BookingScreen5.swift index 0eca04b..8536963 100644 --- a/DSKitExplorer/Screens/BookingScreen5.swift +++ b/DSKitExplorer/Screens/BookingScreen5.swift @@ -137,7 +137,7 @@ struct Testable_BookingScreen5: View { var body: some View { NavigationView { BookingScreen5() - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() .navigationTitle("Barber Details") } } diff --git a/DSKitExplorer/Screens/CartScreen1.swift b/DSKitExplorer/Screens/CartScreen1.swift index 2fe7a66..ad41c24 100644 --- a/DSKitExplorer/Screens/CartScreen1.swift +++ b/DSKitExplorer/Screens/CartScreen1.swift @@ -31,11 +31,11 @@ struct CartScreen1: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "trash.fill") .onTap { dismiss() } } @@ -145,7 +145,7 @@ struct Testable_CartScreen1: View { NavigationView { CartScreen1() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/CartScreen2.swift b/DSKitExplorer/Screens/CartScreen2.swift index 5127de2..88e72af 100644 --- a/DSKitExplorer/Screens/CartScreen2.swift +++ b/DSKitExplorer/Screens/CartScreen2.swift @@ -31,10 +31,10 @@ struct CartScreen2: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill").onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "trash.fill").onTap { dismiss() } } } @@ -134,7 +134,7 @@ struct Testable_CartScreen2: View { NavigationView { CartScreen2() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/CartScreen3.swift b/DSKitExplorer/Screens/CartScreen3.swift index ded14e5..5840267 100644 --- a/DSKitExplorer/Screens/CartScreen3.swift +++ b/DSKitExplorer/Screens/CartScreen3.swift @@ -31,7 +31,7 @@ struct CartScreen3: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "trash.fill").onTap { dismiss() } } }.dsScreen() @@ -136,7 +136,7 @@ struct Testable_CartScreen3: View { NavigationView { CartScreen3() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/CartScreen4.swift b/DSKitExplorer/Screens/CartScreen4.swift index cfacade..916f0a4 100644 --- a/DSKitExplorer/Screens/CartScreen4.swift +++ b/DSKitExplorer/Screens/CartScreen4.swift @@ -31,7 +31,7 @@ struct CartScreen4: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "trash.fill").onTap { dismiss() } } }.dsScreen() @@ -162,7 +162,7 @@ struct Testable_CartScreen4: View { NavigationView { CartScreen4() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/CartScreen5.swift b/DSKitExplorer/Screens/CartScreen5.swift index dc24056..580b45d 100644 --- a/DSKitExplorer/Screens/CartScreen5.swift +++ b/DSKitExplorer/Screens/CartScreen5.swift @@ -35,7 +35,7 @@ struct CartScreen5: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "trash.fill").onTap { dismiss() } } }.dsScreen() @@ -215,7 +215,7 @@ struct Testable_CartScreen5: View { NavigationView { CartScreen5() .navigationTitle("My Cart") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/Categories5.swift b/DSKitExplorer/Screens/Categories5.swift index cd5f50c..66fa632 100644 --- a/DSKitExplorer/Screens/Categories5.swift +++ b/DSKitExplorer/Screens/Categories5.swift @@ -46,7 +46,7 @@ extension Categories5 { tint: .color(category.favourite ? .red : .white) ) .dsPadding(.regular) - .dsBlurBackground(style: .light) + .dsBlurBackgroundLight() .dsCornerRadius() .dsPadding(.regular) } @@ -55,7 +55,7 @@ extension Categories5 { DSText(tag) .dsTextStyle(.headline, 10, Color.white) .dsPadding(.regular) - .dsBlurBackground(style: .light) + .dsBlurBackgroundLight() .dsCornerRadius() .dsPadding(.regular) } diff --git a/DSKitExplorer/Screens/Filters1.swift b/DSKitExplorer/Screens/Filters1.swift index 250b822..abfd3a7 100644 --- a/DSKitExplorer/Screens/Filters1.swift +++ b/DSKitExplorer/Screens/Filters1.swift @@ -37,7 +37,7 @@ struct Filters1: View { ) } }.toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSButton(title: "Reset", style: .clear, action: {}) } }.dsScreen() diff --git a/DSKitExplorer/Screens/Filters2.swift b/DSKitExplorer/Screens/Filters2.swift index 358d67f..b6ecf3f 100644 --- a/DSKitExplorer/Screens/Filters2.swift +++ b/DSKitExplorer/Screens/Filters2.swift @@ -30,7 +30,7 @@ struct Filters2: View { id: \.self, selected: $viewModel.selectedColor ) { color in - Color(uiColor: color) + Color(color) .dsSize(dimension: .actionElement) }.dsSectionStyle(title: "Color") @@ -59,7 +59,7 @@ struct Filters2: View { ) } }.toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSButton(title: "Reset", style: .clear, action: {}) } }.dsScreen() @@ -95,14 +95,14 @@ final class Filters2Model: ObservableObject { @Published var selectedSize: String = "10" let sizes = ["8", "9", "10", "11", "12", "13", "14", "15", "16"] - @Published var selectedColor: UIColor = UIColor(0xF88F6F) - let colors = [UIColor(0xFFC6A3), - UIColor(0xF88F6F), - UIColor(0x5CB946), - UIColor(0x006A7A), - UIColor(0x28527a), - UIColor(0x8ac4d0), - UIColor(0xfbeeac)] + @Published var selectedColor: DSUIColor = DSUIColor(0xF88F6F) + let colors = [DSUIColor(0xFFC6A3), + DSUIColor(0xF88F6F), + DSUIColor(0x5CB946), + DSUIColor(0x006A7A), + DSUIColor(0x28527a), + DSUIColor(0x8ac4d0), + DSUIColor(0xfbeeac)] @Published var selectedSortByOption = "Chelsea Boots" diff --git a/DSKitExplorer/Screens/Filters3.swift b/DSKitExplorer/Screens/Filters3.swift index fc7b15a..bc25e14 100644 --- a/DSKitExplorer/Screens/Filters3.swift +++ b/DSKitExplorer/Screens/Filters3.swift @@ -39,7 +39,7 @@ struct Filters3: View { id: \.self, selected: $viewModel.selectedColor ) { color in - Color(uiColor: color) + Color(color) .dsSize(dimension: .actionElement) }.dsSectionStyle(title: "Color") } @@ -52,7 +52,7 @@ struct Filters3: View { ) } }.toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSButton(title: "Reset", style: .clear, action: {}) } }.dsScreen() @@ -120,14 +120,14 @@ final class Filters3Model: ObservableObject { @Published var selectedSize: String = "10" let sizes = ["8", "9", "10", "11", "12", "13", "14", "15", "16"] - @Published var selectedColor: UIColor = UIColor(0xF88F6F) - let colors = [UIColor(0xFFC6A3), - UIColor(0xF88F6F), - UIColor(0x5CB946), - UIColor(0x006A7A), - UIColor(0x28527a), - UIColor(0x8ac4d0), - UIColor(0xfbeeac)] + @Published var selectedColor: DSUIColor = DSUIColor(0xF88F6F) + let colors = [DSUIColor(0xFFC6A3), + DSUIColor(0xF88F6F), + DSUIColor(0x5CB946), + DSUIColor(0x006A7A), + DSUIColor(0x28527a), + DSUIColor(0x8ac4d0), + DSUIColor(0xfbeeac)] @Published var selectedSortByOption = "Chelsea Boots" diff --git a/DSKitExplorer/Screens/ItemDetails1.swift b/DSKitExplorer/Screens/ItemDetails1.swift index f3dd32f..176f3ba 100644 --- a/DSKitExplorer/Screens/ItemDetails1.swift +++ b/DSKitExplorer/Screens/ItemDetails1.swift @@ -49,10 +49,10 @@ struct ItemDetails1: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill").onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "heart").onTap { dismiss() } } }.dsScreen() @@ -120,7 +120,7 @@ struct Testable_ItemDetails1: View { NavigationView { ItemDetails1() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/ItemDetails2.swift b/DSKitExplorer/Screens/ItemDetails2.swift index e552ea3..b3cb399 100644 --- a/DSKitExplorer/Screens/ItemDetails2.swift +++ b/DSKitExplorer/Screens/ItemDetails2.swift @@ -64,10 +64,10 @@ struct ItemDetails2: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill").onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "heart").onTap { dismiss() } } }.dsScreen() @@ -101,7 +101,7 @@ struct Testable_ItemDetails2: View { NavigationView { ItemDetails2() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/ItemDetails3.swift b/DSKitExplorer/Screens/ItemDetails3.swift index c76b064..ff69a74 100644 --- a/DSKitExplorer/Screens/ItemDetails3.swift +++ b/DSKitExplorer/Screens/ItemDetails3.swift @@ -81,10 +81,10 @@ struct ItemDetails3: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill").onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "heart").onTap { dismiss() } } }.dsScreen() @@ -108,7 +108,9 @@ extension ItemDetails3 { .dsSecondaryBackground() .dsSelectedStyle(isSelected: viewModel.selectedSize == size) .onTap { + #if canImport(UIKit) UIImpactFeedbackGenerator(style: .light).impactOccurred() + #endif viewModel.selectedSize = size } } @@ -127,7 +129,9 @@ extension ItemDetails3 { DSImageView(named: color, size: .size(width: 70, height: 50)) .dsSelectedStyle(isSelected: viewModel.selectedColor == color) .onTap { + #if canImport(UIKit) UIImpactFeedbackGenerator(style: .light).impactOccurred() + #endif viewModel.selectedColor = color } } @@ -163,7 +167,7 @@ struct Testable_ItemDetails3: View { NavigationView { ItemDetails3() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/ItemDetails4.swift b/DSKitExplorer/Screens/ItemDetails4.swift index de17403..c83b49f 100644 --- a/DSKitExplorer/Screens/ItemDetails4.swift +++ b/DSKitExplorer/Screens/ItemDetails4.swift @@ -57,7 +57,7 @@ struct ItemDetails4: View { id: \.self, selected: $viewModel.selectedColor ) { color in - Color(uiColor: color) + Color(color) .dsSize(dimension: .actionElement) }.dsSectionStyle(title: "Color") @@ -79,10 +79,10 @@ struct ItemDetails4: View { DSTermsAndConditions(message: "By continuing you agree to our") } }.toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill").onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "heart").onTap { dismiss() } } }.dsScreen() @@ -126,17 +126,17 @@ final class ItemDetails4Model: ObservableObject { ) @Published var selectedSize: String = "10" - @Published var selectedColor: UIColor = UIColor(0xF88F6F) + @Published var selectedColor: DSUIColor = DSUIColor(0xF88F6F) let imageGallery = [p2Image, p1Image, p3Image] - let colors = [UIColor(0xFFC6A3), - UIColor(0xF88F6F), - UIColor(0x5CB946), - UIColor(0x006A7A), - UIColor(0x28527a), - UIColor(0x8ac4d0), - UIColor(0xfbeeac)] + let colors = [DSUIColor(0xFFC6A3), + DSUIColor(0xF88F6F), + DSUIColor(0x5CB946), + DSUIColor(0x006A7A), + DSUIColor(0x28527a), + DSUIColor(0x8ac4d0), + DSUIColor(0xfbeeac)] let sizes = ["8", "9", "10", "11", "12", "13", "14", "15", "16"] } @@ -148,7 +148,7 @@ struct Testable_ItemDetails4: View { NavigationView { ItemDetails4() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/ItemDetails5.swift b/DSKitExplorer/Screens/ItemDetails5.swift index e10203d..27eaede 100644 --- a/DSKitExplorer/Screens/ItemDetails5.swift +++ b/DSKitExplorer/Screens/ItemDetails5.swift @@ -68,10 +68,10 @@ struct ItemDetails5: View { } } .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up.fill").onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "heart").onTap { dismiss() } } }.dsScreen() @@ -104,7 +104,7 @@ struct Testable_ItemDetails5: View { NavigationView { ItemDetails5() .navigationTitle("Product Details") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/Items1.swift b/DSKitExplorer/Screens/Items1.swift index e56a6d3..c4e6d87 100644 --- a/DSKitExplorer/Screens/Items1.swift +++ b/DSKitExplorer/Screens/Items1.swift @@ -21,11 +21,11 @@ struct Items1: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "square.and.arrow.up") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "heart") .onTap { dismiss() } } @@ -70,7 +70,7 @@ extension Items1 { tint: .color(product.favourite ? .red : .white) ) .dsPadding(.regular) - .dsBlurBackground(style: .systemThinMaterialLight) + .dsBlurSystemThinMaterialLight() .dsCornerRadius() .dsPadding(.regular) } @@ -155,7 +155,7 @@ struct Testable_Items1: View { NavigationView { Items1() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/Items2.swift b/DSKitExplorer/Screens/Items2.swift index 36c3b75..9dd4484 100644 --- a/DSKitExplorer/Screens/Items2.swift +++ b/DSKitExplorer/Screens/Items2.swift @@ -23,11 +23,11 @@ struct Items2: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } @@ -73,7 +73,7 @@ extension Items2 { tint: .color(product.favorite ? .red : .white) ) .dsPadding(.regular) - .dsBlurBackground(style: .light) + .dsBlurBackgroundLight() .dsCornerRadius() .dsPadding(.regular) } diff --git a/DSKitExplorer/Screens/Items3.swift b/DSKitExplorer/Screens/Items3.swift index ebbde04..c4b2173 100644 --- a/DSKitExplorer/Screens/Items3.swift +++ b/DSKitExplorer/Screens/Items3.swift @@ -23,11 +23,11 @@ struct Items3: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } diff --git a/DSKitExplorer/Screens/Items4.swift b/DSKitExplorer/Screens/Items4.swift index b92690a..bc74e4c 100644 --- a/DSKitExplorer/Screens/Items4.swift +++ b/DSKitExplorer/Screens/Items4.swift @@ -31,11 +31,11 @@ struct Items4: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } @@ -153,7 +153,7 @@ struct Testable_Items4: View { NavigationView { Items4() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/Items5.swift b/DSKitExplorer/Screens/Items5.swift index f34c77c..5c838a1 100644 --- a/DSKitExplorer/Screens/Items5.swift +++ b/DSKitExplorer/Screens/Items5.swift @@ -40,11 +40,11 @@ struct Items5: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } @@ -159,7 +159,7 @@ struct Testable_Items5: View { NavigationView { Items5() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/Items6.swift b/DSKitExplorer/Screens/Items6.swift index 0335686..e494df7 100644 --- a/DSKitExplorer/Screens/Items6.swift +++ b/DSKitExplorer/Screens/Items6.swift @@ -21,11 +21,11 @@ struct Items6: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } @@ -61,7 +61,7 @@ extension Items6 { tint: .color(product.favourite ? .red : .white) ) .dsPadding(.regular) - .dsBlurBackground(style: .light) + .dsBlurBackgroundLight() .dsCornerRadius() .dsPadding(.regular) }) @@ -144,7 +144,7 @@ struct Testable_Items6: View { NavigationView { Items6() .navigationTitle("Products") - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/Items7.swift b/DSKitExplorer/Screens/Items7.swift index a1eb641..326aaea 100644 --- a/DSKitExplorer/Screens/Items7.swift +++ b/DSKitExplorer/Screens/Items7.swift @@ -23,11 +23,11 @@ struct Items7: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } @@ -74,7 +74,7 @@ extension Items7 { tint: .color(product.favorite ? .red : .white) ) .dsPadding(.regular) - .dsBlurBackground(style: .light) + .dsBlurBackgroundLight() .dsCornerRadius() .dsPadding(.regular) }) diff --git a/DSKitExplorer/Screens/Items8.swift b/DSKitExplorer/Screens/Items8.swift index f992e8f..c4ad143 100644 --- a/DSKitExplorer/Screens/Items8.swift +++ b/DSKitExplorer/Screens/Items8.swift @@ -23,11 +23,11 @@ struct Items8: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "arrow.up.arrow.down.circle.fill") .onTap { dismiss() } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "line.horizontal.3.decrease.circle.fill") .onTap { dismiss() } } diff --git a/DSKitExplorer/Screens/LogInScreen2.swift b/DSKitExplorer/Screens/LogInScreen2.swift index 2c757cd..2c9d3e4 100644 --- a/DSKitExplorer/Screens/LogInScreen2.swift +++ b/DSKitExplorer/Screens/LogInScreen2.swift @@ -37,7 +37,7 @@ struct LogInScreen2: View { title: "Login with facebook", rightImageNamed: "facebook", pushContentToSides: true, - style: .custom(color: Color(uiColor: UIColor(0x4267B2))) + style: .custom(color: Color(DSUIColor(0x4267B2))) ) { self.dismiss() } diff --git a/DSKitExplorer/Screens/LogInScreen3.swift b/DSKitExplorer/Screens/LogInScreen3.swift index 82f1fdd..e2931a6 100644 --- a/DSKitExplorer/Screens/LogInScreen3.swift +++ b/DSKitExplorer/Screens/LogInScreen3.swift @@ -44,7 +44,7 @@ struct LogInScreen3: View { title: "Facebook", rightImageNamed: "facebook", pushContentToSides: true, - style: .custom(color: Color(uiColor: UIColor(0x4267B2))) + style: .custom(color: Color(DSUIColor(0x4267B2))) ) { self.dismiss() } @@ -53,7 +53,7 @@ struct LogInScreen3: View { title: "Google", rightImageNamed: "google", pushContentToSides: true, - style: .custom(color: Color(uiColor: UIColor(0x4285F4))) + style: .custom(color: Color(DSUIColor(0x4285F4))) ) { self.dismiss() } diff --git a/DSKitExplorer/Screens/NewsScreen1.swift b/DSKitExplorer/Screens/NewsScreen1.swift index 4fd7bcd..965b0d2 100644 --- a/DSKitExplorer/Screens/NewsScreen1.swift +++ b/DSKitExplorer/Screens/NewsScreen1.swift @@ -29,7 +29,7 @@ struct NewsScreen1: View { } .dsScreen() .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { let icon = self.style == .compact ? "list.dash" : "list.bullet.below.rectangle" DSToolbarSFSymbolButton(name: icon) .onTap { diff --git a/DSKitExplorer/Screens/SignUpScreen1.swift b/DSKitExplorer/Screens/SignUpScreen1.swift index 799711a..6d1b159 100644 --- a/DSKitExplorer/Screens/SignUpScreen1.swift +++ b/DSKitExplorer/Screens/SignUpScreen1.swift @@ -21,7 +21,7 @@ struct SignUpScreen1: View { title: "Login with Facebook", rightImageNamed: "facebook", pushContentToSides: true, - style: .custom(color: Color(uiColor: UIColor(0x4267B2))) + style: .custom(color: Color(DSUIColor(0x4267B2))) ) { self.dismiss() } DSText("or sign up with Email").dsTextStyle(.smallSubheadline).frame(maxWidth: .infinity, alignment: .center) diff --git a/DSKitExplorer/Screens/SignUpScreen2.swift b/DSKitExplorer/Screens/SignUpScreen2.swift index 3fecbef..473867a 100644 --- a/DSKitExplorer/Screens/SignUpScreen2.swift +++ b/DSKitExplorer/Screens/SignUpScreen2.swift @@ -86,7 +86,7 @@ struct Testable_SignUpScreen2: View { var body: some View { NavigationView { SignUpScreen2() - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/SignUpScreen3.swift b/DSKitExplorer/Screens/SignUpScreen3.swift index 1f0b899..3d8326d 100644 --- a/DSKitExplorer/Screens/SignUpScreen3.swift +++ b/DSKitExplorer/Screens/SignUpScreen3.swift @@ -39,7 +39,7 @@ struct SignUpScreen3: View { .dsScreen() .navigationTitle("Sign Up") .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "xmark") .onTap { dismiss() } } @@ -69,7 +69,7 @@ struct Testable_SignUpScreen3: View { var body: some View { NavigationView { SignUpScreen3() - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/Screens/SignUpScreen4.swift b/DSKitExplorer/Screens/SignUpScreen4.swift index 0b1de08..09eef5d 100644 --- a/DSKitExplorer/Screens/SignUpScreen4.swift +++ b/DSKitExplorer/Screens/SignUpScreen4.swift @@ -41,7 +41,7 @@ struct SignUpScreen4: View { .dsScreen() .navigationTitle("Sign Up") .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .platformBasedTrailing) { DSToolbarSFSymbolButton(name: "xmark") .onTap { dismiss() } } @@ -69,7 +69,7 @@ struct Testable_SignUpScreen4: View { var body: some View { NavigationView { SignUpScreen4() - .navigationBarTitleDisplayMode(.inline) + .platformBasedNavigationBarTitleDisplayModeInline() } } } diff --git a/DSKitExplorer/ScreensView.swift b/DSKitExplorer/ScreensView.swift index 5ce7ca9..facefe8 100644 --- a/DSKitExplorer/ScreensView.swift +++ b/DSKitExplorer/ScreensView.swift @@ -26,7 +26,7 @@ struct ScreensView: View { ScreenView(screen: screen) } label: { CustomActionView(title: screen.displayName) - } + }.buttonStyle(.plain) } } } diff --git a/DSKitExplorerTests/AssertSnapshot.swift b/DSKitExplorerTests/AssertSnapshot.swift index 3192ed5..43dbc42 100644 --- a/DSKitExplorerTests/AssertSnapshot.swift +++ b/DSKitExplorerTests/AssertSnapshot.swift @@ -20,29 +20,20 @@ extension XCTestCase { file: StaticString = #file, line: UInt = #line ) { - SnapshotTesting.diffTool = "open" - isRecording = false - // UIView.setAnimationsEnabled(false) + // UIView.setAnimationsEnabled(false) // let view = UIHostingController(rootView: testView) // view.overrideUserInterfaceStyle = .light // guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { // fatalError("A key window is required for UI operations") // } - //window.rootViewController = view - let testView = VStack { - Spacer().frame(height: 47) - testView.frame(width: 393, height: 852) - .safeAreaInset(edge: .bottom) { - Spacer().frame(height: 34) - } - }.dsAppearance(LightBlueAppearance()) + SnapshotTesting.assertSnapshot( - of: testView, - as: .wait(for: 0.05, on: .image(drawHierarchyInKeyWindow: true)), + of: testView.frame(width: 393, height: 852).dsAppearance(LightBlueAppearance()), + as: .wait(for: 0.2, on: .image(precision: 0.96, perceptualPrecision: 0.96)), named: "snapshot", - record: record, + record: false, timeout: timeout, file: file, testName: named, diff --git a/DSKitExplorerTests/DSKitExplorer.xctestplan b/DSKitExplorerTests/DSKitExplorer.xctestplan index f03bea5..4f1aa52 100644 --- a/DSKitExplorerTests/DSKitExplorer.xctestplan +++ b/DSKitExplorerTests/DSKitExplorer.xctestplan @@ -9,6 +9,7 @@ } ], "defaultOptions" : { + "codeCoverage" : false, "commandLineArgumentEntries" : [ { "argument" : "TESTMODE" diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen1.snapshot.png index 2e0acff..40c9e88 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_0.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_0.snapshot.png index eb76ebc..840f3d0 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_0.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_0.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_1.snapshot.png index 2a26de0..ee20c56 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_2.snapshot.png index a64f230..2748308 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/AboutUsScreen2_2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen1.snapshot.png index 631f61f..15328fa 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen2.snapshot.png index 7a5f18a..4449a81 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen3.snapshot.png index 35a5d2a..224d87f 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen4.snapshot.png index 3547f5c..87ba474 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen5.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen5.snapshot.png index 44a3057..679a2db 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen5.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/CartScreen5.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories1.snapshot.png index af8e88d..7caafc9 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories2.snapshot.png index 38a0ee0..9fe8fc6 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories3.snapshot.png index d0c5663..1a57dc6 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories4.snapshot.png index 6d12d5a..545ae60 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories5.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories5.snapshot.png index 8be4476..ebdb9e8 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories5.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Categories5.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters1.snapshot.png index 99b0b66..f7d6e3f 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters2.snapshot.png index 99b0b66..f7d6e3f 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters3.snapshot.png index d23206f..549773d 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Filters3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen1.snapshot.png index 0f45aec..5bef167 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen2.snapshot.png index 0ebb4cf..84c7a6f 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen3.snapshot.png index 15a9a0f..622a4cb 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen4.snapshot.png index 5940cc1..7ecfba9 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/HomeScreen4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails1.snapshot.png index a09fade..9991488 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails2.snapshot.png index 7c3b76b..a7acd24 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails3.snapshot.png index 517b147..bccf2a6 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails4.snapshot.png index c3b5ee5..6938c8e 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails5.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails5.snapshot.png index f45ad10..ef89bc1 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails5.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ItemDetails5.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items1.snapshot.png index 7ab1f33..a5950f5 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items2.snapshot.png index 20dcaaf..e28cf94 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items3.snapshot.png index c18e6af..a051e0f 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items4.snapshot.png index 006f1ce..1896c19 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items5.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items5.snapshot.png index 1245ce9..a8ec28a 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items5.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items5.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items6.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items6.snapshot.png index 0e9d9ae..5791edd 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items6.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items6.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items7.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items7.snapshot.png index ae7cc61..71707d1 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items7.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items7.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items8.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items8.snapshot.png index ab99bc0..70c817e 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items8.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Items8.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen1.snapshot.png index d91756c..571fec0 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen2.snapshot.png index 1bfaebd..c25ee6c 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen3.snapshot.png index 2b92ef1..41b3a0f 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen4.snapshot.png index 362b82e..5567805 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/LogInScreen4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen1.snapshot.png index 8783ee2..33c0502 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen2.snapshot.png index 4e9406b..f5f645c 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NewsScreen2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NotificationsScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NotificationsScreen1.snapshot.png index b0a7082..21748c3 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NotificationsScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/NotificationsScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order1.snapshot.png index aabece8..0862600 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order2.snapshot.png index d460a1e..570bdf4 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order3.snapshot.png index 8339737..b00c0ce 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order4.snapshot.png index f8f811c..6ea5cf5 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Order4.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Payment1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Payment1.snapshot.png index c9d463d..84dc857 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Payment1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Payment1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen1.snapshot.png index 98408c7..cd736cd 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen2.snapshot.png index 67d72c3..ba71f3b 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen3.snapshot.png index 572bd34..3364469 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/ProfileScreen3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping1.snapshot.png index 0b1b450..c01ebf3 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping2.snapshot.png index 01d6e84..fc3c2fc 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/Shipping2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen1.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen1.snapshot.png index 0af7718..e449cf4 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen1.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen1.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen2.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen2.snapshot.png index e0be165..bc5b348 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen2.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen2.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen3.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen3.snapshot.png index e7d289b..4726033 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen3.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen3.snapshot.png differ diff --git a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen4.snapshot.png b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen4.snapshot.png index 2236f0d..5e57d44 100644 Binary files a/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen4.snapshot.png and b/DSKitExplorerTests/__Snapshots__/DSKitExplorerTests/SignUpScreen4.snapshot.png differ diff --git a/DSKitTests/AssertSnapshot.swift b/DSKitTests/AssertSnapshot.swift index b83d57c..885fce7 100644 --- a/DSKitTests/AssertSnapshot.swift +++ b/DSKitTests/AssertSnapshot.swift @@ -27,7 +27,7 @@ extension XCTestCase { let view: UIView = UIHostingController(rootView: testView.fixedSize(horizontal: true, vertical: true)).view SnapshotTesting.assertSnapshot( matching: view, - as: .image(size: view.intrinsicContentSize), + as: .image(precision: 0.96, size: view.intrinsicContentSize), record: record, timeout: timeout, file: file, diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 51b3c78..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,218 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - CFPropertyList (3.0.7) - base64 - nkf - rexml - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) - artifactory (3.0.17) - atomos (0.1.3) - aws-eventstream (1.3.0) - aws-partitions (1.913.0) - aws-sdk-core (3.191.6) - aws-eventstream (~> 1, >= 1.3.0) - aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.8) - jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.79.0) - aws-sdk-core (~> 3, >= 3.191.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.146.1) - aws-sdk-core (~> 3, >= 3.191.0) - aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.8) - aws-sigv4 (1.8.0) - aws-eventstream (~> 1, >= 1.0.2) - babosa (1.0.4) - base64 (0.2.0) - claide (1.1.0) - colored (1.2) - colored2 (3.1.2) - commander (4.6.0) - highline (~> 2.0.0) - declarative (0.0.20) - digest-crc (0.6.5) - rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20240107) - dotenv (2.8.1) - emoji_regex (3.2.3) - excon (0.110.0) - faraday (1.10.3) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) - ruby2_keywords (>= 0.0.4) - faraday-cookie_jar (0.0.7) - faraday (>= 0.8.0) - http-cookie (~> 1.0.0) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) - faraday-multipart (1.0.4) - multipart-post (~> 2) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - faraday_middleware (1.2.0) - faraday (~> 1.0) - fastimage (2.3.1) - fastlane (2.220.0) - CFPropertyList (>= 2.3, < 4.0.0) - addressable (>= 2.8, < 3.0.0) - artifactory (~> 3.0) - aws-sdk-s3 (~> 1.0) - babosa (>= 1.0.3, < 2.0.0) - bundler (>= 1.12.0, < 3.0.0) - colored (~> 1.2) - commander (~> 4.6) - dotenv (>= 2.1.1, < 3.0.0) - emoji_regex (>= 0.1, < 4.0) - excon (>= 0.71.0, < 1.0.0) - faraday (~> 1.0) - faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 1.0) - fastimage (>= 2.1.0, < 3.0.0) - gh_inspector (>= 1.1.2, < 2.0.0) - google-apis-androidpublisher_v3 (~> 0.3) - google-apis-playcustomapp_v1 (~> 0.1) - google-cloud-env (>= 1.6.0, < 2.0.0) - google-cloud-storage (~> 1.31) - highline (~> 2.0) - http-cookie (~> 1.0.5) - json (< 3.0.0) - jwt (>= 2.1.0, < 3) - mini_magick (>= 4.9.4, < 5.0.0) - multipart-post (>= 2.0.0, < 3.0.0) - naturally (~> 2.2) - optparse (>= 0.1.1, < 1.0.0) - plist (>= 3.1.0, < 4.0.0) - rubyzip (>= 2.0.0, < 3.0.0) - security (= 0.1.5) - simctl (~> 1.6.3) - terminal-notifier (>= 2.0.0, < 3.0.0) - terminal-table (~> 3) - tty-screen (>= 0.6.3, < 1.0.0) - tty-spinner (>= 0.8.0, < 1.0.0) - word_wrap (~> 1.0.0) - xcodeproj (>= 1.13.0, < 2.0.0) - xcpretty (~> 0.3.0) - xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.54.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.3) - addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.16.2, < 2.a) - httpclient (>= 2.8.1, < 3.a) - mini_mime (~> 1.0) - representable (~> 3.0) - retriable (>= 2.0, < 4.a) - rexml - google-apis-iamcredentials_v1 (0.17.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-playcustomapp_v1 (0.13.0) - google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.31.0) - google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.7.0) - google-cloud-env (>= 1.0, < 3.a) - google-cloud-errors (~> 1.0) - google-cloud-env (1.6.0) - faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.4.0) - google-cloud-storage (1.47.0) - addressable (~> 2.8) - digest-crc (~> 0.4) - google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.31.0) - google-cloud-core (~> 1.6) - googleauth (>= 0.16.2, < 2.a) - mini_mime (~> 1.0) - googleauth (1.8.1) - faraday (>= 0.17.3, < 3.a) - jwt (>= 1.4, < 3.0) - multi_json (~> 1.11) - os (>= 0.9, < 2.0) - signet (>= 0.16, < 2.a) - highline (2.0.3) - http-cookie (1.0.5) - domain_name (~> 0.5) - httpclient (2.8.3) - jmespath (1.6.2) - json (2.7.2) - jwt (2.8.1) - base64 - mini_magick (4.12.0) - mini_mime (1.1.5) - multi_json (1.15.0) - multipart-post (2.4.0) - nanaimo (0.3.0) - naturally (2.2.1) - nkf (0.2.0) - optparse (0.4.0) - os (1.1.4) - plist (3.7.1) - public_suffix (5.0.5) - rake (13.2.1) - representable (3.2.0) - declarative (< 0.1.0) - trailblazer-option (>= 0.1.1, < 0.2.0) - uber (< 0.2.0) - retriable (3.1.2) - rexml (3.2.6) - rouge (2.0.7) - ruby2_keywords (0.0.5) - rubyzip (2.3.2) - security (0.1.5) - signet (0.19.0) - addressable (~> 2.8) - faraday (>= 0.17.5, < 3.a) - jwt (>= 1.5, < 3.0) - multi_json (~> 1.10) - simctl (1.6.10) - CFPropertyList - naturally - terminal-notifier (2.0.0) - terminal-table (3.0.2) - unicode-display_width (>= 1.1.1, < 3) - trailblazer-option (0.1.2) - tty-cursor (0.7.1) - tty-screen (0.8.2) - tty-spinner (0.9.3) - tty-cursor (~> 0.7) - uber (0.1.0) - unicode-display_width (2.5.0) - word_wrap (1.0.0) - xcodeproj (1.24.0) - CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.3) - claide (>= 1.0.2, < 2.0) - colored2 (~> 3.1) - nanaimo (~> 0.3.0) - rexml (~> 3.2.4) - xcpretty (0.3.0) - rouge (~> 2.0.7) - xcpretty-travis-formatter (1.0.1) - xcpretty (~> 0.2, >= 0.0.7) - -PLATFORMS - ruby - x86_64-darwin-23 - -DEPENDENCIES - fastlane - -BUNDLED WITH - 2.5.4