Veto
Components

Button

A labelled button with optional icons and a loading state. Becomes a real link when you give it an Href.

Variants

Filled for the one action you want taken, outlined for the alternatives, text for the ones that should stay out of the way. Soft sits between filled and outlined, underlined reads as a link, ghost stays muted until hovered, and elevated lifts off the page.

razor
<VetoButton Variant="VetoVariant.Filled">Save changes</VetoButton>
<VetoButton Variant="VetoVariant.Outlined">Cancel</VetoButton>
<VetoButton Variant="VetoVariant.Text">Learn more</VetoButton>
<VetoButton Variant="VetoVariant.Soft">Draft</VetoButton>
<VetoButton Variant="VetoVariant.Underlined">Read the guide</VetoButton>
<VetoButton Variant="VetoVariant.Ghost">Share</VetoButton>
<VetoButton Variant="VetoVariant.Elevated">Open</VetoButton>

Colour roles

Each role sets one custom property that every variant reads, so a role costs one rule rather than one per variant.

razor
<VetoButton Color="VetoColor.Danger">Delete</VetoButton>
<VetoButton Color="VetoColor.Danger" Variant="VetoVariant.Outlined">Delete</VetoButton>

Sizes and shape

Three sizes, each with a minimum height that keeps the target comfortably clickable. FullWidth stretches to the container; Rounded fully rounds the ends.

razor
<VetoButton Size="VetoSize.ExtraSmall">Extra small</VetoButton>
<VetoButton Size="VetoSize.Small">Small</VetoButton>
<VetoButton Size="VetoSize.Large">Large</VetoButton>
<VetoButton Size="VetoSize.ExtraLarge">Extra large</VetoButton>
<VetoButton Rounded="true">Rounded</VetoButton>
<VetoButton FullWidth="true">Full width</VetoButton>

With icons

An icon before the label or after it. Icons inherit the button's font size, so they scale with it rather than needing their own.

razor
<VetoButton StartIcon="@VetoIcons.Check">Confirm</VetoButton>
<VetoButton EndIcon="@VetoIcons.ChevronRight">Next</VetoButton>

Loading and disabled

A loading button keeps its colours and disables itself while it waits - it is busy, not unavailable. The label stays in place, so the button does not change width and shift the layout around it.

razor
<VetoButton StartIcon="@VetoIcons.Check" Loading="_saving" OnClick="SaveAsync">
    Save changes
</VetoButton>

@code {
    private bool _saving;

    private async Task SaveAsync()
    {
        _saving = true;
        await SaveTheThing();
        _saving = false;
    }
}

As a link

With an Href the button renders an anchor, so middle-click, open-in-new-tab and the browser's status bar all behave. A disabled button never renders as a link, because a disabled anchor is still clickable.

razor
<VetoButton Href="/docs/usage" EndIcon="@VetoIcons.ChevronRight">
    Read the usage guide
</VetoButton>

Busy while it works

LoadingOnClick shows the loading state for exactly as long as the OnClick handler runs, and ignores clicks meanwhile - no double submit, and no flag on the page to keep in step.

0
razor
<VetoButton StartIcon="@VetoIcons.Check" LoadingOnClick="true" OnClick="SubmitAsync">
    Submit
</VetoButton>

@code {
    private async Task SubmitAsync () => await Task.Delay(1200);
}

Right-click menu

ContextMenu is a menu of your own opened at the pointer on right-click, filled with VetoMenuItem, VetoMenuLabel and VetoMenuDivider as any VetoMenu is. Each item does what its OnClick says, and choosing one closes the menu. Escape or a click elsewhere closes it too; the arrow keys move between items. Leave it null, or disable the button, and right-click is the browser's own.

Right-click the button.
razor
<VetoButton StartIcon="@VetoIcons.Document" ContextMenuLabel="Report actions" OnClick="Open">
    <ChildContent>Report.pdf</ChildContent>
    <ContextMenu>
        <VetoMenuItem Icon="@VetoIcons.Edit" Text="Rename" OnClick="Rename" />
        <VetoMenuItem Icon="@VetoIcons.Copy" Text="Duplicate" OnClick="Duplicate" />
        <VetoMenuDivider />
        <VetoMenuItem Icon="@VetoIcons.Trash" Text="Delete" Destructive="true" OnClick="Delete" />
    </ContextMenu>
</VetoButton>

Parameters

Parameter Type Default Description
ChildContent RenderFragment? null The button's label.
StartIcon string? null An icon before the label.
EndIcon string? null An icon after the label.
Size VetoSize Medium ExtraSmall, Small, Medium, Large or ExtraLarge.
Variant VetoVariant Filled Filled, Outlined, Text, Soft, Underlined (underlines the label), Ghost or Elevated.
Color VetoColor Primary Primary, Secondary, Neutral, Success, Warning or Danger.
FullWidth bool false Stretches to the width of the container.
Rounded bool false Fully rounds the ends.
Loading bool false Swaps the leading icon for a spinner and disables the button.
LoadingOnClick bool false Shows the loading state while the OnClick handler runs, and ignores clicks until it finishes.
Disabled bool false Disables the button. A disabled button never renders as a link.
Type string "button" The type attribute. Defaults to button so it never submits a form by accident.
Href string? null Renders an anchor and navigates instead of raising OnClick.
Target string? null The link target, when Href is set.
OnClick EventCallback<MouseEventArgs> — Raised when the button is activated.
ContextMenu RenderFragment? null A menu opened at the pointer on right-click. Null leaves right-click to the browser.
ContextMenuLabel string? null The accessible name of the right-click menu.
Something went wrong. Reload 🗙