Ir al contenido
Anthony Velez Tapia
Volver a proyectos

Caso de estudio

Django Cotton Gallery

Mantenido

Playground drop-in para librerías de componentes Django Cotton — preview en vivo con controles generados de tus anotaciones, lint y panel de métricas.

El problema

Faltaba algo nativo para previsualizar componentes de Cotton.

Existe Storybook, y según investigué se puede integrar en Django. Pero no te sirve de mucho: no te deja trabajar de verdad. Es una herramienta pensada para otro ecosistema, y se nota en cada paso.

Y hay una limitación de fondo que ninguna extensión de editor puede salvar: por dónde vive, no puede renderizar el componente como el usuario lo diseñó. El editor no ejecuta tu proyecto Django, así que no tiene tus estilos, ni tu contexto, ni tu configuración.

Para ver el componente de verdad hay que estar dentro del proyecto.

Qué es

Un playground para librerías de componentes Django Cotton. Se instala en un proyecto Django existente y expone una galería navegable de sus componentes.

Lo que trae:

  • Playground en vivo. Cada componente se renderiza con controles generados automáticamente a partir de sus anotaciones @prop. Cambias una prop y lo ves al momento. Copias la etiqueta y listo.
  • Informe de lint con tres niveles —errores, avisos y sugerencias— para desajustes entre @prop y <c-vars>, descripciones que faltan y variables sin declarar.
  • Panel de métricas: salud de la configuración, cobertura de anotaciones, componentes zombi y ranking de los más referenciados. Detectar el deterioro antes de que llegue a producción.
  • Buscador con Ctrl+K y filtros estructurados: prop:size, slot:actions, accepts-attrs, has-named-slots, deprecated.
  • Planificador de refactor con el árbol de dependencias transitivas, constructor de anotaciones por formulario, y vista de comparación en paralelo.
  • Interfaz en cuatro idiomas: inglés, castellano, euskera y francés.

Detalle de un componente con sus controles generados en vivo

La otra mitad

Cotton Props hace el mismo trabajo: ayudar a escribir componentes y detectar errores. La diferencia es dónde vive cada una y qué puede enseñar.

galleryprops
DóndeDentro del proyectoDentro del editor
CuándoMientras mirasMientras escribes
PrevisualizaSíNo

Ésta previsualiza porque corre dentro del proyecto. Ésa no puede, porque vive en el editor y el editor no renderiza. Son los dos sitios donde se trabaja con componentes.

Decisiones

Inventar el formato de anotación, y que las dos herramientas lo consuman

Contexto. Cotton no tiene una forma de documentar un componente. Sin eso no hay nada que autocompletar, nada que validar y nada con lo que generar controles.

Decisión. Definir un formato propio —las anotaciones @prop sobre el <c-vars>— y desarrollar en paralelo las dos herramientas que lo leen: la librería Python que se inyecta en Django y la extensión de VS Code.

Por qué importa. No son dos proyectos que se parecen: son dos consumidores de la misma convención. Documentas el componente una vez y lo aprovechan el editor y la galería.

Y de ahí sale el playground gratis. Como la anotación declara el tipo de cada prop, la galería sabe qué control pintar sin que nadie se lo configure:

Tipo anotadoControl que genera
textCampo libre
selectDesplegable con las opciones declaradas
booleanInterruptor
numberCampo numérico

Cambias el valor y el componente se vuelve a renderizar. Los controles no son una lista que haya que mantener aparte: son una lectura de la documentación que ya escribiste.

El linter también corre en CI

El mismo motor que pinta el informe en la galería se ejecuta como comando de gestión:

python manage.py cotton_lint

Informe de lint con sus tres niveles de severidad

La galería no es solo un visor: es una puerta que puedes poner en el pipeline.

Límites

Hay que levantar el servidor. Para ver los errores de un componente tienes que arrancar la web, y mientras escribes no tienes IntelliSense en el editor. Es exactamente el límite contrario al de la extensión, y por eso existen las dos: cada una cubre lo que la otra no alcanza.

No puede
galleryAyudarte mientras escribes en el editor
propsRenderizar el componente como lo diseñaste

La detección es por regex, igual que en la extensión. Un componente escrito de una forma lo bastante rara se sale de lo que la herramienta considera un componente, y entonces no lo ve.

El aislamiento del preview

Durante dos versiones el componente se renderizó en la misma página de la galería, y eso funcionó hasta que alguien metió un modal.

Un modal con su backdrop —la capa oscura que tapa la pantalla— no se queda dentro de su hueco: se despliega sobre la galería entera y puede llegar a bloquearla. El componente hacía exactamente lo que tenía que hacer; el problema era dónde lo estaba metiendo.

Había dos salidas y una era claramente mejor:

  • Limitar el preview, desactivando lo que pueda escaparse de su contenedor. Barato, pero mutila justo los componentes que más interesa ver.
  • Un iframe por preview. Cada componente en su propio documento, con su propio body. Más caro, pero es el aislamiento de verdad y no le quita nada al componente.

En la 1.0.0 entró el iframe, y arregló tres cosas más de las que iba a arreglar: el reset de titulares de la galería pisaba la tipografía en @layer del proyecto que la usa; una raíz de bloque se encogía a 0px dentro del stage flex que la centra; y las media queries ahora disparan con el ancho del stage, así que el conmutador de viewport es real. Las miniaturas del índice también tienen su propio documento, y se descartan al salir de pantalla en vez de mantener un runtime de JS por componente.

Estado

Publicada en PyPI y ya en su primera versión estable: la gramática de anotaciones y los ajustes DJANGO_COTTON_GALLERY_* son API pública, y no se renombran ni se quitan sin una mayor. Funciona sobre Python 3.10 en adelante y Django 4.2 a 6.x. Documentación publicada y changelog al día. Código abierto con licencia MIT.

pip install django-cotton-gallery