ee8797c142
Co-authored-by: Copilot <copilot@github.com>
5.4 KiB
5.4 KiB
Button
A styled <button> element. Supports six visual variants and four sizes. HTMX attributes can be injected directly via the hxAttrs parameter.
HTML structure
button[type=$$Type$$, class=$$Classes$$, $$HxAttrs$$]
$$Label$$
CSS mechanics
Base classes (always applied):
inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium
ring-offset-background transition-colors
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
disabled:pointer-events-none disabled:opacity-50
Variant appended:
| Variant | Added classes |
|---|---|
default |
bg-primary text-primary-foreground hover:bg-primary/90 |
destructive |
bg-destructive text-destructive-foreground hover:bg-destructive/90 |
outline |
border border-input bg-transparent hover:bg-accent hover:text-accent-foreground |
secondary |
bg-secondary text-secondary-foreground hover:bg-secondary/80 |
ghost |
hover:bg-accent hover:text-accent-foreground |
link |
text-primary underline-offset-4 hover:underline |
Size appended:
| Size | Added classes |
|---|---|
default |
h-10 px-4 py-2 text-sm |
sm |
h-9 rounded-md px-3 text-xs |
lg |
h-11 rounded-md px-8 text-base |
icon |
h-10 w-10 |
Constructor signature
public Button(
string label,
string variant = "default",
string size = "default",
string type = "button",
string hxAttrs = "")
| Parameter | Description |
|---|---|
label |
Button text (raw HTML — can include inline SVG) |
variant |
Visual style; see table above |
size |
Physical size; see table above |
type |
HTML button type: "button" / "submit" / "reset" |
hxAttrs |
Verbatim string appended as extra HTML attributes (HTMX, data-*, etc.) |
Usage examples
Standard actions
new Button("Save changes", type: "submit")
new Button("Cancel", variant: "outline")
new Button("Delete", variant: "destructive")
new Button("Learn more", variant: "link")
Sizes
new Button("Small", size: "sm")
new Button("Default", size: "default")
new Button("Large", size: "lg")
new Button("⚙", size: "icon") // icon-only square button
HTMX trigger
new Button(
"Load more",
hxAttrs: """hx-get="/items?page=2" hx-target="#item-list" hx-swap="beforeend"""")
Submit button inside a form
new Button("Sign in", variant: "default", type: "submit", size: "default")
Ghost button with inline SVG icon
new Button(
label: """
<svg class="h-4 w-4" .../>
<span>Refresh</span>
""",
variant: "ghost")
Disabled appearance (via HTML)
The Button component does not have a disabled constructor parameter. Set it via hxAttrs if needed:
new Button("Processing...", variant: "default", hxAttrs: "disabled aria-disabled='true'")
Tips and tricks
- Use
type: "submit"only inside<form>elements. Outside a form, always usetype: "button"to prevent accidental page reloads in some browsers. hxAttrsis written verbatim between the class and the closing>of the button tag — you can add any attribute here:hx-*,data-*,aria-*,onclick, etc.- The
ghostvariant has no visible background at rest — use it for toolbar actions or secondary icon buttons. - The
linkvariant looks like an anchor but behaves as a button — useful for inline text actions that trigger JS or HTMX requests rather than navigation. - To use Button as a DropdownMenu trigger, pass a
Buttoninstance toDropdownMenu'striggerparameter.
Complete page example
Templates/SettingsPage.htmx
<div class="max-w-lg mx-auto py-10 space-y-6">
<h1 class="text-2xl font-bold">Settings</h1>
<div class="flex gap-3">
$$SaveBtn$$
$$CancelBtn$$
$$DangerBtn$$
</div>
<div class="border-t pt-4">
$$LearnMoreLink$$
</div>
</div>
Templates/SettingsPage.htmx.cs
namespace Htmx.ApiDemo.Templates;
public sealed class SettingsPage : SettingsPageBase
{
private readonly IHtmxComponent _save;
private readonly IHtmxComponent _cancel;
private readonly IHtmxComponent _danger;
private readonly IHtmxComponent _learn;
public SettingsPage()
{
_save = new Components.Button("Save changes", type: "submit");
_cancel = new Components.Button("Cancel", variant: "outline");
_danger = new Components.Button("Delete account", variant: "destructive",
hxAttrs: "data-dialog-open=\"confirm-delete\"");
_learn = new Components.Button("Learn more about settings", variant: "link");
}
protected override void RenderSaveBtn(HtmxRenderContext ctx) => _save.Render(ctx.Next());
protected override void RenderCancelBtn(HtmxRenderContext ctx) => _cancel.Render(ctx.Next());
protected override void RenderDangerBtn(HtmxRenderContext ctx) => _danger.Render(ctx.Next());
protected override void RenderLearnMoreLink(HtmxRenderContext ctx) => _learn.Render(ctx.Next());
}
GET handler
[Handler]
[MapGet("/settings")]
public static partial class GetSettingsHandler
{
public record Query();
private static Task<IResult> HandleAsync(
Query _,
HttpContext ctx,
CancellationToken ct)
=> ctx.WriteHtmxPage(new SettingsPage(), title: "Settings");
}