Button An interactive element triggered by a user.
npx vayu-ui add -t button
Preview Code
Primary Secondary Outline Ghost Destructive
Small Medium Large
Click to Load
Disabled Disabled Disabled
< Button variant = "primary" >Primary</ Button >
< Button variant = "secondary" >Secondary</ Button >
< Button variant = "outline" >Outline</ Button >
< Button variant = "ghost" >Ghost</ Button >
< Button variant = "destructive" >Destructive</ Button >
< Button size = "small" variant = "secondary" >Small</ Button >
< Button size = "medium" variant = "secondary" >Medium</ Button >
< Button size = "large" variant = "secondary" >Large</ Button >
< Button variant = "primary" >
< Button.Icon >< Mail /></ Button.Icon >
< Button.Text >Email Login</ Button.Text >
</ Button >
< Button variant = "outline" size = "large" >
< Button.Text >Send</ Button.Text >
< Button.Icon size = "large" >< Send /></ Button.Icon >
</ Button >
< Button
variant = "primary"
loading = {Status. PENDING }
loadingText = "Sending..."
>
Click to Load
</ Button >
< Button variant = "secondary" >
< Button.Icon >< Bell /></ Button.Icon >
< Button.Badge value = { 3 } variant = "danger" />
</ Button >
< Button variant = "outline" >
< Button.Text >Messages</ Button.Text >
< Button.Badge value = { 12 } max = { 9 } variant = "primary" position = "top-right" />
</ Button >
< Button variant = "primary" disabled >Disabled</ Button >
< Button variant = "primary" fullWidth >Full Width Button</ Button >
< Button variant = "primary" size = "medium" >
< Button.Icon >
< Mail />
</ Button.Icon >
< Button.Text >Button Label</ Button.Text >
< Button.Badge value = { 3 } variant = "danger" />
</ Button >
Button — root element, renders a native <button>
Button.Icon — wraps an icon element with sized constraints
Button.Text — wraps button label text with truncation
Button.Badge — notification badge positioned relative to the button
Keyboard Navigation : Activated via Enter and Space keys
Focus Visible : Displays a focus-visible ring using design tokens when navigating with keyboard
ARIA Attributes : Sets aria-disabled, aria-busy, and aria-label as needed
Loading State : Announced via aria-live="polite" with descriptive loading text
Semantic HTML : Renders a native <button> with the correct type attribute
Ref Forwarding : Supports programmatic focus through ref
In default state, the screen reader announces the button's text content or aria-label
When disabled, the button is announced as "dimmed" or "unavailable" depending on the screen reader
During loading (Status.PENDING), aria-busy="true" signals an in-progress operation, and the aria-live="polite" region announces the loadingText value
Button.Badge uses role="status" with aria-live="polite" to announce count changes (e.g., "3 notifications")
Button.Icon is hidden from screen readers by default (aria-hidden="true"); set the label prop to make it accessible as an image
When loading transitions to Status.SUCCESS or Status.REJECTED, the button returns to its default content and the screen reader re-announces the visible text
Button/
├── Button.tsx # Root button component with loading states
├── ButtonIcon.tsx # Icon wrapper subcomponent
├── ButtonBadge.tsx # Notification badge subcomponent
├── ButtonText.tsx # Text wrapper subcomponent
├── types.ts # Shared types, enums, and interfaces
├── index.ts # Public API and compound component export
└── README.md # Component-level documentation
Prop Type Default Description variant"primary" | "secondary" | "outline" | "ghost" | "destructive""primary"Visual style of the button size"small" | "medium" | "large""small"Size of the button loadingStatusStatus.IDLELoading state controlling spinner and text fullWidthbooleanfalseWhether the button spans full container width loadingTextstring"Loading"Text displayed during loading state disabledbooleanfalseDisables the button type"button" | "submit" | "reset""button"Native HTML button type aria-labelstring— Accessible label when no visible text is present
Prop Type Default Description size"small" | "medium" | "large""small"Size of the icon container childrenReactNode— The icon element to render labelstring— Accessible label; makes the icon visible to screen readers
Prop Type Default Description childrenReactNode— Text content of the button
Prop Type Default Description valuenumber | string— Badge content — number or short label maxnumber99Maximum number before truncating with + variant"primary" | "danger" | "warning" | "info" | "success""danger"Visual style of the badge position"top-right" | "top-left" | "inline-right" | "inline-left""top-right"Position relative to the button size"small" | "medium" | "large""small"Size of the badge showZerobooleanfalseWhether to render the badge when value is 0
Value Description Status.IDLEDefault state, no loading indicator Status.PENDINGShows spinner and loading text Status.SUCCESSOperation completed (returns to normal state) Status.REJECTEDOperation failed (returns to normal state)