ComponentsIconButton
IconButton
Show an action as an icon when space is limited.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
Usage
import { IconButton } from "@dethink/components";Try the examples, then open the code to use them in your app.
Variants and shapes
The Button variants minus link, plus a circle shape.
Show sourceexamples/icon-button/basic.tsx
examples/icon-button/basic.tsx
"use client";
import { IconButton } from "@dethink/components";
import { Bell, Bookmark, Search, Settings, Trash2 } from "lucide-react";
export function IconButtonBasic() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<IconButton aria-label="Search">
<Search />
</IconButton>
<IconButton aria-label="Notifications" variant="soft">
<Bell />
</IconButton>
<IconButton aria-label="Settings" variant="outline">
<Settings />
</IconButton>
<IconButton aria-label="Bookmark" variant="ghost">
<Bookmark />
</IconButton>
<IconButton aria-label="Delete" variant="destructive">
<Trash2 />
</IconButton>
<IconButton
aria-label="Search everywhere"
shape="circle"
variant="outline"
>
<Search />
</IconButton>
</div>
);
}Sizes, loading, and disabled
Five sizes with auto-scaled icons; loading swaps the icon for a spinner and makes the button inert.
Show sourceexamples/icon-button/states.tsx
examples/icon-button/states.tsx
"use client";
import { IconButton } from "@dethink/components";
import { RefreshCw, Upload } from "lucide-react";
const sizes = ["xs", "sm", "md", "lg", "xl"] as const;
export function IconButtonStates() {
return (
<div className="space-y-4">
<div className="flex items-center justify-center gap-2">
{sizes.map((size) => (
<IconButton
key={size}
aria-label={`Upload (${size})`}
size={size}
variant="soft"
>
<Upload />
</IconButton>
))}
</div>
<div className="flex items-center justify-center gap-2">
<IconButton aria-label="Refreshing" loading variant="outline">
<RefreshCw />
</IconButton>
<IconButton aria-label="Refresh" disabled variant="outline">
<RefreshCw />
</IconButton>
</div>
</div>
);
}Examples that combine components for common tasks.
Player bar
Toggle buttons done right: the Play button's accessible name flips with its state, likes and repeat carry aria-pressed, and a live region narrates the state for screen readers.
Paused
Show sourceexamples/icon-button/recipe-player.tsx
examples/icon-button/recipe-player.tsx
"use client";
import { useState } from "react";
import { IconButton } from "@dethink/components";
import {
Heart,
Pause,
Play,
Repeat,
SkipBack,
SkipForward,
} from "lucide-react";
/**
* A player bar built entirely from icon buttons: the accessible name flips
* with the toggle state (Play/Pause), aria-pressed carries the toggles, and
* a live region narrates state for screen-reader users.
*/
export function IconButtonRecipePlayer() {
const [playing, setPlaying] = useState(false);
const [liked, setLiked] = useState(false);
const [repeat, setRepeat] = useState(false);
return (
<div className="mx-auto max-w-xs space-y-3">
<div className="border-border bg-muted/40 flex items-center justify-center gap-1 rounded-full border px-3 py-2">
<IconButton aria-label="Previous track" variant="ghost" shape="circle">
<SkipBack />
</IconButton>
<IconButton
aria-label={playing ? "Pause" : "Play"}
shape="circle"
size="lg"
onClick={() => setPlaying(!playing)}
>
{playing ? <Pause /> : <Play />}
</IconButton>
<IconButton aria-label="Next track" variant="ghost" shape="circle">
<SkipForward />
</IconButton>
<IconButton
aria-label="Like"
aria-pressed={liked}
variant={liked ? "soft" : "ghost"}
shape="circle"
onClick={() => setLiked(!liked)}
>
<Heart />
</IconButton>
<IconButton
aria-label="Repeat"
aria-pressed={repeat}
variant={repeat ? "soft" : "ghost"}
shape="circle"
onClick={() => setRepeat(!repeat)}
>
<Repeat />
</IconButton>
</div>
<p
aria-live="polite"
className="text-muted-foreground text-center text-sm"
>
{playing ? "Playing" : "Paused"}
{liked ? " · liked" : ""}
{repeat ? " · repeat on" : ""}
</p>
</div>
);
}IconButton renders a real button element.
| Prop | What it does | Default |
|---|---|---|
aria-label / aria-labelledbystring (one required) | The accessible name is required by the type system — an icon-only button without one will not compile. | Not set |
variant"solid" | "soft" | "outline" | "ghost" | "destructive" | Visual treatment matching the Button variants. | "solid" |
size"xs" | "sm" | "md" | "lg" | "xl" | Square control size; the icon scales with it. | "md" |
shape"square" | "circle" | Corner treatment. | "square" |
loadingboolean | Spinner replaces the icon; the button becomes inert. | false |
…native button propsButtonHTMLAttributes | Renders a real button: onClick, disabled, aria-pressed, type. | Not set |