From 163afbf34bf9270e3defc6f24abefe5f00d63f86 Mon Sep 17 00:00:00 2001 From: ruru <142723369+ruru-m07@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:57:58 +0530 Subject: [PATCH] feat(component): add badge component --- packages/ui/src/components/badge.tsx | 132 +++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 packages/ui/src/components/badge.tsx diff --git a/packages/ui/src/components/badge.tsx b/packages/ui/src/components/badge.tsx new file mode 100644 index 0000000..106c898 --- /dev/null +++ b/packages/ui/src/components/badge.tsx @@ -0,0 +1,132 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/utils/cn"; + +const variants = { + gray: "bg-[#8f8f8f] text-white", + "gray-subtle": "bg-[#1f1f1f]", + blue: "bg-[#0072f5] text-white", + "blue-subtle": "bg-[#10233d] text-[#52a8ff]", + purple: "bg-[#8e4ec6] text-white", + "purple-subtle": "bg-[#2e1938] text-[#bf7af0]", + amber: "bg-[#ffb224] text-black", + "amber-subtle": "bg-[#331b00] text-[#f2a20d]", + red: "bg-[#e5484d] text-white", + "red-subtle": "bg-[#3c1618] text-[#ff6166]", + pink: "bg-[#ea3e83] text-white", + "pink-subtle": "bg-[#4f1c31] text-[#f75f8f]", + green: "bg-[#45a557] text-white", + "green-subtle": "bg-[#0f2e18] text-[#62c073]", + teal: "bg-[#12a594] text-white", + "teal-subtle": "bg-[#083a33] text-[#0ac7b4]", + inverted: "bg-primary text-primary-foreground", +}; + +const sizes = { + sm: "text-xs px-1.5 py-[1.5px]", + md: "text-sm px-2.5 py-[2px]", + lg: "text-lg px-3 py-[2.5px]", +}; + +const badgeVariants = cva( + "w-fit inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 capitalize", + { + variants: { + variant: { + ...variants, + }, + size: { + ...sizes, + }, + }, + defaultVariants: { + variant: "gray", + size: "md", + }, + } +); + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps { + /** + * The content to be displayed inside the badge. + * + * @type {React.ReactNode} + * @required + * @example + * ```tsx + * New + * ``` + */ + children: React.ReactNode; + /** + * Additional CSS class names to apply to the badge. + * + * @type {keyof typeof variants} + * @default "gray" + * @example + * ```tsx + * Gray + * ``` + */ + variant: keyof typeof variants; + /** + * Additional CSS class names to apply to the badge. + * + * @type {string} + * @default "md" + * @example + * ```tsx + * Error + * ``` + */ + size?: "sm" | "md" | "lg"; + /** + * The variant of the badge (e.g., "primary", "secondary", "success"). + * + * @type {string} + * @default "md" + * @example + * ```tsx + * New + * ``` + */ + icon?: React.ReactNode; +} + +/** + * A badge component used to display a small notification or status indicator. + * + * @component + * @example + * ```tsx + * New + * ``` + * + * @param {object} props - The component props. + * @param {React.ReactNode} props.children - The content to be displayed inside the badge. + * @param {string} [props.className] - Additional CSS class names to apply to the badge. + * @param {string} [props.variant] - The variant of the badge (e.g., "gray", "red", etc...). + * @param {string} [props.size="md"] - The size of the badge (e.g., "sm", "md", "lg"). + * @param {React.ReactNode} [props.icon] - An optional icon to display before the badge content. + * @param {React.HTMLAttributes} props - Additional HTML attributes to apply to the badge. + * @returns {React.ReactElement} The rendered badge component. + */ +const Badge: React.FC = ({ + children, + className, + variant, + size = "md", + icon, + ...props +}: BadgeProps): React.ReactElement => { + return ( +
+ {icon && {icon}} + {children} +
+ ); +}; + +export { Badge, badgeVariants };