
ray-menu
Radial (pie) menu for the web. Framework-agnostic. Zero dependencies.
- Web Component — Works with any framework or vanilla HTML
- React bindings —
useRayMenu hook with full TypeScript support - Infinite selection — Select by angle, not distance
- Submenus — Nested menus with async loading support
- Keyboard nav — Arrow keys, number keys, escape
- Drag & drop — Use as a drop target with any drag library
- Theming — CSS variables with
--ray-* prefix - Edge detection — Auto-flip near screen edges
<script type="module"> import "ray-menu"; const menu = document.querySelector("ray-menu"); menu.items = [ { id: "copy", label: "Copy" }, { id: "paste", label: "Paste" }, { id: "delete", label: "Delete" }, ]; document.addEventListener("contextmenu", (e) => { e.preventDefault(); menu.open(e.clientX, e.clientY); }); menu.addEventListener("ray-select", (e) => { console.log("Selected:", e.detail); }); </script> <ray-menu></ray-menu> import { useRayMenu } from "ray-menu/react"; function App() { const menu = useRayMenu({ items: [ { id: "copy", label: "Copy" }, { id: "paste", label: "Paste" }, ], onSelect: (item) => console.log(item), }); return ( <div onContextMenu={(e) => { e.preventDefault(); menu.open(e.clientX, e.clientY); }} > Right-click me </div> ); } ray-menu { --ray-bg: #1a1a2e; --ray-text: #ffffff; --ray-accent: #ff6b6b; } | Attribute | Default | Description |
radius | 120 | Menu radius in pixels |
inner-radius | 40 | Center dead zone |
variant | slice | "slice" or "bubble" |
show-trail-path | false | Cursor trail effect |
show-anchor-line | false | Line from menu to cursor |
start-angle | -90 | Start angle in degrees |
sweep-angle | 360 | Arc span (180 = half circle) |
| Method | Description |
open(x, y) | Open at position |
close() | Close menu |
toggle(x, y) | Toggle at position |
| Event | Description |
ray-select | Item selected |
ray-open | Menu opened |
ray-close | Menu closed |
| Import | Description |
ray-menu | Web Component |
ray-menu/react | React bindings |
ray-menu/core | Pure math utilities |
Full documentation at ray-menu.vercel.app/docs
MIT