ZaidanHomeDocsComponentsBlocksChartsTypesetCreate

Command Palette

Search for a command to run...

GitHub
New
Sections
  • Introduction
  • Components
  • Blocks
  • Installation
  • Customization
  • Dark Mode
  • Typeset
  • Zaidan Skills
  • FAQ
  • Roadmap
  • Changelog
Installation
  • Astro
  • Manual
  • Solid Start
  • TanStack Router
  • TanStack Start
  • Vite
Blocks
  • Data Grid
  • Event Calendar
  • Filters
  • Gantt
  • Image Crop
  • Kanban
  • Message Scroller
  • Questionnaire
  • Sortable
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip

Button

Displays a button or a component that looks like a button.

Kobalte
Kobalte

The Button component is built on top of Kobalte Button, which provides the accessible button primitive.

1
import { ArrowUpIcon } from "lucide-solid";
2
import { Button } from "~/components/ui/button";
3
4
export default function ButtonDemo() {
5
return (
6
<div class="flex flex-wrap items-center gap-2 md:flex-row">
7
<Button variant="outline">Button</Button>
8
<Button variant="outline" size="icon" aria-label="Submit">
9
<ArrowUpIcon />
10
</Button>
11
</div>
12
);
13
}

Installation

pnpm dlx shadcn@latest add @zaidan/button
npx shadcn@latest add @zaidan/button
yarn dlx shadcn@latest add @zaidan/button
bunx --bun shadcn@latest add @zaidan/button

Usage

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

Cursor

Tailwind v4 switched from cursor: pointer to cursor: default for button elements.

If you want to keep the cursor: pointer behavior, add the following code to your CSS file:

globals.css
1
@layer base {
2
button:not(:disabled),
3
[role="button"]:not(:disabled) {
4
cursor: pointer;
5
}
6
}

Size

Use the size prop to change the size of the button.

1
import { ArrowUpRightIcon } from "lucide-solid";
2
import { Button } from "~/components/ui/button";
3
4
export default function ButtonSize() {
5
return (
6
<div class="flex flex-col items-start gap-8 sm:flex-row">
7
<div class="flex items-start gap-2">
8
<Button size="xs" variant="outline">
9
Extra Small
10
</Button>
11
<Button size="icon-xs" aria-label="Submit" variant="outline">
12
<ArrowUpRightIcon />
13
</Button>
14
</div>
15
<div class="flex items-start gap-2">
16
<Button size="sm" variant="outline">
17
Small
18
</Button>
19
<Button size="icon-sm" aria-label="Submit" variant="outline">
20
<ArrowUpRightIcon />
21
</Button>
22
</div>
23
<div class="flex items-start gap-2">
24
<Button variant="outline">Default</Button>
25
<Button size="icon" aria-label="Submit" variant="outline">
26
<ArrowUpRightIcon />
27
</Button>
28
</div>
29
<div class="flex items-start gap-2">
30
<Button variant="outline" size="lg">
31
Large
32
</Button>
33
<Button size="icon-lg" aria-label="Submit" variant="outline">
34
<ArrowUpRightIcon />
35
</Button>
36
</div>
37
</div>
38
);
39
}

Default

1
import { Button } from "~/components/ui/button";
2
3
export default function ButtonDefault() {
4
return <Button>Button</Button>;
5
}

Outline

1
import { Button } from "~/components/ui/button";
2
3
export default function ButtonOutline() {
4
return <Button variant="outline">Outline</Button>;
5
}

Secondary

1
import { Button } from "~/components/ui/button";
2
3
export default function ButtonSecondary() {
4
return <Button variant="secondary">Secondary</Button>;
5
}

Ghost

1
import { Button } from "~/components/ui/button";
2
3
export default function ButtonGhost() {
4
return <Button variant="ghost">Ghost</Button>;
5
}

Destructive

1
import { Button } from "~/components/ui/button";
2
3
export default function ButtonDestructive() {
4
return <Button variant="destructive">Destructive</Button>;
5
}

Link

1
import { Button } from "~/components/ui/button";
2
3
export default function ButtonLink() {
4
return <Button variant="link">Link</Button>;
5
}

Icon

1
import { CircleFadingArrowUpIcon } from "lucide-solid";
2
import { Button } from "~/components/ui/button";
3
4
export default function ButtonIcon() {
5
return (
6
<Button variant="outline" size="icon" aria-label="Move up">
7
<CircleFadingArrowUpIcon />
8
</Button>
9
);
10
}

With Icon

Add the data-icon="inline-start" or data-icon="inline-end" attribute to an icon for correct spacing.

1
import { GitBranchIcon, GitForkIcon } from "lucide-solid";
2
import { Button } from "~/components/ui/button";
3
4
export default function ButtonWithIcon() {
5
return (
6
<div class="flex gap-2">
7
<Button variant="outline">
8
<GitBranchIcon data-icon="inline-start" />
9
New Branch
10
</Button>
11
<Button variant="outline">
12
Fork
13
<GitForkIcon data-icon="inline-end" />
14
</Button>
15
</div>
16
);
17
}

Rounded

Use the rounded-full class to make a button rounded.

1
import { ArrowUpIcon } from "lucide-solid";
2
import { Button } from "~/components/ui/button";
3
4
export default function ButtonRounded() {
5
return (
6
<div class="flex gap-2">
7
<Button class="rounded-full">Get Started</Button>
8
<Button variant="outline" size="icon" class="rounded-full" aria-label="Move up">
9
<ArrowUpIcon />
10
</Button>
11
</div>
12
);
13
}

Spinner

Render a <Spinner /> inside the button to show a loading state. Add data-icon="inline-start" or data-icon="inline-end" to the spinner for correct spacing.

1
import { Button } from "~/components/ui/button";
2
import { Spinner } from "~/components/ui/spinner";
3
4
export default function ButtonSpinner() {
5
return (
6
<div class="flex gap-2">
7
<Button variant="outline" disabled>
8
<Spinner data-icon="inline-start" />
9
Generating
10
</Button>
11
<Button variant="secondary" disabled>
12
Downloading
13
<Spinner data-icon="inline-end" />
14
</Button>
15
</div>
16
);
17
}

Button Group

To create a button group, use the ButtonGroup component. See the Button Group documentation for more details.

1
import {
2
ArchiveIcon,
3
ArrowLeftIcon,
4
CalendarPlusIcon,
5
ClockIcon,
6
ListFilterIcon,
7
MailCheckIcon,
8
MoreHorizontalIcon,
9
TagIcon,
10
Trash2Icon,
11
} from "lucide-solid";
12
import { createSignal } from "solid-js";
13
import { Button } from "~/components/ui/button";
14
import { ButtonGroup } from "~/components/ui/button-group";
15
import {
16
DropdownMenu,
17
DropdownMenuContent,
18
DropdownMenuGroup,
19
DropdownMenuItem,
20
DropdownMenuRadioGroup,
21
DropdownMenuRadioItem,
22
DropdownMenuSeparator,
23
DropdownMenuSub,
24
DropdownMenuSubContent,
25
DropdownMenuSubTrigger,
26
DropdownMenuTrigger,
27
} from "~/components/ui/dropdown-menu";
28
29
export default function ButtonGroupDemo() {
30
const [label, setLabel] = createSignal("personal");
31
32
return (
33
<ButtonGroup>
34
<ButtonGroup class="hidden sm:flex">
35
<Button variant="outline" size="icon" aria-label="Go back">
36
<ArrowLeftIcon />
37
</Button>
38
</ButtonGroup>
39
<ButtonGroup>
40
<Button variant="outline">Archive</Button>
41
<Button variant="outline">Report</Button>
42
</ButtonGroup>
43
<ButtonGroup>
44
<Button variant="outline">Snooze</Button>
45
<DropdownMenu placement="bottom-end">
46
<DropdownMenuTrigger
47
as={Button}
48
variant="outline"
49
size="icon"
50
class="w-fit"
51
aria-label="More options"
52
>
53
<MoreHorizontalIcon />
54
</DropdownMenuTrigger>
55
<DropdownMenuContent class="w-40">
56
<DropdownMenuGroup>
57
<DropdownMenuItem>
58
<MailCheckIcon />
59
Mark as Read
60
</DropdownMenuItem>
61
<DropdownMenuItem>
62
<ArchiveIcon />
63
Archive
64
</DropdownMenuItem>
65
</DropdownMenuGroup>
66
<DropdownMenuSeparator />
67
<DropdownMenuGroup>
68
<DropdownMenuItem>
69
<ClockIcon />
70
Snooze
71
</DropdownMenuItem>
72
<DropdownMenuItem>
73
<CalendarPlusIcon />
74
Add to Calendar
75
</DropdownMenuItem>
76
<DropdownMenuItem>
77
<ListFilterIcon />
78
Add to List
79
</DropdownMenuItem>
80
<DropdownMenuSub>
81
<DropdownMenuSubTrigger>
82
<TagIcon />
83
Label As...
84
</DropdownMenuSubTrigger>
85
<DropdownMenuSubContent>
86
<DropdownMenuRadioGroup value={label()} onChange={setLabel}>
87
<DropdownMenuRadioItem value="personal">Personal</DropdownMenuRadioItem>
88
<DropdownMenuRadioItem value="work">Work</DropdownMenuRadioItem>
89
<DropdownMenuRadioItem value="other">Other</DropdownMenuRadioItem>
90
</DropdownMenuRadioGroup>
91
</DropdownMenuSubContent>
92
</DropdownMenuSub>
93
</DropdownMenuGroup>
94
<DropdownMenuSeparator />
95
<DropdownMenuGroup>
96
<DropdownMenuItem variant="destructive">
97
<Trash2Icon />
98
Trash
99
</DropdownMenuItem>
100
</DropdownMenuGroup>
101
</DropdownMenuContent>
102
</DropdownMenu>
103
</ButtonGroup>
104
</ButtonGroup>
105
);
106
}

As Link

Use the buttonVariants helper to make a link look like a button while preserving native link semantics.

Login
1
import { buttonVariants } from "~/components/ui/button";
2
3
export default function ButtonRender() {
4
return (
5
<a href="/login" class={buttonVariants({ variant: "secondary", size: "sm" })}>
6
Login
7
</a>
8
);
9
}

API Reference

Button

The Button component is a wrapper around the button element that adds a variety of styles and functionality.

PropTypeDefault
variant"default" | "outline" | "ghost" | "destructive" | "secondary" | "link""default"
size"default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg""default"
classstring-

For primitive props, see the Kobalte Button API reference.

On This Page

  • Installation
  • Usage
  • Cursor
  • Size
  • Default
  • Outline
  • Secondary
  • Ghost
  • Destructive
  • Link
  • Icon
  • With Icon
  • Rounded
  • Spinner
  • Button Group
  • As Link
  • API Reference
    • Button
Built by Kevin Abatan. The source code is available on GitHub.