Components
Icon Button
Circular button with glassmorphic styling for icon-based actions
Icon Button
A circular button component designed for icon-based actions. Features glassmorphic styling with backdrop blur, inset shadows, and gradient-masked borders. Includes specialized variants for common actions like plus, close, and arrow buttons.
Usage
import { IconButton, PlusButton, CloseButton, ArrowButton } from "@/components/ui/icon-button";
export default function Example() {
return (
<div className="flex gap-4">
<IconButton>
<SettingsIcon className="w-4 h-4" />
</IconButton>
<PlusButton />
<CloseButton />
<ArrowButton direction="right" />
</div>
);
}
Components
IconButton
The base icon button component with glassmorphic styling.
PlusButton
Pre-configured button with a plus icon for "add" actions.
CloseButton
Pre-configured button with an X icon for "close" or "dismiss" actions.
ArrowButton
Pre-configured button with an arrow icon supporting four directions.
Props
IconButton Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "ghost" | "outline" | "solid" | "default" | Visual style variant |
size | "sm" | "default" | "lg" | "default" | Button size |
asChild | boolean | false | Render as child element (Radix Slot) |
ArrowButton Props
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "up" | "down" | "left" | "right" | "right" | Arrow direction |
| ...IconButtonProps | - | - | All IconButton props |
Variants
Style Variants
// Default - glassmorphic with blur and gradient border
<IconButton variant="default">
<Icon />
</IconButton>
// Ghost - transparent, hover reveals background
<IconButton variant="ghost">
<Icon />
</IconButton>
// Outline - transparent with border
<IconButton variant="outline">
<Icon />
</IconButton>
// Solid - 10% opacity background
<IconButton variant="solid">
<Icon />
</IconButton>
Size Variants
// Small - 40px
<IconButton size="sm">
<Icon className="w-3 h-3" />
</IconButton>
// Default - 60px
<IconButton size="default">
<Icon className="w-4 h-4" />
</IconButton>
// Large - 80px
<IconButton size="lg">
<Icon className="w-5 h-5" />
</IconButton>
Examples
Add Button
<PlusButton onClick={() => handleAdd()} />
Close Modal
<CloseButton
onClick={() => setOpen(false)}
aria-label="Close modal"
/>
Navigation Arrows
<div className="flex gap-2">
<ArrowButton direction="left" onClick={handlePrev} />
<ArrowButton direction="right" onClick={handleNext} />
</div>
Custom Icon
<IconButton variant="default" size="default">
<HeartIcon className="w-4 h-4 text-[var(--ui-text-primary)]" />
</IconButton>
As Link
import Link from "next/link";
<IconButton asChild>
<Link href="/settings">
<SettingsIcon className="w-4 h-4" />
</Link>
</IconButton>
Action Group
<div className="flex gap-2">
<IconButton variant="ghost" size="sm">
<EditIcon className="w-3 h-3" />
</IconButton>
<IconButton variant="ghost" size="sm">
<CopyIcon className="w-3 h-3" />
</IconButton>
<IconButton variant="ghost" size="sm">
<TrashIcon className="w-3 h-3" />
</IconButton>
</div>
Design Tokens
Dimensions
| Size | Dimensions | Border Radius |
|---|---|---|
sm | 40px × 40px | var(--radius-sm) (12px) |
default | 60px × 60px | var(--radius-lg) (16px) |
lg | 80px × 80px | var(--radius-xl) (32px) |
Effects (Default Variant)
| Token | Value | Description |
|---|---|---|
| Outer border | var(--ui-stroke-selected) | 40% opacity border |
| Shadow | var(--shadow-1) | Composite inset + drop |
| Background | var(--gradient-overlay-170) | Glassmorphic gradient |
| Blur | var(--blur-sm) (6px) | Backdrop blur |
| Inner border | var(--ui-stroke-subtle) | 10% opacity, masked |
Icon Sizing
| Button Size | Recommended Icon Size |
|---|---|
sm | 12px - 14px |
default | 16px - 20px |
lg | 20px - 24px |
Glassmorphic Structure
The default variant uses a layered structure:
- Outer container - Border and shadow
- ::before pseudo - Glassmorphic background with blur
- ::after pseudo - Gradient-masked inner border
- Content - Icon with z-index above layers
┌─────────────────────┐ ← Outer border (1.5px)
│ ┌───────────────┐ │ ← 3px inset
│ │ ::before │ │ ← Blur + gradient bg
│ │ ┌─────────┐ │ │
│ │ │ Icon │ │ │ ← Content (z-10)
│ │ └─────────┘ │ │
│ │ ::after │ │ ← Masked border
│ └───────────────┘ │
└─────────────────────┘
Found In
- Bento10 - Plus button in avatar group
- Bento11 - Action buttons
- Bento20 - Arrow navigation
- Bento28 - Control buttons
Accessibility
- Full keyboard navigation support
- Focus ring with
focus-visiblestyling - Disabled state with reduced opacity
aria-labelsupport for icon-only buttonsasChildprop for semantic link rendering- Built-in icons include
aria-hidden="true"
Best Practices
// Always provide accessible labels for icon-only buttons
<IconButton aria-label="Settings">
<SettingsIcon />
</IconButton>
// Or use sr-only text
<IconButton>
<SettingsIcon aria-hidden="true" />
<span className="sr-only">Settings</span>
</IconButton>