Contexto
Para labels chicos que cambian -- un boton Copy -> Copied, un contador, un badge de estado -- queria una animacion que se sintiera tactil sin meter una libreria de animacion completa (framer-motion, GSAP) solo para eso.
Lo que aprendi
slot-text es una animacion "text roll" (estilo slot machine) dependency-free, <2KB gzip, puro CSS transforms (GPU-composited). Cada caracter vive en su propia celda recortada y desliza; el glifo entrante persigue al saliente con un stagger y aterriza con un pequeno rebote. Soporta vanilla JS, React, Vue, Solid y Svelte, cada uno como subpath aparte.
En React es declarativo: el componente <SlotText> rueda al nuevo valor cuando
cambia su prop text. Dos gotchas de empaquetado:
- El componente React vive en el subpath
slot-text/react, no en la raiz. - El CSS se exporta como subpath aparte (
slot-text/style.css). Sin el, las celdas no quedan recortadas y el roll se ve roto (los glifos no deslizan).
import { SlotText } from "slot-text/react";
import "slot-text/style.css";
Ejemplo
El patron clasico copy -> copied, spam-safe (cada click reinicia el revert en vez de encolar rolls):
import { SlotText } from "slot-text/react";
import "slot-text/style.css";
function CopyButton() {
const [label, setLabel] = useState("Copy");
const timer = useRef<number | null>(null);
const onCopy = () => {
setLabel("Copied!");
if (timer.current) clearTimeout(timer.current);
timer.current = window.setTimeout(() => setLabel("Copy"), 1400);
};
return (
<button onClick={onCopy}>
<SlotText text={label} options={{ skipUnchanged: true, interrupt: false }} />
</button>
);
}
Barrido cromatico (arcoiris) con el helper chromatic():
import { chromatic } from "slot-text";
<SlotText text="Live" options={{ color: chromatic() }} />
Opciones (SlotOptions): direction, stagger, duration, exitOffset,
easing, bounce, color, colorFade, skipUnchanged, interrupt. Para
vanilla hay un API imperativo: slotText(el, "Copy") devuelve un controller con
.set(), .flash() y .destroy().
Por que importa
Es el punto medio justo entre un cambio de texto seco y traer una libreria de animacion entera. Lo guardo como recurso para microinteracciones en botones y badges, donde 2KB de transforms puros bastan. Peer dependency: React >= 18 < 20.
Demo con tres patrones (copy/copied, contador, estado cromatico) y selector de direccion en el micro-repo (link abajo).