import React, { useCallback, useRef } from 'react'; import { X } from 'lucide-react'; import { useFocusTrap } from '../../hooks/use-focus-trap'; import { Button } from '@/components/ui/button'; import { __ } from '../../lib/i18n'; /** * Accessible modal: role=dialog, aria-modal, Escape to close, focus moved * inside on open, Tab cycle kept within the dialog, focus restored on close. */ export function McpModal({ open, title, onClose, closeDisabled = false, children, }: { open: boolean; title: string; onClose: () => void; /** Blocks Escape/backdrop/X dismissal (used while showing a show-once secret). */ closeDisabled?: boolean; children: React.ReactNode; }) { const dialogRef = useRef(null); const titleId = useRef(`llmagnet-mcp-modal-${Math.random().toString(36).slice(2)}`).current; const tryClose = useCallback(() => { if (!closeDisabled) onClose(); }, [closeDisabled, onClose]); useFocusTrap(dialogRef, { active: open, onEscape: tryClose }); if (!open) return null; return (
{ if (e.target === e.currentTarget) tryClose(); }} >

{title}

{children}
); } /** Confirmation dialog built on McpModal (used for public_read + revoke flows). */ export function ConfirmDialog({ open, title, body, confirmLabel, cancelLabel = __('Cancel', 'llmagnet-llm-txt-generator'), destructive = false, busy = false, onConfirm, onCancel, }: { open: boolean; title: string; body: React.ReactNode; confirmLabel: string; cancelLabel?: string; destructive?: boolean; busy?: boolean; onConfirm: () => void; onCancel: () => void; }) { return (
{body}
); }