React + MotionButtons

Expanding actions button

One button that opens up to show a couple of extra actions, with the plus turning into a cross.

Settings

Code

import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { ChevronDown, Plus, Share2 } from "lucide-react";

interface ExpandingMenuButtonProps {
  text?: string;
}

export default function ExpandingMenuButton({
  text = "Actions",
}: ExpandingMenuButtonProps) {
  const [open, setOpen] = useState(false);

  return (
    <motion.div
      layout
      transition={{ type: "spring", stiffness: 300, damping: 30 }}
      className="overflow-hidden rounded-[26px] bg-white dark:bg-[#1c1c1e] p-1 text-[#1d1d1f] dark:text-[#f5f5f7] shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)]"
    >
      <button
        type="button"
        aria-expanded={open}
        onClick={() => setOpen((v) => !v)}
        className="flex h-12 items-center gap-2 rounded-full px-4 text-sm font-medium"
      >
        <Plus className={`h-4 w-4 transition-transform ${open ? "rotate-45" : ""}`} />
        {text}
        <ChevronDown className={`h-4 w-4 transition-transform ${open ? "rotate-180" : ""}`} />
      </button>
      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: "auto", opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            className="flex gap-1 overflow-hidden px-1 pb-1"
          >
            <button
              type="button"
              className="rounded-full bg-black/5 px-4 py-2 text-sm dark:bg-white/10"
            >
              Save
            </button>
            <button
              type="button"
              className="flex items-center gap-1 rounded-full bg-black/5 px-4 py-2 text-sm dark:bg-white/10"
            >
              <Share2 className="h-4 w-4" /> Share
            </button>
          </motion.div>
        )}
      </AnimatePresence>
    </motion.div>
  );
}

Prompt for AI

Paste it into ChatGPT, Claude or Cursor and it will adapt the block to your project with these settings, even if you don’t use React.

More in Buttons

Where to use it

Not every action deserves its own button. This one keeps secondary options like “Save” and “Share” tucked away until someone asks for them, which is handy on a recipe card, a product page in a shop or a document in a client portal. Think of it as a compact expandable action menu in React.

Two or three actions is the sweet spot; beyond that, a proper dropdown menu is easier to scan. Give the main label a verb people understand, like “Options” or “More”, instead of an icon on its own.