Files
Htmx/Htmx.ApiDemo/Templates/UiDemo.htmx.cs
T
2026-05-04 18:58:48 +05:00

389 lines
22 KiB
C#

using Htmx.ApiDemo.Templates.Components;
using Immediate.Apis.Shared;
using Immediate.Handlers.Shared;
namespace Htmx.ApiDemo.Templates;
public sealed class UiDemo : UiDemoBase
{
// ── Buttons ──────────────────────────────────────────────────────────
public IHtmxComponent BtnDefault { get; }
public IHtmxComponent BtnDestructive { get; }
public IHtmxComponent BtnOutline { get; }
public IHtmxComponent BtnSecondary { get; }
public IHtmxComponent BtnGhost { get; }
public IHtmxComponent BtnLink { get; }
public IHtmxComponent BtnSm { get; }
public IHtmxComponent BtnLg { get; }
// ── Inputs ───────────────────────────────────────────────────────────
public IHtmxComponent InputText { get; }
public IHtmxComponent InputEmail { get; }
public IHtmxComponent InputPassword { get; }
public IHtmxComponent InputSearch { get; }
// ── Select / Calendar / TimePicker ───────────────────────────────────
public IHtmxComponent SelectDemo { get; }
public IHtmxComponent CalendarDemo { get; }
public IHtmxComponent CalendarRangeDemo { get; }
public IHtmxComponent TimePickerDemo { get; }
public IHtmxComponent TimePicker12hDemo { get; }
// ── Badge ─────────────────────────────────────────────────────────────
public IHtmxComponent BadgeDefault { get; }
public IHtmxComponent BadgeSecondary { get; }
public IHtmxComponent BadgeDestructive { get; }
public IHtmxComponent BadgeOutline { get; }
// ── Card ──────────────────────────────────────────────────────────────
public IHtmxComponent CardDemo { get; }
// ── Separator ─────────────────────────────────────────────────────────
public IHtmxComponent SeparatorH { get; }
public IHtmxComponent SeparatorV { get; }
// ── Skeleton ──────────────────────────────────────────────────────────
public IHtmxComponent SkeletonTitle { get; }
public IHtmxComponent SkeletonLine1 { get; }
public IHtmxComponent SkeletonLine2 { get; }
public IHtmxComponent SkeletonAvatar { get; }
// ── Avatar ────────────────────────────────────────────────────────────
public IHtmxComponent AvatarSm { get; }
public IHtmxComponent AvatarDefault { get; }
public IHtmxComponent AvatarLg { get; }
public IHtmxComponent AvatarImg { get; }
// ── Progress ──────────────────────────────────────────────────────────
public IHtmxComponent Progress25 { get; }
public IHtmxComponent Progress60 { get; }
public IHtmxComponent Progress100 { get; }
// ── Alert ─────────────────────────────────────────────────────────────
public IHtmxComponent AlertDefault { get; }
public IHtmxComponent AlertDestructive { get; }
// ── Breadcrumb ────────────────────────────────────────────────────────
public IHtmxComponent BreadcrumbDemo { get; }
// ── Checkbox ──────────────────────────────────────────────────────────
public IHtmxComponent CheckboxAccept { get; }
public IHtmxComponent CheckboxChecked { get; }
// ── RadioGroup ────────────────────────────────────────────────────────
public IHtmxComponent RadioGroupCol { get; }
public IHtmxComponent RadioGroupRow { get; }
// ── Switch ────────────────────────────────────────────────────────────
public IHtmxComponent SwitchOff { get; }
public IHtmxComponent SwitchOn { get; }
// ── Textarea ──────────────────────────────────────────────────────────
public IHtmxComponent TextareaDemo { get; }
// ── Slider ────────────────────────────────────────────────────────────
public IHtmxComponent SliderDemo { get; }
// ── FileInput ─────────────────────────────────────────────────────────
public IHtmxComponent FileInputDemo { get; }
// ── Table ─────────────────────────────────────────────────────────────
public IHtmxComponent TableDemo { get; }
// ── Pagination ────────────────────────────────────────────────────────
public IHtmxComponent PaginationDemo { get; }
// ── Tabs ──────────────────────────────────────────────────────────────
public IHtmxComponent TabsDemo { get; }
// ── Accordion ─────────────────────────────────────────────────────────
public IHtmxComponent AccordionDemo { get; }
// ── Tooltip ───────────────────────────────────────────────────────────
public IHtmxComponent TooltipTop { get; }
public IHtmxComponent TooltipBottom { get; }
public IHtmxComponent TooltipRight { get; }
// ── Dialog ────────────────────────────────────────────────────────────
public IHtmxComponent DialogDemo { get; }
// ── Dropdown ──────────────────────────────────────────────────────────
public IHtmxComponent DropdownDemo { get; }
// ── Toast Viewport ────────────────────────────────────────────────────
public IHtmxComponent ToastViewportDemo { get; }
public UiDemo()
{
// Buttons
BtnDefault = new Button("Default");
BtnDestructive = new Button("Destructive", variant: "destructive");
BtnOutline = new Button("Outline", variant: "outline");
BtnSecondary = new Button("Secondary", variant: "secondary");
BtnGhost = new Button("Ghost", variant: "ghost");
BtnLink = new Button("Link", variant: "link");
BtnSm = new Button("Small", size: "sm");
BtnLg = new Button("Large", size: "lg");
// Inputs
InputText = new Input("username", label: "Username", placeholder: "Enter username");
InputEmail = new Input("email", inputType: "email", label: "Email", placeholder: "you@example.com");
InputPassword = new Input("password", inputType: "password", label: "Password", placeholder: "••••••••");
InputSearch = new Input("search", inputType: "search", label: "Search", placeholder: "Search…",
hxAttrs: "hx-get=\"/search\" hx-trigger=\"keyup changed delay:300ms\" hx-target=\"#search-results\"");
// Select / Calendar / TimePicker
SelectDemo = new Select(
id: "framework",
label: "Framework",
options: [("htmx", "HTMX"), ("react", "React"), ("vue", "Vue"), ("svelte", "Svelte")],
selectedValue: "htmx",
description: "Choose your preferred framework");
CalendarDemo = new Calendar(id: "demo-cal", name: "demo-date");
CalendarRangeDemo = new CalendarRange(id: "demo-calr", name: "demo-range");
TimePickerDemo = new TimePicker(name: "time-24h", label: "Time (24h)");
TimePicker12hDemo = new TimePicker(name: "time-12h", label: "Time (12h)", use12h: true);
// Badge
BadgeDefault = new Badge("Default");
BadgeSecondary = new Badge("Secondary", variant: "secondary");
BadgeDestructive = new Badge("Destructive", variant: "destructive");
BadgeOutline = new Badge("Outline", variant: "outline");
// Card
CardDemo = new Card(
title: "Component Card",
description: "A reusable card surface with header and footer.",
content: "<p class=\"text-sm text-muted-foreground\">Cards group related content and provide a contained, elevated surface for information.</p>",
footer: "<button type=\"button\" class=\"inline-flex items-center justify-center rounded-md bg-primary text-primary-foreground h-9 px-4 text-sm font-medium hover:bg-primary/90 transition-colors\">Action</button>");
// Separator
SeparatorH = new Separator();
SeparatorV = new Separator(orientation: "vertical");
// Skeleton
SkeletonTitle = new Skeleton("h-5 w-48");
SkeletonLine1 = new Skeleton("h-4 w-full");
SkeletonLine2 = new Skeleton("h-4 w-3/4");
SkeletonAvatar = new Skeleton("h-10 w-10 rounded-full");
// Avatar
AvatarSm = new Avatar("SM", size: "sm");
AvatarDefault = new Avatar("JD");
AvatarLg = new Avatar("AB", size: "lg");
AvatarImg = new Avatar("GitHub", src: "https://github.com/github.png", size: "default");
// Progress
Progress25 = new Progress(25);
Progress60 = new Progress(60);
Progress100 = new Progress(100);
// Alert
AlertDefault = new Alert("Information", description: "This is an informational alert with a default style.");
AlertDestructive = new Alert("Error", description: "Something went wrong. Please check your input.", variant: "destructive");
// Breadcrumb
BreadcrumbDemo = new Breadcrumb([
("Home", "/"),
("Components", "/components"),
("UI Demo", ""),
]);
// Checkbox
CheckboxAccept = new Checkbox("accept-terms", label: "Accept terms and conditions");
CheckboxChecked = new Checkbox("newsletter", label: "Subscribe to newsletter", @checked: true);
// RadioGroup
RadioGroupCol = new RadioGroup(
name: "plan-v",
label: "Plan (vertical)",
options: [
("starter", "Starter", true),
("pro", "Pro", false),
("enterprise", "Enterprise", false),
]);
RadioGroupRow = new RadioGroup(
name: "size-h",
label: "Size (horizontal)",
direction: "flex-row",
options: [
("sm", "SM", true),
("md", "MD", false),
("lg", "LG", false),
]);
// Switch
SwitchOff = new Switch("notif-off", label: "Notifications");
SwitchOn = new Switch("darkmode", label: "Dark mode", isChecked: true);
// Textarea
TextareaDemo = new Textarea(
id: "bio",
label: "Bio",
placeholder: "Tell us about yourself…",
description: "Max 200 characters.");
// Slider
SliderDemo = new Slider(id: "volume", label: "Volume", value: 40, description: "Drag to adjust");
// FileInput
FileInputDemo = new FileInput(
id: "avatar-upload",
label: "Profile picture",
accept: "image/*",
description: "PNG, JPG or GIF up to 2 MB.");
// Table
TableDemo = new Table(
headers: ["Name", "Role", "Status"],
rows: [
["Alice", "Admin", "Active"],
["Bob", "Editor", "Active"],
["Charlie", "Viewer", "Inactive"],
],
caption: "Team members");
// Pagination
PaginationDemo = new Pagination(current: 3, total: 7, urlPattern: "/ui-demo?page={0}");
// Tabs
TabsDemo = new Tabs("demo", [
("overview", "Overview", "<p class=\"text-sm text-muted-foreground\">This is the overview tab content.</p>"),
("settings", "Settings", "<p class=\"text-sm text-muted-foreground\">Manage your settings here.</p>"),
("billing", "Billing", "<p class=\"text-sm text-muted-foreground\">View billing information.</p>"),
]);
// Accordion
AccordionDemo = new Accordion("demo-acc", [
("What is htmx?", "htmx allows you to access AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML."),
("Is it production ready?", "Yes — htmx is used by thousands of projects in production worldwide."),
("Does it replace React?", "htmx is a different tool suited to server-driven UIs. Use whatever fits your team best."),
], openIndex: 0);
// Tooltip
TooltipTop = new Tooltip("Top tooltip", new Button("Hover me"), position: "top");
TooltipBottom = new Tooltip("Bottom tooltip", new Button("Bottom", variant: "secondary"), position: "bottom");
TooltipRight = new Tooltip("Right tooltip", new Button("Right", variant: "outline"), position: "right");
// Dialog
DialogDemo = new Dialog(
id: "demo-dialog",
title: "Are you sure?",
description: "This action cannot be undone.",
content: "Please confirm that you want to proceed with this operation.",
footer: "<button type=\"button\" data-dialog-close class=\"inline-flex items-center justify-center rounded-md border border-input bg-background h-9 px-4 text-sm font-medium hover:bg-accent transition-colors\">Cancel</button>" +
"<button type=\"button\" data-dialog-close class=\"inline-flex items-center justify-center rounded-md bg-primary text-primary-foreground h-9 px-4 text-sm font-medium hover:bg-primary/90 transition-colors\">Confirm</button>");
// Dropdown
DropdownDemo = new DropdownMenu(
trigger: new Button("Options ▾", variant: "outline"),
items: [
("Edit", "/edit", false),
("Duplicate", "/dup", false),
("", "", true), // separator
("Delete", "/delete", false),
]);
// Toast Viewport
ToastViewportDemo = new ToastViewport();
}
protected override void RenderBtnDefault(HtmxRenderContext ctx) => BtnDefault.Render(ctx);
protected override void RenderBtnDestructive(HtmxRenderContext ctx) => BtnDestructive.Render(ctx);
protected override void RenderBtnOutline(HtmxRenderContext ctx) => BtnOutline.Render(ctx);
protected override void RenderBtnSecondary(HtmxRenderContext ctx) => BtnSecondary.Render(ctx);
protected override void RenderBtnGhost(HtmxRenderContext ctx) => BtnGhost.Render(ctx);
protected override void RenderBtnLink(HtmxRenderContext ctx) => BtnLink.Render(ctx);
protected override void RenderBtnSm(HtmxRenderContext ctx) => BtnSm.Render(ctx);
protected override void RenderBtnLg(HtmxRenderContext ctx) => BtnLg.Render(ctx);
protected override void RenderInputText(HtmxRenderContext ctx) => InputText.Render(ctx);
protected override void RenderInputEmail(HtmxRenderContext ctx) => InputEmail.Render(ctx);
protected override void RenderInputPassword(HtmxRenderContext ctx) => InputPassword.Render(ctx);
protected override void RenderInputSearch(HtmxRenderContext ctx) => InputSearch.Render(ctx);
protected override void RenderSelectDemo(HtmxRenderContext ctx) => SelectDemo.Render(ctx);
protected override void RenderCalendarDemo(HtmxRenderContext ctx) => CalendarDemo.Render(ctx);
protected override void RenderCalendarRangeDemo(HtmxRenderContext ctx) => CalendarRangeDemo.Render(ctx);
protected override void RenderTimePickerDemo(HtmxRenderContext ctx) => TimePickerDemo.Render(ctx);
protected override void RenderTimePicker12hDemo(HtmxRenderContext ctx) => TimePicker12hDemo.Render(ctx);
protected override void RenderBadgeDefault(HtmxRenderContext ctx) => BadgeDefault.Render(ctx);
protected override void RenderBadgeSecondary(HtmxRenderContext ctx) => BadgeSecondary.Render(ctx);
protected override void RenderBadgeDestructive(HtmxRenderContext ctx) => BadgeDestructive.Render(ctx);
protected override void RenderBadgeOutline(HtmxRenderContext ctx) => BadgeOutline.Render(ctx);
protected override void RenderCardDemo(HtmxRenderContext ctx) => CardDemo.Render(ctx);
protected override void RenderSeparatorH(HtmxRenderContext ctx) => SeparatorH.Render(ctx);
protected override void RenderSeparatorV(HtmxRenderContext ctx) => SeparatorV.Render(ctx);
protected override void RenderSkeletonTitle(HtmxRenderContext ctx) => SkeletonTitle.Render(ctx);
protected override void RenderSkeletonLine1(HtmxRenderContext ctx) => SkeletonLine1.Render(ctx);
protected override void RenderSkeletonLine2(HtmxRenderContext ctx) => SkeletonLine2.Render(ctx);
protected override void RenderSkeletonAvatar(HtmxRenderContext ctx) => SkeletonAvatar.Render(ctx);
protected override void RenderAvatarSm(HtmxRenderContext ctx) => AvatarSm.Render(ctx);
protected override void RenderAvatarDefault(HtmxRenderContext ctx) => AvatarDefault.Render(ctx);
protected override void RenderAvatarLg(HtmxRenderContext ctx) => AvatarLg.Render(ctx);
protected override void RenderAvatarImg(HtmxRenderContext ctx) => AvatarImg.Render(ctx);
protected override void RenderProgress25(HtmxRenderContext ctx) => Progress25.Render(ctx);
protected override void RenderProgress60(HtmxRenderContext ctx) => Progress60.Render(ctx);
protected override void RenderProgress100(HtmxRenderContext ctx) => Progress100.Render(ctx);
protected override void RenderAlertDefault(HtmxRenderContext ctx) => AlertDefault.Render(ctx);
protected override void RenderAlertDestructive(HtmxRenderContext ctx) => AlertDestructive.Render(ctx);
protected override void RenderBreadcrumbDemo(HtmxRenderContext ctx) => BreadcrumbDemo.Render(ctx);
protected override void RenderCheckboxAccept(HtmxRenderContext ctx) => CheckboxAccept.Render(ctx);
protected override void RenderCheckboxChecked(HtmxRenderContext ctx) => CheckboxChecked.Render(ctx);
protected override void RenderRadioGroupCol(HtmxRenderContext ctx) => RadioGroupCol.Render(ctx);
protected override void RenderRadioGroupRow(HtmxRenderContext ctx) => RadioGroupRow.Render(ctx);
protected override void RenderSwitchOff(HtmxRenderContext ctx) => SwitchOff.Render(ctx);
protected override void RenderSwitchOn(HtmxRenderContext ctx) => SwitchOn.Render(ctx);
protected override void RenderTextareaDemo(HtmxRenderContext ctx) => TextareaDemo.Render(ctx);
protected override void RenderSliderDemo(HtmxRenderContext ctx) => SliderDemo.Render(ctx);
protected override void RenderFileInputDemo(HtmxRenderContext ctx)=> FileInputDemo.Render(ctx);
protected override void RenderTableDemo(HtmxRenderContext ctx) => TableDemo.Render(ctx);
protected override void RenderPaginationDemo(HtmxRenderContext ctx)=> PaginationDemo.Render(ctx);
protected override void RenderTabsDemo(HtmxRenderContext ctx) => TabsDemo.Render(ctx);
protected override void RenderAccordionDemo(HtmxRenderContext ctx)=> AccordionDemo.Render(ctx);
protected override void RenderTooltipTop(HtmxRenderContext ctx) => TooltipTop.Render(ctx);
protected override void RenderTooltipBottom(HtmxRenderContext ctx) => TooltipBottom.Render(ctx);
protected override void RenderTooltipRight(HtmxRenderContext ctx) => TooltipRight.Render(ctx);
protected override void RenderDialogDemo(HtmxRenderContext ctx) => DialogDemo.Render(ctx);
protected override void RenderDropdownDemo(HtmxRenderContext ctx) => DropdownDemo.Render(ctx);
protected override void RenderToastViewportDemo(HtmxRenderContext ctx) => ToastViewportDemo.Render(ctx);
}
[Handler]
[MapGet("/ui-demo")]
public static partial class GetUiDemoHandler
{
public record Query;
private static ValueTask HandleAsync(
Query query,
IHttpContextAccessor httpContextAccessor,
CancellationToken token)
{
var context = httpContextAccessor.HttpContext
?? throw new InvalidOperationException("HttpContext is not available.");
var page = new UiDemo();
context.WriteHtmxPage(page, title: "UI Demo", appName: "HtmxApp", pageTitle: "UI Components");
return ValueTask.CompletedTask;
}
}