Badge
A compact label, tag, or status chip: three fills across six semantic tones and twelve named hues, optionally removable.
Live demo
Badge labels, tags, counts, and statuses inline. Fill treatment (variant) and color (tone) are independent axes: each of the three fills (solid, soft, outline) can carry any of the six semantic tones (accent, neutral, danger, success, warn, info) or any of the twelve named hues (red … black).
It adds a leading status dot (which can pulse to read as live), a tabular count affordance, and a removable form whose × is a real focusable <button> that emits a remove event. That's the removable tag you build a filter row or token input from. A standalone .xtyle-dot indicator covers the bare-dot case. Status tones (success, warn, danger, info) emit a screen-reader-only tone word so meaning never rides on color alone.
When to use
How this component composes with the rest of the set.
Props
9 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Variants
solid
Filled with the tone color. The highest-emphasis treatment.
soft
A soft tone-tinted background with tone-colored text. The default.
outline
Transparent fill with a tone-colored border and text.
Sizes
sm
Compact.
md
Default.
lg
Large.
States
pulse
With pulse and a dot, the dot breathes on a soft opacity loop at Progress's own two speeds (slow 1.8s, fast 0.9s); held still under prefers-reduced-motion.
remove-hover
Pointer over the dismiss button. Its overlay paints the hover tint.
remove-active
Dismiss button pressed. Its overlay paints the press tint.
remove-focus-visible
Keyboard focus on the dismiss button: a token ring plus a transparent outline that becomes real in forced-colors mode.
Anatomy
The named parts that make up the component, with their selectors.
badge
The chip root carrying the variant, tone, and size classes.
dot
The optional leading status dot, painted in the badge's current text color; breathes on a soft opacity loop when pulse is set.
label
The text content wrapper.
count
A tabular-numeric count affordance rendered after the label.
remove
A real <button> dismiss control with an accessible name, its own focus ring, and a state overlay.
indicator
A standalone dot indicator independent of any chip, tonable and sizable on its own. It reads as live three ways, composable: --pulse-slow / --pulse-fast breathe its opacity, --ping radiates an expanding ring (a stronger, attention-grabbing status light), and --glow adds a soft halo. Its color comes from the tone class, or from an inline --dot-color custom property for an arbitrary per-state color the tone set can't name.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent
--accent-2
--accent-2-bg
--accent-2-fg
--accent-2-text
--accent-3
--accent-3-bg
--accent-3-fg
--accent-3-text
--accent-4
--accent-4-bg
--accent-4-fg
--accent-4-text
--accent-bg
--accent-fg
--accent-text
--black
--black-bg
--black-fg
--black-text
--blue
--blue-bg
--blue-fg
--blue-text
--border-normal
--border-thick
--border-thin
--brown
--brown-bg
--brown-fg
--brown-text
--cyan
--cyan-bg
--cyan-fg
--cyan-text
--danger
--danger-bg
--danger-fg
--danger-text
--duration-fast
--ease-standard
--font-sans
--gray
--gray-bg
--gray-fg
--gray-text
--green
--green-bg
--green-fg
--green-text
--info
--info-bg
--info-fg
--info-text
--leading-tight
--neutral
--neutral-bg
--neutral-fg
--neutral-text
--orange
--orange-bg
--orange-fg
--orange-text
--pink
--pink-bg
--pink-fg
--pink-text
--purple
--purple-bg
--purple-fg
--purple-text
--radius-full
--red
--red-bg
--red-fg
--red-text
--ring
--space-0
--space-1
--space-2
--space-3
--state-hover
--state-press
--success
--success-bg
--success-fg
--success-text
--text-sm
--text-xs
--warn
--warn-bg
--warn-fg
--warn-text
--weight-medium
--weight-semibold
--white
--white-bg
--white-fg
--white-text
--yellow
--yellow-bg
--yellow-fg
--yellow-text
Slots
The badge label.
Accessibility
Code
Fills, tones, and affordances
The three fills cross all tones and hues; dot, count, and the removable form layer on top, with a standalone dot for the bare case.
<xtyle-badge variant="soft" tone="accent">New</xtyle-badge>
<xtyle-badge variant="solid" tone="success" dot>Online</xtyle-badge>
<xtyle-badge variant="outline" tone="danger">Failed</xtyle-badge>
<xtyle-badge tone="info" count="12">Notifications</xtyle-badge>
<xtyle-badge variant="soft" tone="purple" removable remove-label="Remove tag">design</xtyle-badge>
<span class="xtyle-dot xtyle-dot--success" role="img" aria-label="Online"></span>
<script lang="ts">
import { Badge } from "@xtyle/svelte";
</script>
<Badge variant="soft" tone="accent">New</Badge>
<Badge variant="solid" tone="success" dot>Online</Badge>
<Badge variant="outline" tone="danger">Failed</Badge>
<Badge tone="info" count={12}>Notifications</Badge>
<Badge variant="soft" tone="purple" removable removeLabel="Remove tag" onremove={() => drop("design")}>design</Badge>
---
import { Badge } from "@xtyle/astro";
---
<Badge variant="soft" tone="accent">New</Badge>
<Badge variant="solid" tone="success" dot>Online</Badge>
<Badge variant="outline" tone="danger">Failed</Badge>
<Badge tone="info" count={12}>Notifications</Badge>
<Badge variant="soft" tone="purple" removable removeLabel="Remove tag">design</Badge>
<span class="xtyle-dot xtyle-dot--success" role="img" aria-label="Online"></span>
Live status
pulse breathes the dot so a chip reads as live, streaming, or connected, at Progress's two speeds (slow and fast); it holds still under reduced-motion.
<xtyle-badge variant="soft" tone="success" dot pulse>Live</xtyle-badge>
<xtyle-badge variant="soft" tone="danger" dot pulse="fast">Alert</xtyle-badge>
<script lang="ts">
import { Badge } from "@xtyle/svelte";
</script>
<Badge variant="soft" tone="success" dot pulse>Live</Badge>
<Badge variant="soft" tone="danger" dot pulse="fast">Alert</Badge>
---
import { Badge } from "@xtyle/astro";
---
<Badge variant="soft" tone="success" dot pulse>Live</Badge>
<Badge variant="soft" tone="danger" dot pulse="fast">Alert</Badge>
Standalone status dot: breathe, ping, glow, custom color
The chip-less .xtyle-dot reads as live three composable ways (opacity breathe, an expanding --ping ring, and a --glow halo) and takes an arbitrary color through the inline --dot-color escape hatch when the tone set can't name it.
<!-- Tone-colored breathe (opacity loop) -->
<span class="xtyle-dot xtyle-dot--success xtyle-dot--pulse-slow" role="img" aria-label="Connected"></span>
<!-- Expanding ping ring for a live status light -->
<span class="xtyle-dot xtyle-dot--danger xtyle-dot--ping" role="img" aria-label="Recording"></span>
<!-- Ping + glow, larger -->
<span class="xtyle-dot xtyle-dot--success xtyle-dot--ping xtyle-dot--glow xtyle-dot--lg" role="img" aria-label="Live"></span>
<!-- Arbitrary color past the tone classes, via the --dot-color escape hatch -->
<span class="xtyle-dot xtyle-dot--glow" style="--dot-color: var(--purple)" role="img" aria-label="Queued"></span>