Button
Anatomy
Clickable action element with variants for style (Default, Primary, Secondary, etc.) and sizes (Xs–Lg plus icon-only variants).
maud_ui::primitives::button
Props
Generated from public Rust fields. Defaults are evaluated from the implementation.
| Prop | Type | Default | Description |
|---|---|---|---|
label | String | "Button" | No description |
variant | Variant | Default | No description |
size | Size | Md | No description |
disabled | bool | false | No description |
button_type | &'static str | "button" | No description |
leading_icon | Option<Markup> | None | Optional leading icon (SVG markup). Use stroke="currentColor" so it inherits the button's text color — emoji characters do NOT inherit color and will render in OS system colors. Emitted as a span with data-icon="inline-start". |
trailing_icon | Option<Markup> | None | Optional trailing icon (SVG markup). Same rules as leading_icon — use stroke="currentColor" so it inherits the button's text color. Emitted as a span with data-icon="inline-end" AFTER the label. |
aria_label | Option<String> | None | aria-label override. Required for icon-only buttons (where label is empty) so screen readers announce the button's purpose. |
class | Option<String> | None | Extra class names appended to the class list — the escape hatch for per-instance overrides that a closed enum cannot express (target the class from your own stylesheet instead of wrapping the button in a div). Rendered last, so it can override nothing by itself; it only gives your CSS a hook. |
bordered | bool | false | Ghost only: give the bare ghost a visible hairline boundary — a quiet bordered pill (the "New issue" button). Ignored by every other variant. |
Examples
Compact row actions
A fixed-height outline action that keeps its verb together inside a table cell.
Form actions
Primary/secondary pairing for settings, onboarding, checkout.
Destructive
Irreversible actions — only after a confirm dialog.
Loading state
Disabled + spinner icon while awaiting a response.
Icon + text
Leading glyph for recognition at a glance.
Trailing icon + leading/trailing pair
Trailing chevrons hint at navigation; pairing both icons frames a label in a command.
Size ladder (shadcn parity)
xs / sm / default / lg — plus four icon-only sizes with required aria-label.
Usage and composition
Import
use maud_ui::primitives::button::{self, Variant, Size, Props};
Example
use maud::html;
use maud_ui::primitives::button;
html! {
(button::render(button::Props {
label: "Save changes".to_string(),
variant: button::Variant::Primary,
size: button::Size::Md,
disabled: false,
button_type: "submit",
leading_icon: None,
trailing_icon: None,
aria_label: None,
}))
}
Variant Styles
| Variant | Use Case |
|---|---|
| Default | Default/neutral button. |
| Primary | Primary call-to-action (Save, Submit, Continue). |
| Secondary | Secondary action (Cancel, Back, etc.). |
| Outline | Outlined button for emphasis without primary color. |
| Ghost | Minimal ghost style, usually for low-priority actions. |
Ghost + bordered | Ghost with a visible hairline (the "New issue" pill). |
| Translucent | Frosted icon pill: white 4% ground, 1px inset highlight ring, muted ink, full radius. |
| Danger | Destructive actions (Delete, Revoke); use with AlertDialog. |
| Link | Styled as a text link. |
Size Ladder
| Size | Class | Notes |
|---|---|---|
| Row | mui-btn--row | Fixed 2rem height, nowrap; pair with Outline for quiet table-cell actions. |
| Xs | mui-btn--xs | Extra-small text button. |
| Sm | mui-btn--sm | Small text button. |
| Md | mui-btn--md | Default text button. |
| Lg | mui-btn--lg | Large text button. |
| Icon | mui-btn--icon | Icon-only button (requires aria_label). |
| IconXs | mui-btn--icon-xs | Extra-small icon-only (requires aria_label). |
| IconSm | mui-btn--icon-sm | Small icon-only (requires aria_label). |
| IconSm28 | mui-btn--icon-28 | The 28px square icon-only step (requires aria_label). |
| IconLg | mui-btn--icon-lg | Large icon-only (requires aria_label). |
Related
ButtonGroup, AlertDialog, Link.
Shadcn reference
https://ui.shadcn.com/docs/components/base/button
Navigation actions use an <a> with the same mui-btn, variant, and size classes as a native button. Every anchor variant stays free of underlines, including hover and focus and when placed inside docs or prose. Use ordinary prose links when an underline is desired.
Accessibility
- Icon-only buttons (
Size::Icon*) must havearia_labelset; enforced bydebug_assert!at render time in debug builds. - Icons use
stroke="currentColor"to inherit button text color (emoji characters do NOT inherit and render in OS colors). - Icons marked
aria-hidden="true"to prevent double announcement. - Disabled buttons set
aria-disabled="true"(not HTMLdisabledattribute for better style control).