Ir al contenido
English

Navegar

Escribe para buscar. Pulsa Escape para cerrar.

    Componentes · js

    Diálogo (dialog)

    Un modal construido sobre el elemento nativo <dialog>. El navegador aporta la capa superior, el fondo inerte y Escape; iVOLT añade la colocación del foco, su devolución, el cierre al pulsar el fondo, los disparadores declarativos y los eventos cancelables.

    CSS: css/components/dialog.css (dentro de ivolt.css). JS: @intervolutions/ivolt/dialog o auto.js.

    dialog/basicfixtures/dialog/basic.htmlAbrir sola — dialog/basic
    <a class="iv-button iv-button--primary" href="#signup" data-iv-open="signup">Create account</a>
    
    <dialog class="iv-dialog" id="signup" data-iv-component="dialog" data-iv-initial-focus="#signup-email" aria-labelledby="signup-title">
      <form method="dialog" class="iv-dialog__panel">
        <header class="iv-dialog__header">
          <h2 class="iv-dialog__title" id="signup-title">Create account</h2>
          <button class="iv-button iv-button--ghost iv-button--icon" type="button" data-iv-close aria-label="Close">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg>
          </button>
        </header>
        <div class="iv-dialog__body iv-stack">
          <p class="iv-u-m-0">Demo dialog. Nothing is sent anywhere.</p>
          <div class="iv-field">
            <label class="iv-label" for="signup-email">Work email</label>
            <input class="iv-input" id="signup-email" type="email" autocomplete="email">
          </div>
        </div>
        <footer class="iv-dialog__footer">
          <a class="iv-button iv-button--ghost" href="#" data-iv-close>Cancel</a>
          <button class="iv-button iv-button--primary" value="confirm">Continue</button>
        </footer>
      </form>
    </dialog>
    // data-iv-component="dialog"
    {
      open: "signup",
      initialFocus: "#signup-email",
      close: true,
    }

    Marcado

    Dale al diálogo data-iv-component="dialog", un id y un nombre accesible (aria-labelledby). Los disparadores usan data-iv-open="id"; cualquier elemento interior con data-iv-close lo cierra. Un <form method="dialog"> hace que los botones cierren el diálogo con su value como valor de retorno.

    JavaScript

    import { Dialog } from "@intervolutions/ivolt/dialog";
    const dialog = Dialog.getOrCreate(document.getElementById("signup"), { closeOnBackdrop: false });
    dialog.open({ trigger: button });
    dialog.element.addEventListener("iv:close", (e) => { if (e.detail.reason === "escape" && dirty) e.preventDefault(); });

    Opciones (defaults < data-iv-* < JS)

    OpciónAtributoPor defectoEfecto
    closeOnBackdropdata-iv-close-on-backdroptruePulsar fuera del panel cierra.
    closeOnEscapedata-iv-close-on-escapetrueEscape cierra (el cancel nativo se intercepta siempre para que el evento siga siendo cancelable).
    initialFocusdata-iv-initial-focusnullSelector que recibe el foco al abrir; si no, el primer elemento enfocable y, en su defecto, el propio diálogo.
    returnFocusdata-iv-return-focustrueEl foco vuelve al disparador al cerrar.

    Métodos y eventos

    open({ trigger }), close(reason, returnValue), toggle(), destroy(), isOpen, returnValue. Los eventos se propagan desde el elemento del diálogo: iv:open e iv:close son cancelables; después llegan iv:opened e iv:closed. detail.reason es uno de trigger, escape, backdrop, form, api o external.

    Teclado

    Tab y Mayús+Tab se quedan dentro del modal (comportamiento del navegador con showModal); Escape cierra; Enter en el formulario envía y cierra. El foco vuelve al disparador.

    Sin JavaScript

    El disparador es un enlace al id del diálogo. Con JavaScript el enlace se intercepta y la URL no cambia. Sin él, .iv-dialog:target muestra el diálogo como un bloque estático con su enlace de cierre. Mantén el contenido esencial accesible también desde otro sitio; un diálogo no es una página.

    Errores frecuentes

    • Llamar a dialog.close() directamente sobre el elemento: funciona, pero iv:close no puede cancelarlo y el motivo pasa a ser external.
    • Un disparador dentro del diálogo que apunta a sí mismo.
    • Sin nombre accesible (aria-labelledby o aria-label).