ComponentsRevealButton
RevealButton
Show an icon that reveals its label on hover or keyboard focus.
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.
import { RevealButton } from "@dethink/components";
export function Example() {
return <RevealButton icon={<SearchIcon />} label="Search" />;
}Try the examples, then open the code to use them in your app.
Variants
Use the same action hierarchy as Button and IconButton while keeping labels available on demand.
Show sourceexamples/reveal-button/basic.tsx
"use client";
import { RevealButton } from "@dethink/components";
import { Bell, Bookmark, Search, Settings, Trash2 } from "lucide-react";
export function RevealButtonBasic() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<RevealButton icon={<Search />} label="Search" />
<RevealButton icon={<Bell />} label="Notifications" variant="soft" />
<RevealButton icon={<Settings />} label="Settings" variant="outline" />
<RevealButton icon={<Bookmark />} label="Bookmark" variant="ghost" />
<RevealButton icon={<Trash2 />} label="Delete" variant="destructive" />
</div>
);
}Sizes
Collapsed dimensions match IconButton sizes; the revealed label expands inline from the icon box.
Show sourceexamples/reveal-button/sizes.tsx
"use client";
import { RevealButton, type RevealButtonSize } from "@dethink/components";
import { Search } from "lucide-react";
const sizes: RevealButtonSize[] = ["xs", "sm", "md", "lg", "xl"];
export function RevealButtonSizes() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
{sizes.map((size) => (
<RevealButton
key={size}
icon={<Search />}
label={`${size.toUpperCase()} search`}
size={size}
variant="outline"
/>
))}
</div>
);
}States
Loading, disabled, always-visible labels, focus styling, and reduced-motion mode.
Show sourceexamples/reveal-button/states.tsx
"use client";
import { RevealButton } from "@dethink/components";
import { RefreshCw, Save, Search, Settings } from "lucide-react";
export function RevealButtonStates() {
return (
<div className="flex flex-wrap items-center justify-center gap-2">
<RevealButton icon={<Search />} label="Hover or focus" />
<RevealButton
className="ring-ring ring-offset-background ring-2 ring-offset-2"
icon={<Settings />}
label="Focused"
variant="outline"
/>
<RevealButton
icon={<Save />}
label="Always visible"
labelVisibility="always"
variant="soft"
/>
<RevealButton
disabled
icon={<RefreshCw />}
label="Disabled"
variant="outline"
/>
<RevealButton
icon={<RefreshCw />}
label="Loading"
loading
variant="outline"
/>
<RevealButton icon={<RefreshCw />} label="No motion" motion="none" />
</div>
);
}Examples that combine components for common tasks.
Production navbar
A branded workspace header with persistent navigation and RevealButton actions that stay compact until intent is clear.
Document toolbar
A compact toolbar where actions stay scannable without permanently taking text-button space.
Customer insight report
Draft updated just now
Show sourceexamples/reveal-button/recipe-toolbar.tsx
"use client";
import { RevealButton } from "@dethink/components";
import { Archive, Copy, Download, Pencil, Share2 } from "lucide-react";
export function RevealButtonRecipeToolbar() {
return (
<div className="border-border bg-muted/30 mx-auto flex w-full max-w-2xl items-center justify-between gap-4 rounded-md border p-3">
<div className="min-w-0">
<p className="text-foreground truncate text-sm font-medium">
Customer insight report
</p>
<p className="text-muted-foreground text-sm">Draft updated just now</p>
</div>
<div
aria-label="Report actions"
className="flex shrink-0 items-center gap-1"
role="toolbar"
>
<RevealButton icon={<Pencil />} label="Edit" variant="ghost" />
<RevealButton icon={<Copy />} label="Duplicate" variant="ghost" />
<RevealButton icon={<Share2 />} label="Share" variant="ghost" />
<RevealButton icon={<Download />} label="Export" variant="outline" />
<RevealButton
icon={<Archive />}
label="Archive"
variant="destructive"
/>
</div>
</div>
);
}RevealButton renders a real button element and owns its accessible name through label.
| Prop | What it does | Default |
|---|---|---|
iconReactNode | Decorative icon shown in the collapsed control and replaced by the spinner while loading. | Not set |
labelstring | Required text used for both the button's accessible name and the revealed visual label. | Not set |
variant"solid" | "soft" | "outline" | "ghost" | "destructive" | Visual treatment matching Button and IconButton variants. | "ghost" |
size"xs" | "sm" | "md" | "lg" | "xl" | Collapsed square control size; the revealed label adds logical inline space. | "md" |
labelVisibility"hover" | "always" | Reveals on hover and focus by default, or keeps the label visible for high-clarity contexts. | "hover" |
motion"none" | "subtle" | "standard" | Controls reveal and press motion. none removes transform-heavy motion. | "standard" |
loadingboolean | Spinner replaces the icon, aria-busy is set, and activation is blocked. | false |
โฆnative button propsButtonHTMLAttributes | Renders a real button: onClick, disabled, aria-pressed, type, form, and related props. | Not set |