import gradio as gr
import json
import os
from PIL import Image
import tempfile
# from utils.extractor import DesignTokenExtractor
# from utils.token_generator import TokenCodeGenerator
def create_token_preview(tokens):
"""Create HTML preview of extracted tokens"""
html = """
Extracted Design Tokens
"""
# Color palette preview
if 'colors' in tokens and tokens['colors']:
html += """
Colors
"""
for name, color in tokens['colors'].items():
html += f"""
{name}
{color['hex']}
{int(color.get('proportion', 0) * 100)}%
"""
html += "
"
# Spacing preview
if 'spacing' in tokens and tokens['spacing']:
html += """
Spacing
"""
for name, value in tokens['spacing'].items():
try:
height = value.replace('px', '')
html += f"""
"""
except:
pass
html += "
"
# Typography preview
if 'typography' in tokens and tokens['typography']:
html += """
Typography
"""
for name, props in tokens['typography'].items():
size = props.get('size', '16px')
weight = props.get('weight', '400')
family = props.get('family', 'sans-serif')
html += f"""
Sample {name.title()} Text
{family} • {size} • Weight {weight}
"""
html += "
"
html += "
"
return html
def process_screenshot(image, output_format, progress=None):
"""Process uploaded screenshot and extract design tokens"""
if image is None:
return None, "Please upload a screenshot", None
# Temporary stub implementation for testing
try:
# Mock tokens for testing
tokens = {
"colors": {
"primary": {"hex": "#3B82F6", "rgb": "rgb(59, 130, 246)", "proportion": 0.25},
"secondary": {"hex": "#8B5CF6", "rgb": "rgb(139, 92, 246)", "proportion": 0.15}
},
"spacing": {
"small": "8px",
"medium": "16px",
"large": "32px"
},
"typography": {
"heading": {"family": "sans-serif", "size": "32px", "weight": "700"},
"body": {"family": "sans-serif", "size": "16px", "weight": "400"}
}
}
# Simple CSS output for testing
code_output = ":root {\n --color-primary: #3B82F6;\n --color-secondary: #8B5CF6;\n --spacing-small: 8px;\n --spacing-medium: 16px;\n --spacing-large: 32px;\n}"
# Save output file
output_filename = "design_tokens.css"
with open(output_filename, "w") as f:
f.write(code_output)
# Create preview visualization
preview_html = create_token_preview(tokens)
return preview_html, code_output, output_filename
except Exception as e:
return None, f"Error processing screenshot: {str(e)}", None
def create_gradio_app():
"""Create the main Gradio application"""
with gr.Blocks(
title="Design Token Extractor",
theme=gr.themes.Soft(),
css="""
.gradio-container {
font-family: 'Inter', system-ui, sans-serif;
}
.gr-button-primary {
background-color: #3b82f6 !important;
}
"""
) as app:
gr.Markdown(
"""
# 🎨 Design Token Extractor
Transform UI screenshots into structured design token libraries using AI-powered analysis.
Upload a screenshot to automatically extract colors, spacing, typography, and component tokens.
---
"""
)
with gr.Row():
with gr.Column(scale=1):
input_image = gr.Image(
label="Upload UI Screenshot",
type="pil",
sources=["upload", "clipboard"],
height=400
)
output_format = gr.Radio(
choices=[
"CSS Variables",
"Tailwind Config",
"JSON Tokens",
"Style Dictionary",
"SCSS Variables"
],
value="CSS Variables",
label="Output Format",
info="Choose the format for your design tokens"
)
extract_btn = gr.Button(
"🚀 Extract Design Tokens",
variant="primary",
size="lg"
)
gr.Markdown(
"""
### Tips for best results:
- Use high-quality screenshots (min 800px width)
- Include various UI elements for comprehensive extraction
- Screenshots with clear color hierarchy work best
- Ensure good contrast between elements
"""
)
with gr.Column(scale=1):
preview = gr.HTML(
label="Token Preview",
value="