Icon Button

A button component that renders a single icon without text. Built on top of Button, it inherits all size and variant options while enforcing an icon-only layout.

import { IconButton } from "@tenstorrent/vesper/icon-button";
import { Gear } from "@tenstorrent/vesper/icons";

export default function IconButtonDemo() {
  return <IconButton icon={<Gear />} aria-label="Settings" />;
}
Always give an IconButton an accessible name by giving it an aria-label. Without one, assistive technology announces the button with no indication of what it is for.

Options

PropTypeDescriptionDefault
iconReactNodeThe icon element to be rendered inside the button.—
size"xs" | "sm" | "md" | "lg"The size of the button. Affects padding and icon 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
asElementTypeThe root element type for polymorphic rendering."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 an IconButton by passing it an icon as a ReactNode:

import { IconButton } from "@tenstorrent/vesper/icon-button";
import { Download } from "@tenstorrent/vesper/icons";

export default function BasicIconButton() {
  return <IconButton aria-label="Download" icon={<Download />} />;
}

Variants

An IconButton 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 { IconButton } from "@tenstorrent/vesper/icon-button";
import { Tenstorrent } from "@tenstorrent/vesper/icons";

export default function IconButtonVariants() {
  return (
    <>
      <IconButton
        aria-label="Primary"
        variant="primary"
        icon={<Tenstorrent />}
      />
      <IconButton aria-label="Subtle" variant="subtle" icon={<Tenstorrent />} />
      <IconButton
        aria-label="Tertiary"
        variant="tertiary"
        icon={<Tenstorrent />}
      />
      <IconButton
        aria-label="Contrast"
        variant="contrast"
        icon={<Tenstorrent />}
      />
      <IconButton aria-label="Ghost" variant="ghost" icon={<Tenstorrent />} />
      <IconButton aria-label="Danger" variant="danger" icon={<Tenstorrent />} />
      <IconButton
        aria-label="Warning"
        variant="warning"
        icon={<Tenstorrent />}
      />
    </>
  );
}

Different sizes

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

import { IconButton } from "@tenstorrent/vesper/icon-button";
import { Tenstorrent } from "@tenstorrent/vesper/icons";

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

Disabling an icon button

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

import { IconButton } from "@tenstorrent/vesper/icon-button";
import { Add } from "@tenstorrent/vesper/icons";

export default function DisabledIconButton() {
  return <IconButton aria-label="Increment count" disabled icon={<Add />} />;
}

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 IconButton as an anchor link. This is helpful for apps where clicking on a button may navigate to a different page, for example:

import { IconButton } from "@tenstorrent/vesper/icon-button";
import { ArrowRight } from "@tenstorrent/vesper/icons";

export default function IconButtonAsLink() {
  return (
    <IconButton
      icon={<ArrowRight />}
      as="a"
      href="#polymorphic-usage"
      aria-label="Next page"
    />
  );
}

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 { IconButton } from "@tenstorrent/vesper/icon-button";
import { ArrowRight } from "@tenstorrent/vesper/icons";

export default function IconButtonAsNextLink() {
  return (
    <IconButton
      icon={<ArrowRight />}
      as={Link}
      prefetch={false}
      href="/dashboard"
      aria-label="Go to dashboard"
    />
  );
}