Skip to main content

Button

Form Controls
Stable
v1.0.0

Interactive button component with 6 variants, 5 sizes, and asChild support for polymorphic rendering.

Quick Import
import { Button } from "@cohere-ai/waypoint-ui/button";

Live Preview

Loading Button...

Props

NameTypeDefaultDescription
variant'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link''default'Visual style variant
size'default' | 'sm' | 'lg' | 'xl' | 'icon''default'Size of the button (default: 36px, sm: 28px, lg: 40px, xl: 48px, icon: 32×32px)
asChildbooleanfalseRender as child element — useful for rendering a router Link with button styles
disabledbooleanfalseDisables interaction and dims the button

Examples

Button Variants

All 6 button variants

1
import { Button } from '@cohere-ai/waypoint-ui/button';
2
 
3
<div className="flex gap-2">
4
<Button variant="default">Default</Button>
5
<Button variant="destructive">Destructive</Button>
6
<Button variant="outline">Outline</Button>
7
<Button variant="secondary">Secondary</Button>
8
<Button variant="ghost">Ghost</Button>
9
<Button variant="link">Link</Button>
10
</div>

Button Sizes

All 5 button sizes

1
import { Button } from '@cohere-ai/waypoint-ui/button';
2
 
3
<div className="flex items-center gap-2">
4
<Button size="sm">Small</Button>
5
<Button size="default">Default</Button>
6
<Button size="lg">Large</Button>
7
<Button size="xl">Extra Large</Button>
8
</div>

Using buttonVariants for non-button elements

Apply button styles to an anchor using the buttonVariants helper

1
import { buttonVariants } from '@cohere-ai/waypoint-ui/button';
2
 
3
<a href="/docs" className={buttonVariants({ variant: 'outline', size: 'sm' })}>
4
Documentation
5
</a>

As Router Link

Render a button as a Next.js Link using asChild

1
import { Button } from '@cohere-ai/waypoint-ui/button';
2
import Link from 'next/link';
3
 
4
<Button asChild variant="default">
5
<Link href="/dashboard">Go to dashboard</Link>
6
</Button>

Performance

Bundle Size
2.3 KB
Gzipped
Render Time
< 1ms
Average
Lighthouse
100
/100
Performance Score

Metrics measured with production build in Chrome 120.

Accessibility

WCAG AA

Keyboard Navigation

Tab to focus, Enter/Space to activate. Disabled buttons are announced as unavailable.

ARIA Attributes

aria-label (required for icon-only buttons)aria-describedbyaria-pressed (for toggle buttons)

Note: For icon-only buttons (size="icon"), always provide aria-label. Focus ring uses ring-ring/50 for visibility in both light and dark modes.

Design Guidelines

Do

Use descriptive button text that clearly indicates the action.

"Save changes", not "Submit"

Use the destructive variant for dangerous or irreversible actions.

Use asChild to render a button as a router Link while keeping button styles.

Don't

Use more than 1–2 primary buttons per view.

Disable buttons without showing an explanation (tooltip or inline message).

Real-World Examples

Common use cases and production-ready implementations.

Form Submit with Loading State

Primary button that shows loading state

<Button variant="default" size="lg" disabled={isLoading}>
{isLoading ? 'Saving...' : 'Save changes'}
</Button>

Destructive Confirmation

Cancel/confirm pair for a destructive action

<div className="flex gap-2 justify-end">
<Button variant="outline" onClick={onCancel}>Cancel</Button>
<Button variant="destructive" onClick={onDelete}>Delete account</Button>
</div>

Found an Issue?

If you've encountered a bug or have feedback about the Button component, please report it to our team. Your feedback helps us improve Waypoint.

Available for all users • Issue will be created in Linear

Was this page helpful?

Your feedback helps us improve our documentation.

Need Help?

Check out the Whitelabeling Playground to explore customization options or visit the Developer Guide for integration help.