Files
Htmx/docs/Components/Button.md
T
2026-05-05 23:55:26 +05:00

192 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Button
A styled clickable button. Use it for form submissions, navigation actions, or triggering HTMX requests.
---
## Quick example
```csharp
new Button("Save changes", type: "submit")
new Button("Cancel", variant: "outline")
new Button("Delete", variant: "destructive")
```
---
## All the options
```csharp
public Button(
string label,
string variant = "default",
string size = "default",
string type = "button",
string hxAttrs = "")
```
| Parameter | What it does |
|---|---|
| `label` | The button text. Can include raw HTML — useful for icons. |
| `variant` | Visual style. See table below. |
| `size` | How big the button is. See table below. |
| `type` | HTML button type. Use `"submit"` for form submit buttons. Defaults to `"button"`. |
| `hxAttrs` | Extra HTML attributes added verbatim — use this for HTMX, `disabled`, `data-*`, etc. |
**Variants:**
| Variant | Looks like |
|---|---|
| `default` | Filled with the primary colour — use for the main action on a page |
| `destructive` | Red — use for irreversible actions like delete |
| `outline` | Transparent with a border — use for secondary actions |
| `secondary` | Muted fill — use for tertiary actions |
| `ghost` | Invisible until hovered — use for toolbar buttons and icon actions |
| `link` | Looks like a hyperlink with an underline on hover |
**Sizes:**
| Size | Dimensions |
|---|---|
| `sm` | Compact (36px tall) — good for dense UI |
| `default` | Standard (40px tall) |
| `lg` | Large (44px tall) — good for prominent CTAs |
| `icon` | Square (40×40) — for icon-only buttons |
---
## Real-world examples
### Form submit button
```csharp
new Button("Sign in", type: "submit")
```
### Confirm and cancel in a dialog footer
```csharp
var footer = """
{cancelButton}
{deleteButton}
""";
// Pre-render each to HTML string and embed:
string Render(IHtmxComponent c)
{
var w = new System.Buffers.ArrayBufferWriter<byte>();
c.Render(new HtmxRenderContext(w));
return System.Text.Encoding.UTF8.GetString(w.WrittenSpan);
}
new Card(
content: "<p>Are you sure you want to delete this item?</p>",
footer: Render(new Button("Cancel", variant: "outline"))
+ Render(new Button("Delete", variant: "destructive", type: "submit")))
```
### HTMX load more button
```csharp
new Button(
"Load more",
variant: "outline",
hxAttrs: """hx-get="/items?page=2" hx-target="#item-list" hx-swap="beforeend"""")
```
### Icon-only ghost button (e.g. a refresh icon in a toolbar)
```csharp
new Button(
label: "<svg class='h-4 w-4' ...fill or stroke SVG here/>",
variant: "ghost",
size: "icon")
```
### Disabled state
Button does not have a `disabled` parameter. Pass it through `hxAttrs`:
```csharp
new Button("Processing...", hxAttrs: "disabled aria-disabled='true'")
```
---
## How it works
Button is a `<button>` element — straightforward HTML with Tailwind classes. The `hxAttrs` string is appended verbatim inside the opening `<button>` tag, so any valid HTML attribute works there. The `label` is inserted as raw HTML, which is how inline SVG icons are supported.
```
---
## Tips and tricks
- Use `type: "submit"` only inside `<form>` elements. Outside a form, always use `type: "button"` to prevent accidental page reloads in some browsers.
- `hxAttrs` is written verbatim between the class and the closing `>` of the button tag — you can add any attribute here: `hx-*`, `data-*`, `aria-*`, `onclick`, etc.
- The `ghost` variant has no visible background at rest — use it for toolbar actions or secondary icon buttons.
- The `link` variant 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 `Button` instance to `DropdownMenu`'s `trigger` parameter.
---
## Complete page example
**`Templates/SettingsPage.htmx`**
```html
<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`**
```csharp
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**
```csharp
[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");
}
```