ActionsIcon button
Icon button
A square, icon-only button. Used for compact toolbars, table actions, and the close button on overlays.
Demo
The default is a 36 × 36 px ghost button. The label is announced by assistive tech; the icon is decorative.
Default
Sizes
Sizes
Variants
Variants
Implementation
icon-button.tsx
import { forwardRef, type ButtonHTMLAttributes } from "react"
import SiteIcon, type SiteIconProps } from "@/components/site-icon"
interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
icon: SiteIconProps["icon"]
label: string
size?: "sm" | "md" | "lg"
variant?: "primary" | "secondary" | "ghost"
}
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
function IconButton({ icon, label, size = "md", variant = "ghost", className, ...props }, ref) {
return (
<button
ref={ref}
aria-label={label}
className={cn("ds-icon-btn", `ds-icon-btn--${size}`, `ds-icon-btn--${variant}`, className)}
{...props}
>
<SiteIcon icon={icon} size={size === "lg" ? "md" : "sm"} aria-hidden />
</button>
)
},
)Props
| Prop | Type | Default | Description |
|---|---|---|---|
icon | LucideIcon | None | The icon |
label | string | None | Required: the accessible label |
size | "sm" | "md" | "lg" | "md" | Touch target |
variant | "primary" | "secondary" | "ghost" | "ghost" | Visual style |
Accessibility
- The
aria-labelprop is required. There is no fallback label. - The icon is marked
aria-hidden; the label is the only thing announced. - Touch target is at least 32 × 32 px. The default is 36 × 36 px.
- Focus ring is the system default.