TechLead
Volver a Sistemas de Diseño
Tema 2 de 8

Tokens de Diseño

Define decisiones de diseño como datos: colores, tipografía, espaciado y más

¿Qué son los Tokens de Diseño?

Los tokens de diseño son las decisiones de diseño atómicas de tu sistema - las variables que definen colores, tipografía, espaciado y más. Piensa en ellos como constantes que garantizan la consistencia en todas las plataformas (web, iOS, Android).

🎯 Tipos de Tokens

Colores

Paletas de marca, semánticos (éxito, error)

Tipografía

Familias de fuentes, tamaños, pesos, alturas de línea

Espaciado

Márgenes, rellenos, brechas (4px, 8px, 16px...)

Dimensionamiento

Anchos, alturas, radios de borde

Efectos

Sombras, desenfoque, gradientes

Movimiento

Duraciones de transición, curvas de aceleración

Jerarquía de Tokens

// 1. Tokens Primitivos (valores brutos)
const primitive = {
  blue500: '#3b82f6',
  blue600: '#2563eb',
  gray100: '#f3f4f6',
  fontSans: 'Inter, system-ui, sans-serif',
  spacing4: '16px',
};

// 2. Tokens Semánticos (significado)
const semantic = {
  colorPrimary: primitive.blue500,
  colorPrimaryHover: primitive.blue600,
  colorBackground: primitive.gray100,
  fontBody: primitive.fontSans,
  spacingMd: primitive.spacing4,
};

// 3. Tokens de Componente (contexto específico)
const component = {
  buttonPrimaryBg: semantic.colorPrimary,
  buttonPrimaryBgHover: semantic.colorPrimaryHover,
  buttonPaddingX: semantic.spacingMd,
  buttonPaddingY: '12px',
};

Formato JSON para Tokens

// tokens/colors.json
{
  "color": {
    "primary": {
      "value": "#3b82f6",
      "type": "color",
      "description": "Color de marca principal"
    },
    "success": {
      "value": "#10b981",
      "type": "color"
    },
    "error": {
      "value": "#ef4444",
      "type": "color"
    },
    "warning": {
      "value": "#f59e0b",
      "type": "color"
    }
  }
}

// tokens/typography.json
{
  "font": {
    "family": {
      "sans": {
        "value": "Inter, system-ui, sans-serif",
        "type": "fontFamily"
      },
      "mono": {
        "value": "Fira Code, monospace",
        "type": "fontFamily"
      }
    },
    "size": {
      "xs": { "value": "0.75rem", "type": "fontSize" },
      "sm": { "value": "0.875rem", "type": "fontSize" },
      "base": { "value": "1rem", "type": "fontSize" },
      "lg": { "value": "1.125rem", "type": "fontSize" },
      "xl": { "value": "1.25rem", "type": "fontSize" }
    }
  }
}

Variables CSS (Implementación Nativa)

/* tokens.css */
:root {
  /* Colores */
  --color-primary: #3b82f6;
  --color-primary-hover: #2563eb;
  --color-success: #10b981;
  --color-error: #ef4444;
  
  /* Tipografía */
  --font-sans: Inter, system-ui, sans-serif;
  --font-mono: 'Fira Code', monospace;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  
  /* Espaciado (escala de 4px) */
  --spacing-1: 0.25rem;  /* 4px */
  --spacing-2: 0.5rem;   /* 8px */
  --spacing-3: 0.75rem;  /* 12px */
  --spacing-4: 1rem;     /* 16px */
  --spacing-6: 1.5rem;   /* 24px */
  --spacing-8: 2rem;     /* 32px */
  
  /* Radios */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-full: 9999px;
  
  /* Sombras */
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
}

/* Usar tokens */
.button {
  background-color: var(--color-primary);
  color: white;
  padding: var(--spacing-3) var(--spacing-6);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  box-shadow: var(--shadow-sm);
}

.button:hover {
  background-color: var(--color-primary-hover);
}

Transformación con Style Dictionary

Style Dictionary transforma tokens de diseño a cualquier formato de plataforma.

npm install style-dictionary

// build-tokens.js
const StyleDictionary = require('style-dictionary');

const sd = StyleDictionary.extend({
  source: ['tokens/**/*.json'],
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'dist/css/',
      files: [{
        destination: 'variables.css',
        format: 'css/variables'
      }]
    },
    js: {
      transformGroup: 'js',
      buildPath: 'dist/js/',
      files: [{
        destination: 'tokens.js',
        format: 'javascript/es6'
      }]
    },
    ios: {
      transformGroup: 'ios',
      buildPath: 'dist/ios/',
      files: [{
        destination: 'Tokens.swift',
        format: 'ios-swift/class.swift'
      }]
    },
    android: {
      transformGroup: 'android',
      buildPath: 'dist/android/',
      files: [{
        destination: 'tokens.xml',
        format: 'android/resources'
      }]
    }
  }
});

sd.buildAllPlatforms();

// Ejecuta: node build-tokens.js
// Salida: CSS, JS, Swift, XML desde una fuente JSON

Integración con Tailwind CSS

// tailwind.config.js
const tokens = require('./tokens/design-tokens.json');

module.exports = {
  theme: {
    extend: {
      colors: {
        primary: tokens.color.primary.value,
        success: tokens.color.success.value,
        error: tokens.color.error.value,
      },
      fontFamily: {
        sans: tokens.font.family.sans.value.split(', '),
        mono: tokens.font.family.mono.value.split(', '),
      },
      spacing: {
        '1': tokens.spacing['1'].value,
        '2': tokens.spacing['2'].value,
        '3': tokens.spacing['3'].value,
        '4': tokens.spacing['4'].value,
      },
      borderRadius: {
        'sm': tokens.radius.sm.value,
        'md': tokens.radius.md.value,
        'lg': tokens.radius.lg.value,
      },
    },
  },
};

// Ahora usa clases de Tailwind basadas en tokens

💡 Mejores Prácticas

  • • Usa nombres semánticos: color-primary no color-blue-500
  • • Mantén una jerarquía clara: primitivo → semántico → componente
  • • Documenta el propósito de cada token
  • • Usa una fuente única de verdad (JSON, YAML)
  • • Automatiza la sincronización de Figma a código
  • • Versionsa tus tokens con gestión de cambios semánticos