Flujo de trabajo completo
Flujo de trabajo completo
El proyecto: Dashboard de analytics
En este capítulo construiremos el diseño de un dashboard de analytics para un ecommerce, aplicando todo lo aprendido en los capítulos anteriores. Al final tendremos:
- Un archivo
.opcon el diseño completo - Variables de diseño organizadas
- Componentes reutilizables
- Código React exportado e integrado
- Soporte para dark mode
- Integración con Claude Code via MCP
flowchart LR
A[Brief del proyecto] --> B[Diseño con IA en OpenPencil]
B --> C[Refinamiento manual]
C --> D[Componentes y variables]
D --> E[Exportación a React]
E --> F[Integración con Claude Code]
F --> G[Revisión colaborativa]
G --> H[Entrega final]
Fase 1: Preparación del entorno
Crear la estructura del proyecto
# Crear el directorio del proyecto
mkdir mi-dashboard && cd mi-dashboard
# Inicializar el proyecto React
bun create vite . --template react-ts
bun install
# Agregar Tailwind CSS v4
bun add tailwindcss @tailwindcss/vite
# o con shadcn
bunx shadcn@latest init
# Crear directorio de diseños
mkdir designs
# Inicializar Git
git init
echo "node_modules/\ndist/" > .gitignore
Crear el documento de diseño
# Crear el documento de OpenPencil
op new designs/dashboard.op
# Definir los brand tokens iniciales
op config set \
--file designs/dashboard.op \
--brand '{
"colorPrimary": "#2563EB",
"colorSecondary": "#7C3AED",
"fontHeading": "Inter",
"fontBody": "DM Sans",
"borderRadius": 8,
"spacingBase": 4
}'
Configurar el MCP para el proyecto
// .cursor/mcp.json (o ~/.claude/settings.json)
{
"mcpServers": {
"openpencil": {
"command": "op",
"args": [
"mcp", "start", "--stdio",
"--file", "./designs/dashboard.op",
"--config", ".openpencil/config.json"
]
}
}
}
// .openpencil/config.json
{
"workspace": "./designs",
"brandTokens": {
"colorPrimary": "#2563EB",
"colorSecondary": "#7C3AED",
"fontHeading": "Inter",
"fontBody": "DM Sans",
"borderRadius": 8
},
"exportDefaults": {
"framework": "react",
"typescript": true,
"outputDir": "./src/components/generated"
}
}
Fase 2: Diseño del sistema de tokens
Antes de diseñar las pantallas, establecemos el sistema de variables. Este paso es crucial y normalmente se subestima.
Generar tokens con IA
Abre OpenPencil y en el chat (Cmd+J):
/brand-setup:
Crea un sistema completo de design tokens para un dashboard de analytics
de ecommerce. El branding es: moderno, confiable, datos-oriented.
Color primario: #2563EB (azul corporativo).
Color secundario: #7C3AED (purple para highlights).
Por favor crea las siguientes colecciones de variables:
1. Primitives: paletas completas de azul, purple, slate, green, red, amber
2. Semantic: colores semánticos para background, text, border, status, actions
3. Typography: escala tipográfica con Inter (headings) y DM Sans (body)
4. Spacing: escala basada en múltiplos de 4 (desde 4px hasta 64px)
5. Shadows: 4 niveles de elevación
Genera también las variantes para dark mode en cada colección.
El agente crea automáticamente todas las variables en el panel de Variables del documento.
Exportar tokens al proyecto
# Exportar tokens a CSS
op tokens export designs/dashboard.op \
--format css \
--out src/styles/tokens.css
# Exportar configuración para Tailwind
op tokens export designs/dashboard.op \
--format tailwind \
--out tailwind.tokens.js
Agrega los tokens a tu configuración de Tailwind:
/* src/index.css */
@import "tailwindcss";
@import "./styles/tokens.css";
@theme {
--color-primary-*: initial;
--font-sans: "DM Sans", sans-serif;
--font-display: "Inter", sans-serif;
}
Fase 3: Diseño del dashboard con IA
Con los tokens configurados, diseñamos las pantallas. Vamos a usar el flujo de 3 capas del agente.
Diseñar el layout principal
En el chat de OpenPencil:
/multi:
Diseña el dashboard de analytics de ecommerce.
Tamaño de pantalla: 1440x900px.
Usa las variables de diseño ya creadas.
El dashboard debe tener:
[SIDEBAR DE NAVEGACIÓN]
- Ancho: 260px, altura: 100%
- Logo de la app arriba
- Sección principal: Dashboard, Productos, Pedidos, Clientes, Analytics, Configuración
- Icono + label para cada item
- Item activo destacado
- Perfil del usuario en la parte inferior
[HEADER]
- Altura: 72px
- Breadcrumb a la izquierda
- Barra de búsqueda global en el centro
- Notificaciones + perfil a la derecha
[ÁREA PRINCIPAL]
- Grid de métricas: 4 KPI cards en la primera fila
* Ventas del mes: $48,234 (+12.5% vs mes anterior)
* Pedidos totales: 1,284 (+8.2%)
* Clientes nuevos: 342 (-2.1%)
* Tasa de conversión: 3.24% (+0.8%)
- Segunda fila: Gráfica de ventas (70%) + Pedidos recientes (30%)
- Tercera fila: Top productos (50%) + Actividad reciente (50%)
Usa los colores semánticos de las variables.
Fondo del sidebar: $color/surface/sidebar
Fondo del área principal: $color/background
El agente lanza múltiples sub-agentes en paralelo:
- Agente Sidebar
- Agente Header
- Agente KPI Cards
- Agente Charts Section
- Agente Tables Section
Después de ~2-3 minutos, tendrás el diseño completo en el canvas.
Refinar manualmente
Después del diseño automático, hay ajustes que el ojo humano hace mejor:
- Jerarquía visual: Revisa que los elementos más importantes tengan más peso visual
- Consistencia de espaciado: Verifica que los gaps sigan la escala de tokens
- Micro-detalles: Ajusta line-heights, letter-spacings, shadow intensities
- Hover states: Añade notas de prototipo para estados interactivos
[Selecciona el KPI card de Ventas]
"Agrega un sparkline (mini gráfica de línea) en la parte inferior de
este card mostrando la tendencia de los últimos 7 días.
Usa el color $color/status/success para la línea cuando la tendencia
es positiva."
Diseñar el modo oscuro
Con el diseño en light mode completado:
"Tengo el diseño del dashboard en modo claro.
Ahora crea la versión en modo oscuro:
1. Agrega una nueva página llamada 'Dark Mode'
2. Copia el diseño completo de la página 'Light Mode'
3. Cambia todos los nodos al modo 'dark' de las variables
4. Ajusta los gráficos y charts para que sean legibles en oscuro
5. Asegura que los contrastes cumplan WCAG AA"
Fase 4: Crear los componentes del sistema
Extraemos los elementos reutilizables como componentes:
Extraer componentes automáticamente
"Analiza el diseño del dashboard y extrae como componentes:
1. KPICard (con variantes para positivo/negativo/neutral)
2. SidebarItem (activo/inactivo)
3. DataTable (headers + rows)
4. MetricBadge (verde/rojo/gris)
5. UserAvatar (sm/md/lg)
6. SearchBar
Para cada componente:
- Crea el componente maestro en la página 'Components'
- Define las props necesarias
- Vincula a las variables de diseño
- Reemplaza los elementos inline en el dashboard por instancias del componente"
Organizar la librería
Después de crear los componentes, la estructura del documento debe ser:
dashboard.op
├── Página: Components
│ ├── KPICard/Positive
│ ├── KPICard/Negative
│ ├── KPICard/Neutral
│ ├── SidebarItem/Active
│ ├── SidebarItem/Inactive
│ ├── DataTable
│ ├── MetricBadge/Success
│ ├── MetricBadge/Error
│ ├── MetricBadge/Neutral
│ ├── UserAvatar/sm
│ ├── UserAvatar/md
│ ├── UserAvatar/lg
│ └── SearchBar
├── Página: Dashboard (Light)
└── Página: Dashboard (Dark)
Fase 5: Exportar a React con Claude Code
Ahora usamos Claude Code con el MCP de OpenPencil para exportar los componentes e integrarlos en el proyecto React.
Sesión de trabajo en Claude Code
Abre el archivo designs/dashboard.op.
Necesito exportar todos los componentes de la página 'Components'
a React con TypeScript y Tailwind CSS.
Por favor:
1. Exporta cada componente a src/components/generated/
2. Para KPICard, agrega el tipo de datos que debería recibir como props
3. Para DataTable, genera una versión genérica que acepte cualquier tipo de datos
4. Genera también el archivo src/styles/tokens.css con todas las variables
Después de exportar, crea un archivo de barrel export en
src/components/generated/index.ts que re-exporte todos los componentes.
Claude usará las herramientas MCP:
1. open_file(designs/dashboard.op)
2. list_pages() → [Components, Dashboard Light, Dashboard Dark]
3. get_page_tree(Components) → lista de todos los componentes
4. Para cada componente:
- get_node(componentId) → propiedades completas
- export_react({componentId, options}) → código TypeScript
5. Escribe cada archivo en src/components/generated/
6. Crea el barrel index.ts
7. export_tokens({format: "css"}) → src/styles/tokens.css
El código generado
// src/components/generated/KPICard.tsx
import { cn } from '@/lib/utils'
import { TrendingUp, TrendingDown, Minus } from 'lucide-react'
type Trend = 'positive' | 'negative' | 'neutral'
interface KPICardProps {
title: string
value: string
change: number
trend: Trend
period?: string
className?: string
}
const trendConfig = {
positive: {
icon: TrendingUp,
textColor: 'text-green-600 dark:text-green-400',
bgColor: 'bg-green-50 dark:bg-green-900/20',
},
negative: {
icon: TrendingDown,
textColor: 'text-red-600 dark:text-red-400',
bgColor: 'bg-red-50 dark:bg-red-900/20',
},
neutral: {
icon: Minus,
textColor: 'text-slate-500',
bgColor: 'bg-slate-50 dark:bg-slate-800',
},
}
export function KPICard({ title, value, change, trend, period = 'vs mes anterior', className }: KPICardProps) {
const { icon: Icon, textColor, bgColor } = trendConfig[trend]
return (
<div className={cn('bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl p-6', className)}>
<p className="text-sm font-medium text-slate-500 dark:text-slate-400">{title}</p>
<p className="text-3xl font-bold text-slate-900 dark:text-slate-100 mt-2">{value}</p>
<div className={cn('flex items-center gap-1 mt-3 px-2 py-1 rounded-full w-fit', bgColor)}>
<Icon className={cn('w-3.5 h-3.5', textColor)} />
<span className={cn('text-xs font-semibold', textColor)}>
{change > 0 ? '+' : ''}{change}%
</span>
</div>
<p className="text-xs text-slate-400 mt-2">{period}</p>
</div>
)
}
Crear la página Dashboard en React
Usando los componentes generados en src/components/generated/,
crea la página principal del dashboard en src/pages/Dashboard.tsx.
La página debe:
- Usar los componentes KPICard, DataTable, SidebarItem
- Tener datos mockeados realistas para el ecommerce
- Implementar el toggle de dark mode
- Ser responsive (sidebar colapsable en mobile)
- Usar React Query para simular el fetching de datos
Fase 6: Sesión de revisión colaborativa
Con el diseño y el código listos, organizamos una sesión de revisión con el equipo.
Iniciar la sesión colaborativa
# Persona que lidera la revisión
op collab start designs/dashboard.op --role owner
# Output:
# Room ID: dashboard-review-2026
# Link: https://app.openpencil.dev/room/dashboard-review-2026
# Comparte este link con tu equipo
Compartir con el equipo
Envía el link por Slack/Teams. Los participantes abren el link en el navegador y ven el mismo canvas en tiempo real.
Estructura de la revisión
sequenceDiagram
participant PD as Product Designer
participant DE as Dev Engineering
participant PM as Product Manager
PD->>todos: Presenta el diseño con viewport following
PM->>PD: Comenta: "KPICard necesita tooltip con detalle"
PD->>canvas: Agrega nota de comentario
DE->>PD: Comenta: "¿El DataTable es sorteable?"
PD->>canvas: Agrega anotación de interacción
DE->>canvas: Selecciona un componente
DE->>PD: "Este spacing parece incorrecto, ¿40px o 48px?"
PD->>canvas: Corrige el spacing en vivo
todos->>PD: Aprueba el diseño
Después de la revisión
# Resolver todos los comentarios aprobados
op comments resolve-all designs/dashboard.op
# Guardar estado final
# Cmd+S en OpenPencil
# Commit del diseño
git add designs/dashboard.op
git commit -m "feat: diseño de dashboard revisado y aprobado"
Fase 7: Integración continua del diseño
Configura el pipeline CI para que al cambiar el diseño se actualice el código automáticamente.
GitHub Actions completo
# .github/workflows/design-sync.yml
name: Design Sync
on:
push:
branches: [main]
paths:
- 'designs/*.op'
jobs:
lint-and-export:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
- name: Install OpenPencil CLI
run: bun install -g @zseven-w/openpencil
- name: Lint design files
run: |
op lint designs/dashboard.op \
--rules accessibility,tokens,spacing \
--format json > lint-report.json
ERRORS=$(jq '.errors | length' lint-report.json)
if [ "$ERRORS" -gt "0" ]; then
echo "❌ Design lint failed"
jq '.errors[]' lint-report.json
exit 1
fi
- name: Export tokens
run: |
op tokens export designs/dashboard.op \
--format css --out src/styles/tokens.css
- name: Export components
run: |
op export react \
--file designs/dashboard.op \
--page Components \
--out src/components/generated \
--typescript \
--extract-components
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Install dependencies
run: bun install
- name: Type check
run: bun tsc --noEmit
- name: Commit generated code
run: |
git config user.name "Design Bot"
git config user.email "[email protected]"
git add src/components/generated/ src/styles/tokens.css
git diff --staged --quiet || \
git commit -m "chore: sync design components from dashboard.op [skip ci]"
git push
Atajos de teclado para productividad máxima
Dominar los atajos es la diferencia entre un flujo de trabajo fluido y uno interrumpido. Aquí los más importantes para el trabajo diario:
Canvas y selección
| Atajo | Acción |
|---|---|
V | Herramienta de selección |
K | Escalar (mantiene proporciones relativas) |
H | Pan del canvas |
Cmd+A | Seleccionar todo |
Escape | Deseleccionar / subir nivel |
Tab | Seleccionar siguiente sibling |
Shift+Tab | Seleccionar sibling anterior |
Enter | Entrar al grupo/frame/componente |
Cmd+click | Seleccionar nodo específico en un grupo |
Herramientas de creación
| Atajo | Herramienta |
|---|---|
R | Rectángulo |
O | Elipse |
T | Texto |
P | Pen / Bezier |
L | Línea |
F | Frame |
C | Comentario |
Organización
| Atajo | Acción |
|---|---|
Cmd+G | Agrupar selección |
Cmd+Shift+G | Desagrupar |
Cmd+Alt+K | Crear componente |
Cmd+] | Traer al frente |
Cmd+[ | Enviar atrás |
Cmd+Alt+] | Traer al frente del todo |
Cmd+Alt+[ | Enviar atrás del todo |
Cmd+Shift+H | Ocultar/mostrar |
Cmd+Shift+L | Bloquear/desbloquear |
IA y colaboración
| Atajo | Acción |
|---|---|
Cmd+J | Abrir/cerrar chat IA |
Cmd+, | Preferencias / Config agentes |
Shift+A | Activar auto-layout |
Cmd+Alt+U | Booleana: Unión |
Cmd+Alt+S | Booleana: Sustracción |
Cmd+Alt+I | Booleana: Intersección |
Exportación rápida
| Atajo | Acción |
|---|---|
Cmd+E | Exportar selección (abre dialog) |
Cmd+Shift+E | Exportar página completa |
Mejores prácticas consolidadas
Para el diseño
-
Tokens primero: Nunca empieces a diseñar sin tener las variables de color y tipografía definidas. Los tokens son el contrato entre diseño y código.
-
Auto-layout siempre: Todo frame con children debe tener auto-layout. El posicionamiento absoluto es la excepción, no la regla.
-
Nombra todo: Cada nodo debe tener un nombre descriptivo. Los nombres genéricos como “Rectangle 3” son deuda técnica de diseño.
-
Componentes desde el primer uso repetido: Si usas el mismo elemento dos veces, hazlo componente. No esperes a la tercera vez.
-
8 point grid: Usa múltiplos de 8 para todos los espaciados principales. Para excepciones menores, múltiplos de 4.
Para la IA
-
Sé específico con el contexto del dominio: El agente genera mejores resultados cuando entiende el negocio (ecommerce, SaaS, healthcare, etc.)
-
Usa
/brand:antes de tareas grandes: Establecer el contexto de marca al inicio ahorra correcciones posteriores. -
Itera en capas: Primero la estructura, luego el contenido, luego los estilos. No pidas todo a la vez.
-
Selecciona antes de modificar: Selecciona los nodos relevantes antes de enviar un prompt. El agente usa tu selección como contexto.
-
Nombra tus templates de prompts: Para diseños que repites (ej: cards de contenido), guarda los prompts como templates con
op prompt save.
Para el código
-
Separa código generado del manual:
src/components/generated/para lo generado,src/components/para tus extensiones. -
Vincula tokens al código desde el día 1: Un token cambiado en el diseño debe reflejarse automáticamente en el código.
-
Commitea el
.opcon el código: El diseño y el código son parte del mismo cambio. Commitéalos juntos. -
Lintea en el CI: El lint de diseño (
op lint) es tan importante como el lint de código.
Para la colaboración
-
Sesión P2P para sincrónico, Git para asincrónico: Usa la colaboración en tiempo real para revisiones y discusiones. Usa Git para el flujo asincrónico normal.
-
Resuelve comentarios antes del commit: Los comentarios abiertos son pendientes de trabajo, como los TODO en el código.
-
Viewport following para demos: Cuando presentes el diseño, haz que el equipo te siga con viewport following.
Checklist de entrega de diseño
Antes de considerar un diseño listo para implementación:
- Todos los colores vinculados a variables semánticas
- Todos los tamaños de fuente en la escala tipográfica
- Todos los espaciados en múltiplos de 4 u 8
- Auto-layout en todos los frames con children
- Todos los estados documentados: default, hover, focus, disabled, loading, error
- Versión desktop Y mobile (si aplica)
- Dark mode (si el proyecto lo requiere)
- Contraste de colores cumple WCAG AA (mínimo 4.5:1 para texto)
-
op lintpasa sin errores - Componentes extraídos y organizados en la página Components
- Comentarios de revisión resueltos
- Archivo
.opcommiteado al repositorio
Resumen del tutorial completo
A lo largo de estos 10 capítulos has aprendido:
- Qué es OpenPencil y por qué importa para desarrolladores: open-source, AI-native, programable
- Instalación en todas las plataformas y configuración del entorno
- Herramientas del canvas: formas, Bezier, texto, auto-layout, operaciones booleanas
- IA integrada: chat, 90+ herramientas, flujo skeleton→content→refine, agentes concurrentes
- CLI
op: automatización, batch design, CI/CD, linting de diseño - MCP Server: integrar OpenPencil con Claude Code, Cursor y Windsurf
- Exportación de código: React, Vue, Svelte, Flutter, SwiftUI, React Native
- Colaboración P2P: WebRTC, Yjs CRDT, rooms, cursores en tiempo real
- Sistema de componentes: maestros, instancias, variables, temas, variantes
- Flujo completo: de brief a producción con un proyecto real
OpenPencil no es solo un editor de diseño. Es la infraestructura para un flujo de trabajo donde diseño y código son una sola disciplina.
El futuro del desarrollo frontend es un ciclo continuo donde el diseñador y el desarrollador (a veces la misma persona, asistida por IA) trabajan en el mismo artefacto, con las mismas herramientas, sin fricción de traspaso.
OpenPencil es esa herramienta.