PhiaUi.Components.Badge (phia_ui v0.1.17)

Copy Markdown View Source

Compact inline label for status indicators, tags, version numbers, and counts.

Provides 6 semantic variants following the shadcn/ui Badge anatomy. Badges are purely presentational — they are <div> elements, not <button> or <a>. For clickable or dismissible badges, compose a badge with a button.

Variants

VariantVisualTypical use cases
:defaultSolid primary backgroundActive state, current plan, primary label
:secondaryMuted secondary backgroundNeutral tag, informational, version number
:destructiveRed/destructive backgroundError, overdue, critical, danger
:outlineBorder only, transparent backgroundDraft, subtle metadata, low-emphasis tag
:ghostTransparent, accent on hoverInline tags, chip lists with hover effect
:linkPrimary colour with underline on hoverClickable tag acting as a link

Basic usage

<.badge>New</.badge>

<.badge variant={:secondary}>Beta</.badge>

<.badge variant={:destructive}>Overdue</.badge>

<.badge variant={:outline}>Draft</.badge>

Status indicators

Use badges to show record status in tables and cards:

<.badge variant={status_variant(@order.status)}>
  {String.capitalize(@order.status)}
</.badge>

Where status_variant/1 maps domain values to badge variants:

defp status_variant("active"),    do: :default
defp status_variant("draft"),     do: :outline
defp status_variant("overdue"),   do: :destructive
defp status_variant(_other),      do: :secondary

Trend indicators in stat cards

The StatCard component uses badges internally for trend labels. You can compose the same pattern directly:

<div class="flex items-center gap-2">
  <span class="text-2xl font-bold">$42,800</span>
  <.badge variant={:default} class="gap-1">
    <.icon name="trending-up" size={:xs} />
    +12.5%
  </.badge>
</div>

Count / notification badge

Overlay a count badge on an icon:

<div class="relative inline-flex">
  <.icon name="bell" size={:md} />
  <.badge class="absolute -top-1 -right-1 h-4 w-4 p-0 flex items-center justify-center text-[10px]">
    {min(@unread_count, 99)}
  </.badge>
</div>

Plan or tier labels

<.badge variant={:outline} class="uppercase tracking-wide text-[10px]">
  Pro
</.badge>

Tag list

<div class="flex flex-wrap gap-1">
  <%= for tag <- @post.tags do %>
    <.badge variant={:secondary}>{tag}</.badge>
  <% end %>
</div>

Combining with a close button (dismissible tag)

<%= for skill <- @skills do %>
  <div class="inline-flex items-center gap-1">
    <.badge variant={:secondary}>{skill}</.badge>
    <button
      phx-click="remove_skill"
      phx-value-skill={skill}
      class="ml-0.5 rounded-full p-0.5 hover:bg-muted"
      aria-label={"Remove #{skill}"}
    >
      <.icon name="x" size={:xs} />
    </button>
  </div>
<% end %>

Summary

Functions

Renders an inline <div> styled as a badge.

Functions

badge(assigns)

Renders an inline <div> styled as a badge.

Badges are display-only elements — they have no interactive behaviour by default. To make a badge interactive, wrap it in a <button> or <a> or compose it with a close/remove button beside it.

The :default variant uses the primary brand colour for high-visibility labels. :outline and :ghost are appropriate for lower-emphasis metadata. :destructive should be reserved for genuine error or danger states.

Example

<.badge variant={:destructive}>
  <.icon name="alert-triangle" size={:xs} />
  Critical
</.badge>

Attributes

  • variant (:atom) - Visual style variant. Controls background, text colour, and hover state. Default: :default (solid primary). Defaults to :default. Must be one of :default, :secondary, :destructive, :outline, :ghost, or :link.
  • class (:string) - Additional CSS classes merged via cn/1. Use uppercase tracking-wide for label-style badges, or gap-1 to add an icon. Defaults to nil.
  • Global attributes are accepted. HTML attributes forwarded to the root <div> element (e.g. data-testid, aria-label).

Slots

  • inner_block (required) - Badge content. Typically a short text label (1–3 words), count, or an icon + text combination.