evOo-local/apps/web/src/pages/shell/pointer-menu.tsx
Claude ebb3cecd97
refactor(web): share one PointerMenu for the space and section menus
The space and section context menus repeated the same dropdown with an
invisible trigger anchored at the pointer; only their label and items differ.

Move-only: PointerMenu in pages/shell renders that dropdown and both menus
pass their label, close handler and items. DOM, attributes and handlers are
unchanged, and the labels stay in ShellPage, so the catalogs do not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
2026-10-04 10:08:48 +00:00

42 lines
1.1 KiB
TypeScript

import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@rakazo/ui-web";
import type { ReactNode } from "react";
import type { ContextMenuPosition } from "../BotContextMenu";
/** A dropdown menu opened at the pointer, for sidebar context menus. */
export function PointerMenu({
position,
label,
onClose,
children,
}: {
position: ContextMenuPosition;
label: string;
onClose: () => void;
children: ReactNode;
}) {
return (
<DropdownMenu
open
onOpenChange={(open) => {
if (!open) onClose();
}}
>
{/* Invisible anchor at the pointer position, mirroring the bot menu. */}
<DropdownMenuTrigger
render={
<button
type="button"
tabIndex={-1}
aria-hidden
className="fixed size-0 p-0 opacity-0"
style={{ left: position.x, top: position.y }}
/>
}
/>
<DropdownMenuContent aria-label={label} align="start" sideOffset={0} className="w-[220px]">
{children}
</DropdownMenuContent>
</DropdownMenu>
);
}