Examples
Variant examples
All eight variants: primary, secondary, tertiary, danger, warning, link, plain (icon-only), control.
Disabled buttons
disabled=true renders the HTML disabled attribute — fully
non-interactive, removed from the tab order. For an aria-disabled variant that stays focusable, see below.
Block level
block=true stretches the button to fill its container width. Common inside modal footers
and login forms.
Progress indicators
isLoading=true adds pf-m-progress /
pf-m-in-progress and renders the PF v6 spinner inside a
__progress span. Pair with spinnerLabel for screen readers.
Links as buttons
Pass href="..." to render an <a> with button styling.
Combine with icon + iconPosition="end" for the common "open
external" pattern.
Inline link as span
component="span" variant="link" inline=true renders the styled element as a
<span> — useful inside running prose where
<a> or <button> would be invalid (e.g. already
inside another anchor).
Inline link as a span renders the button-styled element directly inside running text without breaking the line:
. Use this when you can't nest a real
<a> or <button> (e.g. inside another anchor)
but still want the link styling.
Custom component
component="span" / "div" / etc. replaces the host element.
Use sparingly — the host element loses its native button semantics (no Enter/Space activation, no implicit role)
unless you reintroduce them yourself.
Aria-disabled examples
ariaDisabled=true communicates the disabled state to assistive tech without setting the
HTML disabled attribute — the button stays focusable, so tooltips and pointer handlers
still work.
Button with count
Pass count to render a PF v6 badge on the trailing edge of the button.
countRead=true switches the badge to the muted (read) treatment.
Plain with no padding
hasNoPadding=true strips the inline padding on
variant="plain" buttons. Useful when a plain icon button sits inside another inline
element and you want the icon flush.
asNoPadding() — the icon sits flush.
Stateful
variant="stateful" + stateful=true +
state="read"|"unread"|"attention" renders a notification-style icon button that reflects
the current state via PF's stateful tokens.
Circle buttons
circle=true renders a circular icon-only button (pf-m-circle). Combine it with any variant — including the stateful read / unread / attention states. Always pass
ariaLabel.
Button types
type="submit" / "reset" set the form-control behaviour of a
<button>; the default is "button" (no implicit form
action).
Progress button (login demo)
A submit button that indicates progress while an HTMX request is in flight, then swaps in a success state. The
endpoint is a server-side stub — credentials aren't checked and the read-only inputs can't be edited.
HTMX makes the request; Alpine toggles pf-m-in-progress while it runs.
Favorite
favorite=true turns the button into a star toggle.
favorited=true switches to the filled state — PF v6 cross-fades the outline / filled star
automatically via the two __icon-favorite /
__icon-favorited sub-spans.
Settings
settings=true renders a gear icon with PF v6's rotate-on-hover transition. Always pair
with ariaLabel since the button is icon-only.
Hamburger
hamburger=true renders the three-line menu icon. Add
hamburgerVariant="expand"|"collapse" to morph between the bars and an arrow. Wire to a
real toggle via Alpine.js to drive ariaExpanded.
Documentation
Button props
Parameters accepted by
{#include components/actions/button ... /}. Model mode: pass
btn=<Button> built in Java instead — the Java tab on each example shows the
builder. The content slot wraps button text in pf-v6-c-button__text; skip the slot for
icon-only buttons (favorite / settings / hamburger).
| Name | Type | Default | Description |
|---|---|---|---|
* id
|
String | — | DOM id. |
variant
|
"primary" | "secondary" | "tertiary" | "danger" | "warning" | "link" | "plain" | "control" |
"stateful"
|
"primary"
|
Visual treatment. Not applied when hamburger /
favorite / settings is set — those imply
pf-m-plain.
|
size
|
"sm" | "lg"
|
default |
Compact (sm) or call-to-action (lg) sizing. Omit
for the standard size.
|
circle
|
boolean |
false
|
Renders a circular icon-only button (pf-m-circle). Pair with
icon + ariaLabel.
|
block
|
boolean |
false
|
Stretches the button to fill its container width. |
inline
|
boolean |
false
|
Strips block-level padding (only meaningful for variant="link").
|
disabled / ariaDisabled
|
boolean |
false
|
disabled sets the HTML disabled attribute
(non-focusable, no events). ariaDisabled sets
aria-disabled only (still focusable, useful with tooltips).
|
icon / iconPosition
|
String "set:slug" / "start" | "end"
|
— / "start"
|
Renders the icon inside pf-v6-c-button__icon with
pf-m-start or pf-m-end when the button also has
text. Omit content to make an icon-only button (pair with ariaLabel) — the
spacing modifier is omitted, matching PF core.
|
isLoading / spinnerLabel
|
boolean / String |
false / —
|
Adds pf-m-progress + pf-m-in-progress and renders
the PF v6 spinner inside __progress.
spinnerLabel becomes the spinner's
aria-label.
|
count / countRead
|
Integer / boolean |
— / false
|
Renders a PF v6 badge on the trailing edge with the count value.
countRead=true switches to the muted (read) treatment.
|
component / href /
type
|
Tag string / URL / "submit" | "reset"
|
"button" / — / "button"
|
Element override. href implies <a>;
component forces a specific tag. type applies to
<button> only.
|
ariaLabel / ariaExpanded
|
String / "true" | "false"
|
— |
Accessibility hooks. Required for icon-only buttons. ariaExpanded drives the
open/closed indication on hamburger and disclosure buttons.
|
clicked / hasNoPadding
|
boolean |
false
|
clicked applies active-state styling.
hasNoPadding strips the plain variant's inline padding.
|
stateful / state
|
boolean / "read" | "unread" | "attention"
|
— |
Stateful button for notification-style toggles. Pair variant="stateful" with
stateful=true and a state value.
|
favorite / favorited
|
boolean |
false
|
Star-toggle button. Implies pf-m-plain.
favorited=true shows the filled state.
|
settings
|
boolean |
false
|
Gear-icon button with rotate-on-hover. Implies pf-m-plain.
|
hamburger / hamburgerVariant
|
boolean / "expand" | "collapse"
|
false / —
|
Three-line menu button. Implies pf-m-plain.
hamburgerVariant morphs the icon between bars and an arrow for nav
drawers.
|
content (slot)
|
Qute insert | — |
Button text. Wrapped in pf-v6-c-button__text. Omit for icon-only
buttons.
|
Divergence from PF React. We skip ouiaId /
ouiaSafe (testing tooling we don't use),
className (React-specific), inoperableEvents (managed at
the consumer level here), tabIndex, spinnerAriaLabelledBy,
and spinnerAriaValueText (the latter two are subsumed by the spinner component's own
props if you compose by hand). PF's countOptions object is flattened into
count + countRead.
Usage
Variant precedence. The specialised flags (favorite,
settings, hamburger) imply their own plain treatment and
override variant. Don't set both — pick one.
Disabled vs. aria-disabled. Use disabled=true for buttons that are
genuinely non-interactive (form submit while the form is invalid, action that requires another step first). Use
ariaDisabled=true when you still want pointer / focus events to fire — e.g. when a
tooltip needs to explain why the button is unavailable.
Icon-only buttons need a label. Plain / favorite / settings / hamburger buttons don't have visible
text. PF v6's HTML smoke tests assert each button has an accessible name — always pass
ariaLabel (or wire
ariaLabelledBy
via the consumer template).
Component override caveats. Setting component="span" (or another
non-interactive tag) strips the native button semantics — no Enter/Space activation, no role, no tab-order. Use only
when the host element constrains your choice (inline link inside an anchor, span inside a list). Re-add
role="button" and keyboard handlers yourself if you need them.