b530bb8c97
Co-authored-by: Copilot <copilot@github.com>
4.6 KiB
4.6 KiB
Badge
A small coloured pill label — the kind you see next to a status field that says "Active", "Pending", or "Error".
Quick example
new Badge("Active")
new Badge("Pending", variant: "secondary")
new Badge("Error", variant: "destructive")
new Badge("Draft", variant: "outline")
All the options
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:
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
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
<!-- MyPage.htmx -->
<div class="flex items-center gap-2">
<span>Status:</span>
$$StatusBadge$$
</div>
// 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
<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
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
[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");
}
}