Estado vacío

Lo que se ve cuando una tabla, una lista o una sección no tiene nada todavía (o cuando un filtro no encontró nada). La marca es la media luna del catálogo en gris, respirando despacio; dice qué pasa, qué hacer y ofrece la acción. Tamaño tabla para paneles y tamaño página para la sección entera.

Aún no hay clases esta semana

Programa la primera desde una plantilla y aparecerá en el horario del estudio.

app/views/… (la demo de arriba)

<div class="@container w-full max-w-3xl">
  <div class="grid items-start gap-4 @2xl:grid-cols-[1.15fr_1fr]">
    <%= render Ui::EmptyStateComponent.new(size: :page, title: "Aún no hay clases esta semana",
                                           description: "Programa la primera desde una plantilla y aparecerá en el horario del estudio.") do |empty| %>
      <% empty.with_action do %>
        <%= render Ui::ButtonComponent.new(size: :sm, href: "#programar") do %>Programar clase<% end %>
        <%= render Ui::ButtonComponent.new(variant: :ghost, size: :sm, href: "#plantillas") do %>Ver plantillas<% end %>
      <% end %>
    <% end %>

    <%# Tamaño tabla: el cuerpo de un panel o de Ui::DataTableComponent (slot with_empty). %>
    <div class="hidden overflow-hidden rounded-xl border border-border bg-card @2xl:block">
      <div class="flex items-center justify-between gap-3 border-b border-border-subtle px-4 py-3">
        <p class="text-sm font-medium text-foreground">Reservaciones canceladas</p>
        <span class="font-mono text-2xs text-faint">0</span>
      </div>
      <%= render Ui::EmptyStateComponent.new(title: "Sin cancelaciones esta semana",
                                             description: "Cuando alguien cancele, la verás aquí con su crédito devuelto.") %>
    </div>
  </div>
</div>

Qué hace

  • La sombra de la luna entra y sale despacio (se queda quieta con movimiento reducido).
  • Entra con animate-rise cuando aparece (p. ej. cuando un filtro deja la tabla vacía).
  • Lo usa Ui::DataTableComponent como estado vacío por defecto.

Props

Nombre Tipo Default Descripción
title / description String — / nil Qué pasa y qué hacer, en una línea cada uno.
size :table | :page (o :sm | :lg) :table :page agrega anillos alrededor de la marca y más aire.
framed Boolean size == :page Marco propio (borde de 1px y superficie).
heading Symbol :h3 Etiqueta del título, según el nivel de la página.
with_icon / with_action slots — Un ícono en lugar de la media luna; la acción (Ui::ButtonComponent o un button_to).

Accesibilidad