Primary action control for forms, dialogs, and navigation.
Introduction
Use buttons for discrete actions: submitting forms, opening dialogs, confirming choices, or navigating when rendered as a link (as="a"). Limit each view to one primary action when possible; use variant="outline" or variant="flat" for secondary actions.
Four visual variants (solid, flat, light, outline) cover filled, subtle, and bordered styles. Use loading for async feedback, selected for a pressed action, and density="mini" with icon for icon-only controls. Join related actions with ButtonGroup.
Prefer Button for discrete user actions. Use Link for inline textual navigation, and keep one primary solid action per view when possible.
Import
import { Button } from "@bridge-ui/vue/Components/Button";import { Button } from "@bridge-ui/react/Components/Button";Basic usage
The default button is a solid primary action. Use as="a" with href for a native link, or linkAs with href to render your router’s link component.
Colors
Use the color prop to match the action’s intent. Available colors: primary, secondary, success, info, warning, error, dark, and black.
Variants
The Button component supports four style variants, set with the variant prop:
- solid (default) — filled background
- flat — subtle background tint
- light — lighter fill
- outline — transparent background with a colored border
Sizes
Control the button dimensions with the size prop. Available sizes: 2xs, xs, sm, md (default), lg, xl, and 2xl.
Icons
Add icons with startIcon and endIcon. For icon-only buttons, use density="mini" with the icon prop and an aria-label.
States
Use loading to overlay a spinner while keeping the label in the layout (invisible, so the button width stays stable) and disable interaction, disabled to prevent clicks, or selected for a pressed action.
Density and link
Use density="mini" with the icon prop for icon-only buttons. Set full for full-width buttons, or as="a" with href for a native link.
Rounded
Use the rounded prop to control border radius. Available values: none, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, and full (defaults vary by component).
Customization
Fine-tune appearance with rounded, className (React) or class (Vue), and the classes prop to target the root element.
Router link
linkAs with href renders a link through your router component. linkProps is checked against that component and forwarded to it (method, replace, prefetch, and so on). as="button" and as="span" ignore linkAs. It is also ignored while the button is disabled or loading. AppLink below stands for that router component.
<Button href="/logout" :link-as="AppLink" :link-props="{ method: 'post' }">
Logout
</Button><Button href="/logout" linkAs={AppLink} linkProps={{ method: "post" }}>
Logout
</Button>Related components
ButtonGroup, Icon, Link, ToggleGroup
Accessibility
- Activates with Enter or Space when rendered as button (default)
- Tab moves focus; a visible focus ring is applied via focus:ring-2
- disabled sets the native disabled attribute on <button>; loading also blocks interaction and sets aria-busy
- For as="a" or as="span", the disabled state uses aria-disabled instead of native disabled
- Icon-only buttons (density="mini") need an accessible name via aria-label or visible text
- selected sets aria-pressed
- Link buttons should use meaningful link text
Anatomy
<!-- Default button -->
<button type="button">
<!-- startIcon (optional) -->
Label text
<!-- endIcon (optional) -->
</button>
<!-- Loading state -->
<button type="button" disabled aria-busy="true">
<!-- overlay spinner -->
<span class="invisible"><!-- label still in the DOM --></span>
</button>
<!-- Icon-only (density="mini") -->
<button type="button" aria-label="Delete">
<!-- icon -->
</button>API
| Prop | Type | Default | Description |
|---|---|---|---|
| as | "a" | "span" | "button" | "button" | The element to render as. |
| children | ReactNode | — | Button label. |
| classes | ButtonClasses | — | Classes for internal parts. |
| color | ButtonColor | "primary" | Semantic color of the button. |
| customProps | ButtonCustomProps | — | Extra props for internal parts. Root HTML attributes stay on the component top level. |
| density | ButtonDensity | "default" | Density preset. |
| disabled | boolean | false | Whether the button is disabled. |
| endIcon | IconSource | — | Icon at the inline end. |
| full | boolean | false | Whether the button is full width. |
| href | string | — | Link URL. When linkAs is set, this also accepts that component’s href. |
| icon | IconSource | — | Icon for mini density (replaces label and start/end icons). |
| linkAs | ElementType | — | Component rendered in place of the navigating anchor. Vue also accepts a string tag. With href and no as, this renders a link. as="button" and as="span" ignore it. Ignored while disabled or loading. |
| linkProps | props of linkAs | — | Props forwarded to linkAs. Checked against that component. Ignored while linkAs is not rendered. |
| loading | boolean | false | Overlays a spinner, keeps the label in the DOM to preserve size, and disables the button. |
| rounded | ButtonRounded | "md" | Border radius. |
| selected | boolean | false | Whether the button is in a selected / pressed state. |
| size | ButtonSize | "md" | Button dimensions. |
| slots | ButtonSlots | — | React slots: start, end. |
| startIcon | IconSource | — | Icon at the inline start. |
| text | string | — | Label text when children is not provided. |
| variant | ButtonVariant | "solid" | Visual style variant. |