Confirmación

Se monta una vez en el layout y reemplaza el confirm() nativo en todas las confirmaciones de Turbo (Turbo.config.forms.confirm): cada form, button_to o link_to con data-turbo-confirm la usa tal cual. Toma el título de la pregunta, el texto del botón de lo que se presionó y se vuelve destructiva sola en un DELETE. Para lo irreversible, data-confirm-hold pide mantener presionado mientras un relleno avanza.

¿Confirmas esta acción?

Nada se ha enviado todavía

app/views/… (la demo de arriba)

<%# En la app va una sola vez en el layout; desde ahí toma TODOS los
    data-turbo-confirm. %>
<%= render Ui::ConfirmDialogComponent.new %>

<%# Botones de verdad (button_to, como en el admin). Cada uno manda un GET a
    esta ficha que actualiza el frame de abajo: si cancelas, no se envía. %>
<% demo_form = { class: "contents", data: { turbo_frame: "confirm-dialog-result" } } %>
<div class="flex w-full max-w-sm flex-col items-center gap-5">
  <div class="flex flex-wrap items-center justify-center gap-2">
    <%= button_to "Reenviar guía", ui_component_path("confirm-dialog"), method: :get, params: { hecho: "Correo con la guía reenviado" }, form: demo_form,
                  class: Ui::ButtonComponent.classes(variant: :secondary),
                  data: { turbo_confirm: "¿Reenviar a Ana López el correo con el número de guía?" } %>

    <%= button_to "Cancelar reserva", ui_component_path("confirm-dialog"), method: :get, params: { hecho: "Reservación cancelada" }, form: demo_form,
                  class: Ui::ButtonComponent.classes(variant: :secondary),
                  data: { turbo_confirm: "¿Cancelar tu reservación de Vinyasa Flow? Faltan menos de 12 horas: el crédito no se devuelve.",
                          confirm_tone: "danger", confirm_cancel: "Conservar mi lugar" } %>

    <%= button_to "Eliminar a Ana López", ui_component_path("confirm-dialog"), method: :get, params: { hecho: "Ana López eliminada" }, form: demo_form,
                  class: Ui::ButtonComponent.classes(tone: :danger),
                  data: { turbo_confirm: "¿Eliminar a Ana López? Se borrarán también sus reservaciones, paquetes, pagos y demás datos asociados. Esta acción no se puede deshacer.",
                          confirm_hold: true, confirm_accept: "Eliminar" } %>
  </div>

  <%= turbo_frame_tag "confirm-dialog-result", class: "block min-h-5 text-center text-xs text-muted-foreground" do %>
    <% if params[:hecho].present? %>
      <span class="text-foreground"><%= params[:hecho] %></span> · <span class="font-mono"><%= Time.current.strftime("%H:%M:%S") %></span>
    <% else %>
      Nada se ha enviado todavía
    <% end %>
  <% end %>
</div>

Qué hace

  • Las 25 vistas con data-turbo-confirm la usan sin cambios; resuelve la promesa en false con Cancelar, Esc o el fondo.
  • Dos confirmaciones seguidas no se mezclan; la que queda pendiente se responde "no" antes de mostrar la nueva.
  • Montarla dos veces no rompe nada; gana la última conectada y al desconectarse vuelve la anterior.
  • También confirma los botones con data-turbo="false" (Turbo ignoraba su data-turbo-confirm) y los link_to con data-turbo-method (lee sus data-confirm-*).
  • Desde JS: import { confirm } from "controllers/confirm_dialog_controller"; await confirm("¿Salir?", { tone: "danger" }).

Props

Nombre Tipo Default Descripción
data-turbo-confirm String (en el botón, form o enlace) — La pregunta. "¿…?" al inicio es el título y el resto la descripción.
data-confirm-title String de la pregunta Título propio; el mensaje queda como descripción.
data-confirm-accept String texto del botón Texto del botón de aceptar ("Eliminar"). Si no, el del botón presionado.
data-confirm-cancel String "Cancelar" Texto de cancelar; "Volver" si la acción ya empieza con Cancelar.
data-confirm-tone "danger" danger en DELETE Botón destructivo, ícono de alerta y foco inicial en Cancelar.
data-confirm-hold "true" — Lo irreversible: mantener presionado (o Espacio/Enter) ~1 s para aceptar.
id / title / accept / cancel String "eui-confirm" / "¿Confirmas esta acción?" / "Confirmar" / "Cancelar" Del componente: id del dialog y textos por defecto.
hold_duration Integer (ms) 1000 Cuánto hay que sostener en modo hold.

Accesibilidad