Button
Triggers actions and navigations. Five hierarchies, three sizes, five states, icon-only, file upload, and loading variants.
{ Button } from "@pepulux/ui"Hierarchy — Primary / Secondary / Tertiary / Link color / Link gray
Destructive variant
Sizes — sm / md / lg
States — Default / Disabled / Loading (per hierarchy)
Buttons with icons — leftIcon / rightIcon
Icon button — Icon only=True
Loading state — toggle to see transition
falseFile upload button
As link — asChild + anchor
Full width
Destructive — Primary / Secondary / Tertiary / Link
Figma Buttons/Button destructive carries the same hierarchy in red.
Icon only, Loading text and 2xl size
Social button — Theme: Gray / Color / Brand
Figma Buttons/Social button: Social × Theme × Supporting text × Size. supportingText=false renders the icon-only square.
Social button group and app store badges
Figma Buttons/Social button group (Style: Buttons | Icons) and Mobile app store badge (Store × Style).
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "primary" | "secondary" | "tertiary" | "link-color" | "link-gray" | "destructive" | "destructive-secondary" | "destructive-tertiary" | "destructive-link" | "ghost" | "primary" | Figma Hierarchy — Primary | Secondary | Tertiary | Link color | Link gray, plus the red Destructive versions |
| size | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "icon" | "md" | Figma Size — sm 36px | md 40px | lg 44px | xl 48px | 2xl 56px |
| loading | boolean | false | Figma State=Loading — replaces content with spinner, disables interaction |
| disabled | boolean | false | Figma State=Disabled — dims and blocks clicks |
| iconOnly | boolean | false | Figma Icon only — square button; pass the icon as leftIcon and an aria-label |
| loadingText | boolean | true | Figma Loading text — keep the label beside the spinner while loading |
| leftIcon | ReactNode | — | Icon before label. Pass alone (no children) for Icon only=True |
| rightIcon | ReactNode | — | Icon after label |
| asChild | boolean | false | Renders as child via Radix Slot — use to wrap <a>, <label>, etc. |
| className | string | — | Extra Tailwind classes — e.g. w-full for full-width |
Notes and documentation
Space for notes, documentation, and best practices for using these components.
Buttons should look like buttons
A button is an interactive element that results in an action described in it. They’re one of the most essential components in modern UI design, so it’s important to get these right in your designs.
The most important rule while designing a button is that it should look like a button. It should be obvious.
Users are familiar with what buttons look like and how they behave. The more a button “looks like” a button, the easier it is to quickly and subconsciously discover. This is why rectangles or rounded rectangles are always a safe choice:
As soon as you start changing things too much, buttons lose their actionable qualities and users have to actively search for the action:
Don’t forget hierarchy
When there are more than one action on a page, it’s important to arrange them in a clear hierarchy. Each action on a page sits somewhere on a hierarchy of importance.
Most components and pages have just one “primary” action. This is the main action the user is likely to take (or that the designer wants them to take). Other actions are “secondary”. There may be more than one secondary actions on a page. As a general rule, it’s good to differentiate these and arrange them in a consistent hierarchy if possible. You may even need a third “tertiary” or even fourth “quaternary” action.
The style of the button is primarily used to differentiate more important actions from less important ones—primary actions should be the default option and the most obvious:
Without a clear hierarchy, both visually and structurally, there is no visual cue and the user is forced to read and more carefully consider what each action does. This creates friction and for a frustrating experience:
Destructive actions
There’s a common notion that all “negative” or “destructive” actions need to be a big red button. In most cases, this is not entirely necessary and can make designs look and feel busy:
Unsaved changes
Do you want to save or discard changes?
In most cases, a secondary button will do the trick:
Unsaved changes
Do you want to save or discard changes?
That being said, if a particular destructive action is the primary action, it is usually a good idea to flag this visually with a “destructive” variant of a button. This makes it clear to the user that they are about to take a highly consequential action.
Delete blog post
Are you sure you want to delete this post? You will lose any edits you’ve made and this action cannot be undone.