Buttons are interactive elements that allow the user to perform an action on the page or serve as a prominent hyperlink.
href to render it as a hyperlink — reserve this for CTAs and prominent standalone links.isIconOnly) — the icon alone with reduced side padding. Use in condensed layouts and to open menus or dropdowns. Requires icon or iconSrc.href) — renders as an anchor. Use when the Button is a navigating CTA.variant="primary" — the single most important action on the page, including CTAs and form submission.variant="secondary" — lesser actions. Multiple per page are fine.variant="subtle" — the least important action. Called "Tertiary" in design language.size="md" — the default; use in the majority of cases.size="sm" — for smaller screens and less prominent actions.icon — a Pluma icon by name, placed before the label by default. Adds visual context to the action.iconPosition="trailing" — moves that icon after the label.iconSrc — a custom image icon by URL, for icons absent from the Pluma library. Sizing matches Pluma icons; check how its color and style read against each variant's background.iconLeading / iconTrailing — icons pinned to one side. Use them together when a Button needs an icon on both sides. They render in addition to icon, never in place of it.elementBefore / elementAfter — arbitrary content such as a count badge. elementBefore sits between any leading icon and the label; elementAfter between the label and any trailing icon.isLoading) — overlays a spinner on the content and blocks interaction. Signals a background task in progress.autoLoading, default true) — shows the spinner automatically while an onClick handler's returned promise is pending. Set false to drive the spinner from isLoading alone.isDisabled) — blocks interaction and lightens the colors in every variant. Use it instead of the native disabled attribute.isDanger) — applies the critical color treatment for destructive actions and errors. Combines with any variant.isActive) — applies the active visual state programmatically.2px focus outline are built in — no props control them.Verb + object for primary actions ("Create campaign"), Delete + object for destructive, Permanently delete + object for irreversible, Cancel for cancel, Save / Save changes / Save and close for save, Upload / Upload file for uploads, and a forward-motion verb ("Next", "Continue") for progressive actions.…) when the Button opens a dialog or needs more input before the action completes. Never add one for an immediate action.children. Ember yields the default block: <PlumaButton>Label</PlumaButton>.variant="subtle". A literal variant="tertiary" also exists with different styling, so do not substitute it.isIconOnly drops the label only when an icon is actually present (icon, iconSrc, iconLeading, or iconTrailing). Give icon-only Buttons an aria-label — the custom-icon image always renders alt="", so the accessible name has to come from the label or aria-label.href is ignored when isDisabled is set: the component renders a <button> rather than a disabled link. Otherwise href renders through PlainLink as an <a>.<button type="button">. Override with as.unsafe_withSoftDeprecatedSecondaryVariant — renders secondary with tertiary styling, for the layout-refresh transition. Also settable globally through PlumaProvider's componentConfig.PlumaButton.unsafe_withMigratedButtonVariants — shifts variants down one level (secondary → tertiary styling, tertiary → subtle styling), including the default variant. Intended for after the button-variant-rename codemod (pnx @customerio/pluma-cli upgrade --codemod button-variant-rename). Supersedes unsafe_withSoftDeprecatedSecondaryVariant. Also settable through PlumaProvider.unsafe_iconColor / unsafe_iconSize override the icon's inherited color and its size-derived sizing. Use deliberately — they cause UI inconsistency.ButtonGroup (or ToggleButton) supplies defaults for variant, size, isDisabled, isLoading, unsafe_iconColor, and unsafe_iconSize; explicit props on the Button win for variant, and the group wins for size.isDanger instead of isError, isActive instead of unsafe_isActive, size="md"/size="sm" instead of "medium"/"small". unsafe_isLegacy is deprecated with no replacement; components already render in the target style.<PlumaButton @variant="primary" @icon="manage">Label</PlumaButton>. elementBefore and elementAfter are available both as args (taking a component) and as the :elementBefore / :elementAfter named blocks; the blocks take precedence.