Button
Triggers an action. The most common atom in any product surface. get this one right and most of the rest follows.
Status: stable · @velon-finance/ui
Overview
Variants
Six variants cover the visual hierarchy of actions on any screen. Use at most one primary per surface.
Sizes
With icon
States
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'outline' | 'ghost' | 'link' | 'destructive' | 'primary' | Visual style |
size | 'sm' | 'md' | 'lg' | 'icon' | 'md' | Sizing scale |
asChild | boolean | false | Render as the child element instead of a <button> (Radix Slot) |
disabled | boolean | false | Disables interaction and lowers opacity |
…rest | ButtonHTMLAttributes | . | All native button props (onClick, type, aria-*, etc.) |
Accessibility
- Always render a
<button>(default) unless you genuinely need a link. useasChildwith<a>for navigation actions. - For icon-only buttons, set
aria-labeldescribing the action. - Disabled buttons don’t receive focus. If you need a “disabled-looking” button that still focuses (to show a tooltip), use
aria-disabledinstead of thedisabledprop. - Focus ring meets WCAG AA contrast in both light and dark themes.
Do / Don’t
Do
One primary action per surface, paired with a quieter cancel.
Don’t
Two primaries compete for attention. The user has to read both.
Code
import { Button } from '@velon-finance/ui'
<Button variant="primary" onClick={handleSubmit}>
Confirmar
</Button>