Skip to content

Commit db229bb

Browse files
committed
Initial commit
0 parents  commit db229bb

File tree

10 files changed

+739
-0
lines changed

10 files changed

+739
-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: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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
55+
linux:
56+
if: github.event_name != 'pull_request' || !contains(github.event.pull_request.title, '[skip ci]')
57+
name: Linux (Swift ${{ matrix.swift }})
58+
runs-on: ubuntu-latest
59+
strategy:
60+
fail-fast: false
61+
matrix:
62+
swift:
63+
- "6.0"
64+
- "6.1"
65+
- "6.2"
66+
container:
67+
image: swift:${{ matrix.swift }}
68+
steps:
69+
- name: Git Checkout
70+
uses: actions/checkout@v5
71+
72+
- name: Run Tests
73+
run: swift test

.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

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

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SwiftUI `#Color(hex:)`
2+
3+
[![CI](https://github.com/davdroman/swiftui-color-hex-macro/actions/workflows/ci.yml/badge.svg)](https://github.com/davdroman/swiftui-color-hex-macro/actions/workflows/ci.yml)
4+
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fdavdroman%2Fswiftui-color-hex-macro%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/davdroman/swiftui-color-hex-macro)
5+
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fdavdroman%2Fswiftui-color-hex-macro%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/davdroman/swiftui-color-hex-macro)
6+
7+
`ColorHexMacro` adds a tiny freestanding macro that lets you write colors as hexadecimal
8+
constants while keeping compile-time safety:
9+
10+
```swift
11+
import SwiftUI
12+
import ColorHexMacro
13+
14+
let brand = #Color(hex: "#FF9900")
15+
let overlay = #Color(hex: "0x336699CC")
16+
```
17+
18+
## Features
19+
20+
- Accepts the most common hex formats: `RGB`, `RGBA`, `RRGGBB`, `RRGGBBAA`, with or without `#`,
21+
and with optional `0x` prefixes.
22+
- Emits `SwiftUI.Color` literals, so nothing changes at runtime.
23+
- Diagnoses problems at build time (invalid characters, unsupported lengths, interpolations,
24+
missing arguments, etc.) with helpful fix-ups.
25+
26+
Example diagnostic:
27+
28+
```
29+
#Color(hex: "#12345")
30+
┬───────
31+
╰─ 🛑 Hex literals must contain 3, 4, 6, or 8 digits, but found 5.
32+
```
33+
34+
## Installation
35+
36+
Add the package to your project:
37+
38+
```swift
39+
dependencies: [
40+
.package(url: "https://github.com/davdroman/swiftui-color-hex-macro.git", from: "0.1.0")
41+
],
42+
targets: [
43+
.target(
44+
name: "App",
45+
dependencies: [
46+
.product(name: "ColorHexMacro", package: "swiftui-color-hex-macro")
47+
]
48+
)
49+
]
50+
```
51+
52+
Then import the module alongside SwiftUI wherever you need the macro.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public import SwiftUI
2+
3+
/// Builds a `SwiftUI.Color` from a compile-time hexadecimal string such as
4+
/// `#Color(hex: "#FFCC00")`.
5+
@freestanding(expression)
6+
public macro Color(hex literal: String) -> SwiftUI.Color = #externalMacro(module: "ColorHexMacroPlugin", type: "ColorHexMacro")

0 commit comments

Comments
 (0)