Referencia

Cajas animadas

Las cajitas de Ghosty para tu sitio o tu app — estados, formas, pantallas, colores, temas y un resumen que se reordena arrastrando. Paquete @ghostystudio/boxes.

Actualizado 2026-10-11

Cada caja de Ghosty es un robot con cabeza de tele: su cara dice qué hace (dormida, escuchando, trabajando, con error), sigue al mouse y brinca si le das clic. Es el mismo que ves en Cajas del espacio, y lo publicamos como paquete libre (MIT) para que lo uses en tus propias páginas y apps: @ghostystudio/boxes.

Instalación

html
<script src="https://unpkg.com/@ghostystudio/boxes/dist/boxes.iife.js"></script>
<ghosty-box state="happy"></ghosty-box>

Funciona en HTML pelón y en cualquier framework: es un custom element. En React hay dos componentes: <RobotHead> (una caja) y <GhostyBoxes> (el resumen). Ya traen "use client", así que en Next.js (App Router) se usan tal cual dentro de un Server Component. Cada ejemplo de abajo tiene su pestaña React.

Estados

Lo que la caja está haciendo. Cada estado tiene su cara, su movimiento y su luz.

idle
thinking
searching
listening
speaking
working
happy
success
error
sleeping
html
<ghosty-box state="idle" size="96" title="idle"></ghosty-box><ghosty-box state="thinking" size="96" title="thinking"></ghosty-box><ghosty-box state="searching" size="96" title="searching"></ghosty-box><ghosty-box state="listening" size="96" title="listening"></ghosty-box><ghosty-box state="speaking" size="96" title="speaking"></ghosty-box><ghosty-box state="working" size="96" title="working"></ghosty-box><ghosty-box state="happy" size="96" title="happy"></ghosty-box><ghosty-box state="success" size="96" title="success"></ghosty-box><ghosty-box state="error" size="96" title="error"></ghosty-box><ghosty-box state="sleeping" size="96" title="sleeping"></ghosty-box>

Formas

rectangle
square
circle
hexagon
html
<ghosty-box shape="rectangle" size="110" title="rectangle"></ghosty-box><ghosty-box shape="square" size="110" title="square"></ghosty-box><ghosty-box shape="circle" size="110" title="circle"></ghosty-box><ghosty-box shape="hexagon" size="110" title="hexagon"></ghosty-box>

De temporada también hay tree (navidad) y pumpkin (halloween).

Pantalla

face elige qué enseña: los ojos, una terminal o nada. Con la terminal, screen-icon pone un ícono: mail, inbox, build, ci, preview, desktop o web (y puedes registrar los tuyos con registerScreenIcon).

eyes
terminal
mail
inbox · working
off
html
<ghosty-box face="eyes" size="110" title="eyes"></ghosty-box><ghosty-box face="terminal" state="listening" size="110" title="terminal"></ghosty-box><ghosty-box face="terminal" screen-icon="mail" size="110" title="mail"></ghosty-box><ghosty-box face="terminal" screen-icon="inbox" state="working" size="110" title="inbox · working"></ghosty-box><ghosty-box face="off" size="110" title="off"></ghosty-box>

Colores, temas y acabados

Un tema pinta la caja con una palabra; lo que pongas a mano le gana. color es la carcasa, trim-color las orejas y screen-color los LEDs. texture cambia el acabado y wear (0–1) le pone desgaste.

ghosty
mailmask
mailmaskGreen
a mano
metal
wood · wear
html
<ghosty-box theme="ghosty" size="110" title="ghosty"></ghosty-box><ghosty-box theme="mailmask" size="110" title="mailmask"></ghosty-box><ghosty-box theme="mailmaskGreen" size="110" title="mailmaskGreen"></ghosty-box><ghosty-box color="#7c3aed" trim-color="#fbbf24" screen-color="#fde68a" size="110" title="a mano"></ghosty-box><ghosty-box color="#8a8f98" texture="metal" size="110" title="metal"></ghosty-box><ghosty-box color="#a0522d" texture="wood" wear="0.6" size="110" title="wood · wear"></ghosty-box>

Tu propio tema: registerTheme('mimarca', { color: '#…', trimColor: '#…', screenColor: '#…' }) y luego theme="mimarca".

Resumen que se reordena arrastrando

<ghosty-boxes> es la fila de resumen: título, contador, una caja por elemento con su nombre, estado y puntitos, y lugares libres apagados. Agarra una caja: se levanta, se columpia y sonríe; al soltarla cae con un brinco. También con el teclado: Alt + ← / →.

html
<ghosty-boxes theme="mailmask" data='{"title":"Buzones","count":"4/6","sub":"12 sin leer · 1 importando","items":[{"id":"hola","name":"hola@","label":"8 sin leer","tone":"talk","dots":{"on":8,"cap":10},"head":{"state":"happy"}},{"id":"ventas","name":"ventas@","label":"importando","tone":"work","dots":{"on":3,"cap":10},"head":{"state":"working","screenIcon":"inbox"}},{"id":"soporte","name":"soporte@","label":"4 sin leer","tone":"talk","dots":{"on":4,"cap":10},"head":{"state":"listening"}},{"id":"facturas","name":"facturas@","label":"casi llena","tone":"error","dots":{"on":10,"cap":10},"head":{"state":"error"}},{"id":"l1","name":"libre","off":true},{"id":"l2","name":"libre","off":true}]}'></ghosty-boxes>

Los datos también entran por código, y el orden nuevo sale en un evento:

js
const row = document.querySelector('ghosty-boxes');row.data = { title: 'Buzones', count: '4/6', items: [/* … */] };row.addEventListener('box-reorder', (e) => guardar(e.detail.order)); // { id, from, to, order }row.addEventListener('box-open', (e) => abrir(e.detail.id));

Cada elemento lleva id, name, y opcionales label, tone (work, talk, error, sleep, calm), dots ({ on, cap }), off (lugar libre, fijo), group (sólo se reordena dentro de su grupo) y head (las props de su caja). Los colores de la tarjeta salen de variables CSS sobre .gbx: --gbx-bg, --gbx-border, --gbx-fg, --gbx-muted, --gbx-work, --gbx-talk, --gbx-error, --gbx-dot, --gbx-radius.

Atributos de <ghosty-box>

AtributoValoresDefault
themeghosty, mailmask, mailmaskGreen o uno tuyo—
stateidle, thinking, searching, listening, speaking, working, happy, success, error, sleepingidle
shaperectangle, square, circle, hexagon, tree, pumpkinrectangle
sizepx160
color · trim-color · screen-colorhex o rgb()azul · acero · blanco
faceeyes, terminal, offeyes
screen-iconcon terminal: mail, inbox, build, ci, preview, desktop, web—
texturegrain, smooth, paper, fabric, metal, leather, wood, ribsgrain
wear0–10
speedmultiplicador; 0 la congela1
seed0–1, para que una fila no parpadee al unísonoal azar
paused · interactive="false" · antenna="false" · floor-shadow="false"banderas—

En React son las mismas props en camelCase (trimColor, screenIcon, floorShadow) y los números y banderas van entre llaves (size={96}, antenna={false}). Respeta prefers-reduced-motion. Los cambios de atributo se ven al instante.

El robot es de Fayaz Ahmed (MIT), con estados, formas, pantallas, temas y acabados añadidos por Ghosty.