Paquete de Design Tokens - Sistema de Diseño Código Obsidiana

Descripción
El paquete de Design Tokens es la capa fundamental del Sistema de Diseño Código Obsidiana, proporcionando un sistema centralizado y type-safe de gestión de tokens que asegura consistencia de diseño en todas las aplicaciones y componentes. Construido con estándares web modernos, aprovecha el avanzado espacio de color OKLCH para colores perceptualmente uniformes y Style Dictionary para transformación escalable de tokens.
Este paquete genera salidas específicas para cada plataforma (CSS Custom Properties, módulos JavaScript/TypeScript) desde una única fuente de verdad, permitiendo integración sin pérdidas a través de diferentes tecnologías mientras mantiene la consistencia de diseño. El sistema soporta tematización comprensiva con variantes claras y oscuras para todos los tokens de color.
Estructura de Tokens
La base de nuestros design tokens sigue una estructura jerárquica semántica que soporta tematización comprensiva:
{
"color": {
"primary": {
"light": {
"default": {
"value": "oklch(72.6% 0.21 245)",
"type": "color"
},
"content": {
"value": "oklch(98% 0.003 262.2)",
"type": "color"
}
},
"dark": {
"default": {
"value": "oklch(72.6% 0.21 245)",
"type": "color"
},
"content": {
"value": "oklch(26.2% 0.003 262.2)",
"type": "color"
}
}
}
}
}
Desafíos
- Innovación en Espacio de Color: Implementar el espacio de color OKLCH en un sistema de diseño cuando la mayoría de herramientas y desarrolladores están familiarizados con HSL/RGB, requiriendo validación y educación sobre los beneficios de uniformidad perceptual
- Distribución Multi-Plataforma de Tokens: Crear una única fuente de verdad que genere tokens consistentes para CSS, JavaScript y TypeScript mientras mantiene type safety y soporte de intellisense
- Arquitectura Escalable: Diseñar una estructura de tokens que soporte requerimientos complejos de tematización (modos claro/oscuro) mientras permanece mantenible y extensible para futura evolución del sistema de diseño
- Type Safety y Validación: Asegurar validación en tiempo de ejecución de valores de tokens mientras se proporciona type safety en tiempo de compilación, particularmente para estructuras de tokens anidadas complejas y validación de valores OKLCH
- Integración de Proceso de Build: Integrar Style Dictionary con las herramientas de monorepo Nx para crear un pipeline de build eficiente y cacheable que soporte publicación automatizada y gestión de versiones
Soluciones
Sistema de Color Avanzado con OKLCH: Implementamos el espacio de color OKLCH (Oklch Lightness Chroma Hue) para manipulación de color perceptualmente uniforme, proporcionando mejores ratios de contraste y relaciones de color más predecibles. Construimos validación comprensiva con patrones regex para asegurar sintaxis OKLCH apropiada y rangos de valores (luminosidad 0-100%, croma ≥0, matiz 0-360°).
Validación de Color OKLCH
Nuestro sistema de validación asegura precisión y consistencia de color:
const validateOKLCHColor = (value: string) => {
// Patrón regex para validación de formato OKLCH
const oklchRegex = /^oklch\(\d+\.?\d*% \d+\.?\d* \d+\.?\d*\)$/;
expect(value).toMatch(oklchRegex);
// Extraer y validar componentes individuales
const matches = value.match(/oklch\((\d+\.?\d*)% (\d+\.?\d*) (\d+\.?\d*)\)/);
if (!matches) throw new Error('Invalid OKLCH format');
const [, lightness, chroma, hue] = matches.map(Number);
// Validar rangos de valores
expect(lightness).toBeGreaterThanOrEqual(0);
expect(lightness).toBeLessThanOrEqual(100);
expect(chroma).toBeGreaterThanOrEqual(0);
expect(hue).toBeGreaterThanOrEqual(0);
expect(hue).toBeLessThanOrEqual(360);
};
Generación de Código Multi-Plataforma: Aprovechamos el pipeline de transformación de Style Dictionary para generar tres salidas distintas desde archivos fuente JSON:
- CSS Custom Properties para tematización en tiempo de ejecución
- Módulos ES6 JavaScript para integración de frameworks
- Declaraciones TypeScript con tipos literales para seguridad en tiempo de compilación
Configuración de Style Dictionary
La configuración que impulsa nuestra generación de tokens multi-plataforma:
{
"source": ["src/tokens/**/*.json"],
"platforms": {
"css": {
"transformGroup": "css",
"buildPath": "dist/css/",
"files": [
{
"destination": "_variables.css",
"format": "css/variables"
}
]
},
"js": {
"transformGroup": "js",
"buildPath": "dist/",
"files": [
{
"destination": "index.js",
"format": "javascript/es6"
}
]
},
"ts": {
"transformGroup": "js",
"buildPath": "dist/",
"files": [
{
"destination": "index.d.ts",
"format": "typescript/es6-declarations",
"options": {
"outputLiteralTypes": true
}
}
]
}
}
}
Arquitectura de Tokens Estructurada: Diseñamos una estructura de tokens jerárquica con nomenclatura semántica:
color.{category}.{theme}.{variant}
// Ejemplos: color.primary.light.default, color.base.dark.content
Salidas Generadas
CSS Custom Properties
:root {
--color-primary-light-default: oklch(72.6% 0.21 245);
--color-primary-light-content: oklch(98% 0.003 262.2);
--color-primary-dark-default: oklch(72.6% 0.21 245);
--color-primary-dark-content: oklch(26.2% 0.003 262.2);
--color-success-light-default: oklch(68% 0.18 150);
--color-warning-light-default: oklch(82% 0.16 85);
--color-error-light-default: oklch(70.3% 0.16 35);
}
Declaraciones TypeScript
export const ColorPrimaryLightDefault: string;
export const ColorPrimaryLightContent: string;
export const ColorPrimaryDarkDefault: string;
export const ColorPrimaryDarkContent: string;
export const ColorSuccessLightDefault: string;
export const ColorWarningLightDefault: string;
export const ColorErrorLightDefault: string;
Módulo ES6 JavaScript
export const ColorPrimaryLightDefault = "oklch(72.6% 0.21 245)";
export const ColorPrimaryLightContent = "oklch(98% 0.003 262.2)";
export const ColorPrimaryDarkDefault = "oklch(72.6% 0.21 245)";
export const ColorPrimaryDarkContent = "oklch(26.2% 0.003 262.2)";
export const ColorSuccessLightDefault = "oklch(68% 0.18 150)";
export const ColorWarningLightDefault = "oklch(82% 0.16 85)";
export const ColorErrorLightDefault = "oklch(70.3% 0.16 35)";
Estrategia de Testing Comprensiva: Implementamos testing basado en Jest con múltiples capas de validación:
- Validación estructural asegurando jerarquía consistente de tokens
- Validación de valores OKLCH con verificación de rangos matemáticos
- Validación de consistencia entre temas
- Aplicación de convenciones de nomenclatura
- Validación de completitud de tokens
Tests de Validación de Tokens
describe('Color Tokens', () => {
describe('Theme Consistency', () => {
it('should have matching properties in light and dark themes', () => {
Object.keys(tokens.color).forEach(category => {
const lightKeys = Object.keys(tokens.color[category].light);
const darkKeys = Object.keys(tokens.color[category].dark);
expect(lightKeys).toEqual(darkKeys);
});
});
it('should have consistent token structure across themes', () => {
Object.keys(tokens.color).forEach(category => {
const lightTokens = tokens.color[category].light;
const darkTokens = tokens.color[category].dark;
Object.keys(lightTokens).forEach(tokenKey => {
expect(lightTokens[tokenKey].type).toBe(darkTokens[tokenKey].type);
});
});
});
});
describe('Color Token Completeness', () => {
it('should have all required color variants', () => {
const requiredVariants = ['default', 'content'];
const baseVariants = ['100', '200', '300', 'content'];
Object.entries(tokens.color).forEach(([category, themes]) => {
if (category === 'base') {
expect(Object.keys(themes.light)).toEqual(expect.arrayContaining(baseVariants));
expect(Object.keys(themes.dark)).toEqual(expect.arrayContaining(baseVariants));
} else {
expect(Object.keys(themes.light)).toEqual(expect.arrayContaining(requiredVariants));
expect(Object.keys(themes.dark)).toEqual(expect.arrayContaining(requiredVariants));
}
});
});
});
});
Integración Nx y Automatización: Creamos targets de build eficientes usando Nx:
- Pipeline
clean
→build:tokens
→publish:tokens
- Gestión automatizada de versiones y publicación npm
- Builds cacheables para eficiencia de monorepo
Pipeline de Build
{
"targets": {
"clean": {
"executor": "nx:run-commands",
"options": {
"command": "rm -rf dist",
"cwd": "packages/libs/design-tokens"
}
},
"build:tokens": {
"executor": "nx:run-commands",
"dependsOn": ["clean"],
"options": {
"command": "style-dictionary build",
"cwd": "packages/libs/design-tokens"
}
},
"publish:tokens": {
"executor": "nx:run-commands",
"dependsOn": ["build:tokens"],
"options": {
"command": "npm publish",
"cwd": "packages/libs/design-tokens"
}
}
}
}
Ejemplos de Uso
En CSS
.button {
background-color: var(--color-primary-light-default);
color: var(--color-primary-light-content);
border-radius: var(--design-radius-field);
}
@media (prefers-color-scheme: dark) {
.button {
background-color: var(--color-primary-dark-default);
color: var(--color-primary-dark-content);
}
}
En React/TypeScript
import {
ColorPrimaryLightDefault,
ColorPrimaryLightContent,
DesignRadiusField
} from '@codigo-obsidiana/design-tokens';
const Button: React.FC = () => (
<button
style={{
backgroundColor: ColorPrimaryLightDefault,
color: ColorPrimaryLightContent,
borderRadius: DesignRadiusField,
}}
>
Haz clic aquí
</button>
);
Cambio de Tema
// Cambiar temas dinámicamente
const applyTheme = (theme: 'light' | 'dark') => {
const root = document.documentElement;
if (theme === 'dark') {
root.style.setProperty('--color-primary-default', ColorPrimaryDarkDefault);
root.style.setProperty('--color-primary-content', ColorPrimaryDarkContent);
} else {
root.style.setProperty('--color-primary-default', ColorPrimaryLightDefault);
root.style.setProperty('--color-primary-content', ColorPrimaryLightContent);
}
};
Resultados
Experiencia de Desarrollador Mejorada: Consumo de tokens type-safe con soporte completo de intellisense y validación en tiempo de ejecución, reduciendo inconsistencias de diseño en un 95% entre equipos de desarrollo.
Optimización de Performance: CSS Custom Properties permiten tematización dinámica sin overhead de JavaScript, mientras que las exportaciones ES6 tree-shakeable optimizan tamaños de bundle en aplicaciones JavaScript.
Mejoras de Accesibilidad: El espacio de color OKLCH proporciona capacidades superiores de cálculo de contraste, asegurando cumplimiento WCAG con relaciones de color matemáticamente predecibles.
Mantenimiento Escalable: El enfoque de única fuente de verdad redujo el overhead de mantenimiento de tokens en un 80%, con validación automatizada previniendo que valores de color inválidos entren a producción.
Consistencia Cross-Platform: La distribución unificada de tokens asegura consistencia de diseño pixel-perfect entre React, CSS e implementaciones futuras de plataformas.
Visuales
