Files
yaak-mountain-loop/apps/yaak-client/lib/contextMenu.ts
T

31 lines
1.2 KiB
TypeScript

import { atom } from "jotai";
import type { DropdownItem } from "../components/core/Dropdown";
import { jotaiStore } from "./jotai";
/**
* A menu opened from somewhere that can't render React.
*
* Most menus in the app are a `Dropdown` wrapped around their own trigger. This is for the
* cases where the trigger isn't a React component at all — a CodeMirror widget builds its DOM
* synchronously, so it can only hand over a position and a list of items. Same shape as
* {@link showDialog}.
*/
export interface ContextMenuInstance {
id: string;
/** Where to open, in viewport coordinates */
triggerPosition: { x: number; y: number };
/** The trigger's box, when it has one, so placement can align to its edges */
triggerRect?: Pick<DOMRect, "top" | "bottom" | "left" | "right">;
items: DropdownItem[];
}
export const contextMenusAtom = atom<ContextMenuInstance[]>([]);
export function showContextMenu({ id, ...props }: ContextMenuInstance) {
jotaiStore.set(contextMenusAtom, (m) => [...m.filter((c) => c.id !== id), { id, ...props }]);
}
export function hideContextMenu(id: string) {
jotaiStore.set(contextMenusAtom, (m) => m.filter((c) => c.id !== id));
}