Skip to content

Commit 4b8444b

Browse files
committed
Initial commit
0 parents  commit 4b8444b

File tree

11 files changed

+1121
-0
lines changed

11 files changed

+1121
-0
lines changed

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# EditorConfig is awesome: https://editorconfig.org
2+
3+
root = true
4+
5+
[*]
6+
charset = utf-8
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.swift]
12+
indent_style = tab
13+
14+
[*.md]
15+
indent_style = space
16+
indent_size = 4

.github/workflows/ci.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- "**"
10+
schedule:
11+
- cron: "3 3 * * 2" # 3:03 AM, every Tuesday
12+
13+
concurrency:
14+
group: ci-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
Lint:
19+
runs-on: macos-latest
20+
steps:
21+
- name: Git Checkout
22+
uses: actions/checkout@v5
23+
24+
- name: Install SwiftFormat
25+
uses: pkgxdev/setup@v4
26+
with:
27+
+: swiftformat@latest
28+
29+
- name: SwiftFormat Lint
30+
run: swiftformat --lint . --reporter github-actions-log
31+
macOS:
32+
if: github.event_name != 'pull_request' || !contains(github.event.pull_request.title, '[skip ci]')
33+
name: ${{ matrix.platform }} (Swift ${{ matrix.swift }})
34+
runs-on: macos-15
35+
strategy:
36+
fail-fast: false
37+
matrix:
38+
platform:
39+
- macOS
40+
swift:
41+
- "6.0"
42+
- "6.1"
43+
- "6.2"
44+
steps:
45+
- name: Git Checkout
46+
uses: actions/checkout@v5
47+
48+
- name: Run Tests
49+
uses: mxcl/xcodebuild@v3
50+
with:
51+
platform: ${{ matrix.platform }}
52+
swift: ~${{ matrix.swift }}
53+
action: test
54+
verbosity: xcbeautify

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

.swift-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6.0

.swiftformat

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# SwiftFormat Configuration File
2+
# For documentation, see: https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md
3+
4+
--header ignore
5+
--indent tab
6+
--ifdef no-indent
7+
--ranges preserve
8+
--extensionacl on-declarations
9+
--trailing-commas always
10+
--nil-init insert
11+
12+
# Disabled rules
13+
--disable blankLinesAroundMark
14+
--disable redundantBackticks
15+
--disable redundantLetError
16+
--disable redundantSelf
17+
--disable redundantStaticSelf
18+
--disable redundantType
19+
--disable redundantTypedThrows
20+
--disable unusedArguments

Package.resolved

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// swift-tools-version: 6.0
2+
3+
import CompilerPluginSupport
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "swiftui-color-macros",
8+
platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
9+
products: [
10+
.library(
11+
name: "ColorMacros",
12+
targets: ["ColorMacros"]
13+
)
14+
],
15+
dependencies: [],
16+
targets: [
17+
.macro(
18+
name: "ColorMacrosPlugin",
19+
dependencies: [
20+
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
21+
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
22+
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax")
23+
]
24+
),
25+
26+
.target(name: "ColorMacros", dependencies: ["ColorMacrosPlugin"]),
27+
28+
.testTarget(
29+
name: "ColorMacrosTests",
30+
dependencies: [
31+
"ColorMacros",
32+
"ColorMacrosPlugin",
33+
.product(name: "MacroTesting", package: "swift-macro-testing"),
34+
.product(name: "SwiftCompilerPlugin", package: "swift-syntax")
35+
]
36+
)
37+
]
38+
)
39+
40+
package.dependencies += [
41+
.package(url: "https://github.com/pointfreeco/swift-macro-testing", from: "0.6.0"),
42+
.package(url: "https://github.com/swiftlang/swift-syntax", "600.0.0"..<"603.0.0")
43+
]
44+
45+
for target in package.targets {
46+
target.swiftSettings = target.swiftSettings ?? []
47+
target.swiftSettings? += [
48+
.enableUpcomingFeature("ExistentialAny"),
49+
.enableUpcomingFeature("InternalImportsByDefault")
50+
]
51+
}

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# `#Color`
2+
3+
[![CI](https://github.com/davdroman/swiftui-color-macros/actions/workflows/ci.yml/badge.svg)](https://github.com/davdroman/swiftui-color-macros/actions/workflows/ci.yml)
4+
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fdavdroman%2Fswiftui-color-macros%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/davdroman/swiftui-color-macros)
5+
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fdavdroman%2Fswiftui-color-macros%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/davdroman/swiftui-color-macros)
6+
7+
`ColorMacros` is a bundle of expression macros that turn the color tokens you copy from
8+
Figma/Sketch into compile-time `SwiftUI.Color` literals:
9+
10+
```swift
11+
import SwiftUI
12+
import ColorMacros
13+
14+
let brand = #Color(hex: "#FF9900")
15+
let overlay = #Color(hex: "0x336699CC")
16+
let grass = #Color(rgba: 154, 234, 98, 1)
17+
let warning = #Color(hsla: 32, 100, 50, 0.8)
18+
let accent = #Color(hsba: 200, 60, 80, 0.65)
19+
```
20+
21+
## Features
22+
23+
- `hex:` accepts `RGB`, `RGBA`, `RRGGBB`, `RRGGBBAA`, with or without `#` or a `0x` prefix.
24+
- `rgb:` / `rgba:` accept 0–255 integer channels, optionally plus opacity (0–1).
25+
- `hsl:` / `hsla:` accept degrees/percentages, matching what design tools output.
26+
- `hsb:` / `hsba:` cover hue–saturation–brightness (%), again with optional opacity.
27+
- Every variant emits a `SwiftUI.Color` literal (no runtime helpers) and validates inputs at build time.
28+
29+
Example diagnostic:
30+
31+
```
32+
#Color(hex: "#12345")
33+
┬───────
34+
╰─ 🛑 Hex literals must contain 3, 4, 6, or 8 digits, but found 5.
35+
```
36+
37+
## Installation
38+
39+
Add the package to your project:
40+
41+
```swift
42+
dependencies: [
43+
.package(url: "https://github.com/davdroman/swiftui-color-macros.git", from: "0.1.0")
44+
],
45+
targets: [
46+
.target(
47+
name: "App",
48+
dependencies: [
49+
.product(name: "ColorMacros", package: "swiftui-color-macros")
50+
]
51+
)
52+
]
53+
```
54+
55+
Then import the module alongside SwiftUI wherever you need the macro.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#if canImport(SwiftUI)
2+
@_exported import SwiftUI
3+
#endif
4+
5+
@freestanding(expression)
6+
public macro Color(hex literal: String) -> SwiftUI.Color = #externalMacro(
7+
module: "ColorMacrosPlugin",
8+
type: "ColorMacro"
9+
)
10+
11+
@freestanding(expression)
12+
public macro Color(rgb red: UInt8, _ green: UInt8, _ blue: UInt8) -> SwiftUI.Color = #externalMacro(
13+
module: "ColorMacrosPlugin",
14+
type: "ColorMacro"
15+
)
16+
17+
@freestanding(expression)
18+
public macro Color(rgba red: UInt8, _ green: UInt8, _ blue: UInt8, _ alpha: Double) -> SwiftUI.Color =
19+
#externalMacro(
20+
module: "ColorMacrosPlugin",
21+
type: "ColorMacro"
22+
)
23+
24+
@freestanding(expression)
25+
public macro Color(hsl hue: UInt8, _ saturation: UInt8, _ lightness: UInt8) -> SwiftUI.Color = #externalMacro(
26+
module: "ColorMacrosPlugin",
27+
type: "ColorMacro"
28+
)
29+
30+
@freestanding(expression)
31+
public macro Color(hsla hue: UInt8, _ saturation: UInt8, _ lightness: UInt8, _ alpha: Double) -> SwiftUI.Color =
32+
#externalMacro(
33+
module: "ColorMacrosPlugin",
34+
type: "ColorMacro"
35+
)
36+
37+
@freestanding(expression)
38+
public macro Color(hsb hue: UInt8, _ saturation: UInt8, _ brightness: UInt8) -> SwiftUI.Color = #externalMacro(
39+
module: "ColorMacrosPlugin",
40+
type: "ColorMacro"
41+
)
42+
43+
@freestanding(expression)
44+
public macro Color(hsba hue: UInt8, _ saturation: UInt8, _ brightness: UInt8, _ alpha: Double) -> SwiftUI.Color =
45+
#externalMacro(
46+
module: "ColorMacrosPlugin",
47+
type: "ColorMacro"
48+
)

0 commit comments

Comments
 (0)