diff --git a/app/components/Badge/__tests__/badge.test.tsx b/app/components/Badge/__tests__/badge.test.tsx new file mode 100644 index 00000000..1b7a5444 --- /dev/null +++ b/app/components/Badge/__tests__/badge.test.tsx @@ -0,0 +1,60 @@ +import { render, screen } from "@testing-library/react"; +import { FaCheck, FaInfo, FaTimes } from "react-icons/fa"; +import { describe, expect, it } from "vitest"; + +import Badge from "../badge"; + +describe("Badge", () => { + it("renders the label correctly", () => { + render(); + expect(screen.getByText("Test Label")).toBeInTheDocument(); + }); + + it("renders the icon correctly", () => { + render(} />); + expect(screen.getByText("Test Label")).toBeInTheDocument(); + expect(screen.getByTestId("badge-icon")).toBeInTheDocument(); + }); + + it("applies the correct variant styles", () => { + render(); + expect(screen.getByText("Primary")).toHaveClass("bg-blue-500 text-white"); + }); + + it("applies the correct variant styles for success", () => { + render(); + expect(screen.getByText("Success")).toHaveClass("bg-green-500 text-white"); + }); + + it("applies the correct variant styles for error", () => { + render(); + expect(screen.getByText("Error")).toHaveClass("bg-red-500 text-white"); + }); + + it("renders the correct icon with default variant", () => { + render(} />); + expect(screen.getByTestId("badge-icon")).toBeInTheDocument(); + }); + + it("renders the correct icon with primary variant", () => { + render(} />); + expect(screen.getByTestId("badge-icon")).toBeInTheDocument(); + }); + + it("renders the correct icon with success variant", () => { + render(} />); + expect(screen.getByTestId("badge-icon")).toBeInTheDocument(); + }); + + it("renders the correct icon with error variant", () => { + render(} />); + expect(screen.getByTestId("badge-icon")).toBeInTheDocument(); + }); + + it("has the correct accessibility attributes", () => { + render(); + const badge = screen.getByText("Accessible Badge"); + expect(badge).toHaveAttribute("role", "status"); + expect(badge).toHaveAttribute("aria-label", "Accessible Badge"); + }); +}); diff --git a/app/components/Badge/badge.tsx b/app/components/Badge/badge.tsx new file mode 100644 index 00000000..46540efd --- /dev/null +++ b/app/components/Badge/badge.tsx @@ -0,0 +1,36 @@ +import classNames from "classnames"; +import React from "react"; + +interface BadgeProperties { + label: string; + icon?: React.ReactNode; + variant: "default" | "primary" | "success" | "error"; +} + +const Badge: React.FC = ({ label, icon, variant }) => { + const baseStyles = `inline-flex items-center px-3 py-1 rounded-full text-sm font-medium`; + + const variantStyles: { [key: string]: string } = { + default: "bg-gray-200 text-gray-800", + primary: "bg-blue-500 text-white", + success: "bg-green-500 text-white", + error: "bg-red-500 text-white", + }; + + return ( + + {icon && ( + + {icon} + + )} + {label} + + ); +}; + +export default Badge;