Skip to content

Circle Button

A round call to action: two circles slide together while the arrow turns to point up-right.

$npx shadcn@latest add https://framebrick.co/r/circle-button.json

From the Compose Digi template, see it in context.

Tell us your
new ideas

Installation

$ npx shadcn@latest add https://framebrick.co/r/circle-button.json

Usage

import { CircleButton } from "@/components/ui/circle-button";

<div className="flex items-center justify-between">
  <h2 className="text-4xl font-semibold">Tell us your new ideas</h2>
  <CircleButton href="/contact" label="Contact us" />
</div>

Props

PropTypeDefaultDescription
labelstring—The accessible name: the button shows only an arrow.
sizenumber62Diameter of each circle, in px.
gapnumber32How far apart the circles rest, in px; they meet in the middle. The closed button is size + gap wide.
iconReactNode—An svg in place of the arrow; it takes its colour from the text colour and turns the same way.
hrefstring—Render a Next.js link instead of a button. http(s) links open in a new tab.
…propsbutton / anchor props—Passed to the element (onClick, aria-*, Motion props).
  • It is Compose Digi's footer call to action: two 62 px circles, a pale one and a dark one holding an arrow, 32 px to its right. On hover and on keyboard focus they slide together until they overlap, so what is left is one dark circle, while the arrow turns from right to up-right (0° → −45°). One over-damped spring drives all three moves — stiffness 500, damping 60, mass 1, no overshoot, about 0.65 s — and leaving mirrors it.
  • There is no visible text, so `label` is the accessible name (an aria-label). The icon is decorative.
  • The closed button is size + gap wide and size tall, so it takes the same room open or closed, and the focus ring follows that pill.
  • The pale circle is the foreground at 20% and the dark one is bg-primary with text-primary-foreground, so a themed project gets its own colours; the arrow's contrast is the theme's primary against its foreground.
  • Transforms only, so <MotionConfig reducedMotion="user"> skips them.

AI prompt

Paste into v0, Lovable, Bolt or Claude to rebuild this component in your own project.

Create a React + Tailwind CSS + Motion (motion/react) component called CircleButton — a round call to action made of two circles.
- Props: label (the accessible name, set as aria-label), size (circle diameter in px, 62), gap (how far apart they rest, 32), icon
  (an svg in place of the default arrow), href (a Next.js Link via motion.create(Link); external http(s) links open in a new tab,
  otherwise a motion.button), className.
- The root is relative block rounded-full, width size + gap and height size, with a visible focus ring (ring-[3px] ring-ring/50).
- Two absolutely positioned circles of the given size at top-0 left-0: a pale one (bg-foreground/20) and, on top, a dark one (bg-primary,
  text-primary-foreground) with a right arrow in it (a 24px viewBox, stroke 1.25, round caps, 58% of the circle's width).
- Variants rest and hover (also on keyboard focus), one spring for everything: stiffness 500, damping 60, mass 1. The pale circle's
  x goes from 0 to gap / 2, the dark one's from gap to gap / 2 (so they overlap), and the arrow's wrapper rotates from 0 to -45°.

Be the first to know

Get new templates and components first

One short email when we release a template or a free component. No spam — unsubscribe anytime.

We use your email only for Framebrick updates. Privacy policy