Variant System
A semantic, token-driven system for communicating intent across all Marai.UI components. Variants map directly to your active theme — no hardcoded colors, no manual class strings.
Overview
The Variant enum is the primary way to communicate visual and semantic intent in Marai.UI.
Every component that supports visual variation accepts a Variant parameter.
Variants are resolved through the theme's CSS token system — switching themes updates every component automatically.
Variant Reference
All variant values are members of the Variant enum in the Marai.UI.Utilities namespace.
| Variant | Semantic Meaning | Intended Use |
|---|---|---|
Variant.Default |
Neutral / no emphasis | Neutral default state, low-emphasis and fallback contexts |
Variant.Primary |
Brand identity, main CTA | One primary action per context — submit, save, confirm |
Variant.Secondary |
Supporting action | Cancel, back, secondary navigation alongside Primary |
Variant.Destructive |
Irreversible action | Delete, remove, revoke — always confirm before firing |
Variant.Outline |
Low-weight bordered action | Secondary actions that need visual separation without fill |
Variant.Ghost |
Minimal footprint | Toolbar buttons, icon actions — only visible on hover |
Variant.Link |
Inline text action | Navigation links, inline actions that look like hyperlinks |
Variant.Success |
Positive / confirmed state | Active merchant, approved transaction, completed step |
Variant.Warning |
Attention required | Pending verification, review required, expiring soon |
Variant.Info |
Neutral information | Help text, informational banners, supplementary context |
Variant.Muted |
Subdued, background emphasis | Metadata, timestamps, secondary labels |
Usage
Buttons
<MButton Variant="Variant.Primary">Approve Settlement</MButton>
<MButton Variant="Variant.Outline">View Details</MButton>
<MButton Variant="Variant.Destructive">Revoke Access</MButton>Badges
<MBadge Variant="Variant.Success">Active</MBadge>
<MBadge Variant="Variant.Warning">Pending Review</MBadge>
<MBadge Variant="Variant.Destructive">Suspended</MBadge>Semantic Usage Guidelines
- Primary — limit to one per context. The most important action on a screen
- Destructive — always pair with a confirmation dialog or warning
- Success — for confirmed, active, or completed states — not just "green"
- Warning — for pending or attention-required — not errors
- Muted — for metadata and labels that support content without drawing attention
| ✅ Do | ❌ Don't |
|---|---|
| Use Primary for the single most important action per section | Use multiple Primary buttons in the same form or card |
| Use Destructive for delete, revoke, and irreversible actions | Use Destructive for general "decline" or "cancel" actions |
| Use Success for confirmed, active, and approved states | Use Success purely for visual color without semantic meaning |
| Use Outline or Ghost for secondary actions alongside Primary | Make all buttons the same variant (no visual hierarchy) |
| Use Warning for pending, expiring, or requires-attention states | Use Warning interchangeably with Destructive — they communicate different urgency |
How Tokens Work
Each variant maps to a set of CSS custom properties injected by <MStyleInjector />.
Components read these tokens at render time — not hardcoded hex values. This means:
- Switching the active theme changes all component colors simultaneously
- Dark mode support is handled at the token level — no per-component logic needed
- Brand customization is done once in
Program.csand propagates everywhere
// In Program.cs — customize the Primary brand color
builder.Services.AddMaraiUI(options =>
{
options.Colors.Primary = "#1e3a8a"; // Deep Blue
options.Colors.Secondary = "#64748b"; // Slate Gray
options.Colors.Success = "#059669"; // Emerald Green
options.Colors.Destructive = "#dc2626"; // Red
options.Colors.Warning = "#f59e0b"; // Amber
options.Colors.Info = "#0284c7"; // Sky Blue
});Dark Mode
Variants work identically in dark mode. The <MStyleInjector /> injects separate token sets
for light and dark mode, selected by the dark class on <html>.
Enable dark mode with ThemeService:
@inject ThemeService ThemeService
<MButton Variant="Variant.Ghost" OnClick="ThemeService.ToggleDarkMode">
Toggle Dark Mode
</MButton>Components That Accept Variant
The following components support the Variant parameter:
| Component | Variants Supported |
|---|---|
| MButton | All — Primary, Secondary, Destructive, Outline, Ghost, Link, Success, Warning, Info, Muted |
| MBadge | All — semantic status labels |
| MSpinner | Color variants — Primary, Secondary, Success, Destructive, Warning, Info, Muted |
API Reference
Variant Enum
Namespace: Marai.UI.Utilities
namespace Marai.UI.Utilities;
public enum Variant
{
Default,
Primary,
Secondary,
Destructive,
Outline,
Ghost,
Link,
Success,
Warning,
Info,
Muted
}