Agents (llms.txt)
Octocat

Badge

A Badge component with the possibility of adding an icon and a status

Up to date
import { PackageIcon } from '@phosphor-icons/react/dist/ssr';

import { Badge } from '@/components/badge';

export default function BadgePreview() {
  return (
    <Badge>
      <Badge.Icon>
        <PackageIcon />
      </Badge.Icon>
      <span>Up to date</span>
      <Badge.Status className="bg-emerald-500" />
    </Badge>
  );
}

Dependencies

Source Code

import type { VariantProps } from 'cva';

import { Slot } from '@/components/slot';
import { cn, cva } from '@/lib/utils/classnames';

const badgeStyle = cva({
  base: 'inline-flex items-center gap-1 rounded-full font-semibold leading-none ring-1 ring-inset [&>[data-badge-icon]:first-child]:-ml-0.5 [&>[data-badge-icon]:last-child]:-mr-0.5',
  variants: {
    variant: {
      neutral: 'bg-background text-foreground/80 ring-foreground/10',
      success: 'bg-success/10 text-success ring-success/20',
      error: 'bg-error/10 text-error ring-error/20',
      warning: 'bg-warning/10 text-warning ring-warning/20',
      info: 'bg-info/10 text-info ring-info/20',
    },
    size: {
      md: 'h-6 px-2.5 text-sm',
      sm: 'h-5 px-2 text-xs',
      xs: 'h-4 px-1.5 text-2xs',
    },
  },
  defaultVariants: {
    size: 'md',
  },
});

interface BadgeProps extends React.ComponentPropsWithRef<'div'> {
  variant?: VariantProps<typeof badgeStyle>['variant'];
  size?: VariantProps<typeof badgeStyle>['size'];
  asChild?: boolean;
}

const Badge = ({
  ref,
  children,
  variant = 'neutral',
  size = 'md',
  className,
  asChild,
  ...rest
}: BadgeProps) => {
  const Comp = asChild ? Slot : 'div';

  return (
    <Comp
      ref={ref}
      className={cn(badgeStyle({ variant, size }), className)}
      {...rest}
    >
      {children}
    </Comp>
  );
};

const BadgeIcon = ({
  children,
  className,
  ...rest
}: React.ComponentPropsWithRef<'div'>) => {
  return (
    <div
      data-badge-icon
      className={cn('flex items-center justify-center', className)}
      {...rest}
    >
      {children}
    </div>
  );
};

const BadgeStatus = ({
  className,
  ...rest
}: Omit<React.ComponentPropsWithRef<'div'>, 'children'>) => {
  return (
    <div
      className={cn(
        'mx-0.5 size-1.5 rounded-full bg-current first:ml-0 last:mr-0',
        className
      )}
      {...rest}
    />
  );
};

const CompoundBadge = Object.assign(Badge, {
  Icon: BadgeIcon,
  Status: BadgeStatus,
});

export { CompoundBadge as Badge };

Anatomy


          <Badge>
  <Badge.Icon />
  <Badge.Status />
</Badge>
        

API Reference

Badge

Extends the div element.

Prop Default Type
variant "neutral" "neutral""success""error""warning""info"
size "md" "xs""sm""md"
asChild - boolean

Badge.Icon

Extends the div element.

Badge.Status

Extends the div element.

Examples

Variants

Neutral
Success
Error
Warning
Info
import { Badge } from '@/components/badge';

export default function BadgeVariantsPreview() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <Badge variant="neutral">Neutral</Badge>
      <Badge variant="success">Success</Badge>
      <Badge variant="error">Error</Badge>
      <Badge variant="warning">Warning</Badge>
      <Badge variant="info">Info</Badge>
    </div>
  );
}

Sizes

Extra small
Small
Medium
import { Badge } from '@/components/badge';

export default function BadgeSizesPreview() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <Badge size="xs">Extra small</Badge>
      <Badge size="sm">Small</Badge>
      <Badge size="md">Medium</Badge>
    </div>
  );
}

With icon and status

Up to date
import { PackageIcon } from '@phosphor-icons/react/dist/ssr';

import { Badge } from '@/components/badge';

export default function BadgePreview() {
  return (
    <Badge>
      <Badge.Icon>
        <PackageIcon />
      </Badge.Icon>
      <span>Up to date</span>
      <Badge.Status className="bg-emerald-500" />
    </Badge>
  );
}

Best Practices

  1. Usage:

    • Use appropriate variants for context
    • Keep content concise
    • Consider icon visibility at small sizes
  2. Accessibility:

    • Ensure sufficient color contrast
    • Provide clear meaning through text

Previous

Avatar

Next

Breadcrumb