¡Gracias por tu interés en contribuir! Este documento explica los pasos y el flujo de trabajo para contribuir a nuestro design system.
Es obligatorio tener instalado:
- Node.js (usa la versión especificada en
.nvmrc) - nvm o nvm-windows para gestionar versiones de Node.
- pnpm como gestor de paquetes.
- Clona el repositorio:
git clone https://github.com/Stack-and-Flow/design-system.git cd design-system - Establece la versión correcta de Node:
nvm use
- Instala las dependencias:
pnpm install
- Inicia Storybook:
pnpm run storybook
El design system usa Space Grotesk Variable, cargada vía @fontsource-variable/space-grotesk. Se incluye como dependencia npm normal y estará disponible automáticamente después de pnpm install.
La documentación del repo es bilingüe por pares:
*.mdbase: español.*.en.md: inglés.
Si cambiás una guía, mantené ambos archivos alineados cuando exista el par. No reemplaces el archivo base español por prosa en inglés; el contenido inglés vive en el archivo .en.md correspondiente. Storybook, código, comentarios técnicos, identificadores y nombres públicos siguen en inglés.
El flujo canónico para componentes está en CONTRIBUTOR-FLOW.md. Este documento solo resume las reglas principales.
Todo componente DEBE seguir estrictamente la arquitectura Atomic Design + Container/Presentational (detallada en GUIDELINES.md).
- Determina el nivel correcto: Decide si es un
atom,moleculeuorganism. - Crea la estructura: Si creas un átomo
Button, la estructura DEBE ser exactamente:src/components/atoms/button/ ├── types.ts # Tipos, props públicas, JSDoc controls y variantes CVA ├── useButton.ts # Capa Container: lógica, estado, refs, handlers ├── Button.tsx # Capa Presentacional: solo JSX ├── Button.test.tsx # Tests de hook y comportamiento ├── Button.stories.tsx # Documentación Storybook └── index.ts # Re-exportaciones - Implementa en orden:
types.ts→ hook → componente → tests → stories →index.ts. - Revisa antes del PR: ejecuta la review pre-PR del componente definida en
CONTRIBUTOR-FLOW.md.
Storybook es nuestra única fuente de verdad. Todo componente DEBE estar completamente documentado.
- Inglés obligatorio: toda la documentación de Storybook va en inglés, incluidos headings de docs, descripciones, comentarios, nombres de stories y labels.
- Controls y Args: DEBES definir
controlsmediante JSDoc entypes.tsy establecerargspor defecto en.stories.tsx. - Descripción en Docs: DEBES incluir un bloque JSDoc encima de
const metacon esta estructura:## Descriptionobligatorio.## Dependenciessolo si usa otros componentes o primitives externas.## Usage Guidesolo si la utilización es compleja.
- Docs por story: cada
export const StoryNamenecesita JSDoc útil que explique el escenario y por qué importa. No uses texto de relleno que solo repite el nombre de la story. - Sin stories redundantes: cada story debe demostrar un estado, eje de variante, restricción de composición, comportamiento de accesibilidad o contexto de integración distinto.
- Sin story genérica
DarkMode: usa el toolbar dark-mode de Storybook para cobertura normal de tema. Añadí una story dark-mode dedicada solo para scope dark local, herencia de tema en portales o una regresión específica que el toolbar no pueda expresar, y documentá esa razón en JSDoc. - Sin
parameters.docs.description.component: la documentación del componente vive en JSDoc encima deconst meta. - Sin
playfunctions: Las interacciones se testean enComponentName.test.tsx, no en stories.
Las stories son documentación viva, no la suite de tests. Los tests de interacción y comportamiento viven en ComponentName.test.tsx.
Antes de abrir un PR, verifica:
- El hook está testeado con
renderHookcuando contiene lógica. - El componente está testeado con
render/screen/userEvent. - Hay cobertura de ARIA, teclado, disabled y estados relevantes.
- No se testean strings internos de clases CSS como contrato principal.
-
npm test -- --run src/components/.../ComponentName.test.tsxpasa.
maines la rama base. Todos los PRs apuntan amain.- Si la tarea viene de una issue, usa:
{type}/{issue-number}-{slug}(por ejemplofeat/123-button). - Si además trabajás con worktree, usa el sibling worktree correspondiente:
../design-system-{type}-{issue-number}-{slug}. - Para el flujo completo de naming, START WORK y END WORK, consulta
CONTRIBUTOR-FLOW.md.
Seguimos estrictamente Conventional Commits. El hook commit-msg ejecuta commitlint automáticamente y rechaza cualquier commit que no respete el formato.
Formato obligatorio:
<type>(<scope opcional>): <descripción>
Ejemplos válidos:
feat(button): add loading state
fix(calendar): correct keyboard navigation
chore(infra): update lint tooling
docs: update contribution guide
Tipos frecuentes:
feat:para nuevas funcionalidades o componentes.fix:para corrección de bugs.chore:para herramientas, dependencias, etc.docs:para actualizaciones de documentación.refactor:para cambios de código que no corrigen un bug ni añaden funcionalidad.style:para formato, punto y coma omitidos, etc.test:para añadir o corregir tests.
Antes de crear un commit, puedes validar un mensaje manualmente:
echo "feat(button): add loading state" | pnpm exec commitlint- Antes de implementar desde una issue, verificá que la spec esté definida, que la issue tenga el label
status:approvedy que no esté asignada a otra persona; recién ahí corré START WORK: verificar assignees, asignar la issue, moverla aIn progressy registrar branch/worktree. - Sube tu rama y abre un PR contra
main. - Usa un título de PR con el mismo formato Conventional Commit, por ejemplo
feat(button): add loading state. - Puedes pedir revisión automática a Copilot hasta que esté listo para revisión humana.
- El PR DEBE pasar todos los checks de CI, incluidos tests, build de Storybook, accesibilidad y escaneos de seguridad.
- El PR DEBE ser revisado por al menos un maintainer antes de hacer merge.
- Marca la tarea como
Donesolo mediante END WORK después de PR merged o aprobación explícita del maintainer/usuario.
Antes de pedir revisión, verifica:
- El componente sigue la arquitectura de 6 archivos perfectamente.
- No se usa
interface(solotype). Sinany. - Storybook contiene
args,controlsy un bloque JSDoc encima deconst meta. -
## Descriptionestá presente;## Dependenciesy## Usage Guidese usan solo cuando aplican. - Los componentes interactivos tienen tests en
.test.tsx. - La review pre-PR del componente está pasada o documentada.
- Se usan tokens de
theme.css(sin colores ni espaciados hardcodeados). - Se implementan atributos ARIA en elementos interactivos.
- Se usan Conventional Commits en mensajes de commit y título del PR.
- Los checks de seguridad pasan o los falsos positivos están documentados en el PR.
- Estados visuales implementados: hover, focus, active/pressed, disabled.
- Focus visible vía utilidad compartida
focus-ring(outline: 2px solid var(--color-primary), offset2px) — nuncaoutline: nonesinfocus-visible:focus-ringo equivalente. - Disabled via
opacity: 0.4— sin sustitución de color. - Sin
transition: all— propiedades específicas enumeradas. - Altura visual alineada con la escala semántica que aplique (
controlpara acciones,form-fieldpara campos);touch-target-min(44px) reservado para superficies touch-first o wrappers de hit area. Variantes compactas/densas documentadas pueden ser menores si conservan accesibilidad por teclado/focus. - Limpieza MCP hecha antes de commit/review:
rm -rf .playwright-mcp page-*.png page-*.jpeg *.md.playwright-output.
Los pull requests ejecutan audit de dependencias y escaneo de secretos antes del merge. Consulta SECURITY.md para ver la política, los pasos de remediación y el manejo de falsos positivos.
Sí. Los contributors pueden usar herramientas asistidas por IA (GitHub Copilot, opencode/gentle-ai, Cursor, etc.) en este proyecto.
Sin embargo, dos reglas son innegociables:
- El resultado DEBE cumplir todos los estándares del proyecto — independientemente de cómo se haya generado. Si la IA produjo código que incumple GUIDELINES.md, corrígelo antes de abrir un PR.
- Eres responsable de cada línea en tu PR, generada por IA o no. "Lo escribió la IA" no es una razón válida para saltarse el checklist del PR.
Si usas opencode, este proyecto incluye AGENTS.md — un archivo de contexto que se inyecta automáticamente en todos los agentes al abrir el proyecto.
Los agentes ya conocerán:
- La arquitectura de 6 archivos y dónde corresponde cada pieza de lógica
- Qué tokens de diseño usar (y qué valores hardcodeados evitar)
- Las reglas de Storybook y la estructura requerida de stories
- La lista completa de anti-patrones que provocan rechazo de PR
Para activarlo: simplemente abre el directorio del proyecto en opencode. No se requiere configuración manual — el contexto se carga automáticamente.
Las skills compartidas del equipo viven en skills/. El directorio .atl/ es estado local generado por gentle-ai — registry/cache — y debe permanecer ignorado porque puede mezclar skills del proyecto con skills personales del usuario.
Al usar gentle-ai (opencode), el agente sigue component-contributor. El flujo completo y canónico está en CONTRIBUTOR-FLOW.md.
Resumen de fases:
- Research — investigas referencias, API, estados, accesibilidad y diseño.
- Spec proposal — usas
component-spec-proposerpara convertir la tarea y referencia en una spec validada en la issue. - Approval gate — una vez escrita la spec, esperas el label
status:approveden la issue; sin ese label no hay START WORK ni implementación bajo ningún concepto. - Assignee gate — antes de cualquier acción sobre una issue linkeada, verificas assignees; si está asignada a otra persona, hace falta permiso explícito antes de reasignarla.
- START WORK — después del label
status:approvedy el assignee gate, asignas la issue, la mueves aIn progressy registras branch/worktree. - Spec intake — con START WORK ya completado,
component-contributorlee la sección## Validated component specsin inventar comportamiento. - Review de spec — el agente critica gaps, riesgos e inconsistencias antes de planificar.
- Prefase visual — el agente alinea tokens, superficie, estados, focus, transición y dark mode antes del plan.
- Plan — revisas y apruebas archivos, variantes, tests, stories y accesibilidad.
- Implementación — el agente crea los 6 archivos y explica decisiones.
- Visual review — se corrigen issues CRITICAL o MAJOR antes de continuar.
- Review pre-PR —
components-auditorvalida arquitectura, tests, Storybook, tokens, visual y accesibilidad antes de abrir PR. - END WORK — al cerrar, la tarea pasa a
Donesolo con PR merged o aprobación explícita, más evidencia de validación.
Para activar el flujo completo, primero pedí la spec con
component-spec-proposer; después de validarla, esperástatus:approved, verificá que la issue no esté asignada a otra persona, compartí la URL de la issue y decí "implementa este componente".
Si usas una herramienta de IA, no le permitas:
- Modificar los tokens de
src/styles/theme.csssin tu aprobación explícita - Añadir nuevas dependencias
npmopnpmsin discutirlo - Saltarse la estructura de 6 archivos en favor de un enfoque de un solo archivo "más simple"
- Escribir stories sin args, controls o un bloque JSDoc encima de
const meta - Usar
interfaceen lugar detype, o introducir tiposany
Si la IA propone alguna de estas cosas, recházala y redirigela al patrón correcto.
El código generado por IA pasa por el mismo proceso de revisión exacto que el código escrito por humanos. Sin excepciones.
Antes de pedir revisión en un PR asistido por IA:
- Repasa el checklist del PR como lo harías con cualquier contribución
- Ejecuta la review pre-PR del componente y documenta la evidencia
- Corrige todo issue CRITICAL o MAJOR antes de pedir revisión
- Si se incumple una guía, el PR será rechazado independientemente del autor
- Bugs: Abre un issue usando la plantilla de reporte de bugs. Incluye pasos para reproducir, comportamiento esperado y capturas si aplica.
- Proponer componentes: Antes de escribir código, propón el componente en el GitHub Projects Board o abre un issue de Feature Request para discutir la API y los requisitos con el Project Lead.
- Demo de Storybook: sf-design-system.netlify.app
- GitHub Projects (Kanban): Project Board
- Guidelines: GUIDELINES.md
- Quick Start: QUICK_START.md
- Gobernanza: GOVERNANCE.md