Button

A versatile, polymorphic button component supporting multiple sizes, visual variants, and optional leading or trailing icons.

import { Button } from "@tenstorrent/vesper/button";

export default function ButtonDemo() {
  return <Button>Click me</Button>;
}
Keep the content inside of your button short (1-3 words) and descriptive of the action being taken. It is not advisable to use a Button to render non-text content, or text content that overflows/wraps.

Options

PropTypeDescriptionDefault
size"xs" | "sm" | "md" | "lg"The size of the button. Affects padding and font size."md"
variant"contrast" | "danger" | "ghost" | "primary" | "subtle" | "tertiary" | "warning"The visual style variant of the button."primary"
disabledbooleanWhen true, renders the button in a disabled state and prevents interaction.false
iconLeftReactNodeAn optional icon element rendered to the left of the button content.—
iconRightReactNodeAn optional icon element rendered to the right of the button content.—
asElementTypeThe root element type for polymorphic rendering."button"
childrenReactNodeThe content of the button.—

All other props are forwarded to the underlying <button> element, or whichever root element is specified via the as prop.

Examples

Basic usage

Render a Button by giving it some children:

import { Button } from "@tenstorrent/vesper/button";

export default function BasicButton() {
  return <Button>Submit</Button>;
}

Variants

A Button can be rendered in several different variants:

VariantPreviewWhen to use
"primary"Default variant. Use for the main action a user is expected to take in a given context.
"subtle"Use for secondary actions that are important but should have less visual prominence than the primary action.
"tertiary"Use for secondary or supporting actions that need a clear boundary from surrounding content.
"contrast"Use when an action needs strong visual contrast against its surrounding content.
"ghost"Use for low-emphasis actions where a button's presence should be unobtrusive.
"danger"Use for destructive or potentially irreversible actions that could result in negative consequence.
"warning"Use for actions that may have meaningful consequences or require caution, but are not inherently destructive.
import { Button } from "@tenstorrent/vesper/button";

export default function ButtonVariants() {
  return (
    <>
      <Button variant="primary">Primary</Button>
      <Button variant="subtle">Subtle</Button>
      <Button variant="tertiary">Tertiary</Button>
      <Button variant="contrast">Contrast</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="danger">Danger</Button>
      <Button variant="warning">Warning</Button>
    </>
  );
}

Different sizes

A Button can be rendered in one of four sizes; "xs", "sm", "md", or "lg". The default size is "md".

import { Button } from "@tenstorrent/vesper/button";

export default function ButtonSizes() {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: "var(--vesper-spacing-2)",
      }}
    >
      <Button size="xs">Extra small</Button>
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
    </div>
  );
}

Rendering icons

A Button can render icons to the left or the right of its content via the iconLeft and iconRight props. Simply pass your icon as a ReactNode to either of these props:

import { Button } from "@tenstorrent/vesper/button";
import { ArrowRight, Download } from "@tenstorrent/vesper/icons";

export default function ButtonsWithIcons() {
  return (
    <div
      style={{
        display: "flex",
        gap: "var(--vesper-spacing-2)",
      }}
    >
      <Button iconLeft={<Download />}>Download</Button>
      <Button iconRight={<ArrowRight />}>Continue</Button>
    </div>
  );
}

Disabling a button

You can disable a Button by passing disabled={true} or just disabled as a prop. Disabling a button prevents interaction and changes the color scheme:

import { Button } from "@tenstorrent/vesper/button";

export default function DisabledButton() {
  return <Button disabled>A disabled button</Button>;
}

Polymorphic usage

You can use the as prop to specify what underlying element to render. In this case, we are passing as="a" to render the Button as an anchor link. This is helpful for apps where clicking on a button may navigate to a different page, for example:

Go to Next Page
import { Button } from "@tenstorrent/vesper/button";

export default function ButtonAsLink() {
  return (
    <Button as="a" href="#polymorphic-usage">
      Go to Next Page
    </Button>
  );
}

You can also use other components as the underlying as element. For example, Next.js comes with a bespoke Link component that enables prefetching and client-side navigation between routes, which you may want to use instead of the HTML <a> element:

import Link from "next/link";

import { Button } from "@tenstorrent/vesper/button";

export default function ButtonAsNextLink() {
  return (
    <Button as={Link} prefetch={false} href="/dashboard">
      Go to dashboard
    </Button>
  );
}