Skip to main content

Button

Drive user action. High-converting variants. Clear states.

Workspace name

Acme Studio

1import { Button } from '@/components/ui/button';
2import { Flex } from '@/components/ui/flex';
3
4export function Default() {
5 return (
6 <Flex
7 align="center"
8 justify="between"
9 gap="4"
10 className="border-border bg-card w-full max-w-sm rounded-xl border p-4"
11 >
12 <div className="min-w-0">
13 <p className="text-sm font-medium">Workspace name</p>
14 <p className="text-muted-foreground truncate text-xs">Acme Studio</p>
15 </div>
16 <Button>Save changes</Button>
17 </Flex>
18 );
19}

Installation

pnpm dlx nachui add button

Anatomy

1import { Button } from '@/components/ui/button';
1<Button variant="outline">Button</Button>

Variants

Sizes

Table row

Invoice #2041

Northwind Labs, $1,280

Form footer

Billing address

Updated 3 days ago

Pricing page

Team plan

$24 per seat, billed monthly

Toolbar

Search this project

Icon size keeps the button square

1import { Add01Icon, Search01Icon } from '@hugeicons/core-free-icons';
2import { HugeiconsIcon } from '@hugeicons/react';
3import { Button } from '@/components/ui/button';
4import { Flex } from '@/components/ui/flex';
5import { Stack } from '@/components/ui/stack';
6
7const rows = [
8 {
9 size: 'sm' as const,
10 place: 'Table row',
11 title: 'Invoice #2041',
12 detail: 'Northwind Labs, $1,280',
13 action: 'Mark as paid',
14 },
15 {
16 size: 'default' as const,
17 place: 'Form footer',
18 title: 'Billing address',
19 detail: 'Updated 3 days ago',
20 action: 'Save changes',
21 },
22 {
23 size: 'lg' as const,
24 place: 'Pricing page',
25 title: 'Team plan',
26 detail: '$24 per seat, billed monthly',
27 action: 'Start free trial',
28 },
29];
30
31export function Sizes() {
32 return (
33 <Stack gap="3" className="w-full max-w-md">
34 {rows.map((row) => (
35 <Flex
36 key={row.size}
37 align="center"
38 justify="between"
39 gap="4"
40 className="border-border bg-card rounded-xl border p-4"
41 >
42 <div className="min-w-0">
43 <p className="text-muted-foreground text-[11px] tracking-wide uppercase">{row.place}</p>
44 <p className="mt-1 truncate text-sm font-medium">{row.title}</p>
45 <p className="text-muted-foreground truncate text-xs">{row.detail}</p>
46 </div>
47 <Button
48 size={row.size}
49 leftIcon={
50 <HugeiconsIcon
51 icon={Add01Icon}
52 className={row.size === 'lg' ? 'size-5' : 'size-4'}
53 size={row.size === 'lg' ? 20 : 16}
54 />
55 }
56 >
57 {row.action}
58 </Button>
59 </Flex>
60 ))}
61 <Flex
62 align="center"
63 justify="between"
64 gap="4"
65 className="border-border bg-card rounded-xl border p-4"
66 >
67 <div className="min-w-0">
68 <p className="text-muted-foreground text-[11px] tracking-wide uppercase">Toolbar</p>
69 <p className="mt-1 truncate text-sm font-medium">Search this project</p>
70 <p className="text-muted-foreground truncate text-xs">
71 Icon size keeps the button square
72 </p>
73 </div>
74 <Button size="icon" aria-label="Search this project">
75 <HugeiconsIcon icon={Search01Icon} className="size-4" size={16} />
76 </Button>
77 </Flex>
78 </Stack>
79 );
80}

Secondary

Seats

7 of 10 used on the Team plan

1import { UserAdd01Icon } from '@hugeicons/core-free-icons';
2import { HugeiconsIcon } from '@hugeicons/react';
3import { Button } from '@/components/ui/button';
4import { Flex } from '@/components/ui/flex';
5
6export function Secondary() {
7 return (
8 <Flex
9 align="center"
10 justify="between"
11 gap="4"
12 className="border-border bg-card w-full max-w-md rounded-xl border p-4"
13 >
14 <div className="min-w-0">
15 <p className="text-sm font-medium">Seats</p>
16 <p className="text-muted-foreground text-xs">7 of 10 used on the Team plan</p>
17 </div>
18 <Button
19 variant="secondary"
20 leftIcon={<HugeiconsIcon icon={UserAdd01Icon} className="size-4" size={16} />}
21 >
22 Invite teammate
23 </Button>
24 </Flex>
25 );
26}

Destructive

Delete billing account

Removes 3 projects and every invoice from March 2024 onward. This cannot be undone.

1import { Delete02Icon } from '@hugeicons/core-free-icons';
2import { HugeiconsIcon } from '@hugeicons/react';
3import { Button } from '@/components/ui/button';
4import { Stack } from '@/components/ui/stack';
5
6export function Destructive() {
7 return (
8 <Stack
9 gap="3"
10 className="border-destructive-border bg-destructive-surface w-full max-w-sm rounded-xl border p-4"
11 >
12 <div>
13 <p className="text-destructive-text text-sm font-medium">Delete billing account</p>
14 <p className="text-muted-foreground mt-1 text-xs">
15 Removes 3 projects and every invoice from March 2024 onward. This cannot be undone.
16 </p>
17 </div>
18 <Button
19 variant="destructive"
20 size="sm"
21 className="self-start"
22 leftIcon={<HugeiconsIcon icon={Delete02Icon} className="size-4" size={16} />}
23 >
24 Delete account
25 </Button>
26 </Stack>
27 );
28}

Outline

Invoices

142 records, Jan 1 to Mar 31

1import { Download01Icon } from '@hugeicons/core-free-icons';
2import { HugeiconsIcon } from '@hugeicons/react';
3import { Button } from '@/components/ui/button';
4import { Flex } from '@/components/ui/flex';
5
6export function Outline() {
7 return (
8 <Flex
9 align="center"
10 justify="between"
11 gap="4"
12 className="border-border bg-card w-full max-w-md rounded-xl border p-4"
13 >
14 <div className="min-w-0">
15 <p className="text-sm font-medium">Invoices</p>
16 <p className="text-muted-foreground text-xs">142 records, Jan 1 to Mar 31</p>
17 </div>
18 <Button
19 variant="outline"
20 leftIcon={<HugeiconsIcon icon={Download01Icon} className="size-4" size={16} />}
21 >
22 Export CSV
23 </Button>
24 </Flex>
25 );
26}

Ghost

q3-roadmap.md

Edited by Nadia 4h ago

1import { MoreHorizontalIcon } from '@hugeicons/core-free-icons';
2import { HugeiconsIcon } from '@hugeicons/react';
3import { Button } from '@/components/ui/button';
4import { Flex } from '@/components/ui/flex';
5
6export function Ghost() {
7 return (
8 <Flex
9 align="center"
10 justify="between"
11 gap="2"
12 className="border-border bg-card w-full max-w-md rounded-xl border p-2 pl-4"
13 >
14 <div className="min-w-0">
15 <p className="truncate text-sm font-medium">q3-roadmap.md</p>
16 <p className="text-muted-foreground text-xs">Edited by Nadia 4h ago</p>
17 </div>
18 <Flex align="center" gap="1">
19 <Button variant="ghost" size="sm">
20 Rename
21 </Button>
22 <Button variant="ghost" size="sm">
23 Duplicate
24 </Button>
25 <Button variant="ghost" size="icon" aria-label="More actions">
26 <HugeiconsIcon icon={MoreHorizontalIcon} className="size-4" size={16} />
27 </Button>
28 </Flex>
29 </Flex>
30 );
31}

Rate limit reached

This workspace made 10,000 API requests in the last hour. Limits reset at 14:00 UTC.

1import { ArrowUpRight01Icon } from '@hugeicons/core-free-icons';
2import { HugeiconsIcon } from '@hugeicons/react';
3import { Button } from '@/components/ui/button';
4import { Stack } from '@/components/ui/stack';
5
6export function Link() {
7 return (
8 <Stack gap="2" className="border-border bg-card w-full max-w-sm rounded-xl border p-4">
9 <p className="text-sm font-medium">Rate limit reached</p>
10 <p className="text-muted-foreground text-xs">
11 This workspace made 10,000 API requests in the last hour. Limits reset at 14:00 UTC.
12 </p>
13 <Button
14 variant="link"
15 className="self-start text-sm"
16 rightIcon={<HugeiconsIcon icon={ArrowUpRight01Icon} className="size-3.5" size={14} />}
17 >
18 Read the rate limit docs
19 </Button>
20 </Stack>
21 );
22}

API Reference

Button

PropTypeDefaultDescription
variant"default" | "destructive" | "outline" | "secondary" | "ghost" | "link""default"The button style.
size"default" | "sm" | "lg" | "icon""default"The button size.
loadingbooleanfalseWhether the button is in a loading state.
loaderReact.ReactNode<Loader2 />Custom loader component to be displayed when loading.
leftIconReact.ReactNodeIcon to display on the left side of the button.
rightIconReact.ReactNodeIcon to display on the right side of the button.
fullWidthbooleanfalseWhether the button should take up the full width of its container.
disabledbooleanDisables the button.
classNamestringAdditional CSS class names.
type"button" | "submit" | "reset""button"The type of the button element.
childrenReact.ReactNodeThe button content (text or other elements).

ButtonGroup

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"The layout of the button group, either horizontal or vertical.
attachedbooleanfalseWhether the buttons in the group are attached to each other (i.e., no border-radius between buttons).
classNamestringAdditional CSS class names.
childrenReact.ReactNodeThe buttons inside the group.
Found something to improve?

Notice a bug, typo, or missing detail on this page? Help us make the documentation better by opening a GitHub issue.

Create an Issue
Ctrl+I