Sistema de Diseño
La misma experiencia en tres etapas. El orquestador pasa mode de forma explícita.
| Modo | Cuándo | Pregunta |
|---|---|---|
| PLAN | fase de desarrollo de funcionalidad 2 | ¿Qué patrones/abstracciones debería usar esta funcionalidad? |
| BUILD | fase de desarrollo de funcionalidad 4 | Aplicar las decisiones de PLAN mientras se implementa. |
| REVIEW | fase de desarrollo de funcionalidad 5 | ¿La implementación realmente las sigue? |
Por defecto, usar REVIEW cuando el modo no está especificado y existe un diff de rama. Por defecto, usar PLAN cuando el modo no está especificado y aún no hay diff.
Modo PLAN
Antes de que exista el código. Entradas: brief de refinamiento, nodo de Figma o captura de pantalla, rutas en alcance.
- Buscar en pattern-library (
src/index.ts,src/theme.ts,src/core/) y app-pro-ui funcionalidades similares. - Ejecutar la prueba de abstracción (abajo) en cada elemento importante de la interfaz de usuario del diseño.
- Para cada elemento: dejar local | API de PL existente | token/variante | PR de PL necesario — con rutas citadas.
- Señalar la secuenciación de PL (PR de PL antes/paralelo con app-pro-ui) y la falta de copia/recursos.
Si no hay superficie de IU: devolver No aplicable (sin IU) en una línea.
Salida: # Sistema de diseño (PLAN): [funcionalidad] — lista de reutilización, cambios prospectivos, secuenciación. No se requiere diff de rama.
Modo BUILD
Durante la implementación. Entradas: salida de PLAN del sistema de diseño, archivos que se están editando.
- Aplicar las decisiones de PLAN: usar componentes/tokens de PL nombrados; respetar las llamadas de dejar local.
- Seguir la capa de razonamiento a continuación — no recrear aspectos reutilizables en el código de la funcionalidad.
- Si PLAN es incorrecto dado lo que aprendes mientras codificas, documentar la desviación en el resumen de construcción; no desviarse en silencio.
Salida: ninguna requerida a menos que haya desviación — entonces anotar en el resumen de construcción.
Modo REVIEW
Después de la implementación. Escanear esta rama (app-pro-ui o pattern-library) en busca de decisiones de IU que deberían estar en el sistema de diseño. No solo digas "eliminar el estilo" o "usar un componente compartido". Preferir el cambio más pequeño global de la biblioteca de patrones que permita a cualquier funcionalidad hacer lo mismo—o recomendar dejar la implementación local cuando la abstracción no esté justificada.
Esto no significa "todos los estilos pertenecen a la biblioteca de patrones". Las decisiones repetidas de producto/UX deben codificarse cada vez más en el sistema para que los constructores individuales no las reinventen. El código de la funcionalidad aún puede componerse localmente.
Regla de arquitectura: Las decisiones visuales reutilizables pertenecen a la biblioteca de patrones. El código de la funcionalidad puede usar sx para diseño/composición genuinamente local, pero no debe recrear estilos de componentes reutilizables, tokens, estados o patrones de interacción. Evitar style, CSS personalizado y props heredados del sistema MUI cuando exista una API establecida de PL/MUI.
Esta habilidad es la capa de DS. Para la estructura de hook/util/grid e higiene de código genérica de app-pro-ui, usar la habilidad refactoring.
Capa de razonamiento
Juzgar cada hallazgo con estas reglas. Provienen de años de comentarios de revisión de la biblioteca de patrones y app-pro-ui. Preferir una API existente sobre una nueva. Mover código a la biblioteca de patrones no es automáticamente una mejora.
Prueba de abstracción
Ejecutar esto en cada receta candidata, token o nueva API. Es el juicio principal—la detección solo produce candidatos.
- ¿Es esta una composición local?
- ¿Aparece la misma receta en otro lugar?
- ¿Se supone que el componente ya posee esto?
- ¿Moverlo a la biblioteca de patrones reduciría decisiones futuras significativas?
- ¿Agregar una API realmente empeoraría la biblioteca de patrones?
La similitud por sí sola no justifica la abstracción. Dos fragmentos que se parecen pueden representar conceptos de producto diferentes. Preferir abstracciones compartidas cuando la misma decisión de producto/UX debe evolucionar junta.
sx no es el problema. La cuestión es dónde vive la decisión de diseño. El sx de token de tema es mejor que un hexadecimal. Una receta repetida puede pertenecer a la biblioteca de patrones. Un <Stack sx={{ mt: 2 }}> único generalmente no lo necesita. Si la prueba dice que la solución local es correcta, omitirla de los hallazgos—no listarla como Bajo.
1. Usar el sistema de diseño — no rediseñar decisiones reutilizables en la funcionalidad
- Preferir componentes establecidos de la biblioteca de patrones para patrones de producto reutilizables (
CardWithActionincluso sin acción,CardCTAFeaturedcomo tarjeta compuesta,DetailPanelToggle). No reconstruirlos desdeCarden bruto. - Preferir primitivas de composición de MUI como
Stack/Gridsobre CSS de diseño personalizado cuando el diseño es local. - Usar primitivas de diseño establecidas y valores predeterminados antes de inventar geometría local.
- Poner color, sombra y tratamientos de marketing/AI reutilizables en
pattern-library/src/theme.tscomo tokens moldeados por paleta (primary.main,ai.gradient.start). Preferir un token otheme.shadowssobre valores hexadecimales, rellenos o sombras codificados cuando el valor es una decisión de producto. - Usar
sx, no los props de estilo heredados de MUI. No agregar props con nombre de estilo en componentes compartidos para solucionar eso. Elsxlocal está bien cuando es composición, no una apariencia reutilizable. - Si una funcionalidad necesita una nueva apariencia que otras superficies compartirán (multimedia destacada, superposición expandida, superficies invertidas/de marketing), agregar un patrón o prop en la biblioteca de patrones.
2. Mantener los componentes compartidos genéricos
- No realizar cambios de padding, sidenav o gráficos específicos de una funcionalidad en componentes compartidos como
Card,PageSectiono exportaciones públicas deindex.ts. Acotar prototipos; revertir archivos no relacionados. Cambiar el elemento, no el marco, cuando solo el elemento es incorrecto. - Nombrar props para la reutilización (
footerDescription, no una etiqueta de una sola funcionalidad). El comportamiento adicional es opcional (números de línea, comas en un área de texto). - Preferir variantes de tema y
argsde Storybook sobre JSX bifurcado (verificaciones devariant === "marketing"). - No exportar gráficos u otros elementos internos de la biblioteca de patrones si las aplicaciones no los consumen.
- A largo plazo, envolver una superficie en un tema (ej. marketing) en lugar de pasar props visuales únicos a través de cada página.
3. QA visual en los bordes
- Verificar esquinas redondeadas, tarjetas de igual altura, texto envuelto huérfano, colapso del FAB móvil, z-index vs. paneles/modales, y si un control aún funciona sobre un fondo blanco.
- Preguntar si se requiere espaciado especial o si los estilos predeterminados ya coinciden con otros modales/páginas. No rellenar un encabezado compartido para alinearlo con un vecino desalineado—arreglar el vecino.
4. Cuestionar el requisito de diseño
Antes de agregar una capacidad de DS para soportar un diseño inusual, determinar si el diseño mismo debería ajustarse a un comportamiento de sistema establecido. No expandir el sistema de diseño meramente para codificar un requisito único cuestionable.
5. Resistir la superficie de API innecesaria
Cada abstracción de DS propuesta debe justificar la superficie de API que agrega. Mover código a la biblioteca de patrones no es automáticamente una mejora. La configuración que no mejora la experiencia es un costo de mantenimiento.
Mantener solo la higiene de arquitectura de DS: envoltorios innecesarios que interfieren con la composición, estilos duplicados, complejidad de API de componentes y lógica específica de funcionalidad en primitivas compartidas. Aplanar Box anidados cuando interrumpen la composición de Stack/sx. Usar abreviaturas de tema (background.main) en lugar de useTheme para tokens simples.
6. Entregar con la superficie relacionada
- Un cambio en la biblioteca de patrones que las aplicaciones deben consumir necesita un PR correspondiente en app-pro-ui o moz-ui y una forma de verificarlo (amplify/domain o equivalente).
- Confirmar la convención actual de paquete/versión desde el repositorio consumidor (
package.json, lockfile o documentos de instalación) antes de recomendar cómo incrementar. No asumir un estilo de pin. - No fusionar una primitiva compartida hasta que el PR de la aplicación consumidora esté listo.
Cuando se invoca (modo REVIEW)
Copiar y seguir:
Progreso de revisión:
- [ ] Hacer diff de esta rama contra la base de fusión
- [ ] Recopilar candidatos (no conclusiones)
- [ ] Agrupar por intención (misma decisión, no mismo código)
- [ ] Ejecutar la prueba de abstracción
- [ ] Buscar en la biblioteca de patrones un hogar existente
- [ ] Recomendar el cambio más pequeño — incluyendo dejar local / sin cambio de DS
- [ ] Reportar hallazgos; no implementar a menos que se solicite
No es obligatorio encontrar trabajo. Si el diff es apropiadamente local, decirlo y detenerse.
Paso 1: Escanear la rama
Inspeccionar esta rama vs su base de fusión. Detectar la rama predeterminada (git symbolic-ref refs/remotes/origin/HEAD o origin/main, luego main). Ejecutar desde el repositorio que tiene los cambios (app-pro-ui o pattern-library).
DEFAULT=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/@@')
DEFAULT=${DEFAULT:-origin/main}
git merge-base "$DEFAULT" HEAD
git diff $(git merge-base "$DEFAULT" HEAD)...HEAD -- '*.tsx' '*.ts' '*.jsx' '*.js' '*.css' '*.scss'
git diff --name-only $(git merge-base "$DEFAULT" HEAD)...HEAD
Buscar en las líneas agregadas candidatos:
Estilos
style=sx=styled(css`/css(makeStyles/createStyles/withStyles#hex,rgb(,rgba(,pxcodificados (investigar; no clasificar automáticamente)- Props heredados de Box:
display=,alignItems=,justifyContent=,flexDirection=
IU reinventada o desviada
Carden bruto donde encaja un patrón de tarjeta establecido (CardWithAction,CardCTAFeatured)- Controles de expandir personalizados en lugar de
DetailPanelToggle - CSS de diseño personalizado donde
Stack/Gridcompondría localmente - Geometría de página inventada donde las primitivas de diseño o los valores predeterminados ya establecen el ancho
- Sombras codificadas en lugar de
theme.shadowscuando la sombra es una apariencia compartida - Nuevas exportaciones públicas o ediciones de tema que solo sirven a una funcionalidad
Luego abrir cada acierto y leer el JSX circundante para determinar la intención. También capturar objetos sx asignados antes del JSX, etiquetas <style> y hojas de estilo importadas.
Ignorar .cursor/, node_modules/, .next/. Incluir código de funcionalidad, components/ compartidos, Storybook y src/theme.ts.
Paso 2: Detectar, luego juzgar
La detección es una heurística. La clasificación ocurre después de la prueba de abstracción.
| Detector | Tratar como | Ejemplos |
|---|---|---|
style= / styled( / css` / nuevo .css | Fuga candidata | <Card style={{ flexBasis: "50%" }}> |
| Valores visuales codificados que parecen codificar decisiones del sistema de diseño, especialmente color, espaciado, tipografía, radio, sombra y dimensiones repetidas | Token candidato | color: "#002F50"; investigar px antes de tratar como fuga |
sx={{ ... }} usando claves de tema | Receta candidata | sx={{ mt: 3, width: "100%" }} |
| Props heredados del sistema Box | Legado candidato | <Box display="flex" alignItems="center"> |
| Componente de PL existente no utilizado | Solución de sistema existente candidata | tabla no envuelta en CardWithAction |
| Edición específica de funcionalidad en un componente compartido | Fuga de alcance candidata | padding en CardHeader para coincidir con una historia |
| Prop o exportación de una sola funcionalidad | API no genérica candidata | prop de pie de página con nombre de funcionalidad; exportar gráficos no utilizados |
Investigar antes de clasificar valores codificados. Los casos locales legítimos incluyen dimensiones calculadas, geometría de gráficos, internos de iconos/lienzo, bordes, diseños virtualizados y restricciones intrínsecas de componentes.
Excepciones de último recurso (documentar por qué; no inventar una primitiva):
- Internos de terceros / lienzo / gráficos que no pueden usar props de la biblioteca de patrones
- Diseño de impresión/PDF sin primitiva de informe existente y verdaderamente único
- Archivos solo de prototipo que no se exportan desde la biblioteca de patrones
Los candidatos que pasan la prueba de abstracción como composición local no son hallazgos. Ponerlos bajo No promover solo si de otro modo se confundirían con lagunas. De lo contrario, omitirlos.
Paso 3: Agrupar por intención
Agrupar aciertos que expresan la misma decisión, no el mismo CSS o marcado de apariencia similar.
Intenciones típicas: color/énfasis, receta de espaciado/alineación, tipografía, cromo de componente, estado de interacción, patrón de funcionalidad (banner, encabezado de página, CTA de tarjeta, estado), API genérica vs. de una funcionalidad, alcance de prototipo, requisito de diseño cuestionable.
Un grupo → una recomendación. Preferir una recomendación fuerte sobre varias variantes menores del mismo hallazgo.
Paso 4: Buscar primero en la biblioteca de patrones
Buscar en el repositorio hermano pattern-library antes de proponer algo nuevo. Citar rutas.
- Exportaciones públicas —
pattern-library/src/index.ts - Tokens y valores predeterminados globales —
pattern-library/src/theme.ts - Props / variantes de componentes bajo
pattern-library/src/core/ - Usos existentes de app-pro-ui del mismo componente que ya evitan la fuga
Precedentes para absorber IU en el DS (citar estos; no copiar internos en app-pro-ui):
- Prop semántico:
lineClampdeTypography—pattern-library/src/core/Typography/Typography.tsx - Prop semántico:
aiGlowdeButton—pattern-library/src/core/Button/Button.tsx - Token de tema:
ai.gradient.start—pattern-library/src/theme.ts - Prop de variante:
variant="image"enCardMedia—pattern-library/src/core/CardMedia/CardMedia.tsx
Paso 5: Recomendar el cambio más pequeño
Ahora decidir, por hallazgo agrupado: ningún cambio de DS, dejar local, token/variante de PL existente, nuevo token de PL, nueva variante/prop de PL, nueva exportación de PL.
Documentar cada decisión aprobada con:
- Dónde — ruta de patrón o función de tema, o "app-pro-ui" / "local"
- Qué — el cambio específico (añadir prop
maxLines; cambiarcolorde un div aprimary.main) - Por qué — prueba de abstracción superada
- Impacto — solo esta funcionalidad, o otras funcionalidades lo heredarán
Si el cambio es trivial y local, omitirlo de los hallazgos. No hay "bajo" para el relleno de hallazgos.
A veces la respuesta correcta es "no hacer nada" porque la IU local es composición local y no hay un patrón más amplio. Honestidad es más importante que parecer útil.
Elegir un color de exportación
Buscar en src/theme.ts primero. Si hay un token de tema que coincida semánticamente, ese token es la respuesta. No introducir un nuevo token cuando uno existente se ajusta a la intención.
No cambiar a blanco/negro/darkMode como estilo separado. Los tokens de tema más cercanos: primary.main, secondary.main para énfasis; text.primary, text.secondary para contenido; grey escala para neutrales; background.paper, background.default para fondos; error.main, warning.main, success.main, info.main para estados; divider para separadores; custom.ai para tratamientos de AI; custom.prestige para marca. Preferir palette.augmentColor o un nuevo token de tema con nombre sobre un adjetivo de color codificado.
Para colores que aún no existen en el tema, verificar si son realmente decisiones de producto que deben repetirse. Si una funcionalidad usa un color porque el diseño lo dictó, pero esa opción de color no se aplica en ningún otro lugar, usar una variable local; no agregar un token.
Reporte de salida
# Diseño de sistema de revisión: [título de la rama]
## Hallazgos (DS)
1. **Componente/Función:** [nombre] \
**Ruta:** [archivo:línea] \
**Categoría:** token/variante/exportación/ningún cambio/... \
**Decisión:** [recomendación] \
**Razonamiento:** [por qué se aplica/no se aplica la abstracción] \
**PL existente:** [paths | nada]
2. ...
## No promover
(Solo cuando son capturados por la detección pero la abstracción no está justificada. Incluir por qué.)
## Resumen de hallazgos fuera del alcance de DS
(Desviaciones donde es necesaria la habilidad de refactorización o conocimiento genérico de MUI.)
En modo REVIEW, el archivo de salida es review-branch-[rama de funcionalidad]-ds.md.
Modo independiente (sin PLAN conductor)
Cuando no hay PLAN anterior, seguir el mismo proceso pero activar BUILD con:
- Examinar el diseño proporcionado (nodo de Figma, captura de pantalla, descripción del producto).
- Encontrar componentes PL existentes y rutas de tema antes de escribir cualquier estilo nuevo.
- Documentar cualquier caso en el que el diseño requiere una nueva capacidad de PL (nueva variante, token, exportación).
- No pasar por alto el diseño; pero tampoco agregar capacidad innecesaria de DS para una apariencia que ninguna otra funcionalidad compartirá.
Historial de migración
Anteriormente pattern-library-refactor. El alcance del DS se ha consolidado desde entonces. Los modos PLAN/BUILD/REVIEW fueron formalizados. Ahora es una habilidad.
Para la estructura de hook/util/grid y la higiene del código genérico de app-pro-ui, consultar la habilidad refactoring.