Pho

Button

Trigger an action or event β€” submitting a form, opening a dialog, confirming a change. Button is for actions that mutate state; for navigation that changes the URL, use ButtonLink.

Import

import { Button, ButtonLink } from "@photon/pho-ui/components/button";

Sizes

Three sizes β€” sm, md, lg. The default is md.

<Button size="sm">Upload</Button>
<Button size="md">Upload</Button>
<Button size="lg">Upload</Button>

Variants

variant is a tight, semantic set: primary (the default high-emphasis action), secondary, tertiary, and error for destructive confirmations. There is no ghost or link β€” reach for tertiary for a quiet button, and ButtonLink for navigation.

<Button variant="primary">Upload</Button>
<Button variant="secondary">Upload</Button>
<Button variant="tertiary">Upload</Button>
<Button variant="error">Upload</Button>

Shapes

shape is square (default), circle, or rounded. Icon-only buttons must set svgOnly and an aria-label that names the action.

import { ArrowUp } from "@phosphor-icons/react";

<Button svgOnly aria-label="Upload" shape="square">
  <ArrowUp />
</Button>
<Button svgOnly aria-label="Upload" shape="circle">
  <ArrowUp />
</Button>

Prefix and suffix

prefix and suffix are generic slots placed before and after the label. Pass an icon component (Plus) or an element (<Plus />).

import { ArrowLeft, ArrowRight, Plus } from "@phosphor-icons/react";

<Button prefix={ArrowLeft}>Back</Button>
<Button suffix={ArrowRight}>Continue</Button>
<Button variant="secondary" prefix={Plus} suffix={ArrowRight}>
  New project
</Button>

Rounded

Combine shape="rounded" with the shadow prop for the pill button often used on marketing pages.

<Button variant="secondary" shape="rounded" shadow>
  Get started
</Button>

Loading

Pass loading instead of swapping in your own spinner β€” the button stays readable, announces its busy state (aria-busy), and blocks interaction.

<Button loading>Saving</Button>

Disabled

<Button disabled>Upload</Button>

Disabled variants

<Button disabled>Primary</Button>
<Button disabled variant="secondary">Secondary</Button>
<Button disabled variant="tertiary">Tertiary</Button>
<Button disabled variant="error">Error</Button>

Use ButtonLink for navigation. It shares every visual prop with Button and adds href, rendering the host router’s link through LinkProvider.

View docs
import { ArrowRight } from "@phosphor-icons/react";

<ButtonLink href="/docs" variant="secondary" suffix={ArrowRight}>
  View docs
</ButtonLink>;

Props

Best practices