Datos vivos
Estado: BetaPila de avatares
Los avatares de quienes reservaron, superpuestos y con "+N" al final. Al pasar el cursor la pila se abre con resortes escalonados y el avatar bajo el cursor se levanta con su nombre. Para tarjetas de clase, listas de espera o quién toma un paquete.
- Resorte
- Escalonado
- Tooltip
Hoy · 7:00 AM
7/12Van a Vinyasa Flow
- Ana García
- Sofía Ruiz
- Mariana Cruz
- Diego Torres
- Lucía Herrera
- y 2 más: Pablo Méndez y Renata Ortiz
Ana, Sofía y 5 más ya reservaron.
- Ana García
- Sofía Ruiz
- Mariana Cruz
- y 1 más: Diego Torres
- Ana García
- Sofía Ruiz
- Mariana Cruz
- y 1 más: Diego Torres
- Ana García
- Sofía Ruiz
- Mariana Cruz
- y 1 más: Diego Torres
Hoy · 7:00 AM
7/12Van a Vinyasa Flow
- Ana García
- Sofía Ruiz
- Mariana Cruz
- Diego Torres
- Lucía Herrera
- y 2 más: Pablo Méndez y Renata Ortiz
Ana, Sofía y 5 más ya reservaron.
- Ana García
- Sofía Ruiz
- Mariana Cruz
- y 1 más: Diego Torres
- Ana García
- Sofía Ruiz
- Mariana Cruz
- y 1 más: Diego Torres
- Ana García
- Sofía Ruiz
- Mariana Cruz
- y 1 más: Diego Torres
app/views/… (la demo de arriba)
<% people = [ "Ana García", "Sofía Ruiz", "Mariana Cruz", "Diego Torres", "Lucía Herrera", "Pablo Méndez", "Renata Ortiz" ] %>
<div class="@container flex w-full flex-col items-center gap-8">
<div class="w-full max-w-xs rounded-xl border border-border bg-card p-5">
<div class="flex items-center justify-between gap-3">
<p class="eui-label">Hoy · 7:00 AM</p>
<span class="font-mono text-2xs text-faint">7/12</span>
</div>
<h3 class="mt-2 text-base font-semibold tracking-tight">Van a Vinyasa Flow</h3>
<div class="mt-4">
<%= render Ui::AvatarStackComponent.new(people: people, max: 5, on: :card, label: "7 personas van a esta clase") %>
</div>
<p class="mt-3 text-xs text-muted-foreground">Ana, Sofía y 5 más ya reservaron.</p>
</div>
<div class="hidden items-end gap-8 @lg:flex">
<% [ [ :sm, "sm" ], [ :md, "md" ], [ :lg, "lg" ] ].each do |size, name| %>
<div class="flex flex-col items-center gap-2">
<%= render Ui::AvatarStackComponent.new(people: people.first(4), max: 3, size: size, label: "#{people.first(4).size} personas en lista de espera") %>
<span class="eui-label"><%= name %></span>
</div>
<% end %>
</div>
</div>Qué hace
- Cada avatar tiene su resorte; al abrir salen uno tras otro (28 ms) y al cerrar regresan en orden inverso.
- El avatar activo se levanta y su tooltip entra con sus propios resortes (400/25 y 450/25).
- El "+N" nombra a los que no caben (hasta tres en el tooltip).
- Sin JS la pila se abre y muestra nombres con CSS.
Props
| Nombre | Tipo | Default | Descripción |
|---|---|---|---|
| people | Array<String | Hash> | — | Nombres o { name:, src:, initials: }; sin imagen se muestran iniciales. |
| max | Integer | 5 | Cuántos se ven; el resto va en el "+N". |
| size | :sm | :md | :lg | :md | 28, 36 o 44 px. |
| label | String | "N personas" | Resumen que oye el lector de pantalla (7 personas van a esta clase). |
| on | :background | :card | :raised | :background | Superficie detrás: color del anillo que separa los avatares. |
Accesibilidad
- Es una lista con nombre ("7 personas van a esta clase"); cada persona se lee por su nombre y el "+N" dice quiénes faltan.
- Una sola parada de tabulador; ← → Inicio Fin recorren y Escape esconde el tooltip.
- Al enfocar se abre igual que con el cursor; el anillo de foco va en el avatar.
- Con movimiento reducido se abre sin animación.