f6ae86617c
Co-authored-by: Copilot <copilot@github.com>
192 lines
5.6 KiB
Markdown
192 lines
5.6 KiB
Markdown
# 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");
|
||
}
|
||
```
|