Button
Triggers an action or navigation, with variants, sizes and a loading state.
Selector: button[muiButton], a[muiButton]
import { Button } from '@mushilu-san/ui/primitives';Loading example…
Overview
<button> or <a>, so it keeps the native role, form submission and keyboard behaviour for free.
aria-disabled="true" and swallow clicks. A disabled button is also taken out of the tab order (tabindex="-1"), while a loading one keeps focus so the state is announced.
When to use
Submitting a form or confirming a step. Triggering an in-page action, such as opening a Dialog. A call to action that navigates. Apply muiButtonto an<a>so it is still a link.
When not to use
Switching between views of related content. Use Tabs instead.Inline navigation inside a sentence. Use a plain link.
Examples
Sizes
Loading example…
Loading and disabled
loading is set the button sets aria-busy and ignores clicks.
Loading example…
As a link
<a muiButton> when the action navigates.
Loading example…
Guidelines
Do
Use one primarybutton per view for the main action.Write labels as verbs that describe the outcome: "Save changes", not "OK". Use destructivefor actions that delete or cannot be undone, and confirm them.Use loadingfor in-flight actions rather than disabling the button, so focus is not lost.
Don't
Do not put a muiButtonon a<div>or<span>.Do not rely on colour alone to distinguish destructive actions. Say it in the label. Do not use a disabled button as the only explanation for why an action is unavailable. Tell the user why.
Accessibility
Roles and attributes
| Element | Role | Notes |
|---|---|---|
button[muiButton] | button (native) | |
a[muiButton] | link (native) | |
host | — | aria-disabled="true" when disabled or loading; aria-busy="true" while loading; tabindex="-1" when disabled. |
Keyboard
| Keys | Action |
|---|---|
| TabShiftTab | |
| EnterSpace |
Icon-only buttons need an aria-labelthat describes the action.The loading spinner is decorative ( aria-hidden). Change the label text if the state matters.
API
Button
| Name | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'ghost' | 'destructive' | 'primary' | Visual style: `primary` for the main action, `secondary` for supporting actions, `ghost` for low emphasis, `destructive` for irreversible actions. Default `primary`. |
size | 'sm' | 'md' | 'lg' | 'md' | Button size. Every size keeps a 44px minimum touch target. Default `md`. |
disabled | boolean | false | Disables the button. Sets `aria-disabled` and swallows clicks but keeps the element in the DOM. Accepts attribute presence, e.g. <… disabled>. |
loading | boolean | false | Shows a spinner and sets `aria-busy`. Clicks are ignored while loading. Accepts attribute presence, e.g. <… loading>. |
| Name | Type | Description |
|---|---|---|
clicked | MouseEvent | Emits the native click event unless the button is disabled or loading. |
CSS parts
::part(root)
Tokens
--mui-color-primary--mui-color-primary-hover--mui-color-primary-active--mui-color-danger--mui-color-danger-hover--mui-radius-md--mui-touch-target--mui-color-focus-ring