Prop Naming Conventions
WireKit components carry several prop names for what looks at first glance like the same concept — "which color, which shape, how much emphasis?". This page is the contract behind each name, so that a developer reading API tables across the catalog can tell them apart, and so that the answer to "which prop do I reach for here?" is a lookup rather than a guess.
One thing to know before the table: variant does not mean the same thing on every component. On most it picks a visual treatment. On a handful it is an older spelling of the color axis and is kept working on purpose. The alias matrix below names every component in that second group.
The four families
| Prop | Semantic | Values | Examples |
|---|---|---|---|
intent |
Semantic color identity. What is this thing FOR — is it the primary action, a warning, a success? | A shared vocabulary, applied per component — see below | button, badge, alert, callout, stat |
surface |
How that color is applied. Same intent, different weight of ink: solid fill, outline, soft tint, ghost. | filled, outline, soft, ghost, link |
button, badge, theme-controller |
variant |
Visual mode. Same content, different surface treatment or layout register. | Family-specific (outlined / elevated / flat on card; default / dark / accent / muted on marketing surfaces) |
card, hero, cta, link, tabs |
tone |
Qualitative emphasis. How loud should this read? On feature it is the older name for the color axis rather than a family of its own. |
Per component | feature |
The Examples column is a handful of representative components, not the catalog — many more carry each prop. The API table on a component's own page is the authority for that component.
intent and surface are the two axes that compose: intent picks the color family, surface picks how much of it lands on the element. <x-wirekit:: is a destructive action rendered as an outline rather than a solid fill — two independent choices, not seven pre-blended ones.
The alias matrix
On these components variant is a back-compat alias of intent. Both set the same axis, both validate against the same value set, and intent wins when a caller supplies both:
| Component | variant sets |
Prefer |
|---|---|---|
alert |
the color axis | intent |
callout |
the color axis | intent |
text |
the color axis | intent |
progress |
the color axis | intent |
progress.circle |
the color axis | intent |
reading-progress |
the color axis | intent |
timeline.item |
the color axis | intent |
Two more components carry the same arrangement, each on its own axis and under a different older name:
| Component | Older name | Sets | Prefer |
|---|---|---|---|
card |
variant |
the surface axis | surface |
feature |
tone |
the color axis | intent |
card takes surface="outline", "elevated" or "flat" — outline spelled the way button spells it — and keeps accepting variant="outlined" with its trailing d. feature takes the shared role names, where primary resolves to the chip treatment it calls accent and info is a tint of its own, and keeps accepting tone. On both, the canonical name wins when a caller supplies both.
On every component not named above, variant is the visual-mode family from the table above and is not an alias of anything.
Why the alias exists: intent is what button and badge call this axis, so it is what a developer moving between components reaches for. Adding it to these components without breaking the code already written meant accepting both. Nothing about it is deprecated in v2 — see Where this is heading for the v3 position.
The shared vocabulary is a vocabulary, not one fixed enum
intent draws from a shared set of role names — primary, neutral, info, success, warning, danger, plus accent on the components whose design calls for it. Which of those a given component accepts is that component's own decision, and the values are validated per component:
| Component | Accepts |
|---|---|
button |
primary, neutral, info, success, warning, danger |
badge, stat |
the same, plus accent |
alert, callout |
primary, neutral, info, success, warning, danger |
text |
default, muted, subtle, accent, success, warning, danger |
feature |
accent, neutral, soft, success, warning, danger — plus primary, which resolves to accent, and info, a tint of its own |
feature takes intent, so both halves of the migration line up — intent="primary" and
tone="accent" are the same call, written in two vocabularies — and tone keeps working for the
whole of v2.
text is the instructive one. Its color axis is a typographic scale rather than a severity set, so it has no primary — and an intent spelling it does not carry fails validation rather than quietly rendering the default. Loud beats a silent fallback: a heading that came out in the wrong color with no error is the failure nobody notices.
The practical consequence: copying intent="primary" from a button onto a text is not a safe move, and neither is a blanket find-and-replace across a codebase. Check the component's own API table.
When you are authoring a component
- Reach for
intentwhen the modifier maps to a semantic state (warn / success / danger). Draw from the shared role names above rather than inventing synonyms. - Reach for
surfacewhen the modifier picks how heavily that color is applied — fill, outline, soft, ghost. - Reach for
variantwhen the modifier picks a visual mode that is neither of those: a card that is outlined instead of elevated, a hero that renders dark instead of default. - Do not reach for
tone. It exists on one component and is not the direction the vocabulary is going. - Validate with
WireKit::so an unknown value raises in debug and falls back to the first allowed value in production. See Authoring Custom Components → Prop validation for the call shape.validateProp()
Where this is heading
variant and tone are supported for the whole of v2 and will not be renamed in any v2 release. The unification lands in v3.0.0, which has no fixed date. If you are writing new code today, write intent and surface — those two names survive the transition unchanged.
v3.0.0 reduces the modifier vocabulary to two canonical axes: intent for the color role, surface for the surface treatment. variant and tone are the names that go.
The mapping is settled per component, and the two kinds of change are worth separating, because only one of them is mechanical:
Both columns work today — the canonical name is accepted on every component below, and v3.0.0 is when the older one goes rather than when the newer one arrives.
| Component | Older spelling | Canonical spelling | Kind of change |
|---|---|---|---|
| every component in the alias matrix | variant="…" |
intent="…" |
prop rename, value unchanged |
card |
variant="outlined" |
surface="outline" |
prop rename and value rename |
card |
variant="elevated" / "flat" |
surface="elevated" / "flat" |
prop rename, value unchanged |
feature |
tone="accent" |
intent="primary" |
prop rename and value rename |
feature |
tone="soft" |
intent="info" |
prop rename and value rename; the same chip until you give info a color of its own |
feature |
tone="success" / "warning" / "danger" |
intent="…" |
prop rename, value unchanged |
Every row in the alias matrix is in the first group: the value you already wrote is the value intent takes, because both spellings already resolve into one validated set. Renaming the prop on those components changes nothing about what renders.
The rows that also rename a value are the ones a find-and-replace gets wrong, and they are named above so the rewrite can be done per component rather than in one sweep.
Preparing early costs nothing and is safe today: intent and surface are accepted on every component in the tables above, feature and card included. Moving a call site from variant to intent, or from tone to intent, is a no-op at runtime (for tone="soft", as long as info keeps the accent's color); moving card from variant="outlined" to surface="outline" is the one pair that also changes the value, and both spellings resolve to the same treatment.
Finding your own call sites
You do not have to read the tables above against your templates by hand:
php artisan wirekit:doctor:props
It reports every prop written in the older of two spellings and names the canonical one, file by file. The report is advisory: by default it does not change the exit code, because both spellings are supported API. Once your own tree has converted, --fail-on-legacy-axis makes a relapse a failure. Full flags: CLI Reference.
The pairs it knows are read out of the component templates themselves rather than kept as a list, so a component that gains its canonical spelling in a later release is covered by the same command on the day it ships.