import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@repo/shadcn-ui/components"; // hooks/use-pinned-preview-sheet.ts import * as React from "react"; type UsePinnedPreviewSheetOptions = { /** Persiste el pin en localStorage (clave). Si omites, no persiste. */ persistKey?: string; /** Anchura del panel anclado (Tailwind). */ pinnedWidthClass?: string; // p.ej. "w-[420px]" /** Título del Sheet (no anclado). */ title?: string | ((item: T | null) => string); }; export type PinnedPreviewSheetAPI = { /** Estado */ isOpen: boolean; isPinned: boolean; item: T | null; /** Acciones */ open: (item: T) => void; close: () => void; togglePin: () => void; setItem: (item: T | null) => void; /** Renderizado: coloca este nodo cerca del listado (al final de la página/feature) */ PreviewContainer: React.FC<{ /** Render del cuerpo del preview */ children: (item: T) => React.ReactNode; /** Cabecera opcional (si quieres sustituir el SheetHeader) */ header?: React.ReactNode; }>; }; export function usePinnedPreviewSheet( opts?: UsePinnedPreviewSheetOptions ): PinnedPreviewSheetAPI { const { persistKey, pinnedWidthClass = "w-[420px]", title } = opts ?? {}; const [isOpen, setOpen] = React.useState(false); const [item, setItem] = React.useState(null); const [isPinned, setPinned] = React.useState(() => { if (!persistKey) return false; try { return localStorage.getItem(persistKey) === "1"; } catch { return false; } }); const open = React.useCallback((next: T) => { setItem(next); setOpen(true); }, []); const close = React.useCallback(() => { if (isPinned) return; // Anclado: no cerrar setOpen(false); }, [isPinned]); const togglePin = React.useCallback(() => { setPinned((p) => { const next = !p; if (persistKey) { try { localStorage.setItem(persistKey, next ? "1" : "0"); } catch { } } // Si se fija el pin y hay item, abre “estático”; si se desancla, mostramos Sheet si había abierto if (!next && item) setOpen(true); return next; }); }, [persistKey, item]); const HeaderTitle = React.useMemo(() => { if (!item) return ""; if (typeof title === "function") return title(item); return title ?? ""; }, [item, title]); const PreviewContainer: PinnedPreviewSheetAPI["PreviewContainer"] = React.useCallback( ({ children, header }) => { if (!item) return null; // Modo anclado: aside fijo sin overlay, no bloquea scroll, accesible. if (isPinned) { return ( ); } // Modo Sheet (deslizable desde la derecha) return ( (o ? setOpen(true) : close())}> {header ?? ( {HeaderTitle} )}
{children(item)}
); }, [HeaderTitle, close, isOpen, isPinned, item, pinnedWidthClass, togglePin] ); return { isOpen, isPinned, item, open, close, togglePin, setItem, PreviewContainer }; }