Propel

Badge

A small rounded pill of inline text for statuses, labels, and counts.

Badge
Show code
import { Badge } from "@makeplane/propel/components/badge";

export default function BasicDemo() {
  return <Badge label="Badge" variant="neutral" size="xs" />;
}

Installation

import { Badge } from "@makeplane/propel/components/badge";

Usage

import { Badge } from "@makeplane/propel/components/badge";

export default function BasicDemo() {
  return <Badge label="Badge" variant="neutral" size="xs" />;
}

Examples

Variants

The variant axis carries both semantic color (success, warning, danger) and decorative hues.

neutralgreybrandinfoindigosuccessemeraldwarningyellowdangercrimsonorange
Show code
import { Badge, type BadgeVariant } from "@makeplane/propel/components/badge";

const VARIANTS: BadgeVariant[] = [
  "neutral",
  "grey",
  "brand",
  "info",
  "indigo",
  "success",
  "emerald",
  "warning",
  "yellow",
  "danger",
  "crimson",
  "orange",
];

export default function VariantsDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {VARIANTS.map((variant) => (
        <Badge key={variant} variant={variant} size="xs" label={variant} />
      ))}
    </div>
  );
}

Sizes

size has two steps — xs 20 px with 12px text and sm 24 px with 13px. A badge is inline chrome, so it stops where the compact ladder does; the old 18px step was retired when the family moved onto the shared rungs.

xssm
Show code
import { Badge, type BadgeSize } from "@makeplane/propel/components/badge";

const SIZES: BadgeSize[] = ["xs", "sm"];

export default function SizesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {SIZES.map((size) => (
        <Badge key={size} variant="brand" size={size} label={size} />
      ))}
    </div>
  );
}

With icon

DonePro
Show code
import { Badge } from "@makeplane/propel/components/badge";
import { Icon } from "@makeplane/propel/components/icon";
import { Check, Sparkles } from "lucide-react";

export default function WithIconDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Badge variant="success" size="xs" startIcon={<Icon icon={Check} />} label="Done" />
      <Badge variant="brand" size="xs" endIcon={<Icon icon={Sparkles} />} label="Pro" />
    </div>
  );
}

Icon only

Omit label for a compact icon-only badge: the label part is skipped so the icon sits centered, and the pill renders role="img". Because the icon is decorative, aria-label is required in this state — the type makes omitting both label and aria-label an error.

Show code
import { Badge, type BadgeSize } from "@makeplane/propel/components/badge";
import { Icon } from "@makeplane/propel/components/icon";
import { Check } from "lucide-react";

const SIZES: BadgeSize[] = ["xs", "sm"];

export default function IconOnlyDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {SIZES.map((size) => (
        <Badge
          key={size}
          variant="success"
          size={size}
          startIcon={<Icon icon={Check} />}
          aria-label="Completed"
        />
      ))}
    </div>
  );
}

API Reference

Badge

The ready-made badge: composes the atomic `Badge` pill with the `BadgeLabel` and optional leading (`startIcon`) and trailing (`endIcon`) icon slots. With no `label` the pill is icon-only — the label part is skipped entirely (an empty flex child would still consume the pill's `gap` and render it lopsided), and the pill defaults to `role="img"` so an author-supplied `aria-label` is valid ARIA (a bare `<span>`'s `generic` role doesn't support naming).

PropTypeDefaultDescription
size(required)"xs" | "sm"
variant(required)"neutral" | "grey" | "brand" | "info" | "indigo" | "success" | "emerald" | "warning" | "yellow" | "danger" | "crimson" | "orange"
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
startIconReactNodeElement rendered before the label (inline-start), e.g. `<Icon icon={Check} />`.
endIconReactNodeElement rendered after the label (inline-end), e.g. `<Icon icon={Sparkles} />`.
labelstring
aria-labelstring