Clidey UXDocs

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

Clicked 0 times

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>
VariantDescription
defaultSolid primary color background. Use for the main action.
destructiveRed background. Use for irreversible or dangerous actions.
outlineTransparent background with border. Use for secondary actions.
secondaryMuted background. Use for less prominent actions.
ghostNo background or border, only hover state. Use in toolbars or inline.
linkUnderlined 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>
SizeHeightUse case
sm32px (h-8)Compact UIs, table rows
default36px (h-9)Standard forms and toolbars
lg40px (h-10)Hero sections, prominent CTAs
icon36×36pxIcon-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>}
  </>;
}

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#

PropTypeDefaultDescription
variant"default" | "destructive" | "outline" | "secondary" | "ghost" | "link""default"Visual style variant.
size"default" | "sm" | "lg" | "icon""default"Button size.
asChildbooleanfalseMerge props onto the immediate child element instead of rendering a <button>.
loadingbooleanfalseShows a spinner and disables the native button while pending.
disabledbooleanfalseDisables the button and applies muted styling.
classNamestring—Additional CSS classes.
childrenReactNode—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?