IconButton
An interactive page: C# runs over a Blazor Server connection.
Usage
<IconButton Icon="Lucide.Pencil" Label="Edit" Variant="ButtonVariant.Ghost" Accent="Accent.Neutral" />
@* A link. *@
<IconButton Icon="Lucide.ExternalLink" Label="Open the docs" Href="https://example.com/docs" />
@* In a form: posts delete=42 when pressed. *@
<IconButton Icon="Lucide.Trash" Label="Delete invoice 42" Submit Name="delete" Value="42"
Accent="Accent.Danger" Variant="ButtonVariant.Ghost" />An IconButton is a Button with one icon and no visible text, for actions people know by their icon: edit, delete, more. Label is required: it's the button's name and its tooltip. When the icon alone isn't clear, use a Button with text.
Labels and variants
Use Label for what the button does, and Variant, Accent and Href as on Button.
Code
<Row Gap="2" Align="Align.Center" Wrap Justify="Justify.Center">
<IconButton Icon="Lucide.Plus" Label="New project" />
<IconButton Icon="Lucide.Settings" Label="Settings" Variant="ButtonVariant.Soft" />
<IconButton Icon="Lucide.Pencil" Label="Edit" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.Ellipsis" Label="More actions" Variant="ButtonVariant.Ghost" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.Trash" Label="Delete" Variant="ButtonVariant.Ghost" Accent="Accent.Danger" />
<IconButton Icon="Lucide.ExternalLink" Label="Open Lucide's icon list" Href="https://lucide.dev/icons" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
</Row>Ghost with a Neutral accent suits rows of tools, where a filled button for each would be loud; keep a solid one for the action that matters most.
Sizes and states
Use Size, Loading and Disabled as on Button.
Preview
Code
<Row Gap="2" Align="Align.Center" Wrap Justify="Justify.Center">
<IconButton Icon="Lucide.Bell" Label="Notifications" Size="ControlSize.Sm" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.Bell" Label="Notifications" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.Bell" Label="Notifications" Size="ControlSize.Lg" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.RefreshCw" Label="Refresh" Loading Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.Share2" Label="Share" Disabled Variant="ButtonVariant.Outline" Accent="Accent.Neutral" />
</Row>Actions on a row
Use Href for a link and Submit with Name and Value to post which row a button is on, with OnClick for the same on interactive pages.
Preview
Previewing team-photo.jpg.
Code
NavigationManager Navigation
@* A link and a post on each row. Static pages: Delete posts its Name=Value and redirects with the
deleted names in the address. Interactive pages: OnClick says which button it was. *@
<form method="post" @formname="icon-button-files" @onsubmit="Delete" data-enhance class="ib-grow">
<AntiforgeryToken />
<Stack Gap="0" MaxWidth="28.Rem" Grow Border="1" Radius="Radius.Md">
foreach (var file in Shown)
{
<Row Gap="1" Align="Align.Center" PaddingX="3" PaddingY="2" BorderTop="(file == Shown[0] ? 0 : 1)">
<Icon Name="Lucide.FileText" Color="Color.Muted" />
<TextBlock As="span" Grow Truncate MarginLeft="1">file</TextBlock>
<IconButton Icon="Lucide.Eye" Label="($"Preview {file}")" Href="Navigation.GetUriWithQueryParameter("preview", file)"
Size="ControlSize.Sm" Variant="ButtonVariant.Ghost" Accent="Accent.Neutral" />
<IconButton Icon="Lucide.Trash" Label="($"Delete {file}")" Submit Name="delete" Value="file"
OnClick="() => _clicked = file"
Size="ControlSize.Sm" Variant="ButtonVariant.Ghost" Accent="Accent.Danger" />
</Row>
}
if (Shown.Count == 0)
{
<TextBlock Size="TextSize.Sm" Color="Color.Muted" Padding="3">No files.</TextBlock>
}
</Stack>
</form>
if (Preview is not null && Shown.Contains(Preview))
{
<TextBlock Size="TextSize.Sm" Color="Color.Muted" MarginTop="2">Previewing Preview.</TextBlock>
}
if (_deleted.Count > 0)
{
<TextBlock Size="TextSize.Sm" Color="Color.Muted" MarginTop="2">
Deleted string.Join(", ", _deleted).
if (RendererInfo.IsInteractive)
{
<Button Variant="ButtonVariant.Link" Size="ControlSize.Sm" OnClick="() => _deleted.Clear()">Restore</Button>
}
else
{
<Anchor Href="Navigation.GetUriWithQueryParameter("deleted", (string?)null)">Restore</Anchor>
}
</TextBlock>
}
{
// Static pages: the deleted names live in the address (?deleted=…), so each page load knows them.
[SupplyParameterFromQuery(Name = "deleted")]
private string[]? DeletedQuery { get; set; }
[SupplyParameterFromQuery(Name = "preview")]
private string? Preview { get; set; }
// The pressed button's Name=Value posts with the form.
[SupplyParameterFromForm(FormName = "icon-button-files", Name = "delete")]
private string? Posted { get; set; }
// Interactive pages post nothing, so OnClick says which button it was.
private string? _clicked;
private List<string> _deleted = [];
private List<string> Shown => Files.Where(f => !_deleted.Contains(f)).ToList();
protected override void OnInitialized() => _deleted = [.. DeletedQuery ?? []];
private void Delete()
{
var file = Files.FirstOrDefault(f => f == (Posted ?? _clicked));
if (file is null || _deleted.Contains(file))
{
return;
}
_deleted.Add(file);
// A static post redirects to the new address, so a reload doesn't post again.
if (!RendererInfo.IsInteractive)
{
Navigation.NavigateTo(Navigation.GetUriWithQueryParameters(new Dictionary<string, object?> { ["deleted"] = _deleted.ToArray() }));
}
}
}Live: Delete runs OnClick in C#, and nothing is posted.
Put the row in the label too ("Delete budget-2026.xlsx"), so screen readers and the tooltip say which one. OnClick runs only on interactive pages; on static ones the post is what happens, as with Button.
A tooltip on focus
Wrap it in a Tooltip for a hint that shows on keyboard focus as well as hover, or for more than the label, such as a shortcut.
<Tooltip>
<Content>Bold <Kbd Keys="Ctrl+B" /></Content>
<ChildContent><IconButton Icon="Lucide.Bold" Label="Bold" Variant="ButtonVariant.Ghost" /></ChildContent>
</Tooltip>Mode support
| Feature | Off | Static | Live |
|---|---|---|---|
| Submit or reset a form, follow a link; Name and Value tell buttons apart | Yes | Yes | Yes |
| Loading and disabled states | Yes | Yes | Yes |
| OnClick runs C# | No | No | Yes |
Off: JavaScript disabled. Static: a static SSR page with IzzyBlazor's script. Live: an interactive page (Server, WebAssembly or Auto).
Accessibility
- It renders a native
button, or anawithHref, so Enter, Space and focus work as the browser defines them. Labelis required and becomes itsaria-label; the icon itself is hidden from screen readers.- The tooltip is the native
title, so it shows on mouse hover, not on keyboard focus. Inside aTooltipit has none, and the Tooltip shows on hover and focus. - A loading button (not a link) keeps focus and sets
aria-busyandaria-disabled; screen readers hearLoadingLabelbefore the label ("Loading Delete"). - A disabled or loading link loses its
href, keepsrole="link"and setsaria-disabled. - A toggle (
Pressed) setsaria-pressed, so screen readers hear "pressed" or "not pressed"; pressed, it shows an edge in the accent color as well as a tint.
Parameters
| Prop | Type | Default |
|---|---|---|
IconThe icon. | IconData | Required |
LabelWhat the button does, for screen readers and the tooltip. | string | Required |
HrefRenders a link to this URL instead of a button. | string? | |
SubmitSubmits the form it's in (or Form), when it's a button (not a link), like type="submit". | bool | false |
ResetResets the form it's in, when it's a button, like type="reset". | bool | false |
NamePosted with the form as Name=Value when this button submits it, so one handler can tell which button was pressed, such as which row's Delete. | string? | |
ValueThe value posted with Name. | string? | |
FormActionSubmits to this URL instead of the form's own action (native formaction). | string? | |
FormThe id of a form elsewhere on the page that this button submits (native form). | string? | |
AccentPrimary (the default) for the main action, Neutral for everything else, Danger for destructive actions, or a custom color (Accent.Of("#0d9488"), Accent.Token("brand")); text on a custom color is chosen for contrast. | Accent | Accent.Primary |
VariantVisual weight. | ButtonVariant | ButtonVariant.Solid |
SizeHeight. | ControlSize | ControlSize.Md |
StartIconAn icon before the text. | IconData? | |
EndIconAn icon after the text. | IconData? | |
FullWidthStretches to the full width of its container. | bool | false |
LoadingShows a spinner in place of the start icon and blocks further clicks. | bool | false |
LoadingLabelRead to screen readers while Loading. | string? | "Loading" |
DisabledDisables the button. | bool | false |
@bind-PressedMakes it a toggle button, such as Bold in an editor: true shows it pressed, false not, and screen readers hear which (aria-pressed). | bool? | |
ChildContentThe label. | RenderFragment? | |
OnClickRuns on click on interactive pages (a link still navigates). | EventCallback<MouseEventArgs> |
Plus 16 item props and 4 common props.
Full APISee also
- Button: submits, resets, links or runs C#.
- ButtonGroup: joined or spaced buttons with shared defaults.
- Tooltip: text on hover and keyboard focus.
- CopyButton: copies text, such as an install command.
- Troubleshooting: OnClick does nothing on a static page.