ee8797c142
Co-authored-by: Copilot <copilot@github.com>
4.9 KiB
4.9 KiB
Alert
A contextual callout box for informational or error messages. Two variants: default (neutral) and destructive (red). An optional inline SVG icon is positioned automatically.
HTML structure
div[role=alert].{variant classes}
{icon SVG} ← positioned absolute top-left via Tailwind arbitrary selectors
div
h5.font-medium ← title (always rendered)
div.text-sm ← description (omitted when empty)
CSS mechanics
| Class / selector | Effect |
|---|---|
[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 |
Positions any direct SVG child at top-left |
[&>svg~*]:pl-7 |
Adds left padding to all siblings after the SVG so text is not covered by the icon |
[&>svg+div]:translate-y-[-3px] |
Vertically aligns the text div with the icon center |
border-destructive/50 text-destructive |
Red destructive variant |
The arbitrary selector approach ([&>svg]:*) means you can pass any SVG and it will be positioned correctly without extra wrapper divs.
Constructor signature
public Alert(
string title,
string description = "",
string variant = "default",
string icon = "")
| Parameter | Description |
|---|---|
title |
Required heading text |
description |
Optional body text below the title |
variant |
"default" or "destructive" |
icon |
Raw SVG string; omit for a text-only alert |
Usage examples
Informational (no icon)
new Alert(
title: "Heads up",
description: "Your session expires in 5 minutes.")
Destructive
new Alert(
title: "Error",
description: "Invalid email or password.",
variant: "destructive")
With an icon
new Alert(
title: "New message",
description: "You have 3 unread messages.",
variant: "default",
icon: """
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07
A19.5 19.5 0 013.07 9.77a19.79 19.79 0 01-3.07-8.67
A2 2 0 012 .18L5 0a2 2 0 012 1.72 ..."/>
</svg>
""")
Title-only
new Alert(title: "Changes saved successfully.", variant: "default")
Tips and tricks
- The icon SVG should be
h-4 w-4— larger sizes will push text out of alignment. - For the
destructivevariant the icon automatically inheritstext-destructivecolor via the variant class. - The
descriptionslot is a raw HTML string — you can include<a>links or<code>spans. - Use
Alertinside a page's optional error slot rather than always rendering it — pass an empty byte array ([]) when there is no error so the slot renders nothing.
Complete page example
Templates/SystemStatusPage.htmx
<div class="max-w-2xl mx-auto py-10 space-y-4">
<h1 class="text-2xl font-bold mb-6">System Status</h1>
$$MaintenanceAlert$$
$$DatabaseAlert$$
$$ApiAlert$$
</div>
Templates/SystemStatusPage.htmx.cs
namespace Htmx.ApiDemo.Templates;
public sealed class SystemStatusPage : SystemStatusPageBase
{
private readonly IHtmxComponent _maintenance;
private readonly IHtmxComponent _database;
private readonly IHtmxComponent _api;
public SystemStatusPage(bool maintenanceScheduled, bool dbDegraded, bool apiOk)
{
_maintenance = maintenanceScheduled
? new Components.Alert(
title: "Scheduled maintenance",
description: "The service will be unavailable on Saturday 00:00–02:00 UTC.",
variant: "default")
: HtmxEmpty.Instance;
_database = dbDegraded
? new Components.Alert(
title: "Database degraded",
description: "Query latency is elevated. Our team is investigating.",
variant: "destructive")
: HtmxEmpty.Instance;
_api = apiOk
? new Components.Alert(title: "All systems operational.")
: HtmxEmpty.Instance;
}
protected override void RenderMaintenanceAlert(HtmxRenderContext ctx)
=> _maintenance.Render(ctx.Next());
protected override void RenderDatabaseAlert(HtmxRenderContext ctx)
=> _database.Render(ctx.Next());
protected override void RenderApiAlert(HtmxRenderContext ctx)
=> _api.Render(ctx.Next());
}
GET handler
[Handler]
[MapGet("/status")]
public static partial class GetSystemStatusHandler
{
public record Query();
private static Task<IResult> HandleAsync(
Query _,
HttpContext ctx,
CancellationToken ct)
{
var page = new SystemStatusPage(
maintenanceScheduled: true,
dbDegraded: false,
apiOk: true);
return ctx.WriteHtmxPage(page, title: "System Status");
}
}