A badge is a small status component that can be used to display a status or a count.
export const Example = () => {
return <Badge>Badge</Badge>;
};
If you haven't included Piksel UI in your project, include it first. You can check the installation page.
Copy the following source code and add it to your project.
import { cn } from "@/utils/cn";
import { Slot } from "@radix-ui/react-slot";
import { forwardRef, HTMLAttributes } from "react";
import { tv, VariantProps } from "tailwind-variants";
export const badgeDisplayName = "Badge";
export type BadgeProps = HTMLAttributes<HTMLDivElement> &
VariantProps<typeof badgeStyles> & {
/**
* If true, the badge will be rendered as a child component
*/
asChild?: boolean;
};
/**
* @name Badge
* @description The Badge component is
*/
export const Badge = forwardRef<HTMLDivElement, BadgeProps>((props, ref) => {
const {
asChild,
variant,
color,
size,
radius,
truncate,
className,
children,
...rest
} = props;
const componentClassNames = badgeStyles({
variant,
color,
size,
radius,
truncate,
className,
});
const Component = asChild ? Slot : "div";
return (
<Component className={cn(componentClassNames)} {...rest} ref={ref}>
{children}
</Component>
);
});
Badge.displayName = badgeDisplayName;
export const badgeStyles = tv({
/**
* Base styles of the badge
*/
base: [
"relative inline-flex items-center justify-center no-underline outline-0",
"font-medium ring-0 ring-offset-0 transition-all flex-shrink-0 max-w-full whitespace-nowrap overflow-hidden",
"focus-visible:ring-2 focus-visible:ring-offset-2",
"disabled:opacity-75 disabled:cursor-not-allowed",
],
variants: {
/**
* Variant prop of the badge
*/
variant: {
filled: "border",
soft: "",
outline: "border focus-visible:ring-transparent",
},
/**
* Color prop of the badge
*/
color: {
blue: "ring-blue-300 border-blue-600",
red: "ring-red-300 border-red-600",
indigo: "ring-indigo-300 border-indigo-600",
green: "ring-green-300 border-green-600",
yellow: "ring-yellow-200 border-yellow-500",
zinc: "ring-zinc-300 border-zinc-600",
white: "ring-zinc-50 border-zinc-50",
black: "ring-zinc-400 border-zinc-900",
},
/**
* Size prop of the badge
*/
size: {
sm: "px-1 py-0 text-sm gap-0.5",
md: "px-1.5 py-0.5 text-sm gap-1",
lg: "px-2 py-1 text-sm gap-1.5",
},
radius: {
none: "rounded-none",
sm: "rounded-sm",
md: "rounded-md",
lg: "rounded-lg",
full: "rounded-full",
},
truncate: {
true: "truncate line-clamp-1",
},
},
compoundVariants: [
/* -------------------------------------------------------------------------- */
/* Variants and colors */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Filled variant */
/* -------------------------------------------------------------------------- */
{
variant: "filled",
color: "blue",
className: "bg-blue-500 text-white hover:text-white",
},
{
variant: "filled",
color: "red",
className: "bg-red-500 text-white hover:text-white",
},
{
variant: "filled",
color: "indigo",
className: "bg-indigo-500 text-white hover:text-white",
},
{
variant: "filled",
color: "green",
className: "bg-green-500 text-white hover:text-white",
},
{
variant: "filled",
color: "yellow",
className: "bg-yellow-400 text-black hover:text-black",
},
{
variant: "filled",
color: "zinc",
className: "bg-zinc-500 text-white hover:text-white",
},
{
variant: "filled",
color: "white",
className: "bg-zinc-50 text-zinc-950 hover:text-zinc-950",
},
{
variant: "filled",
color: "black",
className: "bg-zinc-950 text-white hover:text-white",
},
/* -------------------------------------------------------------------------- */
/* Soft variant */
/* -------------------------------------------------------------------------- */
{
variant: "soft",
color: "blue",
className: "bg-blue-100 text-blue-600 hover:text-blue-600",
},
{
variant: "soft",
color: "red",
className: "bg-red-100 text-red-600 hover:text-red-600",
},
{
variant: "soft",
color: "indigo",
className: "bg-indigo-100 text-indigo-600 hover:text-indigo-600",
},
{
variant: "soft",
color: "green",
className: "bg-green-100 text-green-600 hover:text-green-600",
},
{
variant: "soft",
color: "yellow",
className: "bg-yellow-100 text-yellow-600 hover:text-yellow-600",
},
{
variant: "soft",
color: "zinc",
className: "bg-zinc-100 text-zinc-600 hover:text-zinc-600",
},
{
variant: "soft",
color: "white",
className: "bg-white text-zinc-950 hover:text-zinc-950",
},
{
variant: "soft",
color: "black",
className: "bg-zinc-200 text-zinc-600",
},
/* -------------------------------------------------------------------------- */
/* Outline variant */
/* -------------------------------------------------------------------------- */
{
variant: "outline",
color: "blue",
className: ["text-blue-500 outline-blue-500"],
},
{
variant: "outline",
color: "red",
className: ["text-red-500 outline-red-500"],
},
{
variant: "outline",
color: "indigo",
className: ["text-indigo-500 outline-indigo-500"],
},
{
variant: "outline",
color: "green",
className: ["text-green-500 outline-green-500"],
},
{
variant: "outline",
color: "yellow",
className: ["text-yellow-600 outline-yellow-500"],
},
{
variant: "outline",
color: "zinc",
className: ["text-zinc-500 outline-zinc-500"],
},
{
variant: "outline",
color: "white",
className: ["text-zinc-500 outline-zinc-500"],
},
{
variant: "outline",
color: "black",
className: ["text-zinc-950 outline-zinc-950"],
},
],
defaultVariants: {
variant: "filled",
color: "blue",
size: "md",
radius: "md",
},
});
The Badge component has the following props.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild? | boolean | false | The component used for the root node. |
variant? | 'filled' | 'soft' | 'outline' | 'filled' | The variant of the badge. |
color? | 'blue' | 'red' | 'indigo' | 'green' | 'yellow' | 'zinc' | 'white' | 'black' | 'blue' | The color of the badge. |
size? | 'sm' | 'md' | 'lg' | 'md' | The size of the badge. |
radius? | 'none' | 'sm' | 'md' | 'lg' | 'full' | 'md' | The border radius of the badge. |
truncate? | boolean | false | Whether the badge text is truncated. |