Button
A composable action control with variants, sizes, icons, and loading states.
API Reference
Original primitive API
Behavior, accessibility details, and low-level props are documented by Base UI.
Basic
import { Button } from "moduix";export function ButtonDemo() { return <Button>Save Changes</Button>;}Full list of component variables available for project-level overrides.
| Property | Default | Description |
|---|---|---|
| --button-border-width | var(--border-width-sm) | Controls base button border width. |
| --button-color | var(--color-foreground) | Controls base button text and icon color. |
| --button-content-gap | var(--spacing-2) | Controls spacing between text and icons. |
| --button-default-bg | var(--color-primary) | Controls default variant background. |
| --button-default-bg-hover | var(--color-foreground) | Controls default variant hover background. |
| --button-default-border-color | var(--color-primary) | Controls default variant border color. |
| --button-default-color | var(--color-primary-foreground) | Controls default variant text and icon color. |
| --button-destructive-bg | var(--color-destructive) | Controls destructive variant background. |
| --button-destructive-border-color | var(--color-destructive) | Controls destructive variant border color. |
| --button-destructive-color | var(--color-primary-foreground) | Controls destructive variant text and icon color. |
| --button-destructive-hover-brightness | 0.96 | Controls destructive variant hover brightness filter. |
| --button-destructive-outline-bg | var(--color-background) | Controls destructive-outline variant background. |
| --button-destructive-outline-bg-hover | var(--color-destructive) | Controls destructive-outline variant hover background. |
| --button-destructive-outline-border-color | var(--color-destructive) | Controls destructive-outline variant border color. |
| --button-destructive-outline-color | var(--color-destructive) | Controls destructive-outline variant text and icon color. |
| --button-destructive-outline-color-hover | var(--button-destructive-color) | Controls destructive-outline variant hover text and icon color. |
| --button-disabled-opacity | var(--opacity-disabled) | Controls disabled state opacity. |
| --button-focus-ring-color | var(--color-ring) | Controls focus-visible outline color. |
| --button-focus-ring-offset | var(--button-border-width) | Controls focus-visible outline offset. |
| --button-focus-ring-width | var(--border-width-md) | Controls focus-visible outline width. |
| --button-font-size | var(--text-sm) | Controls base button font size. |
| --button-font-size-xs | var(--text-xs) | Controls `xs` button font size. |
| --button-font-size-lg | var(--text-md) | Controls `lg` button font size. |
| --button-font-size-xl | var(--text-lg) | Controls `xl` button font size. |
| --button-font-weight | var(--weight-medium) | Controls button font weight. |
| --button-ghost-bg | transparent | Controls ghost variant background. |
| --button-ghost-bg-hover | var(--color-accent) | Controls ghost variant hover background. |
| --button-ghost-border-color | transparent | Controls ghost variant border color. |
| --button-ghost-color | var(--color-foreground) | Controls ghost variant text and icon color. |
| --button-icon-size | 1rem | Controls nested SVG icon size. |
| --button-line-height | var(--line-height-text-sm) | Controls base button line height. |
| --button-line-height-xs | var(--line-height-text-xs) | Controls `xs` button line height. |
| --button-line-height-lg | var(--line-height-text-md) | Controls `lg` button line height. |
| --button-line-height-xl | var(--line-height-text-lg) | Controls `xl` button line height. |
| --button-link-color | var(--color-primary) | Controls link variant color. |
| --button-link-color-hover | var(--color-foreground) | Controls link variant hover color. |
| --button-link-text-decoration | underline | Controls link variant text decoration. |
| --button-link-underline-offset | 0.25em | Controls link variant underline offset. |
| --button-outline-bg | var(--color-background) | Controls outline variant background. |
| --button-outline-bg-hover | var(--color-accent) | Controls outline variant hover background. |
| --button-outline-border-color | var(--color-border) | Controls outline variant border color. |
| --button-outline-color | var(--color-foreground) | Controls outline variant text and icon color. |
| --button-padding-x-xs | 0.625rem | Controls `xs` button horizontal padding. |
| --button-padding-x-sm | 0.75rem | Controls `sm` button horizontal padding. |
| --button-padding-x-md | 1rem | Controls `md` button horizontal padding. |
| --button-padding-x-lg | 1.25rem | Controls `lg` button horizontal padding. |
| --button-padding-x-xl | 1.5rem | Controls `xl` button horizontal padding. |
| --button-padding-y-xs | 0.25rem | Controls `xs` button vertical padding. |
| --button-padding-y-sm | 0.375rem | Controls `sm` button vertical padding. |
| --button-padding-y-md | 0.5rem | Controls `md` button vertical padding. |
| --button-padding-y-lg | 0.625rem | Controls `lg` button vertical padding. |
| --button-padding-y-xl | 0.75rem | Controls `xl` button vertical padding. |
| --button-radius | var(--radius-md) | Controls button corner radius. |
| --button-secondary-bg | var(--color-secondary) | Controls secondary variant background. |
| --button-secondary-bg-hover | var(--color-accent) | Controls secondary variant hover background. |
| --button-secondary-border-color | var(--color-secondary) | Controls secondary variant border color. |
| --button-secondary-color | var(--color-secondary-foreground) | Controls secondary variant text and icon color. |
| --button-size-icon-sm | var(--size-sm) | Controls `icon-sm` button size. |
| --button-size-icon-md | var(--size-lg) | Controls `icon-md` button size. |
| --button-size-icon-lg | var(--size-xl) | Controls `icon-lg` button size. |
| --button-size-xs | var(--size-xs) | Controls `xs` button min height. |
| --button-size-sm | var(--size-sm) | Controls `sm` button min height. |
| --button-size-md | var(--size-lg) | Controls `md` button min height. |
| --button-size-lg | var(--size-xl) | Controls `lg` button min height. |
| --button-size-xl | 3.5rem | Controls `xl` button min height. |
| --button-spinner-animation | var(--animation-spin) | Controls built-in spinner animation. |
| --button-spinner-border-width | var(--border-width-sm) | Controls built-in spinner border width. |
| --button-spinner-radius | var(--radius-full) | Controls built-in spinner corner radius. |
| --button-spinner-size | 0.875rem | Controls built-in spinner size. |
| --button-transition | var(--transition-default) | Controls transition timing for interactive states. |
Interactive variables scoped for docs preview without changing size scale tokens.
| Property | Value | Default | Description |
|---|---|---|---|
| --button-border-width | var(--border-width-sm) | Controls base button border width. | |
| --button-color | var(--color-foreground) | Controls base button text and icon color. | |
| --button-content-gap | var(--spacing-2) | Controls spacing between text and icons. | |
| --button-default-bg | var(--color-primary) | Controls default variant background. | |
| --button-default-bg-hover | var(--color-foreground) | Controls default variant hover background. | |
| --button-default-border-color | var(--color-primary) | Controls default variant border color. | |
| --button-default-color | var(--color-primary-foreground) | Controls default variant text and icon color. | |
| --button-destructive-bg | var(--color-destructive) | Controls destructive variant background. | |
| --button-destructive-border-color | var(--color-destructive) | Controls destructive variant border color. | |
| --button-destructive-color | var(--color-primary-foreground) | Controls destructive variant text and icon color. | |
| --button-destructive-hover-brightness | 0.96 | Controls destructive variant hover brightness filter. | |
| --button-destructive-outline-bg | var(--color-background) | Controls destructive-outline variant background. | |
| --button-destructive-outline-bg-hover | var(--color-destructive) | Controls destructive-outline variant hover background. | |
| --button-destructive-outline-border-color | var(--color-destructive) | Controls destructive-outline variant border color. | |
| --button-destructive-outline-color | var(--color-destructive) | Controls destructive-outline variant text and icon color. | |
| --button-destructive-outline-color-hover | var(--button-destructive-color) | Controls destructive-outline variant hover text and icon color. | |
| --button-disabled-opacity | var(--opacity-disabled) | Controls disabled state opacity. | |
| --button-focus-ring-color | var(--color-ring) | Controls focus-visible outline color. | |
| --button-focus-ring-offset | var(--button-border-width) | Controls focus-visible outline offset. | |
| --button-focus-ring-width | var(--border-width-md) | Controls focus-visible outline width. | |
| --button-font-size | var(--text-sm) | Controls base button font size. | |
| --button-font-size-xs | var(--text-xs) | Controls `xs` button font size. | |
| --button-font-size-lg | var(--text-md) | Controls `lg` button font size. | |
| --button-font-size-xl | var(--text-lg) | Controls `xl` button font size. | |
| --button-font-weight | var(--weight-medium) | Controls button font weight. | |
| --button-ghost-bg | transparent | Controls ghost variant background. | |
| --button-ghost-bg-hover | var(--color-accent) | Controls ghost variant hover background. | |
| --button-ghost-border-color | transparent | Controls ghost variant border color. | |
| --button-ghost-color | var(--color-foreground) | Controls ghost variant text and icon color. | |
| --button-icon-size | 1rem | Controls nested SVG icon size. | |
| --button-line-height | var(--line-height-text-sm) | Controls base button line height. | |
| --button-line-height-xs | var(--line-height-text-xs) | Controls `xs` button line height. | |
| --button-line-height-lg | var(--line-height-text-md) | Controls `lg` button line height. | |
| --button-line-height-xl | var(--line-height-text-lg) | Controls `xl` button line height. | |
| --button-link-color | var(--color-primary) | Controls link variant color. | |
| --button-link-color-hover | var(--color-foreground) | Controls link variant hover color. | |
| --button-link-text-decoration | underline | Controls link variant text decoration. | |
| --button-link-underline-offset | 0.25em | Controls link variant underline offset. | |
| --button-outline-bg | var(--color-background) | Controls outline variant background. | |
| --button-outline-bg-hover | var(--color-accent) | Controls outline variant hover background. | |
| --button-outline-border-color | var(--color-border) | Controls outline variant border color. | |
| --button-outline-color | var(--color-foreground) | Controls outline variant text and icon color. | |
| --button-padding-x-xs | 0.625rem | Controls `xs` button horizontal padding. | |
| --button-padding-x-sm | 0.75rem | Controls `sm` button horizontal padding. | |
| --button-padding-x-md | 1rem | Controls `md` button horizontal padding. | |
| --button-padding-x-lg | 1.25rem | Controls `lg` button horizontal padding. | |
| --button-padding-x-xl | 1.5rem | Controls `xl` button horizontal padding. | |
| --button-padding-y-xs | 0.25rem | Controls `xs` button vertical padding. | |
| --button-padding-y-sm | 0.375rem | Controls `sm` button vertical padding. | |
| --button-padding-y-md | 0.5rem | Controls `md` button vertical padding. | |
| --button-padding-y-lg | 0.625rem | Controls `lg` button vertical padding. | |
| --button-padding-y-xl | 0.75rem | Controls `xl` button vertical padding. | |
| --button-radius | var(--radius-md) | Controls button corner radius. | |
| --button-secondary-bg | var(--color-secondary) | Controls secondary variant background. | |
| --button-secondary-bg-hover | var(--color-accent) | Controls secondary variant hover background. | |
| --button-secondary-border-color | var(--color-secondary) | Controls secondary variant border color. | |
| --button-secondary-color | var(--color-secondary-foreground) | Controls secondary variant text and icon color. | |
| --button-size-icon-sm | var(--size-sm) | Controls `icon-sm` button size. | |
| --button-size-icon-md | var(--size-lg) | Controls `icon-md` button size. | |
| --button-size-icon-lg | var(--size-xl) | Controls `icon-lg` button size. | |
| --button-size-xs | var(--size-xs) | Controls `xs` button min height. | |
| --button-size-sm | var(--size-sm) | Controls `sm` button min height. | |
| --button-size-md | var(--size-lg) | Controls `md` button min height. | |
| --button-size-lg | var(--size-xl) | Controls `lg` button min height. | |
| --button-size-xl | 3.5rem | Controls `xl` button min height. | |
| --button-spinner-animation | var(--animation-spin) | Controls built-in spinner animation. | |
| --button-spinner-border-width | var(--border-width-sm) | Controls built-in spinner border width. | |
| --button-spinner-radius | var(--radius-full) | Controls built-in spinner corner radius. | |
| --button-spinner-size | 0.875rem | Controls built-in spinner size. | |
| --button-transition | var(--transition-default) | Controls transition timing for interactive states. |
Anatomy
Button is composed as one interactive root with optional internal loading slots. In common
usage, compose content as children and optionally enable loading states.
Button
├─ content
└─ loadingIndicator (when loading)
└─ spinner (default)| Part | Role |
|---|---|
Button | Interactive root. Handles click, disabled, loading, and focus states. |
content slot | Wrapper around button children so content layout stays stable. |
loadingIndicator | Slot rendered in loading state; accepts custom indicator via props. |
spinner | Default spinner inside loadingIndicator when no custom indicator is provided. |
The root exposes data-disabled from Base UI and data-loading from moduix. Use these attributes
or CSS variables when styling state from CSS.
Composition
Use Button behavior props such as render, nativeButton, disabled, and
focusableWhenDisabled. Use className for the
root button. Use classNames for internal slots that are rendered by the component:
<Button
className={styles.button}
classNames={{
content: styles.content,
loadingIndicator: styles.loadingIndicator,
spinner: styles.spinner,
}}
/>For submit buttons, pass type="submit". For links, style an <a> directly instead of rendering
an anchor through Button; Base UI Button intentionally keeps button semantics.
Examples
Variants
Use variant to match the intent of the action. For navigation links, style an <a> directly instead of rendering a link through Button.
import { Button } from "moduix";export function ButtonVariantsDemo() { return ( <div> <Button>Default</Button> <Button variant="outline">Outline</Button> <Button variant="secondary">Secondary</Button> <Button variant="destructive">Destructive</Button> <Button variant="destructive-outline">Destructive Outline</Button> <Button variant="ghost">Ghost</Button> <Button variant="link">Link</Button> </div> );}Sizes
Use text sizes for standard actions and icon sizes for buttons that only contain an icon.
import { Button, StarIcon } from "moduix";export function ButtonSizesDemo() { return ( <div> <Button size="xs">Extra-small</Button> <Button size="sm">Small</Button> <Button size="md">Medium</Button> <Button size="lg">Large</Button> <Button size="xl">Extra-large</Button> <Button size="icon-sm" variant="outline" aria-label="Small favorite"> <StarIcon /> </Button> <Button size="icon-md" variant="outline" aria-label="Favorite"> <StarIcon /> </Button> <Button size="icon-lg" variant="outline" aria-label="Large favorite"> <StarIcon /> </Button> </div> );}Icons
Pass icons as children. The component does not lock you into a specific icon set.
import { Button, PlusIcon, StarIcon, ArrowUpRightIcon } from "moduix";export function ButtonIconsDemo() { return ( <div> <Button> <PlusIcon /> Create Item </Button> <Button size="icon-md" variant="outline" aria-label="Favorites"> <StarIcon /> </Button> <Button variant="link"> Open Docs <ArrowUpRightIcon /> </Button> </div> );}Disabled
Use focusableWhenDisabled when the button becomes disabled after focus, for example during a pending action.
import { Button } from "moduix";export function ButtonDisabledDemo() { return ( <div> <Button disabled>Disabled</Button> <Button disabled focusableWhenDisabled variant="outline"> Focusable Disabled </Button> </div> );}Loading
Use the built-in loading props when an action should keep its size while it is pending.
import { Button } from "moduix";import { useState } from "react";export function LoadingButton() { const [loading, setLoading] = useState(false); return ( <Button loading={loading} loadingText="Saving" onClick={() => { setLoading(true); setTimeout(() => setLoading(false), 1800); }} > Save Changes </Button> );}Custom Loading Indicator
Pass loadingIndicator to use an icon or spinner from your application.
import { Button, StarIcon } from "moduix";export function CustomLoadingIndicatorDemo() { return ( <Button loading loadingText="Syncing" variant="outline" loadingIndicator={<StarIcon className={styles.customLoadingIndicator} />} > Sync </Button> );}.customLoadingIndicator { width: 0.875rem; height: 0.875rem; animation: var(--animation-spin);}Custom Styles
Pass className for the button root and classNames for internal slots when styling with CSS Modules, Tailwind CSS, or CSS-in-JS.
import { Button } from "moduix";export function CustomStylesButtonDemo() { return ( <Button className={styles.customButton} classNames={{ content: styles.customButtonContent, loadingIndicator: styles.customLoadingIndicatorColor, spinner: styles.customSpinner, }} loading loadingText="Publishing" > Publish </Button> );}.customButton { border-color: var(--color-primary); background-color: var(--color-primary); color: var(--color-primary-foreground); box-shadow: 0 1px 2px rgb(0 0 0 / 0.08);}.customButtonContent { letter-spacing: 0.025em;}.customLoadingIndicatorColor { color: var(--color-primary-foreground);}.customSpinner { border-width: var(--border-width-md);}