Skip to content

Button

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

<script lang="ts">
  import ArrowUpIcon from "phosphor-svelte/lib/ArrowUpIcon";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<div class="flex flex-wrap items-center gap-2 md:flex-row">
  <Button variant="outline">Button</Button>
  <Button variant="outline" size="icon" aria-label="Submit">
    <ArrowUpIcon />
  </Button>
</div>
<Button variant="outline">Button</Button>
<Button variant="outline" size="icon" aria-label="Submit">
  <ArrowUpIcon />
</Button>

Installation

pnpm dlx jsrepo@latest add button

Usage

<script lang="ts">
  import { Button } from '$lib/components/ui/button/index.js';
</script>
 
<Button variant="outline">Button</Button>

Examples

Size

<script lang="ts">
  import ArrowUpRightIcon from "phosphor-svelte/lib/ArrowUpRightIcon";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<div class="flex flex-col items-start gap-8 sm:flex-row">
  <div class="flex items-start gap-2">
    <Button size="sm" variant="outline">Small</Button>
    <Button size="icon-sm" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
  <div class="flex items-start gap-2">
    <Button variant="outline">Default</Button>
    <Button size="icon" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
  <div class="flex items-start gap-2">
    <Button variant="outline" size="lg">Large</Button>
    <Button size="icon-lg" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
</div>
<!-- Small -->
<Button size="sm" variant="outline">Small</Button>
<Button size="icon-sm" aria-label="Submit" variant="outline">
  <ArrowUpRightIcon />
</Button>
 
<!-- Medium -->
<Button variant="outline">Default</Button>
<Button size="icon" aria-label="Submit" variant="outline">
  <ArrowUpRightIcon />
</Button>
 
<!-- Large -->
<Button size="lg" variant="outline">Large</Button>
<Button size="icon-lg" aria-label="Submit" variant="outline">
  <ArrowUpRightIcon />
</Button>

Default

<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button>Button</Button>
<Button>Button</Button>

Outline

<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="outline">Outline</Button>
<Button variant="outline">Outline</Button>

Secondary

<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="secondary">Secondary</Button>
<Button variant="secondary">Secondary</Button>

Ghost

<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="ghost">Ghost</Button>
<Button variant="ghost">Ghost</Button>

Destructive

<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="destructive">Destructive</Button>
<Button variant="destructive">Destructive</Button>
<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="link">Link</Button>
<Button variant="link">Link</Button>

Icon

<script lang="ts">
  import ArrowCircleUpIcon from "phosphor-svelte/lib/ArrowCircleUpIcon";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="outline" size="icon" aria-label="Submit">
  <ArrowCircleUpIcon />
</Button>
<Button variant="outline" size="icon" aria-label="Submit">
  <CircleFadingArrowUpIcon />
</Button>

With Icon

The spacing between the icon and the text is automatically adjusted based on the size of the button. You do not need any margin on the icon.

<script lang="ts">
  import GitBranchIcon from "phosphor-svelte/lib/GitBranchIcon";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button variant="outline" size="sm">
  <GitBranchIcon /> New Branch
</Button>
<Button variant="outline" size="sm">
  <IconGitBranch /> New Branch
</Button>

Rounded

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

<script lang="ts">
  import ArrowUpIcon from "phosphor-svelte/lib/ArrowUpIcon";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<div class="flex flex-col gap-8">
  <Button variant="outline" size="icon" class="rounded-full">
    <ArrowUpIcon />
  </Button>
</div>
<Button variant="outline" size="icon" className="rounded-full">
  <ArrowUpRightIcon />
</Button>

Spinner

<script lang="ts">
  import { Button } from "$lib/components/ui/button/index.js";
  import { Spinner } from "$lib/components/ui/spinner/index.js";
</script>
 
<Button size="sm" variant="outline" disabled>
  <Spinner />
  Submit
</Button>
<Button size="sm" variant="outline" disabled>
  <Spinner />
  Submit
</Button>

Button Group

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

<script lang="ts">
  import ArchiveIcon from "phosphor-svelte/lib/ArchiveIcon";
  import ArrowLeftIcon from "phosphor-svelte/lib/ArrowLeftIcon";
  import CalendarPlusIcon from "phosphor-svelte/lib/CalendarPlusIcon";
  import ClockIcon from "phosphor-svelte/lib/ClockIcon";
  import DotsThreeIcon from "phosphor-svelte/lib/DotsThreeIcon";
  import EnvelopeSimpleIcon from "phosphor-svelte/lib/EnvelopeSimpleIcon";
  import FunnelSimpleIcon from "phosphor-svelte/lib/FunnelSimpleIcon";
  import TagIcon from "phosphor-svelte/lib/TagIcon";
  import TrashIcon from "phosphor-svelte/lib/TrashIcon";
  import { Button } from "$lib/components/ui/button/index.js";
  import * as ButtonGroup from "$lib/components/ui/button-group/index.js";
  import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
 
  let label = $state("personal");
</script>
 
<ButtonGroup.Root>
  <ButtonGroup.Root class="hidden sm:flex">
    <Button variant="outline" size="icon-sm" aria-label="Go Back">
      <ArrowLeftIcon />
    </Button>
  </ButtonGroup.Root>
  <ButtonGroup.Root>
    <Button size="sm" variant="outline">Archive</Button>
    <Button size="sm" variant="outline">Report</Button>
  </ButtonGroup.Root>
  <ButtonGroup.Root>
    <Button size="sm" variant="outline">Snooze</Button>
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>
        {#snippet child({ props })}
          <Button
            {...props}
            variant="outline"
            size="icon-sm"
            aria-label="More Options"
          >
            <DotsThreeIcon />
          </Button>
        {/snippet}
      </DropdownMenu.Trigger>
      <DropdownMenu.Content align="end" class="w-52">
        <DropdownMenu.Group>
          <DropdownMenu.Item>
            <EnvelopeSimpleIcon />
            Mark as Read
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            <ArchiveIcon />
            Archive
          </DropdownMenu.Item>
        </DropdownMenu.Group>
        <DropdownMenu.Separator />
        <DropdownMenu.Group>
          <DropdownMenu.Item>
            <ClockIcon />
            Snooze
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            <CalendarPlusIcon />
            Add to Calendar
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            <FunnelSimpleIcon />
            Add to List
          </DropdownMenu.Item>
          <DropdownMenu.Sub>
            <DropdownMenu.SubTrigger>
              <TagIcon />
              Label As...
            </DropdownMenu.SubTrigger>
            <DropdownMenu.SubContent>
              <DropdownMenu.RadioGroup bind:value={label}>
                <DropdownMenu.RadioItem value="personal"
                  >Personal</DropdownMenu.RadioItem
                >
                <DropdownMenu.RadioItem value="work"
                  >Work</DropdownMenu.RadioItem
                >
                <DropdownMenu.RadioItem value="other"
                  >Other</DropdownMenu.RadioItem
                >
              </DropdownMenu.RadioGroup>
            </DropdownMenu.SubContent>
          </DropdownMenu.Sub>
        </DropdownMenu.Group>
        <DropdownMenu.Separator />
        <DropdownMenu.Group>
          <DropdownMenu.Item class="text-destructive focus:text-destructive">
            <TrashIcon />
            Trash
          </DropdownMenu.Item>
        </DropdownMenu.Group>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  </ButtonGroup.Root>
</ButtonGroup.Root>
<ButtonGroup.Root>
  <ButtonGroup.Root class="hidden sm:flex">
    <Button variant="outline" size="icon" aria-label="Go Back">
      <ArrowLeft />
    </Button>
  </ButtonGroup.Root>
  <ButtonGroup.Root>
    <Button variant="outline">Archive</Button>
    <Button variant="outline">Report</Button>
  </ButtonGroup.Root>
  <ButtonGroup.Root>
    <Button variant="outline">Snooze</Button>
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>
        {#snippet child({ props })}
          <Button {...props} variant="outline" size="icon" aria-label="More Options">
            <MoreHorizontal />
          </Button>
        {/snippet}
      </DropdownMenu.Trigger>
      <DropdownMenu.Content align="end" class="w-52">
        <DropdownMenu.Group>
          <DropdownMenu.Item>
            <MailCheck />
            Mark as Read
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            <Archive />
            Archive
          </DropdownMenu.Item>
        </DropdownMenu.Group>
        <DropdownMenu.Separator />
        <DropdownMenu.Group>
          <DropdownMenu.Item>
            <Clock />
            Snooze
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            <CalendarPlus />
            Add to Calendar
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            <ListFilter />
            Add to List
          </DropdownMenu.Item>
          <DropdownMenu.Sub>
            <DropdownMenu.SubTrigger>
              <Tag />
              Label As...
            </DropdownMenu.SubTrigger>
            <DropdownMenu.SubContent>
              <DropdownMenu.RadioGroup bind:value={label}>
                <DropdownMenu.RadioItem value="personal">Personal</DropdownMenu.RadioItem>
                <DropdownMenu.RadioItem value="work">Work</DropdownMenu.RadioItem>
                <DropdownMenu.RadioItem value="other">Other</DropdownMenu.RadioItem>
              </DropdownMenu.RadioGroup>
            </DropdownMenu.SubContent>
          </DropdownMenu.Sub>
        </DropdownMenu.Group>
        <DropdownMenu.Separator />
        <DropdownMenu.Group>
          <DropdownMenu.Item class="text-destructive focus:text-destructive">
            <Trash2 />
            Trash
          </DropdownMenu.Item>
        </DropdownMenu.Group>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  </ButtonGroup.Root>
</ButtonGroup.Root>

You can convert the <button> into an <a> element by simply passing an href as a prop.

<script lang="ts">
  import { Button } from '$lib/components/ui/button/index.js';
</script>
 
<Button href="/docs">Dashboard</Button>

Alternatively, you can use the buttonVariants helper to create a link that looks like a button.

<script lang="ts">
  import { buttonVariants } from '$lib/components/ui/button';
</script>
 
<a href="/docs" class={buttonVariants({ variant: 'outline' })}> Dashboard </a>