├── .gitignore ├── Tests ├── LinuxMain.swift └── SystemColorsTests │ ├── SystemColorsTests.swift │ └── XCTestManifests.swift ├── Package.swift ├── .github └── workflows │ └── tests.yml ├── LICENSE ├── README.md └── Sources └── SystemColors └── SystemColors.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | .swiftpm/ -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import swiftui_system_colorsTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += SystemColors.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Tests/SystemColorsTests/SystemColorsTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import SystemColors 3 | 4 | final class SystemColorsTests: XCTestCase { 5 | static var allTests: [(String, () -> ())] = [ 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Tests/SystemColorsTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(SystemColors.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "SystemColors", 8 | platforms: [ 9 | .iOS(.v9), 10 | .watchOS(.v6), 11 | .tvOS(.v13), 12 | .macOS(.v10_10) 13 | ], 14 | products: [ 15 | .library( 16 | name: "SystemColors", 17 | targets: ["SystemColors"]), 18 | ], 19 | targets: [ 20 | .target( 21 | name: "SystemColors", 22 | dependencies: []), 23 | .testTarget( 24 | name: "SystemColorsTests", 25 | dependencies: ["SystemColors"]), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Build & Test 2 | 3 | on: 4 | push: 5 | branches: [ void ] 6 | pull_request: 7 | branches: [ void ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Build for macOS 17 | run: swift build -v 18 | - name: Run tests for macOS 19 | run: swift test -v 20 | - name: Build for iOS 21 | run: xcodebuild -destination 'platform=iOS Simulator,name=iPhone 8' -scheme SystemColors 22 | - name: Run tests for iOS 23 | run: xcodebuild test -destination 'name=iPhone 8' -scheme SystemColors 24 | - name: Build for tvOS 25 | run: xcodebuild build -destination 'platform=tvOS Simulator,name=Apple TV' -scheme SystemColors 26 | - name: Run tests for tvOS 27 | run: xcodebuild test -destination 'name=Apple TV' -scheme SystemColors 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Denis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftUI System Colors 2 | 3 | ![Swift 5.3](https://img.shields.io/badge/Swift-5.3-FA5B2C) ![Xcode 12](https://img.shields.io/badge/Xcode-12-44B3F6) ![iOS 8.0](https://img.shields.io/badge/iOS-8.0-178DF6) ![iPadOS 8.0](https://img.shields.io/badge/iPadOS-8.0-178DF6) ![MacOS 10.10](https://img.shields.io/badge/MacOS-10.10-178DF6) ![Tests](https://github.com/diniska/swiftui-system-colors/workflows/Build%20&%20Test/badge.svg) 4 | 5 | Use standard **system colors** from **SwiftUI** on iOS, macOS or tvOS. 6 | 7 | Currently, SwiftUI doesn't provide access to standard system colors, so you can find some sort of color conversion (`Color(UIColor.label)`) in almost any SwiftUI project. This library focusing on bringing all the system colors to SwiftUI so you no longer need to write the conversion manually every time. 8 | 9 | Benefits of using `SystemColors` package dependency in your project compared to custom implementation or copy-pasting: 10 | 11 | * Receive **updates** soon after a system new color is introduced, 12 | * Standardised **naming** for iOS and macOS so that it is always `Color.label` instead of iOS's `UIColor.label` and macOS's `NSColor.labelColor` 13 | * All the **compatibility** checks like `@available(iOS 13.0, *)` or `#if canImport(UIKit)` are implemented by the package and maintained by the community - less chance to introduce an error in one of the platforms support. 14 | 15 | 16 | ## How to use 17 | 18 | ### Step 1 19 | 20 | Add a dependency using Swift Package Manager to your project: [https://github.com/diniska/swiftui-system-colors](https://github.com/diniska/swiftui-system-colors) 21 | 22 | ### Step 2 23 | 24 | Import the dependency 25 | 26 | ```swift 27 | import SystemColors 28 | ``` 29 | 30 | ### Step 3 31 | 32 | Use system colors from SwiftUI the same way you do with `UIColor` or `NSColor`: 33 | 34 | ```swift 35 | Rectangle() 36 | .background(Color.label) 37 | ``` 38 | 39 | 40 | ## Contribution 41 | 42 | Please, open a pull request or an issue if you find that one or the other color is missing or represented in a wrong way. 43 | 44 | Please, only add system colors to this package. We only provide convenient interfaces without making a decision about how some colors should look. 45 | For example, if there is no color `systemFill` provided by macOS - we don't provide it on macOS either, but for iOS, it exists and we provide that color on iOS. 46 | 47 | If you have ideas of how to better test the provided bridging code - please add an issue with the description of your idea or add a pull request with the implementation. 48 | 49 | Please, keep the similar code style if you propose a change to the package. Current code style has the next benefits: 50 | 51 | * Easy to edit with multiple cursors 52 | * Easy to add new colors with documentation by copying the documentation from Xcode and using multiple cursors 53 | * Providing relevant links to the parts of the standard documentation. 54 | -------------------------------------------------------------------------------- /Sources/SystemColors/SystemColors.swift: -------------------------------------------------------------------------------- 1 | #if canImport(SwiftUI) && canImport(Combine) && (arch(arm64) || arch(x86_64)) 2 | // https://stackoverflow.com/a/61954608 3 | import SwiftUI 4 | 5 | #if canImport(UIKit) 6 | import UIKit 7 | private typealias PlatformColor = UIColor 8 | #elseif canImport(AppKit) 9 | import AppKit 10 | private typealias PlatformColor = NSColor 11 | #endif 12 | 13 | #if !os(watchOS) // All the methods below are not availalbe for WatchOS at the time of writing 14 | 15 | // MARK: - Adaptable colors 16 | // Links to standard colors documentation 17 | // Platform | Reference 18 | // ---------|----------- 19 | // iOS | https://developer.apple.com/documentation/uikit/uicolor/standard_colors 20 | // OSX | https://developer.apple.com/documentation/appkit/nscolor/standard_colors 21 | @available(iOS 13.0, macOS 10.15, *) 22 | public extension Color { 23 | /// A blue color that automatically adapts to the current trait environment. 24 | static var systemBlue: Color { Color(PlatformColor.systemBlue) } 25 | /// A brown color that automatically adapts to the current trait environment. 26 | static var systemBrown: Color { Color(PlatformColor.systemBrown) } 27 | /// A cyan color that automatically adapts to the current trait environment. 28 | @available(iOS 15.0, macOS 12.0, tvOS 15.0, *) 29 | static var systemCyan: Color { Color(PlatformColor.systemCyan) } 30 | /// A green color that automatically adapts to the current trait environment. 31 | static var systemGreen: Color { Color(PlatformColor.systemGreen) } 32 | /// An indigo color that automatically adapts to the current trait environment. 33 | static var systemIndigo: Color { Color(PlatformColor.systemIndigo) } 34 | /// A mint color that automatically adapts to the current trait environment. 35 | @available(iOS 15.0, macOS 10.15, tvOS 15.0, *) 36 | static var systemMint: Color { Color(PlatformColor.systemMint) } 37 | /// An orange color that automatically adapts to the current trait environment. 38 | static var systemOrange: Color { Color(PlatformColor.systemOrange) } 39 | /// A pink color that automatically adapts to the current trait environment. 40 | static var systemPink: Color { Color(PlatformColor.systemPink) } 41 | /// A purple color that automatically adapts to the current trait environment. 42 | static var systemPurple: Color { Color(PlatformColor.systemPurple) } 43 | /// A red color that automatically adapts to the current trait environment. 44 | static var systemRed: Color { Color(PlatformColor.systemRed) } 45 | /// A teal color that automatically adapts to the current trait environment. 46 | static var systemTeal: Color { Color(PlatformColor.systemTeal) } 47 | /// A yellow color that automatically adapts to the current trait environment. 48 | static var systemYellow: Color { Color(PlatformColor.systemYellow) } 49 | } 50 | 51 | // MARK: - Adaptable Gray Colors 52 | // Links to standard colors documentation 53 | // Platform | Reference 54 | // ---------|----------- 55 | // iOS | https://developer.apple.com/documentation/uikit/uicolor/standard_colors 56 | // OSX | https://developer.apple.com/documentation/appkit/nscolor/standard_colors 57 | 58 | @available(iOS 13.0, OSX 10.15, *) 59 | public extension Color { 60 | /// The standard base gray color that adapts to the environment. 61 | static var systemGray: Color { Color(PlatformColor.systemGray) } 62 | } 63 | 64 | #if canImport(UIKit) && !os(tvOS) 65 | @available(iOS 13.0, *) 66 | public extension Color { 67 | /// A second-level shade of gray that adapts to the environment. 68 | static var systemGray2: Color { Color(PlatformColor.systemGray2) } 69 | /// A third-level shade of gray that adapts to the environment. 70 | static var systemGray3: Color { Color(PlatformColor.systemGray3) } 71 | /// A fourth-level shade of gray that adapts to the environment. 72 | static var systemGray4: Color { Color(PlatformColor.systemGray4) } 73 | /// A fifth-level shade of gray that adapts to the environment. 74 | static var systemGray5: Color { Color(PlatformColor.systemGray5) } 75 | /// A sixth-level shade of gray that adapts to the environment. 76 | static var systemGray6: Color { Color(PlatformColor.systemGray6) } 77 | } 78 | #endif 79 | 80 | // MARK: - Fixed Colors 81 | // Links to standard colors documentation 82 | // Platform | Reference 83 | // ---------|----------- 84 | // iOS | https://developer.apple.com/documentation/uikit/uicolor/standard_colors 85 | // OSX | https://developer.apple.com/documentation/appkit/nscolor/standard_colors 86 | 87 | @available(iOS 13.0, OSX 10.15, *) 88 | public extension Color { 89 | /// A color object with a grayscale value of 1/3 and an alpha value of 1.0. 90 | static var darkGray: Color { Color(PlatformColor.darkGray) } 91 | /// A color object with a grayscale value of 2/3 and an alpha value of 1.0. 92 | static var lightGray: Color { Color(PlatformColor.lightGray) } 93 | /// A color object with RGB values of 1.0, 0.0, and 1.0, and an alpha value of 1.0. 94 | static var magenta: Color { Color(PlatformColor.magenta) } 95 | } 96 | 97 | // MARK: - UI Element Colors 98 | // Links to standard colors documentation 99 | // Platform | Reference 100 | // ---------|----------- 101 | // iOS | https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors 102 | // OSX | https://developer.apple.com/documentation/appkit/nscolor/ui_element_colors 103 | 104 | #if canImport(UIKit) 105 | @available(iOS 13.0, *) 106 | public extension Color { 107 | // MARK: Label Colors 108 | /// The color for text labels that contain primary content. 109 | static var label: Color { Color(PlatformColor.label) } 110 | /// The color for text labels that contain secondary content. 111 | static var secondaryLabel: Color { Color(PlatformColor.secondaryLabel) } 112 | /// The color for text labels that contain tertiary content. 113 | static var tertiaryLabel: Color { Color(PlatformColor.tertiaryLabel) } 114 | /// The color for text labels that contain quaternary content. 115 | static var quaternaryLabel: Color { Color(PlatformColor.quaternaryLabel) } 116 | 117 | // MARK: Fill Colors 118 | /// An overlay fill color for thin and small shapes. 119 | @available(tvOS, unavailable) 120 | static var systemFill: Color { Color(PlatformColor.systemFill) } 121 | /// An overlay fill color for medium-size shapes. 122 | @available(tvOS, unavailable) 123 | static var secondarySystemFill: Color { Color(PlatformColor.secondarySystemFill) } 124 | /// An overlay fill color for large shapes. 125 | @available(tvOS, unavailable) 126 | static var tertiarySystemFill: Color { Color(PlatformColor.tertiarySystemFill) } 127 | /// An overlay fill color for large areas that contain complex content. 128 | @available(tvOS, unavailable) 129 | static var quaternarySystemFill: Color { Color(PlatformColor.quaternarySystemFill) } 130 | 131 | // MARK: Text Colors 132 | /// The color for placeholder text in controls or text views. 133 | static var placeholderText: Color { Color(PlatformColor.placeholderText) } 134 | 135 | // MARK: Standard Content Background Colors 136 | /// Use these colors for standard table views and designs that have a white primary background in a light environment. 137 | 138 | /// The color for the main background of your interface. 139 | @available(tvOS, unavailable) 140 | static var systemBackground: Color { Color(PlatformColor.systemBackground) } 141 | /// The color for content layered on top of the main background. 142 | @available(tvOS, unavailable) 143 | static var secondarySystemBackground: Color { Color(PlatformColor.secondarySystemBackground) } 144 | /// The color for content layered on top of secondary backgrounds. 145 | @available(tvOS, unavailable) 146 | static var tertiarySystemBackground: Color { Color(PlatformColor.tertiarySystemBackground) } 147 | 148 | // MARK: Grouped Content Background Colors 149 | /// Use these colors for grouped content, including table views and platter-based designs. 150 | 151 | /// The color for the main background of your grouped interface. 152 | @available(tvOS, unavailable) 153 | static var systemGroupedBackground: Color { Color(PlatformColor.systemGroupedBackground) } 154 | /// The color for content layered on top of the main background of your grouped interface. 155 | @available(tvOS, unavailable) 156 | static var secondarySystemGroupedBackground: Color { Color(PlatformColor.secondarySystemGroupedBackground) } 157 | /// The color for content layered on top of secondary backgrounds of your grouped interface. 158 | @available(tvOS, unavailable) 159 | static var tertiarySystemGroupedBackground: Color { Color(PlatformColor.tertiarySystemGroupedBackground) } 160 | 161 | // MARK: Separator Colors 162 | /// The color for thin borders or divider lines that allows some underlying content to be visible. 163 | static var separator: Color { Color(PlatformColor.separator) } 164 | /// The color for borders or divider lines that hides any underlying content. 165 | static var opaqueSeparator: Color { Color(PlatformColor.opaqueSeparator) } 166 | 167 | // MARK: Link Color 168 | /// The specified color for links. 169 | static var link: Color { Color(PlatformColor.link) } 170 | 171 | // MARK: Nonadaptable Colors 172 | /// The nonadaptable system color for text on a light background. 173 | @available(tvOS, unavailable) 174 | static var darkText: Color { Color(PlatformColor.darkText) } 175 | /// The nonadaptable system color for text on a dark background. 176 | @available(tvOS, unavailable) 177 | static var lightText: Color { Color(PlatformColor.lightText) } 178 | } 179 | #elseif canImport(AppKit) 180 | 181 | @available(OSX 10.15, *) 182 | public extension Color { 183 | // MARK: Label Colors 184 | /// The primary color to use for text labels. 185 | static var label: Color { Color(PlatformColor.labelColor) } 186 | /// The secondary color to use for text labels. 187 | static var secondaryLabel: Color { Color(PlatformColor.secondaryLabelColor) } 188 | /// The tertiary color to use for text labels. 189 | static var tertiaryLabel: Color { Color(PlatformColor.tertiaryLabelColor) } 190 | /// The quaternary color to use for text labels and separators. 191 | static var quaternaryLabel: Color { Color(PlatformColor.quaternaryLabelColor) } 192 | 193 | // MARK: Text Colors 194 | /// The color to use for text. 195 | static var text: Color { Color(PlatformColor.textColor) } 196 | /// The color to use for placeholder text in controls or text views. 197 | static var placeholderText: Color { Color(PlatformColor.placeholderTextColor) } 198 | /// The color to use for selected text. 199 | static var selectedText: Color { Color(PlatformColor.selectedTextColor) } 200 | /// The color to use for the background area behind text. 201 | static var textBackground: Color { Color(PlatformColor.textBackgroundColor) } 202 | /// The color to use for the background of selected text. 203 | static var selectedTextBackground: Color { Color(PlatformColor.selectedTextBackgroundColor) } 204 | /// The color to use for the keyboard focus ring around controls. 205 | static var keyboardFocusIndicator: Color { Color(PlatformColor.keyboardFocusIndicatorColor) } 206 | /// The color to use for selected text in an unemphasized context. 207 | static var unemphasizedSelectedText: Color { Color(PlatformColor.unemphasizedSelectedTextColor) } 208 | /// The color to use for the text background in an unemphasized context. 209 | static var unemphasizedSelectedTextBackground: Color { Color(PlatformColor.unemphasizedSelectedTextBackgroundColor) } 210 | 211 | // MARK: Content Colors 212 | /// The color to use for links. 213 | static var link: Color { Color(PlatformColor.linkColor) } 214 | /// The color to use for separators between different sections of content. 215 | static var separator: Color { Color(PlatformColor.separatorColor) } 216 | /// The color to use for the background of selected and emphasized content. 217 | static var selectedContentBackground: Color { Color(PlatformColor.selectedContentBackgroundColor) } 218 | /// The color to use for selected and unemphasized content. 219 | static var unemphasizedSelectedContentBackground: Color { Color(PlatformColor.unemphasizedSelectedContentBackgroundColor) } 220 | 221 | // MARK: Menu Colors 222 | /// The color to use for the text in menu items. 223 | static var selectedMenuItemText: Color { Color(PlatformColor.selectedMenuItemTextColor) } 224 | 225 | // MARK: Table Colors 226 | /// The color to use for the optional gridlines, such as those in a table view. 227 | static var grid: Color { Color(PlatformColor.gridColor) } 228 | /// The color to use for text in header cells in table views and outline views. 229 | static var headerText: Color { Color(PlatformColor.headerTextColor) } 230 | /// The colors to use for alternating content, typically found in table views and collection views. 231 | static var alternatingContentBackgroundColors: [Color] { PlatformColor.alternatingContentBackgroundColors.map(Color.init) } 232 | 233 | // MARK: Control Colors 234 | /// The user's current accent color preference. 235 | static var controlAccent: Color { Color(PlatformColor.controlAccentColor) } 236 | /// The color to use for the flat surfaces of a control. 237 | static var control: Color { Color(PlatformColor.controlColor) } 238 | /// The color to use for the background of large controls, such as scroll views or table views. 239 | static var controlBackground: Color { Color(PlatformColor.controlBackgroundColor) } 240 | /// The color to use for text on enabled controls. 241 | static var controlText: Color { Color(PlatformColor.controlTextColor) } 242 | /// The color to use for text on disabled controls. 243 | static var disabledControlText: Color { Color(PlatformColor.disabledControlTextColor) } 244 | /// The color to use for the face of a selected control—that is, a control that has been clicked or is being dragged. 245 | static var selectedControl: Color { Color(PlatformColor.selectedControlColor) } 246 | /// The color to use for text in a selected control—that is, a control being clicked or dragged. 247 | static var selectedControlText: Color { Color(PlatformColor.selectedControlTextColor) } 248 | /// The color to use for text in a selected control. 249 | static var alternateSelectedControlText: Color { Color(PlatformColor.alternateSelectedControlTextColor) } 250 | /// The patterned color to use for the background of a scrubber control. 251 | static var scrubberTexturedBackground: Color { Color(PlatformColor.scrubberTexturedBackground) } 252 | 253 | // MARK: Window Colors 254 | /// The color to use for the window background. 255 | static var windowBackground: Color { Color(PlatformColor.windowBackgroundColor) } 256 | /// The color to use for text in a window's frame. 257 | static var windowFrameText: Color { Color(PlatformColor.windowFrameTextColor) } 258 | /// The color to use in the area beneath your window's views. 259 | static var underPageBackground: Color { Color(PlatformColor.underPageBackgroundColor) } 260 | 261 | // MARK: Highlights and Shadows 262 | /// The highlight color to use for the bubble that shows inline search result values. 263 | static var findHighlight: Color { Color(PlatformColor.findHighlightColor) } 264 | /// The color to use as a virtual light source on the screen. 265 | static var highlight: Color { Color(PlatformColor.highlightColor) } 266 | /// The color to use for virtual shadows cast by raised objects on the screen. 267 | static var shadow: Color { Color(PlatformColor.shadowColor) } 268 | } 269 | 270 | #endif // UIKit / AppKit condition 271 | 272 | #endif // WatchOS condition 273 | 274 | #endif // SwiftUI availability condition 275 | --------------------------------------------------------------------------------