Highly ambitious ATProtocol AppView service and sdks
at fix-postgres 56 lines 1.7 kB view raw
1import { ComponentChildren } from "preact"; 2import { Text } from "./Text.tsx"; 3import { cn } from "../../utils/cn.ts"; 4 5type ModalSize = "sm" | "md" | "lg" | "xl"; 6 7interface ModalProps { 8 title: string; 9 description?: string; 10 children: ComponentChildren; 11 size?: ModalSize; 12 onClose?: string; // Hyperscript for close action, defaults to clearing modal-container 13} 14 15const sizeClasses = { 16 sm: "max-w-sm", 17 md: "max-w-lg", 18 lg: "max-w-3xl", 19 xl: "max-w-5xl", 20}; 21 22export function Modal({ 23 title, 24 description, 25 children, 26 size = "lg", 27 onClose = "on click set #modal-container's innerHTML to ''", 28}: ModalProps) { 29 return ( 30 <div 31 className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" 32 /* @ts-ignore - Hyperscript attribute */ 33 _={`on click if event.target === me then ${ 34 onClose.replace("on click ", "") 35 }`} 36 > 37 <div className={cn("bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-700 rounded-md p-6 w-full max-h-[90vh] overflow-y-auto", sizeClasses[size])}> 38 <div className="flex justify-between items-start mb-4"> 39 <div> 40 <Text as="h2" size="2xl" className="font-semibold">{title}</Text> 41 {description && <Text as="p" variant="secondary" className="mt-2">{description}</Text>} 42 </div> 43 <button 44 type="button" 45 /* @ts-ignore - Hyperscript attribute */ 46 _={onClose} 47 className="text-gray-400 dark:text-zinc-500 hover:text-gray-600 dark:hover:text-zinc-400 text-2xl leading-none" 48 > 49 50 </button> 51 </div> 52 {children} 53 </div> 54 </div> 55 ); 56}