
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