v0.2 · TypeScript · Zero deps

Radial menus that predict
where you're going

Open a context menu and select items by moving your pointer in a direction — not by hovering over them. Includes safe triangle (safety triangle) dropdown submenu navigation.

Try the demo → Quick start Interactive docs
$ npm install prediction-cone
$ yarn add prediction-cone
$ pnpm add prediction-cone
$ bun add prediction-cone
Interactive

See it in action

Click inside the area below, then move your pointer in any direction.

Move your pointer after opening to select

Getting started

Quick start

main.ts
import { createPredictionConeMenu } from 'prediction-cone';

const menu = createPredictionConeMenu({
  items: [
    { id: 'home',     label: '🏠 Home'     },
    { id: 'profile',  label: '👤 Profile'  },
    { id: 'settings', label: '⚙️ Settings' },
    { id: 'logout',   label: '🚪 Logout'   },
  ],
  ringRadius:       120,
  itemSize:         60,
  coneHalfAngleDeg: 22.5,
  deadzone:         30,
});

menu.attach(document);

menu.on('select', (e) => {
  console.log('Selected:', e.item?.label);
});
Reference

API

.attach(element, options?)

Attach to a DOM element. Opens on the configured trigger event.

.detach()

Remove all event listeners previously added by .attach().

.openAt(x, y, ctx?)

Open the menu programmatically at given viewport coordinates.

.close()

Dismiss the menu without firing a select event.

.setItems(items)

Replace the item list at runtime without re-creating the menu.

.on(event, handler)

Subscribe to open, close, change, or select events.

Dropdown Menu

createDropdownMenu(options)

Create a list-based dropdown with triangle submenu navigation.

item.children

Add nested ConeItem[] to show a submenu with triangle-safe hover prediction.

Customization

CSS variables

Set any of these on an ancestor element to theme the menu.

--pcm-bg
Item background
--pcm-text
Item text color
--pcm-activeBg
Active item background
--pcm-activeText
Active item text color
--pcm-border
Border color
--pcm-shadow
Box shadow