Pill buttons
The signature interaction of trc-ui: a thin pill with a round accent dot. On hover, the dot stretches until it fills the pill and the label turns dark.
Outline and solid
Hover the pills, or reach them with the Tab key: keyboard focus plays the same animation. The solid pill marks the main action; keep it to one per screen.
<PillButton solid>Create an account</PillButton>
<PillButton>Get started</PillButton>Compact size
<PillButton size="sm">Sign in</PillButton>
<PillButton size="sm" solid>Get started</PillButton>As a link
PillLink renders the same pill as an <a>. Pass your router's link component with as to keep client-side navigation.
<PillLink href="#">Read the docs</PillLink>The Back exception
Pills carry no icon other than their arrow. The only exception is going back, with a left arrow.
import { ArrowLeft, PillButton } from "trc-ui";
<PillButton icon={<ArrowLeft />}>Back</PillButton>Loading and disabled
loading replaces the arrow with a spinner, disables the button and announces it as busy. A disabled pill does not stretch on hover.
<PillButton loading>Sending</PillButton>
<PillButton disabled>Unavailable</PillButton>How the stretch works
The dot and the fill are a single shape that grows from the dot's width to the full pill, under the border, with an ease-in-out-quart curve over 500 ms. The label darkens 150 ms after the fill starts, and lightens right away when it leaves, so it stays readable at every frame. On touch screens there is no hover: the pill stays at rest. With reduced motion, the change is instant.
:root {
--trc-ease: cubic-bezier(0.77, 0, 0.175, 1);
--trc-duration: 500ms;
}PillButton
| Prop | Type | Default | Description |
|---|---|---|---|
solid | boolean | false | White background: the main action of a screen. Use one per screen at most. |
size | "md" | "sm" | "md" | 56 px, or 40 px for headers and toolbars. |
icon | ReactNode | – | Replaces the arrow in the dot. Reserved for “Back” (left arrow). |
loading | boolean | false | Shows a spinner in the dot, disables the button and sets aria-busy. |
type | "button" | "submit" | "reset" | "button" | Defaults to button: a pill never submits a form by accident. |
…props | ComponentProps<"button"> | – | Any native button attribute, and a ref. |
PillLink
| Prop | Type | Default | Description |
|---|---|---|---|
solid | boolean | false | White background: the main action of a screen. Use one per screen at most. |
size | "md" | "sm" | "md" | 56 px, or 40 px for headers and toolbars. |
icon | ReactNode | – | Replaces the arrow in the dot. Reserved for “Back” (left arrow). |
as | ElementType | "a" | Your router's link component (Next.js, React Router…). |
…props | ComponentProps<typeof as> | – | Props of the rendered element: href, target… |