From 36f071fa52fcee61bdb3468ee14a65dbc7e16512 Mon Sep 17 00:00:00 2001 From: likithayadav_g Date: Mon, 19 Jan 2026 12:28:19 +0530 Subject: [PATCH 1/2] feat(spinner): add accessible spinner component with size variants --- src/components/spinner/Spinner.test.tsx | 62 +++++++++++++++++++++++++ src/components/spinner/Spinner.tsx | 19 ++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/components/spinner/Spinner.test.tsx create mode 100644 src/components/spinner/Spinner.tsx diff --git a/src/components/spinner/Spinner.test.tsx b/src/components/spinner/Spinner.test.tsx new file mode 100644 index 0000000..04d0e1d --- /dev/null +++ b/src/components/spinner/Spinner.test.tsx @@ -0,0 +1,62 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { describe, it, expect } from "vitest"; +import { Spinner, type SpinnerProps } from "./Spinner"; + +type RenderOptions = { + additionalProps?: Partial; +}; + +const defaultProps: SpinnerProps = { + size: "md", + className: "", +}; + +const renderSpinner = ({ additionalProps }: RenderOptions = {}) => { + const user = userEvent.setup(); + + render(); + + return { + user, + spinner: screen.getByRole("status", { name: /loading/i }), + }; +}; + +describe("Spinner", () => { + it("should render a loading indicator with accessible role", () => { + const { spinner } = renderSpinner(); + + expect(spinner).toBeInTheDocument(); + }); + + it("should render medium size spinner by default", () => { + const { spinner } = renderSpinner(); + + expect(spinner).toHaveClass("w-8 h-8"); + }); + + it("should render small size spinner when size is sm", () => { + const { spinner } = renderSpinner({ + additionalProps: { size: "sm" }, + }); + + expect(spinner).toHaveClass("w-4 h-4"); + }); + + it("should render large size spinner when size is lg", () => { + const { spinner } = renderSpinner({ + additionalProps: { size: "lg" }, + }); + + expect(spinner).toHaveClass("w-12 h-12"); + }); + + it("should apply custom className when provided", () => { + const { spinner } = renderSpinner({ + additionalProps: { className: "text-red-500" }, + }); + + expect(spinner).toHaveClass("text-red-500"); + }); +}); diff --git a/src/components/spinner/Spinner.tsx b/src/components/spinner/Spinner.tsx new file mode 100644 index 0000000..56ec01e --- /dev/null +++ b/src/components/spinner/Spinner.tsx @@ -0,0 +1,19 @@ +export interface SpinnerProps { + size?: "sm" | "md" | "lg"; + className?: string; +} + +export const Spinner = ({ size = "md", className = "" }: SpinnerProps) => { + const sizeStyles = { + sm: "w-4 h-4 border-2", + md: "w-8 h-8 border-3", + lg: "w-12 h-12 border-4", + } as const; + + return ( + + ); +}; From f14692f52d71c25acd86eee7100b319b2009c09d Mon Sep 17 00:00:00 2001 From: likithayadav_g Date: Wed, 4 Feb 2026 14:39:51 +0530 Subject: [PATCH 2/2] refactor(spinner): simplify renderSpinner function and remove redundant tests --- src/components/spinner/Spinner.test.tsx | 36 +------------------------ 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/src/components/spinner/Spinner.test.tsx b/src/components/spinner/Spinner.test.tsx index 04d0e1d..3b0d4a5 100644 --- a/src/components/spinner/Spinner.test.tsx +++ b/src/components/spinner/Spinner.test.tsx @@ -3,16 +3,12 @@ import userEvent from "@testing-library/user-event"; import { describe, it, expect } from "vitest"; import { Spinner, type SpinnerProps } from "./Spinner"; -type RenderOptions = { - additionalProps?: Partial; -}; - const defaultProps: SpinnerProps = { size: "md", className: "", }; -const renderSpinner = ({ additionalProps }: RenderOptions = {}) => { +const renderSpinner = (additionalProps?: Partial) => { const user = userEvent.setup(); render(); @@ -29,34 +25,4 @@ describe("Spinner", () => { expect(spinner).toBeInTheDocument(); }); - - it("should render medium size spinner by default", () => { - const { spinner } = renderSpinner(); - - expect(spinner).toHaveClass("w-8 h-8"); - }); - - it("should render small size spinner when size is sm", () => { - const { spinner } = renderSpinner({ - additionalProps: { size: "sm" }, - }); - - expect(spinner).toHaveClass("w-4 h-4"); - }); - - it("should render large size spinner when size is lg", () => { - const { spinner } = renderSpinner({ - additionalProps: { size: "lg" }, - }); - - expect(spinner).toHaveClass("w-12 h-12"); - }); - - it("should apply custom className when provided", () => { - const { spinner } = renderSpinner({ - additionalProps: { className: "text-red-500" }, - }); - - expect(spinner).toHaveClass("text-red-500"); - }); });