Button
shadcn-htmx/buttonFreeComponent
A native <button> element with shadcn variants, sized for htmx v4. Ships in five flavours: Hono JSX (TypeScript), Jinja2 macro, Go html/template, Phoenix function component, and a raw HTML snippet. Follows the WAI-ARIA APG button pattern.
Live preview
live · rendered by the registry
Rendered by shadcn-htmx on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://shadcn-htmx.productdevbook.com/r/button.jsonSource
1/** @jsxImportSource hono/jsx */2import type { PropsWithChildren } from "hono/jsx"3import { cloneElement, isValidElement } from "hono/jsx"4import { cn, type ClassValue } from "@/registry/lib/cn"56// Variants mirror shadcn/ui's Button (new-york-v4), translated to htmx-friendly7// server-rendered JSX. Source of truth:8// repos/shadcn-ui/apps/v4/registry/new-york-v4/ui/button.tsx9//10// Accessibility contract follows the WAI-ARIA APG button pattern:11// repos/aria-practices/content/patterns/button/button-pattern.html12// Because we render a real <button>, role and Space/Enter activation come for13// free from the platform — we only add aria-* where the pattern demands it.14//15// Polymorphic rendering: shadcn uses Radix Slot.Root for `asChild`. Hono JSX16// has cloneElement, so we implement the same idea — pass a single JSX child17// (e.g. <a href="...">), and the button classes are merged onto it.1819export type ButtonVariant =20 | "default"21 | "destructive"22 | "outline"23 | "secondary"24 | "ghost"25 | "link"2627export type ButtonSize =28 | "default"29 | "xs"30 | "sm"31 | "lg"32 | "icon"33 | "icon-xs"34 | "icon-sm"35 | "icon-lg"3637const base =38 "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none " +39 "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 " +40 "disabled:pointer-events-none disabled:opacity-50 " +41 // aria-disabled mirrors the disabled affordance for cases where the element42 // must stay focusable (so screen readers can land on it and announce why43 // it's unavailable). See repos/mdn/files/en-us/web/accessibility/aria/attributes/aria-disabled/.44 "aria-disabled:pointer-events-none aria-disabled:opacity-50 " +45 "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 " +46 "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 " +47 // htmx v4: while a request triggered by/targeting this button is in flight,48 // htmx adds the .htmx-request class. We mirror disabled affordance.49 "[&.htmx-request]:pointer-events-none [&.htmx-request]:opacity-70"5051const variants: Record<ButtonVariant, string> = {52 default: "bg-primary text-primary-foreground hover:bg-primary/90",53 destructive:54 "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",55 outline:56// … truncated
More from shadcn-htmx
All 83 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | shadcn-htmx | Components | Free | no deps | |
| Active Searchactive-search | shadcn-htmx | Components | Free | no deps | |
| Alertalert | shadcn-htmx | Components | Free | no deps | |
| Alert Dialogalert-dialog | shadcn-htmx | Components | Free | no deps | |
| Aspect Ratioaspect-ratio | shadcn-htmx | Components | Free | no deps | |
| Auto Gridauto-grid | shadcn-htmx | Components | Free | no deps | |
| Autocompleteautocomplete | shadcn-htmx | Components | Free | no deps | |
| Autosize Textareaautosize-textarea | shadcn-htmx | Components | Free | no deps |
