import { useEffect, useRef } from "preact/hooks"; import { t } from "../../services/i18n"; import { ComponentChildren } from "preact"; import type { CSSProperties } from "preact/compat"; interface ModalProps { className: string; title: string; size: "lg" | "sm"; children: ComponentChildren; footer?: ComponentChildren; maxWidth?: number; /** * If set, the modal body and footer will be wrapped in a form and the submit event will call this function. * Especially useful for user input that can be submitted with Enter key. */ onSubmit?: () => void; /** Called when the modal is shown. */ onShown?: () => void; /** Called when the modal is hidden, either via close button, backdrop click or submit. */ onHidden?: () => void; helpPageId?: string; } export default function Modal({ children, className, size, title, footer, onShown, onSubmit, helpPageId, maxWidth, onHidden: onHidden }: ModalProps) { const modalRef = useRef(null); if (onShown || onHidden) { useEffect(() => { const modalElement = modalRef.current; if (modalElement) { if (onShown) { modalElement.addEventListener("shown.bs.modal", onShown); } if (onHidden) { modalElement.addEventListener("hidden.bs.modal", onHidden); } } }); } const style: CSSProperties = {}; if (maxWidth) { style.maxWidth = `${maxWidth}px`; } return (
{title}
{helpPageId && ( )}
{onSubmit ? (
{ e.preventDefault(); onSubmit(); }}> {children}
) : ( {children} )}
); } function ModalInner({ children, footer }: Pick) { return ( <>
{children}
{footer && (
{footer}
)} ); }