Button
A versatile button component with multiple variants, styles, and sizes. The button automatically adapts its appearance based on the current brand theme.
Button Playground
Button Playground
Preview
Code
Controls
Variant:
Primary
Neutral
Error
Style:
Filled
Thematic
Subtle
Outline
Size:
Small
Medium
Large
Icon Only:
Leading Icon:
Trailing Icon:
Disabled:
Loading:
Full Width:
Installation
You can add the button component to your project manually:
1
Install the following dependencies:
npm
pnpm
yarn
bun
npm install class-variance-authority clsx tailwind-merge @react-aria/focus @react-aria/interactions2
Copy and paste the following code into your project.
Button.tsx
Loader.tsx
cn.ts
Loading source code...
3
Update the import paths to match your project setup.
Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.
Basic Usage
A simple button with default styling:
import { Button } from '@versaui/ui/components/Button';
<Button>Click Me</Button>Variants
Three semantic color variants control the button's palette:
// Primary (default) — main actions
<Button variant="primary">Save</Button>
// Neutral — secondary actions
<Button variant="neutral">Cancel</Button>
// Error — destructive actions
<Button variant="error">Delete</Button>Button Styles
Four visual styles control the button's surface treatment:
// Filled (default) — solid background
<Button buttonStyle="filled">Filled</Button>
// Thematic — gradient background
<Button buttonStyle="thematic">Thematic</Button>
// Subtle — transparent with hover background
<Button buttonStyle="subtle">Subtle</Button>
// Outline — border only
<Button buttonStyle="outline">Outline</Button>Sizes
Three sizes available — small, medium (default), and large:
<Button size="small">Small</Button>
<Button size="medium">Medium</Button>
<Button size="large">Large</Button>Icons
Add leading and/or trailing icons. Icon sizes are automatically matched to the button size:
import { PlusIcon, ArrowRightIcon } from '@phosphor-icons/react';
// Leading icon
<Button leadingIcon={<PlusIcon />}>Add Item</Button>
// Trailing icon
<Button trailingIcon={<ArrowRightIcon />}>Continue</Button>
// Both icons
<Button leadingIcon={<PlusIcon />} trailingIcon={<ArrowRightIcon />}>
Create
</Button>
// Icon-only (no children)
<Button leadingIcon={<PlusIcon />} />States
// Loading — shows spinner, disables interaction
<Button loading>Saving...</Button>
// Disabled
<Button disabled>Disabled</Button>
// Full width
<Button fullWidth>Full Width Button</Button>Accessibility
- Full keyboard navigation support
- Focus ring visible on keyboard focus via
@react-aria/focus - Proper ARIA attributes for loading and disabled states
- Screen reader announcements for state changes
- Active press scale animation for visual feedback
Button Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Button label content. Omit for icon-only buttons. |
variant | 'primary' | 'neutral' | 'error' | 'primary' | Semantic color variant. |
buttonStyle | 'filled' | 'thematic' | 'subtle' | 'outline' | 'filled' | Visual style variant. |
size | 'small' | 'medium' | 'large' | 'medium' | Button size. Also controls icon sizing. |
leadingIcon | ReactNode | — | Icon before the label. |
trailingIcon | ReactNode | — | Icon after the label. |
disabled | boolean | false | Prevents interaction. |
loading | boolean | false | Shows loading spinner and disables interaction. |
fullWidth | boolean | false | Stretches to container width. |
className | string | — | Additional CSS classes. |