Button
The Button component is the primary action element. It supports 6 visual variants, 4 sizes, and can render as any element via the asChild prop.
Interactive example#
Button · Live example
These are actual UX buttons. Click them or use Tab, Enter, and Space.
The code uses shared demo presentation helpers. Their complete source and styling are included in the LLM build context.
Import#
TSX
import { Button, IconSearch } from '@clidey/ux';
Variants#
TSX
<Button variant="default">Default</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
| Variant | Description |
|---|---|
default | Solid primary color background. Use for the main action. |
destructive | Red background. Use for irreversible or dangerous actions. |
outline | Transparent background with border. Use for secondary actions. |
secondary | Muted background. Use for less prominent actions. |
ghost | No background or border, only hover state. Use in toolbars or inline. |
link | Underlined text, no button shape. Use for inline navigation actions. |
Sizes#
TSX
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon" aria-label="Search"><IconSearch /></Button>
| Size | Height | Use case |
|---|---|---|
sm | 32px (h-8) | Compact UIs, table rows |
default | 36px (h-9) | Standard forms and toolbars |
lg | 40px (h-10) | Hero sections, prominent CTAs |
icon | 36×36px | Icon-only buttons — use with aria-label |
With icons#
Place UX catalog icons inside the button. They automatically scale to match the button size:
TSX
import { IconPlus as Plus, IconDownload as Download, IconTrash as Trash2 } from '@clidey/ux';
<Button>
<Plus />
Add item
</Button>
<Button variant="outline">
<Download />
Export
</Button>
<Button variant="destructive" size="icon" aria-label="Delete">
<Trash2 />
</Button>
Loading state#
The loading prop displays a spinner and disables the button. Handle failure in your application and clear progress when the request finishes:
TSX
import { useState } from 'react';
import { Button } from '@clidey/ux';
export function SaveButton({ save }: { save: () => Promise<void> }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
return <>
<Button loading={loading} onClick={async () => {
setLoading(true);
setError('');
try { await save(); }
catch { setError('Could not save. Please try again.'); }
finally { setLoading(false); }
}}>{loading ? 'Saving…' : 'Save changes'}</Button>
{error && <p role="alert">{error}</p>}
</>;
}
Render as a link (asChild)#
Use asChild to render the button as an <a> tag or any other element while keeping button styles:
TSX
import { Button } from '@clidey/ux';
// Render as native anchor
<Button asChild>
<a href="/dashboard">Go to Dashboard</a>
</Button>
// With React Router
import { Link } from 'react-router-dom';
<Button asChild>
<Link to="/settings">Settings</Link>
</Button>
Full-width button#
TSX
<Button className="w-full">Create account</Button>
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "default" | Visual style variant. |
size | "default" | "sm" | "lg" | "icon" | "default" | Button size. |
asChild | boolean | false | Merge props onto the immediate child element instead of rendering a <button>. |
loading | boolean | false | Shows a spinner and disables the native button while pending. |
disabled | boolean | false | Disables the button and applies muted styling. |
className | string | — | Additional CSS classes. |
children | ReactNode | — | Button content. |
All standard <button> HTML attributes (onClick, type, form, etc.) are also accepted.
buttonVariants utility#
The buttonVariants function lets you apply button styles to non-button elements:
TSX
import { buttonVariants } from '@clidey/ux';
import { Link } from 'react-router-dom';
<Link to="/home" className={buttonVariants({ variant: 'outline', size: 'sm' })}>
Home
</Link>
Was this page helpful?
