snapp-mobile/snappdesigntokens
A Swift library for parsing and processing [DTCG-compliant](https://www.designtokens.org/tr/third-editors-draft/format/) design tokens into type-safe Swift structures.
Installation
Swift Package Manager
Add SnappDesignTokens to your Package.swift file:
dependencies: [
.package(url: "https://github.com/Snapp-Mobile/SnappDesignTokens.git", from: "0.1.0")
]Or add it through Xcode:
- File > Add Package Dependencies...
- Enter package URL:
https://github.com/Snapp-Mobile/SnappDesignTokens.git - Select version and add to your target
Quick Start
import SnappDesignTokens
import Foundation
// Load and parse DTCG-compliant JSON file
let url = Bundle.main.url(forResource: "tokens", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let token = try decoder.decode(Token.self, from: data)
// Access token values
if case .group(let group) = token,
case .value(.color(let colorValue)) = group["brand.primary"] {
print("Brand color: \(colorValue.hex)")
}Usage
Loading Design Tokens
let jsonData = """
{
"color": {
"base": {
"red": { "$value": "#FF0000", "$type": "color" },
"blue": { "$value": "#0000FF", "$type": "color" }
}
}
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let token = try decoder.decode(Token.self, from: jsonData)Processing Pipelines
// Resolve aliases and flatten hierarchy
let processedToken = try await CombineProcessor.combine(
.resolveAliases,
.flatten()
).process(token)
// Alternative syntax
let processedToken = try await ResolveAliasesTokenProcessor
.resolveAliases
.combine(.flatten())
.process(token)Working with Token Values
// Color tokens
if case .color(let color) = token.value {
print("Hex: \(color.hex)")
print("RGB: \(color.components)")
print("Alpha: \(color.alpha)")
}
// Dimension tokens
if case .dimension(let dimension) = token.value {
print("Value: \(dimension.value)")
print("Unit: \(dimension.unit)") // .px, .rem, etc.
}
// Typography tokens
if case .typography(let typography) = token.value {
print("Font: \(typography.fontFamily)")
print("Size: \(typography.fontSize)")
print("Weight: \(typography.fontWeight)")
}Alias Resolution
let jsonData = """
{
"base": {
"color1": { "$value": "#FF0000", "$type": "color" },
"color2": { "$value": "{base.color1}" }
}
}
""".data(using: .utf8)!
let token: Token = try jsonData.decode()
let resolved = try await ResolveAliasesTokenProcessor
.resolveAliases
.process(token)
// base.color2 now contains #FF0000Expression Evaluation
let jsonData = """
{
"space1": { "$value": "2*2", "$type": "dimension" },
"space2": { "$value": "2", "$type": "dimension" }
}
""".data(using: .utf8)!
let token: Token = try jsonData.decode()
// Using arithmetical evaluation
let evaluated = try await DimensionValueEvaluationProcessor
.arithmeticalEvaluation
.process(token)
// space1 is now 4
// Or using NSExpression-based evaluation
let evaluated = try await DimensionValueEvaluationProcessor
.expressionsEvaluation
.process(token)Unit Conversion
let token: Token = .group([
"dimension1": .value(.dimension(.constant(.init(value: 160, unit: .px)))),
"dimension2": .value(.dimension(.constant(.init(value: 1, unit: .rem))))
])
let processor: DimensionValueConversionProcessor = .dimensionValueConversion(
using: .converter(with: 16), // 1rem = 16px
targetUnit: .rem
)
let converted = try await processor.process(token)
// dimension1 is now 10rem, dimension2 remains 1remDocumentation
For more information about the library, visit Documentation page.
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
License
SnappDesignTokens is available under the MIT license. See the LICENSE file for more info.
Package Metadata
Repository: snapp-mobile/snappdesigntokens
Default branch: main
README: README.md