Hacktron Design System

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
defaultBadge label.
leftIconIcon 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.
rightIconIcon 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 own surface-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/rightIcon slot, never inline in the default slot - only those slots land inside UBadge's own inline-flex items-center root, 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 Badge to show a finding's severity - use SeverityBadge instead, which has the real severity tokens and fixed labels built in.
  • Don't reach for Badge for a long-running or async status (a scan, a job) - use StatusBadge instead, which adds the dot and optional pulse those states need.
  • Don't expect informational or neutral variants - unlike Alert/Toast, which share this same naming vocabulary, Badge only has default/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>

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
leftIconIcon before the label.
rightIconIcon 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 informational for 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. 3 in 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 Badge with 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"
animatebooleanfalse

Slots

Name Description
defaultStatus 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. red for failed, orange for cancelled).
Don't
  • Don't use this for a static label or a severity level - use Badge or SeverityBadge instead. This component exists specifically for long-running/async status (scans, jobs), not general labeling.