61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
"""Generate Swift Color enum from design tokens."""
|
|
|
|
from __future__ import annotations
|
|
import json
|
|
import os
|
|
|
|
_FILE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(_FILE_DIR)))
|
|
TOKENS_PATH = os.path.join(ROOT, "docs", "design-system", "tokens.json")
|
|
OUTPUT_PATH = os.path.join(ROOT, "app", "design-tokens", "swift", "Colors.swift")
|
|
|
|
|
|
def load_tokens() -> dict:
|
|
with open(TOKENS_PATH, encoding="utf-8-sig") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def hex_to_rgb(hex_color: str) -> tuple[int, int, int]:
|
|
h = hex_color.lstrip("#")
|
|
return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
|
|
|
|
|
|
def generate(tokens: dict) -> str:
|
|
lines = [
|
|
"// Auto-generated from design tokens — do not edit manually",
|
|
"import SwiftUI",
|
|
"",
|
|
"extension Color {",
|
|
]
|
|
|
|
for color_name, shades in tokens.get("colors", {}).items():
|
|
if isinstance(shades, dict):
|
|
for shade, value in shades.items():
|
|
if shade not in ("system",) and isinstance(value, str) and value.startswith("#"):
|
|
try:
|
|
r, g, b = hex_to_rgb(value)
|
|
suffix = shade.capitalize()
|
|
swift_name = f"{color_name}{suffix}"
|
|
lines.append(f" static let {swift_name} = Color(red: {r/255:.4f}, green: {g/255:.4f}, blue: {b/255:.4f})")
|
|
except (ValueError, IndexError):
|
|
pass
|
|
|
|
for space_name, value in tokens.get("spacing", {}).items():
|
|
lines.append(f" static let spacing{space_name.capitalize()} = CGFloat({value.replace('rem', '').strip()})")
|
|
|
|
lines.append("}")
|
|
return "\n".join(lines) + "\n"
|
|
|
|
|
|
def main():
|
|
tokens = load_tokens()
|
|
swift = generate(tokens)
|
|
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
|
|
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
|
|
f.write(swift)
|
|
print(f"Written: {OUTPUT_PATH}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|