Metamorph

Menu Morph

The three menu bars become the menu: the button flows into the card and each bar into a row.

Preview

Installation

Terminal
npx @usefluid/cli add menu-morph

Usage

MenuMorph.tsx
import { MenuMorph } from "./MenuMorph";

const [open, setOpen] = useState(false);

<MenuMorph
  open={open}
  onOpenChange={setOpen}
  title="Acme"
  items={[
    { label: "Home", href: "/" },
    { label: "Orders", href: "/orders" },
    { label: "Help", onSelect: openHelp },
  ]}
/>

API reference

PropTypeDefaultDescription
openboolean—Whether the card is open.
onOpenChange(open) => void—Called on the button, Esc, a tap outside or choosing an item.
items{ label, href?, onSelect? }[]—Any number of rows. With href a row is a link.
titlestring—Heading shown on the open card.
labelstring"Menu"Accessible name of the button.
side"left" | "right""right"The side the card opens towards. Put the menu at that edge of your header.
widthnumber320Width of the open card in px; it never exceeds the screen.

Keyboard and screen readers

The button has aria-expanded. Esc and a tap outside close it; focus goes back to the button, unless an item's onSelect moved it somewhere on purpose.

Notes

Closed, it takes 48 x 48. Open, the card floats over the page (z-index 20), so place the menu in your header and nothing moves.

Every colour comes from the --fluid-* variables, and the piece is yours to change.

How it is made

Two contours of the engine. The round button flows to the size of the card, and the three bars each stretch into a row of the menu, all on springs with slightly different frequencies. Rows beyond three are born from a point. Then the words come out of a blur, one at a time. Esc, a tap outside or choosing an item closes it, and focus goes back to the button.

For your agent

For your agent

Add Menu Morph to my project with the Fluid library. Use MenuMorph as the mobile menu of my product, with its real sections. Read my project first. Use my logo, my colours and my font through the --fluid-* variables. Keep 44px touch targets, visible focus and reduced motion. If I have no SVG logo, ask before making one up.