¿Qué hace milda?
Milda es un compilador con interfaz gráfica para sistemas de diseño. Un archivo .milda es el sistema de diseño:
fundamentos (tokens), componentes, reglas de uso, documentación y activos. A partir de él se generan paquetes React, librerías Figma,
sitios de documentación y archivos legibles por agentes. Nunca editas una salida; modificas el archivo
y lo regeneras.
Esta skill apunta a la superficie de lenguaje 0.10 con preludio 0.0.2. Cada archivo que escribas comienza con ese encabezado.
El ciclo: escribe, verifica, corrige
Nunca le digas al usuario que un archivo .milda es válido hasta que el lector esté de acuerdo. Después de cada edición, ejecuta:
npx -y -p @mildastudio/milda-lsp milda-check --strict ruta/al/sistema/
Pasa el directorio, o todos los archivos del sistema juntos, porque los tokens declarados en un archivo
resuelven referencias en otro. Imprime ruta:línea:columna severidad [código] mensaje, los mismos
diagnósticos que muestran las extensiones del editor, y termina con código distinto de cero en cualquier error (o, con --strict, cualquier
advertencia). Corrige lo que reporte y ejecútalo de nuevo hasta que diga 0 errores, 0 advertencias. Una advertencia no es
ruido: faceta "background" desconocida omitida significa que esa línea no hizo nada.
Para mostrarle el resultado al usuario, el playground en https://play.milda.dev renderiza un archivo pegado en vivo, sin necesidad de cuenta.
Piensa en Milda: diez reglas
La mayoría de los errores provienen de escribir CSS, un árbol DOM o un componente React en la sintaxis de Milda. Estas reglas son lo que la sintaxis existe para expresar.
- El sistema es la fuente; el código es una salida. Todo lo que tiene forma de plataforma se decide en el momento de la generación, por lo que un archivo nunca contiene una propiedad CSS, una etiqueta, un nombre de evento de un framework o una pseudo-clase.
- Di qué es algo, nunca de qué está hecho. Una parte tiene un tipo neutro (
contenedor,texto,entrada,icono,control, ...), nuncadivobutton. Cada destino elige su propio elemento. - Un valor tiene un nombre, y el nombre tiene una capa. Los componentes nunca pintan con literales. Una faceta
apunta a un token; una capa
Semánticaalias a una capaBasede literales. Un cambio de estilo es un cambio a los fundamentos. - El contexto es una dimensión, no una copia. Modo oscuro, densidad, marca: cada uno es un
grupo-de-contexto, y un token responde por contexto conalias por Grupo { ... }. Una propiedad tipificada por un grupo de contexto (unavariante) usa el mismo mecanismo por instancia. - Un estado proviene de un comportamiento.
hovered,pressed,focus-visible,disabled,open,selectedson emitidos por los comportamientos del arquetipo. Estilízalos conestado hovered { }, nunca con nada específico de puntero o plataforma. La lista está cerrada (referencia/vocabulario.md), y el lector advierte sobre cualquier otra palabra:estado hoverse reporta con la ortografía que pretendía. - El contrato es la identidad.
propsyeventsson contra lo que los consumidores programan y lo que las diferencias de versiones nombran. Nómbralos por significado (variante,cambioMarcado), no por una plataforma. - Construye a partir de lo que existe. Comienza un componente a partir de un
arquetipodel preludio: trae la forma del contrato, las partes requeridas y los comportamientos (teclado, ARIA, enfoque). Compón componentes más grandes a partir de componentes más pequeños con partesinstancia. - Cada referencia es por nombre. Partes por ruta con puntos (
Cabecera.Titulo), tokens por ruta (espacio.pqparaespacio/pq), componentes por identificador. Sin ids. Los comentarios (#) son lo único que no sobrevive un ciclo. - Extiende a través de costuras, nunca parcheando la salida. Cuando el vocabulario no pueda decir algo,
usa un
slot, una opción por destino, o como último recurso contenidoforeignetiquetado con su destino. Nunca sugieras editar código generado. - Di cómo se debe usar. Pon restricciones de interfaz (
requerido,requerido cuando,uno-de) enprops, y reglas de composición (regla ... { nunca X dentro de Y }) a nivel superior, cada una con su motivo.
Un archivo, de arriba a abajo
milda 0.10
prelude 0.0.2
meta { nombre "Acme" }
grupo-de-contexto EsquemaColor { Claro Oscuro }
fundamentos {
capa Base {
token violeta/600 : color = hex(7c3aed)
token blanco : color = hex(ffffff)
token gris/900 : color = hex(0f172a)
}
capa Semantica {
token acento : color = alias por EsquemaColor { predeterminado -> violeta.600 }
token sobre-acento : color = alias por EsquemaColor { predeterminado -> blanco; Oscuro -> gris.900 }
token espacio/pq : espaciado = 8px
token radio/pq : radio = 6px
}
}
componente Boton "La acción principal." {
arquetipo Button
props {
etiqueta : texto = "Comenzar"
}
events {
clic
}
parte Boton: contenedor {
emite { clic al activar }
diseno { pila fila; espacio espacio.pq; alinear centro }
relleno acento
tinta sobre-acento
esquina radio.pq
insercion espacio.pq
estado focus-visible {
anillo acento
}
}
parte etiqueta: texto {
contenido enlazar etiqueta
}
}
Orden: encabezado, meta, grupo-de-contextos, grupos (secciones de biblioteca), fundamentos, tipos,
componentes, reglas, luego ejemplos, activos, iconos, docs. La parte raíz se nombra según el
componente; otras partes se nombran por la anatomía del arquetipo (etiqueta, icono, control, ...) o
por ti, anidadas con rutas de puntos.
De CSS y React a Milda
| Tú escribirías | Milda dice |
|---|---|
<div>, <span>, <button> | parte X: contenedor / texto / la raíz del arquetipo |
background | relleno |
color | tinta |
padding, padding-inline-start | insercion, insercion.inline-start |
margin | nada: espacio en el padre, alineación, o sangria |
border, border-radius | borde <color> <ancho>, esquina |
box-shadow, outline (enfoque) | elevacion, anillo |
font-size + line-height, font-weight | texto <token de tipografia o tamano-letra>, peso |
display: flex; flex-direction: row | diseno { pila fila } |
justify-content, align-items, flex: 1 | distribuir, alinear, tamano llenar |
position: absolute | diseno { pila capas } + posicion superponer en hijo |
:hover, :focus-visible, :disabled | estado hovered { }, estado focus-visible { }, ... |
.btn--secondary, [data-variant] | cuando variante = Secundario { } |
.card:hover .icon | cuando ancestro Tarjeta hovered { } en la parte icono |
@media (prefers-color-scheme: dark) | grupo-de-contexto EsquemaColor + alias por EsquemaColor |
--space-sm: 8px / var(--space-sm) | token espacio/pq : espaciado = 8px / espacio.pq |
#7c3aed, oklch(...) | hex(7c3aed), oklch(...), solo dentro de un token |
color-mix(), calc() | calcular <token> en oklch { oscurecer 10% } |
prop onClick | events { clic } + emite { clic al activar } |
{children} | slot de contenido predeterminado en la parte que los contiene |
{cond && <X/>} | presente cuando <prop> en la parte |
z-index, text-align, box-sizing | nada: orden de partes, el contenedor, solo hay una caja |
Facetas, estados y condiciones en una parte
parte Panel: contenedor {
diseno { pila columna; espacio espacio.pq; tamano llenar ajustar }
relleno superficie
tinta texto
borde linea fina
esquina radio.pq
insercion espacio.pq espacio.md
cuando tono = peligro {
borde peligro fina
}
estado hovered {
relleno superficie-elevada
}
estado hovered cuando tono = peligro {
relleno peligro-subtle
}
}
El valor de una faceta se resuelve como un token primero; un literal desnudo se acepta solo donde ningún token reclama
la palabra (opacidad 50, insercion 0). Prefiere tokens. cuando clave en props, estado en estados de comportamiento,
y los dos se combinan.
Props, eventos y restricciones
arquetipo TextField
props {
etiqueta : texto requerido "Qué pide el campo. También su nombre accesible."
valor : texto
invalido : booleano = falso
error : texto requerido cuando invalido "Se muestra bajo el control mientras es inválido."
tamano : enum(pq, md) = md
tono : contexto Tono = Neutro
}
events {
cambioValor
}
Tipos: texto, numero, booleano, enum(a, b), contexto <Grupo>, array<T>, tus propios tipos.
Un texto al final es la documentación de la propiedad. uno-de a, b / cualquier-de / exclusivo restringen
grupos de props.
Dónde mirar a continuación
- referencia/sintaxis.md: cada declaración con un ejemplo verificado (tokens y valores, diseño, slots, instancias, comportamientos, reglas, documentación, activos, iconos).
- referencia/vocabulario.md: generado a partir del paquete de lenguaje. Cada tipo de token, tipo de parte, faceta, estado, palabra de diseño y función literal que el lector acepta. Cuando tengas dudas sobre una palabra, mira aquí en lugar de adivinar.
- referencia/arquetipos.md: generado a partir del preludio. Cada arquetipo con su contrato, anatomía (qué partes son requeridas) y comportamientos.
- ejemplos/acme.milda: un sistema completo y limpio para copiar patrones.
- La especificación normativa: https://github.com/mildastudio/milda-lang/tree/main/spec (
FORMAT.mdpara lo que promete un archivo,GRAMMAR.ebnfpara la sintaxis,PRELUDE.mdpara los arquetipos). - Para un sistema de diseño que ya está publicado, el servidor MCP de Milda responde con sus componentes y tokens exactos; ver https://milda.dev/mcp.
Antes de terminar
- El encabezado dice
milda 0.10yprelude 0.0.2. - Sin color, longitud o fuente literal en un componente; cada valor es una referencia a un token.
- Sin palabra de plataforma en ningún lugar: sin etiquetas, propiedades CSS, pseudo-clases o nombres de eventos de frameworks.
- Cada componente comienza a partir de un arquetipo a menos que sea una composición pura de instancias.
milda-check --strictsobre todo el sistema imprime0 errores, 0 advertencias.