mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-14 15:42:02 +02:00
31 lines
1.2 KiB
TypeScript
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));
|
|
}
|