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
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | default | secondary | outline | ghost | destructive | default | Visual style |
| size | sm | default | lg | icon | default | Button size |
| asChild | boolean | false | Render as child element |
| disabled | boolean | false | Disable interactions |