Componentsv2.189.1
Iconsv1.19.0
MCPv0.8.62
Tokensv0.34.3

Buttons are interactive elements that allow the user to perform an action on the page or serve as a prominent hyperlink.

Importing

You can import the Button component via:

import { Button } from '@customerio/pluma-components/react';

Variants

Primary

Use a primary button as a CTA for the most important action on a page. Ideally, there should be at most only one primary button on any given page.

Loading editor

Secondary

A secondary button can be used for any action less important than "primary". There can be multiple secondary buttons on a page. This is the default, if no variant is provided.

Loading editor

Tertiary

A tertiary button can also be used for "secondary" actions, but with less visual weight attached to it.

Loading editor

Subtle

A subtle button is another low-priority button type, but without a border, to make it even less prominent than the "tertiary" or "secondary" styles.

Loading editor

The Button component accepts a href prop, which makes it render an anchor element with the button component's styles. This link will behave like the Link component. This means:

  • Button will use the provider's linkComponent (or an a tag for external links)
  • Button will also accept PlainLink props, like isExternal or replace
Loading editor

For buttons that render just like a link (i.e. renders inline and doesn't include paddings), see the Link component.

Danger states

All button variations support an danger state via the isDanger argument. This should be used for "dangerous" actions, like deleting a model.

Note: isError is the deprecated name for this argument.

Loading editor

Loading editor

Loading editor

Loading editor

Size

A button can be medium (default) or small:

Loading editor

Loading editor

Icons

A button will render an icon if an icon name is passed in as the icon argument:

Loading editor

Icon position

The icon can be positioned on either side with the iconPosition argument, which can be either 'leading' or 'trailing'. 'leading' is the default, if no argument is provided.

Loading editor

Loading editor

Icon only button

A button can be rendered with just an icon by setting the isIconOnly argument to true. This will stop the button from rendering the text content, and adjust the paddings so it looks balanced:

Loading editor

Custom icons

If you need to use a custom icon that isn't part of the Pluma Icon set, you can use the iconSrc prop to provide a URL to an image. The image will be automatically sized to match the button's icon size:

Loading editor

Custom image icons support the same positioning options as standard icons:

Loading editor

Loading editor

Loading editor

When both icon and iconSrc are provided, iconSrc takes precedence. If iconSrc is an empty string, the component will fall back to using the icon prop.

Disabled buttons

Whenever possible, we prefer using native HTML attributes over custom component arguments. In this component's case, there is an exception for the disabled attribute.

Use the isDisabled argument instead of the native disabled attribute. Rather than setting the native disabled attribute, the Button renders aria-disabled="true" and blocks click events. This is deliberate: a natively disabled element is removed from the accessibility tree and the tab order, so screen readers skip it and it can't be focused — which breaks tooltips and other affordances that explain why the button is disabled. Using aria-disabled keeps the button focusable and announced (as disabled) while still preventing interaction.

It also works around a second limitation: the disabled attribute isn't valid on all HTML elements, so we can't rely on the browser to universally render the disabled style or block clicks — important when the Button renders as a link (for example, a routing-library link we want to disable).

Loading editor

Loading states

Buttons are often tied to some sort of asynchronous task like saving data to the server, polling for updates, etc. In those cases, it's a good idea to signal to the user that the UI is not frozen and something is happening behind the scenes.

To show a spinner during an asynchronous action, pass the isLoading argument to a Button. The original button text will be retained so that the button doesn't change shape. Additionally, the button will be disabled so that the user can't click the button again.

Loading editor

Because this scenario is so common, you have the option to pass a function that returns a promise to the onClick argument. This will automatically show the spinner while the promise is running. If you want to pass a promise to onClick, but don't want the spinner to display, you can set the autoLoading argument to false.

Loading editor

API

If true, the button will automatically show the spinner when the onClick function is called and it returns a promise. If false, the spinner will only show if the isLoading prop is set to true. By default, this is true.

If provided, the component will render as a link instead

The name of an icon (from Pluma Icons) to render in the button

Default:leading

Which side of the text the icon should be rendered on. leading renders the icon before the text, trailing renders it after

The source URL of a custom image icon to render in the button. When provided, this will be rendered using the Image component with icon sizing. Use v2 sizing (icon-v2-sm, icon-v2-md, icon-v2-lg, icon-v2-xl) for new implementations. The image will always have alt="" as it is purely decorative - meaning comes from button text or aria-label.

Whether to make the button in the active state

Whether the button should be rendered in an danger state

Disables the button. Use this instead of the native disabled prop, to make sure non-button elements (when used with as) get the correct styles

Deprecated: Use isDanger instead.

When this flag is true, an a tag will be used instead of the provider's linkComponent, even if it exists. Additionally, target="_blank" rel="noopener noreferrer" will be added automatically

When this is set to true, the button won't render any text, and will reduce its side paddings

Shows a spinner in the button overlaid on top of the button's content. The button will act as if disabled while in the loading state.

If provided, the component will render as a button and call this function when clicked. If the function returns a promise, the button will show a spinner while the promise is running. If autoLoading is false, the spinner will not automatically show.

This is passed into the provider's linkComponent. It can be used by the link component implementation to handle replaceState instead of pushState

Default:md

The size of the button. medium and small are deprecated, use md and sm instead.

Change the color of the icon. By default, the icon inherits the button's text color. Use with care, as it can cause inconsistencies in the UI.

Overrides the icon size used within the button. Should only be used deliberately, as it can cause inconsistencies in the UI. For example, this is used in Pagination to increase the icon size.

Whether to make the button look "active", i.e. apply its hover state.

Legacy styling flag for backwards compatibility

Whether to render the button variants as if the upcoming major release that removes the secondary variant has already shipped.

Intended for use after running the button-variant-rename codemod (`pnx

Whether to render the button variants with the secondary variant removed. secondary will render as tertiary. In a later release, button variants will be reduced to only primary, secondary, and tertiary:

  • the current secondary variant will be removed
  • the current tertiary will be renamed to secondary
  • the current subtle will be renamed to tertiary This flag allows us to make the buttons look like the target state for the upcoming layout refresh.

Default:secondary

The visual style variant of the button.

This allows turning off the automatic addition of target="_blank" rel="noopener noreferrer". This can be used for links to other protocols like mailto: