Radial Menu
betaA round button whose options fan out along an arc: press and drag onto one, click, or walk the ring with the keyboard.
- Navigation
- 1 file
- 1 npm package
- Accessibility notes
Loading the example…
pnpm dlx @dowel-ui/cli add radial-menunpm packages installed: class-variance-authority.
import { RadialMenu } from "@/components/ui/radial-menu";Default
Gallery
With Selection
Right To Left
<RadialMenu>
| Prop | Type | Default |
|---|---|---|
items (required) | RadialMenuItem[] | — |
arcAngular spread in degrees, centred on straight up. | number | 180 |
defaultOpen | boolean | false |
iconThe core's icon. It turns 135° while open, so a plus reads as a cross. | ReactNode | — |
labelThe core button's accessible name, and the menu's. | string | "Add" |
onOpenChange | (open: boolean) => void | — |
onSelectCalled with the chosen item's value. The menu then closes. | (value: string) => void | — |
open | boolean | — |
radiusDistance of the options from the core's centre, in px. | number | 68 |
staggerDelay between options flying out, in ms. | number | 28 |
stroke | boolean | — |
tone | "default" | "inverted" | "default" |
Plus every attribute of <div> except onSelect, part.
The core is a menu button (aria-haspopup="menu", aria-expanded, aria-controls) named by `label`; the options are role="menuitem" buttons named by their labels, in a role="menu" that is inert and aria-hidden while closed. Enter/Space opens and focuses the first option (Down/Up open onto the first or last); Left/Right and Up/Down walk around the ring with wrap-around (Left/Right follow the visual order in RTL), Home/End jump, Enter/Space select and return focus to the core, Escape closes and refocuses the core, Tab and an outside press close. The press-and-drag marking gesture is a pointer shortcut only; clicking and the keyboard reach every option. Captions are aria-hidden duplicates of the names. The fly-out settles instantly under reduced motion.
10/10
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — passes
- No fixed widths — passes