Badge
A small label for a status, count or category.
Default Default (Ghost)
<template> <Badge variant="default">New</Badge></template>Props
| Name | Type | Default |
|---|---|---|
| variant | "default" | "success" | "warning" | "error" | "default" |
| fill | "default" | "ghost" | "default" |
| size | "sm" | "md" | "sm" |
Slots
| Name | Description |
|---|---|
| default | Badge label. |
| leftIcon | Icon before the label. Figma models this as a leftIcon boolean + fixed icon; adapted to a slot to match this codebase's existing icon-slot pattern. |
| rightIcon | Icon after the label. |
Guidelines
Do
- Use
variant="default"for a plain, non-semantic label - a tag, category, or count that doesn't represent a state. - Use
variant="success"/"warning"/"error"for a semantic feedback label (e.g. "Connected", "Pending", "Failed") - these render on this design system's ownsurface-semantic-*/stroke-semantic-*/text-semantic-*tokens, not Nuxt UI's raw color classes. - Set
fill="ghost"on any variant when the badge sits on an already-bordered or busy surface (a table row, a card list item) where a second border/fill would be visual clutter - it strips the background and border, leaving just the colored text.
- Put an icon in the
leftIcon/rightIconslot, never inline in the default slot - only those slots land inside UBadge's owninline-flex items-centerroot, so the icon gets properly centered against the label. The default slot is wrapped in a plain, non-flex<span>, so an icon placed there just sits on the text baseline instead of centered.
Don't
- Don't reach for
Badgeto show a finding's severity - useSeverityBadgeinstead, which has the real severity tokens and fixed labels built in. - Don't reach for
Badgefor a long-running or async status (a scan, a job) - useStatusBadgeinstead, which adds the dot and optional pulse those states need. - Don't expect
informationalorneutralvariants - unlikeAlert/Toast, which share this same naming vocabulary,Badgeonly hasdefault/success/warning/error.
Examples
Semantic feedback
Success, warning, and error states - each filled with a border in its own color.
Success Warning Error
<template> <Badge variant="success">Success</Badge> <Badge variant="warning">Warning</Badge> <Badge variant="error">Error</Badge></template>Icons
A leading or trailing icon alongside the label, via the leftIcon/rightIcon slots - the icon scales with the badge's sm/md size.
Connected Connected Docs Docs
<template> <Badge variant="success" size="sm"> <template #leftIcon> <UIcon name="i-lucide-check" /> </template> Connected </Badge> <Badge variant="success" size="md"> <template #leftIcon> <UIcon name="i-lucide-check" /> </template> Connected </Badge> <Badge variant="default" size="sm"> Docs <template #rightIcon> <UIcon name="i-lucide-arrow-up-right" /> </template> </Badge> <Badge variant="default" size="md"> Docs <template #rightIcon> <UIcon name="i-lucide-arrow-up-right" /> </template> </Badge></template>Dismissible
dismissible + dismissLabel + @dismiss render a fixed IconButton internally, so every removable badge shares one button treatment instead of composing IconButton by hand in #rightIcon. Click it to remove it.
main
<template> <Badge v-if="tagVisible" size="sm" dismissible dismiss-label="Remove main" @dismiss="tagVisible = false"> main </Badge></template>Related components
SeverityBadge
A fixed-label badge for a finding's severity level.
LowMediumHighCriticalInformationInvalid
<template> <SeverityBadge severity="critical" /></template>Props
| Name | Type | Default |
|---|---|---|
| severity | "low" | "medium" | "high" | "critical" | "informational" | "invalid" | "low" |
Slots
| Name | Description |
|---|---|
| leftIcon | Icon before the label. |
| rightIcon | Icon after the label. |
Guidelines
Do
- Use it anywhere a finding, vulnerability, or scan result needs a severity label - the label text is fixed per severity so it stays consistent everywhere it's used.
- Use
informationalfor context that isn't a real finding (e.g. informational scan notes), not as a stand-in for "low". - Pass content in the default slot only when the badge shows a severity-colored count or count summary (e.g.
3in a per-severity count row, or "3 critical") - the slot replaces the fixed label. Never pass the bare severity name through it; leave the slot empty and let the fixed label own that wording.
- In an app with i18n, call
provideSeverityLabels(() => ({ ... }))once at the app root with the translated labels; every SeverityBadge below it uses them. The built-in English labels are only the fallback.
Don't
- Don't use
Badgewith a manually-typed severity label instead - that duplicates styling this component already owns and risks the label text drifting (e.g. "Informational" vs "Information").
StatusBadge
A colored dot and label for showing a status, with an optional pulse for in-progress states.
Running Completed Triaging Failed Cancelled Draft
<template> <StatusBadge color="blue" :animate="true">Running</StatusBadge></template>Props
| Name | Type | Default |
|---|---|---|
| color | "blue" | "green" | "yellow" | "red" | "gray" | "orange" | "gray" |
| animate | boolean | false |
Slots
| Name | Description |
|---|---|
| default | Status label text. |
Guidelines
Do
- Use
:animate="true"only for states that are actively in progress (running, triaging) - a pulsing dot on a finished/failed state reads as broken, not busy. - Colors are named literally (
blue/green/yellow/red/gray/orange), not by semantic role - pick whichever reads correctly for the status at hand (e.g.redfor failed,orangefor cancelled).
Don't
- Don't use this for a static label or a severity level - use
BadgeorSeverityBadgeinstead. This component exists specifically for long-running/async status (scans, jobs), not general labeling.