Context Menu

@sushindustries/ui

One menu, reachable by right-click, by long press, and by a button that is always there.

4 min read
View as Markdown
Viewport width
Desktop100%whatever the page has
tanstacktanstack add https://adamjurek.com/r/tanstack/context-menu.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/context-menu.json

Three doors to the same room

Right-click is the interaction people ask for and the one fewest people can perform. A menu that is only reachable that way does not exist on a phone, does not exist for anyone navigating by keyboard, and does not exist for someone on a trackpad who has never found secondary click.

DoorWho uses it
Right-clickpointer, and it is what people expect of an icon
Long press, 450mstouch and pen. pointerType is checked, because a held mouse button is a drag, not a long press
A visible buttoneveryone else, including every keyboard user

The button is the important one, and it is always visible rather than revealed on hover. A control that only exists while a pointer is over it does not exist on a touch screen at all.

The long press cancels on movement

A press that turns into a drag is a scroll. Without the cancel, a menu opens in the face of anyone who scrolls the page with their thumb on a folder.

Install

tanstack add https://adamjurek.com/r/tanstack/context-menu.json
shell
pnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/context-menu.json
shell
pnpm add @sushindustries/ui @sushindustries/atoms
shell

What you get

Version0.1.0
Categorylayout · Overlays
Filescontext-menu.tsx, icon.tsx
Dependenciesreact-dom@^19.0.0
Tagsblock, menu, touch, keyboard, no-deps
Used byFolder ShelfFolder ShelfA desktop of folders that open into draggable windows, several at once, remembered between visits.@sushindustries/ui · layout