"use client"; /** * MorePopover — generic secondary-action menu for the selection toolbar. * * The parent (`TextSelectionToolbar`) owns all side effects and builds * the appropriate `items` array based on auth state. Items can be marked * `locked` to render a small Lock badge — used for the public flow * where every More action sits behind the auth wall. */ import { type ReactNode, useEffect, useRef } from "react"; import { createPortal } from "react-dom"; import { Lock } from "lucide-react"; import { type Position } from "./shared"; import { Drawer, DrawerClose, DrawerContent, DrawerHeader, DrawerTitle, } from "@/components/ui/drawer"; export type MoreItem = { key: string; label: string; description: string; icon: ReactNode; onClick: () => void; /** Show a lock badge — indicates the action is behind the auth wall. */ locked?: boolean; }; export function MorePopover({ open, position, onClose, items, isMobile, }: { open: boolean; position: Position; onClose: () => void; items: MoreItem[]; isMobile: boolean; }) { const ref = useRef(null); useEffect(() => { if (!open || isMobile) return; function handleClick(e: MouseEvent) { if (ref.current && !ref.current.contains(e.target as Node)) onClose(); } // Delay so the click that opened us doesn't immediately fire it. const timer = setTimeout(() => { document.addEventListener("mousedown", handleClick); }, 10); return () => { clearTimeout(timer); document.removeEventListener("mousedown", handleClick); }; }, [open, onClose, isMobile]); if (!open) return null; // Mobile: bottom drawer if (isMobile) { return ( !o && onClose()}> More Options
{items.map((item) => ( ))}
); } // Desktop: floating popover anchored to `position`, flipping when it // would overflow the viewport. const popoverW = 260; const popoverH = items.length * 56 + 8; const pad = 8; let popLeft = position.x; let popTop = position.y + 8; if (popLeft + popoverW > window.innerWidth - pad) { popLeft = window.innerWidth - popoverW - pad; } if (popLeft < pad) popLeft = pad; if (popTop + popoverH > window.innerHeight - pad) { popTop = position.y - popoverH - 8; } if (popTop < pad) popTop = pad; return createPortal(
{items.map((item) => ( ))}
, document.body, ); }