Something went wrong. Try again.
A local-first note taking app
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152import { createContext, useContext, type ReactNode } from 'react';
/** A single native context-menu entry. */export type ContextMenuItem = { id: string; label: string; type?: 'normal' | 'separator';};
/** Show a context menu; resolves with the chosen item id, or null if dismissed. */export type ShowContextMenu = ( items: ContextMenuItem[],) => Promise<string | null>;
/** * Default capability: no menu. Keeps `useContextMenu()` safe when no provider * is mounted (e.g. a non-Electron build or a test that doesn't supply one). */const ContextMenuContext = createContext<ShowContextMenu>(async () => null);
/** * Injects a context-menu capability into the tree. The composition root passes * the real (Electron) implementation; tests/storybook can pass a fake and * assert on the items it was given. */export function ContextMenuProvider({ show, children,}: { show: ShowContextMenu; children: ReactNode;}) { return ( <ContextMenuContext.Provider value={show}> {children} </ContextMenuContext.Provider> );}
/** Access the injected context-menu capability. */export function useContextMenu(): ShowContextMenu { return useContext(ContextMenuContext);}
/** * Electron-backed implementation, sourced from the preload bridge. This is the * single place that touches `window.textile.contextMenu`; wire it at the * composition root via `<ContextMenuProvider show={electronShowContextMenu}>`. */export const electronShowContextMenu: ShowContextMenu = async (items) => (await window.textile?.contextMenu.show(items)) ?? null;