Egbe Lajo
COMPONENT

Modal

Overlay dialog for focused tasks. Supports ESC to close, click-outside, and body scroll lock.

Usage

import { Modal, ModalHeader, ModalBody, ModalFooter } from "@/components/ui";
import { Button } from "@/components/ui";

function DeleteConfirmation({ open, onClose, onConfirm }) {
  return (
    <Modal open={open} onClose={onClose} size="md">
      <ModalHeader>
        <h2 className="text-heading-lg">Confirmar exclusao</h2>
      </ModalHeader>
      <ModalBody>
        <p className="text-body-md text-foreground-secondary">
          Tem certeza que deseja excluir este membro?
          Esta acao nao pode ser desfeita.
        </p>
      </ModalBody>
      <ModalFooter>
        <Button variant="outline" onClick={onClose}>Cancelar</Button>
        <Button variant="danger" onClick={onConfirm}>Excluir</Button>
      </ModalFooter>
    </Modal>
  );
}

Sizes

SizeMax WidthUse Case
sm384pxSimple confirmations
md512pxForms, detail views
lg672pxComplex forms, previews
xl896pxData-heavy content

Interaction Behavior

  • ESC key closes the modal
  • Click outside (backdrop) closes the modal
  • Body scroll is locked while modal is open
  • Focus trap — add via your preferred focus-trap library
  • Animation — backdrop fades in, panel scales in (200ms ease-out)

API Reference

PropTypeDefaultDescription
open*booleanControls visibility
onClose*() => voidCalled on ESC or backdrop click
size"sm" | "md" | "lg" | "xl""md"Max width of the panel
children*ReactNodeModal content

React Native

On mobile, Modal uses React Native's built-in Modal component withtransparent and animationType="fade". For bottom-anchored content, use BottomSheet instead — it supports swipe-to-dismiss via PanResponder.

Mobile — Modal
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from "@/components/mobile";

<Modal visible={isOpen} onClose={close}>
  <ModalHeader><Text style={textStyles["heading-lg"]}>Confirmar</Text></ModalHeader>
  <ModalBody><Text>Tem certeza?</Text></ModalBody>
  <ModalFooter>
    <Button variant="outline" onPress={close}>Cancelar</Button>
    <Button variant="danger" onPress={handleDelete}>Excluir</Button>
  </ModalFooter>
</Modal>
Mobile — BottomSheet
import { BottomSheet } from "@/components/mobile";

<BottomSheet visible={open} onClose={close} snapPoint={0.4}>
  <Text>Swipe down to dismiss</Text>
</BottomSheet>