The PlainButton is a foundational component with minimal styling used to build other button components in Pluma.

PlainButton

Usage

  • Use PlainButton for an interactive action that has styling requirements Button cannot express — gradient borders, custom backgrounds, animations, or other bespoke treatments.
  • Use Button instead when the element should be visually recognizable as a button, such as submitting a form, opening a dialog, or a CTA.
  • Use PlainLink instead for a custom hyperlink that does not need button features like loading states, and Link for a fully-styled hyperlink.
  • Never reproduce default Button styling with a PlainButton — use Button.
  • PlainButton is an unstyled primitive that ships no visual styling. Apply layout and appearance through Box props (display, alignItems, px, py, cursor) or custom styles.

Types

  • Regular — renders a <button> element. Use for actions that don't navigate away from the current page. Pair with onClick.
  • Link (href) — renders an anchor element. Use for navigation. Set isExternal so external URLs receive safe attributes automatically.

Behaviors

  • Base — the default rendering when no interaction is detected.
  • Loading (isLoading) — communicates that a background task is in progress and blocks interaction.
  • Disabled (isDisabled) — blocks interaction. Styling stays close to the base state because PlainButton is unstyled.
  • Auto-loading (autoLoading, default true) — enters the loading state automatically while a promise returned from onClick is pending. Set false to drive loading from isLoading alone.

Content

  • Write labels that clearly describe the action or destination in 1–3 words.
  • Pair an icon with a descriptive text label.
  • Never use a vague label like "Click" that doesn't explain the action.
  • Follow the Button component's content guidelines for casing, verb choice, and label patterns.

Implementation Notes

  • Extends Box — all Box sprinkle props (spacing, layout, color, border) are available directly on the component.
  • Loading renders no spinner. PlainButton only adds the plainButtonIsLoading class (pluma-c-plain-button-is-loading) and blocks clicks; style that class — exported from plain-button.style-exports.ts as classNames.plainButtonIsLoading — to draw a loading indicator.
  • Content access to state — React: children accepts a render function receiving { isLoading, isDisabled }. Ember: the default block yields { isLoading, isDisabled }.
  • Disabled uses aria-disabled, not the native disabled attribute. When as is a custom component, isDisabled is also forwarded to it so it can suppress its own interactions.
  • href is ignored while isDisabled is set — the component renders a <button> instead of a link. Otherwise href renders through PlainLink.
  • Default element is <button type="button">. Override with as; the component is polymorphic and retains PlainButton behavior.
  • withSafeExternalAttributes={false} suppresses the automatic target="_blank" rel="noopener noreferrer" for protocols like mailto: and tel:.
  • replace is passed to the provider's link component to trigger replaceState instead of pushState.
  • Ember invocation: <PlumaPlainButton @onClick={{this.handleClick}} @isLoading={{this.isLoading}}> with @-prefixed args.

On this page