Skip to content

Orbital Action Menu

A radial menu that fans actions along an arc, evenly spaced at any count.

DOM + CSS2 deps1 file · 4 KB TSX

Proplayfulminimalglass
Preview

Props

62
180
180
Hover label

The source is part of Pro

$27/month or $179 once. See Pro

Requires framer-motion, lucide-react
"use client";

import { useState, type ReactNode } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { Plus } from "lucide-react";

type Action = { id: string; icon: ReactNode; label: string };

export function OrbitalActionMenu({
  actions,
  radius = 62,
  spread = 180,
  startAngle = 180,
  showLabels = true,
}: {
  actions: Action[];
  radius?: number;
  /** Total arc in degrees. */

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Details

About this component

Radial menus are usually built by hand-placing each item, which looks fine in the demo and falls apart the first time someone adds a seventh action. Computing position from polar coordinates instead makes the arc self-distributing: normalise the index across the item count, map it onto the spread, and take the cosine and sine at the radius. Dividing by count minus one rather than by count is the detail that matters — it places the first and last items exactly on the arc's ends instead of leaving a gap at one side. Because spread and start angle are parameters, the same component covers a quarter-arc fanning up from a bottom-right button and a full 360-degree ring around a centred trigger. Two motion choices make it feel considered rather than merely animated: items travel out from the trigger's own centre, so the fan reads as unfolding from the button rather than fading in beside it, and the plus rotates 135 degrees into a close X — one element in continuous motion, not an icon swap. Icon-only buttons need labels, so every action carries one.

Curator’s note

Built for viberdy 2.1. Polar placement from the index rather than hand-tuned offsets — the difference shows the moment you add an item.

Pairs well with

Pro