# Button
A versatile button component with multiple variants, sizes, icon support, and loading states.
# Button
Displays a button or a component that looks like a button with extensive customization options.
## Installation
Download the Button component using the Frontfriend CLI:
```bash
npx frontfriend download button
```
This will install the Button component along with its dependencies (Icon, Spinner components).
## Usage
```tsx
import { Button } from '@/components/ui/button';
export default function Demo() {
return ;
}
```
```vue
```
## API Reference
### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'main' \| 'destructive' \| 'tertiary' \| 'secondary' \| 'ghost' \| 'ghostmain' \| 'link' \| 'linkDestructive'` | `'main'` | Visual style variant |
| `size` | `'default' \| 'sm' \| 'lg'` | `'default'` | Button size |
| `icon` | `keyof typeof icons` | `undefined` | Icon to display |
| `iconPosition` | `'prefix' \| 'suffix' \| 'default'` | `'default'` | Icon position. Use 'default' for icon-only buttons |
| `loading` | `boolean` | `false` | Show loading spinner |
| `loadingText` | `string` | `undefined` | Custom text to show during loading |
| `asChild` | `boolean` | `false` | Compose with child element using Radix Slot |
| ...rest | `React.ButtonHTMLAttributes` | - | All standard button HTML attributes |
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'main' \| 'destructive' \| 'tertiary' \| 'secondary' \| 'ghost' \| 'ghostmain' \| 'link' \| 'linkDestructive'` | `'main'` | Visual style variant |
| `size` | `'default' \| 'sm' \| 'lg'` | `'default'` | Button size |
| `icon` | `IconName` | `undefined` | Icon to display |
| `iconPosition` | `'prefix' \| 'suffix' \| 'default'` | `'default'` | Icon position. Use 'default' for icon-only buttons |
| `loading` | `boolean` | `false` | Show loading spinner |
| `loadingText` | `string` | `undefined` | Custom text to show during loading |
| `as` | `keyof HTMLElementTagNameMap` | `'button'` | HTML element to render as |
| `asChild` | `boolean` | `false` | Compose with child element using Radix Primitive |
| `label` | `string` | `'Button'` | Fallback text when no slot content provided |
| `class` | `string` | `undefined` | Additional CSS classes |
| ...rest | `ButtonHTMLAttributes` | - | All standard button HTML attributes |
## Examples
### Variants
The Button component supports 8 different visual variants to match different use cases.
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
export default function VariantsDemo() {
return (
);
}
```
```vue
```
### Sizes
Three size options are available: small, default, and large.
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
export default function SizesDemo() {
return (
);
}
```
```vue
```
### With Icons
Buttons can display icons in three different positions: prefix (before text), suffix (after text), or default (icon-only).
#### Icon Prefix
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
export default function IconPrefixDemo() {
return (
);
}
```
```vue
```
#### Icon Suffix
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
export default function IconSuffixDemo() {
return (
);
}
```
```vue
```
#### Icon Only
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
export default function IconOnlyDemo() {
return (
);
}
```
```vue
```
### Loading State
Display a loading spinner and optional loading text while an async action is in progress.
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
import { useState } from 'react';
export default function LoadingDemo() {
const [isLoading, setIsLoading] = useState(false);
const handleClick = async () => {
setIsLoading(true);
await new Promise(resolve => setTimeout(resolve, 2000));
setIsLoading(false);
};
return (
);
}
```
```vue
```
### As Child (Composition)
Use the `asChild` prop to compose the Button with other components, such as links.
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
import Link from 'next/link';
export default function AsChildDemo() {
return (
);
}
```
```vue
```
### Disabled State
*Historical interactive example. See the [current Button reference](/docs/components/react-radix/button/) for live examples.*
```tsx
import { Button } from '@/components/ui/button';
export default function DisabledDemo() {
return (
);
}
```
```vue
```
## Design Tokens
The Button component uses design tokens from `@frontfriend/tailwind` for consistent theming. All colors, spacing, and typography are controlled through the design token system, ensuring consistency across your application.
## Accessibility
- Button includes proper ARIA attributes
- Icon-only buttons should include an `aria-label` for screen readers
- Disabled state is properly communicated to assistive technologies
- Loading state maintains button focus and communicates status
## Related Components
- **Icon**: Used internally for displaying icons
- **Spinner**: Used for loading states