Badge
Displays a badge or a component that looks like a badge.
Installation
Install the following dependencies:
Set up the token layer and the StyleX compiler, if you have not already. See
Installation, and paste states.ts from the same page.
The badge's focus ring and invalid ring come from it. The badge also needs
interop.css, which sizes the icon.
Copy and paste the following code into your project.
Update the import paths to match your project setup.
Usage
Variants
Use the variant prop to change the visual style.
With icon
Set iconPosition to the side the icon is on, so the badge tightens its
padding there.
Without iconPosition the padding stays symmetric and the glyph looks inset
against the round end. StyleX has no :has(), so the badge has to be told
which side the icon is on.
Loading
Render a Spinner and set iconPosition to its
side.
Link
Pass render to change the element the badge renders.
Badges have no built-in hover styles. Add a hover through xstyle when using
render for a link or another interactive element.
Custom colors
Pass xstyle to change the background, border and text colors.
API reference
Pass render to replace a part's element or compose it with another component.
Badge
Renders a span through Base UI's
useRender, so it accepts
render alongside every span attribute.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | "default" |
iconPosition | "start" | "end" | "both" | — |
render | ReactElement | ((props, state) => ReactElement) | <span /> |
xstyle | StyleXStyles | — |
className | string | — |
xstyle is merged last, so it beats the variant. className is concatenated
with no conflict resolution. Use it for plain-CSS hooks.
Setting aria-invalid switches the border and ring to the destructive pair.
badgeStyles
The style maps behind Badge. Spread them onto any element:
Merge className from the stylex.props() result by hand. A second
className attribute beside the spread replaces it.
| Key | What it is |
|---|---|
base | Shape and type, with the shared focus ring |
variants | One namespace per variant |
iconStart | Leading-icon padding |
iconEnd | Trailing-icon padding |
base is two styles, the badge's own and the shared states.focusRing. Set a
border of your own through --carbon-border-color rather than borderColor. A
flat borderColor replaces the property with all of its conditions, so the ring loses its focus colour.
Keep the carbon-icons class. interop.css sizes icons off it, and without it
a Lucide icon keeps its own 24px.
Data attributes
| Attribute | On | Effect |
|---|---|---|
data-slot="badge" | the badge | Targets the badge from a parent |
data-variant | the badge | Reflects the variant prop, for styling from a parent |
CSS variables
| Variable | On | Effect |
|---|---|---|
--carbon-icon-size | the badge | The icon's size, read by interop.css. Defaults to 12px |
--carbon-border-color | the badge | The resting border colour the focus ring reads. outline sets it |