Skip to content
portalbits
Home Docs GitHub(opens in a new tab)

Guides

Get startedFoundationsMotion

Components

All components

Buttons

ButtonIconButton

Inputs

InputSelectTextareaSlider

Selection

CheckboxToggleToggleGroupSwitchRadioGroup

Identity

AvatarBadge

Overlays

DialogPopoverTooltipDropdownMenuAlertDialog

Disclosure

TabsAccordion

Cards

AppCardArticleCardFeatureCard

Content

CarouselSectionHeaderEmptyStateAlertProgressSeparatorRowListRow

Chrome

PortalShellSidebarNavMobileNavTopBarAuthFrameColorSelectorFloatingNav

Button

Pill controls for the main action, a quieter alternative, and inline text.

Not saved yet

Variations
More examples

Link button

Pass href to navigate. Quiet never takes a link.

Get started

Source

<script lang="ts">
  import 'portal-bits/styles.css';
  import 'portal-bits/tokens.css';
  import type { Snippet } from 'svelte';

  let { children }: { children: Snippet } = $props();
</script>

{@render children()}
<script lang="ts">
  import ButtonExample from './ButtonExample.svelte';
</script>

<ButtonExample variant={"primary"} size={40} disabled={false} icon={false} />
<script lang="ts">
  import { Button } from 'portal-bits';
  let {
    variant = 'primary',
    size = 40,
    disabled = false,
    icon = false,
  }: {
    variant?: 'primary' | 'secondary' | 'green' | 'quiet';
    size?: 32 | 40 | 48;
    disabled?: boolean;
    icon?: boolean;
  } = $props();
  let saved = $state(false);
</script>

{#snippet label()}
  {#if icon}
    <svg
      width="15"
      height="15"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
      stroke-linecap="round"
      stroke-linejoin="round"
      aria-hidden="true"><path d="M20 6 9 17l-5-5" /></svg
    >
  {/if}
  {saved ? 'Changes saved' : 'Save changes'}
{/snippet}

<div class="stack">
  {#if variant === 'quiet'}
    <Button variant="quiet" {disabled} onclick={() => (saved = !saved)}>
      {@render label()}
    </Button>
  {:else}
    <Button {variant} {size} {disabled} onclick={() => (saved = !saved)}>
      {@render label()}
    </Button>
  {/if}
  <p role="status">{saved ? 'Saved' : 'Not saved yet'}</p>
</div>

<style>
  .stack {
    display: grid;
    justify-items: center;
    gap: 12px;
  }
  p {
    margin: 0;
    color: var(--portal-muted);
    font-size: 13px;
    line-height: 20px;
  }
</style>

API reference

These tables list the props and snippets that Button declares. Attributes passed through to an element or primitive are listed under Forwarded attributes, not here.

Props

NameTypeDefaultRequiredBindingDescription
variant'primary' | 'secondary' | 'green' | 'quiet'secondaryNoOne-wayVisual style. Quiet is inline text with an underline.
size32 | 40 | 4840NoOne-wayHeight in pixels. It does not apply to quiet.
classstring""NoOne-wayExtra classes, added after the component classes.

Snippets

NameTypeDefaultRequiredBindingDescription
childrenSnippetNoneNoOne-wayThe label or content.

Forwarded attributes

  • Primary, secondary, and green accept every Bits UI `Button.Root` prop. That includes `href`, which renders an anchor, plus `type`, `disabled`, `child`, `ref`, native attributes, and event handlers.
  • Quiet accepts native button attributes and handlers. It renders a `button` with `type="button"` unless you set `type`.

The primitive underneath is a Bits UI peer dependency. Its own options are documented in the Bits UI Button documentation. Only the props listed on this page are part of the Button contract. No data attributes are documented as stable.

Limits

  • Quiet does not accept `href` or `child`, and `size` does not apply. Use your own anchor for navigation. Quiet is an adaptation; its spacing and underline were not measured.
  • `variant` is the only prop that changes the render path. A `variant` value outside the four listed fails type checking.
  • Disabled quiet actions stay visible and do not fire.

Related

  • IconButton
  • Toggle
Next IconButton

On this page

  • Preview
  • Source
  • API reference
  • Props
  • Snippets
  • Forwarded attributes
  • Limits