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

177 lines
4.6 KiB
Markdown

# Badge
A small coloured pill label — the kind you see next to a status field that says "Active", "Pending", or "Error".
---
## Quick example
```csharp
new Badge("Active")
new Badge("Pending", variant: "secondary")
new Badge("Error", variant: "destructive")
new Badge("Draft", variant: "outline")
```
---
## All the options
```csharp
public Badge(string text, string variant = "default")
```
| Parameter | What it does |
|---|---|
| `text` | The label inside the pill |
| `variant` | The colour scheme: `"default"` (primary colour), `"secondary"` (muted), `"destructive"` (red), `"outline"` (border only) |
---
## Real-world examples
### Status column in a user table
When you need a Badge inside a table cell (which takes a raw HTML string), render it to a string first:
```csharp
static string RenderBadge(string text, string variant)
{
var writer = new System.Buffers.ArrayBufferWriter<byte>();
new Badge(text, variant).Render(new HtmxRenderContext(writer));
return System.Text.Encoding.UTF8.GetString(writer.WrittenSpan);
}
new Table(
headers: new[] { "Name", "Role", "Status" },
rows: users.Select(u => new[]
{
u.DisplayName ?? "",
u.Role,
RenderBadge(u.IsActive ? "Active" : "Suspended",
u.IsActive ? "default" : "destructive"),
}))
```
### Dynamic variant based on data
```csharp
var badge = order.Status switch
{
"complete" => new Badge("Complete"),
"pending" => new Badge("Pending", variant: "secondary"),
"cancelled" => new Badge("Cancelled", variant: "destructive"),
_ => new Badge(order.Status, variant: "outline"),
};
```
### Inside a page slot
```html
<!-- MyPage.htmx -->
<div class="flex items-center gap-2">
<span>Status:</span>
$$StatusBadge$$
</div>
```
```csharp
// MyPage.htmx.cs
public sealed class MyPage : MyPageBase
{
private readonly IHtmxComponent _statusBadge;
public MyPage(string status)
{
_statusBadge = new Badge(status == "active" ? "Active" : "Inactive",
status == "active" ? "default" : "secondary");
}
protected override void RenderStatusBadge(HtmxRenderContext ctx)
=> _statusBadge.Render(ctx.Next());
}
```
---
## How it works
Badge is a `<span>` with `rounded-full` giving it the pill shape. The four variants are just different combinations of background and text colour classes. Badge is a purely server-rendered display element — it has no JavaScript and no click behaviour. If you need a clickable badge, wrap it in an `<a>` tag or use a `Button` component with a `link` variant.
---
## Complete page example
**`Templates/OrdersPage.htmx`**
```html
<div class="max-w-4xl mx-auto py-10">
<h1 class="text-2xl font-bold mb-6">Orders</h1>
$$OrdersTable$$
</div>
```
**`Templates/OrdersPage.htmx.cs`**
```csharp
namespace Htmx.ApiDemo.Templates;
public sealed class OrdersPage : OrdersPageBase
{
private readonly IHtmxComponent _table;
public OrdersPage(IEnumerable<Order> orders)
{
_table = new Components.Table(
headers: new[] { "Order", "Customer", "Amount", "Status" },
rows: orders.Select(o => new[]
{
System.Net.WebUtility.HtmlEncode(o.Id),
System.Net.WebUtility.HtmlEncode(o.CustomerName),
$"${o.Total:F2}",
BadgeHtml(o.Status),
}));
}
private static string BadgeHtml(string status)
{
var variant = status switch
{
"paid" => "default",
"pending" => "secondary",
"cancelled" => "destructive",
_ => "outline",
};
var buf = new System.Buffers.ArrayBufferWriter<byte>();
new Components.Badge(status, variant).Render(new HtmxRenderContext(buf));
return System.Text.Encoding.UTF8.GetString(buf.WrittenSpan);
}
protected override void RenderOrdersTable(HtmxRenderContext ctx)
=> _table.Render(ctx.Next());
}
```
**GET handler**
```csharp
[Handler]
[MapGet("/orders")]
public static partial class GetOrdersHandler
{
public record Query();
private static Task<IResult> HandleAsync(
Query _,
HttpContext ctx,
CancellationToken ct)
{
// Replace with real data source
var orders = new[]
{
new Order("ORD-001", "Alice Smith", 42.00m, "paid"),
new Order("ORD-002", "Bob Jones", 18.50m, "pending"),
new Order("ORD-003", "Carol White", 99.99m, "cancelled"),
};
return ctx.WriteHtmxPage(new OrdersPage(orders), title: "Orders");
}
}
```