Badge

A small label used to highlight status, counts, or metadata associated with an element.

Playground

Event status

Awaiting response

Supply Chain Sync

2:30 PM - 3:00 PM

vue
<script setup>
import { Badge } from 'frappe-ui'
</script>

<template>
  <div class="w-96 rounded-r-md border-l-2 border-outline-gray-3 px-3 py-2 transition-colors hover:bg-surface-gray-1">
    <Badge theme="red" size="md">
      <template #prefix>
        <span class="lucide-mail" aria-hidden="true" />
      </template>
      Awaiting response
    </Badge>
    <p class="mt-2 text-base-medium leading-relaxed text-ink-gray-8">Supply Chain Sync</p>
    <p class="text-sm leading-relaxed text-ink-gray-6">2:30 PM - 3:00 PM</p>
  </div>
</template>

Call metadata

Outbound Call

May 16, Friday
32:48
Listen
Note
vue
<script setup>
import { Badge } from 'frappe-ui'
</script>

<template>
  <div class="w-[28rem]">
    <p class="mb-2 text-base-medium text-ink-gray-8">Outbound Call</p>
    <div class="flex flex-wrap items-center gap-1.5">
      <Badge>
        <template #prefix>
          <span class="lucide-calendar" aria-hidden="true" />
        </template>
        May 16, Friday
      </Badge>
      <Badge>
        <template #prefix>
          <span class="lucide-timer" aria-hidden="true" />
        </template>
        32:48
      </Badge>
      <Badge>
        <template #prefix>
          <span class="lucide-play" aria-hidden="true" />
        </template>
        Listen
      </Badge>
      <Badge>
        <template #prefix>
          <span class="lucide-sticky-note" aria-hidden="true" />
        </template>
        Note
      </Badge>
    </div>
  </div>
</template>

List status

Lead pipeline

5 leads
CompanyOwnerStatusValue
A
Acme Corp
Jane Cooper
Qualified
$24.5k
G
Globex
Sammy Well
In Progress
$18.2k
I
Initech
Brian Robinson
On Hold
$9.8k
S
Soylent
Matt Clinton
Lost
$4.1k
U
Umbrella
Jane Cooper
New
$12.0k
vue
<script setup>
import { Badge } from 'frappe-ui'

const leads = [
  {
    name: 'Acme Corp',
    owner: 'Jane Cooper',
    status: 'Qualified',
    theme: 'green',
    dotClass: 'bg-surface-green-7',
    value: '$24.5k',
  },
  {
    name: 'Globex',
    owner: 'Sammy Well',
    status: 'In Progress',
    theme: 'blue',
    dotClass: 'bg-surface-blue-7',
    value: '$18.2k',
  },
  {
    name: 'Initech',
    owner: 'Brian Robinson',
    status: 'On Hold',
    theme: 'amber',
    dotClass: 'bg-surface-amber-7',
    value: '$9.8k',
  },
  {
    name: 'Soylent',
    owner: 'Matt Clinton',
    status: 'Lost',
    theme: 'red',
    dotClass: 'bg-surface-red-7',
    value: '$4.1k',
  },
  {
    name: 'Umbrella',
    owner: 'Jane Cooper',
    status: 'New',
    theme: 'gray',
    dotClass: 'bg-surface-gray-8',
    value: '$12.0k',
  },
]
</script>

<template>
  <div
    class="w-full max-w-[640px] overflow-hidden rounded-lg border border-outline-gray-1 bg-surface-base shadow-sm"
  >
    <div class="flex items-center justify-between border-b border-outline-gray-1 px-3 py-2.5">
      <h3 class="m-0 text-base-medium text-ink-gray-8">Lead pipeline</h3>
      <Badge theme="gray" variant="outline">5 leads</Badge>
    </div>

    <div
      class="grid grid-cols-[minmax(0,1fr)_7.5rem_6.5rem_5rem] gap-3 border-b border-outline-gray-1 bg-surface-gray-1 px-3 py-1.5 text-sm-medium text-ink-gray-5"
    >
      <span>Company</span>
      <span>Owner</span>
      <span>Status</span>
      <span>Value</span>
    </div>

    <div class="divide-y divide-outline-gray-1">
      <div
        v-for="lead in leads"
        :key="lead.name"
        class="grid grid-cols-[minmax(0,1fr)_7.5rem_6.5rem_5rem] items-center gap-3 px-3 py-2 transition-colors hover:bg-surface-gray-1"
      >
        <div class="flex min-w-0 items-center gap-2">
          <div
            class="flex size-6 shrink-0 items-center justify-center rounded bg-surface-gray-2 text-xs-medium text-ink-gray-6"
          >
            {{ lead.name.slice(0, 1) }}
          </div>
          <span class="truncate text-sm text-ink-gray-8">{{ lead.name }}</span>
        </div>
        <span class="truncate text-sm text-ink-gray-6">{{ lead.owner }}</span>
        <Badge :theme="lead.theme" class="justify-self-start">
          <template #prefix>
            <span class="size-1 rounded-full" :class="lead.dotClass" />
          </template>
          {{ lead.status }}
        </Badge>
        <span class="text-sm-medium text-ink-gray-7">{{ lead.value }}</span>
      </div>
    </div>
  </div>
</template>

Row tags

Hyper-verge landing page
App
Frappe
+2
23 Feb
Client feedback
Opensource
+3
28 Feb
vue
<script setup>
import { Badge } from 'frappe-ui'
</script>

<template>
  <div class="flex w-full max-w-[640px] flex-col divide-y divide-outline-gray-1">
    <div class="flex items-center gap-3 py-2.5">
      <span class="lucide-circle size-4 text-ink-gray-4" aria-hidden="true" />
      <span class="flex-1 text-base text-ink-gray-8">
        Hyper-verge landing page
      </span>
      <div class="flex items-center gap-1.5">
        <Badge theme="green">App</Badge>
        <Badge theme="amber">Frappe</Badge>
        <Badge>+2</Badge>
      </div>
      <Badge theme="red">
        <template #prefix>
          <span class="lucide-calendar" aria-hidden="true" />
        </template>
        23 Feb
      </Badge>
    </div>
    <div class="flex items-center gap-3 py-2.5">
      <span class="lucide-circle size-4 text-ink-gray-4" aria-hidden="true" />
      <span class="flex-1 text-base text-ink-gray-8">Client feedback</span>
      <div class="flex items-center gap-1.5">
        <Badge theme="red">Opensource</Badge>
        <Badge>+3</Badge>
      </div>
      <Badge theme="red">
        <template #prefix>
          <span class="lucide-calendar" aria-hidden="true" />
        </template>
        28 Feb
      </Badge>
    </div>
  </div>
</template>

Reactions

The words breathing and ventilation are hyponyms, not synonyms, of respiration.

😄
12
🍩
8
🔥
7
vue
<script setup>
import { Badge } from 'frappe-ui'

const reactions = [
  { emoji: '😄', count: 12 },
  { emoji: '🍩', count: 8 },
  { emoji: '🔥', count: 7 },
]
</script>

<template>
  <div class="w-[28rem]">
    <p class="text-base text-ink-gray-8">
      The words breathing and ventilation are hyponyms, not synonyms, of
      respiration.
    </p>
    <div class="mt-2 flex items-center gap-1.5">
      <Badge v-for="r in reactions" :key="r.emoji" size="md">
        <template #prefix>
          <span class="text-sm leading-none">{{ r.emoji }}</span>
        </template>
        {{ r.count }}
      </Badge>
      <button
        type="button"
        class="inline-flex h-5 items-center justify-center rounded-full px-1.5 text-ink-gray-5 hover:bg-surface-gray-2"
        aria-label="Add reaction"
      >
        <span class="lucide-smile-plus size-3.5" aria-hidden="true" />
      </button>
    </div>
  </div>
</template>

API Reference

Show types
typescript
interface Label {
  toString(): string
}

export interface BadgeProps {
  /** Visual color theme of the badge */
  theme?: 'gray' | 'blue' | 'green' | 'amber' | 'red' | 'violet' | 'orange'

  /** Controls the size of the badge */
  size?: 'sm' | 'md' | 'lg'

  /** Visual style of the badge */
  variant?: 'solid' | 'subtle' | 'outline' | 'ghost'

  /** Content displayed inside the badge */
  label?: Label | string | number
}
theme
= "gray"
"blue" | "red" | "green" | "gray" | "amber" | "violet" | "orange"

Visual color theme of the badge

size
= "md"
"md" | "sm" | "lg"

Controls the size of the badge

variant
= "subtle"
"subtle" | "outline" | "solid" | "ghost"

Visual style of the badge

label
string | number | Label

Content displayed inside the badge

prefix

Content shown before the badge label

default

Main badge content (overrides `label` prop)

suffix

Content shown after the badge label