Botón con estados

El botón cuenta lo que pasa con la acción: gira mientras reserva, dibuja una palomita al terminar y regresa solo a su estado normal; si algo falla, se sacude y lo dice. El ancho cambia con resorte entre estados. Dentro de un formulario escucha a Turbo, así que funciona con el submit de siempre.

app/views/… (la demo de arriba)

<div class="flex flex-wrap items-center justify-center gap-3">
  <%= render Ui::ActionButtonComponent.new(label: "Reservar clase", simulate: true) do %>
    <%= render Ui::IconComponent.new(:calendar, size: :sm) %>
  <% end %>
  <%= render Ui::ActionButtonComponent.new(label: "Usar 1 crédito", loading_label: "Cobrando…", success_label: "Listo", error_label: "Sin créditos", variant: :secondary, simulate: :error) %>
</div>

Qué hace

  • Con Turbo: turbo:submit-start → cargando; turbo:submit-end → éxito si detail.success, si no error.
  • Solo reacciona si este botón envió el formulario; un segundo clic mientras carga no reenvía.
  • El ancho de cada estado se mide y el botón lo sigue con el resorte "responsive".
  • La sacudida del error es un impulso de velocidad sobre un resorte, no una animación fija.
  • Controlable desde fuera: action-button#start / #succeed / #fail / #reset o data-action-button-state-value (Turbo Stream).

Props

Nombre Tipo Default Descripción
label String — Texto en reposo (y nombre accesible). Un bloque opcional se pinta antes, p. ej. un ícono.
loading_label String "Reservando…" Mientras carga; se anuncia.
success_label String "Reservado" Al terminar bien; se anuncia.
error_label String "No se pudo" Si falla; se anuncia.
variant :primary | :secondary :primary Superficie del botón; en error toma el color de error.
size :sm | :md | :lg :md Alto (sigue el dial de densidad) y tipografía.
simulate true | :success | :error nil Solo para demos: simula ~1.2s de carga y luego éxito o error.
reset_after Integer (ms) 2000 Cuánto se queda el resultado antes de volver a idle (el error, medio segundo más); 0 = se queda.
type String "submit" Tipo del <button>.
data Hash {} Atributos data del <button>; la acción del controlador se combina con las tuyas.

Accesibilidad