import React, { useEffect } from 'react'; import { X } from 'lucide-react'; import { useKeyboardInset } from '../lib/useKeyboardInset'; interface FormSheetProps { title: string; icon?: React.ReactNode; onClose: () => void; onSubmit: (e: React.FormEvent) => void; children: React.ReactNode; // the fields submitLabel?: string; danger?: boolean; // red submit button for destructive actions busy?: boolean; // Desktop only: open next to the click instead of centred anchor?: { x: number; y: number } | null; } // Small create/rename dialogs. Phone: bottom sheet directly above the keyboard, full width, large // fields. Desktop: centred dialog (or next to the click). Escape and the backdrop close it. export const FormSheet: React.FC = ({ title, icon, onClose, onSubmit, children, submitLabel = 'Erstellen', anchor, danger = false, busy = false, }) => { const { inset, visibleHeight } = useKeyboardInset(); useEffect(() => { const onKey = (e: KeyboardEvent) => e.key === 'Escape' && onClose(); window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [onClose]); const desktopAnchor = anchor ? ({ '--sheet-left': `${anchor.x}px`, '--sheet-top': `${anchor.y}px`, '--sheet-x': `clamp(12px, calc(${anchor.x}px - 8.25rem), calc(100vw - 16.5rem - 12px))`, '--sheet-y': `calc(${anchor.y}px + 8px)`, } as React.CSSProperties) : undefined; return (
e.stopPropagation()} style={ { ...desktopAnchor, '--kb-inset': `${inset}px`, '--vv-max': visibleHeight ? `${visibleHeight - 16}px` : '85vh', } as React.CSSProperties } className={`fixed inset-x-0 bottom-[var(--kb-inset)] max-h-[var(--vv-max)] panel-surface rounded-t-2xl border-t border-border shadow-panel p-4 space-y-3 overflow-y-auto sm:inset-x-auto sm:bottom-auto sm:max-h-[85vh] sm:w-full sm:rounded-card sm:border ${ anchor ? 'sm:max-w-[16.5rem] sm:left-[var(--sheet-x)] sm:top-[var(--sheet-y)]' : 'sm:max-w-sm sm:left-1/2 sm:top-1/2 sm:-translate-x-1/2 sm:-translate-y-1/2' }`} >