Search

Ctrl + K

Badge

This document outlines the steps to create Badge component styled withTailwind CSS and using some npm dependency libraries.

Prerequisites

  • Node.js and npm installed on your machine.
  • Tailwind CSS installed in your project.
  • CVA(class-variance-authority) is a utility for managing CSS class names based on various conditions.
  • clsx is a tiny utility for constructing className strings conditionally.
Step 1: Create variant styles
1// badge.helpers.ts
2import { cva } from "class-variance-authority";
3
4export const badgeVariants = cva(
5  "absolute flex justify-center items-center border-white px-[3px]",
6  {
7    variants: {
8      shape: {
9        square: "rounded-sm",
10        circle: "rounded-full",
11      },
12      size: {
13        small: "min-w-3 h-3 data-[outline=true]:border text-[9px]",
14        medium: "min-w-4 h-4 data-[outline=true]:border text-xs",
15        large: "min-w-5 h-5 data-[outline=true]:border-2 text-sm",
16      },
17      position: {
18        topRight: "",
19        topLeft: "",
20        bottomRight: "",
21        bottomLeft: "",
22      },
23      color: {
24        primary: "bg-blue-500 text-white",
25        secondary: "bg-gray-500 text-white",
26        success: "bg-green-500 text-white",
27        danger: "bg-red-500 text-white",
28        warning: "bg-yellow-500 text-white",
29        info: "bg-cyan-500 text-white",
30        light: "bg-gray-200 text-black",
31        dark: "bg-gray-900 text-white",
32      },
33    },
34    compoundVariants: [
35      {
36        position: "topRight",
37        size: "small",
38        className: "-top-1 left-[calc(100%-7px)]",
39      },
40      {
41        position: "topRight",
42        size: "medium",
43        className: "-top-1.5 left-[calc(100%-10px)]",
44      },
45      {
46        position: "topRight",
47        size: "large",
48        className: "-top-2 left-[calc(100%-12px)]",
49      },
50      {
51        position: "bottomRight",
52        size: "small",
53        className: "-bottom-1 left-[calc(100%-7px)]",
54      },
55      {
56        position: "bottomRight",
57        size: "medium",
58        className: "-bottom-1.5 left-[calc(100%-10px)]",
59      },
60      {
61        position: "bottomRight",
62        size: "large",
63        className: "-bottom-2 left-[calc(100%-12px)]",
64      },
65      {
66        position: "topLeft",
67        size: "small",
68        className: "-top-1 right-[calc(100%-7px)]",
69      },
70      {
71        position: "topLeft",
72        size: "medium",
73        className: "-top-1.5 right-[calc(100%-10px)]",
74      },
75      {
76        position: "topLeft",
77        size: "large",
78        className: "-top-2 right-[calc(100%-12px)]",
79      },
80      {
81        position: "bottomLeft",
82        size: "small",
83        className: "-bottom-1 right-[calc(100%-7px)]",
84      },
85      {
86        position: "bottomLeft",
87        size: "medium",
88        className: "-bottom-1.5 right-[calc(100%-10px)]",
89      },
90      {
91        position: "bottomLeft",
92        size: "large",
93        className: "-bottom-2 right-[calc(100%-12px)]",
94      },
95    ],
96    defaultVariants: {
97      shape: "square",
98      size: "medium",
99      color: "primary",
100      position: "topRight",
101    },
102  },
103);
104
Step 2: Create Badge component
1// badge.component.tsx
2import { VariantProps } from "class-variance-authority";
3import { badgeVariants } from "./badge.helpers";
4
5interface BadgeProps extends VariantProps<typeof badgeVariants> {
6  title: string;
7  showOutline?: boolean;
8  hidden?: boolean;
9  className?: string;
10  labelClassName?: string;
11  children: React.ReactNode;
12}
13
14const Badge: React.FC<BadgeProps> = ({
15  title,
16  shape,
17  size,
18  color,
19  position,
20  showOutline,
21  hidden,
22  className,
23  labelClassName,
24  children,
25}) => {
26  return (
27    <div className={cn("relative w-fit", className)}>
28      {children}
29      {!hidden && (
30        <div
31          data-outline={Boolean(showOutline).toString()}
32          className={cn(
33            badgeVariants({ shape, size, position, color }),
34            labelClassName
35          )}
36        >
37          {title}
38        </div>
39      )}
40    </div>
41  );
42};
43
44export default Badge;
45