Skip to main content
WireKit
Copy for LLM

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? 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::button intent="danger" surface="outline"> 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

On every other component, 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

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

  1. Reach for intent when the modifier maps to a semantic state (warn / success / danger). Draw from the shared role names above rather than inventing synonyms.
  2. Reach for surface when the modifier picks how heavily that color is applied — fill, outline, soft, ghost.
  3. Reach for variant when 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.
  4. Do not reach for tone. It exists on one component and is not the direction the vocabulary is going.
  5. Validate with WireKit::validateProp() 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.

Where this is heading

The short answer for planning 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:

Component Today v3.0.0 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
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 is already accepted on every component in the alias matrix, and surface is already accepted on the components that will grow it. Moving a call site from variant to intent right now is a no-op at runtime.