Dynamic Island in Framer Motion

One pill grows into a notification, a music player or a search box, overshooting a little each time before it settles. React, Tailwind, Framer Motion.

By buying you agree to the Terms and ask for instant access, so you lose the 14-day withdrawal right. When we still refundWe'll also email you when a new piece lands (about once a week). Unsubscribe in one click, anytime.

Just this one, or all 16?

Dynamic Island Navbar$3

Just this one component.

The Shelf (All-Access)$29$54 if bought one by one

All 16 components and templates in the catalogue today, this one included. Pay once, keep them.

By buying you agree to the Terms and ask for instant access, so you lose the 14-day withdrawal right. When we still refundWe'll also email you when a new piece lands (about once a week). Unsubscribe in one click, anytime.

Full product pageReact · Tailwind · TypeScript

Dynamic Island Navbar, preview

Use it in Next.js

app/Header.tsx

"use client";
import DynamicIsland from "@/components/DynamicIsland";

export default function Header() {
  return (
    <div className="relative h-64">
      <DynamicIsland
        items={["Docs", "Pricing", "Changelog"]}
        notificationTitle="Deploy finished"
        notificationText="main is live"
        onStateChange={(state) => console.log(state)} // "idle" | "notify" | "music" | "search"
        onSelect={(item) => console.log(item)}
      />
    </div>
  );
}

Good to know

  • The Dynamic Island navbar page below has the rest of the props and callbacks.
  • The island is one motion.nav. Framer Motion animates its width, height and border radius between four sizes, one per state.
  • It isn't a spring. Width and height use a 0.6 s tween on a cubic-bezier that overshoots (0.32, 1.32, 0.5, 1), so the pill bulges past its size and settles back. The radius eases without the overshoot.
  • It doesn't use the layout prop or layoutId. The sizes sit in a SIZES table at the top of DynamicIsland.tsx, so you change them in one place.
  • What's inside each state fades and slides in with CSS transitions after a short delay, once the pill has room.
  • Search adds 62 px of height per result. A notification closes by itself after notificationMs (2.2 s by default), and Escape or a click outside folds the island back.
  • useReducedMotion sets the pill's transition to 0, and the CSS transitions are cut to almost nothing.

Install

  1. Copy from the zipPut react/src/components into src/, then npm i framer-motion.
  2. Or ask your AIPaste PROMPT.md into Cursor, Lovable or v0.

Props

onStateChange
called with idle, notify, music or search
items
what search finds
notificationMs
how long the notification stays
accent
any hex colour

How qodesign compares

All comparisons, with prices read on each library's own site.

From the blog: How to Animate Height Auto in React and Tailwind CSS

From the blog: Hide Navbar on Scroll Down in React and Tailwind

Questions

Which framer-motion version does it need?

The package.json asks for framer-motion ^11.11.0. We haven't tested it with the motion package's motion/react import yet.

Why explicit sizes instead of layout animations?

The pill's size is fixed per state in one table, so you always know how big it gets. You can switch to the layout prop yourself, but that's not what ships.

Does the island work in Next.js?

Yes, as a client component. Keep "use client" at the top of the file that renders it, as in the snippet above. App Router and Pages Router both work.

Can Cursor or v0 add it for me?

Yes. Each download has a PROMPT.md. Paste it into Cursor, Lovable, v0 or Claude Code and it fits the piece into your app.

Can I use it in client work?

Yes, in personal and client projects. You can't resell the code itself as a kit.