ee8797c142
Co-authored-by: Copilot <copilot@github.com>
4.7 KiB
4.7 KiB
Badge
A small inline label pill. Used to indicate status, category, or count. Four variants cover most use-cases.
HTML structure
span.{base classes + variant classes}
{text}
CSS mechanics
| Class | Effect |
|---|---|
inline-flex items-center rounded-full |
Pill shape that sits inline with text |
px-2.5 py-0.5 text-xs font-semibold |
Compact size and bold label |
transition-colors |
Smooth color changes on hover |
focus:ring-2 focus:ring-ring focus:ring-offset-2 |
Keyboard focus outline |
Variants:
| Variant | Classes |
|---|---|
default |
bg-primary text-primary-foreground hover:bg-primary/80 |
secondary |
bg-secondary text-secondary-foreground hover:bg-secondary/80 |
destructive |
bg-destructive text-destructive-foreground hover:bg-destructive/80 |
outline |
text-foreground border border-input hover:bg-accent |
Constructor signature
public Badge(string text, string variant = "default")
| Parameter | Description |
|---|---|
text |
Label displayed inside the badge |
variant |
"default" / "secondary" / "destructive" / "outline" |
Usage examples
Basic badges
new Badge("New")
new Badge("Beta", variant: "secondary")
new Badge("Error", variant: "destructive")
new Badge("Pending", variant: "outline")
Status indicator in a table cell
// Render to bytes and embed in table cell HTML
var writer = new System.Buffers.ArrayBufferWriter<byte>();
new Badge("Active", variant: "default").Render(new HtmxRenderContext(writer));
var badgeHtml = System.Text.Encoding.UTF8.GetString(writer.WrittenSpan);
new Table(
headers: new[] { "Name", "Status" },
rows: users.Select(u => new[] { u.DisplayName ?? "", badgeHtml }))
Embedding in a page slot
<!-- MyPage.htmx -->
<div class="flex items-center gap-2">
<span class="text-sm">Status:</span>
$$StatusBadge$$
</div>
// MyPage.htmx.cs
public IHtmxComponent StatusBadge { get; }
public MyPage(string status)
{
StatusBadge = status == "active"
? new Badge("Active")
: new Badge("Inactive", variant: "secondary");
}
protected override void RenderStatusBadge(HtmxRenderContext ctx)
=> StatusBadge.Render(ctx.Next());
Tips and tricks
- Badge does not have a click handler — wrap it in an
<a>or aButtonif you need interactivity. - All four variants respond to focus, so a Badge embedded inside a focusable element will show a ring.
- For a count badge (e.g.
"3 new") just include the count in the text string. - To render a Badge inside raw HTML strings (e.g. inside a
Tablecell orCardcontent), render it eagerly to a string in the constructor rather than relying on slot rendering.
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");
}
}