Context Menu
@sushindustries/uiOne menu, reachable by right-click, by long press, and by a button that is always there.
tanstacktanstack add https://adamjurek.com/r/tanstack/context-menu.jsonpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/context-menu.jsonActions are the consumer's
const menu = useContextMenu();
<div {...menu.triggerProps}>
<button {...menu.buttonProps}>Actions</button>
</div>
<ContextMenu state={menu} actions={actions} />tsx
MenuAction is an id, a label, an optional glyph and hint, and an onSelect
that may be async. This component knows how to summon a menu and where to put
it; it does not know what "save as Markdown" means and should not.
Where this is used
| Where | Actions |
|---|---|
FolderShelf tiles and rows | supplied by actionsFor |
| The home page desktop | apps/web/src/modules/chrome/shelf-actions.ts |
Those actions are worth reading as an example of degrading rather than hiding: the share sheet is not on most desktop browsers and the clipboard is not available over plain HTTP, and neither is a reason to remove a menu item. Each falls back to the thing the reader would have done by hand.