| import json |
|
|
|
|
| class TokenCodeGenerator: |
| def generate_css_variables(self, tokens): |
| """Generate CSS custom properties""" |
| css = ":root {\n" |
| |
| |
| for name, color in tokens.get('colors', {}).items(): |
| css += f" --color-{name}: {color['hex']};\n" |
| css += f" --color-{name}-rgb: {color['rgb']};\n" |
| |
| css += "\n" |
| |
| |
| for name, value in tokens.get('spacing', {}).items(): |
| css += f" --spacing-{name}: {value};\n" |
| |
| css += "\n" |
| |
| |
| if 'typography' in tokens: |
| for name, props in tokens['typography'].items(): |
| css += f" --font-{name}: {props.get('family', 'sans-serif')};\n" |
| css += f" --font-size-{name}: {props.get('size', '16px')};\n" |
| css += f" --font-weight-{name}: {props.get('weight', '400')};\n" |
| |
| css += "}\n\n" |
| |
| |
| css += "/* Example usage:\n" |
| css += " * color: var(--color-primary);\n" |
| css += " * padding: var(--spacing-medium);\n" |
| css += " * font-family: var(--font-body);\n" |
| css += " */\n" |
| |
| return css |
| |
| def generate_tailwind_config(self, tokens): |
| """Generate Tailwind configuration""" |
| config = { |
| "theme": { |
| "extend": { |
| "colors": {}, |
| "spacing": {}, |
| "fontFamily": {}, |
| "fontSize": {}, |
| "fontWeight": {} |
| } |
| } |
| } |
| |
| |
| for name, color in tokens.get('colors', {}).items(): |
| config["theme"]["extend"]["colors"][name] = color['hex'] |
| |
| |
| for name, value in tokens.get('spacing', {}).items(): |
| config["theme"]["extend"]["spacing"][name] = value |
| |
| |
| if 'typography' in tokens: |
| for name, props in tokens['typography'].items(): |
| if 'family' in props: |
| config["theme"]["extend"]["fontFamily"][name] = props['family'] |
| if 'size' in props: |
| config["theme"]["extend"]["fontSize"][name] = props['size'] |
| if 'weight' in props: |
| config["theme"]["extend"]["fontWeight"][name] = props['weight'] |
| |
| |
| output = "/** @type {import('tailwindcss').Config} */\n" |
| output += f"module.exports = {json.dumps(config, indent=2)}" |
| |
| return output |
| |
| def generate_json_tokens(self, tokens): |
| """Generate W3C Design Token Community Group format""" |
| formatted_tokens = { |
| "$schema": "https://design-tokens.github.io/community-group/format.json", |
| "tokens": {} |
| } |
| |
| |
| if 'colors' in tokens: |
| formatted_tokens["tokens"]["color"] = {} |
| for name, color in tokens['colors'].items(): |
| formatted_tokens["tokens"]["color"][name] = { |
| "$value": color['hex'], |
| "$type": "color", |
| "$description": f"Color {name} - {color.get('proportion', 0)*100:.1f}% of design" |
| } |
| |
| |
| if 'spacing' in tokens: |
| formatted_tokens["tokens"]["spacing"] = {} |
| for name, value in tokens['spacing'].items(): |
| formatted_tokens["tokens"]["spacing"][name] = { |
| "$value": value, |
| "$type": "dimension" |
| } |
| |
| |
| if 'typography' in tokens: |
| formatted_tokens["tokens"]["typography"] = {} |
| for name, props in tokens['typography'].items(): |
| formatted_tokens["tokens"]["typography"][name] = { |
| "fontFamily": { |
| "$value": props.get('family', 'sans-serif'), |
| "$type": "fontFamily" |
| }, |
| "fontSize": { |
| "$value": props.get('size', '16px'), |
| "$type": "dimension" |
| }, |
| "fontWeight": { |
| "$value": props.get('weight', '400'), |
| "$type": "fontWeight" |
| } |
| } |
| |
| return json.dumps(formatted_tokens, indent=2) |
| |
| def generate_style_dictionary(self, tokens): |
| """Generate Style Dictionary format tokens""" |
| sd_tokens = { |
| "color": {}, |
| "spacing": {}, |
| "typography": {} |
| } |
| |
| |
| for name, color in tokens.get('colors', {}).items(): |
| sd_tokens["color"][name] = { |
| "value": color['hex'], |
| "type": "color", |
| "attributes": { |
| "rgb": color.get('rgb', ''), |
| "proportion": color.get('proportion', 0) |
| } |
| } |
| |
| |
| for name, value in tokens.get('spacing', {}).items(): |
| sd_tokens["spacing"][name] = { |
| "value": value, |
| "type": "spacing" |
| } |
| |
| |
| if 'typography' in tokens: |
| for name, props in tokens['typography'].items(): |
| sd_tokens["typography"][name] = { |
| "fontFamily": { |
| "value": props.get('family', 'sans-serif') |
| }, |
| "fontSize": { |
| "value": props.get('size', '16px') |
| }, |
| "fontWeight": { |
| "value": props.get('weight', '400') |
| } |
| } |
| |
| return json.dumps(sd_tokens, indent=2) |
| |
| def generate_scss_variables(self, tokens): |
| """Generate SCSS variables""" |
| scss = "// Design Tokens - SCSS Variables\n\n" |
| |
| |
| scss += "// Colors\n" |
| for name, color in tokens.get('colors', {}).items(): |
| scss += f"$color-{name}: {color['hex']};\n" |
| |
| scss += "\n// Spacing\n" |
| for name, value in tokens.get('spacing', {}).items(): |
| scss += f"$spacing-{name}: {value};\n" |
| |
| scss += "\n// Typography\n" |
| if 'typography' in tokens: |
| for name, props in tokens['typography'].items(): |
| scss += f"$font-{name}: {props.get('family', 'sans-serif')};\n" |
| scss += f"$font-size-{name}: {props.get('size', '16px')};\n" |
| scss += f"$font-weight-{name}: {props.get('weight', '400')};\n" |
| scss += "\n" |
| |
| |
| scss += "\n// Utility Mixins\n" |
| scss += "@mixin text-style($style) {\n" |
| scss += " @if $style == 'heading' {\n" |
| scss += " font-family: $font-heading;\n" |
| scss += " font-size: $font-size-heading;\n" |
| scss += " font-weight: $font-weight-heading;\n" |
| scss += " } @else if $style == 'body' {\n" |
| scss += " font-family: $font-body;\n" |
| scss += " font-size: $font-size-body;\n" |
| scss += " font-weight: $font-weight-body;\n" |
| scss += " }\n" |
| scss += "}\n" |
| |
| return scss |