Skip to content

Modal

Diálogo centrado para confirmaciones, contenido o feedback. Portal a body, backdrop, cierre con ✕ / ESC / clic fuera.

Preview principal

MODALportal · ESC · backdrop

Diálogo centrado sobre backdrop. Cierra con ✕, ESC o clic fuera.

Confirmación

Decisión explícita antes de una acción importante o destructiva.

Persistente

persistent: ESC o clic fuera no cierra — el panel salta como feedback. Solo el footer.

Contenido largo

El cuerpo hace scroll; cabecera y footer se quedan fijos.

Sin título

Solo cuerpo + X flotante. Útil para feedback breve.

Tamaños

sm 400px · md 512px · lg 640px

Tamaño Ancho máx.
sm 400px
md 512px
lg 640px
  • Portal a document.body (z-index alto)
  • Bloquea scroll del fondo
  • Cierra con ✕, ESC o backdrop (onClose) — salvo persistent
  • Con persistent: solo acciones explícitas (footer); sin ESC, sin clic fuera, sin ✕. Al intentarlo, el panel salta.
  • Foco inicial en el panel (role="dialog", aria-modal)
  • Animación entrada/salida (~180ms)
import { useState } from "react";
import { Button, Modal } from "devsoftec-ui";
function Ejemplo() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Abrir</Button>
<Modal
open={open}
onClose={() => setOpen(false)}
title="Confirmar"
footer={
<>
<Button variant="secondary" onClick={() => setOpen(false)}>Cancelar</Button>
<Button onClick={() => setOpen(false)}>Continuar</Button>
</>
}
>
¿Seguro que quieres continuar?
</Modal>
</>
);
}
<Modal
open={open}
onClose={() => setOpen(false)}
persistent
title="Términos de uso"
footer={<Button onClick={() => setOpen(false)}>Acepto</Button>}
>
Debes aceptar para continuar.
</Modal>
Prop Tipo Default Descripción
open boolean Visibilidad
onClose () => void Cierre (✕, ESC, backdrop)
persistent boolean false Bloquea ESC/backdrop/✕; salta al intentar
title ReactNode Cabecera (+ ✕ si no es persistent)
footer ReactNode Acciones fijas (sin scroll)
size sm | md | lg md Ancho máximo
children ReactNode Cuerpo
className string Clase adicional