Button
A fully styled, accessible button with semantic variants, configurable sizes, loading state, and safe Tailwind overrides.
Overview
MButton is beautiful by default. Write <MButton>Save Changes</MButton> and the result
is already styled, accessible, and production-ready. Use Variant to communicate intent,
Size to control scale, and Loading for async feedback. The Class parameter
lets you override any default safely — user-supplied classes always win conflicts.
Usage
@using Marai.UI.Components.MButtonBasic Usage
@using Marai.UI.Components.MButton
<div class="flex flex-wrap gap-3">
<MButton>Save Changes</MButton>
<MButton Variant="Variant.Primary">Submit</MButton>
<MButton Variant="Variant.Outline">Cancel</MButton>
</div>
Variants
Use Variant to communicate intent. All variants use token-driven colors from your active theme.
@using Marai.UI.Components.MButton
<div class="flex flex-wrap gap-3">
<MButton Variant="Variant.Default">Default</MButton>
<MButton Variant="Variant.Primary">Primary</MButton>
<MButton Variant="Variant.Secondary">Secondary</MButton>
<MButton Variant="Variant.Destructive">Destructive</MButton>
<MButton Variant="Variant.Outline">Outline</MButton>
<MButton Variant="Variant.Ghost">Ghost</MButton>
<MButton Variant="Variant.Link">Link</MButton>
<MButton Variant="Variant.Success">Success</MButton>
<MButton Variant="Variant.Warning">Warning</MButton>
<MButton Variant="Variant.Info">Info</MButton>
<MButton Variant="Variant.Muted">Muted</MButton>
</div>
Sizes
Use Size to control button scale. Defaults to Size.Default.
@using Marai.UI.Components.MButton
<div class="flex flex-wrap items-center gap-3">
<MButton Variant="Variant.Primary" Size="Size.Xs">Extra Small</MButton>
<MButton Variant="Variant.Primary" Size="Size.Sm">Small</MButton>
<MButton Variant="Variant.Primary" Size="Size.Default">Default</MButton>
<MButton Variant="Variant.Primary" Size="Size.Lg">Large</MButton>
<MButton Variant="Variant.Primary" Size="Size.Xl">Extra Large</MButton>
</div>
Loading State
Set Loading="true" to show an inline spinner, disable the button, and communicate the busy state to
screen readers via aria-busy. Button content remains visible and the button width does not collapse.
@using Marai.UI.Components.MButton
<div class="flex flex-wrap gap-3">
<MButton Variant="Variant.Primary" Loading="true">Processing</MButton>
<MButton Variant="Variant.Outline" Loading="true">Saving</MButton>
<MButton Variant="Variant.Destructive" Loading="true">Deleting</MButton>
</div>
<div class="mt-4 flex flex-wrap gap-3">
<MButton Variant="Variant.Primary" Loading="@_isSubmitting" OnClick="HandleSubmit">
@(_isSubmitting ? "Submitting" : "Approve Merchant")
</MButton>
</div>
@code {
private bool _isSubmitting;
private async Task HandleSubmit()
{
_isSubmitting = true;
await Task.Delay(2000);
_isSubmitting = false;
}
}
Disabled State
Set Disabled="true" to apply the native disabled attribute. Default styling includes
disabled:pointer-events-none disabled:opacity-50.
@using Marai.UI.Components.MButton
<div class="flex flex-wrap gap-3">
<MButton Variant="Variant.Primary" Disabled="true">Submit</MButton>
<MButton Variant="Variant.Outline" Disabled="true">Cancel</MButton>
<MButton Variant="Variant.Destructive" Disabled="true">Delete Account</MButton>
</div>
Form Submit and Reset
Use Type="submit" or Type="reset" for form buttons.
The default Type is "button" to prevent accidental form submission.
@using Marai.UI.Components.MButton
<div class="flex gap-3">
<MButton Variant="Variant.Primary" Type="submit">
Submit Application
</MButton>
<MButton Variant="Variant.Outline" Type="reset">
Reset Form
</MButton>
</div>
Click Handler
@using Marai.UI.Components.MButton
<MButton Variant="Variant.Primary" OnClick="HandleApprove">
Approve Transaction
</MButton>
@if (_approved)
{
<p class="mt-3 text-sm text-green-700">Transaction approved successfully.</p>
}
@code {
private bool _approved;
private void HandleApprove()
{
_approved = true;
}
}
Icon Button
Use Size="Size.Icon" for square icon buttons. Always provide aria-label for screen readers.
@using Marai.UI.Components.MButton
<div class="flex flex-wrap gap-3">
<MButton Variant="Variant.Outline" Size="Size.Icon" aria-label="Add merchant">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" viewBox="0 0 24 24" aria-hidden="true">
<line x1="12" y1="8" x2="12" y2="16" />
<line x1="8" y1="12" x2="16" y2="12" />
</svg>
</MButton>
<MButton Variant="Variant.Ghost" Size="Size.Icon" aria-label="Delete record">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" viewBox="0 0 24 24" aria-hidden="true">
<path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6" />
</svg>
</MButton>
</div>
Theming
Button colors are driven by your theme's CSS variables — --marai-primary, --marai-primary-foreground,
and equivalents for each variant. Switch the active theme and all buttons update automatically.
Safe Tailwind Overrides
The Class parameter is appended last, so it always wins conflicts. Override radius, background, padding — anything.
@using Marai.UI.Components.MButton
<div class="flex flex-wrap gap-3">
<MButton Variant="Variant.Primary" Class="rounded-full px-6">
Pill Shape
</MButton>
<MButton Variant="Variant.Outline" Class="border-2 font-semibold">
Bold Outline
</MButton>
<MButton Variant="Variant.Ghost" Class="text-slate-500">
Subtle Ghost
</MButton>
</div>
Standard HTML Attributes
Any unrecognized attribute passes through to the <button> element.
@using Marai.UI.Components.MButton
<MButton Variant="Variant.Primary"
aria-label="Save merchant profile"
data-testid="save-merchant-btn"
name="intent"
value="save">
Save Merchant
</MButton>
Accessibility
- Focus-visible ring is built in — keyboard navigation is visible by default
Loadingsetsaria-disabledandaria-busyautomatically- Use
aria-labelon icon-only buttons — visible text is not sufficient for screen readers - Use
Type="submit"inside<EditForm>— the default"button"prevents accidental submission - Arbitrary ARIA attributes (
aria-pressed,aria-expanded,aria-controls) pass through viaAdditionalAttributes
API Reference
| Parameter | Type | Default | Description |
|---|---|---|---|
| Variant | Variant | Variant.Default |
Visual and semantic style. Maps to token-driven colors. |
| Size | Size | Size.Default |
Height, padding, and font-size preset. |
| Loading | bool | false |
Shows inline spinner, disables the button, and sets aria-busy. |
| Disabled | bool | false |
Applies the native disabled attribute and reduces opacity. |
| Type | string | "button" |
Native HTML type. Use "submit" or "reset" for form buttons. |
| Class | string? | null |
Additional Tailwind classes. User-supplied classes win all conflicts. |
| ChildContent | RenderFragment? | null |
Content rendered inside the button — text, icons, or any markup. |
| OnClick | EventCallback<MouseEventArgs> | — | Blazor click callback invoked when the button is clicked. |
| AdditionalAttributes | Dictionary<string, object>? | null |
Any unmatched HTML attributes pass through to the <button>. |