Buttonv3.0.11Ready for Production
A compact button primitive optimized for product interfaces with four size variants, three visual styles, and danger states.
Prefer AI-assisted development?
Installation
Install the Product Button primitive:
npm install @pmi/catalyst-buttonVariants
The three core variants provide different levels of visual emphasis for application contexts.
Size
Four size options including extra-small for compact interfaces.
Danger
Use the danger prop for destructive or warning actions across all variants.
With Icons
Use any icon from @pmi/catalyst-icons in leading, trailing, both, or icon-only positions.
Disabled
Disabled state applies to all variants and sizes, visually indicating non-interactivity.
As Child
Use asChild to render the Button as a different element (e.g., <a>) while retaining all styles and behaviors.
API
The root Button primitive with full variant and state control. Accepts all standard React button attributes (onClick, type, aria-*, etc.).
Prop
Type
Prop
Type
Extends
React.ButtonHTMLAttributes<HTMLButtonElement>for native button behavior and accessibility.
Prop
Type
Extends
React.HTMLAttributes<HTMLSpanElement>for flexible label rendering.
Text label part for button content with size-aware positioning. Accepts all standard React span attributes (className, id, data-*, etc.).
Accessibility
Keyboard Interactions
| Key | Action |
|---|---|
Tab | Moves focus to the button |
Space | Activates the focused button |
Enter | Activates the focused button |
ARIA
- Use
<button>elements. Screen readers do not recognize<div>or<img>as interactive controls. - Provide
aria-labelon icon-only buttons where no visible text label exists. - When styling a link as a button,
Spaceactivates buttons whileEnteractivates links.
Focus Management
Button receives focus via standard tab order. The focus ring uses a 2px outline with offset, mapped to pmi-off-black-800 (light) and white (dark). Contrast meets WCAG 2.2 standards.
See the APG Button Pattern and MDN Button Role for the full specification.
Choosing the Right Component
- Form submissions — save, submit, reset.
- In-page actions — open a modal, toggle a panel, trigger a calculation.
- Destructive operations — delete or remove, paired with the
dangerprop. - Confirming choices — accept terms, complete a step.
Button vs. Link
Ask: "Does this take the user somewhere, or does it do something?"
- Navigates to a URL → use a Link.
- Performs an action → use a Button.
Need a link that looks like a button? Use asChild:
<Button asChild>
<a href="/settings">Go to Settings</a>
</Button>When to Use Something Else
- Inline text navigation → Link
- Stateful toggles (e.g., bookmark on/off) → toggle or icon button with
aria-pressed - Navigation menus → dedicated nav component
Variant Selection
| Scenario | Variant |
|---|---|
| Primary action ("Save", "Submit") | solid |
| Secondary action ("Cancel", "Back") | outline |
| Tertiary / inline action ("Edit", "More") | ghost |
| Destructive primary ("Delete account") | solid + danger |
| Destructive secondary ("Remove item") | outline + danger |