Unkey
Components

Button

A versatile button component with multiple variants, states, and sizes

Button

A versatile button component that supports various styles, states, and interactive features. Button is built with accessibility in mind and provides consistent interaction patterns across all variants.

Each button can be customized with different variants, colors, and sizes, making it adaptable to any UI context. All buttons include proper focus states, loading indicators, and keyboard interactions.

Basic Variants

Button comes in three basic variants that serve different UI purposes:

Primary

The default button style with a solid background. Use for primary actions and main call-to-actions.

Light

Dark

Outline

Button with transparent background and visible border. Ideal for secondary actions that don't require as much visual emphasis.

Light

Dark

Ghost

Button with no background or border until interacted with. Perfect for tertiary actions or when space is limited.

Light

Dark

Color Variants

Each button variant can be combined with different color schemes to convey the nature of the action:

Danger - Primary

Solid background danger variant for destructive actions that should be clearly highlighted.

Light

Dark

Danger - Outline

Danger variant with outline style. Use for destructive actions that require less visual prominence.

Light

Dark

Danger - Ghost

Minimal danger variant. Suitable for destructive actions in tight UI spaces or alongside other content.

Light

Dark

Warning - Primary

Warning variant with solid background for actions that require caution but aren't destructive.

Light

Dark

Warning - Outline

Warning variant with outline style for secondary cautionary actions.

Light

Dark

Warning - Ghost

Warning variant with ghost style for tertiary cautionary actions.

Light

Dark

Success - Primary

Success variant with solid background for positive or confirming actions.

Light

Dark

Success - Outline

Success variant with outline style for secondary positive actions.

Light

Dark

Success - Ghost

Success variant with ghost style for subtle positive actions.

Light

Dark

Size Variants

All button variants and color schemes can be combined with different sizes to fit various UI contexts.

Light

Dark

Special Features

Button includes additional features that enhance usability and interaction:

With Icons

Buttons can include icons from the Lucide library for enhanced visual meaning. Icons can be placed before or after text.

Light

Dark

With Keyboard Shortcuts

Buttons can display and respond to keyboard shortcuts for improved accessibility and power-user workflows.

Count: 0

Press ⌘B to increment the counter

Additional Features

The Button component includes some additional features not shown in the examples above:

Legacy Variant Support

For backward compatibility, the component supports legacy variants:

  • default will be mapped to primary variant
  • destructive will be mapped to primary variant with danger color

Shape Variants

For special layouts, buttons can use the shape prop:

Light

Dark

Props

The Button component accepts all standard HTML button attributes plus the following:

PropTypeDefault
variant
"default" | "destructive" | "primary" | "outline" | "ghost"
-
shape
"square"
-
color
"default" | "success" | "warning" | "danger"
-
size
"icon" | "sm" | "md" | "lg" | "xlg" | "2xlg"
-
disabled
boolean
-
form
string
-
formAction
string
-
formEncType
string
-
formMethod
string
-
formNoValidate
boolean
-
formTarget
string
-
name
string
-
type
"submit" | "reset" | "button"
-
value
string | number | readonly string[]
-
defaultChecked
boolean
-
defaultValue
string | number | readonly string[]
-
suppressContentEditableWarning
boolean
-
suppressHydrationWarning
boolean
-
accessKey
string
-
autoCapitalize
"off" | "none" | "on" | "sentences" | "words" | "characters" | (string & {})
-
autoFocus
boolean
-
className
string
-
contentEditable
Booleanish | "inherit" | "plaintext-only"
-
contextMenu
string
-
dir
string
-
draggable
Booleanish
-
enterKeyHint
"enter" | "done" | "go" | "next" | "previous" | "search" | "send"
-
hidden
boolean
-
id
string
-
lang
string
-
nonce
string
-
slot
string
-
spellCheck
Booleanish
-
style
CSSProperties
-
tabIndex
number
-
title
string
-
translate
"yes" | "no"
-
radioGroup
string
-
role
AriaRole
-
about
string
-
content
string
-
datatype
string
-
inlist
any
-
prefix
string
-
property
string
-
rel
string
-
resource
string
-
rev
string
-
typeof
string
-
vocab
string
-
autoCorrect
string
-
autoSave
string
-
itemProp
string
-
itemScope
boolean
-
itemType
string
-
itemID
string
-
itemRef
string
-
results
number
-
security
string
-
unselectable
"off" | "on"
-
inputMode
"none" | "search" | "text" | "tel" | "url" | "email" | "numeric" | "decimal"
-
is
string
-
aria-activedescendant
string
-
aria-atomic
Booleanish
-
aria-autocomplete
"none" | "list" | "inline" | "both"
-
aria-braillelabel
string
-
aria-brailleroledescription
string
-
aria-busy
Booleanish
-
aria-checked
boolean | "true" | "false" | "mixed"
-
aria-colcount
number
-
aria-colindex
number
-
aria-colindextext
string
-
aria-colspan
number
-
aria-controls
string
-
aria-current
boolean | "true" | "false" | "page" | "step" | "location" | "date" | "time"
-
aria-describedby
string
-
aria-description
string
-
aria-details
string
-
aria-disabled
Booleanish
-
aria-dropeffect
"none" | "link" | "copy" | "execute" | "move" | "popup"
-
aria-errormessage
string
-
aria-expanded
Booleanish
-
aria-flowto
string
-
aria-grabbed
Booleanish
-
aria-haspopup
boolean | "true" | "false" | "dialog" | "grid" | "listbox" | "menu" | "tree"
-
aria-hidden
Booleanish
-
aria-invalid
boolean | "true" | "false" | "grammar" | "spelling"
-
aria-keyshortcuts
string
-
aria-label
string
-
aria-labelledby
string
-
aria-level
number
-
aria-live
"off" | "assertive" | "polite"
-
aria-modal
Booleanish
-
aria-multiline
Booleanish
-
aria-multiselectable
Booleanish
-
aria-orientation
"horizontal" | "vertical"
-
aria-owns
string
-
aria-placeholder
string
-
aria-posinset
number
-
aria-pressed
boolean | "true" | "false" | "mixed"
-
aria-readonly
Booleanish
-
aria-relevant
"text" | "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals"
-
aria-required
Booleanish
-
aria-roledescription
string
-
aria-rowcount
number
-
aria-rowindex
number
-
aria-rowindextext
string
-
aria-rowspan
number
-
aria-selected
Booleanish
-
aria-setsize
number
-
aria-sort
"none" | "ascending" | "descending" | "other"
-
aria-valuemax
number
-
aria-valuemin
number
-
aria-valuenow
number
-
aria-valuetext
string
-
children
ReactNode
-
dangerouslySetInnerHTML
{ __html: string | TrustedHTML; }
-
onCopy
ClipboardEventHandler<HTMLButtonElement>
-
onCopyCapture
ClipboardEventHandler<HTMLButtonElement>
-
onCut
ClipboardEventHandler<HTMLButtonElement>
-
onCutCapture
ClipboardEventHandler<HTMLButtonElement>
-
onPaste
ClipboardEventHandler<HTMLButtonElement>
-
onPasteCapture
ClipboardEventHandler<HTMLButtonElement>
-
onCompositionEnd
CompositionEventHandler<HTMLButtonElement>
-
onCompositionEndCapture
CompositionEventHandler<HTMLButtonElement>
-
onCompositionStart
CompositionEventHandler<HTMLButtonElement>
-
onCompositionStartCapture
CompositionEventHandler<HTMLButtonElement>
-
onCompositionUpdate
CompositionEventHandler<HTMLButtonElement>
-
onCompositionUpdateCapture
CompositionEventHandler<HTMLButtonElement>
-
onFocus
FocusEventHandler<HTMLButtonElement>
-
onFocusCapture
FocusEventHandler<HTMLButtonElement>
-
onBlur
FocusEventHandler<HTMLButtonElement>
-
onBlurCapture
FocusEventHandler<HTMLButtonElement>
-
onChange
FormEventHandler<HTMLButtonElement>
-
onChangeCapture
FormEventHandler<HTMLButtonElement>
-
onBeforeInput
FormEventHandler<HTMLButtonElement>
-
onBeforeInputCapture
FormEventHandler<HTMLButtonElement>
-
onInput
FormEventHandler<HTMLButtonElement>
-
onInputCapture
FormEventHandler<HTMLButtonElement>
-
onReset
FormEventHandler<HTMLButtonElement>
-
onResetCapture
FormEventHandler<HTMLButtonElement>
-
onSubmit
FormEventHandler<HTMLButtonElement>
-
onSubmitCapture
FormEventHandler<HTMLButtonElement>
-
onInvalid
FormEventHandler<HTMLButtonElement>
-
onInvalidCapture
FormEventHandler<HTMLButtonElement>
-
onLoad
ReactEventHandler<HTMLButtonElement>
-
onLoadCapture
ReactEventHandler<HTMLButtonElement>
-
onError
ReactEventHandler<HTMLButtonElement>
-
onErrorCapture
ReactEventHandler<HTMLButtonElement>
-
onKeyDown
KeyboardEventHandler<HTMLButtonElement>
-
onKeyDownCapture
KeyboardEventHandler<HTMLButtonElement>
-
onKeyPress
KeyboardEventHandler<HTMLButtonElement>
-
onKeyPressCapture
KeyboardEventHandler<HTMLButtonElement>
-
onKeyUp
KeyboardEventHandler<HTMLButtonElement>
-
onKeyUpCapture
KeyboardEventHandler<HTMLButtonElement>
-
onAbort
ReactEventHandler<HTMLButtonElement>
-
onAbortCapture
ReactEventHandler<HTMLButtonElement>
-
onCanPlay
ReactEventHandler<HTMLButtonElement>
-
onCanPlayCapture
ReactEventHandler<HTMLButtonElement>
-
onCanPlayThrough
ReactEventHandler<HTMLButtonElement>
-
onCanPlayThroughCapture
ReactEventHandler<HTMLButtonElement>
-
onDurationChange
ReactEventHandler<HTMLButtonElement>
-
onDurationChangeCapture
ReactEventHandler<HTMLButtonElement>
-
onEmptied
ReactEventHandler<HTMLButtonElement>
-
onEmptiedCapture
ReactEventHandler<HTMLButtonElement>
-
onEncrypted
ReactEventHandler<HTMLButtonElement>
-
onEncryptedCapture
ReactEventHandler<HTMLButtonElement>
-
onEnded
ReactEventHandler<HTMLButtonElement>
-
onEndedCapture
ReactEventHandler<HTMLButtonElement>
-
onLoadedData
ReactEventHandler<HTMLButtonElement>
-
onLoadedDataCapture
ReactEventHandler<HTMLButtonElement>
-
onLoadedMetadata
ReactEventHandler<HTMLButtonElement>
-
onLoadedMetadataCapture
ReactEventHandler<HTMLButtonElement>
-
onLoadStart
ReactEventHandler<HTMLButtonElement>
-
onLoadStartCapture
ReactEventHandler<HTMLButtonElement>
-
onPause
ReactEventHandler<HTMLButtonElement>
-
onPauseCapture
ReactEventHandler<HTMLButtonElement>
-
onPlay
ReactEventHandler<HTMLButtonElement>
-
onPlayCapture
ReactEventHandler<HTMLButtonElement>
-
onPlaying
ReactEventHandler<HTMLButtonElement>
-
onPlayingCapture
ReactEventHandler<HTMLButtonElement>
-
onProgress
ReactEventHandler<HTMLButtonElement>
-
onProgressCapture
ReactEventHandler<HTMLButtonElement>
-
onRateChange
ReactEventHandler<HTMLButtonElement>
-
onRateChangeCapture
ReactEventHandler<HTMLButtonElement>
-
onResize
ReactEventHandler<HTMLButtonElement>
-
onResizeCapture
ReactEventHandler<HTMLButtonElement>
-
onSeeked
ReactEventHandler<HTMLButtonElement>
-
onSeekedCapture
ReactEventHandler<HTMLButtonElement>
-
onSeeking
ReactEventHandler<HTMLButtonElement>
-
onSeekingCapture
ReactEventHandler<HTMLButtonElement>
-
onStalled
ReactEventHandler<HTMLButtonElement>
-
onStalledCapture
ReactEventHandler<HTMLButtonElement>
-
onSuspend
ReactEventHandler<HTMLButtonElement>
-
onSuspendCapture
ReactEventHandler<HTMLButtonElement>
-
onTimeUpdate
ReactEventHandler<HTMLButtonElement>
-
onTimeUpdateCapture
ReactEventHandler<HTMLButtonElement>
-
onVolumeChange
ReactEventHandler<HTMLButtonElement>
-
onVolumeChangeCapture
ReactEventHandler<HTMLButtonElement>
-
onWaiting
ReactEventHandler<HTMLButtonElement>
-
onWaitingCapture
ReactEventHandler<HTMLButtonElement>
-
onAuxClick
MouseEventHandler<HTMLButtonElement>
-
onAuxClickCapture
MouseEventHandler<HTMLButtonElement>
-
onClick
MouseEventHandler<HTMLButtonElement>
-
onClickCapture
MouseEventHandler<HTMLButtonElement>
-
onContextMenu
MouseEventHandler<HTMLButtonElement>
-
onContextMenuCapture
MouseEventHandler<HTMLButtonElement>
-
onDoubleClick
MouseEventHandler<HTMLButtonElement>
-
onDoubleClickCapture
MouseEventHandler<HTMLButtonElement>
-
onDrag
DragEventHandler<HTMLButtonElement>
-
onDragCapture
DragEventHandler<HTMLButtonElement>
-
onDragEnd
DragEventHandler<HTMLButtonElement>
-
onDragEndCapture
DragEventHandler<HTMLButtonElement>
-
onDragEnter
DragEventHandler<HTMLButtonElement>
-
onDragEnterCapture
DragEventHandler<HTMLButtonElement>
-
onDragExit
DragEventHandler<HTMLButtonElement>
-
onDragExitCapture
DragEventHandler<HTMLButtonElement>
-
onDragLeave
DragEventHandler<HTMLButtonElement>
-
onDragLeaveCapture
DragEventHandler<HTMLButtonElement>
-
onDragOver
DragEventHandler<HTMLButtonElement>
-
onDragOverCapture
DragEventHandler<HTMLButtonElement>
-
onDragStart
DragEventHandler<HTMLButtonElement>
-
onDragStartCapture
DragEventHandler<HTMLButtonElement>
-
onDrop
DragEventHandler<HTMLButtonElement>
-
onDropCapture
DragEventHandler<HTMLButtonElement>
-
onMouseDown
MouseEventHandler<HTMLButtonElement>
-
onMouseDownCapture
MouseEventHandler<HTMLButtonElement>
-
onMouseEnter
MouseEventHandler<HTMLButtonElement>
-
onMouseLeave
MouseEventHandler<HTMLButtonElement>
-
onMouseMove
MouseEventHandler<HTMLButtonElement>
-
onMouseMoveCapture
MouseEventHandler<HTMLButtonElement>
-
onMouseOut
MouseEventHandler<HTMLButtonElement>
-
onMouseOutCapture
MouseEventHandler<HTMLButtonElement>
-
onMouseOver
MouseEventHandler<HTMLButtonElement>
-
onMouseOverCapture
MouseEventHandler<HTMLButtonElement>
-
onMouseUp
MouseEventHandler<HTMLButtonElement>
-
onMouseUpCapture
MouseEventHandler<HTMLButtonElement>
-
onSelect
ReactEventHandler<HTMLButtonElement>
-
onSelectCapture
ReactEventHandler<HTMLButtonElement>
-
onTouchCancel
TouchEventHandler<HTMLButtonElement>
-
onTouchCancelCapture
TouchEventHandler<HTMLButtonElement>
-
onTouchEnd
TouchEventHandler<HTMLButtonElement>
-
onTouchEndCapture
TouchEventHandler<HTMLButtonElement>
-
onTouchMove
TouchEventHandler<HTMLButtonElement>
-
onTouchMoveCapture
TouchEventHandler<HTMLButtonElement>
-
onTouchStart
TouchEventHandler<HTMLButtonElement>
-
onTouchStartCapture
TouchEventHandler<HTMLButtonElement>
-
onPointerDown
PointerEventHandler<HTMLButtonElement>
-
onPointerDownCapture
PointerEventHandler<HTMLButtonElement>
-
onPointerMove
PointerEventHandler<HTMLButtonElement>
-
onPointerMoveCapture
PointerEventHandler<HTMLButtonElement>
-
onPointerUp
PointerEventHandler<HTMLButtonElement>
-
onPointerUpCapture
PointerEventHandler<HTMLButtonElement>
-
onPointerCancel
PointerEventHandler<HTMLButtonElement>
-
onPointerCancelCapture
PointerEventHandler<HTMLButtonElement>
-
onPointerEnter
PointerEventHandler<HTMLButtonElement>
-
onPointerLeave
PointerEventHandler<HTMLButtonElement>
-
onPointerOver
PointerEventHandler<HTMLButtonElement>
-
onPointerOverCapture
PointerEventHandler<HTMLButtonElement>
-
onPointerOut
PointerEventHandler<HTMLButtonElement>
-
onPointerOutCapture
PointerEventHandler<HTMLButtonElement>
-
onGotPointerCapture
PointerEventHandler<HTMLButtonElement>
-
onGotPointerCaptureCapture
PointerEventHandler<HTMLButtonElement>
-
onLostPointerCapture
PointerEventHandler<HTMLButtonElement>
-
onLostPointerCaptureCapture
PointerEventHandler<HTMLButtonElement>
-
onScroll
UIEventHandler<HTMLButtonElement>
-
onScrollCapture
UIEventHandler<HTMLButtonElement>
-
onWheel
WheelEventHandler<HTMLButtonElement>
-
onWheelCapture
WheelEventHandler<HTMLButtonElement>
-
onAnimationStart
AnimationEventHandler<HTMLButtonElement>
-
onAnimationStartCapture
AnimationEventHandler<HTMLButtonElement>
-
onAnimationEnd
AnimationEventHandler<HTMLButtonElement>
-
onAnimationEndCapture
AnimationEventHandler<HTMLButtonElement>
-
onAnimationIteration
AnimationEventHandler<HTMLButtonElement>
-
onAnimationIterationCapture
AnimationEventHandler<HTMLButtonElement>
-
onTransitionEnd
TransitionEventHandler<HTMLButtonElement>
-
onTransitionEndCapture
TransitionEventHandler<HTMLButtonElement>
-
loading
boolean
-
keyboard
{ display: string; trigger: (e: KeyboardEvent) => boolean; callback: (e: KeyboardEvent) => void | Promise<void>; }
-
asChild
boolean
-
loadingLabel
string
-

Usage Guidelines

When using the Button component:

  • Hierarchy: Maintain a clear visual hierarchy with your button choices
    • Use primary buttons for main actions and primary call-to-actions
    • Use outline buttons for secondary actions
    • Use ghost buttons for tertiary actions or in dense UIs
  • Color semantics: Apply color variants based on the action's impact:
    • Default for neutral or standard actions
    • Success for positive, confirming, or creative actions
    • Warning for cautionary actions that require attention
    • Danger for destructive or irreversible actions
  • Interaction states:
    • Ensure loading state is shown during asynchronous operations to prevent multiple submissions
    • Use disabled state appropriately for actions that are currently unavailable
    • Test that focus states are clearly visible for keyboard navigation
  • Sizing and spacing:
    • Use appropriate size based on the button's importance and the available space
    • Maintain consistent spacing between buttons in a group (recommend 16px/1rem)
    • For button groups, maintain consistent sizing within the group
  • Content guidelines:
    • Use concise, action-oriented text (e.g., "Save changes" instead of "Submit")
    • Add icons to enhance meaning, but avoid overloading buttons with too many elements
    • For destructive actions, consider using explicit verbs ("Delete" instead of "Remove")
  • Accessibility:
    • Consider adding keyboard shortcuts for frequently used actions
    • Ensure sufficient color contrast between text and background (WCAG AA minimum)
    • Add appropriate aria attributes for complex button behaviors
  • Responsive behavior:
    • On mobile, ensure buttons are at least 44×44px (touch target size)
    • Consider stacking buttons vertically on very small screens