framingui/docs
Components

Button

Trigger actions and events. Supports multiple variants, sizes, and states.

Import

import { Button } from '@framingui/ui';

Basic Usage

<Button>Click me</Button>

Variants

5 built-in variants for different contexts.

// Default - Primary actions
<Button variant="default">Save Changes</Button>

// Secondary - Less prominent actions
<Button variant="secondary">Cancel</Button>

// Outline - Bordered style
<Button variant="outline">Learn More</Button>

// Ghost - Minimal, no background
<Button variant="ghost">Skip</Button>

// Destructive - Dangerous actions
<Button variant="destructive">Delete Account</Button>

Sizes

<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon"><PlusIcon /></Button>

With Icons

import { Plus, ArrowRight, Loader2 } from 'lucide-react';

// Icon on the left
<Button>
  <Plus className="w-4 h-4 mr-2" />
  Add Item
</Button>

// Icon on the right
<Button>
  Continue
  <ArrowRight className="w-4 h-4 ml-2" />
</Button>

// Icon only
<Button size="icon" variant="outline">
  <Plus className="w-4 h-4" />
</Button>

Loading State

import { Loader2 } from 'lucide-react';

<Button disabled>
  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
  Please wait
</Button>

As Link

Use asChild to render as a different element.

import Link from 'next/link';

<Button asChild>
  <Link href="/dashboard">Go to Dashboard</Link>
</Button>

<Button asChild variant="outline">
  <a href="https://github.com" target="_blank">
    View on GitHub
  </a>
</Button>

Full Width

<Button className="w-full">
  Sign In
</Button>

Button Group

<div className="flex gap-2">
  <Button variant="outline">Cancel</Button>
  <Button>Save</Button>
</div>

// Stacked on mobile, inline on desktop
<div className="flex flex-col sm:flex-row gap-2">
  <Button variant="outline" className="w-full sm:w-auto">Cancel</Button>
  <Button className="w-full sm:w-auto">Confirm</Button>
</div>

Real World Examples

Form Submit Button

function ContactForm() {
  const [isSubmitting, setIsSubmitting] = useState(false);

  return (
    <form onSubmit={handleSubmit}>
      {/* form fields */}
      <Button type="submit" disabled={isSubmitting} className="w-full">
        {isSubmitting ? (
          <>
            <Loader2 className="w-4 h-4 mr-2 animate-spin" />
            Sending...
          </>
        ) : (
          'Send Message'
        )}
      </Button>
    </form>
  );
}

CTA Section

<div className="text-center space-y-4">
  <h2 className="text-3xl font-bold">Ready to get started?</h2>
  <p className="text-neutral-600">Start your free trial today.</p>
  <div className="flex justify-center gap-4">
    <Button size="lg">Start Free Trial</Button>
    <Button size="lg" variant="outline">Schedule Demo</Button>
  </div>
</div>

Danger Zone

<div className="border border-red-200 rounded-lg p-4 bg-red-50">
  <h3 className="font-semibold text-red-900">Delete Account</h3>
  <p className="text-sm text-red-700 mt-1">
    This action cannot be undone.
  </p>
  <Button variant="destructive" className="mt-4">
    Delete My Account
  </Button>
</div>

Props

PropTypeDefaultDescription
variantdefault | secondary | outline | ghost | destructivedefaultVisual style
sizesm | default | lg | icondefaultButton size
asChildbooleanfalseRender as child element
disabledbooleanfalseDisable interactions