edbnedbn/ui
Get Started
WelcomeChoosing a VariantChangelogLicense
Components
OverviewButton
Alert DialogPopoverDropdown MenuPull Down MenuSheet
Motion Utilities
Motion ProviderSpring PresetsHooks
0installs
Components
BlocksMaps
HomeDocsComponentsAnimatedButton

On this page

Button

A unified button component with motion animations, loading states, and icon support. Built on Radix UI Slot with Premium spring physics.

Usage

import { Button } from "@/components/ui/animated/button"
<Button variant="outline">Button</Button>

Installation

Install via CLI

TypeScript
npx edbn-ui add button

Install dependencies

TypeScript
npm install motion class-variance-authority @radix-ui/react-slot @phosphor-icons/react

Set up MotionProvider

Wrap your app with the MotionProvider for animation support.

TypeScript
// app/layout.tsx
import { MotionProvider } from "@/components/motion-provider"

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <MotionProvider>{children}</MotionProvider>
      </body>
    </html>
  )
}

Import and use

TypeScript
import { Button, IconButton, buttonVariants } from "@/components/ui/animated/button"

export default function MyComponent() {
  return <Button variant="default">Click me</Button>
}
Looking for a lighter alternative? Check out the Static Button which uses CSS transitions instead of spring animations.

Examples

Variants

Six visual styles to match different contexts and actions.

Sizes

Multiple size options for different contexts and layouts.

With Icons

Add icons at the start or end of the button with smooth enter/exit animations.

Loading State

Built-in loading spinner with automatic button disabling.

Success State

Show a success checkmark with animation after completing an action.

Ripple Effect

Material Design-inspired ripple effect on click for enhanced visual feedback. Automatically enabled on all variants except ghost and link.

The ripple effect uses currentColor, so it automatically adapts to your button's text color. It fades smoothly during loading and success state transitions.

Icon Button

Square buttons for icon-only actions with required accessible labels.

Animation Control

Disable animations per-component or respect system reduced-motion preferences.

As Child (Composition)

Merge button styles with any child element using Radix Slot.

TypeScript
import Link from "next/link"

{/* Render as a link with button styles */}
<Button asChild>
  <Link href="/dashboard">Go to Dashboard</Link>
</Button>

{/* Use with any component */}
<Button asChild variant="ghost">
  <a href="https://github.com" target="_blank">
    View on GitHub
  </a>
</Button>

API Reference

Button Props

PropTypeDefaultDescription
variant"default" | "destructive" | "outline" | "secondary" | "ghost" | "link""default"Visual style of the button
size"sm" | "default" | "lg" | "xl" | "icon" | "icon-sm" | "icon-lg""default"Size of the button
loadingbooleanfalseShow loading spinner and disable button
successbooleanfalseShow success checkmark with animation
iconStartLucideIcon—Icon displayed at the start (left)
iconEndLucideIcon—Icon displayed at the end (right)
disableAnimationbooleanfalseDisable motion animations
asChildbooleanfalseMerge props with child element

IconButton Props

PropTypeDefaultDescription
iconLucideIconRequiredThe icon to display
aria-labelstringRequiredAccessible label for screen readers

Accessibility

Built with WCAG 2.1 guidelines. Keyboard and screen reader support included.

Keyboard

TabMove focus to button
Enter/Space
Activate button

Screen Readers

• Icon buttons require aria-label

• Loading states use aria-busy

• Spinners are aria-hidden

Best Practices

Stable dimensions
Keep button width constant across loading and success states.
Announce changes
Use a toast or live region to inform users of async results.
Restore focus
After async actions complete, return focus to the triggering element.

Motion Preferences

Respects prefers-reduced-motion. Override with disableAnimation prop or MotionProvider.