"use client" import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from "react" import { createPortal } from "react-dom" import { cn } from "@/lib/utils" export interface AnchorRect { left: number top: number width: number height: number } /** * Carte flottante ancrée à un rectangle (popover détails / création rapide), * positionnée en `fixed` et recadrée dans la fenêtre. */ export function AgendaFloatingCard({ anchor, onClose, children, className, width = 416, }: { anchor: AnchorRect onClose: () => void children: ReactNode className?: string width?: number }) { const cardRef = useRef(null) const [pos, setPos] = useState<{ left: number; top: number } | null>(null) useLayoutEffect(() => { const card = cardRef.current if (!card) return const margin = 8 const vw = window.innerWidth const vh = window.innerHeight const rect = card.getBoundingClientRect() const w = Math.min(width, vw - margin * 2) const h = rect.height // Préférence : à droite de l'ancre, sinon à gauche, sinon en dessous. let left = anchor.left + anchor.width + margin if (left + w > vw - margin) left = anchor.left - w - margin if (left < margin) left = Math.min(Math.max(margin, anchor.left), vw - w - margin) let top = anchor.top if (top + h > vh - margin) top = vh - h - margin if (top < margin) top = margin setPos({ left, top }) }, [anchor, width, children]) useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") { e.stopPropagation() onClose() } } window.addEventListener("keydown", onKey, true) return () => window.removeEventListener("keydown", onKey, true) }, [onClose]) if (typeof document === "undefined") return null return createPortal(
, document.body, ) }