diff --git a/Example/OpenSwiftUIUITests/Graphic/Color/NamedColorUITests.swift b/Example/OpenSwiftUIUITests/Graphic/Color/NamedColorUITests.swift index 570c1fcd0..6152779a4 100644 --- a/Example/OpenSwiftUIUITests/Graphic/Color/NamedColorUITests.swift +++ b/Example/OpenSwiftUIUITests/Graphic/Color/NamedColorUITests.swift @@ -4,22 +4,13 @@ import Testing import SnapshotTesting - -import Foundation +@testable import TestingHost @MainActor @Suite(.snapshots(record: .never, diffTool: diffTool)) struct NamedColorUITests { - @Test(.disabled { - #if os(macOS) - true - #else - false - #endif - }) + @Test func namedColor() { - openSwiftUIAssertSnapshot( - of: Color("custom") - ) + openSwiftUIAssertSnapshot(of: NamedColorExample()) } } diff --git a/Example/Shared/Assets/Assets.xcassets/custom.colorset/Contents.json b/Example/Shared/Assets/Assets.xcassets/custom.colorset/Contents.json index 6642af3cc..e3f35f076 100644 --- a/Example/Shared/Assets/Assets.xcassets/custom.colorset/Contents.json +++ b/Example/Shared/Assets/Assets.xcassets/custom.colorset/Contents.json @@ -6,11 +6,329 @@ "components" : { "alpha" : "1.000", "blue" : "0x00", - "green" : "0xFB", - "red" : "0xFE" + "green" : "0x00", + "red" : "0xFF" } }, "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0xCC", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xCC", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x88", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xCC", + "green" : "0xCC", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xCC", + "green" : "0x00", + "red" : "0xCC" + } + }, + "idiom" : "universal" + }, + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0x69", + "red" : "0xFF" + } + }, + "idiom" : "iphone" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x7F", + "green" : "0xFF", + "red" : "0x00" + } + }, + "idiom" : "iphone" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xCD", + "green" : "0x5A", + "red" : "0x6A" + } + }, + "idiom" : "iphone" + }, + { + "appearances" : [ + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0xD7", + "red" : "0xFF" + } + }, + "idiom" : "iphone" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xD0", + "green" : "0xE0", + "red" : "0x40" + } + }, + "idiom" : "iphone" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEE", + "green" : "0x82", + "red" : "0xEE" + } + }, + "idiom" : "iphone" + }, + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x6B", + "green" : "0x6B", + "red" : "0xFF" + } + }, + "idiom" : "mac" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0xCC", + "red" : "0x88" + } + }, + "idiom" : "mac" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x88", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "mac" + }, + { + "appearances" : [ + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0xAA", + "red" : "0xFF" + } + }, + "idiom" : "mac" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x88", + "green" : "0x88", + "red" : "0x00" + } + }, + "idiom" : "mac" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xCC", + "green" : "0x00", + "red" : "0x88" + } + }, + "idiom" : "mac" } ], "info" : { diff --git a/Example/Shared/ContentView.swift b/Example/Shared/ContentView.swift index f4b0b302b..48e536a5d 100644 --- a/Example/Shared/ContentView.swift +++ b/Example/Shared/ContentView.swift @@ -10,6 +10,6 @@ import SwiftUI struct ContentView: View { var body: some View { - SunsetSceneExample() + NamedColorExample() } } diff --git a/Example/Shared/Graphics/Color/NamedColorExample.swift b/Example/Shared/Graphics/Color/NamedColorExample.swift new file mode 100644 index 000000000..36935edbf --- /dev/null +++ b/Example/Shared/Graphics/Color/NamedColorExample.swift @@ -0,0 +1,29 @@ +// +// NamedColorExample.swift +// Shared + +#if OPENSWIFTUI +import OpenSwiftUI +#else +import SwiftUI +#endif + +struct NamedColorExample: View { + let name = "custom" + var body: some View { + VStack(spacing: 0) { + Color(name) + .environment(\.colorScheme, .light) + .environment(\._colorSchemeContrast, .standard) + Color(name) + .environment(\.colorScheme, .dark) + .environment(\._colorSchemeContrast, .standard) + Color(name) + .environment(\.colorScheme, .light) + .environment(\._colorSchemeContrast, .increased) + Color(name) + .environment(\.colorScheme, .dark) + .environment(\._colorSchemeContrast, .increased) + } + } +} diff --git a/Package.resolved b/Package.resolved index b37377f1e..801914170 100644 --- a/Package.resolved +++ b/Package.resolved @@ -7,7 +7,7 @@ "location" : "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git", "state" : { "branch" : "main", - "revision" : "bf9efed2c19a4dc296830000e707dbc7688a63fe" + "revision" : "ac15cc1820ea01111fc8aec31bf8d4900ea7498a" } }, { diff --git a/Sources/OpenSwiftUICore/Graphic/CatalogLookup.swift b/Sources/OpenSwiftUICore/Graphic/CatalogLookup.swift index 49a740ac7..1b0027a70 100644 --- a/Sources/OpenSwiftUICore/Graphic/CatalogLookup.swift +++ b/Sources/OpenSwiftUICore/Graphic/CatalogLookup.swift @@ -2,10 +2,11 @@ // CatalogLookup.swift // OpenSwiftUICore // +// Audited for 6.5.4 // Status: Complete // ID: 7D88FB88100BA54A0D48F777CDF70C18 (SwiftUICore) -// MARK: - CatalogKey [6.4.41] +// MARK: - CatalogKey package struct CatalogKey: Hashable { package var colorScheme: ColorScheme @@ -43,7 +44,7 @@ extension CatalogKey: ProtobufMessage { } } -// MARK: - CatalogAssetMatchType [6.4.41] +// MARK: - CatalogAssetMatchType package enum CatalogAssetMatchType: Equatable { case always @@ -51,14 +52,15 @@ package enum CatalogAssetMatchType: Equatable { case cuiIdiom(Int) package static func defaultValue(idiom: Int) -> [CatalogAssetMatchType] { - guard idiom == 8 else { - return [.appearance] + if idiom == 8 { /* CUIDeviceIdiomVision */ + [.cuiIdiom(idiom), .appearance] + } else { + [.appearance] } - return [.cuiIdiom(idiom), .appearance] } } -// MARK: - EnvironmentValues + CoreUI [6.4.41] +// MARK: - EnvironmentValues + CoreUI extension EnvironmentValues { private struct CUIAsssetIdiomKey: EnvironmentKey { diff --git a/Sources/OpenSwiftUICore/Graphic/Color/NamedColor.swift b/Sources/OpenSwiftUICore/Graphic/Color/NamedColor.swift index 44dd4d27f..caa3da4f4 100644 --- a/Sources/OpenSwiftUICore/Graphic/Color/NamedColor.swift +++ b/Sources/OpenSwiftUICore/Graphic/Color/NamedColor.swift @@ -2,6 +2,7 @@ // NamedColor.swift // OpenSwiftUICore // +// Audited for 6.5.4 // Status: Complete // ID: F70ADAD69423F89598F901BDE477D497 (SwiftUICore) @@ -89,16 +90,25 @@ extension Color { guard let catalog = CUICatalog.defaultUICatalog(for: bundle) else { return nil } + let idiom: Int + let matchTypes: [CatalogAssetMatchType] + if isUIKitBased() { + idiom = environment.cuiAssetIdiom + matchTypes = environment.cuiAssetMatchTypes + } else { + idiom = 0 + matchTypes = [.appearance] + } let gamut = key.displayGamut.cuiDisplayGamut - let idiom = CUIDeviceIdiom(rawValue: environment.cuiAssetIdiom)! + let deviceIdiom = CUIDeviceIdiom(rawValue: idiom)! let color = catalog.findAsset( key: key.catalogKey, - matchTypes: environment.cuiAssetMatchTypes, + matchTypes: matchTypes, ) { appearanceName -> CUINamedColor? in let color = catalog.color( withName: name, displayGamut: gamut, - deviceIdiom: idiom, + deviceIdiom: deviceIdiom, appearanceName: appearanceName ) return color @@ -152,7 +162,7 @@ extension CUICatalog { let colorScheme = key.colorScheme let contrast = key.contrast for matchType in matchTypes { - let isVision = matchType == .cuiIdiom(8) + let isVision = isUIKitBased() && matchType == .cuiIdiom(8) let appearanceConfigurations: [(ColorScheme?, ColorSchemeContrast)] switch (contrast, isVision) { case (.standard, false): @@ -165,14 +175,26 @@ extension CUICatalog { appearanceConfigurations = [(nil, .increased), (nil, .standard)] } for (scheme, contrast) in appearanceConfigurations { - // FIXME: macOS should use NSAppearanceNameSystem and other stuff - let appearanceName = switch (scheme, contrast) { - case (nil, .standard): "UIAppearanceAny" - case (nil, .increased): "UIAppearanceHighContrastAny" - case (.light, .standard): "UIAppearanceLight" - case (.light, .increased): "UIAppearanceHighContrastLight" - case (.dark, .standard): "UIAppearanceDark" - case (.dark, .increased): "UIAppearanceHighContrastDark" + let useNSAppearance = appearanceNames().contains { $0.hasPrefix("NSAppearance") } + let appearanceName: String + if useNSAppearance { + appearanceName = switch (scheme, contrast) { + case (nil, .standard): "NSAppearanceNameSystem" + case (nil, .increased): "NSAppearanceNameAccessibilitySystem" + case (.light, .standard): "NSAppearanceNameAqua" + case (.light, .increased): "NSAppearanceNameAccessibilityAqua" + case (.dark, .standard): "NSAppearanceNameDarkAqua" + case (.dark, .increased): "NSAppearanceNameAccessibilityDarkAqua" + } + } else { + appearanceName = switch (scheme, contrast) { + case (nil, .standard): "UIAppearanceAny" + case (nil, .increased): "UIAppearanceHighContrastAny" + case (.light, .standard): "UIAppearanceLight" + case (.light, .increased): "UIAppearanceHighContrastLight" + case (.dark, .standard): "UIAppearanceDark" + case (.dark, .increased): "UIAppearanceHighContrastDark" + } } guard let asset = assetLookup(appearanceName) else { continue @@ -196,7 +218,7 @@ extension CUICatalog { } } -// MARK: - Color.Resolved + name [6.5.4] +// MARK: - Color.Resolved + name extension Color.Resolved { package static func named( @@ -217,7 +239,7 @@ extension Color.Resolved { } } -// MARK: - SystemColorType + name [6.5.4] +// MARK: - SystemColorType + name extension SystemColorType { package static let namedTypes: [String: SystemColorType] = [