Radial menuNew
One starting point, a few ways forward. Commands unfold into a small clockwise constellation.
Install with the shadcn CLI
Overview
Put a compact set of creative commands around the control that opens them. Fine spokes grow from the centre, buttons travel out with a 24ms stagger, and the source turns into a close control. Each command has a visible name and a real menu button. Selection folds the constellation home and returns focus to its source.
States
- open
- Commands move to fixed clockwise anchors over 460ms, staggered by 24ms. The first enabled command receives focus.
- navigate
- Arrow keys move through enabled commands in the same order as the ring. Home and End reach the first and last.
- choose
- Selecting a command calls onSelect with its id, closes the menu and returns focus to the central control.
- close
- Escape, a second trigger click or focus leaving the menu folds commands home. Closed items are inert.
Usage
A starting point in a canvas
Keep the commands short and local to a creative workspace. Four to six items give names enough breathing room; the component reserves its own space rather than covering surrounding content.
Props
| Prop | Type | Description |
|---|---|---|
| items | RadialMenuItem[] | Commands with id, short label, icon and optional disabled. |
| onSelect | (id: string) => void | Runs the selected command. The application owns what it creates. |
| label | stringdefault Insert | Accessible name of the trigger and menu. |
| open / defaultOpen | booleandefault false | Controlled or initial disclosure state. |
| onOpenChange | (open: boolean) => void | Reports opening and closing requests. |
| disabled | booleandefault false | Disables the source and keeps the menu closed. |
Accessibility and motion
- The trigger exposes aria-haspopup and aria-expanded. Arrow Down opens the menu; native Enter and Space also activate the trigger.
- Disabled commands are skipped during keyboard navigation. Escape and selection return focus to the trigger; Tab can leave normally.
- Geometry is measured only when the container resizes. Opening and closing move buttons and spokes through transforms and opacity.
- The reserved 284px canvas adapts its radius to the container. Use short labels and at least 240px of width.
- Reduced motion changes the disclosure in place without the stagger, travel or rotating source. Icons are supplied by your application.
Requirements
React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.
Source
Registry item: /r/radial-menu.json