Variants & Intents
WireKit components communicate color, severity, or brand intent through one of two prop shapes. This page is the single source of truth for which prop name and which allowed values belong to each component — useful when copy-pasting between components and you hit a "is primary valid here?" moment.
Canonical Set
Every WireKit component that exposes a color prop accepts the same six canonical values:
primary | neutral | success | warning | danger | info
The names map onto the VariantResolver::INTENTS constant in PHP (src/VariantResolver.php), and they map onto the design tokens in dist/wirekit.css:
| Value | Token | Reads as |
|---|---|---|
primary |
--color-wk-accent |
brand emphasis, the call-to-action color |
neutral |
--color-wk-bg-muted / --color-wk-text-muted |
quiet, non-emphasized |
success |
--color-wk-success |
positive outcome (saved, completed, validated) |
warning |
--color-wk-warning |
careful, reversible action ahead |
danger |
--color-wk-danger |
destructive or error state |
info |
aliased to --color-wk-accent |
informational; visual synonym of primary |
Note on
infoandprimary: WireKit uses a single brand token (--color-wk-accent) for both informational and brand-emphasis surfaces — they render identically. Use whichever name expresses your intent semantically; switching between them is purely stylistic.
Per-Component Reference
Two prop shapes are in use:
intent+surface(orthogonal: color × visual style) — used bybutton,badge.messageusesintentalone (single soft-tinted bubble surface).intentalone, withvariantstill accepted as its older name — the components in the alias matrix, such asalert,calloutandprogress. Writeintent: it is the one spelling every intent-carrying component takes.buttonandbadgedo not acceptvariantat all; see Pitfall 5.
| Component | Prop | Allowed values | Notes |
|---|---|---|---|
<x-wirekit::button> |
intent |
primary, neutral, success, warning, danger, info | Modern API. Pair with surface for visual style. |
<x-wirekit::button> |
surface |
filled, outline, soft, ghost, link | Pair with intent. |
<x-wirekit::badge> |
intent |
primary, neutral, success, warning, danger, info | Modern API. Pair with surface. |
<x-wirekit::badge> |
surface |
filled, outline, soft, ghost | Pair with intent. |
<x-wirekit::message> |
intent |
primary, neutral, success, warning, danger, info | Bubble background tint. primary and info render identically. |
<x-wirekit::alert> |
intent |
primary, neutral, success, warning, danger, info | variant is the older name for the same prop and still works. primary is a visual synonym of info; neutral is a quiet gray treatment for non-severity-bearing notices. |
<x-wirekit::callout> |
intent |
primary, neutral, success, warning, danger, info | Same set + semantics as alert, variant included. Visually denser (15% vs 10% bg tint). |
<x-wirekit::progress> |
intent |
primary, neutral, success, warning, danger, info (+ accent) |
primary is the canonical name; accent is a back-compat alias for the historical default. The same six canonical values as every other intent-carrying component — this row used to deny info and neutral, contradicting Pitfall 1 below and the component, which validates both. |
Choosing Between intent and variant
The two names are not interchangeable, and which one applies is a property of the component rather than a style preference.
button and badge take intent + surface, and never variant. Both dropped the legacy variant prop; write the intent + surface pair the old value stood for:
<x-wirekit::button intent="primary">Save</x-wirekit::button>
<x-wirekit::button intent="neutral">Cancel</x-wirekit::button>
<x-wirekit::button intent="neutral" surface="outline">Cancel</x-wirekit::button>
<x-wirekit::button intent="neutral" surface="ghost">Dismiss</x-wirekit::button>
<x-wirekit::button intent="danger">Delete</x-wirekit::button>
<x-wirekit::button surface="link">Read more</x-wirekit::button>
The pair composes better than a combined shorthand: you can change "filled to soft" without touching color, or "primary to danger" without touching surface style.
On alert, callout and progress, variant is a back-compat alias of intent — both set the same color axis, and intent wins when a caller supplies both. These components have no meaningful surface dimension (an alert is always "the alert surface", not filled-vs-outline), so there is nothing for surface to pick.
On card, hero, cta, link and tabs, variant means something else entirely — a visual mode, not a color — and is not an alias of anything. The prop naming conventions page carries the full matrix of which components mean which.
Common Pitfalls
Pitfall 1 — every component accepts the same six canonical values. <message>, <alert>, <callout>, <progress>, and the other intent-carrying components all consume primary / neutral / success / warning / danger / info. Reach for the same value name across components — you won't be surprised by a per-component enum gap.
Pitfall 2 — variant="accent" on <progress> is legacy. The canonical name is primary. accent continues to work to avoid breaking existing developer code, but new code should use primary.
Pitfall 3 — severity semantics on alert/callout. Historically, alert and callout were "severity-only" (info / success / warning / danger). The expansion to include primary and neutral adds two non-severity treatments: primary is a brand-emphasis variant of info, and neutral is a quiet gray treatment for notices that aren't carrying any severity weight. If you find yourself wanting severity="info", write intent="info" — the prop is the color axis every component shares, not a severity of its own.
Pitfall 4 — the four status names also exist as icon aliases. info, success, warning, and danger are both canonical intent values on components like <x-wirekit::badge> AND semantic icon aliases on <x-wirekit::icon>. They are intentionally paired — <x-wirekit::icon name="info"> resolves to heroicon-m-information-circle (or its sibling in the active preset), the same icon you would conventionally place inside <x-wirekit::badge intent="info">. The shared keyword is a feature, not a collision: status surfaces and their leading icons read identically across the catalog. See the icon semantic-alias reference for the full mapping.
Pitfall 5 — variant on <button> or <badge> fails silently. Neither component declares the prop, so Blade forwards it to the attribute bag and it lands in the rendered HTML as a literal variant="danger" that nothing reads — while the button keeps its default intent="primary" and renders as the brand-colored call to action. Nothing throws: the unknown-prop warning is a debug-only log, never a render-time error, so a delete button written this way ships looking like the primary action. Write intent="danger" instead.
See Also
<x-wirekit::button>—intent+surfacereference implementation<x-wirekit::badge>— same prop shape as button<x-wirekit::message>— chat bubble with intent tint<x-wirekit::alert>— intent-based notice<x-wirekit::callout>— intent-based denser notice<x-wirekit::progress>— intent-based progress fill- Design Tokens — full color-token reference
- Theming — setup guide and theme presets