Skip to main content
Glama
Modal.tsx3.18 kB
import React, { ReactNode, useCallback, useState } from "react"; import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild, Description, } from "@headlessui/react"; import classNames from "classnames"; import { ClosePanelButton } from "@ui/ClosePanelButton"; type ModalProps = { onClose: () => void; title: string | ReactNode; description?: string | ReactNode; children: ReactNode; size?: "sm" | "md" | "lg"; }; export function Modal({ onClose, title, description, children, size = "sm", }: ModalProps) { const [open, setOpen] = useState(true); const handleClose = useCallback(() => { setOpen(false); }, [setOpen]); return ( <Transition show={open} appear afterLeave={onClose}> <Dialog static as="div" data-testid="modal" className="fixed inset-0 z-40 overflow-hidden" open // Real openness status is controlled by Transition above onClose={handleClose} > <div className="flex sm:min-h-screen sm:items-center sm:justify-center sm:px-4"> <TransitionChild enter="ease-out duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="ease-in duration-200" leaveFrom="opacity-100" leaveTo="opacity-0" > <div className="fixed inset-0 bg-black/50 transition-opacity" data-testid="modal-overlay" /> </TransitionChild> <TransitionChild enter="ease-out duration-300" enterFrom="opacity-0 translate-y-12" enterTo="opacity-100 translate-y-0" leave="ease-in duration-200" leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-12" > <DialogPanel className={classNames( "inline-block bg-background-secondary rounded-xl", "text-content-primary", "text-left shadow-xl dark:border transform", "transition-all align-middle", "rounded-b-none sm:rounded-b-xl", "absolute bottom-0 sm:relative", size === "lg" ? "sm:max-w-6xl" : size === "md" ? "sm:max-w-3xl" : "sm:max-w-xl", "w-full", )} > {/* Header */} <div className="p-6 pb-2"> <div className="flex items-start justify-between"> <div> <DialogTitle as="h4">{title}</DialogTitle> <Description className="mt-1 text-sm"> {description} </Description> </div> <ClosePanelButton onClose={handleClose} /> </div> </div> {/* Contents */} <div className="mx-6 mb-12 max-h-[80dvh] overflow-y-auto sm:mb-6"> {children} </div> </DialogPanel> </TransitionChild> </div> </Dialog> </Transition> ); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-convex/convex-backend'

If you have feedback or need assistance with the MCP directory API, please join our Discord server